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.
Hi,
I have currently implemented the code used in the I2C_EEPROM example that utilizes the interrupt state machine to drive the I2C bus. I have, however, modified it not to use the FIFO. Currently the code works just fine sending and receiving data to an EEPROM with the following exception: If a NACK is received from the EEPROM in the middle of a data write, the current transfer will gracefully terminate, however, the next transfer has an unwanted byte. Here's how it is playing out:
(1) Set start bit flag to start transfer.
(2) Processor sends start bit and outputs slave address
(3) Transmit ready interrupt occurs and we stuff next byte into I2CDXR in which the CPU copies to I2CXSR.
(4) CPU starts sending byte in I2CXSR
(5) Another transmit ready interrupt occurs and we again stuff next byte into I2CDXR in which the CPU copies to I2CXSR when ready.
(6) A NACK interrupt occurs because the previous I2CDXR stuffed byte (i.e. the one currently be transmitted) has been NACKED. We Force a stop bit and clear the NACK bit in I2CSTR.
(7) A stop condition detected interrupt occurs to signify end of transfer.
The above all works well, the problem comes when the next transfer is initiated. Once we initiate another transfer the following happens on the bus:
(1) Start bit occurs correctly
(2) slave address sent correctly
(3) The last byte we stuffed into I2CDXR from the last transfer gets dumped on the bus, obviously not want we want. So how do we clear or empty the I2CXSR/I2CDSR register before we start a new transfer upon receiving a NACK?
Thanks,
Dan
Dan,
I looked through the I2C documentation and I think there are two ways we can easily flush the data from the buffer.
1) Reset the I2C module.
I know this isn't an ideal solution but clearing and setting the IRS bit in the I2CMDR register should flush the byte out of the buffer. Keep in mind you will need to re-initialize the control registers after this occurs.
2) Turn on digital loopback mode and transmit the byte to yourself.
By setting the DLB bit in I2CMDR, messages transmitted will be received in the I2CDRR. This can then be read, completly flushing the bad byte from the I2C peripheral. This is the best method I can come up with without destroying the control register values.
Let me know if you have trouble with this or need further assistance,
Trey German
Hi Dan,
Once you receive the NACK and you terminated that session, did you try writing to the I2CDXR register and then waiting for XRDY interrupt before setting the STT bit. Im trying to figure out if it will overwrite the bits in the XSR register