Skip to main content
Visitor II
January 16, 2024
Solved

Restart One Shot ADC + DMA

  • January 16, 2024
  • 1 reply
  • 2349 views

Hi,

I have an STM32H747IGT6 that I wish to:

  1. Continuously sample 4096 ADC samples
  2. Transfer each sample from the peripheral to memory using DMA
  3. Trigger an interrupt at the end of the conversions
  4. After the CPU operates on the stored data, restart the process at item (1)

The process works fine through (3) with the ADC configured as LL_ADC_REG_DMA_TRANSFER_LIMITED and the DMA configured with LL_DMA_MODE_NORMAL. However, I can't figure out how to restart the DMA / ADC. Can anyone offer guidance on how to restart a one shot DMA transfer to memory from an ADC?

The ADC conversions are triggered from a timer. 

Thanks!

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

    Ok, the missing step is to start a new conversion on the ADC. For others, see below using LL API. 

     

     

     LL_DMA_ConfigAddresses(DMA1,
     LL_DMA_STREAM_1,
     LL_ADC_DMA_GetRegAddr(ADC2, LL_ADC_DMA_REG_REGULAR_DATA),
     (uint32_t)&shared_mem[SHMEM_SAMPLE_0_INDEX],
     LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
     LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_1, SHMEM_NUM_SAMPLES);
     LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_1);
     LL_ADC_REG_StartConversion(ADC2);

     

    1 reply

    Super User
    January 16, 2024

    Set the memory address back to the beginning of the buffer.

    Set the number of transfers.

    (Re)start the stream.

    slc2015Author
    Visitor II
    January 16, 2024

    Hi TDK,

    I've tried those steps and I agree they seem sensible for the DMA end. However, it seems like the ADC is still stopped after the end of the transfer and no more DMA requests are being generated. 

    The reference manual shows the following with no mention of how to restart the ADc for a second one shot sequence. 

    slc2015_0-1705447519382.png

     

    slc2015AuthorAnswer
    Visitor II
    January 16, 2024

    Ok, the missing step is to start a new conversion on the ADC. For others, see below using LL API. 

     

     

     LL_DMA_ConfigAddresses(DMA1,
     LL_DMA_STREAM_1,
     LL_ADC_DMA_GetRegAddr(ADC2, LL_ADC_DMA_REG_REGULAR_DATA),
     (uint32_t)&shared_mem[SHMEM_SAMPLE_0_INDEX],
     LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
     LL_DMA_SetDataLength(DMA1, LL_DMA_STREAM_1, SHMEM_NUM_SAMPLES);
     LL_DMA_EnableStream(DMA1, LL_DMA_STREAM_1);
     LL_ADC_REG_StartConversion(ADC2);