Skip to main content
Explorer
February 14, 2025
Solved

Using SPI on STM32H7 in mixed mode, normal and DMA.

  • February 14, 2025
  • 2 replies
  • 1527 views

I am working on a STM32H723 microcontroller and I am trying to use and SPI communication in mixed mode, i.e. normal and DMA.

The reason I need this is because I have a third party software stack for a device that is set up in a certain way, and it cyclically has to send small packets before sendind a big packet of user data. The application requires hard real-timeness so I want this exchange to be as fast and as little CPU blocking as possible. Considering these transfers must follow a certain order and that the stack I'm using is not organised as a state machine, I can only send the little packets in blocking mode, but then I'd like to send the big packet in DMA mode. 

The problem I'm encountering is that after using once the SPI transfer in DMA mode, the blocking transfers don't work anymore. When debugging I see that the periphery becomes permanently busy when trying to perform a normal transfer after using it in DMA mode in the previous cycle. 

I'd like to know whether it's possible to use an SPI periphery in this kind of mixed mode and if it is, what are the steps required to prepare the periphery for a normal transfer after performing a transfer in DMA mode. 

 

Thanks,

Ion

 

    This topic has been closed for replies.
    Best answer by TDK

    As an alternative, since you have DMA working, you can turn a DMA transfer into a blocking transfer when you want it to block until complete.

    HAL_SPI_TransmitReceive_DMA(&hspi1, ...);
    while (HAL_SPI_GetState(&shpi1) != HAL_SPI_STATE_READY);

     

    Should be possible to do what you want. I can look at it later if you don't get the solution by then.

    2 replies

    TDKAnswer
    Super User
    February 14, 2025

    As an alternative, since you have DMA working, you can turn a DMA transfer into a blocking transfer when you want it to block until complete.

    HAL_SPI_TransmitReceive_DMA(&hspi1, ...);
    while (HAL_SPI_GetState(&shpi1) != HAL_SPI_STATE_READY);

     

    Should be possible to do what you want. I can look at it later if you don't get the solution by then.

    Super User
    February 14, 2025

    Works fine for me. Generated new project for H723, enabled SPI with DMA, code runs without errors switching back and forth repeatedly. Must be something specific to what you're doing.

    // in main loop
    if (HAL_OK != HAL_SPI_TransmitReceive(&hspi1, data, data, sizeof(data), HAL_MAX_DELAY)) {
     Error_Handler(); 
    } 
    HAL_Delay(100); 
    if (HAL_OK != HAL_SPI_TransmitReceive_DMA(&hspi1, data, data, sizeof(data))) {
     Error_Handler(); 
    } 
    while (HAL_SPI_GetState(&hspi1) != HAL_SPI_STATE_READY);

     

    ioncasuAuthor
    Explorer
    February 18, 2025

    Hi, TDK,

    Sorry for the late answer, I've been away.

    Thank you very much for taking your time to test it. I've tried on a new project and it works indeed. I will have to investigate the problem on my custom board...

     

    Super User
    February 14, 2025

     The application requires hard real-timeness so I want this exchange to be as fast and as little CPU blocking as possible. 

    A dual-core H7 can be a great choice for this. Let one core manage the SPI device 100% of its time and other core do real-time tasks.

    ioncasuAuthor
    Explorer
    February 18, 2025

    Hi, Pavel. 

    Thanks for your input. Unfortunately, we have the single CPU version of the MCU.