Skip to content

[SPI] Fix bug on stm32f7 where 16 bits would be transferred instead of 8

Luca Erbetta requested to merge fix-spi-f7 into main

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:

  1. Every 8 bit write actually resulted in a 16 bit transfer
  2. 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:

  1. Perform a 8-bit write in the transfer() function of SPIBus by accessing the DR register through a 8-bit pointer (*(volatile uint8_t*)&spi->DR = static_cast<uint8_t>(data);)
  2. Add additional checks to wait for the write operation to be complete before reading back the fifo

Screens

Before:
image

After:
image

Note

This fix was only tested on an stm32f756 micro.

Edited by Luca Erbetta

Merge request reports

Loading