2017-01-15 09:50 AM
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 functionHAL_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 regardsVolker2018-02-24 08:37 AM
I have the same problem. Is anybody having a solution?
The solution proposed by ST is not working to me, since the condition is based on the RX FIFO status
SPI_FLAG_FRLVL
which my code always see it free...
2018-02-24 09:41 AM
Disabling/enabling using SPI_CR1_SPE does not flush the FIFO to me.
2018-07-04 12:24 AM
You'll be screwed if you need SPI protocol at SPI slave mode with RX and TX and with DMA and with unpredictable packets lengths....
The only thing can help is to set concrete packet length. But before sending normal packets, MASTER should send little bit bigger packet as a first packet after system is initiated... If normal packet length = 10 bytes, than first packet from Master should be 10+ x bytes. X depends on your set threshold of SPI FIFO and data settings. Anyway it helps only with slave tx dma, but if you have at same time rx dma, than your rx dma buffer will be unpredictable, there is a quite fishy solution on that with some garbage bytes, but it's a long story...
2018-11-06 04:27 AM
Hello,
I have kind of similar problem with receiving bytes via SPI and DMA. I am using MASTER MODE and communicating with SPI memory. The data sent by memory to the STM32L152 are correct (on logic analyzer), but STM receives bytes shifted by 3 bytes. I am now using low level drivers, in past I was using in this application HAL and it was working properly.
Here is detailed description:
For read data from memory:
SPI_Receive_DMA(readData, 4);
SPI_Transmit_DMA(readCmd, 4);
where basically the contents of this functions is:
void SPI_Receive_DMA(uint8_t *RxBuffer, uint32_t size) {
ubReceptionComplete = 0;
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_2);
LL_DMA_ConfigTransfer(DMA1, LL_DMA_CHANNEL_2,
LL_DMA_DIRECTION_PERIPH_TO_MEMORY | LL_DMA_PRIORITY_VERYHIGH | LL_DMA_MODE_NORMAL | LL_DMA_PERIPH_NOINCREMENT | LL_DMA_MEMORY_INCREMENT
| LL_DMA_PDATAALIGN_BYTE | LL_DMA_MDATAALIGN_BYTE);
LL_DMA_ConfigAddresses(DMA1, LL_DMA_CHANNEL_2, LL_SPI_DMA_GetRegAddr(SPI1), (uint32_t) RxBuffer, LL_DMA_GetDataTransferDirection(DMA1, LL_DMA_CHANNEL_2));
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_2, size);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_2);
}
void SPI_Transmit_DMA(uint8_t *TxBuffer, uint32_t size) {
ubTransmissionComplete = 0;
LL_DMA_DisableChannel(DMA1, LL_DMA_CHANNEL_3);
LL_DMA_ConfigTransfer(DMA1, LL_DMA_CHANNEL_3,
LL_DMA_DIRECTION_MEMORY_TO_PERIPH | LL_DMA_PRIORITY_HIGH | LL_DMA_MODE_NORMAL | LL_DMA_PERIPH_NOINCREMENT | LL_DMA_MEMORY_INCREMENT
| LL_DMA_PDATAALIGN_BYTE | LL_DMA_MDATAALIGN_BYTE);
LL_DMA_ConfigAddresses(DMA1, LL_DMA_CHANNEL_3, (uint32_t) TxBuffer, LL_SPI_DMA_GetRegAddr(SPI1), LL_DMA_GetDataTransferDirection(DMA1, LL_DMA_CHANNEL_3));
LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_3, size);
LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_3);
}
With 4B buffer size, it should read 2 data bytes from SPI memory (first 2 bytes are blank, because of STM transmitting the read command to the SPI memory). The 2 data bytes in memory have values 0x19 and 0x1A.
The STM reads this 4B from SPI/DMA: 0, 0, 0, 0x19
but it should actually reads: 0, 0, 0x19, 0x1A (this is how the logic analyzer reads it).
When I try for the second time to read the data from SPI memory, I got: 0x1A, 0, 0, 0x19
But as I said before, with HAL drivers it works with no problems and now with LL it makes problems (and the SPI and DMA settings is the same). I am suspecting the access to the buffer via DMA (probably the address is somehow incremented from the beginning by +1), but I don't have no idea how to debug this.
Also could be this a bug of LL drivers?
Thank you for any help!
2018-11-06 05:55 AM
On Tue, Nov 6, 2018, 13:27 ST Community wrote:
2019-01-17 08:43 AM
I struggled with this problem for about two weeks, the only workaround I could find was building my own set of non-blocking libraries to handle SPI as Slave. Now it works perfectly by using interrupts. The core of the SPI PHY is a shift register. If you understand that concept, you can easily build your own libraries.
2020-10-01 04:41 AM
I have the same problem. As a solution, I tried to use EXTI interrupt for SS line. Inside the EXTI handler, I call HAL_SPI_Abort just before HAL_SPI_Receive_DMA. Sometimes it helps, but not always.
2021-04-03 07:32 AM
same issues...
2024-05-13 05:17 AM - edited 2024-05-13 05:17 AM
I have the same issue on the SPI Slave RxBuffer. It is offset by 4-bytes.
Has anybody resolved the issue?
2024-05-13 06:31 AM
Yes but a general-case solution requires much more sophisticated synchronization between the SPI Master and Slave than just "Master-asserts-NSS-and-waits-a-while-before-sending".