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