cancel
Showing results for 
Search instead for 
Did you mean: 

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

smati2
Associate II

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.

23 REPLIES 23

Hi @AScha.3,

I have tried with cache enabled or disabled. It actually got worst if cache was disabled. Can you please share your main initialization routine especially relating to MPU (MPU_Config) and SPI. In my case, as was mentioned earlier, I am using SPI4 in Slave mode. FYI, the Master (the other micro) is transmitting at 3M Baud.

Thanks.

I could switch back to dma but I didn't have good luck there and so now I'm using just regular HAL_SPI_TransmitReceive calls with a Timeout value (see an example call below):

rc = HAL_SPI_TransmitReceive(&hspi4, aTxBuff, aRxBuff, 16, 20000);

ok - but there is not much to see, because i use HAL;

setting of spi->8bit, slave, ...is done in Cube -> gen.code. (i need not to show - right? )

MPU is not used (i dont know how, cache is managed by direct instructions)

then in main:

(MX.. init , by HAL )

0693W00000aICNCQA4.png0693W00000aICNHQA4.png0693W00000aICNRQA4.pngnow it is running, always ...when data from spi comes, then copy from input buffer (in callback just set flag: buffer ready):

0693W00000aICNgQAO.pngcache "clear" was not effective here, so i put it only just before using the buffer ->

then copy it, when needed (and clear flag :(

0693W00000aICNlQAO.pngdata from ESP is 8bit , at 12 Mbaud speed; no dropouts or errors (at used speed);

why using HAL ? just because overall speed is not high, a 2KB data block needs minimum 2ms , so "slow HAL" calls add some 2us or so...not intersting, to bother around with the registers... 🙂 ; would not make anything faster or better, because the data rate is coming from the source and has big interval breaks up to 500ms ;

internet radio 🙂 .

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

Hi @Pavel A. 

After changing the transfer size from 32 to 16 bytes, even though the return is 0x80 and ignoring it since data received is valid, it can run for some time. It can run say for over 27K bytes of transfer then it fails and data is not valid at that point. I really think I need to address this return of 0x80 issue... What is return code of 0x80 any way?

The cache maintenance is just flawed. You are doing the broken "adjustment" of invalidation function parameters, the second invalidation is missing and the buffer is probably not aligned properly. Just read my article, a link to which I posted below!

Also HAL is not only bloated, but also broken:

https://community.st.com/s/question/0D50X0000C5Tns8SQC/bug-stm32-hal-driver-lock-mechanism-is-not-interrupt-safe

Engineering is not about luck. It is about understanding the issues and solving them correctly.

Well, surely and the use of the word "luck" was not the right choice. I should have said:...I didn't get the expected result there and so...

@Piranha​  ok, i know, you dont "like" the HAL 🙂

but what i am doing wrong ?

>You are doing the broken "adjustment" of invalidation function parameters

hm ? invalidateCache .. is wrong? maybe i can use the MPU - but i didnt find a simple and clear "how to do " . simple test with MPU on - crashed. (my fault, not mpu .)

>the second invalidation is missing 

? the other block, half /+ full , i do same. what missing else ?

>Just read my article

i did. (not understanding all - but most, i think. )

so : what i could/should do better ? (actual state is working with no errors or dropouts - as far, as i seen until now )

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

0x80 is not a valid value of HAL_StatusTypeDef.

julien B
ST Employee

Hi @smati2​ ,

If the process is stuck by waiting a TXP set, maybe the Master is deactivating the line

too early (NSS line at high level too fast at end of transfer).

In this case, you can try to switch on NSS soft to test it :

hspi4.Init.NSS = SPI_NSS_SOFT;

Others points:

Are you using other process in your software ?

If yes, try to disable IRQ before call HAL api:

      /* Mask interrupts that block the SPI data processing in polling mode. */

              __disable_irq();

              HAL_SPI_TransmitReceive(…);

           /* Re-enable interrupts */

              __enable_irq();

Are you using the default system clock configuration on your H743 ?

If not, try with the default configuration.

BRs,

Julien.