Hi, I have observed that my I2C bus is hanging on the 7th bit of the second byte
I saw the USCI30 errata so I tried to implement the workaround
case 8u: // Vector 8: STPIFG if (UCB1IFG & UCRXIFG) { if ((ucb1_i2c.rx_curr_len < ucb1_i2c.slave_rx->dat_len) && (ucb1_i2c.slave_rx != NULL)) { *ucb1_i2c.slave_rx->data++ = UCB1RXBUF; // Get RX'd byte into buffer ucb1_i2c.rx_curr_len++; } else { ucb1_i2c.rx_succeed = 0u; uint8_t dummyClear = UCB1RXBUF; } } if (ucb1_i2c.rx_succeed && (NULL != ucb1_i2c.stp_cb)) { (*ucb1_i2c.stp_cb)(); // vTaskNotifyGiveFromISR(decode_i2c_handler, pdFALSE); } ucb1_i2c.rx_succeed = 1u; ucb1_i2c.rx_curr_len = 0; break; case 10u: // Vector 10: RXIFG { if ((UCB1STAT & UCSCLLOW) != 0) { __delay_cycles(200); } else { UCB1IFG |= UCRXIFG; break; } if (ucb1_i2c.rx_mode == SLAVE_RECEIVE) { if ((ucb1_i2c.rx_curr_len < ucb1_i2c.slave_rx->dat_len)&& (ucb1_i2c.slave_rx != NULL)) { *ucb1_i2c.slave_rx->data++ = UCB1RXBUF; // Get RX'd byte into buffer ucb1_i2c.rx_curr_len++; } else { ucb1_i2c.rx_succeed = 0u; uint8_t dummyClear = UCB1RXBUF; } }
The above is a snippet of my I2C ISR (the STPIFG and the slave receive of the RXIFG portion)
So, from the errata, the workaround is to check that the UCSCLLOW has been set for at least 3 USCI bit clock cycle.
I am working with 12.8MHz SMCLK and 400kHz I2C clock frequency.
So, in my RX ISR handling, I am checking if UCSCLLOW is set, I will delay for 200 cycles.
I think this should be long enough since 200 cycles of 12.8MHz clock is around 15.625us and I only need 7.5us to cover 3 USCI bit clock cycle
If the UCSCLLOW is not set, I will just break and let it reenter the ISR to check again.
For the last byte received, I am expecting the UCSCLLOW to not be set. So, I will wait for the STPIFG to be triggered and read the last byte in there.
After implementing this, I get this image for my SCL line on the oscilloscope
I observed that I am still facing the same issue with I2C hanging occasionally on the 7th bit of the second byte even after implementing this.
May I ask if I am misunderstanding something regarding this errata/workaround and check if my implementation of the workaround is correct?