cancel
Showing results for 
Search instead for 
Did you mean: 

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

ioncasu
Associate II

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

 

3 REPLIES 3
TDK
Guru

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.

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

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);

 

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

 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.