Bug in spi-master READ
Posted: Sat Mar 25, 2017 8:38 pm
It looks like there is serious bug in spi-master receive when DMA is used.
I was testing it with ILI9341 display with application based on spi-master example (the example itself works ok).
I've added the function to read line of data from display. Display data format (when read) is:
dummy_byte [R_byte G_byte B_byte] ........ [R_byte G_byte B_byte]
The screen was filled with blue color, so the response should be: 00 00 00 fc 00 00 fc 00 00 fc .....
Here are results of testing:
The first column is sequential number of read, first (dummy) byte is not shown, first 10 RGB values are shown (30 bytes)
When reading less than 33 bytes (no DMA used), the result is as expected, both in duplex and in half duplex mode:
[ 0] Rd line: 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc
[ 1] Rd line: 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc
[ 2] Rd line: 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc
[ 3] Rd line: 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc
When reading more than 32 bytes (DMA used) in duplex mode, no values are received:
[ 0] Rd line: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 1] Rd line: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 2] Rd line: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 3] Rd line: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
When reading more than 32 bytes (DMA used) in half duplex mode (.flags=SPI_DEVICE_HALFDUPLEX), the first read is OK, but for every following read values are shifted by 3 bytes (3, 6, 9, ...) :
[ 0] Rd line: 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc
[ 1] Rd line: 00 80 00 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc
[ 2] Rd line: 00 fc 00 00 28 00 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc
[ 3] Rd line: 00 fc 00 00 fc 00 00 10 00 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Nothing can reset this, even after spi_bus_remove_device, spi_bus_free -> spi_bus_initialize, spi_bus_add_device
and reinitializing the display, the receive buffer is still shifted!
Only the first read after booting is correct.
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------------
With a little change in spi_master.c:
host->hw->dma_conf.val |= SPI_OUT_RST|SPI_AHBM_RST|SPI_AHBM_FIFO_RST; to
host->hw->dma_conf.val |= SPI_IN_RST|SPI_OUT_RST|SPI_AHBM_RST|SPI_AHBM_FIFO_RST;
in 4 places where SPI_OUT_RST appears, the shiffting starts from the end of the receive buffer!
-----------------------------------------------------------------------------------------------------------------------------------------------
I would appreciate if someone could explain this issue.
I was testing it with ILI9341 display with application based on spi-master example (the example itself works ok).
I've added the function to read line of data from display. Display data format (when read) is:
dummy_byte [R_byte G_byte B_byte] ........ [R_byte G_byte B_byte]
The screen was filled with blue color, so the response should be: 00 00 00 fc 00 00 fc 00 00 fc .....
Here are results of testing:
The first column is sequential number of read, first (dummy) byte is not shown, first 10 RGB values are shown (30 bytes)
When reading less than 33 bytes (no DMA used), the result is as expected, both in duplex and in half duplex mode:
[ 0] Rd line: 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc
[ 1] Rd line: 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc
[ 2] Rd line: 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc
[ 3] Rd line: 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc
When reading more than 32 bytes (DMA used) in duplex mode, no values are received:
[ 0] Rd line: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 1] Rd line: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 2] Rd line: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[ 3] Rd line: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
When reading more than 32 bytes (DMA used) in half duplex mode (.flags=SPI_DEVICE_HALFDUPLEX), the first read is OK, but for every following read values are shifted by 3 bytes (3, 6, 9, ...) :
[ 0] Rd line: 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc
[ 1] Rd line: 00 80 00 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc
[ 2] Rd line: 00 fc 00 00 28 00 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc
[ 3] Rd line: 00 fc 00 00 fc 00 00 10 00 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc 00 00 fc
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Nothing can reset this, even after spi_bus_remove_device, spi_bus_free -> spi_bus_initialize, spi_bus_add_device
and reinitializing the display, the receive buffer is still shifted!
Only the first read after booting is correct.
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------------------------------------------------------------
With a little change in spi_master.c:
host->hw->dma_conf.val |= SPI_OUT_RST|SPI_AHBM_RST|SPI_AHBM_FIFO_RST; to
host->hw->dma_conf.val |= SPI_IN_RST|SPI_OUT_RST|SPI_AHBM_RST|SPI_AHBM_FIFO_RST;
in 4 places where SPI_OUT_RST appears, the shiffting starts from the end of the receive buffer!
-----------------------------------------------------------------------------------------------------------------------------------------------
I would appreciate if someone could explain this issue.