From 4a6e19ed3878839f80e74861b98fe6a65a5d7e35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Th=C3=A9baudeau?= Date: Sun, 13 Dec 2015 02:33:31 +0100 Subject: [PATCH] cc2538: pwm: Automatically disable PM1+ if running MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The peripheral core clocks of the PWM timers are gated in PM1+, so these power modes must be disabled if a PWM timer is running. Use lpm_register_peripheral() to handle this automatically and dynamically. Signed-off-by: Benoît Thébaudeau --- cpu/cc2538/dev/pwm.c | 18 ++++++++++++++++++ cpu/cc2538/dev/pwm.h | 3 +-- cpu/cc2538/lpm.c | 2 +- examples/zolertia/zoul/test-pwm.c | 4 ---- 4 files changed, 20 insertions(+), 7 deletions(-) diff --git a/cpu/cc2538/dev/pwm.c b/cpu/cc2538/dev/pwm.c index 837efcb14..d6b5b9286 100644 --- a/cpu/cc2538/dev/pwm.c +++ b/cpu/cc2538/dev/pwm.c @@ -46,6 +46,7 @@ #include "dev/gpio.h" #include "dev/sys-ctrl.h" #include "dev/pwm.h" +#include "lpm.h" #include #include /*---------------------------------------------------------------------------*/ @@ -73,6 +74,21 @@ pwm_configured(uint8_t timer, uint8_t ab) return 0; } /*---------------------------------------------------------------------------*/ +static bool +permit_pm1(void) +{ + uint8_t timer, ab; + + for(timer = PWM_TIMER_0; timer <= PWM_TIMER_3; timer++) + for(ab = PWM_TIMER_A; ab <= PWM_TIMER_B; ab++) + if(pwm_configured(timer, ab) && + REG(PWM_GPTIMER_NUM_TO_BASE(timer) + GPTIMER_CTL) & + (ab == PWM_TIMER_A ? GPTIMER_CTL_TAEN : GPTIMER_CTL_TBEN)) + return false; + + return true; +} +/*---------------------------------------------------------------------------*/ int8_t pwm_enable(uint32_t freq, uint8_t duty, uint8_t timer, uint8_t ab) { @@ -95,6 +111,8 @@ pwm_enable(uint32_t freq, uint8_t duty, uint8_t timer, uint8_t ab) PRINTF("PWM: F%08luHz: %u%% on GPT%u-%u\n", freq, duty, timer, ab); + lpm_register_peripheral(permit_pm1); + gpt_base = PWM_GPTIMER_NUM_TO_BASE(timer); gpt_en = GPTIMER_CTL_TAEN; gpt_dir = GPTIMER_CTL_TAPWML; diff --git a/cpu/cc2538/dev/pwm.h b/cpu/cc2538/dev/pwm.h index f80402f31..744fa4b6c 100644 --- a/cpu/cc2538/dev/pwm.h +++ b/cpu/cc2538/dev/pwm.h @@ -47,8 +47,7 @@ * Depending on the specific needs these limits can be changed to meet a given * duty cycle and lower frequencies by using the prescaler (GPTIMER_TnPR). * - * The PWM timer is stopped when dropping below PM0, alternatively you can set - * LPM_CONF_MAX_PM to zero, or call lpm_max_pm(0) + * Running a PWM timer prevents the LPM driver from dropping to PM1+. * * @{ * diff --git a/cpu/cc2538/lpm.c b/cpu/cc2538/lpm.c index 3aacf5149..7e582c6fb 100644 --- a/cpu/cc2538/lpm.c +++ b/cpu/cc2538/lpm.c @@ -101,7 +101,7 @@ static uint8_t max_pm; #ifdef LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX #define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX #else -#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX 4 +#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX 5 #endif static lpm_periph_permit_pm1_func_t diff --git a/examples/zolertia/zoul/test-pwm.c b/examples/zolertia/zoul/test-pwm.c index 7048b2a01..a19412a9d 100644 --- a/examples/zolertia/zoul/test-pwm.c +++ b/examples/zolertia/zoul/test-pwm.c @@ -35,10 +35,6 @@ * \defgroup remote-test-pwm Test the CC2538 PWM driver * * Demonstrates the use of the CC2538 PWM driver for the Zolertia's Zoul boards - * The PWM timer is stopped when dropping below PM0, alternatively you can set - * LPM_CONF_MAX_PM to zero, or call lpm_max_pm(0). In this example is not - * needed as we disable RDC in the Makefile, and the CC2538 never drops below - * PM0 * * @{ *