Skip to main content
smati2
Associate II
February 23, 2023
Question

STM32H7xx - Bug in SPI Driver HAL in larger transmission (32 bytes transmission in one call)

  • February 23, 2023
  • 23 replies
  • 8162 views

Hi all. I am having an issue with HAL_SPI_TransmitReceive routine under STM32H743. I am using STM32CubeIDE ver 1.10.1. In our setup for STM32H743, it is bare metal (no RTOS). The SPI is in Slave mode. In particular, I am using SPI4 as follows:

Mode: Slave

PE11 = SPI4_NSS

PE12 = SPI4_SCK

PE13 = SPI4_MISO

PE14 = SPI4_MOSI

Data Size = 8 Bits with first bit as MSB bit

Note that the Master is transmitting at 3M baud.

I am using HAL_SPI_TransmitReceive function. It all works fine until the need for receiving 32 bytes in one call as indicated below:

HAL_SPI_TransmitReceive(&hspi4, aTxBuff, aRxBuff, MAX_NUMBYTES_TO_WRITE_EACH_TIME, 5000)

where MAX_NUMBYTES_TO_WRITE_EACH_TIME = 32

I get about half of them and the rest are all zero and the call gets stuck in HAL_SPI_TransmitReceive and never returns.

Note: I saw a post (https://community.st.com/s/question/0D53W00000MfuaASAR/stm32h7xx-serious-bug-in-spi-driver-hal-version-130-170-and-180?t=1677157489831) where another member (@Dub Bartolec) was having a similar problem. The member had discovered a bug on this routine and had noticed it existed in version 1.3.0, 1.7.0 and 1.8.0 in CubeMX. Having seen that post, I got the latest version (ver 1.11.0 ) from ST GitHub (https://github.com/STMicroelectronics/STM32CubeH7/tree/master/Drivers) and replaced my stm32h7xx_hal_spi.c and stm32h7xx_hal_spi.h with that version. It now actually receives the entire 32 bytes and the bytes are valid. However, it does not come out of the HAL_SPI_TransmitReceive routine. The transmitter thinks it needs to send more but TXP is not set so it gets stuck in that loop. I am doing 8 bytes transfers.

Please assist as we are stuck and the rest of the process cannot continue until I get over this communication issue.

Many thanks in advance.

This topic has been closed for replies.

23 replies

smati2
smati2Author
Associate II
March 16, 2023

Hi @julien B 

Thank you for your suggestions. Though it does not appear that Master is removing the NSS early, I tried to do the NSS = SPI_NSS_SOFT, but had the same result. It basically moves on for a while and then the glitch happens.

As for other tasks, on this particular case, there isn't anything else.

I have tried the default configuration, but no real remedy. Now here's what I have done that has made significant changes:

On the short transfers, I am using the HAL_SPI_TransmitReceive call. However, on the larger transfers (32 bytes transfer size), I am doing HAL_SPI_TransmitReceive_DMA and that appears to work all the way through. In fact, I am doing a custom bootloader and with the above the update of over 600K byte transfers completes and data is valid. In fact, the issue that I had mentioned where data was valid but the status return was 0x80 does not appear to happen any more :)

However, to speed up the process, I would like to bump up the transfer size to potentially 256 or more. Yet, as the first attempt at transfer size of 64 bytes, it has a hiccup. The process goes for a while and then runs into an issue, which appears to be interrupt not firing! So, it hangs waiting for the completion interrupt after the HAL_SPI_TransmitReceive_DMA call. What's difficult to troubleshoot is that the process goes say about 15K bytes of transfer with all the transfer size of 64 bytes on each transfer before the hiccup happens. What's interesting though is that all the time that is is working well, the MISO is transmitting 0xA5 (which is what I do desire to send on MISO) while reading the MOSI bytes. However, upon the hiccup, it appears to have 7 or 8 bytes of 0xA5 sent on MISO, but the remaining bytes of that 64 byte transfer are some unexpected data or at 0xFF (MISO staying high). This may not be related, but nevertheless, could be a clue to the issue. Here are Logic Analyzer captures:

0693W00000aJ9YJQA0.png 

0693W00000aJ9YTQA0.pngFYI, in above, every toggle on "SEC_DEBUG1" is after the interrupt and toggled in the callback (HAL_SPI_TxRxCpltCallback) routine. As you can see the last transfers (256 bytes, which is split into four 64 bytes) are not getting the interrupt. Moreover, on a good transfer, all the MISO bytes are 0xA5 (see below):

0693W00000aJ9Z7QAK.png  

However, at the end where it starts having the issue, I only see 8 bytes of 0xA5 from MISO and then the rest are not what I am expecting and EOT interrupt does not fire... (see below):

0693W00000aJ9ZRQA0.png 

------------------------------------------------------------------------------------------------------------------

Here are the snippet of the code at the hiccup point waiting for interrupt call back routine to set the EOT completion and the related define and variable info:

0693W00000aJ9OYQA0.png 

0693W00000aJ9OeQAK.png 

0693W00000aJ9P2QAK.png 

Note: In above image, if resolution is small, I have also attached the image (SPI_DMA transfer hiccup.jpg).

Hope you or someone can assist. Thank you.