I2C committed but not tested.
authortravisutk <travisutk@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Fri, 5 Jun 2009 19:11:45 +0000 (19:11 +0000)
committertravisutk <travisutk@12e2690d-a6be-4b82-a7b7-67c4a43b65c8>
Fri, 5 Jun 2009 19:11:45 +0000 (19:11 +0000)
I really should have brought a soldering iron and a Leatherman.

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

firmware/apps/Makefile
firmware/apps/goodfet.c
firmware/apps/i2c/i2c.c [new file with mode: 0644]
firmware/apps/spi/spi.c
firmware/include/command.h

index b3aa926..2c99c0d 100644 (file)
@@ -10,7 +10,7 @@ GCCINC=-T ../ldscripts/161x.x
 
 CC=msp430-gcc -g -mmcu=$(mcu) -DGCC $(GCCINC) -I ../include
 
-apps= monitor/monitor.c spi/spi.c
+apps= monitor/monitor.c spi/spi.c i2c/i2c.c
 libs= ../lib/msp430f1612.c ../lib/command.c
 app=goodfet
 
index 9462020..34d7d0a 100644 (file)
@@ -39,6 +39,9 @@ void handle(unsigned char app,
   case SPI:\r
     spihandle(app,verb,len);\r
     break;\r
+  case I2C:\r
+    i2chandle(app,verb,len);\r
+    break;\r
   default:\r
     txdata(app,NOK,0);\r
   }\r
@@ -61,6 +64,7 @@ int main(void)
     app=serial_rx();\r
     verb=serial_rx();\r
     len=serial_rx();\r
+    \r
     //Read data, if any\r
     for(i=0;i<len;i++){\r
       cmddata[i]=serial_rx();\r
diff --git a/firmware/apps/i2c/i2c.c b/firmware/apps/i2c/i2c.c
new file mode 100644 (file)
index 0000000..1f92b9e
--- /dev/null
@@ -0,0 +1,186 @@
+//GoodFET I2C Master Application
+//Handles basic I/O
+
+//Higher level left to client application.
+
+//Based upon a neighborly example at
+//http://codinglab.blogspot.com/2008/10/i2c-on-avr-using-bit-banging.html
+
+#include "platform.h"
+#include "command.h"
+
+#include <signal.h>
+#include <io.h>
+#include <iomacros.h>
+
+
+//Pins and I/O
+#define SS   BIT3
+#define SDA  BIT2
+#define SCL  BIT3
+
+#define I2CDELAY(x) delay(x)
+
+//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
+
+#define READSDA (P5IN&SDA?1:0)
+#define SETBOTH P5DIR&=~(SDA|SCL)
+
+#define I2C_DATA_HI() SETSDA
+#define I2C_DATA_LO() CLRSDA
+
+#define I2C_CLOCK_HI() SETSCL
+#define I2C_CLOCK_LO() CLRSCL
+
+//! Write an I2C bit.
+void I2C_WriteBit( unsigned char c )
+{
+  if(c>0)
+    I2C_DATA_HI();
+  else
+    I2C_DATA_LO();
+
+  I2C_CLOCK_HI();
+  I2CDELAY(1);
+
+  I2C_CLOCK_LO();
+  I2CDELAY(1);
+
+  if(c>0)
+    I2C_DATA_LO();
+
+  I2CDELAY(1);
+}
+
+//! Read an I2C bit.
+unsigned char I2C_ReadBit()
+{
+  I2C_DATA_HI();
+
+  I2C_CLOCK_HI();
+  I2CDELAY(1);
+
+  unsigned char c = READSDA;
+
+  I2C_CLOCK_LO();
+  I2CDELAY(1);
+
+  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()
+{
+  // set both to high at the same time
+  SETBOTH;
+  I2CDELAY(1);
+  
+  I2C_DATA_LO();
+  I2CDELAY(1);
+  
+  I2C_CLOCK_LO();
+  I2CDELAY(1);
+}
+
+//! Send a STOP Condition
+void I2C_Stop()
+{
+  I2C_CLOCK_HI();
+  I2CDELAY(1);
+
+  I2C_DATA_HI();
+  I2CDELAY(1);
+}
+
+//! write a byte to the I2C slave device
+unsigned char I2C_Write( unsigned char c )
+{
+  char i;
+  for (i=0;i<8;i++){
+    I2C_WriteBit( c & 128 );
+    c<<=1;
+  }
+  
+  return I2C_ReadBit();
+}
+
+
+//! read a byte from the I2C slave device
+unsigned char I2C_Read( unsigned char ack )
+{
+  unsigned char res = 0;
+  char i;
+  
+  for (i=0;i<8;i++){
+    res <<= 1;
+    res |= I2C_ReadBit();  
+  }
+  
+  if( ack > 0)
+    I2C_WriteBit(0);
+  else
+    I2C_WriteBit(1);
+  
+  I2CDELAY(1);
+  
+  return res;
+}
+
+
+//! Handles a monitor command.
+void i2chandle(unsigned char app,
+              unsigned char verb,
+              unsigned char len){
+  unsigned char i;
+  switch(verb){
+    
+  case PEEK:
+    break;
+  case POKE:
+    break;
+    
+  case READ:
+    if(len>0)          //optional parameter of length
+      len=cmddata[0];
+    if(len==0)         //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:
+    for(i=0;i<len;i++)
+      I2C_Write(cmddata[i]);
+    txdata(app,verb,0);
+    break;
+  case START:
+    I2C_Start();
+    break;
+  case STOP:
+    I2C_Stop();
+    break;
+  case SETUP:
+    I2C_Init();
+    txdata(app,verb,0);
+    break;
+  }
+}
index 5e76205..e6fb370 100644 (file)
@@ -78,8 +78,8 @@ void spihandle(unsigned char app,
     P5OUT&=~SS; //Drop !SS to begin transaction.
     for(i=0;i<len;i++)
       cmddata[i]=spitrans8(cmddata[i]);
-    txdata(app,verb,len);
     P5OUT|=SS;  //Raise !SS to end transaction.
+    txdata(app,verb,len);
     break;
   case SETUP:
     spisetup();
index 2df7778..f91eded 100644 (file)
@@ -11,6 +11,8 @@ extern unsigned char cmddata[256];
 #define PEEK  0x02
 #define POKE  0x03
 #define SETUP 0x10
+#define START 0x20
+#define STOP  0x21
 #define NOK   0x7E
 #define OK    0x7F