cancel
Showing results for 
Search instead for 
Did you mean: 

Non blocking SPI DMA transceive never completes in RTOS application

WCarey
Associate III

Description:

My RTOS application on NUCLEO-H563ZI board runs a thread CollectSamplesThread. I generate an interrupt every 8Khz using a timer and the ISR triggers a non blocking SPI transfer:

The application code:

 
void InitAdeSpi()
{
    // SPI1 Initialisation
    if (hSPI.hdmarx != NULL)
    {
        HAL_DMA_RegisterCallback(hSPI.hdmarx, HAL_DMA_XFER_CPLT_CB_ID, AdcSpiRxCallback);
    }
}

void AdcSpiRxCallback()
{
    BaseType_t xHigherPriorityTaskWoken = pdFALSE;
    // Release the sempahore thats blocked to validate the frames in CollectSamplesThread
    xSemaphoreGiveFromISR(xSpiRxSemph, &xHigherPriorityTaskWoken);
    portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
 
 
void TIM3_IRQHandler(void)
{
    EvbDataRdyTimerHandler();
}
 
void EvbDataRdyTimerHandler(void) // Ensure this matches the existing declaration
{
    __HAL_TIM_CLEAR_FLAG(&hTimDready, TIM_FLAG_UPDATE);
   // Release the sempahore that is blocked in the CollectSamplesThread for Dready callback
      xSemaphoreGiveFromISR(xSamplesAvailSemph, &xHigherPriorityTaskWoken);
       portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
} 
 
 
void CollectSamplesThread(void *pArg)
{
    HAL_StatusTypeDef halStatus;
    int32_t status = 0;
    if (pArg == NULL)
    {
        while (1)
        {
              if (xSemaphoreTake(xSamplesAvailSemph, portMAX_DELAY) == pdTRUE)
              {
                  halStatus = HAL_SPI_TransmitReceive_DMA(hSPI, pTxData, pRxData, (uint16_t)numBytes);
                  if (halStatus != HAL_OK)
                  {
                         status = -1;
                   }
                  if (status == 0)
                  {
                       if (xSemaphoreTake(xSpiRxSemph, portMAX_DELAY) == pdTRUE)
                       {
                            //Validate samples
                        }
                }
          }
     }
}
 
I enabled SPI1 IRQ and also DMA Tx & Rx channel IRQs.

Issue:

Tx DMA ISR is hit, Rx DMA ISR is not hit. SPI1 ISR, SPI1_IRQHandler, is also not hit.

Additional info:

System clock is configured to 250 Mhz.

Before calling HAL_SPI_TransmitReceive_DMA, 

  • SPI1->SR = 0x00011002 (TXP=1, TXC=1, no EOT)
  • SPI1->IER = 0x0 (interrupts disabled)

At if (halStatus != HAL_OK),

  • SPI1->SR = 0x00010012 (TXP=1, EOT=1, TXC=1) ✓ EOT flag is set
  • SPI1->IER = 0x00000360 (EOTIE=1, bits 5,6,8,9 enabled) ✓ EOT interrupt is enabled

 

 

3 REPLIES 3
gbm
Principal

While I have no idea on what's wrong with SPI DMA, I can see some other problems with your code.

To minimize jitter you should move all ADC-related actions to timer ISR; you should do fixed-frequency sampling anyway.

With the default SysTick freq of 1 kHz anything requiring higher frequency and implemented in a RTOS thread will only have chance to work if the thread is the only one with the highest priority.

My likely solution would be: control ADC operation in timer ISR, put ADC data to buffer of system queue in RX DMA ISR, process the data from this queue in a thread. No semaphores needed.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
KnarfB
Super User

Have not used H5, but in general hSPI.hdmarx is used internally by HAL.

You could implement 

void HAL_SPI_TxRxCpltCallback(SPI_HandleTypeDef *hspi)

or void HAL_SPI_RxCpltCallback(SPI_HandleTypeDef *hspi) ?

at the global level, overriding the default "do nothing" handlers.

hth

KnarfB 

Saket_Om
ST Employee

Hello @WCarey 

It is better to first get your SPI communication working without an RTOS. Once it is functioning correctly, you can then integrate the operating system.

Please check the example below as reference to implement your SPI transfer:

STM32CubeH5/Projects/NUCLEO-H503RB/Examples/SPI/SPI_FullDuplex_ComDMA_Master at main · STMicroelectronics/STM32CubeH5

To give better visibility on the answered topics, please click on "Accept as Solution" on the reply which solved your issue or answered your question.
Saket_Om