2019-11-02 04:13 PM
It seems like we have run into a delicate timing difference of the I2C in STM32F042 and STM32F072. Identical code (coming from the exact same source file) for I2C works fine on STM32F042G4U but has a problem on STM32F072V8T.
When doing larger I2C transfers we break them down into blocks to fit into a USB data packet. This produces a faulty behaviour on the STM32F072V8T which we think we traced down to the timing of the TCR and RSNE flags in the ISR register of I2C1.
What happens is when we write 0x3E to NBYTES we sometimes do not get the RXNE flag for the last byte at the same time as we get the TCR flag. But this happens only on the STM32F072V8T.
We handle all the status changes in an interrupt routine. I2C1 gets set up for a read transaction with length 0x3E. In the interrupt routine we check first if there is new data (RXNE) then if a transfer is complete (TCR). If the transfer is indicated complete we send off the data via USB and prepare I2C for the next data packet. The ISR is just read once at the beginning of the interrupt routine, so this can not be a problem with overlapping events.
On the STM32F042G4U this works just fine. We always get the last byte of a transfer together with the TCR flag. But on the STM32F072V8T we sometimes do get the TCR flag without the RXNE flag. The RXNE flag arrives later, which causes the current data packet to have one byte too few and the next packet one too much.
Is there any definitive specification how these flags should be related timingwise? Right now I have no good idea how to catch this problem in a clean and reliable way.