- New code to dump the contents of Atmel's 2-wire EEPROM chips
authoreinsteinnn <einsteinnn@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Wed, 21 Sep 2011 17:38:27 +0000 (17:38 +0000)
committereinsteinnn <einsteinnn@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Wed, 21 Sep 2011 17:38:27 +0000 (17:38 +0000)
git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@1050 12e2690d-a6be-4b82-a7b7-67c4a43b65c8

client/GoodFETtwe.py [new file with mode: 0644]
client/goodfet.twe [new file with mode: 0755]
firmware/apps/twe/twe.c [new file with mode: 0644]
firmware/include/twe.h [new file with mode: 0644]

diff --git a/client/GoodFETtwe.py b/client/GoodFETtwe.py
new file mode 100644 (file)
index 0000000..4410cb3
--- /dev/null
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+# GoodFET Atmel 2-wire EEPROM client library
+# 
+
+import sys, time, string, cStringIO, struct, glob, serial, os;
+
+from GoodFET import GoodFET;
+
+class GoodFETtwe(GoodFET):
+    
+    JEDECsize=0;
+
+    def setup(self):
+        """Move the FET into the SPI application."""
+        self.writecmd(0x05, 0x10, 0, []) # SETUP
+    
+    def peekblock(self, adr):
+        """Grab a few block from an SPI Flash ROM.  Block size is unknown"""
+        data = [adr&0xFF, (adr&0xFF00)>>8]
+        
+        self.writecmd(0x05, 0x02, 2, data) # PEEK
+        return self.data
+    
+
diff --git a/client/goodfet.twe b/client/goodfet.twe
new file mode 100755 (executable)
index 0000000..e3ba5ab
--- /dev/null
@@ -0,0 +1,54 @@
+#!/usr/bin/env python
+
+# GoodFET - Atmel 2-wire EEPROM
+
+import sys;
+import binascii;
+import array;
+
+from GoodFETtwe import GoodFETtwe;
+from intelhex import IntelHex;
+
+if(len(sys.argv)==1):
+    print "Usage: %s verb [objects]\n" % sys.argv[0];
+    print "%s info" % sys.argv[0];
+    print "%s dump $foo.rom [0x$start 0x$stop]" % sys.argv[0];
+    sys.exit();
+
+#Initialize FET and set baud rate
+client=GoodFETtwe();
+client.serInit()
+
+client.setup();
+
+#~ if(sys.argv[1]=="info"):
+    #~ data=client.SPIjedec();
+    #~ print "Ident as %s\nManufacturer: %02x %s\nType: %02x\nCapacity: %02x (%i bytes)" % (
+        #~ client.SPIjedecstr(),
+        #~ ord(data[1]),client.SPIjedecmanstr(),
+        #~ ord(data[2]),
+        #~ ord(data[3]),
+        #~ client.JEDECsize);
+
+if(sys.argv[1]=="dump"):
+    f = sys.argv[2];
+    
+    start=0;
+    stop=0;
+    if(len(sys.argv)>3):
+        start=int(sys.argv[3],16);
+    if(len(sys.argv)>4):
+        stop=int(sys.argv[4],16);
+    
+    print "Dumping code from %06x to %06x as %s." % (start,stop,f);
+    file = open(f, mode='wb')
+    
+    i=start;
+    while i<=stop:
+        data=client.peekblock(i);
+        
+        print "Dumped %06x."%i;
+        for j in data:
+            if i<stop: file.write(j);
+            i+=1;
+    file.close()
diff --git a/firmware/apps/twe/twe.c b/firmware/apps/twe/twe.c
new file mode 100644 (file)
index 0000000..12a3013
--- /dev/null
@@ -0,0 +1,255 @@
+/*! \file spi.c
+  \author EiNSTeiN_ <einstein@g3nius.org>
+  \brief Atmel 2-wire EEPROM
+*/
+
+#include "command.h"
+
+#include <signal.h>
+#include <io.h>
+#include <iomacros.h>
+
+#include "twe.h"
+
+#include "platform.h"
+
+//! Handles a monitor command.
+void spi_handle_fn( uint8_t const app,
+                                       uint8_t const verb,
+                                       uint32_t const len);
+
+// define the spi app's app_t
+app_t const twe_app = {
+
+       /* app number */
+       TWE,
+
+       /* handle fn */
+       twe_handle_fn,
+
+       /* name */
+       "2-wire EEPROM",
+
+       /* desc */
+       "\tThis app handles Atmel's 2-wire EEPROM protocol.\n"
+};
+
+// Transmit the START condition
+void twe_start()
+{
+    SETSDA;
+    
+    SETSCL;
+    delay_us(1);
+    
+    // high to low transision of SDA while SCL is high
+    CLRSDA;
+    delay_us(1);
+    
+    CLRSCL;
+    delay_us(2);
+    
+    SETSDA;
+  
+}
+
+// transmit the STOP condition
+void twe_stop()
+{
+    CLRSDA;
+    SETSCL;
+    delay_us(1);
+    
+    // low to high transision of SDA while SCL is high
+    SETSDA;
+    delay_us(2);
+    
+    CLRSCL;
+    delay_us(1);
+}
+
+//! Write 8 bits and read 1
+unsigned char twe_tx(unsigned char byte){
+  unsigned int bit;
+  
+  for (bit = 0; bit < 8; bit++) {
+    delay_us(15);
+    
+    /* write SDA on trailing edge of previous clock */
+    if (byte & 0x80)
+      SETSDA;
+    else
+      CLRSDA;
+    byte <<= 1;
+    
+    SETSCL;
+    delay_us(1);
+    CLRSCL;
+  }
+  
+  // 9th bit is ACK
+  SPIDIR &= ~SDA;
+  SPIREN |= SDA;  /* as per datasheet, SDA must be pulled high externally */
+  SPIOUT |= SDA;
+  SETSCL;
+  delay_us(1);
+  bit = (SPIIN & SDA) ? 1 : 0;
+  delay_us(1);
+  CLRSCL;
+  delay_us(10);
+  SPIOUT &= ~SDA;
+  SPIREN &= ~SDA;
+  SPIDIR |= SDA;
+  
+  if(bit) {
+    debugstr("not acked :s");
+  }
+  
+  return bit;
+}
+
+//! Read 8 bits, optionally acking it
+unsigned char twe_rx(unsigned int ack){
+  unsigned int rd = 0;
+  unsigned int bit = 0;
+  
+  SPIDIR &= ~SDA;
+  SPIREN |= SDA; /* as per datasheet, SDA must be pulled high externally */
+  SPIOUT |= SDA;
+  
+  for (bit = 0; bit < 8; bit++) {
+    delay_us(10);
+    SETSCL;
+    delay_us(1);
+    if(SPIIN & SDA)
+        rd |= 1 << (7-bit);
+    delay_us(1);
+    CLRSCL;
+  }
+  
+  SPIOUT &= ~SDA;
+  SPIREN &= ~SDA;
+  SPIDIR |= SDA;
+  
+  if(ack) {
+    // 9th bit is ACK
+    CLRSDA;
+      
+    SETSCL;
+    delay_us(15);
+    CLRSCL;
+    delay_us(15);
+  }
+  //~ else {
+    //~ SETSDA;
+  //~ }
+  
+  
+  return rd;
+}
+
+//! Read a block to a buffer.
+void twe_peekblock(uint8_t const app,
+              uint8_t const verb,
+              uint16_t adr,
+              uint32_t len)
+{
+  unsigned char i;
+  
+  // start command / write
+  twe_start();
+  twe_tx(0xa0); // preamble=1010, device adr=000, write=0
+  
+  // output address bytes
+  //~ debughex((adr >> 8) & 0xff);
+  twe_tx((adr >> 8) & 0xff);
+  //~ debughex(adr & 0xff);
+  twe_tx(adr & 0xff);
+  
+  // start command / read
+  twe_start();
+  twe_tx(0xa1); // preamble=1010, device adr=000, read=1
+  
+  //Send reply header
+  txhead(app, verb, len);
+  
+  for(i=0;i<len;i++)
+    serial_tx(twe_rx(i != (len-1)));
+  
+  twe_stop();
+  
+  return;
+}
+
+//! Read a block to a buffer.
+void twe_pokeblock(uint16_t adr,
+              uint8_t *buf,
+              uint32_t len)
+{
+  unsigned char i;
+  // start command / write
+  twe_start();
+  twe_tx(0xa0); // preamble=1010, device adr=000, write=0
+  
+  // output address bytes
+  twe_tx((adr >> 8) & 0xFF);
+  twe_tx(adr & 0xFF);
+  
+  for(i=0;i<len;i++)
+    twe_tx(buf[i]);
+  
+  twe_stop();
+  
+  return;
+}
+
+//! Set up the pins for SPI mode.
+void twe_setup()
+{
+  int i;
+  
+  SETSDA; // normal position
+  CLRSCL; // normal position
+  SPIDIR |= SDA | SCL;
+  
+  twe_start();
+  
+  SETSDA;
+  for(i=0;i<9;i++) {
+    SETSCL;
+    delay_us(15);
+    CLRSCL;
+    delay_us(15);
+  }
+  
+  twe_start();
+  twe_stop();
+  
+  
+}
+
+//! Handles a monitor command.
+void twe_handle_fn( uint8_t const app,
+                                       uint8_t const verb,
+                                       uint32_t const len)
+{
+  uint16_t adr;
+  switch(verb)
+  {
+    case PEEK: //Grab 128 bytes from an SPI Flash ROM
+      adr = cmddataword[0];
+      twe_setup();
+      twe_peekblock(app, verb, adr, 128);
+      break;
+
+    //~ case POKE: //Grab 128 bytes from an SPI Flash ROM
+      //~ debugstr("reading");
+      //~ twe_pokeblock(cmddata, len);
+      //~ break;
+
+    case SETUP:
+      twe_setup();
+      txdata(app,verb,0);
+      break;
+  }
+}
diff --git a/firmware/include/twe.h b/firmware/include/twe.h
new file mode 100644 (file)
index 0000000..3d43a8a
--- /dev/null
@@ -0,0 +1,44 @@
+/*! \file spi.h
+  \author EiNSTeiN_ <einstein@g3nius.org>
+  \brief Definitions for the Atmel 2-wire EEPROM application.
+*/
+
+#ifndef TWE_H
+#define TWE_H
+
+#include "app.h"
+
+#define TWE 0x05
+
+//Pins and I/O
+//~ #define MOSI BIT1
+//~ #define MISO BIT2
+//~ #define SCK  BIT3
+#define SDA BIT1
+#define SCL BIT3
+
+#define SETSDA SPIOUT |= SDA
+#define CLRSDA SPIOUT &= ~SDA
+#define SETSCL SPIOUT |= SCL
+#define CLRSCL SPIOUT &= ~SCL
+
+//! Set up the pins for SPI mode.
+void twe_setup();
+
+//! Read and write an SPI byte.
+unsigned char twe_trans8(unsigned char byte);
+
+//! Read a block to a buffer.
+//~ void twe_peekblock(uint8_t const app,
+              //~ uint8_t const verb,
+              //~ uint16_t adr,
+              //~ uint32_t len);
+
+
+void twe_handle_fn( uint8_t const app,
+                                       uint8_t const verb,
+                                       uint32_t const len);
+
+extern app_t const twe_app;
+
+#endif /* TWE_H */