From 52d942e2d21775bd62ba1a5d02d46f7057c89dd4 Mon Sep 17 00:00:00 2001 From: bcostm Date: Tue, 14 Nov 2017 14:55:28 +0100 Subject: [PATCH] STM32L1 ADC: remove adc_inited flag --- .../TARGET_STM/TARGET_STM32L1/analogin_api.c | 63 +++++++++---------- 1 file changed, 30 insertions(+), 33 deletions(-) diff --git a/targets/TARGET_STM/TARGET_STM32L1/analogin_api.c b/targets/TARGET_STM/TARGET_STM32L1/analogin_api.c index d4eead2bbb..b9d4694d4f 100644 --- a/targets/TARGET_STM/TARGET_STM32L1/analogin_api.c +++ b/targets/TARGET_STM/TARGET_STM32L1/analogin_api.c @@ -36,10 +36,9 @@ #include "mbed_error.h" #include "PeripheralPins.h" -int adc_inited = 0; - void analogin_init(analogin_t *obj, PinName pin) { + static int adc_hsi_inited = 0; RCC_OscInitTypeDef RCC_OscInitStruct; uint32_t function = (uint32_t)NC; @@ -49,14 +48,14 @@ void analogin_init(analogin_t *obj, PinName pin) if ((pin < 0xF0) || (pin >= 0x100)) { // Normal channels // Get the peripheral name from the pin and assign it to the object - obj->handle.Instance = (ADC_TypeDef *) pinmap_peripheral(pin, PinMap_ADC); + obj->handle.Instance = (ADC_TypeDef *)pinmap_peripheral(pin, PinMap_ADC); // Get the functions (adc channel) from the pin and assign it to the object function = pinmap_function(pin, PinMap_ADC); // Configure GPIO pinmap_pinout(pin, PinMap_ADC); } else { // Internal channels - obj->handle.Instance = (ADC_TypeDef *) pinmap_peripheral(pin, PinMap_ADC_Internal); + obj->handle.Instance = (ADC_TypeDef *)pinmap_peripheral(pin, PinMap_ADC_Internal); function = pinmap_function(pin, PinMap_ADC_Internal); // No GPIO configuration for internal channels } @@ -68,41 +67,39 @@ void analogin_init(analogin_t *obj, PinName pin) // Save pin number for the read function obj->pin = pin; - // The ADC initialization is done once - if (adc_inited == 0) { - adc_inited = 1; + // Configure ADC object structures + obj->handle.State = HAL_ADC_STATE_RESET; + obj->handle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4; + obj->handle.Init.Resolution = ADC_RESOLUTION_12B; + obj->handle.Init.DataAlign = ADC_DATAALIGN_RIGHT; + obj->handle.Init.ScanConvMode = DISABLE; // Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) + obj->handle.Init.EOCSelection = EOC_SINGLE_CONV; // On STM32L1xx ADC, overrun detection is enabled only if EOC selection is set to each conversion (or transfer by DMA enabled, this is not the case in this example). + obj->handle.Init.LowPowerAutoWait = ADC_AUTOWAIT_UNTIL_DATA_READ; // Enable the dynamic low power Auto Delay: new conversion start only when the previous conversion (for regular group) or previous sequence (for injected group) has been treated by user software. + obj->handle.Init.LowPowerAutoPowerOff = ADC_AUTOPOWEROFF_IDLE_PHASE; // Enable the auto-off mode: the ADC automatically powers-off after a conversion and automatically wakes-up when a new conversion is triggered (with startup time between trigger and start of sampling). + obj->handle.Init.ChannelsBank = ADC_CHANNELS_BANK_A; + obj->handle.Init.ContinuousConvMode = DISABLE; // Continuous mode disabled to have only 1 conversion at each conversion trig + obj->handle.Init.NbrOfConversion = 1; // Parameter discarded because sequencer is disabled + obj->handle.Init.DiscontinuousConvMode = DISABLE; // Parameter discarded because sequencer is disabled + obj->handle.Init.NbrOfDiscConversion = 1; // Parameter discarded because sequencer is disabled + obj->handle.Init.ExternalTrigConv = 0; // Not used + obj->handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; + obj->handle.Init.DMAContinuousRequests = DISABLE; + __HAL_RCC_ADC1_CLK_ENABLE(); + + if (HAL_ADC_Init(&obj->handle) != HAL_OK) { + error("Cannot initialize ADC"); + } + + // This section is done only once + if (adc_hsi_inited == 0) { + adc_hsi_inited = 1; // Enable the HSI (to clock the ADC) RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; RCC_OscInitStruct.HSIState = RCC_HSI_ON; RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE; RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; HAL_RCC_OscConfig(&RCC_OscInitStruct); - - obj->handle.State = HAL_ADC_STATE_RESET; - // Enable ADC clock - __ADC1_CLK_ENABLE(); - - // Configure ADC - obj->handle.Init.ClockPrescaler = ADC_CLOCK_ASYNC_DIV4; - obj->handle.Init.Resolution = ADC_RESOLUTION12b; - obj->handle.Init.DataAlign = ADC_DATAALIGN_RIGHT; - obj->handle.Init.ScanConvMode = DISABLE; // Sequencer disabled (ADC conversion on only 1 channel: channel set on rank 1) - obj->handle.Init.EOCSelection = EOC_SINGLE_CONV; // On STM32L1xx ADC, overrun detection is enabled only if EOC selection is set to each conversion (or transfer by DMA enabled, this is not the case in this example). - obj->handle.Init.LowPowerAutoWait = ADC_AUTOWAIT_UNTIL_DATA_READ; // Enable the dynamic low power Auto Delay: new conversion start only when the previous conversion (for regular group) or previous sequence (for injected group) has been treated by user software. - obj->handle.Init.LowPowerAutoPowerOff = ADC_AUTOPOWEROFF_IDLE_PHASE; // Enable the auto-off mode: the ADC automatically powers-off after a conversion and automatically wakes-up when a new conversion is triggered (with startup time between trigger and start of sampling). - obj->handle.Init.ChannelsBank = ADC_CHANNELS_BANK_A; - obj->handle.Init.ContinuousConvMode = DISABLE; // Continuous mode disabled to have only 1 conversion at each conversion trig - obj->handle.Init.NbrOfConversion = 1; // Parameter discarded because sequencer is disabled - obj->handle.Init.DiscontinuousConvMode = DISABLE; // Parameter discarded because sequencer is disabled - obj->handle.Init.NbrOfDiscConversion = 1; // Parameter discarded because sequencer is disabled - obj->handle.Init.ExternalTrigConv = 0; // Not used - obj->handle.Init.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE; - obj->handle.Init.DMAContinuousRequests = DISABLE; - - if (HAL_ADC_Init(&obj->handle) != HAL_OK) { - error("Cannot initialize ADC"); - } } } @@ -231,7 +228,7 @@ static inline uint16_t adc_read(analogin_t *obj) // Wait end of conversion and get value if (HAL_ADC_PollForConversion(&obj->handle, 10) == HAL_OK) { - return (HAL_ADC_GetValue(&obj->handle)); + return (uint16_t)HAL_ADC_GetValue(&obj->handle); } else { return 0; }