How to clear internal SPI TX buffer in slave mode after transaction cancellation? SPI used in slave mode with DMA circular buffer.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-09-21 12:53 AM
Hello. I am using STM32F407VG controller. I have to transfer data from another device via SPI interface. STM32 SPI is used in slave mode, circular DMA enabled. Devices are connected via joint.
In some cases I need to resynchronize data exchange. At this moment SPI master device stops data exchange for some time (clock is stopped, CS is high). SPI slave (STM32F407VG) after some time tried to stop SPI (HAL_SPI_Abort(&hspi1); ) and then restart SPI with circular DMA again.
But after this operation other side (SPI master) receive one unnecessary byte. This byte have been transferred by DMA to SPI TX buffer before transaction is stopped. How to remove this byte from SPI TX buffer before start transaction. I tried to disable SPI, disable SPI pheripheral clock, but nothing help.
I have an idea to disable GPIO and switch SPI to master mode. Is there another way possible? May be unreferenced register to reset spi buffer or spi module exists.
Solved! Go to Solution.
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-09-21 1:44 AM
This has been discussed here several times, you may want to search. The consensus appears to be that the easiest way is to reset SPI through its respective RCC_APBxRSTR bit, and then configure it again.
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-09-21 1:44 AM
This has been discussed here several times, you may want to search. The consensus appears to be that the easiest way is to reset SPI through its respective RCC_APBxRSTR bit, and then configure it again.
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-09-21 2:13 AM
Resolved. Thanks!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2018-09-21 2:34 AM
Please mark as answered (Best). Thanks
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-05-08 7:31 PM
I've been struggling with a similar problem on an STM32L073 and resetting the SPI though the RCC_APBxRSTR bit and reconfiguring it did not resolve this issue.
I'm using the SPI in full duplex slave mode. The workaround I've come up with to flush the SPI TX buffer is to briefly switch to Master mode, which will clock out the TX byte/word in the buffer, then immediately switch back to Slave mode once the byte is flushed. The SPI_SCK and SPI_ MOSI pins are also briefly switched to inputs during this operation to avoid bus contention. The example below is specific to SPI1 on the STM32L073
HAL_SPI_DMAStop(&hspi1); // Disable DMA before flushing TX buffer
// Flush TX byte in TX DR
GPIOB->MODER &= ~GPIO_MODER_MODE3; // Set SPI CLK pin (PB3) to input to avoid bus contention
GPIOA->MODER &= ~GPIO_MODER_MODE12; // Set SPI MOSI pin (PA12) to input to avoid bus contention
SET_BIT(SPI1->CR1,SPI_CR1_MSTR); // Change to Master mode to flush TX buffer
while (SPI1->SR & SPI_SR_BSY) {} // Wait for byte/word to be clocked out
CLEAR_BIT(SPI1->CR1,SPI_CR1_MSTR); // Switch back to Slave mode
GPIOB->MODER |= GPIO_MODE_AF_PP << GPIO_MODER_MODE3_Pos; // Set SPI CLK Pin (PB3) back to Alternate Function
GPIOA->MODER |= GPIO_MODE_AF_PP << GPIO_MODER_MODE12_Pos; // Set SPI MOSI Pin (PA12) back to Alternate Function
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-05-08 10:30 PM
So, SPI transmitted old bytes from FIFO/buffer after being reset? Are you sure you've stopped DMA before the reset?
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-05-09 9:31 AM
Not sure if it's different on the STM32L073, but stopping the TX/RX DMAs, deinitializing them, shutting down the SPI, then reconfiguring everything didn't flush that byte from the TX buffer.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-05-09 9:42 AM
I have been going through the same issue with STM32F302VCT as a SPI1 slave (full duplex) connected with raspberry pi as master SPI. Even de-init of SPI1+dma and re-configuring / re-init of SPI1+dma don't resolve the issue. The issue is that transmit buffer fifo (SPI_FLAG_FTLVL) is not cleared after a successful transfer. I am amazed that ST doesn't have any example solution to handle such scenerio.
Please Help!!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-05-09 11:53 AM
> stopping the TX/RX DMAs, deinitializing them, shutting down the SPI,
> then reconfiguring everything didn't flush that byte from the TX buffer.
Can you please post the code you used for all this?
And how exactly do you know it does not clear the Tx buffer - do you observe the SPI bus using a LA, or some other way?
Thanks,
JW
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2020-05-09 11:56 AM
To avoid confusion with others, please start a new thread, stating the problem and posting relevant portions of code, perhaps also linking this thread.
Thanks,
JW
