cancel
Showing results for 
Search instead for 
Did you mean: 

Dual ADC mode single DMA configuration - How?

MHilt.1
Associate

The STM32H7(4/5) documentation states that two of the ADCs on board can be used in dual ADC mode, so that their 16bit samples are read into the upper- and lower halfwords of a single 32bit register (ADCx_CDR), from where a single DMA can read them into designated buffer array.

The documentation states this in no uncertain terms:

" A single DMA request is generated each time both master and slave EOC events

have occurred. At that time, the slave ADC converted data is available in the

upper half-word of the ADCx_CDR 32-bit register and the master ADC converted

data is available in the lower half-word of ADCx_CDR register. "

 

There is no example, documentation, or publicly available implementation of this that I could find, and making the above happen has proven impossible to me and my colleagues. The DMA setup is straightforward, but the ADCs still read data into their respective registers, and not into a common one, or if there is a separate common register, it isn't apparent how to point the DMA there.

 

I'd be extremely thankful of any help, be it pointing towards examples, or working code snippets for this. Here is the ADC1 initialization segment, where I suspect the issue lies:

 

hadc1.Instance = ADC1;
  hadc1.Init.Resolution = ADC_RESOLUTION_16B;
  hadc1.Init.ScanConvMode = ADC_SCAN_DISABLE;
  hadc1.Init.EOCSelection = ADC_EOC_SINGLE_CONV;
  hadc1.Init.LowPowerAutoWait = DISABLE;
  hadc1.Init.ContinuousConvMode = DISABLE;
  hadc1.Init.NbrOfConversion = 1;
  hadc1.Init.DiscontinuousConvMode = ENABLE;
  hadc1.Init.ExternalTrigConv = ADC_EXTERNALTRIG_T2_TRGO;
  hadc1.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_RISING;
  hadc1.Init.ConversionDataManagement = ADC_CONVERSIONDATA_DMA_CIRCULAR;
  hadc1.Init.Overrun = ADC_OVR_DATA_OVERWRITTEN;
  hadc1.Init.LeftBitShift = ADC_LEFTBITSHIFT_NONE;
  hadc1.Init.OversamplingMode = DISABLE;
  if (HAL_ADC_Init(&hadc1) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Configure the ADC multi-mode
  */
  multimode.Mode = ADC_DUALMODE_REGSIMULT;
  multimode.DualModeData = ADC_DUALMODEDATAFORMAT_32_10_BITS;
  multimode.TwoSamplingDelay = ADC_TWOSAMPLINGDELAY_1CYCLE;
  if (HAL_ADCEx_MultiModeConfigChannel(&hadc1, &multimode) != HAL_OK)
  {
    Error_Handler();
  }
 
  /** Configure Regular Channel
  */
  sConfig.Channel = ADC_CHANNEL_3;
  sConfig.Rank = ADC_REGULAR_RANK_1;
  sConfig.SamplingTime = ADC_SAMPLETIME_1CYCLE_5;
  sConfig.SingleDiff = ADC_DIFFERENTIAL_ENDED;
  sConfig.OffsetNumber = ADC_OFFSET_NONE;
  sConfig.Offset = 0;
  sConfig.OffsetSignedSaturation = DISABLE;
  if (HAL_ADC_ConfigChannel(&hadc1, &sConfig) != HAL_OK)
  {
    Error_Handler();
  }

And DMA initialization seems to happen inside ADC init.

 

 

 

5 REPLIES 5
Foued_KH
ST Employee

Hello @MHilt.1​ ,

I recommend you to follow properly the steps as described in this wiki page : Getting started with ADC - stm32mcu.

Also, you can get inspired from the available example in the STM32Cube package.

Foued

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.

MHilt.1
Associate

You answer is not helpful at all, and does not even address the topic in question. The page you linked describes setting up a single ADC.

I have no problems setting up a single ADC, that is trivial.

However, the page fleetingly mentions that dual modes do exist, but does not give any hints on how to use them.

I am left to assume your devices do not work as advertised.

AKhot.1
Senior

Did you find the solution to this? I am also trying to use dual regular simultaneous mode but I couldn't find any documentation or any resource to use ADC1 and ADC2 together.

TDK
Guru

Dual mode DMA examples exist. Perhaps look at those. Compare register settings between those and your own code if that's what you are trying to achieve.

https://github.com/STMicroelectronics/STM32CubeH7/blob/master/Projects/NUCLEO-H743ZI/Examples/ADC/ADC_DualModeInterleaved/readme.txt

 

If you feel a post has answered your question, please click "Accept as Solution".
PatriceL
Associate III

Hi

I found your post while I'm also struggling with DUAL mode and DMA. I agree it's not well documented, and code examples are close to useless.

 

I'm fighting, so I'm on the verge on opening another thread here.

 

In the mean time, what I found is that there is no dedicated register to gather the 32 bits value that result from ADC1 value + ADC2 value : actually it looks like the concatenation of these two values are actually in ADC1_DR register, as you can read in app note AN3116 § 2. As an exemple in § 2.1.1 :

 

PatriceL_0-1732620251675.png

 

The code pointed to by @TDK is giving more help (and I fix my original reply here) : It looks like we only need 1 DMA channel to configure, and bound it to the master ADC, aka ADC1 since it looks like (at least in STM32U5 series) you cannot decide who is slave and who is master:

 

PatriceL_0-1732621091707.png