2 \author Travis Goodspeed
7 //Higher level left to client application.
9 //Based upon a neighborly example at
10 //http://codinglab.blogspot.com/2008/10/i2c-on-avr-using-bit-banging.html
16 #ifndef _GNU_ASSEMBLER_
23 //! Handles an i2c command.
24 void i2c_handle_fn( uint8_t const app,
28 // define the i2c app's app_t
29 app_t const i2c_app = {
41 "\tThe I2C app implements the i2c bus protocol thus\n"
42 "\tturning your GoodFET into a USB-to-i2c adapter.\n"
45 #define I2CDELAY(x) delay(x<<4)
48 //2xx only, need 1xx compat code
52 #define SDAINPUT SPIDIR&=~SDA
53 #define SDAOUTPUT SPIDIR|=SDA
54 #define SCLINPUT SPIDIR&=~SCL
55 #define SCLOUTPUT SPIDIR|=SCL
57 #define PULLON SPIREN|=(SDA|SCL)
58 #define PULLOFF SPIREN&=~(SDA|SCL)
60 #define CLRSDA SPIOUT&=~SDA
61 #define SETSDA SPIOUT|=SDA
62 #define CLRSCL SPIOUT&=~SCL
63 #define SETSCL SPIOUT|=SCL
65 #define READSDA (SPIIN&SDA?1:0)
66 #define SETBOTH SPIOUT|=(SDA|SCL)
68 #define I2C_DATA_HI() SETSDA
69 #define I2C_DATA_LO() CLRSDA
71 #define I2C_CLOCK_HI() SETSCL
72 #define I2C_CLOCK_LO() CLRSCL
74 //#warning "Using internal resistors. Won't work on 161x devices."
76 // Take control of the bus
91 //! Inits bitbanging port, must be called before using the functions below
99 // XXX This is never called...
106 //! Write an I2C bit.
107 void I2C_WriteBit( unsigned char c )
122 unsigned char I2C_ReadBit()
127 unsigned char c = READSDA;
141 unsigned char I2C_ReadBit_Wait()
147 unsigned char c = READSDA;
166 return c?0:1; // return true on ACK (0)
169 //! Send a START Condition
172 I2C_Take(); // XXX Should probably check to see if someone else is using the bus before we do this
182 //! Send a STOP Condition
196 //! write a byte to the I2C slave device
197 unsigned char I2C_Write( unsigned char c )
201 I2C_WriteBit( c & 0x80 );
205 return I2C_ReadBit_Wait();
209 //! read a byte from the I2C slave device
210 unsigned char I2C_Read( unsigned char ack )
212 unsigned char res = 0;
217 res |= I2C_ReadBit();
230 //! Handles an i2c command.
231 void i2c_handle_fn( uint8_t const app,
241 if(l > 0) //optional parameter of length
243 if(!l) //default value of 1
247 cmddata[i]=I2C_Read(i<l?1:0);
253 cmddata[0] = cmddata[0] << 1;
254 for(i=0; i<len; i++) {
255 if (!I2C_Write(cmddata[i])) //if NACK
265 unsigned char address = cmddata[1] << 1;
267 for(i=2; i < len; i++){
268 I2C_Write(cmddata[i]);
271 I2C_Write(address|1); // spit out the target address again and flip the read bit
272 I2CDELAY(1); // XXX We should wait for clock to go high here XXX
274 cmddata[i]=I2C_Read(i+1<l?1:0); // If the next i is still less than l, then ACK