Skip to main content
Associate II
April 22, 2024
Question

M4 Coprocessor (of MP15xx) DMA SPI4 example stays in "busy" state after first transmission

  • April 22, 2024
  • 1 reply
  • 1575 views

Hello,

I'd like to setup a DMA transfer to feed a SPI Display with 8192 bytes per DMA cycle. To offload the MP1 I want to do this with the help of the M4 coprocessor. For my tests I am using the CubeIDE and a custom board. As a basis for learning I tried the example "SPI_FullDuplex_ComDMA_Master". The example (FW_MP1_V1.6.0) itself waits for a keypress and then starts exactly one DMA transfer, I can see the clock pulses on the scope.

Since I need a peridoc refresh of the display, I tried as an experiment to wrap a simple loop together with a delay around the DMA-Send section but for some reason the DMA does not repeat, it gets stuck in a

hspi->State = HAL_SPI_STATE_BUSY_TX_RX

state and the error handler is called.

 

 

while(1)
{
 if(HAL_SPI_TransmitReceive_DMA(&hspi4, (uint8_t*)aTxBuffer, (uint8_t *)aRxBuffer, BUFFERSIZE) != HAL_OK)
 {
 Error_Handler();
 }
 HAL_Delay(50);
}

 

Why is the "DMA-in-a-loop" not working?

I can increase the time to HAL_Delay(1000) but that makes no difference. Any idea?

This topic has been closed for replies.

1 reply

ST Employee
April 22, 2024

Hello @EOF ,

Before starting a new communication transfer, you must wait the callback call to get the transfer complete confirmation or an error detection.
for this you need to trigger a flag and test on it before starting a new transfer in the callback of transfer complete. Here is an example:
 
 
enum {
 TRANSFER_WAIT,
 TRANSFER_COMPLETE,
 TRANSFER_ERROR
};
__IO uint32_t wTransferState = TRANSFER_WAIT;
while(1)
{
if(HAL_SPI_TransmitReceive_DMA(&SpiHandle, (uint8_t*)aTxBuffer, (uint8_t *)aRxBuffer, BUFFERSIZE) != HAL_OK)
 {
 /* Transfer error in transmission process */
 Error_Handler();
 }
 while (wTransferState == TRANSFER_WAIT)
 {
 }
}

//callback 
void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)
{
 /* Turn LED1 on: Transfer in transmission process is complete */
 BSP_LED_On(LED1);
 /* Turn LED2 on: Transfer in reception process is complete */
 BSP_LED_On(LED2);
 wTransferState = TRANSFER_COMPLETE;
}

BR

EOFAuthor
Associate II
April 23, 2024

Hello S Tea.

Yes, I know about the concept of the "HAL_SPI_TxRxCpltCallback", actually it is part of the SPI example. But it should also work without using the callback. The transfer takes around 2ms of time and the delay of 50ms is far enough time for the previous DMA to be finished before another one fires. Still you are right, this is the way it should be done.

But actually after a reboot of Linux and then a download "through Linux core" without any breakpoints it is working with the code I posted for an infinit time. But after changing code, add / remove breakpoints suddenly things become worse and as a result the example is not working anymore. Code changes do not help, as well as removing all breakpoints, repeating downloads...

What I can say "for sure" is, that in the "bad" situation the SysTick, though it is counting up in the processor register (STCVR), does not trigger the "void SysTick_Handler(void)" anymore. So all functions that rely on the HAL ticker will fail, I guess. There seems not to be any kind of remedy for this apart from issuing a "reboot" command in the Linux shell. After the reboot (not power off) the system runs again well until I start again making changes.

Actually I doubt my environment. Could be something with my Linux image for openAMP. A typical output is:

INIT: Id "STM1" respawning too fast: disabled for 5 minutes
INIT: Id "STM2" respawning too fast: disabled for 5 minutes
[ 46.008109] remoteproc remoteproc0: powering up m4
[ 46.017179] remoteproc remoteproc0: Booting fw image SPI_FullDuplex_ComDMA_Master_CM4.elf, size 2344144
[ 46.025168] remoteproc remoteproc0: header-less resource table
[ 46.031117] remoteproc remoteproc0: no resource table found for this firmware
[ 46.038286] remoteproc remoteproc0: header-less resource table
[ 46.043892] remoteproc remoteproc0: remote processor m4 is now up

Thank you S Tea for your effort, if you have any ideas (or a minimal working openAMP Linux image), please tell me (I read about users who report also problems with the "SysTick") but I understand that it is hard for you to help me in my somewhat complex environment.

ST Employee
April 23, 2024

Hello @EOF ,

Clearly I can't get all your changes and configuration with your Linux image but if it is impacting your systick we can bypass this by choosing another Timebase to be used for the HAL like Tim2 for example.

take a look to see how this can be done in UM1718 Example of configuration using TIM2 as HAL timebase source.

if it is the case and the problem is related to Systick this can be your way around it.

BR