0
\$\begingroup\$

I am using STM32G431KB Nucleo for measure a potentiometer voltage via ADC1_IN1 and ADC1_IN2 channels with Scan Mode DMA. And my samples arrays are always zero, no change. I share my code below. What did you think the problem is?

static void MX_ADC1_Init(void) {
    // Enable the clock for ADC1
    RCC->AHB2ENR |= RCC_AHB2ENR_ADC12EN;
    RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
    // Configure the ADC1 clock source (assume synchronous clock mode)
    RCC->CCIPR &= ~RCC_CCIPR_ADC12SEL;
    RCC->CCIPR |= RCC_CCIPR_ADC12SEL_1;

    // Power up the ADC1
    ADC1->CR &= ~ADC_CR_DEEPPWD;
    ADC1->CR |= ADC_CR_ADVREGEN;

    // Wait for ADC voltage regulator to stabilize
    for (volatile uint32_t delay = 0; delay < 10000; delay++);

    // Disable ADC1 before calibration
    ADC1->CR &= ~ADC_CR_ADEN;

    // Calibrate the ADC1
    ADC1->CR &= ~ADC_CR_ADCALDIF;
    ADC1->CR |= ADC_CR_ADCAL;

    // Wait for calibration to complete
    while (ADC1->CR & ADC_CR_ADCAL);

    // Configure ADC common settings
    ADC12_COMMON->CCR &= ~(ADC_CCR_PRESC | ADC_CCR_CKMODE);
    ADC12_COMMON->CCR |= (ADC_CCR_CKMODE_0 | ADC_CCR_CKMODE_1);
    ADC12_COMMON->CCR |= ADC_CCR_PRESC_3;

    // Configure ADC1 resolution and continuous conversion mode
    ADC1->CFGR &= ~ADC_CFGR_RES;         // 12-bit resolution
    ADC1->CFGR |= ADC_CFGR_CONT;         // Continuous conversion mode
    ADC1->CFGR |= ADC_CFGR_DMAEN;
    ADC1->CFGR |= ADC_CFGR_DMACFG;
    // Configure ADC1 channels (sequence)
    ADC1->SQR1 &= ~ADC_SQR1_SQ1_Msk;
    ADC1->SQR1 |= (1 << ADC_SQR1_SQ1_Pos); // First conversion in regular sequence: ADC1_IN1 (PA0)
    ADC1->SQR1 &= ~ADC_SQR1_SQ2_Msk;
    ADC1->SQR1 |= (2 << ADC_SQR1_SQ2_Pos); // Second conversion in regular sequence: ADC1_IN2 (PA1)
    ADC1->SQR1 &= ~ADC_SQR1_L_Msk;
    ADC1->SQR1 |= (1 << ADC_SQR1_L_Pos);   // Sequence length: 2 conversions

    DMA1_Channel1->CPAR = (uint32_t)(&(ADC1->DR));
    DMA1_Channel1->CMAR = (uint32_t)samples;
    DMA1_Channel1->CNDTR = 2;
    DMA1_Channel1->CCR |= DMA_CCR_CIRC | DMA_CCR_MINC | DMA_CCR_PSIZE_1 | DMA_CCR_MSIZE_1 | DMA_CCR_PL_1;
    DMA1_Channel1->CCR |= DMA_CCR_EN;

    // Enable ADC1
    ADC1->CR |= ADC_CR_ADEN;

    // Wait until ADC1 is ready
    while (!(ADC1->ISR & ADC_ISR_ADRDY));

    // Start ADC1 conversion
    ADC1->CR |= ADC_CR_ADSTART;
}

I make some changes about configurations and code looks like this. Nothing solved yet. Same problem. I add ADCMUX as STM32G4 have ADCMUX block and I guess it needs a config so I make configs.

static void MX_DMA1_Init(void) {

    RCC->AHB1ENR |= RCC_AHB1ENR_DMA1EN;
    RCC->AHB1ENR |= RCC_AHB1ENR_DMAMUX1EN;
    DMAMUX1_Channel1->CCR = 0;
    DMAMUX1_Channel1->CCR |= (5 << DMAMUX_CxCR_DMAREQ_ID_Pos);
    DMA1_Channel1->CPAR = (uint32_t)(&(ADC1->DR));
    DMA1_Channel1->CMAR = (uint32_t)samples;
    DMA1_Channel1->CNDTR = 2;
    DMA1_Channel1->CCR &= ~DMA_CCR_MEM2MEM;
    DMA1_Channel1->CCR &= ~DMA_CCR_DIR;
    DMA1_Channel1->CCR |= DMA_CCR_CIRC | DMA_CCR_MINC | DMA_CCR_PSIZE_0 | DMA_CCR_MSIZE_0 | DMA_CCR_PL_1;
    DMA1_Channel1->CCR |= DMA_CCR_EN;

}

static void MX_ADC1_Init(void) {

    RCC->AHB2ENR |= RCC_AHB2ENR_ADC12EN;
    RCC->CCIPR &= ~RCC_CCIPR_ADC12SEL;
    RCC->CCIPR |= RCC_CCIPR_ADC12SEL_1;

    ADC1->CR &= ~ADC_CR_DEEPPWD;
    ADC1->CR |= ADC_CR_ADVREGEN;

    for (volatile uint32_t delay = 0; delay < 10000; delay++);

    ADC1->CR &= ~ADC_CR_ADEN;

    ADC1->CR &= ~ADC_CR_ADCALDIF;
    ADC1->CR |= ADC_CR_ADCAL;

    while (ADC1->CR & ADC_CR_ADCAL);

    ADC12_COMMON->CCR &= ~(ADC_CCR_PRESC | ADC_CCR_CKMODE);
    ADC12_COMMON->CCR |= (ADC_CCR_CKMODE_0 | ADC_CCR_CKMODE_1);
    ADC12_COMMON->CCR |= ADC_CCR_PRESC_3;


    ADC1->CFGR &= ~ADC_CFGR_RES;         // 12-bit resolution
    ADC1->CFGR |= ADC_CFGR_CONT;         // Continuous conversion mode
    ADC1->CFGR |= ADC_CFGR_DMAEN;
    ADC1->CFGR |= ADC_CFGR_DMACFG;

    ADC1->SMPR1 |= ADC_SMPR1_SMP1_2 | ADC_SMPR1_SMP2_2;
    //ADC1->CR |= ADC_CR_ADSTP;
    ADC1->SQR1 &= ~ADC_SQR1_SQ1_Msk;
    ADC1->SQR1 |= (1 << ADC_SQR1_SQ1_Pos); // First conversion in regular sequence: ADC1_IN1 (PA0)
    ADC1->SQR1 &= ~ADC_SQR1_SQ2_Msk;
    ADC1->SQR1 |= (2 << ADC_SQR1_SQ2_Pos); // Second conversion in regular sequence: ADC1_IN2 (PA1)
    ADC1->SQR1 &= ~ADC_SQR1_L_Msk;
    ADC1->SQR1 |= (1 << ADC_SQR1_L_Pos);   // Sequence length: 2 conversions


    ADC1->CR |= ADC_CR_ADEN;

    while (!(ADC1->ISR & ADC_ISR_ADRDY));

    ADC1->CR |= ADC_CR_ADSTART;

}

Other codes are RCC Config and GPIO Config I am sure they don't have an issue.

\$\endgroup\$
0

1 Answer 1

0
\$\begingroup\$
  1. Make sure your GPIO's are configured as inputs (I believe PA1 and PA2)

  2. Make sure your DMAMUX1 channel is pointed to ADC1

    DMAMUX1_Channel1->CCR = 0; DMAMUX1_Channel1->CCR |= (5 << DMAMUX_CxCR_DMAREQ_ID_Pos); // ADC1

  3. Check your sampling time config:

    ADC1->SMPR1 |= ADC_SMPR1_SMP1_2 | ADC_SMPR1_SMP2_2; // Set sampling time for ADC1_IN1 and ADC1_IN2

  4. Check DMA Channel configuration:

    DMA1_Channel1->CCR |= DMA_CCR_CIRC | DMA_CCR_MINC; // Circular mode, memory increment mode DMA1_Channel1->CCR |= DMA_CCR_PSIZE_0 | DMA_CCR_MSIZE_0 | DMA_CCR_PL_1; // Peripheral and memory size: 16-bit, priority level: high

But one thing you may want to do is use cubemx to set this all up and autogenerate the code and then look at that.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.