Skip to main content
marcus2
Associate II
January 9, 2017
Question

Timer triggered triple ADC regular sampling with DMA on STM32F7 - no interrupt

  • January 9, 2017
  • 4 replies
  • 1200 views
Posted on January 09, 2017 at 13:28

Hello all,

I have read through all contributions (e.g.,

https://community.st.com/0D50X00009XkdjTSAR

) and cubemx (1.5.0) examples I found but did not find a working solution. Timer triggered, single channel sampling via DMA works nicely (ADC1, but I checked also the other channels), see code extraction below. As soon as I comment (1) and uncomment (2) I do not get a DMA interrupt anymore.

What do I miss?

Thanks,

   Marcus

ADC_HandleTypeDef adcHdl1;

ADC_HandleTypeDef adcHdl2;

ADC_HandleTypeDef adcHdl3;

DMA_HandleTypeDef adcDmaHdl2_0;

DMA_HandleTypeDef adcDmaHdl2_1;

DMA_HandleTypeDef adcDmaHdl2_3;

static uint32_t adcData[6];    

int main(void) {

  ...

  MX_ADC_Init();

  /*(1)*/ HAL_ADC_Start_DMA(&adcHdl1, adcData, 2);   // DMA single channel ADC

  /*(2)*/ //HAL_ADCEx_MultiModeStart_DMA(&adcHdl1, (uint32_t *)adcData, 6); // DMA multimode (triple) ADC

  while(1);

}

void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *adcHdl) {

  ...

}

void MX_ADC_Init(void) {

  ADC_MultiModeTypeDef multimode;

  ADC_ChannelConfTypeDef sConfig;

  adcHdl1.Instance = ADC1;

  adcHdl2.Instance = ADC2;

  adcHdl3.Instance = ADC3;

    

  adcSetParameters(&adcHdl1);

  adcHdl1.Init.DMAContinuousRequests     = ENABLE;

  adcHdl1.Init.ExternalTrigConv          = ADC_EXTERNALTRIGCONV_T5_TRGO;    

  adcHdl1.Init.ExternalTrigConvEdge      = ADC_EXTERNALTRIGCONVEDGE_RISING;

  adcSetParameters(&adcHdl2);

  adcHdl2.Init.DMAContinuousRequests     = DISABLE;

  adcHdl2.Init.ExternalTrigConv          = ADC_EXTERNALTRIGCONV_T1_CC1;        

  adcHdl2.Init.ExternalTrigConvEdge      = ADC_EXTERNALTRIGCONVEDGE_NONE;    

    

  adcSetParameters(&adcHdl3);

  adcHdl3.Init.DMAContinuousRequests     = DISABLE;

  adcHdl3.Init.ExternalTrigConv          = ADC_EXTERNALTRIGCONV_T1_CC1;        

  adcHdl3.Init.ExternalTrigConvEdge      = ADC_EXTERNALTRIGCONVEDGE_NONE;    

    

  if (HAL_ADC_Init(&adcHdl1) != HAL_OK) Error_Handler(PANIC);

  if (HAL_ADC_Init(&adcHdl2) != HAL_OK) Error_Handler(PANIC);

  if (HAL_ADC_Init(&adcHdl3) != HAL_OK) Error_Handler(PANIC);

    

  sConfig.Rank = 1;

  sConfig.SamplingTime = ADC_SAMPLETIME_3CYCLES;

  sConfig.Channel = ADC_CHANNEL_3;

  if (HAL_ADC_ConfigChannel(&adcHdl1, &sConfig) != HAL_OK) Error_Handler(PANIC);

  sConfig.Channel = ADC_CHANNEL_6;

  if (HAL_ADC_ConfigChannel(&adcHdl2, &sConfig) != HAL_OK) Error_Handler(PANIC);

  sConfig.Channel = ADC_CHANNEL_4;

  if (HAL_ADC_ConfigChannel(&adcHdl3, &sConfig) != HAL_OK) Error_Handler(PANIC);

  /**Configure the ADC multi-mode */

  /* (2) */

  /*  multimode.Mode          = ADC_TRIPLEMODE_REGSIMULT;

  multimode.DMAAccessMode     = ADC_DMAACCESSMODE_1;

  multimode.TwoSamplingDelay  = ADC_TWOSAMPLINGDELAY_5CYCLES;

  HAL_ADCEx_MultiModeConfigChannel(&adcHdl1, &multimode); 

*/

}

void adcSetParameters(ADC_HandleTypeDef* adcHdl) {

  adcHdl->Init.ClockPrescaler           = ADC_CLOCKPRESCALER_PCLK_DIV4;

  adcHdl->Init.Resolution               = ADC_RESOLUTION12b;

  adcHdl->Init.ScanConvMode             = DISABLE;

  adcHdl->Init.ContinuousConvMode       = DISABLE;

  adcHdl->Init.DiscontinuousConvMode    = DISABLE;

  adcHdl->Init.DataAlign                = ADC_DATAALIGN_RIGHT;

  adcHdl->Init.NbrOfConversion          = 1;

  adcHdl->Init.EOCSelection             = ADC_EOC_SINGLE_CONV;

}

    

    

void HAL_ADC_MspInit(ADC_HandleTypeDef* adcHdl) {

  GPIO_InitTypeDef GPIO_InitStruct;

    __HAL_RCC_DMA2_CLK_ENABLE();

  if(adcHdl->Instance==ADC1) {

    __ADC1_CLK_ENABLE();

  

  GPIO_InitStruct.Pin = GPIO_PIN_3;

    GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;

    GPIO_InitStruct.Pull = GPIO_NOPULL;

    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    adcDmaHdl2_0.Instance                 = DMA2_Stream0;

    adcDmaHdl2_0.Init.Channel             = DMA_CHANNEL_0;

    adcDmaHdl2_0.Init.Direction           = DMA_PERIPH_TO_MEMORY;

    adcDmaHdl2_0.Init.PeriphInc           = DMA_PINC_DISABLE;

    adcDmaHdl2_0.Init.MemInc              = DMA_MINC_ENABLE;

    adcDmaHdl2_0.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;

    adcDmaHdl2_0.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;

    adcDmaHdl2_0.Init.Mode                = DMA_CIRCULAR;

    adcDmaHdl2_0.Init.Priority            = DMA_PRIORITY_HIGH;

    adcDmaHdl2_0.Init.FIFOMode            = DMA_FIFOMODE_DISABLE;

    adcDmaHdl2_0.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_HALFFULL;

    adcDmaHdl2_0.Init.MemBurst            = DMA_MBURST_SINGLE;

    adcDmaHdl2_0.Init.PeriphBurst         = DMA_PBURST_SINGLE;

    HAL_DMA_Init(&adcDmaHdl2_0);

    __HAL_LINKDMA(adcHdl, DMA_Handle, adcDmaHdl2_0);

    HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, 0, 0);

    HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);

  }

  else if(adcHdl->Instance==ADC2)   {    ... }

  else if(adcHdl->Instance==ADC3)   { ... }

  HAL_NVIC_SetPriority(ADC_IRQn, 0, 0);        

  HAL_NVIC_EnableIRQ(ADC_IRQn);

}

void DMA2_Stream0_IRQHandler(void) {

  HAL_DMA_IRQHandler(&adcDmaHdl2_0);

}

#timer #dma #interrupt #interrupts #hal #triple-mode #stm32f7 #adc
This topic has been closed for replies.

4 replies

ST Technical Moderator
January 17, 2017
Posted on January 17, 2017 at 15:48

Hello

Eger.Marcus

‌,

Try with the new release of CubeMx 4.0,then let me know about your update.

Regards

Imen

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks
marcus2
marcus2Author
Associate II
January 18, 2017
Posted on January 18, 2017 at 13:56

The problem seems to be solved:

1) I had to start the ADCs in a correct sequence (adc3 and adc2 before adc1) in main() such as

  if (HAL_ADC_Start(&adcHdl3) != HAL_OK)

        Error_Handler(SOME_ERROR);

  if (HAL_ADC_Start(&adcHdl2) != HAL_OK)

        Error_Handler(SOME_ERROR);

  if (HAL_ADCEx_MultiModeStart_DMA(&adcHdl1, (uint32_t *)adcData, 3) != HAL_OK)

        Error_Handler(SOME_ERROR);

2)  I had to set (the same as in my code extract above)

   

multimode.DMAAccessMode     = ADC_DMAACCESSMODE_1

otherwise the HAL_ADC_ErrorCallback() is fired.

Unfortunately, CubeMX does not help a lot, here (except point 2, which I did right by chance). I got the hint for the major point from an ST developer.

- Marcus

ST Technical Moderator
January 18, 2017
Posted on January 18, 2017 at 14:12

Hi

Eger.Marcus

,

I'm pleased

to hear

that your problem has been resolved.

Thank you for posting your issueand how you fixed it.

Regards

Imen

In order to give better visibility on the answered topics, please click on 'Best answer' on the reply which solved your issue or answered your question. Thanks