From: travisutk Date: Tue, 1 Sep 2009 22:19:32 +0000 (+0000) Subject: Getting closer to an I2C Python client. X-Git-Url: http://git.rot13.org/?p=goodfet;a=commitdiff_plain;h=c28cce5afcc1e1747f51e5afe15e338dae030376 Getting closer to an I2C Python client. All sorts of resistor headaches. git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@105 12e2690d-a6be-4b82-a7b7-67c4a43b65c8 --- diff --git a/client/GoodFET.py b/client/GoodFET.py index 297111e..3a192fc 100755 --- a/client/GoodFET.py +++ b/client/GoodFET.py @@ -18,8 +18,9 @@ class GoodFET: """Open the serial port""" if port is None: - port=os.environ.get("GOODFET"); - + glob_list = glob.glob(os.environ.get("GOODFET")); + if len(glob_list) > 0: + port = glob_list[0]; if port is None: glob_list = glob.glob("/dev/tty.usbserial*"); if len(glob_list) > 0: @@ -150,6 +151,7 @@ class GoodFET: def SPIsetup(self): """Moved the FET into the SPI application.""" self.writecmd(0x01,0x10,0,self.data); #SPI/SETUP + def SPItrans8(self,byte): """Read and write 8 bits by SPI.""" @@ -245,8 +247,23 @@ class GoodFET: print "Initializing MSP430."; self.writecmd(0x11,0x10,0,self.data); - - + def I2Csetup(self): + """Move the FET into the I2C application.""" + self.writecmd(0x02,0x10,0,self.data); #SPI/SETUP + def I2Cstart(self): + """Start an I2C transaction.""" + self.writecmd(0x02,0x20,0,self.data); #SPI/SETUP + def I2Cstop(self): + """Stop an I2C transaction.""" + self.writecmd(0x02,0x21,0,self.data); #SPI/SETUP + def I2Cread(self,len=1): + """Read len bytes by I2C.""" + self.writecmd(0x02,0x00,1,[len]); #SPI/SETUP + return self.data; + def I2Cwrite(self,bytes): + """Write bytes by I2C.""" + self.writecmd(0x02,0x01,len(bytes),bytes); #SPI/SETUP + return ord(self.data[0]); def CCsetup(self): """Move the FET into the CC2430/CC2530 application.""" #print "Initializing Chipcon."; diff --git a/client/Makefile b/client/Makefile index bf3fb10..27933cb 100644 --- a/client/Makefile +++ b/client/Makefile @@ -2,6 +2,7 @@ link: rm -f /usr/local/bin/goodfet.* + rm -rf *~ ln -s `pwd`/goodfet.* /usr/local/bin/ install: #Try 'make link' instead. diff --git a/client/goodfet.i2crom b/client/goodfet.i2crom new file mode 100644 index 0000000..d504f02 --- /dev/null +++ b/client/goodfet.i2crom @@ -0,0 +1,158 @@ +#!/usr/bin/env python + +#GoodFET I2C EEPROM Client +#by Travis Goodspeed + +import sys; +import binascii; +import array; + +from GoodFET import GoodFET; +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.hex [0x$start 0x$stop]" % sys.argv[0]; + print "%s erase" % sys.argv[0]; + print "%s write $foo.hex [0x$start 0x$stop]" % sys.argv[0]; + print "%s verify $foo.hex [0x$start 0x$stop]" % sys.argv[0]; + print "%s peek 0x$start [0x$stop]" % sys.argv[0]; + print "%s poke 0x$adr 0x$val" % sys.argv[0]; + sys.exit(); + +#Initailize FET and set baud rate +client=GoodFET(); +client.serInit() + + +client.I2Csetup(); + +#Dummy read. +#Might read as all ones if chip has a startup delay. +#client.SPIjedec(); + +if(sys.argv[1]=="foo"): + client.I2Cstart(); + + # Write AA55 at 0x00 + #print "%i" % client.I2Cwrite([0xA0, 0x00, 0x00, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55]); + client.I2Cstop(); + + client.I2Cstart(); + print "%i" % client.I2Cwrite([0xA0, 0x00, 0x00]); # Set ADR=0x00 + client.I2Cstart();#restart + print "%i" % client.I2Cwrite([0xA1]); # Set ADR=0x00 + data=client.I2Cread(128); + s=""; + for d in data: + s+="%02x " % ord(d); + print s + client.I2Cstop(); + + +if(sys.argv[1]=="test"): + result=""; + dropped=0; + for i in range(40): + data=client.SPIjedec(); + if ord(data[1])==0xFF: + result+="-"; + dropped=dropped+1; + else: + result+="+"; + print "Connection Test: (- is bad)\n%s" % result; + print "%i misreads" % dropped; + if(dropped==40): + print "No successful reads. Is the chip wired correctly?"; + elif(dropped>0): + print "Some success, some failures. Is a wire loose?"; + else: + print "All reads succeeded. Wiring is probably good."; + +if(sys.argv[1]=="info"): + data=client.SPIjedec(); + print "Ident as %s\nManufacturer: %02x %s\nType: %02x\nCapacity: %02x" % ( + client.SPIjedecstr(), + ord(data[1]),client.SPIjedecmanstr(), + ord(data[2]), + ord(data[3])); + +if(sys.argv[1]=="dump"): + f = sys.argv[2]; + start=0x0000; + stop=0x100000; #TODO, adjust this by the JEDEC size parameter. + 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.SPIpeekblock(i); + if(i%0x1000==0): + print "Dumped %06x."%i; + for j in data: + file.write(j); + i+=1; + file.close() +if(sys.argv[1]=="flash"): + f = sys.argv[2]; + start=0x0000; + stop=0x100000; #TODO, adjust this by the JEDEC size parameter. + if(len(sys.argv)>3): + start=int(sys.argv[3],16); + if(len(sys.argv)>4): + stop=int(sys.argv[4],16); + + print "Flashing code from %06x to %06x with %s." % (start,stop,f); + file = open(f, mode='rb') + + i=start; + chars=list(file.read()); + chunksize=0x80; + + while i<=stop: + bytes=range(0,chunksize); + for j in range(0,chunksize): + bytes[j]=ord(chars[i+j]); + #client.SPIpokebyte(i,ord(chars[i])); + client.SPIpokebytes(i,bytes); + + i+=chunksize; + if(i%0x100==0): + print "Flashed %06x."%i; + file.close() + + +if(sys.argv[1]=="erase"): + client.SPIchiperase(); + +if(sys.argv[1]=="peek"): + start=0x0000; + if(len(sys.argv)>2): + start=int(sys.argv[2],16); + stop=start; + if(len(sys.argv)>3): + stop=int(sys.argv[3],16); + print "Peeking from %06x to %06x." % (start,stop); + while start<=stop: + print "%06x: %02x" % (start,client.SPIpeek(start)); + start=start+1; + +if(sys.argv[1]=="poke"): + start=0x0000; + val=0x00; + if(len(sys.argv)>2): + start=int(sys.argv[2],16); + if(len(sys.argv)>3): + val=int(sys.argv[3],16); + print "Poking %06x to become %02x." % (start,val); + + while client.SPIpeek(start)!=val: + client.SPIpokebyte(start,val); + print "Poked to %02x" % client.SPIpeek(start); + diff --git a/firmware/apps/i2c/i2c.c b/firmware/apps/i2c/i2c.c index 1f92b9e..1171ee1 100644 --- a/firmware/apps/i2c/i2c.c +++ b/firmware/apps/i2c/i2c.c @@ -15,21 +15,21 @@ //Pins and I/O -#define SS BIT3 -#define SDA BIT2 -#define SCL BIT3 +#include +#define SDA TDI +#define SCL TDO -#define I2CDELAY(x) delay(x) +#define I2CDELAY(x) delay(x<<4) -//Bits are cleared by output of low. -//Bits are set but input and pull-up resistor. -#define SETSDA P5DIR&=~SDA -#define CLRSDA P5DIR|=SDA -#define SETSCL P5DIR&=~SCL -#define CLRSCL P5DIR|=SCL + +//2xx only, need 1xx compat code +#define CLRSDA P5OUT&=~SDA +#define SETSDA P5OUT|=SDA +#define CLRSCL P5OUT&=~SCL +#define SETSCL P5OUT|=SCL #define READSDA (P5IN&SDA?1:0) -#define SETBOTH P5DIR&=~(SDA|SCL) +#define SETBOTH P5OUT|=(SDA|SCL) #define I2C_DATA_HI() SETSDA #define I2C_DATA_LO() CLRSDA @@ -37,6 +37,25 @@ #define I2C_CLOCK_HI() SETSCL #define I2C_CLOCK_LO() CLRSCL +#warning "Using internal resistors. Won't work on 161x devices." + +//! Inits bitbanging port, must be called before using the functions below +void I2C_Init() +{ + + //Clear SDA and SCL. + //Direction, not value, is used to set the value. + //(Pull-up or 0.) + P5DIR|=(SDA|SCL); + P5REN|=SDA|SCL; + + + I2C_CLOCK_HI(); + I2C_DATA_HI(); + + I2CDELAY(1); +} + //! Write an I2C bit. void I2C_WriteBit( unsigned char c ) { @@ -64,7 +83,7 @@ unsigned char I2C_ReadBit() I2C_CLOCK_HI(); I2CDELAY(1); - + unsigned char c = READSDA; I2C_CLOCK_LO(); @@ -73,19 +92,6 @@ unsigned char I2C_ReadBit() return c; } -//! Inits bitbanging port, must be called before using the functions below -void I2C_Init() -{ - //Clear SDA and SCL. - //Direction, not value, is used to set the value. - //(Pull-up or 0.) - P5OUT&=~(SDA|SCL); - - I2C_CLOCK_HI(); - I2C_DATA_HI(); - - I2CDELAY(1); -} //! Send a START Condition void I2C_Start() @@ -116,7 +122,7 @@ unsigned char I2C_Write( unsigned char c ) { char i; for (i=0;i<8;i++){ - I2C_WriteBit( c & 128 ); + I2C_WriteBit( c & 0x80 ); c<<=1; } @@ -161,22 +167,25 @@ void i2chandle(unsigned char app, case READ: if(len>0) //optional parameter of length len=cmddata[0]; - if(len==0) //default value of 1 + if(!len) //default value of 1 len=1; for(i=0;i