--- /dev/null
+#!/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
+
+
--- /dev/null
+#!/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()
--- /dev/null
+/*! \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;
+ }
+}
--- /dev/null
+/*! \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 */