Hi there,
I note my same problem is reported elsewhere on the forum for another MCU, but there is no listed solution in that thread.
I am regularly Rx two bytes over I2C in the FIFO buffer on the TM4C129X. (at a 1kHz rate I get two more bytes to read). I am using burst receive so I can let the two bytes fill up the FIFO before reading them back one after the other quickly.
The No-Acknowledge (NAK) response (bit) gets delayed by two bytes, so I have to read 4 bytes from the FIFO before a NAK is automatically generated by the TM4C129X's I2C Master for the slave to interpret.
If however I set the FIFO size to 1 with I2CMasterBurstLengthSet(i2c_base, 0x01); instead of 0x02 as per the code below, the NAK is correctly sent by the master and the slave correctly stops sending data after the second byte. The problem with using a FIFO size of 1 is that it defeats the purpose of the FIFO buffer and the second read ends up taking in the order of 25-30us instead of a small fraction of that (a few us), as the I2C Tx speed is only 400kbps. This is a waste of CPU cycles for me.
I realise that the FIFO is better suited to work with interrupts, however that is not what I am using, and I would really like to get the code working with minor changes to my existing code shown below without employing interrupts. The three functions below are called one after the other, with a suitable delay of perhaps 150-200us between the initiate_Rx() and readFirstMeasByte().
My question: How can I use the FIFO buffer with *_ FIFO_BURST_RECEIVE_* while having the TMC129X Master issue a NAK after the second byte is automatically read into the Rx FIFO ?
void initiate_Rx(uint32_t i2c_base, uint8_t addr) { I2CMasterSlaveAddrSet(i2c_base, addr, true); I2CRxFIFOConfigSet(i2c_base, (I2C_FIFO_CFG_RX_MASTER|I2C_FIFO_CFG_RX_TRIG_2)); I2CRxFIFOFlush(i2c_base); I2CMasterBurstLengthSet(i2c_base, 0x02); I2CMasterControl(i2c_base, I2C_MASTER_CMD_FIFO_BURST_RECEIVE_START); } uint8_t readFirstMeasByte(uint32_t i2c_base) { uint8_t meas_byte; while ((I2CFIFOStatus(i2c_base))&I2C_FIFO_RX_EMPTY); I2CFIFODataGetNonBlocking(i2c_base, &meas_byte); I2CMasterControl(i2c_base,I2C_MASTER_CMD_FIFO_BURST_RECEIVE_FINISH); meas_byte&=(uint8_t)0x3F;//mask off the top two most significant bits as these are status bits return meas_byte; } uint8_t readSecondMeasByte(uint32_t i2c_base) { uint8_t meas_byte; while ((I2CFIFOStatus(i2c_base))&I2C_FIFO_RX_EMPTY); I2CFIFODataGetNonBlocking(i2c_base, &meas_byte); return meas_byte; }