This fixes an issue where the slave interface would time out when the
master goes from a short write to a read (e.g. when accessing memory
registers) with a START signal between. The previous implementation
would expect the full buffer length to be written before starting to
listen to new commands.
This also adds debug trace printing which helped during implemention and
testing.
Places error checking into a function inspired from a C implementation
of HAL.
In fixing a different timing related bug, #3887, a new bug was introduced causing I2C reads longer than 255 bytes to timeout for some I2C devices, #3888.
The issue was caused by incorrect branch order, and poll function being called unnecessarily.
Async I2C read poll function now only looks for I2C transfer complete reload (TCR) interrupts, intead of TCR and transfer complete (TC) interrupts,
since TC interrupts are not raised when AUTOEND bit is set.
For I2C devices that support variable length reads, sending chunks of data as long as the master keeps ACK:ing after each received byte, sequential reads will sometimes get out of sync, causing additional reads to return invalid data.
This was caused by a delay between awaiting the DMA read and sending the software STOP signal, which may result in the slave to have time to send a byte of data in between, causing potential miss-alignment. This would then cause subsequent reads to return invalid data.
Async write-reads now no longer send STOP after the initial write, matching the behaviour of the blocking version.
The I2C master-write function was failing when executed immediately after an I2C read operation, requiring manual delays to function correctly. This fix introduces a check to ensure the I2C bus is free before initiating the write operation.
According to the RM0399 manual for STM32H7 chips, the BUSY bit (Bit 15 in the I2C ISR register) indicates whether a communication is in progress on the bus. The BUSY bit is set by hardware when a START condition is detected and cleared when a STOP condition is detected or when PE = 0.
This fix prevents the write operation from starting until the BUSY bit is cleared.