cc2538: pwm: Automatically disable PM1+ if running
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 <benoit.thebaudeau.dev@gmail.com>
This commit is contained in:
parent
9c6d9a7fe0
commit
4a6e19ed38
4 changed files with 20 additions and 7 deletions
|
@ -46,6 +46,7 @@
|
|||
#include "dev/gpio.h"
|
||||
#include "dev/sys-ctrl.h"
|
||||
#include "dev/pwm.h"
|
||||
#include "lpm.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
@ -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;
|
||||
|
|
|
@ -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+.
|
||||
*
|
||||
* @{
|
||||
*
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
*
|
||||
* @{
|
||||
*
|
||||
|
|
Loading…
Reference in a new issue