arduino / arduino/ArduinoCore-mbed

ADC channel weird interaction within a sequence PortentaH7

Open
#514 2 comments 0 reactions 0 assignees View on GitHub
Dominant language
C
Stars
411
Forks
225
PR merge metrics
No merged PRs in 30d

Description

I am using the pin A0 (PA0_C) of the Portenta which is linked to the ADC1_INP1 when I use it alone it does its job properly and convert the signal to digital values. The code for ADC :
```
void ADC_Init(void) {
/*******************Horloges**************************/
SET_BIT(RCC_C2->APB4ENR, RCC_APB4ENR_SYSCFGEN_Msk); //SYSCFG clock
delay(1000);
SET_BIT(RCC_C2->APB4ENR, RCC_APB4ENR_RTCAPBEN_Msk); //RTCAPB clock
delay(1000);
SET_BIT(RCC_C2->AHB1ENR, RCC_AHB1ENR_ADC12EN_Msk); //ADC12 clocks
delay(1000);
SET_BIT(RCC_C2->AHB4ENR, RCC_AHB4ENR_GPIOAEN_Msk); //GPIOA clock
delay(1000);
// SET_BIT(RCC_C2->AHB4ENR, RCC_AHB4ENR_GPIOCEN_Msk); //GPIOA clock
// delay(1000);
/********************Port config************************/
//AO
SET_BIT(GPIOA->MODER, GPIO_MODER_MODE1_0);
SET_BIT(GPIOA->MODER, GPIO_MODER_MODE1_1);
CLEAR_BIT(GPIOA->PUPDR, GPIO_PUPDR_PUPD1_0);
CLEAR_BIT(GPIOA->PUPDR, GPIO_PUPDR_PUPD1_1);
//A3
SET_BIT(GPIOC->MODER, GPIO_MODER_MODE3_0);
SET_BIT(GPIOC->MODER, GPIO_MODER_MODE3_1);
CLEAR_BIT(GPIOC->PUPDR, GPIO_PUPDR_PUPD3_0);
CLEAR_BIT(GPIOC->PUPDR, GPIO_PUPDR_PUPD3_1);

CLEAR_BIT(SYSCFG->PMCR, SYSCFG_PMCR_PA0SO_Msk);
delay(1000);//PA0_C in analog mode
/********************ADC voltage regulator***************/
CLEAR_BIT(ADC1->CR, ADC_CR_DEEPPWD_Msk); //END DEEPPWD
SET_BIT(ADC1->CR, ADC_CR_ADVREGEN_Msk); //ENABLE ADC VOLTAGE REG
delay(1000);//WAIT VOLTAGE REG
/********************ADC calibration*********************/
CLEAR_BIT(ADC1->CR, ADC_CR_ADCALDIF_Msk);
SET_BIT(ADC1->CR, ADC_CR_ADCALLIN_Msk);
SET_BIT(ADC1->CR, ADC_CR_ADCAL_Msk);
while (ADC_CR_ADCAL & ADC_CR_ADCAL_Msk != 0) {}
/******************ADC clock*****************************/
SET_BIT(ADC12_COMMON->CCR, ADC_CCR_CKMODE_0 | ADC_CCR_CKMODE_1);
/*******************ADC Prescaler************************/
SET_BIT(ADC12_COMMON->CCR, ADC_CCR_PRESC_0 | ADC_CCR_PRESC_1 );
/*******************Input Mode***************************/
CLEAR_BIT(ADC1->DIFSEL, ADC_DIFSEL_DIFSEL_0); //Single Ended
/*******************ADC Enable***************************/
SET_BIT(ADC1->ISR, ADC_ISR_ADRDY_Msk);
SET_BIT(ADC1->CR, ADC_CR_ADEN_Msk);
while (ADC_ISR_ADRDY & ADC_ISR_ADRDY_Msk != 1) {}
SET_BIT(ADC1->ISR, ADC_ISR_ADRDY_Msk);
/*******************Ajout du facteur de calibration linéaire**********/
// SET_BIT(ADC1->CR,ADC_CR_LINCALRDYW6_Msk);
// while(ADC_CR_LINCALRDYW6 & ADC_CR_LINCALRDYW6_Msk !=1){}

/********************ADC RES*****************************/
//SET_BIT(ADC1->CFGR, ADC_CFGR_RES_2 | ADC_CFGR_RES_1);
CLEAR_BIT(ADC1->CFGR, ADC_CFGR_RES_0 | ADC_CFGR_RES_1 | ADC_CFGR_RES_2);
/********************ADC Data Management*****************/
SET_BIT(ADC1->CFGR, ADC_CFGR_DMNGT_0 | ADC_CFGR_DMNGT_1);//DMA Circular mode
/********************OVRMODE*****************************/
SET_BIT(ADC1->CFGR, ADC_CFGR_OVRMOD_Msk); //Erase old data
/*******************RSHIFT****************************/
SET_BIT(ADC1->CFGR2, ADC_CFGR2_RSHIFT1_Msk | ADC_CFGR2_RSHIFT2_Msk | ADC_CFGR2_RSHIFT3_Msk | ADC_CFGR2_RSHIFT4_Msk);
/********************CONT/Single/Discont*****************/
CLEAR_BIT(ADC1->CFGR, ADC_CFGR_DISCEN_Msk); // discontinuous mode
CLEAR_BIT(ADC1->CFGR, ADC_CFGR_CONT_Msk); // | ADC_CFGR_DISCEN_Msk

/********************Trigger Detection*******************/
SET_BIT(ADC1->CFGR, ADC_CFGR_EXTEN_0 | ADC_CFGR_EXTSEL_1 | ADC_CFGR_EXTSEL_3);//Trig rising edge TRGO2
CLEAR_BIT(ADC1->CFGR, ADC_CFGR_EXTEN_1 | ADC_CFGR_EXTSEL_0 | ADC_CFGR_EXTSEL_2 | ADC_CFGR_EXTSEL_4);
/********************INput Preselection******************/
SET_BIT(ADC1->PCSEL, ADC_PCSEL_PCSEL_1);//Chan 1
/********************Sample Time reg*********************/
SET_BIT(ADC1->SMPR1, ADC_SMPR1_SMP1_0); //2.5 CLCK Cycles
/********************ADC IT******************************/

SET_BIT(ADC1->IER, ADC_IER_EOCIE_Msk | ADC_IER_EOSMPIE_Msk );//| ADC_IER_EOSIE_Msk | ADC_IER_OVRIE_Msk
NVIC_EnableIRQ(ADC_IRQn);
NVIC_SetVector(ADC_IRQn, (uint32_t)&ADC_IRQHandler);
}
```
However when I add this line to add some channels afterward :
```
SET_BIT(ADC1->SQR1, ADC_SQR1_SQ1_0);
```
which should ask for a sequence of conversion of 1 channel with the first channel being INP1 I only read noise. What is even more disturbing to me is that when I don't add this line I get good result even though not writing it means having a sequence of 1 conv with chan 0 first but there is no chan0 for the ADC on the pin A0.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start in ADC_Init and compare the ADC1->SQR1 configuration with and without SET_BIT(ADC1->SQR1, ADC_SQR1_SQ1_0). Trace how PA0_C/A0 maps to ADC1_INP1, then inspect the configured sequence, preselection, and conversion results. Done means a one-channel sequence consistently returns the expected A0 signal rather than noise.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
embedded-iot
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.