I am trying to figure out how this DMA Initialization code is used to sample following 4 ADC channels and save data in 'adc_data'.

ADC1: channel 1 & channel 3.
ADC2: channel 2 & channel 4.

To me it looks like incomplete code as it is only initializing ADC1 but not ADC2. My MCU is STM32L476.

extern volatile uint32_t adc_data[];

  // DMA for ADC1
  // Wait a bit
  nop(); nop(); nop(); nop(); nop(); nop();
  DMA1_Channel1->CPAR = (uint32_t)&(ADC123_COMMON->CDR);
  DMA1_Channel1->CMAR = (uint32_t)&adc_data;
  DMA1_Channel1->CNDTR = 2;
                       DMA_CCR_CIRC | DMA_CCR_TCIE | DMA_CCR_EN;
  • \$\begingroup\$ It is incomplete code indeed. You need to see where adc_data is allocated. Somewhere someone must tell the linker what adc_data is and where it is allocated. This is one of many reasons why we should never do spaghetti programming with extern. \$\endgroup\$ – Lundin Apr 16 '19 at 10:39

You can setup the ADC1 and ADC2 in a master-slave configuration. That will result in the samples of both ADCs being written to one common data register.

That data register is 32 bit wide, so transferring just 2 samples will actually contain the result of 4 conversions (2 from ADC1 and 2 from ADC2).

In the code to use the samples they should get extracted from the adc_data[] as they won't be useful as a single uint32_t.

For more information see the Reference Manual in Section 16.3.30 Dual ADC Modes.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.