X-Git-Url: http://git.rot13.org/?p=goodfet;a=blobdiff_plain;f=firmware%2Fapps%2Fi2c%2Fi2c.c;h=1018c5fba8d7e28723c3105425b95bcdd5d24a73;hp=c10739778503737224a56b1419c25b51ab7edbaf;hb=f78ae2192de82239171b62eab19fa69c571ebd92;hpb=c1ef7ebcf885f8eac4fb047a376393fc7c7de196 diff --git a/firmware/apps/i2c/i2c.c b/firmware/apps/i2c/i2c.c index c107397..1018c5f 100644 --- a/firmware/apps/i2c/i2c.c +++ b/firmware/apps/i2c/i2c.c @@ -11,28 +11,59 @@ #include "platform.h" #include "command.h" +#include "i2c.h" -#include -#include -#include - +#ifndef _GNU_ASSEMBLER_ +#include +#endif //Pins and I/O #include -#define SDA TDI -#define SCL TDO + +//! Handles an i2c command. +void i2c_handle_fn( uint8_t const app, + uint8_t const verb, + uint32_t const len); + +// define the i2c app's app_t +app_t const i2c_app = { + + /* app number */ + I2C_APP, + + /* handle fn */ + i2c_handle_fn, + + /* name */ + "I2C", + + /* desc */ + "\tThe I2C app implements the i2c bus protocol thus\n" + "\tturning your GoodFET into a USB-to-i2c adapter.\n" +}; #define I2CDELAY(x) delay(x<<4) //2xx only, need 1xx compat code -#define CLRSDA P5OUT&=~SDA -#define SETSDA P5OUT|=SDA -#define CLRSCL P5OUT&=~SCL -#define SETSCL P5OUT|=SCL +#define SDA TDI +#define SCL TDO + +#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) + +#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 @@ -48,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 ) { @@ -74,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); @@ -114,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); @@ -130,7 +201,7 @@ unsigned char I2C_Write( unsigned char c ) c<<=1; } - return I2C_ReadBit(); + return I2C_ReadBit_Wait(); } @@ -155,45 +226,64 @@ unsigned char I2C_Read( unsigned char ack ) return res; } - -//! Handles a monitor command. -void i2chandle(unsigned char app, - unsigned char verb, - unsigned long 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) //default value of 1 - len=1; - for(i=0;i 0) //optional parameter of length + l=cmddata[0]; + if(!l) //default value of 1 + l=1; + I2C_Start(); + for(i=0; i < l; i++) + cmddata[i]=I2C_Read(i