This thread has been locked.
If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.
I've been testing some I2C read/write code and come across an unexpected behavior. On my I2C bus I have a single slave at address 0x28 and I can read from it rapidly and repeatable without issue.
The issue that I've come across relates to the Error flag - Bit 1 in the I2CMCS (read) register:
When I READ a single byte from the non-existent I2C slave (0x27), then the Error bit (Bit 1) is set. A successful follow up READ or WRITE from the existing slave (0x28) then clears the Error bit. This is expected behavior.
However, when I WRITE a byte to the non-existent I2C slave (0x27) and the Error bit is set, then a successful READ will not clear the bit. Only a successful WRITE will clear the bit. This essentially indicates an error for every successful READing that follows a single unsuccessful WRITE.
The only way that I've found to clear the Error-bit is by resetting the I2C peripheral with "SysCtlPeripheralReset(SYSCTL_PERIPH_I2C1);" and then reconfiguring the peripheral, or by successfully writing to an I2C slave
This behavior of the Error-bit seems out of place at least because I haven't seen anywhere that says a failed write will jam the status register. First off, is there any evidence that this behavior is expected? And secondly, besides resetting the peripheral or writing to an existing I2C slave, is there something that I can do that will allow for a successful read to clear the Error-bit?
Code Excerpts:
// --------- Setup Pins and Peripherals --------------
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_I2C1);
MAP_SysCtlPeripheralEnable(SYSCTL_PERIPH_GPIOA);
//
// Enable pin PA6 for I2C1 I2C1SCL
//
MAP_GPIOPinConfigure(GPIO_PA6_I2C1SCL);
MAP_GPIOPinTypeI2CSCL(GPIO_PORTA_BASE, GPIO_PIN_6);
//
// Enable pin PA7 for I2C1 I2C1SDA
//
MAP_GPIOPinConfigure(GPIO_PA7_I2C1SDA);
MAP_GPIOPinTypeI2C(GPIO_PORTA_BASE, GPIO_PIN_7);
// Setup Master clock speed
MAP_I2CMasterInitExpClk(I2C_BUS_PORT_BASE, SysCtlClockGet(), FALSE);
// Test the Read/Write error handling
TempSimpleRead(0x27);
TempSimpleRead(0x28);
TempSimpleRead(0x27);
TempSimpleWrite(0x28);
TempSimpleWrite(0x27);
TempSimpleWrite(0x28);
TempSimpleWrite(0x27);
TempSimpleRead(0x28);
------------------------------------------
void TempSimpleRead(uint8_t bSlaveAddr)
{
uint8_t tmpRx = 0U;
MAP_I2CMasterSlaveAddrSet(I2C1_BASE, bSlaveAddr, TRUE); // set address & read
MAP_I2CMasterControl(I2C1_BASE, I2C_MASTER_CMD_SINGLE_RECEIVE); // call for read - single
// wait for read to finish
while(I2CMasterBusy(I2C1_BASE) == FALSE);
while(I2CMasterBusy(I2C1_BASE) == TRUE);
__NOP(); // Add a little delay
tmpRx = I2CMasterDataGet(I2C1_BASE);
}
void TempSimpleWrite(uint8_t bSlaveAddr)
{
uint8_t tmpRx = 0U;
MAP_I2CMasterSlaveAddrSet(I2C_BUS_PORT_BASE, bSlaveAddr, FALSE); // set address & write
MAP_I2CMasterDataPut(I2C_BUS_PORT_BASE, 0xA5);
MAP_I2CMasterControl(I2C_BUS_PORT_BASE, I2C_MASTER_CMD_SINGLE_SEND); // call for write - single
// wait for read to finish
while(I2CMasterBusy(I2C_BUS_PORT_BASE) == FALSE);
while(I2CMasterBusy(I2C_BUS_PORT_BASE) == TRUE);
}
Development Environment Context:
Okay, so this is expected from the design then. Thank you for looking into my questions, once again :-)
Cheers,
Timothy