From 2f8b23a596f8424b68006b9c83094c8f8a76088f Mon Sep 17 00:00:00 2001 From: crasbe Date: Mon, 18 Nov 2024 20:54:53 +0100 Subject: [PATCH 1/2] cpu/stm32l0: fix ADC initialization order --- cpu/stm32/periph/adc_l0.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cpu/stm32/periph/adc_l0.c b/cpu/stm32/periph/adc_l0.c index e56d953f8774..99fad3c70d5d 100644 --- a/cpu/stm32/periph/adc_l0.c +++ b/cpu/stm32/periph/adc_l0.c @@ -128,9 +128,6 @@ int32_t adc_sample(adc_t line, adc_res_t res) /* lock and power on the ADC device */ prep(); - /* Enable ADC */ - _enable_adc(); - /* Reactivate VREFINT and temperature sensor if necessary */ if (adc_config[line].chan == 17) { ADC->CCR |= ADC_CCR_VREFEN; @@ -145,6 +142,9 @@ int32_t adc_sample(adc_t line, adc_res_t res) ADC1->CFGR1 |= res & ADC_CFGR1_RES; ADC1->CHSELR = (1 << adc_config[line].chan); + /* Enable ADC */ + _enable_adc(); + /* clear flag */ ADC1->ISR |= ADC_ISR_EOC; From 5de25c6f1370f2ddd574145016686634c7bafa06 Mon Sep 17 00:00:00 2001 From: crasbe Date: Tue, 19 Nov 2024 16:26:31 +0100 Subject: [PATCH 2/2] cpu/stm32l1: fix ADC initialization & resolution setting --- cpu/stm32/periph/adc_l1.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/cpu/stm32/periph/adc_l1.c b/cpu/stm32/periph/adc_l1.c index d7c97003c4d8..fc030be73b3c 100644 --- a/cpu/stm32/periph/adc_l1.c +++ b/cpu/stm32/periph/adc_l1.c @@ -131,8 +131,6 @@ int adc_init(adc_t line) ADC->CCR |= ADC_CCR_TSVREFE; } - /* enable the ADC module */ - ADC1->CR2 = ADC_CR2_ADON; /* turn off during idle phase*/ ADC1->CR1 = ADC_CR1_PDI; @@ -157,12 +155,18 @@ int32_t adc_sample(adc_t line, adc_res_t res) /* lock and power on the ADC device */ prep(); - /* set resolution, conversion channel and single read */ + /* mask and set resolution, conversion channel and single read */ + ADC1->CR1 &= ~ADC_CR1_RES_Msk; ADC1->CR1 |= res & ADC_CR1_RES; ADC1->SQR1 &= ~ADC_SQR1_L; ADC1->SQR5 = adc_config[line].chan; - /* wait for regulat channel to be ready*/ + /* only set ADON when ADONS bit is cleared (ADC not ready) */ + if(!(ADC1->SR & ADC_SR_ADONS_Msk)) { + ADC1->CR2 |= ADC_CR2_ADON; + } + + /* wait for regular channel to be ready*/ while (!(ADC1->SR & ADC_SR_RCNR)) {} /* start conversion and wait for results */ ADC1->CR2 |= ADC_CR2_SWSTART; @@ -171,6 +175,10 @@ int32_t adc_sample(adc_t line, adc_res_t res) sample = (int)ADC1->DR; ADC1 -> SR &= ~ADC_SR_STRT; + /* wait for ADC to become ready before disabling it */ + while (!(ADC1->SR & ADC_SR_ADONS)) {} + ADC1->CR2 &= ~ADC_CR2_ADON_Msk; + /* power off and unlock device again */ done();