Hi Folks,
I'm trying to figure out how to use the I2C module in the 27F chip and I think I almost have it working but I'm having a problem. If I just write one byte to the external eeprom it will work just as advertised. But if I wrap a For () loop around it it won't work.. It gets hung up waiting for the Stop condition.
I've based my code on this post from 5 years ago: e2e.ti.com/.../416428
It works fine if I just do this:
i2cStatus = i2cWriteByte(halHandle->i2cHandle, addr, data); eepromReadData = i2cReadByte(halHandle->i2cHandle, addr);
It only will work if I set a breakpoint and only execute a Write OR a Read. If I let it run at speed it will hang.
Here's my write function:
char i2cWriteByte(I2C_Handle i2cHandle, uint_least8_t addr, char data) { I2C_Obj *i2c = (I2C_Obj *)i2cHandle; // i2c->I2CMDR &= I2C_I2CMDR_IRS_BIT; // reset I2C // Make sure I2C is not busy and has stopped while (i2c->I2CSTR & I2C_I2CSTR_BB_BITS); // Check for Bus Busy i2c->I2CSTR &= I2C_I2CSTR_SCD_BITS; // Clear the SCD bit (stop condition bit) while(i2c->I2CMDR &= I2C_I2CMDR_STP_BIT); // stop bit loop i2c->I2CSAR = 0x50; // I2C slave address while (i2c->I2CSTR & I2C_I2CSTR_BB_BITS); // still busy? i2c->I2CCNT = 2; // assume register address = 1 byte, and data is 1 byte i2c->I2CMDR = 0x6E20; // start, stop, no rm, reset i2c 01101110 00100000 // I2caRegs.I2CMDR.bit.NACKMOD = 0; // NACK mode bit // I2caRegs.I2CMDR.bit.FREE = 1; // Run free I2C when suspended // I2caRegs.I2CMDR.bit.STT = 1; // START condition bit // // bit 12 reserved don't care // I2caRegs.I2CMDR.bit.STP = 1; // STOP condition bit // I2caRegs.I2CMDR.bit.MST = 1; // Master mode // I2caRegs.I2CMDR.bit.TRX = 1; // Transmitter mode // I2caRegs.I2CMDR.bit.XA = 0; // 7-bit addressing mode // I2caRegs.I2CMDR.bit.RM = 0; // Nonrepeat mode // I2caRegs.I2CMDR.bit.DLB = 0; // Digital loopback mode is disabled // I2caRegs.I2CMDR.bit.IRS = 1; // The I2C module is enabled // I2caRegs.I2CMDR.bit.STB = 0; // The I2C module is not in the START byte mode // I2caRegs.I2CMDR.bit.FDF = 0; // Free data format mode is disabled // I2caRegs.I2CMDR.bit.BC = 000; // 8 bits per data byte i2c->I2CDXR = addr; // data to be sent (1 byte) while ( !(i2c->I2CSTR & (I2C_I2CSTR_XRDY_BITS|I2C_I2CSTR_ARDY_BITS)) ); i2c->I2CDXR = data; // data to be sent (1 byte) i2c->I2CMDR |= I2C_I2CMDR_STP_BIT; // stop bit when CNT=0 while(!(i2c->I2CSTR &= I2C_I2CSTR_SCD_BITS));// wait for STOP condition return I2C_SUCCESS; } Here's the Read function:
char i2cReadByte(I2C_Handle i2cHandle, uint_least8_t addr) { I2C_Obj *i2c = (I2C_Obj *)i2cHandle; uint16_t tempdata; uint_least16_t i2cReadStatus; i2c->I2CMDR &= I2C_I2CMDR_IRS_BIT; // Make sure I2C is not busy and has stopped while (i2c->I2CSTR & I2C_I2CSTR_BB_BITS); // Check for Bus Busy i2c->I2CSTR &= I2C_I2CSTR_SCD_BITS; // Clear the SCD bit (stop condition bit) while(i2c->I2CMDR &= I2C_I2CMDR_STP_BIT); // stop bit loop i2c->I2CSAR = 0x50; // I2C slave address while (i2c->I2CSTR & I2C_I2CSTR_BB_BITS); // still busy? i2c->I2CMDR = 0x6620; // start, no stop bit, master, tx, reset I2C 01100110 // I2caRegs.I2CMDR.bit.NACKMOD = 0; // bit 15 NACK mode bit // I2caRegs.I2CMDR.bit.FREE = 1; // bit 14 Stop I2C when suspended // I2caRegs.I2CMDR.bit.STT = 1; // bit 13 START condition bit // // bit 12 reserved = don't care // I2caRegs.I2CMDR.bit.STP = 0; // bit 11 STOP condition bit // I2caRegs.I2CMDR.bit.MST = 1; // bit 10 Master mode // I2caRegs.I2CMDR.bit.TRX = 1; // bit 9 Transmitter mode // I2caRegs.I2CMDR.bit.XA = 0; // bit 8 7-bit addressing mode // I2caRegs.I2CMDR.bit.RM = 0; // bit 7 Nonrepeat mode // I2caRegs.I2CMDR.bit.DLB = 0; // bit 6 Digital loopback mode is disabled // I2caRegs.I2CMDR.bit.IRS = 1; // bit 5 The I2C module is enabled // I2caRegs.I2CMDR.bit.STB = 0; // bit 4 The I2C module is not in the START byte mode // I2caRegs.I2CMDR.bit.FDF = 0; // bit 3 Free data format mode is disabled // I2caRegs.I2CMDR.bit.BC = 000; // bit2 2-0 8 bits per data byte i2c->I2CCNT = 1; // assume register address is one byte i2c->I2CDXR = addr; // address of the data byte while(!(i2c->I2CSTR &= I2C_I2CSTR_ARDY_BITS)); // all ready? i2c->I2CMDR = 0x6C20; // start, stop bit when CNT =0, master, rx, reset I2C 00101100 // I2caRegs.I2CMDR.bit.NACKMOD = 0; // NACK mode bit // I2caRegs.I2CMDR.bit.FREE = 1; // Stop I2C when suspended // I2caRegs.I2CMDR.bit.STT = 1; // START condition bit // // bit 12 reserved = don't care // I2caRegs.I2CMDR.bit.STP = 1; // STOP condition bit // I2caRegs.I2CMDR.bit.MST = 1; // Master mode // I2caRegs.I2CMDR.bit.TRX = 0; // Receiver mode // I2caRegs.I2CMDR.bit.XA = 0; // 7-bit addressing mode // I2caRegs.I2CMDR.bit.RM = 0; // Nonrepeat mode // I2caRegs.I2CMDR.bit.DLB = 0; // Digital loopback mode is disabled // I2caRegs.I2CMDR.bit.IRS = 1; // The I2C module is enabled // I2caRegs.I2CMDR.bit.STB = 0; // The I2C module is not in the START byte mode // I2caRegs.I2CMDR.bit.FDF = 0; // Free data format mode is disabled // I2caRegs.I2CMDR.bit.BC = 000; // 8 bits per data byte i2c->I2CCNT = 1; // only read one byte data if (i2c->I2CSTR & I2C_I2CSTR_NACK_BITS) // If a NACK occurred then SCL is held low and STP bit cleared { i2c->I2CMDR = 0; // reset I2C so SCL isn't held low return i2cReadStatus = I2C_Status_NACK; } i2c->I2CMDR |= I2C_I2CMDR_STP_BIT; // stop bit when CNT=0 while(!(i2c->I2CSTR &= I2C_I2CSTR_SCD_BITS));// stop bit detected? tempdata = i2c->I2CDRR; // read one byte data return(tempdata); }
Have I missed something that waits until something happens? It will hang at the while(!(i2c->I2CSTR &=I2C_I2cSTR_SCD_BITS)); line #68.
Any help will be greatly appreciated.
Thanks,
Richard