Skip to main content
joshuahjamesmccrory
Associate II
March 10, 2017
Question

How to setup ADC DMA to synch with timer? STM32F4

  • March 10, 2017
  • 13 replies
  • 3925 views
Posted on March 10, 2017 at 22:43

I'm trying to setup 3 ADCs to read on a timer tick. On the STM32cube the timer can be set to 'Output Compare' to a single channel. And the ADC's can be set to external trigger conversion on a 'Timer Capture Compare # Event' Finally in the specific settings after a timer has been enabled, the timer can have a trigger event selection. If i'm trying to synch 3 ADCs to all write to separate buffers, what settings do i need to achieve that ?  

    This topic has been closed for replies.

    13 replies

    T J
    Senior III
    March 10, 2017
    Posted on March 11, 2017 at 00:59

    separate buffers require separate DMAs.

    page 404 of RM0090

    13.9 Multi ADC mode

    In devices with two ADCs or more, the Dual (with two ADCs) and Triple (with three ADCs)

    ADC modes can be used (see Figure 51).

    In multi ADC mode, the start of conversion is triggered alternately or simultaneously by the

    ADC1 master to the ADC2 and ADC3 slaves, depending on the mode selected by the

    MULTI[4:0] bits in the ADC_CCR register.

    Note: In multi ADC mode, when configuring conversion trigger by an external event, the

    application must set trigger by the master only and disable trigger by slaves to prevent

    spurious triggers that would start unwanted slave conversions.

    The four possible modes below are implemented:

    • Injected simultaneous mode

    • Regular simultaneous mode

    • Interleaved mode

    • Alternate trigger mode

    It is also possible to use the previous modes combined in the following ways:

    • Injected simultaneous mode + Regular simultaneous mode

    • Regular simultaneous mode + Alternate trigger mode

    Note: In multi ADC mode, the converted data can be read on the multi-mode data register

    (ADC_CDR). The status bits can be read in the multi-mode status register (ADC_CSR).
    joshuahjamesmccrory
    Associate II
    March 11, 2017
    Posted on March 11, 2017 at 01:30

    Thanks Nick, so since all the ADCs are connected to DMA2, i'm required to use one buffer to write all 3 of them to (if i want simultaneous writing to buffers)?

    So if that's the case i originally had multi (3 ADCs) mode working, but i couldn't seem to get the MemtoMem DMA working where i could get it to automatically transfer each portion (since triple mode writes each value as (ADC1 | ADC2 | ADC3 | ADC1 ...)  to thier own separate buffer after the fact. I don't know if you know how to accomplish that, or if i should just write all the data to flash and post-process the data to it's correct, separate, columns?

    Additionally, Would you mind detailing how to sync a single ADC to a timer to write thru DMA? Meaning I've got an internal clock synced timer so that the ADC writes to a buffer from DMA while synced to a clock. Could i use that same method to synch the triple mode to a single timer? Thanks for the response regardless!

    T J
    Senior III
    March 11, 2017
    Posted on March 11, 2017 at 02:09

    Hi again,

    in CubeMX

    you can set up three streams all using DMA2

    ie ADC1,ADC2 and ADC3 all using DMA2 but to pump data to different memory locations.

    Do you use HAL ?

    I can only use STM32F0xx series here, so I am not sure I can help much more than this.

    I will attach a STM32F427 Cube test file in the next window, since it will take 10 hours for the moderation to approve it...

    T J
    Senior III
    March 11, 2017
    Posted on March 11, 2017 at 05:06

    yes., I think you can automate the process by making the mast ADC trigger off the Timer and then the slave ADCs to trigger from the master.

    joshuahjamesmccrory
    Associate II
    March 11, 2017
    Posted on March 11, 2017 at 05:12

     ,

     ,

    Ok, i'm gonna put this out to clarify, i assume that under '

    Configuration | ADC | ADC_Regular_Conversion_Mode | External Trigger Conversion Source' the selection 'Timer ♯ Capture Compare ♯ Event' means: Whatever timer you choose, the 2nd number is the amount of ticks it looks for from the 'Output Compare' event from the selected timer. I.E. Timer 1 Capture Compare 2 event means it looks for two ticks before it writes one value from the ADC over DMA to memory.

    T J
    Senior III
    March 11, 2017
    Posted on March 11, 2017 at 05:20

    the timers have many output compare channels, usually 4 on some timers, less on others.

    it is the second channel.

    every time the selected output compare timer channel is matched to the timer counter, the ADC will fire.

    you can fire all 3 ADC's off the same Timer Output compare channel if you like.

    joshuahjamesmccrory
    Associate II
    March 11, 2017
    Posted on March 11, 2017 at 17:18

    Ok, So after digging a little more, i now know why i can't do what i was trying to do. Each DMA at a specific time step is only going to stransfer one piece of info from one point to another. My original intent was to have 3 ADCs simultaneously measuring values, drawing said values to separate buffers over DMA. On the STM32F407VG i'm using dedicates DMA2 to all ADCs, therefore i cannot physically write ADC values at the same exact time step to separate buffers since they all have to go across DMA2. So if i wanted to do 3 independant ADCs over DMA, they will be spaced apart by some sort of lag regardless since they all have to use the same DMA. Next i thought, well i could use Triple mode and at least have them organized and minimal time difference between each sample. With that i wanted to then use MEMTOMEM to separate the values from the one buffer that triple mode writes to into separate buffers, BUT MEMTOMEM also requires using DMA2, thus i cannot do that. Therefore i can only draw values over triple mode, then postprocess the data to separate the ADC outputs. Or use DMA MEMTOMEM after i'm done reading ADCs. If you use an MCU that has MEMTOMEM on separate DMAs OR the ADCs are on separate DMAs, then you can pull this off.

    Finally, to my original question. the most basic settings to get an ADC to sync with a timer, you can select a timer with a 'trigger out' event in the ADC settings: (C

    onfiguration | ADC | ADC_Regular_Conversion_Mode | External Trigger Conversion Source)

     Then under the timer settings: (C

    onfiguration | TIM# | Trigger Event Selection) You can select 'Update Event'. Not all timers have a 'Trigger Out' event, and i think the method above using Capture Compare Events works as well, as long as you select the correct trigger event selection in the timer settings (i don't know which setting is needed for a capture compare event yet) And the Timer settings under 'Pinout' are set to 'Output Compare, No Output' on a channel and then the channel is the 2nd Number on the '

    External Trigger Conversion Source' Capture Compare Event in the ADC settings.

    So my solution to 3 ADCs simultaneously is to use the triple mode (Make sure you use  'HAL_ADC_Start' for ADC2 and ADC3 1st, then '

    HAL_ADCEx_MultiModeStart_DMA

    ' for ADC1) to write data to a single buffer, use the MCU to write the values to a separate FLASH buffer, and either have buffer large enough to encompass all the data i want to capture, or have the write to flash rate be as minimal as i can to effectively capture the data i need.

    Please anyone feel free to correct anything i wrote on the wall of text above, thanks!

    T J
    Senior III
    March 11, 2017
    Posted on March 11, 2017 at 22:39

    You can make all 3 channels fetch an analog input simultaneously by triggering all 3 from the same output compare channel.

    if the DMAs grab those values with slightly different timing, that does not affect the instantaneous capture that you have saved in the 3 DR registers.

    that way you can still have 3 separate DMA channels automatically shifting data to separate channel data buffers

    Rich G
    Visitor II
    February 5, 2018
    Posted on February 05, 2018 at 19:22

    Hi, did you ever get this working?  I'm wanting to capture 3 analogue sources at a regular interval without loading the CPU.  i.e. using a timer to trigger ADC in scan mode and use DMA.  I just can't seem to get it working.  I cannot get the ADC capture complete callback to be invoked. I'm wanting to use CubeMX as much as possible; I'm new to this!

    Thank you! 

    T J
    Senior III
    February 5, 2018
    184254CGIL2