X-Git-Url: http://git.rot13.org/?p=goodfet;a=blobdiff_plain;f=firmware%2Fapps%2Fi2c%2Fi2c.c;h=6e1dfdea058437b79d83b98749146d0f2bde1a17;hp=af2c7f16702af9b87b7001c7683de5c2871ec520;hb=027937b9bed208a4a79b7e9d89a7326747b52a9e;hpb=69539bb167246135b1bde3c55dca7d19bc3c7aee diff --git a/firmware/apps/i2c/i2c.c b/firmware/apps/i2c/i2c.c index af2c7f1..6e1dfde 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 @@ -47,37 +46,24 @@ app_t const i2c_app = { //2xx only, need 1xx compat code -#if (platform == 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 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 @@ -87,36 +73,35 @@ app_t const i2c_app = { //#warning "Using internal resistors. Won't work on 161x devices." -//! Inits bitbanging port, must be called before using the functions below -void I2C_Init() +// Take control of the bus +void I2C_Take() { - - //Clear SDA and SCL. - //Direction, not value, is used to set the value. - //(Pull-up or 0.) - -#if (platform == tilaunchpad) - SDAOUTPUT; - SCLOUTPUT; -#else - P5DIR|=(SDA|SCL); -#endif - //P5REN|=SDA|SCL; - - I2C_CLOCK_HI(); I2C_DATA_HI(); + SCLOUTPUT; + SDAOUTPUT; +} + +void I2C_Release() +{ + SDAINPUT; + SCLINPUT; +} +//! Inits bitbanging port, must be called before using the functions below +void I2C_Init() +{ + I2C_Take(); + //PULLON; I2CDELAY(1); } -#if (platform == tilaunchpad) +// XXX This is never called... void I2C_Exit() { - SDAINPUT; - SCLINPUT; + I2C_Release(); + PULLOFF; } -#endif //! Write an I2C bit. void I2C_WriteBit( unsigned char c ) @@ -131,41 +116,64 @@ void I2C_WriteBit( unsigned char c ) 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(); SDAINPUT; - I2CDELAY(1); + I2C_CLOCK_HI(); unsigned char c = READSDA; + if(c) + I2C_DATA_HI(); + else + I2C_DATA_LO(); + SDAOUTPUT; + I2CDELAY(1); I2C_CLOCK_LO(); I2CDELAY(1); - SDAOUTPUT; 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(); + I2CDELAY(1); + + return c?0:1; // return true on ACK (0) +} //! Send a START Condition void I2C_Start() { - // set both to high at the same time - SETBOTH; - I2CDELAY(1); + I2C_Take(); // XXX Should probably check to see if someone else is using the bus before we do this + I2CDELAY(3); I2C_DATA_LO(); - I2CDELAY(1); + I2CDELAY(3); I2C_CLOCK_LO(); I2CDELAY(1); @@ -174,11 +182,15 @@ 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); + I2C_Release(); } //! write a byte to the I2C slave device @@ -190,7 +202,7 @@ unsigned char I2C_Write( unsigned char c ) c<<=1; } - return I2C_ReadBit(); + return I2C_ReadBit_Wait(); } @@ -215,7 +227,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, @@ -225,28 +236,48 @@ 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