From e74074eba88807da6b0ce0ce22742af8eb528680 Mon Sep 17 00:00:00 2001 From: Sissors Date: Sun, 22 Mar 2015 15:15:40 +0100 Subject: [PATCH] [HAL][K20XX/KLXX] Fixed deepsleep power consumption when AnalogIn is used The power consumption was reported by Paul Staron to be 100uA higher when an AnalogIn was used previously. Problem 1 is that 40uA was used by the async ADC clock, which is never actually used, so it is disabled. Problem 2 is that setting it for high speed mode increased it by another 60uA while in deepsleep. This currently seems to me to be possibly a bug in the design, but the workaround is checking if this is the case before going to deepsleep, and if yes, disable it. Afterwards it is re-enabled. --- .../TARGET_Freescale/TARGET_K20XX/analogin_api.c | 1 - .../hal/TARGET_Freescale/TARGET_K20XX/sleep.c | 13 +++++++++++++ .../hal/TARGET_Freescale/TARGET_KLXX/analogin_api.c | 1 - .../hal/TARGET_Freescale/TARGET_KLXX/sleep.c | 13 +++++++++++++ 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20XX/analogin_api.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20XX/analogin_api.c index 473c5d0394..f7c4cf1f90 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20XX/analogin_api.c +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20XX/analogin_api.c @@ -51,7 +51,6 @@ void analogin_init(analogin_t *obj, PinName pin) { | ADC_CFG1_ADICLK(clkdiv >> 2); // Input Clock ADC0->CFG2 = ADC_CFG2_MUXSEL_MASK // ADxxb or ADxxa channels - | ADC_CFG2_ADACKEN_MASK // Asynchronous Clock Output Enable | ADC_CFG2_ADHSC_MASK // High-Speed Configuration | ADC_CFG2_ADLSTS(0); // Long Sample Time Select diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20XX/sleep.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20XX/sleep.c index 6ccb7e5d88..4a7dced648 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20XX/sleep.c +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_K20XX/sleep.c @@ -29,6 +29,15 @@ void sleep(void) //Very low-power stop mode void deepsleep(void) { + //Check if ADC is enabled and HS mode is set, if yes disable it (lowers power consumption by 60uA) + uint8_t ADC_HSC = 0; + if (SIM->SCGC6 & SIM_SCGC6_ADC0_MASK) { + if (ADC0->CFG2 & ADC_CFG2_ADHSC_MASK) { + ADC_HSC = 1; + ADC0->CFG2 &= ~(ADC_CFG2_ADHSC_MASK); + } + } + //Check if PLL/FLL is enabled: uint32_t PLL_FLL_en = (MCG->C1 & MCG_C1_CLKS_MASK) == MCG_C1_CLKS(0); @@ -67,4 +76,8 @@ void deepsleep(void) while((MCG->S & MCG_S_LOCK0_MASK) == 0u) { } // Wait until locked #endif } + + if (ADC_HSC) { + ADC0->CFG2 |= (ADC_CFG2_ADHSC_MASK); + } } diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/analogin_api.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/analogin_api.c index 4e3f52c35c..e9cad0db3d 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/analogin_api.c +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/analogin_api.c @@ -58,7 +58,6 @@ void analogin_init(analogin_t *obj, PinName pin) { | ADC_CFG1_ADICLK(clkdiv >> 2); // Input Clock: (Bus Clock)/2 ADC0->CFG2 = cfg2_muxsel // ADxxb or ADxxa channels - | ADC_CFG2_ADACKEN_MASK // Asynchronous Clock Output Enable | ADC_CFG2_ADHSC_MASK // High-Speed Configuration | ADC_CFG2_ADLSTS(0); // Long Sample Time Select diff --git a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/sleep.c b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/sleep.c index 9645e30c53..c3ea772007 100644 --- a/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/sleep.c +++ b/libraries/mbed/targets/hal/TARGET_Freescale/TARGET_KLXX/sleep.c @@ -30,6 +30,15 @@ void sleep(void) //Very low-power stop mode void deepsleep(void) { + //Check if ADC is enabled and HS mode is set, if yes disable it (lowers power consumption by 60uA) + uint8_t ADC_HSC = 0; + if (SIM->SCGC6 & SIM_SCGC6_ADC0_MASK) { + if (ADC0->CFG2 & ADC_CFG2_ADHSC_MASK) { + ADC_HSC = 1; + ADC0->CFG2 &= ~(ADC_CFG2_ADHSC_MASK); + } + } + #if ! defined(TARGET_KL43Z) //Check if PLL/FLL is enabled: uint32_t PLL_FLL_en = (MCG->C1 & MCG_C1_CLKS_MASK) == MCG_C1_CLKS(0); @@ -54,4 +63,8 @@ void deepsleep(void) MCG->C1 &= ~MCG_C1_CLKS_MASK; } #endif + + if (ADC_HSC) { + ADC0->CFG2 |= (ADC_CFG2_ADHSC_MASK); + } }