I am struggling right now with an intermittent failure on the 28035 I2C bus. The system will randomly hang during the check of the BB bit, and this is never cleared once asserted. The code is polled, and admittedly brute force, but is a first stab at understanding the I2C peripheral. I have not been able to find a reproducible set of events that re-creates the issue reliably so grabbing a scope capture has evaded me. The 28035 is the only master on the bus with 2 slave devices.
Code:
void Write7SegDisplayMem(uint8_t *buf_ptr, uint16_t length)
{
uint16_t i;
// Wait until the STP bit is clear from any prior communications
while(I2caRegs.I2CMDR.bit.STP == 1);
// Setup slave address
I2caRegs.I2CSAR = SEVEN_SEG_ADDR;
// Check if the bus is busy
while(I2caRegs.I2CSTR.bit.BB == 1);
// Make sure we are a transmitter
I2caRegs.I2CMDR.bit.TRX = 1;
// FREE, STT, MST, TRX, RM, IRS
I2caRegs.I2CMDR.all = 0x66A0;
// Now insert bytes as required
while((I2caRegs.I2CSTR.bit.XRDY == 0) || (I2caRegs.I2CSTR.bit.ARDY == 0));
I2caRegs.I2CDXR = 0x00; // Start at beginning of display memory
if(I2caRegs.I2CSTR.bit.NACK == 1)
{
I2caRegs.I2CSTR.bit.NACK = 1;
}
// Now the display buffer
for(i = 0; i < length; i++)
{
while((I2caRegs.I2CSTR.bit.XRDY == 0) || (I2caRegs.I2CSTR.bit.ARDY == 0));
I2caRegs.I2CDXR = ((*(buf_ptr + i)) & 0x00FF);
if(I2caRegs.I2CSTR.bit.NACK == 1)
{
I2caRegs.I2CSTR.bit.NACK = 1;
}
}
// Clear NACK if received
while(I2caRegs.I2CSTR.bit.NACK == 1)
{
I2caRegs.I2CSTR.bit.NACK = 1;
}
// FREE, STP, MST, TRX, RM, IRS
I2caRegs.I2CMDR.all = 0x4EA0;
// Wait for the STOP to be issued
while(I2caRegs.I2CSTR.bit.SCD != 1);
// And clear it
I2caRegs.I2CSTR.bit.SCD = 1;
}
Basically, I check for STP being cleared and pass that check, but then hang on the check for BB. From the documentation it seems like the STP being issued (and cleared by the hardware) should allow the BB to clear, but that doesn't seem to be happening. Since I wrote this polled, it hangs my code. My first thought is to add a timeout and if I hang on that line for too long, to reset the I2C device. I'm still perplexed as to what is going on though.
I have found similar posts on this issue in the past, but none were ever answered. See here:
https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/164613
https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/47556
https://e2e.ti.com/support/microcontrollers/c2000/f/171/t/162457
Any guidance greatly appreciated.
Thanks,
Mike