AnsweredAssumed Answered

Configuring SDADC for Repeat Triggering with DMA

Question asked by Stephen on Jun 22, 2016
I need SDADC1 to do a scanned injected DMA conversion of fifty samples total each time there is a TRGO output from TIM4. I have confirmed by measurement using HAL_GetTick() that TIM4 is cycling at the desired rate of 1Hz. SDADC2 and SDADC3 each have their own arrays to fill by DMA, and are triggered by SDADC1.

I tried first to set all the SDADCs to discontinuous mode because once triggered I need the conversions to stop after the fifty samples, and continue again on the next trigger. But HAL_SDADC_InjectedConvCpltCallback() is never called.

Next I set all SDADCs to continuous mode. I found that HAL_SDADC_InjectedConvCpltCallback() is called. But code I wrote to measure how frequently it is called shows the interval between calls for SDADC1 to be much faster than 1Hz. Pasted below is the code:

    static volatile double Tsdadc[5];
    static volatile uint32_t isdadc = 0;
    static volatile uint32_t PriTicksdadc = 0;

    void HAL_SDADC_InjectedConvCpltCallback(SDADC_HandleTypeDef* hsdadc)
    { BaseType_t xHigherPriorityTaskWoken = pdFALSE;
      volatile HAL_StatusTypeDef DMAStop, DMAStart;

      volatile uint32_t CurTick = 0;

      switch( (uint32_t)(hsdadc->Instance))
      { case (uint32_t)SDADC3:
          xQueueSendToBackFromISR( QueueSDADC_InjConvCpltHandle, &SDADC3_RDY, &xHigherPriorityTaskWoken );
        break;
        case (uint32_t)SDADC2:
          xQueueSendToBackFromISR( QueueSDADC_InjConvCpltHandle, &SDADC2_RDY, &xHigherPriorityTaskWoken );
        break;
        case (uint32_t)SDADC1:
          if( isdadc >= sizeof(Tsdadc)/sizeof(Tsdadc[0]) )
            HAL_GetTick(); // Just something to break on
          else
          { if( PriTicksdadc == 0 )
              PriTicksdadc = HAL_GetTick();
            else
            { CurTick = HAL_GetTick();
              Tsdadc[isdadc++] = (double)(CurTick - PriTicksdadc) / (double)portTICK_PERIOD_MS;
              PriTicksdadc = CurTick;
            }
          }

          xQueueSendToBackFromISR( QueueSDADC_InjConvCpltHandle, &SDADC1_RDY, &xHigherPriorityTaskWoken );
        break;
      }
      portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
    }

When the breakpoint that is set at the line with the comment “// Just something to break on” breaks, the value of every element in the Tsdadc[] array is zero. This indicates conversions are continuous and do not stop. But the need is for them to stop after DMA has filled an array of 50 conversions and wait for the next trigger from TIM4 TRGO before resuming conversions. How is this done?

The STM32CubeMX project file is attached.

The DMA buffers are not circular.

Attachments

Outcomes