[SPI] Fix bug on stm32f7 where 16 bits would be transferred instead of 8
The DR
register on the SPI peripheral on stm32f7xx micros is 16 bit wide. Write operations on this register directly cause 16 bits to be written into the FIFO, and thus a 16 bit transfer on the SPI bus.
When operating in 8-bit mode, this caused two problems:
- Every 8 bit write actually resulted in a 16 bit transfer
- To every write, there is an associated read to clear the FIFO. Since the write operation was of 16 bits, but the read operation only read 8, the FIFO would never be cleared, causing every transfer operation to return immediately and thus the chip select not being asserted for the full duration of the transfer. This is due to the check
while ((spi->SR & SPI_SR_RXNE) == 0)
;
always being true due to the FIFO never being emptied.
Solution:
- Perform a 8-bit write in the
transfer()
function ofSPIBus
by accessing theDR
register through a 8-bit pointer (*(volatile uint8_t*)&spi->DR = static_cast<uint8_t>(data);
) - Add additional checks to wait for the write operation to be complete before reading back the fifo
Screens
Note
This fix was only tested on an stm32f756 micro.
Edited by Luca Erbetta