AnsweredAssumed Answered

STM32L4 SPI DMA FIFO not writing into or corrupting memory

Question asked by Noyb on Mar 10, 2016
Latest reply on Mar 11, 2016 by Noyb
Hi, I just wanted to connect a STM32 to a GPS using a SPI with DMA. Here is my setting :

la : LOGICPORT LA1034

board : NUCLEO-L476RG
mcu : STM32L476RGT6
gps : EVA-7M

cube : 4.13.0
lib : HAL 1.3.0

clock : 80 MHz
spi : SPI3, master, full duplex, 2 wires, prescaler 256 (312 kHz), no NSS
dma : DMA2_Rq3_Ch1 as Rx, DMA2_Rq3_Ch2 as Tx, BYTE

The scenario is as follow :

> STM32 send a 6 bytes UBX polling request frame using HAL_SPI_Transmit_DMA
> The logic analyzer 'see' the frame being sent
> After a while, I try to read the 6 first bytes from the answered UBX frame

Here are the results of my analysis :

1- Trying to receive 6 bytes using HAL_SPI_Receive_DMA into memory @ 'bufUbx' (multiple of 8)

expected frame : B5 62 0A 04 | 64 00
expected @ bufUbx : B5 62 0A 04 | 64 00 .. .. | .. .. .. .. | .. .. .. ..

?? : unreceived byte(s)

received frame : FF B5 62 0A | 04 64
received @ bufUbx : FF FF FF FF | B5 62 0E 34 | ?? .. .. .. | .. .. .. ..

The logic analyzer 'see' 6 bytes incoming from the GPS, yet it starts with an unexpected dummy byte set at FF.

The STM32 starts writing 4 bytes after 'bufUbx', padding the first 32 bits with the received dummy byte. The last bytes are merged into one, corrupting memory.

As the frame starts with a dummy byte, the UBX size is not complete. So I tried receiving 1 more byte as read ahead.

2- Trying to receive 6 + 1 bytes using HAL_SPI_Receive_DMA into memory @ 'bufUbx' (multiple of 8)

expected frame : B5 62 0A 04 | 64 00 31
expected @ bufUbx : B5 62 0A 04 | 64 00 31 .. | .. .. .. .. | .. .. .. ..

?? : unreceived byte(s)

received frame : FF B5 62 0A | 04 64 00
received @ bufUbx : FF FF FF FF | B5 62 0A 34 | ?? ?? .. .. | .. .. .. ..

The logic analyzer shows that the UBX size 64 00 is now received, the frame still starting with a dummy byte.

The STM32 still doesn't write the last received bytes into memory, corrupting it instead. So I try to receive even more bytes to see where it leads.

3- Trying to receive 6 + 1 + 4 bytes using HAL_SPI_Receive_DMA into memory @ 'bufUbx' (multiple of 8)

expected frame : B5 62 0A 04 | 64 00 31 2E | 30 30 31
expected @ bufUbx : B5 62 0A 04 | 64 00 31 2E | 30 30 31 .. | .. .. .. ..

?? : unreceived byte(s)

received frame : FF B5 62 0A | 04 64 00 31 | 2E 30 30
received @ bufUbx : FF FF FF FF | B5 62 0A 04 | 64 00 31 ?? | ?? ?? .. ..

The logic analyzer shows the expected number of bytes requested, yet starting again with the dummy byte.

The STM32 still writes at the wrong location into memory, but instead to corrupt the last bytes, it just skip them.

If the 32 FIFO is to take into consideration, let's try to received a multiple of 4 bytes to check if the whole FIFO is dumped in one operation into memory.

4- Trying to receive 12 bytes using HAL_SPI_Receive_DMA into memory @ 'bufUbx' (multiple of 8)

expected frame : B5 62 0A 04 | 64 00 31 2E | 30 30 20 28
expected @ bufUbx : B5 62 0A 04 | 64 00 31 2E | 30 30 20 28 | .. .. .. ..

?? : unreceived byte(s)

received frame : FF B5 62 0A | 04 64 00 31 | 2E 30 30 20
received @ bufUbx : FF FF FF FF | B5 62 0A 04 | 64 00 31 2E | ?? ?? ?? ..

Nothing has changed, the received UBX frame still starts with a dummy byte.

The STM32 just writes 1 byte more into memory, skipping the remaining 3 bytes.

As a matter of fact, I used STM32cubeMX to create my initialization code and I'm using the brand new HAL library to perform some basic data transfer.

I don't see what's so complicated to perform, I could provide you with my initialization and callback routines.

Outcomes