2020-03-13 03:48 AM
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
2024-02-25 10:50 PM
use "dual interleaved mode" instead
2024-03-13 03:18 AM
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.
2024-03-14 08:55 AM
In the opening post, injected channels are set up. Can't the problem be caused by using those, i.e. using injected conversions?
JW