Getting closer to an I2C Python client.
authortravisutk <travisutk@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Tue, 1 Sep 2009 22:19:32 +0000 (22:19 +0000)
committertravisutk <travisutk@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Tue, 1 Sep 2009 22:19:32 +0000 (22:19 +0000)
All sorts of resistor headaches.

git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@105 12e2690d-a6be-4b82-a7b7-67c4a43b65c8

client/GoodFET.py
client/Makefile
client/goodfet.i2crom [new file with mode: 0644]
firmware/apps/i2c/i2c.c
firmware/apps/jtag/jtag.c
firmware/goodfet.c
firmware/include/apps.h
firmware/include/platform.h

index 297111e..3a192fc 100755 (executable)
@@ -18,8 +18,9 @@ class GoodFET:
         """Open the serial port"""
         
         if port is None:
         """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:
         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 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."""
         
     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);
 
         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.";
     def CCsetup(self):
         """Move the FET into the CC2430/CC2530 application."""
         #print "Initializing Chipcon.";
index bf3fb10..27933cb 100644 (file)
@@ -2,6 +2,7 @@
 
 link:
        rm -f /usr/local/bin/goodfet.*
 
 link:
        rm -f /usr/local/bin/goodfet.*
+       rm -rf *~
        ln -s `pwd`/goodfet.* /usr/local/bin/
 install:
        #Try 'make link' instead.
        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 (file)
index 0000000..d504f02
--- /dev/null
@@ -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);
+
index 1f92b9e..1171ee1 100644 (file)
 
 
 //Pins and I/O
 
 
 //Pins and I/O
-#define SS   BIT3
-#define SDA  BIT2
-#define SCL  BIT3
+#include <jtag.h>
+#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 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
 
 #define I2C_DATA_HI() SETSDA
 #define I2C_DATA_LO() CLRSDA
 #define I2C_CLOCK_HI() SETSCL
 #define I2C_CLOCK_LO() CLRSCL
 
 #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 )
 {
 //! Write an I2C bit.
 void I2C_WriteBit( unsigned char c )
 {
@@ -64,7 +83,7 @@ unsigned char I2C_ReadBit()
 
   I2C_CLOCK_HI();
   I2CDELAY(1);
 
   I2C_CLOCK_HI();
   I2CDELAY(1);
-
+  
   unsigned char c = READSDA;
 
   I2C_CLOCK_LO();
   unsigned char c = READSDA;
 
   I2C_CLOCK_LO();
@@ -73,19 +92,6 @@ unsigned char I2C_ReadBit()
   return c;
 }
 
   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()
 
 //! 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++){
 {
   char i;
   for (i=0;i<8;i++){
-    I2C_WriteBit( c & 128 );
+    I2C_WriteBit( c & 0x80 );
     c<<=1;
   }
   
     c<<=1;
   }
   
@@ -161,22 +167,25 @@ void i2chandle(unsigned char app,
   case READ:
     if(len>0)          //optional parameter of length
       len=cmddata[0];
   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<len;i++)
       cmddata[i]=I2C_Read(1);  //Always acknowledge
     txdata(app,verb,len);
     break;
   case WRITE:
       len=1;
     for(i=0;i<len;i++)
       cmddata[i]=I2C_Read(1);  //Always acknowledge
     txdata(app,verb,len);
     break;
   case WRITE:
+    cmddata[0]=0;
     for(i=0;i<len;i++)
     for(i=0;i<len;i++)
-      I2C_Write(cmddata[i]);
-    txdata(app,verb,0);
+      cmddata[0]+=I2C_Write(cmddata[i]);
+    txdata(app,verb,1);
     break;
   case START:
     I2C_Start();
     break;
   case START:
     I2C_Start();
+    txdata(app,verb,0);
     break;
   case STOP:
     I2C_Stop();
     break;
   case STOP:
     I2C_Stop();
+    txdata(app,verb,0);
     break;
   case SETUP:
     I2C_Init();
     break;
   case SETUP:
     I2C_Init();
index 2b04a81..ea02b40 100644 (file)
@@ -8,8 +8,6 @@
 #include "jtag.h"
 
 
 #include "jtag.h"
 
 
-
-
 //! Set up the pins for JTAG mode.
 void jtagsetup(){
   P5DIR|=MOSI+SCK+TMS;
 //! Set up the pins for JTAG mode.
 void jtagsetup(){
   P5DIR|=MOSI+SCK+TMS;
index 8ce6108..5d01977 100644 (file)
 void init(){\r
   WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer\r
   \r
 void init(){\r
   WDTCTL = WDTPW + WDTHOLD;                 // Stop watchdog timer\r
   \r
-  //LED and TX OUT\r
+  //LED out and on.\r
   PLEDDIR |= PLEDPIN;\r
   PLEDDIR |= PLEDPIN;\r
+  PLEDOUT |= PLEDPIN;\r
   \r
   \r
+  //Setup clocks, unique to each '430.\r
   msp430_init_dco();\r
   msp430_init_uart();\r
   \r
   msp430_init_dco();\r
   msp430_init_uart();\r
   \r
-  \r
-  \r
-  \r
   //Enable Interrupts.\r
   //eint();\r
 }\r
   //Enable Interrupts.\r
   //eint();\r
 }\r
@@ -38,7 +37,7 @@ void handle(unsigned char app,
   case SPI:\r
     spihandle(app,verb,len);\r
     break;\r
   case SPI:\r
     spihandle(app,verb,len);\r
     break;\r
-  case I2C:\r
+  case I2CAPP:\r
     i2chandle(app,verb,len);\r
     break;\r
   case CHIPCON:\r
     i2chandle(app,verb,len);\r
     break;\r
   case CHIPCON:\r
index 8a8b999..48ec492 100644 (file)
@@ -2,7 +2,7 @@
 
 #define MONITOR 0x00
 #define SPI 0x01
 
 #define MONITOR 0x00
 #define SPI 0x01
-#define I2C 0x02
+#define I2CAPP 0x02
 #define JTAG 0x10
 #define JTAG430 0x11
 #define CHIPCON 0x30
 #define JTAG 0x10
 #define JTAG430 0x11
 #define CHIPCON 0x30
index b5e1fa8..e6cbcec 100644 (file)
@@ -6,12 +6,23 @@
 
 
 //Use P3 instead of P5 for target I/O on chips without P5.
 
 
 //Use P3 instead of P5 for target I/O on chips without P5.
-#ifdef __msp430x22x4
-#warning "2274, using P3 instead.  Will break 2618 and 1612 support."
+#ifndef __MSP430_HAS_PORT5__
+#ifndef __MSP430_HAS_PORT5_R__
+//#warning "No P5, using P3 instead.  Will break 2618 and 1612 support."
 #define P5OUT P3OUT
 #define P5DIR P3DIR
 #define P5REN P3REN
 #define P5IN P3IN
 #define P5OUT P3OUT
 #define P5DIR P3DIR
 #define P5REN P3REN
 #define P5IN P3IN
+
+#endif
+#endif
+
+//Use false P5REN for 1612.
+#ifdef __MSP430_HAS_PORT5__
+#ifndef __MSP430_HAS_PORT5_R__
+//#warning "1xx, using fake P5REN for external pulling resistors."
+#define P5REN P5OUT
+#endif
 #endif
 
 unsigned char serial_rx();
 #endif
 
 unsigned char serial_rx();