Hi,
According to the user guide, for master receive, if I am expecting to receive only one byte, I need to set the start bit, wait for it to be cleared, then set the stop bit.
else { ucb1_i2c.rx_mode = MASTER_RECEIVE; xSemaphoreGiveFromISR(ucb1_i2c.tx_semaphore,pdFALSE); if(NULL != i2ca_tx_callback) { (*i2ca_tx_callback)(); } i2c_set_receive_mode(USCI_B1_BASE); uint8_t UCB1STT_timeout = 0; UCB1CTL1 |= UCTXSTT; if(1u == ucb1_i2c.master_rx->dat_len) { // UCB1STT_timeout usually around 57 while((UCB1CTL1 & UCTXSTT) && (UCB1STT_timeout < 200)) { UCB1STT_timeout++; } UCB1CTL1 |= UCTXSTP; // Generate I2C stop condition } }
currently, inside my isr, after the last byte is sent in master transmit mode, I will change to master receive mode. I will then set the start bit, poll for the UCTXSTT flag, then set the stop bit for the case when 1 byte is expected to be received.
However, I did not want my code to be stuck in the isr in case there was some error on the bus and the UCTXSTT flag was not cleared. Hence, I added a timeout counter to limit the number of times the while loop will occur.
Previously I checked that the loop usually happens around 57 times hence I used a timeout count of 200. However, recently it exceeded the 200 count and caused the bus to hang when I set the stop bit before the start bit was cleared.
Firstly, I would like to ask, other than polling for the UCTXSTT flag in the isr, is there other alternative way to handle the case of receiving one byte in master receive mode?
If the UCTXSTT flag was not cleared after polling it a certain number of times, how can I safely stop the transaction without causing the bus to hang?
Thanks
Kelvin