byte UnhangI2C(void) { int i = 0; // This will clear out a "hung" I2C device // by clocking away the low it may be asserting // on SDA PTCDD |= 3; PTCPE |= 3; PTCD |= 1; for( i = 0 ; i < 30 ; ++i ) { i2cdelay(5000); PTCD ^= 1; // if the clock is hi, raise SDA // to send a stop. i2cdelay(2500); if(PTCD & 1) PTCD |= 2; else PTCD &= ~2; } // Now make them inputs, should both be high. PTCDD &= ~3; i2cdelay(1); return PTCD & 3; }
//************************************************************************* // i2cclock //************************************************************************* void i2cclock(void) { i2cdelay(I2CDATASETTLE); //-- Minimum Clock Low Time SCL_TRIS=I2CHIGH; //-- Release clock i2cdelay(I2CCLOCKHIGH); //-- Minimum Clock High Time SCL_TRIS=I2CLOW; //-- Lower the clock i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time }
//************************************************************************* // void i2csendack(void) //************************************************************************* void i2csendack(void) { //--- Send Ack to slave except for last time --- SDA=0; SDA_TRIS=I2CLOW; //-- Send ACK i2cdelay(I2CDATASETTLE); //-- Give it time to settle i2cclock(); //-- Pulse the clock SDA_TRIS=I2CHIGH; //-- Release ACK i2cdelay(I2CDATASETTLE); //-- Gap between next byte }
//************************************************************************* // i2creadbit //************************************************************************* char i2creadbit(void) { char Data=0; i2cdelay(I2CDATASETTLE); //-- Minimum Clock Low Time SCL_TRIS=I2CHIGH; //-- Release clock i2cdelay(I2CHALFCLOCK); //-- 1/2 Minimum Clock High Time if(SDA !=0 ) Data=1; //-- READ in the data bit i2cdelay(I2CHALFCLOCK); //-- 1/2 Minimum Clock High Time SCL_TRIS=I2CLOW; //-- Lower the clock i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time return(Data); }
//************************************************************************* // i2csendbyte //************************************************************************* char i2csendbyte(char Byte) { char count; SDA=I2CLOW; SCL=I2CLOW; i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time for(count=8;count>0;count--) //-- Send 8 bits of data { if( (Byte & 0x80)== 0) //-- Get the Bit { SDA=I2CLOW; //-- Ensure Port pin is low SDA_TRIS=I2CLOW; //-- Lower pin if bit = 0 } else { SDA_TRIS=I2CHIGH; //-- Release pin if bit = 1 } Byte=Byte<<1; //-- Shift next bit into position i2cclock(); //-- Pulse the clock } SDA_TRIS=I2CHIGH; //-- Release data pin for ACK return(1); }
//************************************************************************* // I2C_Send // // Inputs: // char Address - Address to write data to // char *Data - Pointer to buffer // char Num - Number of bytes to send //************************************************************************* char I2C_Send(char Address,char *Data,char Num) { i2cstart(); //-- Send Address i2csendbyte(Address & 0xFE); //-- Lowest bit = 0 => WRITE if(!i2cgetack()) { i2cstop(); printf("DID NOT SEND INITIAL WRITE COMMAND PROPPERLY\r\n"); //i2cdelay(10000000); return(0); } while(Num--) { i2csendbyte(*Data); if(!i2cgetack()) { i2cstop(); printf("HEX: 0x%x",*Data); printf("DID NOT SEND COMMAND PROPPERLY\r\n"); //i2cdelay(10000000); return(0); } Data++; } i2cstop(); i2cdelay(100); return(1); }
//************************************************************************* // i2cstop //************************************************************************* void i2cstop(void) { //-- Generate Stop Condition -- SDA_TRIS=I2CLOW; SCL_TRIS=I2CHIGH; i2cdelay(50); SDA_TRIS=I2CHIGH; //SCL_TRIS=I2CHIGH; //SCL = I2CLOW; //i2cdelay(50); //SDA_TRIS=I2CLOW; //SDA_TRIS = I2CLOW; //SDA = I2CLOW; //i2cdelay(50); //SCL_TRIS=I2CHIGH; //i2cdelay(50); //SDA = I2CHIGH; //i2cdelay(50); //SDA_TRIS = I2CHIGH; //i2cdelay(I2CSTOPDELAY); //SDA_TRIS = I2CHIGH; //printf("STOPPING NOW\r\n"); }
char I2C_Read_Delay(char Address,char *Data, char Num, DWORD countMs) { i2cstart(); //-- Send Address i2csendbyte(Address | 0x01); //-- Lowest bit = 1 => READ if(!i2cgetack()) { i2cstop(); printf("ERROR IN SENDING READ CMD\n\r"); //i2cdelay(10000000); return(0); } i2cdelay(countMs*1000); while(Num--) { *Data=i2cgetbyte(); printf("Got the data from byte %d, it's %x\r\n", Num, *Data); Data++; if(Num > 0) { i2csendack(); } } i2cstop(); return(1); }
//************************************************************************* // i2cstart //************************************************************************* void i2cstart(void) { //-- Ensure pins are in high impedance mode -- SDA_TRIS=I2CHIGH; SCL_TRIS=I2CHIGH; SCL=I2CLOW; SDA=I2CLOW; i2cdelay(I2CSTARTDELAY); //-- Generate the start condition SDA_TRIS=I2CLOW; SDA=I2CLOW; i2cdelay(I2CSTARTDELAY); SCL_TRIS=I2CLOW; i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time }
//************************************************************************* // i2cgetack //************************************************************************* char i2cgetack(void) { SDA=I2CLOW; SCL=I2CLOW; SCL_TRIS=I2CLOW; //-- Ensure clock is low SDA_TRIS=I2CHIGH; //-- Release the Data pin so slave can ACK SCL_TRIS=I2CHIGH; //-- raise the clock pin i2cdelay(I2CHALFCLOCK); //-- wait for 1/2 the clock pulse if(SDA) //-- sample the ACK signal { return(0); //-- No ACK so return BAD } i2cdelay(I2CHALFCLOCK); //-- Else wait for rest of clock SCL_TRIS=I2CLOW; //-- Finish the clock pulse i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time return(1); }
//************************************************************************* // i2cstop //************************************************************************* void i2cstop(void) { //-- Generate Stop Condition -- SDA_TRIS=I2CLOW; SCL_TRIS=I2CHIGH; i2cdelay(I2CSTOPDELAY); SDA_TRIS=I2CHIGH; }
void pause(char sec) { int count1,count2; while(sec-- >0) { for(count1=10;count1>0;count1--) { for(count2=10;count2>0;count2--) { i2cdelay(96); } } } }
//************************************************************************* // char i2cgetbyte(void) // // Reads in a byte from the I2C Port //************************************************************************* char i2cgetbyte(void) { char count,Byte=0; SDA=I2CLOW; SCL=I2CLOW; i2cdelay(I2CCLOCKLOW); //-- Minimum Clock Low Time for(count=8;count>0;count--) //-- Read 8 bits of data { Byte=Byte <<1; SDA_TRIS=I2CHIGH; //-- Release pin so data can be recieved if(i2creadbit()) { Byte +=1; } } return(Byte); }