cancel
Showing results for 
Search instead for 
Did you mean: 

Why SPI returns busy after a while of sending correctly?

LBaum.3
Associate II

Hello ST community,

I use a STM32F767ZI-Nucleo. There is a timer generating interrupts every 20ms. If a timer interrupt occurs I use HAL_SPI_Transmit_DMA to send some data. I monitor the return value of this function and after some time of sending without any failure the return value is HAL_BUSY (I toggle an GPIO pin if this occurs). I also use the HAL_SPI_TxCpltCallback where I toggle another GPIO to monitor when the SPI transfer is completed.

I noticed that sometimes the HAL_SPI_TxCpltCallback is not reached after a transmission. At the next trasmission I get a HAL_BUSY and also the data is corrupted.

In pic1.png you can see what I monitored with a logic analyzer.

pic2.png shows the SPI trasmission where no HAL_SPI_TxCpltCallback is reached.

pic3.png is the next trasmission after that which returns HAL_BUSY and contains the corrupted data. There you can see anohter phenomenon. The TxCpltCallback occurs during the transmission.

In pic4.png you can see how a normal or correct transmission looks like.

Is there anyone who has an idea why my SPI is sometimes busy and therefore the data is corrupted?

12 REPLIES 12

I investigated the HAL_SPI_Transmit_DMA function and i determined that it also checks the BSY bit in the SPI status register. So in my opinion the BSY Bit is the reason for the failure.

The question I am facing now is how can I accomplish that the sending event after the event where BSY bit stays high works accurate?

My idea was to set the BSY bit manually to zero. But for all I know the BSY bit cannot be set to zero by software.

TDK
Guru

> So in my opinion the BSY Bit is the reason for the failure.

The reason (one, at least) for the failure is you're using data before it's actually there. Did you fix that part of it?

You haven't posted any evidence of the BSY bit misbehaving.

If you feel a post has answered your question, please click "Accept as Solution".

Yes, I changed the variables to global ones.

I noticed that the failure is at the slave side and there I don't use any data before it's actually there. So this could not be the reason for the fault.

As @Community member​ mentioned the errata sheet says that the BSY bit may stay high instead of going low at the end of transaction.

0693W00000BbgqWQAR.pngBy way of proof I monitored the BSY bit before each transmission. I transmit the BSY bit via uart as you can see in the following code segment.

0693W00000BbgvqQAB.pngThe result was as follows.0693W00000BbgwFQAR.pngThis is what I received from the uart interface. So you can see that I got five times "01" which means the BSY bit was set before the next transaction should take place and for the rest of the trasmissions I got "00" which means the BSY bit was not set.

For comparison purpose the following picture shows the same transmission recorded with a logic analyzer. You can see that during the recorded 15 seconds there are five HAL_BUSY returns (channel 4 "HAL_BUSY" is set and immediately reset five times)

0693W00000BbgswQAB.pngTherefore, in my opinion the BSY bit coresponds to the HAL_BUSY returns of the HAL_SPI_Transmit_DMA function and it's also the reason for this failure.

The question I am facing now is how can I accomplish that the sending event after the transmission where BSY bit stays high works accurate?

My idea was that the controller has to determine when the BSY bit stays high. If I know that I could reset the SPI interface before the next transmission will take place. But I have no idea how to determine this after the transmission. I can only determine it before the next transmission and there it could take to much time to reset the interface.