ajg

ADC Scan Conversion With DMA happens Once (solved)

Discussion created by ajg on Mar 18, 2018

Implementing a scan conversion of channels 0-4 triggered by a timer with HAL libraries I found the following problems:

1. These asserts in HAL_ADC_Start_DMA() would fail with Scan Mode and Software Start:

   assert_param(IS_FUNCTIONAL_STATE(hadc->Init.ContinuousConvMode));
   assert_param(IS_ADC_EXT_TRIG_EDGE(hadc->Init.ExternalTrigConvEdge));

     Solution: Ignore them (by default, they are) or comment them out.

2. The ADC DMA would run once and not run again. Per the STM32F410 ref manual (was using a Nucleo board for test):
     "No new DMA request is issued to the DMA controller if the DDS bit is cleared to 0 in the
      ADC_CR2 register (this avoids generating an overrun error). However the DMA bit is
      not cleared by hardware. It must be written to 0, then to 1 to start a new transfer.

      I added the following line in HAL_ADC_Start_DMA():

        /* Enable ADC DMA mode */
          hadc->Instance->CR2 &= ~ADC_CR2_DMA; //clear it, then set it per ref manual
          hadc->Instance->CR2 |= ADC_CR2_DMA;

3. Ignorance on my part
    CubeMx allows for configuration of Scan Mode of the ADC.
    However, you must remember to activate the pull down for each conversion to set the Channel #.

    Otherwise, the initial channel is used for All conversions (of course).

 

The ADC is now happily converting 5 channels when it is triggered by a timer:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
/* USER CODE BEGIN Callback 0 */

/* USER CODE END Callback 0 */
  if (htim->Instance == TIM11) {
    HAL_IncTick();
  }
  if(htim->Instance == TIM1)
  {
    if(adcDmaComplete == 1)
    {
        if (HAL_ADC_Start_DMA(&hadc1, (uint32_t *)adcValues, 5) != HAL_OK)
        {
              _Error_Handler(__FILE__, __LINE__);
        }else
            adcDmaComplete = 0;
    }
  }
}

 

FYI,

 

AJG

Outcomes