Merge pull request #1419 from bthebaudeau/cc2538-pwm-lpm-register-peripheral
cc2538: pwm: Fix clock and automatically disable PM1+ if running
This commit is contained in:
commit
af35e04ad7
|
@ -46,6 +46,7 @@
|
||||||
#include "dev/gpio.h"
|
#include "dev/gpio.h"
|
||||||
#include "dev/sys-ctrl.h"
|
#include "dev/sys-ctrl.h"
|
||||||
#include "dev/pwm.h"
|
#include "dev/pwm.h"
|
||||||
|
#include "lpm.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -73,6 +74,21 @@ pwm_configured(uint8_t timer, uint8_t ab)
|
||||||
return 0;
|
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
|
int8_t
|
||||||
pwm_enable(uint32_t freq, uint8_t duty, uint8_t timer, uint8_t ab)
|
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);
|
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_base = PWM_GPTIMER_NUM_TO_BASE(timer);
|
||||||
gpt_en = GPTIMER_CTL_TAEN;
|
gpt_en = GPTIMER_CTL_TAEN;
|
||||||
gpt_dir = GPTIMER_CTL_TAPWML;
|
gpt_dir = GPTIMER_CTL_TAPWML;
|
||||||
|
@ -135,10 +153,10 @@ pwm_enable(uint32_t freq, uint8_t duty, uint8_t timer, uint8_t ab)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the peripheral clock and equivalent deassert count */
|
/* Get the peripheral clock and equivalent deassert count */
|
||||||
interval_load = sys_ctrl_get_io_clock() / freq;
|
interval_load = sys_ctrl_get_sys_clock() / freq;
|
||||||
duty_count = ((interval_load * duty) + 1) / 100;
|
duty_count = ((interval_load * duty) + 1) / 100;
|
||||||
|
|
||||||
PRINTF("PWM: IO %luHz: %lu %lu\n", sys_ctrl_get_io_clock(),
|
PRINTF("PWM: sys %luHz: %lu %lu\n", sys_ctrl_get_sys_clock(),
|
||||||
interval_load, duty_count);
|
interval_load, duty_count);
|
||||||
|
|
||||||
/* Set the start value (period), count down */
|
/* Set the start value (period), count down */
|
||||||
|
|
|
@ -47,8 +47,7 @@
|
||||||
* Depending on the specific needs these limits can be changed to meet a given
|
* 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).
|
* duty cycle and lower frequencies by using the prescaler (GPTIMER_TnPR).
|
||||||
*
|
*
|
||||||
* The PWM timer is stopped when dropping below PM0, alternatively you can set
|
* Running a PWM timer prevents the LPM driver from dropping to PM1+.
|
||||||
* LPM_CONF_MAX_PM to zero, or call lpm_max_pm(0)
|
|
||||||
*
|
*
|
||||||
* @{
|
* @{
|
||||||
*
|
*
|
||||||
|
@ -78,15 +77,15 @@
|
||||||
/** \name PWM recommended values respect to peripheral clock frequency
|
/** \name PWM recommended values respect to peripheral clock frequency
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/* Roughly 244 Hz with a 16 MHz IO clock, no prescaler */
|
/* Roughly 244 Hz with a 16-MHz system clock, no prescaler */
|
||||||
#define PWM_SYS_IO_16MHZ_NO_PRES_MIN 0xFFFF
|
#define PWM_SYS_16MHZ_NO_PRES_MIN 0xFFFF
|
||||||
#define PWM_SYS_IO_16MHZ_NO_PRES_MIN_FREQ 244
|
#define PWM_SYS_16MHZ_NO_PRES_MIN_FREQ 244
|
||||||
/* Roughly 1 Hz with a 16 MHz IO clock, to keep frequency parameter in Hz */
|
/* Roughly 1 Hz with a 16-MHz system clock, to keep frequency parameter in Hz */
|
||||||
#define PWM_SYS_IO_16MHZ_PRES_MIN 0x00F42400
|
#define PWM_SYS_16MHZ_PRES_MIN 0x00F42400
|
||||||
#define PWM_SYS_IO_16MHZ_PRES_MIN_FREQ 1
|
#define PWM_SYS_16MHZ_PRES_MIN_FREQ 1
|
||||||
/* Yields 160 KHz at 16 MHz and allows down to 1% (integer) duty cycles */
|
/* Yields 160 KHz at 16 MHz and allows down to 1% (integer) duty cycles */
|
||||||
#define PWM_SYS_IO_16MHZ_NO_PRES_MAX 100
|
#define PWM_SYS_16MHZ_NO_PRES_MAX 100
|
||||||
#define PWM_SYS_IO_16MHZ_NO_PRES_MAX_FREQ 160000
|
#define PWM_SYS_16MHZ_NO_PRES_MAX_FREQ 160000
|
||||||
/** @} */
|
/** @} */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** \name PWM driver definitions and configuration values
|
/** \name PWM driver definitions and configuration values
|
||||||
|
@ -107,8 +106,8 @@
|
||||||
#define PWM_GPTIMER_CFG_SPLIT_MODE 0x04
|
#define PWM_GPTIMER_CFG_SPLIT_MODE 0x04
|
||||||
#define PWM_DUTY_MAX 100
|
#define PWM_DUTY_MAX 100
|
||||||
#define PWM_DUTY_MIN 0
|
#define PWM_DUTY_MIN 0
|
||||||
#define PWM_FREQ_MIN PWM_SYS_IO_16MHZ_PRES_MIN_FREQ
|
#define PWM_FREQ_MIN PWM_SYS_16MHZ_PRES_MIN_FREQ
|
||||||
#define PWM_FREQ_MAX PWM_SYS_IO_16MHZ_NO_PRES_MAX_FREQ
|
#define PWM_FREQ_MAX PWM_SYS_16MHZ_NO_PRES_MAX_FREQ
|
||||||
/** @} */
|
/** @} */
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
/** \name PWM functions
|
/** \name PWM functions
|
||||||
|
|
|
@ -101,7 +101,7 @@ static uint8_t max_pm;
|
||||||
#ifdef LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX
|
#ifdef LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX
|
||||||
#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX
|
#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX
|
||||||
#else
|
#else
|
||||||
#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX 4
|
#define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX 5
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static lpm_periph_permit_pm1_func_t
|
static lpm_periph_permit_pm1_func_t
|
||||||
|
|
|
@ -35,10 +35,6 @@
|
||||||
* \defgroup remote-test-pwm Test the CC2538 PWM driver
|
* \defgroup remote-test-pwm Test the CC2538 PWM driver
|
||||||
*
|
*
|
||||||
* Demonstrates the use of the CC2538 PWM driver for the Zolertia's Zoul boards
|
* 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