cancel
Showing results for 
Search instead for 
Did you mean: 

Is there anything to care about when using DMA transmit function of SPI (HAL_SPI_Transmit_DMA()) ?

Laurie1
Associate III

I am trying to control a screen with spi interface of STM32H750VB. I have tried "HAL_SPI_Transmit()" and "HAL_SPI_Transmit_IT()", it works well. But when I tried "HAL_SPI_Transmit_DMA()", it does not work. So I wrote the following code to compare DMA transmitting function of UART and SPI, and I found "hspix.State" is always "HAL_SPI_STATE_BUSY_TX", but nothing happens to UART. Is there anyone knows what is wrong with my code, or is there anything remarkable about "HAL_SPI_Transmit_DMA()" ?

char debugInfo[] = "Debug Info\r\n";
  while (1)
  {
#if 1    // testing SPI transmitting function in DMA mode
    HAL_SPI_Transmit_DMA(&hspi4, (uint8_t *)debugInfo, strlen(debugInfo) + 1);
    while(hspi4.State != HAL_SPI_STATE_READY);    // program will stuck here
#else    // testing UART transmitting function in DMA mode
    HAL_UART_Transmit_DMA(&huart1, (uint8_t *)debugInfo, strlen(debugInfo) + 1);
    while(huart1.gState != HAL_UART_STATE_READY || huart1.RxState != HAL_UART_STATE_READY);    // program won't stuck
#endif
 
    HAL_Delay(500);
  }

7 REPLIES 7
TDK
Guru

https://community.st.com/s/article/FAQ-DMA-is-not-working-on-STM32H7-devices

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

I have read the whole article. However after I tried those solutions, current problem still exists:face_with_tears_of_joy:

The article are talking about why the DMA does not work. It figure out that DMA may not able to access some RAM, or the desired data may be in the Dcache. And it gives out some solutions to put the data in the specific section forcelly or disable cache.

But my situation is: DMA does not work when using SPI, but works well when using UART (SPI4 and USART1 are both in the APB2 in H750). I guess if there is some BUG in the SPI interrupt function (codes to update hspi->State are missing or something else).

Thank you:)

There's nothing special about SPI here, and certainly nothing wrong in the code you show. Is DMAMUX set up correctly? Does blocking SPI work as expected?

If you've gone through the code and can't spot the error, I would suggest using a known working example, then comparing what it's doing to what you're doing.

https://github.com/STMicroelectronics/STM32CubeH7/blob/ccb11556044540590ca6e45056e6b65cdca2deb2/Projects/NUCLEO-H743ZI/Examples/SPI/SPI_FullDuplex_ComDMA/Src/main.c

Verify proper/expected return value of HAL_* functions, especially when troubleshooting.

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

Blocking and Interrupt SPI function works well, only "HAL_SPI_Transmit_DMA()" returns "HAL_BUSY" since hspi->State is "HAL_SPI_STATE_TX_BUSY".

Maybe I should use *_IT instead of *_DMA, or try something else next time.:sad_but_relieved_face:

Thank you for your help:rose:

It shouldn’t return HAL_BUSY the first time you call it. If it does, you’re using it elsewhere in your program.
If you feel a post has answered your question, please click "Accept as Solution".

It returns HAL_OK the first time, sorry.​

Observe waveform on the SPI pins. Instrument the DMA ISR and/or whatever code should result in the status to go to the desired state and observe it's behaviour.

Cube is open source.

JW