Skip to main content
Explorer
March 13, 2020
Question

STM32H7 ADC dual mode simultanious mode problem

  • March 13, 2020
  • 11 replies
  • 11024 views

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

    This topic has been closed for replies.

    11 replies

    March 29, 2020

    Did you use ver. Y or V of the chip?

    Explorer
    March 30, 2020
    Hi Mikhail,
    I have rev V, sorry, I forgot to mention.
    Martin
    April 9, 2020

    deleted

    Visitor II
    July 17, 2020

    I have the same problem. the DMA transfer seems to be triggered by the master EOC.

    When I select the same sample time for master and slave the DMA reads the previous slave sample. When the slave sample time is shorter than the master sample time it works correctly. When the sample time of the slave is larger than the master sample time the DMA transfer is triggered at the master EOC, so way before the slave is finished.

    I'm using rev V too. and am using the ChibiOS HAL. Only regular simultaneous mode, happens when either sampling 1 or more channels. Figure 202 of RM0433 (page 996) very clearly shows that the DMA request should only be sent after both master and slave EOC.

    It is a bit unclear from the reference manual when the 32 bit format on CDR2 is used and when the 16 bit format on CDR. Maybe it has to do something with that?

    I didn't try the Cube HAL yet, do people get correct results with that? Or is there an error in the silicon?

    July 18, 2020

    Do you use 1 or 2 DMA channels?

    Visitor II
    July 18, 2020

    1 DMA channel, getting data from ADC12_CDR,

    DMNGT = 11: DMA Circular Mode selected

    DAMDF = 10: Data formatting mode for 32 down to 10-bit resolution,

    DUAL = 00110: Regular simultaneous mode only

    Explorer
    July 22, 2020

    Hello all,

    thanks Piers for posting your description of the same problem.

    Now that we see clearly that this is not a problem of a single project but seems to be a hardware issue of the ADC peripheral I want to call ST members to give their statement to this. Is this a known problem? Can you reproduce it in your labs. Are there plans to fix it with the next revision?

    Thanks for some clarifying notes

    kind regards

    Martin

    Explorer
    October 29, 2021

    Hello ST community and ST employees in particular,

    the last days I had a really hard time finding an error in my project and it turned out to be this again. Although the two signals sampled with ADC1 and ADC2 are in phase by design they are not when looking at the ADC_CDR output,, there is a shift by one sample.

    This is really a hardware bug and it is embarrassing for ST to not even just put it into the errata.

    Explorer
    August 28, 2023

     


    @Mr_M_from_G wrote:

    Hello ST community and ST employees in particular,

     

    the last days I had a really hard time finding an error in my project and it turned out to be this again. Although the two signals sampled with ADC1 and ADC2 are in phase by design they are not when looking at the ADC_CDR output,, there is a shift by one sample.

    This is really a hardware bug and it is embarrassing for ST to not even just put it into the errata.


    I am seeing the same behaviour,is there any known solution to this?

    Best Regards

    Explorer
    April 18, 2022

    Hello all.

    We have developed in the past some devices using the STM32F4 and F7 families, with no issues using ADC+DMA+Timer Triggering with no effort (mostly tweaking the examples provided by ST and using the ioc Cube files).

    However, we are trying to do the same, but we are finding big issues with the H7 family, in specific when we use more than one ADC (to my knowledge this example is not provided by ST yet). There are also problems with the DMA (we have reader and moved the data buffers to RAM D2 area) and we do not see the triggering of the DMA interrupt with the Timer trigger.

    Maybe somebody in the forum knows one repository or is able to share a simple example of this structure (if it is based on STM32Cubemx ioc file the better, since for it will be easier to add things).

    Thank you in advance.

    Visitor II
    November 22, 2022

    Hello guys,

    About 3 weeks ago I encountered some problems about using ADC and DMA in simultaneous mode configuration. I noticed the forward shift of one adc channel inside DMA ( of the slave ADC in particularly).

    I carefully read your conversation and it seems that my problem is the same.

    Do you have some news about this ticket?

    Explorer
    November 22, 2022
    Hi Fmoll,
    thanks for reporting your issue.
    No, I don’t have any new information about that. Also ST members have never posted any comment.
    I think we have to collect more cases here, yours is number three or four
    So if anyone read this case and has the same issue, please post here ;)
    Visitor II
    February 26, 2024

    use "dual interleaved mode" instead

    Explorer
    March 13, 2024

    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.

    Super User
    March 14, 2024

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

    JW