2024-03-05 02:07 PM - edited 2024-03-06 05:58 AM
I am using `HAL_SPI_Transmit_IT()` API to transmits 6 frames. The TXP interrupt correctly fires and feeds the TXDR register however after feeding the last frame into TXDR the EOT never fires, actually no interrupt fire after the last frame is feed.
It's worth noting polling mode also failed because EOT isn't being set either.
In other drivers we use HAL_SPI_Receive_DMA() and it works as expected.
I reviewed the STHAL driver but I do not see anything obvious wrong.
What criteria, besides TSIZE, triggers the hardware to set the EOT flag?
Solved! Go to Solution.
2024-03-06 11:14 AM
Solution:
When the SCLK signal is incorrectly routed to the GPIO block the EOT flag is not set.
Ensure you correctly routed the GPIO block to the SPI SCLK signal using the correct alternative function for the GPIO block.
2024-03-05 07:30 PM
9 bits on a SPI frame? (SPI byte)
As I understand SPI: it is byte oriented, entire transmission must have N * 8 clocks (bits). If receiving 9 bits - the last byte can be "incomplete" (still waiting to fill a byte).
No idea how if it is possible to configure 9 bits as a word (I do not think so, SPI is byte oriented).
2024-03-05 07:47 PM - edited 2024-03-05 07:57 PM
What you are saying is incorrect. SPI is a glorified shift register with timing around it, it isn't word/byte/half-word oriented protocol.
On this MCU, I am using SPI1. The datasheet indicates it can handle 4 to 32bits. Additionally the STHAL API allows you to configure anything from 4 to 32 bits.
The peripheral also has a packing feature but this isn't activated based on how it's accessed.
Given the setup I stated above the TXDR is accessed as 16 bits which means the threshold is hit because it's setup for 1 data packet and the frame is 9 bits wide. So on one access to TXDRAsU16 will push to the FIFO which hits the threshold, which causes the FIFO to offload into the shift register which shifts out 9 bits. However after the last frame is sent the EOT is not generated.
Please note I can observe the handling of `TXP` because it suppose to generate 6 events since I am using a data packet size of 1. So I get 6 TXP events which means the hardware FIFO is popping correctly.
2024-03-05 08:34 PM
How are you determining that EOT isn't getting set? It will be cleared in the HAL IRQ handler so won't ever be set if you're in user code.
The HAL supported method would be to handle the end of transfer action in HAL_SPI_TxRxCpltCallback.
> What are the criteria EOT to fire, the datasheet is not explicit?
The reference manual will have the details. EOT fires when TSIZE words have been written.
> TSIZE: 6 (does not change)
TSIZE is not meant to change. You can track the progress using the CTSIZE field in SPIx_SR register.
2024-03-05 08:47 PM - edited 2024-03-05 08:51 PM
2024-03-05 08:53 PM
I am sorry, desmond: You are right: the Word Size can be anything, even 9 bit (SPI_DATASIZE_9BIT).
I had in mind this: "Word Size" vs. "Frame Size" (what is your "Frame Size"?)
Example:
If I configure 9bit per word (DATASIZE, similar to "Word Size") but my frame looks like this: 9bit + 8bit +8bit (so, my "Frame Size" is 25bits - it will never complete (and even the words received might look wrong, shifted on bits).
"Frame Size" is the number of bits (simplified: the "Number of Words") in a chunk (one transaction).
The SPI waits (as I understand) for N x WordSize (DATASIZE). If the last word is not complete (like in the example: 2 bits are still expected with 9bits per word and 3 words per frame but just 25bits) - the EOT will never come.
Yes, "EOT fires when TSIZE words have been written" (or received): If number of bits are "incomplete" - EOT does come (still waiting for bits, to shift out or to shift in).
If you configure "Word Size" to 9bit - your "Frame" must have a length of N x 9bits.
2024-03-05 09:06 PM - edited 2024-03-05 09:09 PM
The frame size is correctly set. It is set to 9 bits by configuring `CFG1::DSIZE[4:0]`.
There is no 9 bit word, the access layer of the IP block is via TXDR register. If I configured a 9 bit frame then I need to access TXDR register on u16. Each u16 access will consume 16bits in the FIFO. The FIFO will pop 16 bits into the shift register and then the shift register will shift out 9 bits on the wire.
Additionally I am not activating the IP packing feature as this is auto activate depends on my access of TXDR (asU32 or as U16) + the threshold + the frameSize. See the reference manual on it.
Regardless of all of this if I setup the SPI for 8bit transfer the EOT still doesn't work even in polling mode. Either criteria for EOT event is not solely based on TSIZE or the IP block has a serious bug when transmitting only.
2024-03-05 09:43 PM
"hmmmm", did you get it?
9bit word size configured, trying to reading 2x 16bit words from FIFO, but the other side sends just 3 words (27bits as 3 x 9bits) - the SPI is still waiting for the missing bits. You can read the FIFO anytime you want, but the SPI peripheral is still waiting for bits (or bits = words provided, you want to transmit).
There is nothing wrong in MCU, the SPI works for me on all STM MCUs I have ever used.
But what I know "for sure": if the SPI device is still waiting for an expected bit (to receive) or when transmitting not yet enough words provided with all the number of bits needed for N * words - it "hangs" (actually - "the SPI waits still for you").
My bet: you have a mismatch between "bits provided" and "bits configured". Am sure EOT will come when the correct number of bits were there. And the "confusion" about Word Size and Frame Size.
2024-03-05 09:52 PM - edited 2024-03-05 10:09 PM
I appreciate the help but I would prefer a ST employee provide some advice.
2024-03-05 10:29 PM
The post below is the same observation I have made but I am not using the stm32h7. However I suspect the SPI IP would be the same