cancel
Showing results for 
Search instead for 
Did you mean: 

Detecting the complete end of SPI transfer in TX master mode, other than BSY flag polling

IvanFromCyberia
Associate II

STM32G4 reference manual description offers only monitoring "Busy flag (BSY)" to check if SPI transfer is complete.

In order to make sure the transfer is over I have to do polling of this bit. It is waste of time and resources.

Is there any other reasonable way to detect the end of transfer with interrupt event generation?

If I have both TX and RX, I can see the RXed data amount to know the TX is over.

But in case of TX only I cannot do anything else, but polling.

I believe there should be a solution, but somehow I cannot find it.

Please, help.

1 ACCEPTED SOLUTION

Accepted Solutions

For TX, setting a timer at the start of the transaction and using the update interrupt may be your best bet. There is no interrupt tied to the BSY bit.

Yes, the 3-wire RXONLY mode implementation was truly a bizarre choice. I believe it has been changed on newer families.

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

View solution in original post

9 REPLIES 9
STTwo-32
ST Employee

Hello @IvanFromCyberia 

As you said, To detect the end of the SPI transfert, you can only use the Busy flag according to the RM0440.

Best Regards.

STTwo-32 

 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

TDK
Guru

> If I have both TX and RX, I can see the RXed data amount to know the TX is over.

Why are you okay with polling RXed data, but not the BSY bit?

Could always use four-wire mode and poll for RX, but seems equivalent to polling for BSY to me.

Could set a one-pulse timer after starting the transfer which concludes when transaction is over.

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

Use the SPI in DMA mode: the DMA gives you an event (triggering a Callback) to realize all was transferred.

In SW polling or INT mode: you can also watch the size variable: I think there is a structure to set the amount of bytes to send which is decremented. OK: you have to poll this variable, still wasting time.

Using SPI with DMA and an RTOS, where DMA done sets a semaphore (or sends an event) would let you do other stuff in parallel. (a DMA is like a second core, without DMA - all is single core and you had to poll and waste time).

RXed data may come with SPI or DMA interrupt. It it inevitable, and it is not polling.

Eventually I am 100% sure the transfer is over.

Extra time is a solution, but it takes extra measures.

I wish I have simple SPI BSY event flag with interrupt.

I believe when DMA or SPI interrupt report about SPI Sending data is complete - it means that all data is sent to SPI DR register, and it does not mean the SPI transfer itself is complete . Eventually part of it will be in transfer and the rest will be in FIFO. So, if I send more than 1 TX frames (8/16 bits) at least 1 or more frames will be in fifo and one will be in transfer state. When I have to start new transfer to the other slave with new Slave Select, for instance, I have to poll BSY flag first. No matter what you are using - nonblocking DMA or SPI interrupt API with OS, HAL, or LL - the BSY polling should be always performed before initiating new transfers with new Slave Select setting to make sure the previous transfer is complete without corruption.

Nikita91
Lead II

You can use a DMA on RX. When the amount of words is stored by the DMA you get an end of DMA interrupt and you are sure that the SPI has finished working. The trick is not using 'end of sending', but 'end of receive'.

If you don't need the RX data you can use only 1 word for DMA transfer using an increment of 0.

I run SPI in half duplex master mode.

It runs either one - TX or RX only at a time. If I have TX, RX is not active. RX DMA is not usable here.

Also, I found that if I run RX only - it starts receiving immediately and endlessly.

I have to stop it by SW when I received all needed data. When I stop reception - I see it continues clocking for at least one extra frame. Quite strange implementation of SPI. But this topic is for another thread.

For TX, setting a timer at the start of the transaction and using the update interrupt may be your best bet. There is no interrupt tied to the BSY bit.

Yes, the 3-wire RXONLY mode implementation was truly a bizarre choice. I believe it has been changed on newer families.

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

 Yep, It is the only way to make it work, but, there is a trade of between complexity and wasted CPU resources.

With extra timer I eventually make things more complex, If I have this extra timer available, for each SPI instance, though.

Still, I did not decide whether to keep polling BSY or use timer.