Skip to main content
Explorer II
January 9, 2025
Solved

ADC in continuous mode with DMA stops instead of running indefinitely

  • January 9, 2025
  • 3 replies
  • 1847 views

We have a STM32U575xx chip, where I want to read a bunch of voltages continuously.

These voltages don't need to be measured at a particularly high rate, nor does the timing need to be strict. So it seemed efficient to run the ADC continuously with DMA. We expect that somewhere in memory there are constantly updating ADC readouts, and we can read these values when we want to, without any blocking calls. Any unused values can just be overwritten again.

However, this doesn't work entirely: we can do a non-blocking ADC read with DMA, but it seems to be only a single read, while I was expected a continuous readout because the ADC is in independent mode.

We start the ADC/DMA on init:

 

 HAL_ADCEx_Calibration_Start(&hadc1, ADC_CALIB_OFFSET_LINEARITY, ADC_SINGLE_ENDED);
 HAL_ADC_Start_DMA(&hadc1, m_adc1Values, Adc1NbrChannels);

 

Why does this ADC stop? Am I missing a setting, or does 'continuous' and 'independent' not mean what I expect it to?

 

It concerns ADC1, channels 1 to 7. We set it up with GPDMA1, channel 0. The complete CubeMX configuration is below.

 

Our workaround now is to just restart it whenever the DMA has stopped, with this entry in our on-tick callback:

 

 if (HAL_IS_BIT_CLR(hadc1.Instance->ISR, ADC_FLAG_EOC))
 {
 HAL_ADC_Start_DMA(&hadc1, m_adc1Values, Adc1NbrChannels);
 }

 

 

 

    This topic has been closed for replies.
    Best answer by Robert_149494

    I think I've found the solution (but it's hard to adequately test currently).

    I found two settings that were incorrect:

    Robert_149494_0-1737969373779.png

    "DMA continuous conversions" should be Enabled (don't know how I missed that) and "End of Conversion Selection" should be "End of sequence of conversion".

    With those settings I managed to get a continuously ADC, though I saw one of the channels produce only zeros. But that might have been an unrelated issue.

    3 replies

    Graduate II
    January 10, 2025

    Your screen shots are unreadable. 

    Explorer II
    January 13, 2025

    Really? The pictures are in high resolution and I can read them fine. You'd have to open the file in the browser and click the zoom button or download the bitmaps first and use a local viewer. Direct links:

    https://community.st.com/t5/stm32-mcus-products/adc-in-continuous-mode-with-dma-stops-instead-of-running/m-p/760651?attachment-id=29553

    https://community.st.com/t5/stm32-mcus-products/adc-in-continuous-mode-with-dma-stops-instead-of-running/m-p/760651?attachment-id=29554

    Graduate
    January 11, 2025

    In the code above, you don't start the ADC. You've only started the calibration process which is a one time thing. Wait until the calibration is done then setup the DMA and start the ADC.

    It will probably be useful to use continuous ADC conversion with DMA in circular mode. STM32 doesn't like it's ADC to be stopped for more than 0.5..1 ms.

    Explorer II
    January 13, 2025

    @gbm wrote:

    In the code above, you don't start the ADC. You've only started the calibration process which is a one time thing. Wait until the calibration is done then setup the DMA and start the ADC.


    HAL_ADC_Start_DMA() starts the ADC + DMA, doesn't it? I know for sure we do start it successfully, because we get proper readouts. And with that restarting loop above we get continuously updated values, it's just that I wanted to avoid this loop.

     


    @gbm wrote:

    It will probably be useful to use continuous ADC conversion with DMA in circular mode. STM32 doesn't like it's ADC to be stopped for more than 0.5..1 ms.


    DMA is already in circular mode, visible in the screenshot.

    Graduate
    January 13, 2025

    Just have a look inside of this function. Also you can look for similar named HAL calls, that would give you the clue, if you are calling the right one.

    Robert_149494AuthorAnswer
    Explorer II
    January 27, 2025

    I think I've found the solution (but it's hard to adequately test currently).

    I found two settings that were incorrect:

    Robert_149494_0-1737969373779.png

    "DMA continuous conversions" should be Enabled (don't know how I missed that) and "End of Conversion Selection" should be "End of sequence of conversion".

    With those settings I managed to get a continuously ADC, though I saw one of the channels produce only zeros. But that might have been an unrelated issue.