diff --git a/os/hal/platforms/STM32F4xx/adc_lld.c b/os/hal/platforms/STM32F4xx/adc_lld.c index f78c7ac0f..f34c4fd61 100644 --- a/os/hal/platforms/STM32F4xx/adc_lld.c +++ b/os/hal/platforms/STM32F4xx/adc_lld.c @@ -321,17 +321,16 @@ void adc_lld_start_conversion(ADCDriver *adcp) { /* ADC setup.*/ adcp->adc->SR = 0; adcp->adc->CR1 = grpp->cr1 | ADC_CR1_OVRIE | ADC_CR1_SCAN; - adcp->adc->SMPR1 = grpp->smpr1; /* Writing SMPRx requires ADON=0. */ - adcp->adc->SMPR2 = grpp->smpr2; adcp->adc->CR2 = grpp->cr2 | ADC_CR2_CONT | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_ADON; + adcp->adc->SMPR1 = grpp->smpr1; + adcp->adc->SMPR2 = grpp->smpr2; adcp->adc->SQR1 = grpp->sqr1; adcp->adc->SQR2 = grpp->sqr2; adcp->adc->SQR3 = grpp->sqr3; - /* Must wait the ADC to be ready for conversion, see 9.3.6 "Timing diagram" - in the Reference Manual.*/ - while ((adcp->adc->SR & ADC_SR_ADONS) == 0) - ; + /* TODO: According to section 10.3.6 of the reference manual there should + be a 2uS delay between the ADC activation and conversion start.*/ + /* ADC start by raising ADC_CR2_SWSTART.*/ adcp->adc->CR2 = grpp->cr2 | ADC_CR2_SWSTART | ADC_CR2_CONT | ADC_CR2_DMA | ADC_CR2_DDS | ADC_CR2_ADON; @@ -373,6 +372,26 @@ void adcSTM32DisableTSVREFE(void) { ADC->CCR &= ~ADC_CCR_TSVREFE; } +/** + * @brief Enables the VBATE bit. + * @details The VBATE bit is required in order to sample the VBAT channel. + * @note This is an STM32-only functionality. + */ +void adcSTM32EnableVBATE(void) { + + ADC->CCR |= ADC_CCR_VBATE; +} + +/** + * @brief Disables the VBATE bit. + * @details The VBATE bit is required in order to sample the VBAT channel. + * @note This is an STM32-only functionality. + */ +void adcSTM32DisableVBATE(void) { + + ADC->CCR &= ~ADC_CCR_VBATE; +} + #endif /* HAL_USE_ADC */ /** @} */ diff --git a/os/hal/platforms/STM32F4xx/adc_lld.h b/os/hal/platforms/STM32F4xx/adc_lld.h index 0e846f50a..6260773a2 100644 --- a/os/hal/platforms/STM32F4xx/adc_lld.h +++ b/os/hal/platforms/STM32F4xx/adc_lld.h @@ -556,6 +556,8 @@ extern "C" { void adc_lld_stop_conversion(ADCDriver *adcp); void adcSTM32EnableTSVREFE(void); void adcSTM32DisableTSVREFE(void); + void adcSTM32EnableVBATE(void); + void adcSTM32DisableVBATE(void); #ifdef __cplusplus } #endif diff --git a/testhal/STM32F4xx/ADC/main.c b/testhal/STM32F4xx/ADC/main.c index b9890100e..80dab61b2 100644 --- a/testhal/STM32F4xx/ADC/main.c +++ b/testhal/STM32F4xx/ADC/main.c @@ -53,8 +53,8 @@ static void adcerrorcallback(ADCDriver *adcp, adcerror_t err) { /* * ADC conversion group. - * Mode: Linear buffer, 16 samples of 8 channels, SW triggered. - * Channels: IN10, IN11, IN10, IN11, IN10, IN11, Sensor, VRef. + * Mode: Linear buffer, 16 samples of 1 channel, SW triggered. + * Channels: IN10. */ static const ADCConversionGroup adcgrpcfg1 = { FALSE, @@ -62,12 +62,11 @@ static const ADCConversionGroup adcgrpcfg1 = { NULL, adcerrorcallback, 0, 0, /* CR1, CR2 */ - 0, /* SMPR1 */ - ADC_SMPR2_SMP_AN10(ADC_SAMPLE_4), - 0, /* SMPR3 */ + ADC_SMPR1_SMP_AN10(ADC_SAMPLE_3), + 0, /* SMPR2 */ ADC_SQR1_NUM_CH(ADC_GRP1_NUM_CHANNELS), - 0, 0, 0, /* SQR2, SQR3, SQR4 */ - ADC_SQR5_SQ1_N(ADC_CHANNEL_IN10) + 0, /* SQR2 */ + ADC_SQR3_SQ1_N(ADC_CHANNEL_IN10) }; /* @@ -81,16 +80,14 @@ static const ADCConversionGroup adcgrpcfg2 = { adccallback, adcerrorcallback, 0, 0, /* CR1, CR2 */ - 0, /* SMPR1 */ - ADC_SMPR2_SMP_AN10(ADC_SAMPLE_48) | ADC_SMPR2_SMP_SENSOR(ADC_SAMPLE_192) | - ADC_SMPR2_SMP_VREF(ADC_SAMPLE_192), - 0, /* SMPR3 */ + ADC_SMPR1_SMP_AN11(ADC_SAMPLE_56) | ADC_SMPR1_SMP_AN10(ADC_SAMPLE_56) | + ADC_SMPR1_SMP_SENSOR(ADC_SAMPLE_144) | ADC_SMPR1_SMP_VREF(ADC_SAMPLE_144), + 0, /* SMPR2 */ ADC_SQR1_NUM_CH(ADC_GRP2_NUM_CHANNELS), - 0, 0, /* SQR2, SQR3 */ - ADC_SQR4_SQ8_N(ADC_CHANNEL_SENSOR) | ADC_SQR4_SQ7_N(ADC_CHANNEL_VREFINT), - ADC_SQR5_SQ6_N(ADC_CHANNEL_IN11) | ADC_SQR5_SQ5_N(ADC_CHANNEL_IN10) | - ADC_SQR5_SQ4_N(ADC_CHANNEL_IN11) | ADC_SQR5_SQ3_N(ADC_CHANNEL_IN10) | - ADC_SQR5_SQ2_N(ADC_CHANNEL_IN11) | ADC_SQR5_SQ1_N(ADC_CHANNEL_IN10) + ADC_SQR2_SQ8_N(ADC_CHANNEL_SENSOR) | ADC_SQR2_SQ7_N(ADC_CHANNEL_VREFINT), + ADC_SQR3_SQ6_N(ADC_CHANNEL_IN11) | ADC_SQR3_SQ5_N(ADC_CHANNEL_IN10) | + ADC_SQR3_SQ4_N(ADC_CHANNEL_IN11) | ADC_SQR3_SQ3_N(ADC_CHANNEL_IN10) | + ADC_SQR3_SQ2_N(ADC_CHANNEL_IN11) | ADC_SQR3_SQ1_N(ADC_CHANNEL_IN10) }; /* @@ -102,9 +99,9 @@ static msg_t Thread1(void *arg) { (void)arg; chRegSetThreadName("blinker"); while (TRUE) { - palSetPad(GPIOB, GPIOB_LED4); + palSetPad(GPIOD, GPIOD_LED5); chThdSleepMilliseconds(500); - palClearPad(GPIOB, GPIOB_LED4); + palClearPad(GPIOD, GPIOD_LED5); chThdSleepMilliseconds(500); } }