cancel
Showing results for 
Search instead for 
Did you mean: 

STM32 SPI receive always shifted 3-4 bytes

volker2
Associate II
Posted on January 15, 2017 at 18:50

Hallo,  i use the HAL to program a little test software to transfer data via spi between

two STM32 Nucleo boards.

One board with a STM32L476 sends every 5 ms 74 bytes of data as a spi master with 625 kBit.

Chip select is used as GPIO output. clock is high if idle, CS is low active,

data valid with faling edge of clock.

A secon Nucleo64 should receive this 74 byte, configured as spi slave without NSS usage.

CS is used as an IRQ input with detection of the faling edge. DMA on den and receive, in normal mode.

I have programmed, that with the falling edge IRQ of the CS, the function

HAL_SPI_TransmitReceive_DMA() will be called. On the first NUCLEO i can adjust a time, so

that CS will be low a short time before the data was sent (I tried 50µs).The slave receives data, but the data was shifted. So the first 3 or 4 bytes in my

receive-array will be the last 3-4 bytes of the telegram before. And then the new data was

in the array.

I don't understand that behaviour. Controlled with the logic analyser everything is correct.

Do you know a solution for that?

Best regards

Volker
19 REPLIES 19
S.Ma
Principal
Posted on January 15, 2017 at 19:53

Try to disable-enable the spi on both sides before toggling nss to flush the fifos: it could give some clues to the shifted bytes behaviour. Is it 8 or 16 bit transmission? How many bytes are exchanged? Is it 4 or 3 wired communication?

Posted on January 15, 2017 at 19:58

74 Bytes are exchanged with a 8 Bit transmisson. It is a 4 wire connection. I don`t use nss and i use normal mode, not the fifos.

How can i disable-enable the SPI with the HAL?

Posted on January 15, 2017 at 21:35

Do you have

If you 'clear' the buffer in the receiver (e.g. set it to all 0) and then perform 1 transfer, what do you see in the receiver buffer?

What is the state of relevant DMA buffers after the transfer?

JW

volker2
Associate II
Posted on January 16, 2017 at 07:33

I think 'clear' the buffer is not the solution because the dma transfer thinks that for a complete receive of the 74 byte not all bytes are received. So how can i reset the dma transfer after a complete receive of 74 bytes, so the slave waits for the next correct transfer?

I will check the DMA buffers and answer you this evening.

julien B
ST Employee
Posted on January 24, 2017 at 15:06

Hello,

You are using a STM32 device with a SPI who include a FIFO.

To be sure to not retrieve old data, please use 'HAL_SPIEx_FlushRxFifo' function before call a 'HAL_Receive' function. Thanks to this, the FIFO will be flushed (Rx side only), and you will retrieve correct data. (i.e. without shift).

BRs,

Julien.

Posted on March 29, 2017 at 10:51

Hi,

I am having the same problem. I have an STM32F205VE and an STM32F746IG linked using SPI (three wire, software CS) and a GPIO handshake line. I am performing DMA transfers using the HAL_SPI_TransmitReceive_DMA() transfer function but I find that the data received on the master (the F205) is offset by the 3 bytes. The data received on the slave side is fine. I can understand how the rx fifo could cause this problem, but I cannot work out how to resolve it!

The 

HAL_SPIEx_FlushRxFifo() does not seem to exist in the HAL anymore. The only reference I can find for it in the whole library is in the stm32_hal_legacy.h file.

What is the best to flush the fifos? I don't mind accessing the registers directly, I just need some guidance on which bits need to be set/reset to solve this problem. 

Regards

Tim

Posted on November 21, 2017 at 16:56

I'm having the same issue too with the STM32L4 configured as SPI slave. My Tx buffer contains {01, 02, 03, 04, 05, 06, 07} When I read 7 bytes repeatedly from the slave I get:

01 02 03 04 05 06 07

05 06 07 01 02 03 04

05 06 07 01 02 03 04

05 06 07 01 02 03 04

...

Resetting the master doesn't change anything. Resetting the STM32 slave will send the correct first 7 bytes the first time and then repeat.

Posted on January 20, 2018 at 05:30

I am having the same problem. L4 nucleo. If i get < 3 bytes of data there is no shift. If i get more that 3 there is a shift. Start position is at index 3 or 4.

I did confirm that data is fine in a wire using oscilloscope.

Ok. I solved mine. I disabled only DMA channels when I didn't need them and no data should have arrived but it did (2 bytes with content of 0x00). Adding this code after TX part before RX part solved my issue:

    while (LL_SPI_GetTxFIFOLevel(SPI3) != LL_SPI_TX_FIFO_EMPTY) ;

    while (LL_SPI_IsActiveFlag_BSY(SPI3)) ;

    while (LL_SPI_GetRxFIFOLevel(SPI3) != LL_SPI_RX_FIFO_EMPTY)

    {

        LL_SPI_ReceiveData8(SPI3);

    }

I need to change my SPI mode to TX or RX only instead of just enabling/disabling DMA channels.

kylepennington
Associate III
Posted on February 20, 2018 at 01:41

Volker, did you manage to find a solution to this problem?