38 #include "contiki-conf.h"
44 #include "rtimer-arch.h"
52 #if LPM_CONF_ENABLE != 0
55 static unsigned long irq_energest = 0;
57 #define ENERGEST_IRQ_SAVE(a) do { \
58 a = energest_type_time(ENERGEST_TYPE_IRQ); } while(0)
59 #define ENERGEST_IRQ_RESTORE(a) do { \
60 energest_type_set(ENERGEST_TYPE_IRQ, a); } while(0)
62 #define ENERGEST_IRQ_SAVE(a) do {} while(0)
63 #define ENERGEST_IRQ_RESTORE(a) do {} while(0)
73 #define DEEP_SLEEP_PM1_THRESHOLD 10
74 #define DEEP_SLEEP_PM2_THRESHOLD 100
76 #define assert_wfi() do { asm("wfi"::); } while(0)
79 rtimer_clock_t lpm_stats[3];
81 #define LPM_STATS_INIT() do { memset(lpm_stats, 0, sizeof(lpm_stats)); \
83 #define LPM_STATS_ADD(pm, val) do { lpm_stats[pm] += val; } while(0)
85 #define LPM_STATS_INIT()
86 #define LPM_STATS_ADD(stat, val)
93 static rtimer_clock_t sleep_enter_time;
98 static uint8_t max_pm;
101 #ifdef LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX
102 #define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX LPM_CONF_PERIPH_PERMIT_PM1_FUNCS_MAX
104 #define LPM_PERIPH_PERMIT_PM1_FUNCS_MAX 2
107 static lpm_periph_permit_pm1_func_t
108 periph_permit_pm1_funcs[LPM_PERIPH_PERMIT_PM1_FUNCS_MAX];
111 periph_permit_pm1(
void)
115 for(i = 0; i < LPM_PERIPH_PERMIT_PM1_FUNCS_MAX &&
116 periph_permit_pm1_funcs[i] !=
NULL; i++) {
117 if(!periph_permit_pm1_funcs[i]()) {
131 ENERGEST_OFF(ENERGEST_TYPE_CPU);
132 ENERGEST_ON(ENERGEST_TYPE_LPM);
135 ENERGEST_IRQ_RESTORE(irq_energest);
145 LPM_STATS_ADD(0,
RTIMER_NOW() - sleep_enter_time);
148 ENERGEST_IRQ_SAVE(irq_energest);
150 ENERGEST_ON(ENERGEST_TYPE_CPU);
151 ENERGEST_OFF(ENERGEST_TYPE_LPM);
155 select_32_mhz_xosc(
void)
171 select_16_mhz_rcosc(
void)
216 select_32_mhz_xosc();
222 ENERGEST_IRQ_SAVE(irq_energest);
224 ENERGEST_ON(ENERGEST_TYPE_CPU);
225 ENERGEST_OFF(ENERGEST_TYPE_LPM);
231 rtimer_clock_t lpm_exit_time;
232 rtimer_clock_t duration;
240 || !periph_permit_pm1() || max_pm == 0) {
256 if(duration < DEEP_SLEEP_PM1_THRESHOLD || lpm_exit_time == 0) {
267 select_16_mhz_rcosc();
275 if(duration < DEEP_SLEEP_PM1_THRESHOLD) {
282 select_32_mhz_xosc();
285 }
else if(duration >= DEEP_SLEEP_PM2_THRESHOLD && max_pm == 2) {
297 ENERGEST_IRQ_RESTORE(irq_energest);
298 ENERGEST_OFF(ENERGEST_TYPE_CPU);
299 ENERGEST_ON(ENERGEST_TYPE_LPM);
319 select_32_mhz_xosc();
324 ENERGEST_IRQ_SAVE(irq_energest);
325 ENERGEST_ON(ENERGEST_TYPE_CPU);
326 ENERGEST_OFF(ENERGEST_TYPE_LPM);
352 for(i = 0; i < LPM_PERIPH_PERMIT_PM1_FUNCS_MAX; i++) {
353 if(periph_permit_pm1_funcs[i] == permit_pm1_func) {
355 }
else if(periph_permit_pm1_funcs[i] ==
NULL) {
356 periph_permit_pm1_funcs[i] = permit_pm1_func;
Header with declarations of the RF Core XREGs.
int process_nevents(void)
Number of events waiting to be processed.
#define SYS_CTRL_PMCTL
Power Mode Control.
#define SCB_SYSCTRL
System Control.
#define SYS_CTRL_CLOCK_STA
Clock status register.
#define LPM_CONF_MAX_PM
Maximum PM.
Header file for the System Control Block (SCB)
#define lpm_enter()
Drop to Deep Sleep.
#define NULL
The null pointer.
#define SYS_CTRL_PMCTL_PM2
PM2.
#define lpm_exit()
Perform an 'Exit Deep Sleep' sequence.
#define lpm_init()
Initialise the LPM module.
#define RFCORE_XREG_FSMSTAT0_FSM_FFCTRL_STATE
FIFO and FFCTRL status.
Header file with register manipulation macro definitions.
#define SYS_CTRL_PMCTL_PM0
PM0.
Header file for the energy estimation mechanism
void clock_adjust(void)
Adjust the clock following missed SysTick ISRs.
#define SYS_CTRL_CLOCK_CTRL
Clock control register.
Header file for the cc2538 System Control driver.
#define SCB_SYSCTRL_SLEEPDEEP
Deep sleep enable.
#define SYS_CTRL_PMCTL_PM1
PM1.
void lpm_register_peripheral(lpm_periph_permit_pm1_func_t permit_pm1_func)
Register a peripheral function which will get called by the LPM module to get 'permission' to drop to...
#define RTIMER_NOW()
Get the current clock time.
rtimer_clock_t rtimer_arch_next_trigger()
Get the time of the next scheduled rtimer trigger.
#define SYS_CTRL_PMCTL_PM3
PM3.
Header file for the Contiki process interface.
void lpm_set_max_pm(uint8_t pm)
Prevent the SoC from dropping to a PM higher than max_pm.
#define RFCORE_XREG_FSMSTAT0
Radio status register.
#define LPM_CONF_STATS
Set to 1 to enable LPM-related stats.