cancel
Showing results for 
Search instead for 
Did you mean: 

Is there any example with DMA and ADC1 for the STM32G431 using the Low-Level layer?

jvadillo
Associate II

I am trying to make the ADC and the DMA work in the STM32G431 without success. I can make the ADC work but the DMA transaction is not triggered.

This is my code:

//******************************************************************************
void ADCInit(void)
//******************************************************************************
{
  LL_GPIO_InitTypeDef    GPIO_InitStructure;
  LL_ADC_InitTypeDef     adcInit;
  LL_ADC_REG_InitTypeDef adcRegInit;
  
  // Enable clocks
  LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_GPIOA|LL_AHB2_GRP1_PERIPH_GPIOB);
  LL_AHB2_GRP1_EnableClock(LL_AHB2_GRP1_PERIPH_ADC12);
 
  // Reset any previous configuration
  LL_ADC_CommonDeInit(ADC12_COMMON);
  LL_ADC_DeInit(ADC1);  // For voltage and current  
  
  // Enable Power regulators
  LL_ADC_DisableDeepPowerDown(ADC1);
  LL_ADC_EnableInternalRegulator(ADC1);
  LL_ADC_SetCommonClock(ADC12_COMMON, LL_ADC_CLOCK_SYNC_PCLK_DIV1);
  Delay(100);  // tADCVREG_STUP = 20us --> stabilization
  
  // Start calibration of the ADCs
  LL_ADC_StartCalibration(ADC1,LL_ADC_SINGLE_ENDED);
  while (LL_ADC_IsCalibrationOnGoing(ADC1));  
  
  LL_ADC_SetCommonPathInternalCh(ADC12_COMMON, LL_ADC_PATH_INTERNAL_VREFINT);
  
  // Configure all analog pins
  GPIO_InitStructure.Mode       = LL_GPIO_MODE_ANALOG;
  GPIO_InitStructure.OutputType = LL_GPIO_OUTPUT_PUSHPULL;
  GPIO_InitStructure.Speed      = LL_GPIO_SPEED_HIGH;
  GPIO_InitStructure.Pull       = LL_GPIO_PULL_NO;
  
  GPIO_InitStructure.Pin =  LL_GPIO_PIN_0;
  LL_GPIO_Init(GPIOA, &GPIO_InitStructure);  
  GPIO_InitStructure.Pin =  LL_GPIO_PIN_1;   
  LL_GPIO_Init(GPIOA, &GPIO_InitStructure);  
  
  memset((void *)iSamplingBuf,0xFF,sizeof(iSamplingBuf));
 
  // Now Initialize the ADCs
  LL_ADC_StructInit(&adcInit);
  adcInit.Resolution    = LL_ADC_RESOLUTION_12B;
  adcInit.DataAlignment = LL_ADC_DATA_ALIGN_RIGHT;
  adcInit.LowPowerMode  = LL_ADC_LP_MODE_NONE;
  LL_ADC_Init(ADC1, &adcInit);
  
  LL_ADC_REG_StructInit(&adcRegInit);
  adcRegInit.TriggerSource    = LL_ADC_REG_TRIG_SOFTWARE;
  adcRegInit.SequencerDiscont = LL_ADC_REG_SEQ_DISCONT_DISABLE;
  adcRegInit.ContinuousMode   = LL_ADC_REG_CONV_SINGLE;
  adcRegInit.DMATransfer      = LL_ADC_REG_DMA_TRANSFER_LIMITED;
  adcRegInit.Overrun          = LL_ADC_REG_OVR_DATA_OVERWRITTEN;
  adcRegInit.SequencerLength  = LL_ADC_REG_SEQ_SCAN_DISABLE;
  LL_ADC_REG_Init(ADC1, &adcRegInit);
  
  LL_ADC_REG_SetSequencerRanks (ADC1,LL_ADC_REG_RANK_1,LL_ADC_CHANNEL_1);
  LL_ADC_REG_SetSequencerRanks (ADC1,LL_ADC_REG_RANK_2,LL_ADC_CHANNEL_2);
  LL_ADC_SetChannelSamplingTime(ADC1,LL_ADC_CHANNEL_1, LL_ADC_SAMPLINGTIME_47CYCLES_5);
  LL_ADC_SetChannelSingleDiff  (ADC1,LL_ADC_CHANNEL_1, LL_ADC_SINGLE_ENDED);
  LL_ADC_SetChannelSamplingTime(ADC1,LL_ADC_CHANNEL_2, LL_ADC_SAMPLINGTIME_47CYCLES_5);
  LL_ADC_SetChannelSingleDiff  (ADC1,LL_ADC_CHANNEL_2, LL_ADC_SINGLE_ENDED);
  LL_ADC_REG_SetSequencerLength(ADC1,LL_ADC_REG_SEQ_SCAN_DISABLE);
 
  
  
  LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1); //enable clock
  LL_DMA_ConfigTransfer(DMA1,
                        LL_DMA_CHANNEL_1,
                        LL_DMA_DIRECTION_PERIPH_TO_MEMORY |
                        LL_DMA_MODE_CIRCULAR |
                        LL_DMA_PERIPH_NOINCREMENT |
                        LL_DMA_MEMORY_INCREMENT |
                        LL_DMA_PDATAALIGN_HALFWORD |
                        LL_DMA_MDATAALIGN_HALFWORD |
                        LL_DMA_PRIORITY_HIGH );
  LL_DMA_SetPeriphRequest(DMA1, LL_DMA_CHANNEL_1, LL_DMAMUX_REQ_ADC1);
  
  LL_DMA_ConfigAddresses(DMA1,
                         LL_DMA_CHANNEL_1,
                         LL_ADC_DMA_GetRegAddr(ADC1, LL_ADC_DMA_REG_REGULAR_DATA),
                         (uint32_t)iSamplingBuf,
                         LL_DMA_DIRECTION_PERIPH_TO_MEMORY);
  LL_DMA_SetDataLength(DMA1, LL_DMA_CHANNEL_1, ARRAYSIZE(iSamplingBuf));
  LL_DMA_EnableChannel(DMA1, LL_DMA_CHANNEL_1); 
  
  
  // Enable ADC1
  LL_ADC_ClearFlag_ADRDY(ADC1);
  LL_ADC_Enable(ADC1);
  while (!LL_ADC_IsEnabled(ADC1));
 
  LL_ADC_REG_StartConversion(ADC1);
  
  for (;;)
  {
    
  }
}  
 

What I am doing wrong?

Is there any example with DMA and ADC1 for the STM32G431 using the Low-Level layer?

1 ACCEPTED SOLUTION

Accepted Solutions
jvadillo
Associate II

After working some hours on the subject and with the help of the STM32 Cube MX code generator, I found that the ADCMUX clock initialization was missing:

LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMAMUX1);

View solution in original post

4 REPLIES 4
jvadillo
Associate II

Is there any person working with an STM32G4 and using the ADC with the DMA?

jvadillo
Associate II

After working some hours on the subject and with the help of the STM32 Cube MX code generator, I found that the ADCMUX clock initialization was missing:

LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMAMUX1);

I am working on ADC w/DMA. Using HAL libraries and SATM32CUBEMX for config. But i am facing issues, not able to get any output using DMA interface

AScen.1
Associate II

Does the above example with the below 2 lines to configure the clocks work fine?

LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMA1);

LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_DMAMUX1);

For the above code, few LL APIs like the below give me compilation error and the others are fine.

For example, "undefined reference to `LL_ADC_DeInit' ". Any idea why?

LL_ADC_DeInit()

LL_GPIO_Init()

LL_ADC_Init()

Here are my includes:

#include <zephyr.h>

#include <sys/printk.h>

#include <drivers/adc.h>

#include <stm32g4xx_ll_system.h>

#include <stm32g4xx_ll_dma.h>

#include <stm32g4xx_ll_adc.h>