cancel
Showing results for 
Search instead for 
Did you mean: 

STM32H7 ADC dual mode simultanious mode problem

Mr_M_from_G
Senior II

Hello,

I am working with STM32H743, using ADC1 and 2 in dual simultanious mode, using DMA to store data from ADC_CDR (2 16 bit values) to memory, some hundred values in a stream in continuous mode. This works fine in general but I frequently see a missynchronisation between the two ADCs so that at the output of DMA I have in one 32bit word the lower half word from one ADC1 conversion of one point in time and in the upper half word the ADC2 conversion from the preceeding or succeeding point in time (I didn't check which of the two, but it is only one of them).

I read RM0433 ADC section up and down and could not find anything about that. It seems to be more related to hardware, that sometimes triggering DMA does not properly wait for both ADCs to be ready and have their data transfered to ACD_CDR. But it is not occuring or not from sample to sample but it is there for one complete data stream or not, so it seems to be set or not with every setting of ADSTART.

Here is my ADC init code:

#define SetBitMask(Var,BitMask) (Var|=(BitMask))

  SetBitMask (ADC1->CFGR, ADC_CFGR_RES_0);  // 14 bit
  SetBitMask (ADC2->CFGR, ADC_CFGR_RES_0);  // 14 bit
  SetBitMask (ADC1->DIFSEL, ADC_DIFSEL_DIFSEL_3);
  SetBitMask (ADC2->DIFSEL, ADC_DIFSEL_DIFSEL_4);
  ADC1->OFR1 = 0x8000 | (3 << ADC_OFR1_OFFSET1_CH_Pos); // offset for 16 bit signed values
  ADC2->OFR1 = 0x8000 | (4 << ADC_OFR1_OFFSET1_CH_Pos); // offset for 16 bit signed values
  ADC1->SQR1 = (3 << ADC_SQR1_SQ1_Pos) | (1-1); 
  ADC1->PCSEL = 1 << 3;
  ADC1->SMPR1 = 0; // 1.5 clk cycles sampling time
  ADC2->SQR1 = (4 << ADC_SQR1_SQ1_Pos) | (1-1);
  ADC2->PCSEL = 1 << 4;
  ADC2->SMPR1 = 0; // 1.5 clk cycles sampling time
 
  // the above settings result in:
  // for the two differential channels 3 and 4: 14 bit res, formatted as signed values -8192..8191, input res = 0.4mV diff / count
  // for the other = single ended channels: 14 bit res, formatted as unsigned values 0.. 16383, input res = 0.2mV / count
  // in continuous conversion mode (selected below) we get 1.5 + 7.5 = 9 clock cycles conversion time = 9 * 1/34,56 MHz = 260,417nsec corresp. to 3840 kSps
 
  // injected channels :
  // put them in the sequence so that ADC1 is in JDR1, ADC2 is in JDR2, ADC3 is in JDR3, where ADC1 = PA1, ADC2 = PA2, ADC3 = PA3
  ADC1->JSQR = (17 << ADC_JSQR_JSQ1_Pos) | (14 << ADC_JSQR_JSQ2_Pos) | (15 << ADC_JSQR_JSQ3_Pos) | (3-1);
  ADC1->PCSEL |= (1 << 14) | (1 << 15) | (1 << 17);
  ADC1->SMPR2 = (4 << ADC_SMPR2_SMP14_Pos) | (4 << ADC_SMPR2_SMP15_Pos) | (4 << ADC_SMPR2_SMP17_Pos); // 4 = 32.5 clk cycles, slow channels: max 1Msps
 
  SetBitMask (ADC12_COMMON->CCR, ADC_CCR_DUAL_0 | ADC_CCR_DAMDF_1); // dual mode with output to ADC_CDR
  SetBitMask (ADC1->CFGR, ADC_CFGR_CONT | ADC_CFGR_DMNGT_0  | ADC_CFGR_DMNGT_1); // ADC in continuous mode and in DMA circular mode
 

Is there any information about that?

Anybody experienced the same? - and solved it 😉

Thanks a lot

Martin

22 REPLIES 22
KlausZ
Associate

use "dual interleaved mode" instead

PAkRad
Associate III

Yes, it is that same issue.

IT is something not controlled at HW level.

Actually some times the ADC2 is one sample ahead of ADC1 and viceversa.

In the opening post, injected channels are set up. Can't the problem be caused by using those, i.e. using injected conversions?

JW