AnsweredAssumed Answered

STM32F746-discovery, how to define a Transfer Complete Callback function for DMA on Multichannel ADC scan?

Question asked by Adamo.Francesco on Apr 2, 2017
Latest reply on Apr 5, 2017 by Adamo.Francesco

Hi all,

I am developing an application with my STM32F746G-Discovery board; for this application I need to acquire 4 to 6 analog signals from external sensors.
My application uses the Arduino UNO headers on the back of the discovery board to interface with a motor driver shield by Pololu; I was already able to generate the logic and PWM signals to control the motor status, direction and rotation speed by means of an LCD GUI.
Now I need to acquire some analog signals from external sensors, possibly using DMA to transfer ADC samples in memory.
Until now I was able to initialize the ADC and DMA using STM32CubeMX, defining the needed ADC3 channels, associated ranks, working mode and so on.

 

This is the MX_ADC3_Init function generated by STM32CubeMX:

 

/* ADC3 init function */
static void MX_ADC3_Init(void)
{

   ADC_ChannelConfTypeDef sConfig;

 

    /**Configure the global features of the ADC (Clock, Resolution, Data Alignment and number of conversion)
    */
  hadc3.Instance = ADC3;
  hadc3.Init.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV8;
  hadc3.Init.Resolution = ADC_RESOLUTION_12B;
  hadc3.Init.ScanConvMode = ENABLE;
  hadc3.Init.ContinuousConvMode = ENABLE;
  hadc3.Init.DiscontinuousConvMode = DISABLE;
  hadc3.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE;
  hadc3.Init.ExternalTrigConv = ADC_SOFTWARE_START;
  hadc3.Init.DataAlign = ADC_DATAALIGN_RIGHT;
  hadc3.Init.NbrOfConversion = 2;
  hadc3.Init.DMAContinuousRequests = ENABLE;
  hadc3.Init.EOCSelection = ADC_EOC_SEQ_CONV;
  if (HAL_ADC_Init(&hadc3) != HAL_OK)
  {
    Error_Handler();
  }

 

    /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
    */
  sConfig.Channel = ADC_CHANNEL_0;
  sConfig.Rank = 1;
  sConfig.SamplingTime = ADC_SAMPLETIME_480CYCLES;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

 

    /**Configure for the selected ADC regular channel its corresponding rank in the sequencer and its sample time.
    */
  sConfig.Channel = ADC_CHANNEL_7;
  sConfig.Rank = 2;
  if (HAL_ADC_ConfigChannel(&hadc3, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

}

 

and this is the DMA Init function:

 

/**
  * Enable DMA controller clock
  */
static void MX_DMA_Init(void)
{
  /* DMA controller clock enable */
  __HAL_RCC_DMA2_CLK_ENABLE();

 

  /* DMA interrupt init */
  /* DMA2_Stream0_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}

 

Using this template code and following some online demos I was able to intercept the single ADC channel conversion complete interrupt but I would like to define a DMA Transfer Complete Callback function to scale all sensors readings using a single function; however I can't figure out how to do this.

 

I tried to define a custom XferCpltCallback function with this prototype

 

void myADC_DMA_XferCpltCallback(DMA_HandleTypeDef* hdma_adc)
{
        // ADC readings scaling code

}

 

and pointing to it inserting this code after the MX_DMA_init() call:

 

if (HAL_DMA_RegisterCallback(&hdma_adc3, HAL_DMA_XFER_CPLT_CB_ID, myDMA_XferCpltCallback) != HAL_OK)
        return 0;

 

and then starting the DMA with:

 

if (HAL_ADC_Start_DMA(&hadc3, (uint32_t*) ADC_BUF, 2) != HAL_OK)
        return 0;

 

before the infinite loop in the main function.

 

Debugging the code I can see that both functions return HAL_OK, so I can guess that the callback is correctly registered and that the DMA starts without errors.

 

However if I put an interrupt at the beginning of the callback function I can see that it is never called and that the ADC samples buffer (ADC_BUF) is never updated.

 

Can anyone of you give me some hint on how I should define this callback and how I should point to it?

 

Thanks in advance for any help.

Outcomes