From dbbe5b65216d0c80ee7b7b731c70fee8d4abd069 Mon Sep 17 00:00:00 2001 From: Steven Cooreman Date: Tue, 19 May 2015 16:12:44 +0200 Subject: [PATCH] Fix missing clock enable in ADC/DAC --- .../TARGET_EFM32/analogin_api.c | 39 ++++++++++++------- .../TARGET_EFM32/analogout_api.c | 17 +++++--- 2 files changed, 36 insertions(+), 20 deletions(-) diff --git a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/analogin_api.c b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/analogin_api.c index cc7fb09aca..1d3a817c0e 100644 --- a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/analogin_api.c +++ b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/analogin_api.c @@ -43,22 +43,33 @@ void analogin_preinit(analogin_t *obj, PinName pin) void analogin_init(analogin_t *obj, PinName pin) { - // TODO_LP only once - module in C++ ? - /* Init with default settings */ - ADC_Init_TypeDef init = ADC_INIT_DEFAULT; - ADC_Init(obj->adc, &init); + static uint8_t adc_initialized = 0; - ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT; - - /* Init for single conversion use, measure input channel with Vdd reference. */ - singleInit.reference = adcRefVDD; - singleInit.resolution = adcRes12Bit; - singleInit.acqTime = adcAcqTime32; - - ADC_InitSingle(obj->adc, &singleInit); - - /* Init pins */ + /* Init structure */ analogin_preinit(obj, pin); + + /* Only initialize the ADC once */ + if (!adc_initialized) { + /* Turn on the clock */ + CMU_ClockEnable(cmuClock_ADC0, true); + + /* Init with default settings */ + ADC_Init_TypeDef init = ADC_INIT_DEFAULT; + init.prescale = 4; + ADC_Init(obj->adc, &init); + + /* Init for single conversion use */ + ADC_InitSingle_TypeDef singleInit = ADC_INITSINGLE_DEFAULT; + + /* Measure input channel with Vdd reference. */ + singleInit.reference = adcRefVDD; + singleInit.resolution = adcRes12Bit; + singleInit.acqTime = adcAcqTime32; + + ADC_InitSingle(obj->adc, &singleInit); + + adc_initialized = 1; + } } void analogin_enable(analogin_t *obj, uint8_t enable) diff --git a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/analogout_api.c b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/analogout_api.c index 207b8e6630..c91c4e39df 100644 --- a/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/analogout_api.c +++ b/libraries/mbed/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/analogout_api.c @@ -23,6 +23,7 @@ #include "pinmap.h" #include "pinmap_function.h" #include "PeripheralPins.h" +#include "clocking.h" #include "em_dac.h" #include "em_cmu.h" @@ -42,30 +43,34 @@ void analogout_preinit(dac_t *obj, PinName pin) } void analogout_init(dac_t *obj, PinName pin) { - static uint8_t initialized = 0; + static uint8_t dac_initialized = 0; - if (!initialized) { + /* init in-memory structure */ + analogout_preinit(obj, pin); + + if (!dac_initialized) { /* Initialize the DAC. Will disable both DAC channels, so should only be done once */ /* Use default settings */ + CMU_ClockEnable(cmuClock_DAC0, true); + DAC_Init_TypeDef init = DAC_INIT_DEFAULT; /* Calculate the DAC clock prescaler value that will result in a DAC clock * close to 500kHz. Second parameter is zero. This uses the current HFPERCLK * frequency instead of setting a new one. */ - init.prescale = DAC_PrescaleCalc(500000, 0); + init.prescale = DAC_PrescaleCalc(500000, REFERENCE_FREQUENCY); /* Set reference voltage to VDD */ init.reference = dacRefVDD; DAC_Init(obj->dac, &init); - initialized = 1; + dac_initialized = 1; } /* Use default channel settings */ DAC_InitChannel_TypeDef initChannel = DAC_INITCHANNEL_DEFAULT; DAC_InitChannel(obj->dac, &initChannel, obj->channel); - /* init pins */ - analogout_preinit(obj, pin); + } void analogout_enable(dac_t *obj, uint8_t enable)