From 607e3a4c20df279c6c317f9bb0f554c6dde6a6c5 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Tue, 10 Feb 2015 14:57:35 +0000 Subject: Safer ADC start for STM32F4 and STM32L1. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@7677 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/hal/ports/STM32/STM32F4xx/adc_lld.c | 23 ++++++++++++++++------- os/hal/ports/STM32/STM32L1xx/adc_lld.c | 23 ++++++++++++++++------- 2 files changed, 32 insertions(+), 14 deletions(-) (limited to 'os') diff --git a/os/hal/ports/STM32/STM32F4xx/adc_lld.c b/os/hal/ports/STM32/STM32F4xx/adc_lld.c index 29992bbdb..65556b1a3 100644 --- a/os/hal/ports/STM32/STM32F4xx/adc_lld.c +++ b/os/hal/ports/STM32/STM32F4xx/adc_lld.c @@ -317,6 +317,7 @@ void adc_lld_stop(ADCDriver *adcp) { */ void adc_lld_start_conversion(ADCDriver *adcp) { uint32_t mode; + uint32_t cr2; const ADCConversionGroup *grpp = adcp->grpp; /* DMA setup.*/ @@ -343,15 +344,23 @@ void adc_lld_start_conversion(ADCDriver *adcp) { adcp->adc->SQR2 = grpp->sqr2; adcp->adc->SQR3 = grpp->sqr3; - /* ADC configuration and start, the start is performed using the method - specified in the CR2 configuration, usually ADC_CR2_SWSTART.*/ + /* ADC configuration and start.*/ adcp->adc->CR1 = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN; - if ((grpp->cr2 & ADC_CR2_SWSTART) != 0) - adcp->adc->CR2 = grpp->cr2 | ADC_CR2_CONT | ADC_CR2_DMA | - ADC_CR2_DDS | ADC_CR2_ADON; + + /* Enforcing the mandatory bits in CR2.*/ + cr2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_ADON; + + /* The start method is different dependign if HW or SW triggered, the + start is performed using the method specified in the CR2 configuration.*/ + if ((cr2 & ADC_CR2_SWSTART) != 0) { + /* Initializing CR2 while keeping ADC_CR2_SWSTART at zero.*/ + adcp->adc->CR2 = (cr2 | ADC_CR2_CONT) & ~ADC_CR2_SWSTART; + + /* Finally enabling ADC_CR2_SWSTART.*/ + adcp->adc->CR2 = (cr2 | ADC_CR2_CONT); + } else - adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | - ADC_CR2_DDS | ADC_CR2_ADON; + adcp->adc->CR2 = cr2; } /** diff --git a/os/hal/ports/STM32/STM32L1xx/adc_lld.c b/os/hal/ports/STM32/STM32L1xx/adc_lld.c index 7ca69e2fd..80d07a51a 100644 --- a/os/hal/ports/STM32/STM32L1xx/adc_lld.c +++ b/os/hal/ports/STM32/STM32L1xx/adc_lld.c @@ -200,6 +200,7 @@ void adc_lld_stop(ADCDriver *adcp) { */ void adc_lld_start_conversion(ADCDriver *adcp) { uint32_t mode; + uint32_t cr2; const ADCConversionGroup *grpp = adcp->grpp; /* DMA setup.*/ @@ -229,15 +230,23 @@ void adc_lld_start_conversion(ADCDriver *adcp) { adcp->adc->SQR4 = grpp->sqr4; adcp->adc->SQR5 = grpp->sqr5; - /* ADC configuration and start, the start is performed using the method - specified in the CR2 configuration, usually ADC_CR2_SWSTART.*/ + /* ADC configuration and start.*/ adcp->adc->CR1 = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN; - if ((grpp->cr2 & ADC_CR2_SWSTART) != 0) - adcp->adc->CR2 = grpp->cr2 | ADC_CR2_CONT | ADC_CR2_DMA | - ADC_CR2_DDS | ADC_CR2_ADON; + + /* Enforcing the mandatory bits in CR2.*/ + cr2 = grpp->cr2 | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_ADON; + + /* The start method is different dependign if HW or SW triggered, the + start is performed using the method specified in the CR2 configuration.*/ + if ((cr2 & ADC_CR2_SWSTART) != 0) { + /* Initializing CR2 while keeping ADC_CR2_SWSTART at zero.*/ + adcp->adc->CR2 = (cr2 | ADC_CR2_CONT) & ~ADC_CR2_SWSTART; + + /* Finally enabling ADC_CR2_SWSTART.*/ + adcp->adc->CR2 = (cr2 | ADC_CR2_CONT); + } else - adcp->adc->CR2 = grpp->cr2 | ADC_CR2_DMA | - ADC_CR2_DDS | ADC_CR2_ADON; + adcp->adc->CR2 = cr2; } /** -- cgit v1.2.3