I2C master app and client. Impressively ugly. Might work occasionally.
authorasmig <asmig@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Mon, 18 Feb 2013 02:55:02 +0000 (02:55 +0000)
committerasmig <asmig@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Mon, 18 Feb 2013 02:55:02 +0000 (02:55 +0000)
git-svn-id: https://svn.code.sf.net/p/goodfet/code/trunk@1503 12e2690d-a6be-4b82-a7b7-67c4a43b65c8

client/GoodFETI2C.py [new file with mode: 0644]
client/goodfet.i2ceeprom [new file with mode: 0755]
firmware/apps/i2c/i2c.c

diff --git a/client/GoodFETI2C.py b/client/GoodFETI2C.py
new file mode 100644 (file)
index 0000000..614be83
--- /dev/null
@@ -0,0 +1,32 @@
+#!/usr/bin/env python
+# GoodFET I2C and I2Ceeprom Client Library
+# 
+# Pre-alpha.  You've been warned!
+
+#import sys, time, string, cStringIO, struct, glob, serial, os
+
+from GoodFET import GoodFET
+
+class GoodFETI2C(GoodFET):
+    def I2Csetup(self):
+        """Move the FET into the I2C application."""
+        self.writecmd(0x02,0x10)
+        
+    def I2Cstart(self):
+       """Produce Start condition on I2C bus"""
+        self.writecmd(0x02,0x20)
+    def I2Cstop(self):
+       """Produce Stop condition on I2C bus"""
+        self.writecmd(0x02,0x21)
+    def I2Cread(self,count=1):
+        """Read data from I2C."""
+        self.writecmd(0x02,0x00,1,[count])
+    def I2Cwritebytes(self,data):
+       """Write multiple bytes to I2C."""
+        self.writecmd(0x02,0x01,len(data),data)
+    def I2Cwritebyte(self,val):
+       """Write a single byte to I2C."""
+        self.I2Cwritebytes([val])
+    def I2Ctrans(self,readcount,data):
+       """Use PEEK to do a multi-start transaction"""
+       return self.writecmd(0x02,0x02,len(data)+1,[readcount]+data)
diff --git a/client/goodfet.i2ceeprom b/client/goodfet.i2ceeprom
new file mode 100755 (executable)
index 0000000..10f0326
--- /dev/null
@@ -0,0 +1,75 @@
+#!/usr/bin/env python
+
+#GoodFET I2C eeprom Client
+
+import re
+import sys
+import binascii
+import array
+from GoodFETI2C import GoodFETI2C
+#from intelhex import IntelHex
+
+if(len(sys.argv)==1):
+    print "Usage: %s verb [objects]\n" % sys.argv[0]
+    print "%s dump 0x$target $filename.bin [0x$start [0x$length]]" % sys.argv[0]
+    print "%s read 0x$target [0x$start [0x$length]]" % sys.argv[0]
+    print "%s write 0x$target 0x$adr 0x$val [0x...]" % sys.argv[0]
+    sys.exit()
+
+#Initialize FET and set baud rate
+client=GoodFETI2C()
+#client.verbose=True
+client.serInit()
+client.I2Csetup()
+
+control_chars = ''.join(map(chr, range(0,32) + range(127,256)))
+control_char_re = re.compile('[%s]' % re.escape(control_chars))
+
+def dotnpc(s):
+    """Replace non-printing-characters with dots"""
+    return control_char_re.sub('.', s)
+
+def xxd(data):
+    for offset in range(0, len(data), 16):
+       line = data[offset:offset+16]
+       hex = binascii.hexlify(line)
+       print "%07x: %4s %4s %4s %4s %4s %4s %4s %4s  %s" %tuple([offset] + [hex[s:s+4] for s in range(0,32,4)] + [dotnpc(line)])
+
+if(sys.argv[1]=="dump"):
+    devadr = int(sys.argv[2],16)
+    f = sys.argv[3]
+    start=0x00
+    count=0x100
+    if(len(sys.argv)>4):
+        start=int(sys.argv[4],16)
+    if(len(sys.argv)>5):
+        count=int(sys.argv[5],16)
+    
+    print "Dumping %i bytes from device 0x%02x starting at 0x%02x to file: %s." % (count,devadr,start,f)
+    file = open(f, mode='wb')
+    data=client.I2Ctrans(count, [devadr, start])
+    print "Dumped %i bytes."%len(data)
+    file.write(data)
+    file.close()
+
+if(sys.argv[1]=="read"):
+    devadr = int(sys.argv[2],16)
+    start=0x00
+    if(len(sys.argv)>3):
+        start=int(sys.argv[3],16)
+    count=1
+    if(len(sys.argv)>4):
+        count=int(sys.argv[4],16)
+    print "Reading %i bytes from device 0x%02x starting at 0x%02x." % (count,devadr,start)
+    data=client.I2Ctrans(count, [devadr, start])
+    if(data):
+       xxd(data)
+    else:
+       print "No data received"
+
+if(sys.argv[1]=="write"):
+    if(len(sys.argv)>2):
+        data=[int(x,16) for x in sys.argv[2:]]
+    for i,byte in enumerate(data):
+        print "0x%02x: 0x%02x" % (i,byte)
+    client.I2Cwritebytes(data)
index e58b266..1018c5f 100644 (file)
 #include "command.h"
 #include "i2c.h"
 
 #include "command.h"
 #include "i2c.h"
 
-#include <signal.h>
+#ifndef _GNU_ASSEMBLER_
 #include <msp430.h>
 #include <msp430.h>
-#include <iomacros.h>
-
+#endif
 
 //Pins and I/O
 #include <jtag.h>
 
 //Pins and I/O
 #include <jtag.h>
@@ -47,37 +46,24 @@ app_t const i2c_app = {
 
 
 //2xx only, need 1xx compat code
 
 
 //2xx only, need 1xx compat code
-#if (board == tilaunchpad)
-// P3.1 SDA
-// P3.3 SCL
-#define SDA (1<<1)
-#define SCL (1<<3)
-
-#define CLRSDA P3OUT&=~SDA
-#define SETSDA P3OUT|=SDA
-#define CLRSCL P3OUT&=~SCL
-#define SETSCL P3OUT|=SCL
-
-#define READSDA (P3IN&SDA?1:0)
-#define SDAINPUT P3DIR&=~SDA
-#define SDAOUTPUT P3DIR|=SDA
-#define SCLINPUT P3DIR&=~SCL
-#define SCLOUTPUT P3DIR|=SCL
-#define SETBOTH P3OUT|=(SDA|SCL)
-
-#else
-
 #define SDA TDI
 #define SCL TDO
 
 #define SDA TDI
 #define SCL TDO
 
-#define CLRSDA P5OUT&=~SDA
-#define SETSDA P5OUT|=SDA
-#define CLRSCL P5OUT&=~SCL
-#define SETSCL P5OUT|=SCL
+#define SDAINPUT SPIDIR&=~SDA
+#define SDAOUTPUT SPIDIR|=SDA
+#define SCLINPUT SPIDIR&=~SCL
+#define SCLOUTPUT SPIDIR|=SCL
 
 
-#define READSDA (P5IN&SDA?1:0)
-#define SETBOTH P5OUT|=(SDA|SCL)
-#endif
+#define PULLON SPIREN|=(SDA|SCL)
+#define PULLOFF SPIREN&=~(SDA|SCL)
+
+#define CLRSDA SPIOUT&=~SDA
+#define SETSDA SPIOUT|=SDA
+#define CLRSCL SPIOUT&=~SCL
+#define SETSCL SPIOUT|=SCL
+
+#define READSDA (SPIIN&SDA?1:0)
+#define SETBOTH SPIOUT|=(SDA|SCL)
 
 #define I2C_DATA_HI() SETSDA
 #define I2C_DATA_LO() CLRSDA
 
 #define I2C_DATA_HI() SETSDA
 #define I2C_DATA_LO() CLRSDA
@@ -93,30 +79,24 @@ void I2C_Init()
   
   //Clear SDA and SCL.
   //Direction, not value, is used to set the value.
   
   //Clear SDA and SCL.
   //Direction, not value, is used to set the value.
-  //(Pull-up or 0.)
   
   
-#if (platform == tilaunchpad)
-  SDAOUTPUT;
   SCLOUTPUT;
   SCLOUTPUT;
-#else
-  P5DIR|=(SDA|SCL);
-#endif
-  //P5REN|=SDA|SCL;
-  
+  SDAOUTPUT;
   
   I2C_CLOCK_HI();
   I2C_DATA_HI();
   
   I2C_CLOCK_HI();
   I2C_DATA_HI();
+  //PULLON;
 
   I2CDELAY(1);
 }
 
 
   I2CDELAY(1);
 }
 
-#if (platform == tilaunchpad)
+// This is never called...
 void I2C_Exit()
 {
   SDAINPUT;
   SCLINPUT;
 void I2C_Exit()
 {
   SDAINPUT;
   SCLINPUT;
+  PULLOFF;
 }
 }
-#endif
 
 //! Write an I2C bit.
 void I2C_WriteBit( unsigned char c )
 
 //! Write an I2C bit.
 void I2C_WriteBit( unsigned char c )
@@ -132,40 +112,68 @@ void I2C_WriteBit( unsigned char c )
   I2C_CLOCK_LO();
   I2CDELAY(1);
 
   I2C_CLOCK_LO();
   I2CDELAY(1);
 
-  if(c>0)
-    I2C_DATA_LO();
-
-  I2CDELAY(1);
+  /*if(c>0)
+   *I2C_DATA_LO();
+   *
+   *I2CDELAY(1);
+   */
 }
 
 //! Read an I2C bit.
 unsigned char I2C_ReadBit()
 {
 }
 
 //! Read an I2C bit.
 unsigned char I2C_ReadBit()
 {
-  I2C_DATA_HI();
-
-  I2C_CLOCK_HI();
   SDAINPUT;
   SDAINPUT;
-  I2CDELAY(1);
+  I2C_CLOCK_HI();
   
   unsigned char c = READSDA;
   
   unsigned char c = READSDA;
+  if(c)
+    I2C_DATA_HI();
+  else
+    I2C_DATA_LO();
 
 
-  I2C_CLOCK_LO();
-  I2CDELAY(1);
   SDAOUTPUT;
   SDAOUTPUT;
+  I2CDELAY(1);
+  I2C_CLOCK_LO();
 
   return c;
 }
 
 
   return c;
 }
 
+unsigned char I2C_ReadBit_Wait()
+{
+  SDAINPUT;
+  I2C_CLOCK_HI();
+  
+  unsigned int i = 0;
+  unsigned char c = READSDA;
+
+  while(c>0 && i<=35)
+  {
+    I2CDELAY(1);
+    c = READSDA;
+    i++;
+  }
+
+  if(c)
+    I2C_DATA_HI();
+  else
+    I2C_DATA_LO();
+
+  SDAOUTPUT;
+  I2CDELAY(1);
+  I2C_CLOCK_LO();
+
+  return c;
+}
 
 //! Send a START Condition
 void I2C_Start()
 {
   // set both to high at the same time
   SETBOTH;
 
 //! Send a START Condition
 void I2C_Start()
 {
   // set both to high at the same time
   SETBOTH;
-  I2CDELAY(1);
+  I2CDELAY(3);
   
   I2C_DATA_LO();
   
   I2C_DATA_LO();
-  I2CDELAY(1);
+  I2CDELAY(3);
   
   I2C_CLOCK_LO();
   I2CDELAY(1);
   
   I2C_CLOCK_LO();
   I2CDELAY(1);
@@ -174,8 +182,11 @@ void I2C_Start()
 //! Send a STOP Condition
 void I2C_Stop()
 {
 //! Send a STOP Condition
 void I2C_Stop()
 {
+  I2C_DATA_LO();
+  I2CDELAY(3);
+
   I2C_CLOCK_HI();
   I2C_CLOCK_HI();
-  I2CDELAY(1);
+  I2CDELAY(3);
 
   I2C_DATA_HI();
   I2CDELAY(1);
 
   I2C_DATA_HI();
   I2CDELAY(1);
@@ -190,7 +201,7 @@ unsigned char I2C_Write( unsigned char c )
     c<<=1;
   }
   
     c<<=1;
   }
   
-  return I2C_ReadBit();
+  return I2C_ReadBit_Wait();
 }
 
 
 }
 
 
@@ -215,7 +226,6 @@ unsigned char I2C_Read( unsigned char ack )
   return res;
 }
 
   return res;
 }
 
-
 //! Handles an i2c command.
 void i2c_handle_fn( uint8_t const app,
                                        uint8_t const verb,
 //! Handles an i2c command.
 void i2c_handle_fn( uint8_t const app,
                                        uint8_t const verb,
@@ -225,28 +235,44 @@ void i2c_handle_fn( uint8_t const app,
        unsigned long l;
        switch(verb)
        {
        unsigned long l;
        switch(verb)
        {
-
-       case PEEK:
-               break;
-       case POKE:
-               break;
-
        case READ:
                l = len;
                if(l > 0)                                       //optional parameter of length
                        l=cmddata[0];
                if(!l)                                          //default value of 1
                        l=1;
        case READ:
                l = len;
                if(l > 0)                                       //optional parameter of length
                        l=cmddata[0];
                if(!l)                                          //default value of 1
                        l=1;
-               for(i = 0; i < l; i++)
-                       cmddata[i]=I2C_Read(1); //Always acknowledge
+               I2C_Start();
+               for(i=0; i < l; i++)
+                       cmddata[i]=I2C_Read(i<l?1:0);
+               I2C_Stop();
                txdata(app,verb,l);
                break;
        case WRITE:
                txdata(app,verb,l);
                break;
        case WRITE:
-               cmddata[0]=0;
-               for(i=0;i<len;i++)
+               I2C_Start();
+               for(i=0; i<len; i++)
                        cmddata[0]+=I2C_Write(cmddata[i]);
                        cmddata[0]+=I2C_Write(cmddata[i]);
+               I2C_Stop();
                txdata(app,verb,1);
                break;
                txdata(app,verb,1);
                break;
+       case PEEK:
+               l = cmddata[0];
+               I2C_Start();
+               unsigned char address = cmddata[1]<<1;
+               I2C_Write(address);
+               for(i=2; i < len; i++){
+                       I2C_Write(cmddata[i]);
+               }
+               I2C_Start();
+               I2C_Write(address|1);                           // spit out the target address again and flip the read bit
+               I2CDELAY(1);    // XXX We should wait for clock to go high here XXX
+               for(i=0; i < l; i++)
+                       cmddata[i]=I2C_Read(i+1<l?1:0);         // If the next i is still less than l, then ACK
+               I2C_Stop();
+               txdata(app,verb,l);
+               break;
+       case POKE:
+               break;
+
        case START:
                I2C_Start();
                txdata(app,verb,0);
        case START:
                I2C_Start();
                txdata(app,verb,0);