X-Git-Url: http://git.rot13.org/?p=goodfet;a=blobdiff_plain;f=firmware%2Fapps%2Fi2c%2Fi2c.c;h=1018c5fba8d7e28723c3105425b95bcdd5d24a73;hp=85677dfbdb29ec4f64cabb450087720c0b79cac1;hb=f78ae2192de82239171b62eab19fa69c571ebd92;hpb=5fb0341d348e101b30794945a6c91546e25e8e7b diff --git a/firmware/apps/i2c/i2c.c b/firmware/apps/i2c/i2c.c index 85677df..1018c5f 100644 --- a/firmware/apps/i2c/i2c.c +++ b/firmware/apps/i2c/i2c.c @@ -13,10 +13,9 @@ #include "command.h" #include "i2c.h" -#include -#include -#include - +#ifndef _GNU_ASSEMBLER_ +#include +#endif //Pins and I/O #include @@ -30,7 +29,7 @@ void i2c_handle_fn( uint8_t const app, app_t const i2c_app = { /* app number */ - I2C, + I2C_APP, /* handle fn */ i2c_handle_fn, @@ -43,20 +42,28 @@ app_t const i2c_app = { "\tturning your GoodFET into a USB-to-i2c adapter.\n" }; +#define I2CDELAY(x) delay(x<<4) + + +//2xx only, need 1xx compat code #define SDA TDI #define SCL TDO -#define I2CDELAY(x) delay(x<<4) +#define SDAINPUT SPIDIR&=~SDA +#define SDAOUTPUT SPIDIR|=SDA +#define SCLINPUT SPIDIR&=~SCL +#define SCLOUTPUT SPIDIR|=SCL +#define PULLON SPIREN|=(SDA|SCL) +#define PULLOFF SPIREN&=~(SDA|SCL) -//2xx only, need 1xx compat code -#define CLRSDA P5OUT&=~SDA -#define SETSDA P5OUT|=SDA -#define CLRSCL P5OUT&=~SCL -#define SETSCL P5OUT|=SCL +#define CLRSDA SPIOUT&=~SDA +#define SETSDA SPIOUT|=SDA +#define CLRSCL SPIOUT&=~SCL +#define SETSCL SPIOUT|=SCL -#define READSDA (P5IN&SDA?1:0) -#define SETBOTH P5OUT|=(SDA|SCL) +#define READSDA (SPIIN&SDA?1:0) +#define SETBOTH SPIOUT|=(SDA|SCL) #define I2C_DATA_HI() SETSDA #define I2C_DATA_LO() CLRSDA @@ -72,18 +79,25 @@ 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; + SCLOUTPUT; + SDAOUTPUT; I2C_CLOCK_HI(); I2C_DATA_HI(); + //PULLON; I2CDELAY(1); } +// This is never called... +void I2C_Exit() +{ + SDAINPUT; + SCLINPUT; + PULLOFF; +} + //! Write an I2C bit. void I2C_WriteBit( unsigned char c ) { @@ -98,38 +112,68 @@ void I2C_WriteBit( unsigned char c ) 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() { - I2C_DATA_HI(); - + SDAINPUT; I2C_CLOCK_HI(); - I2CDELAY(1); unsigned char c = READSDA; + if(c) + I2C_DATA_HI(); + else + I2C_DATA_LO(); - I2C_CLOCK_LO(); + SDAOUTPUT; I2CDELAY(1); + I2C_CLOCK_LO(); 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; - I2CDELAY(1); + I2CDELAY(3); I2C_DATA_LO(); - I2CDELAY(1); + I2CDELAY(3); I2C_CLOCK_LO(); I2CDELAY(1); @@ -138,8 +182,11 @@ void I2C_Start() //! Send a STOP Condition void I2C_Stop() { + I2C_DATA_LO(); + I2CDELAY(3); + I2C_CLOCK_HI(); - I2CDELAY(1); + I2CDELAY(3); I2C_DATA_HI(); I2CDELAY(1); @@ -154,7 +201,7 @@ unsigned char I2C_Write( unsigned char c ) c<<=1; } - return I2C_ReadBit(); + return I2C_ReadBit_Wait(); } @@ -179,7 +226,6 @@ unsigned char I2C_Read( unsigned char ack ) return res; } - //! Handles an i2c command. void i2c_handle_fn( uint8_t const app, uint8_t const verb, @@ -189,28 +235,44 @@ void i2c_handle_fn( uint8_t const app, 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; - 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