Contiki-NG
lpm.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014, Texas Instruments Incorporated - http://www.ti.com/
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  * notice, this list of conditions and the following disclaimer in the
12  * documentation and/or other materials provided with the distribution.
13  * 3. Neither the name of the copyright holder nor the names of its
14  * contributors may be used to endorse or promote products derived
15  * from this software without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21  * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
28  * OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 /*---------------------------------------------------------------------------*/
31 /**
32  * \addtogroup cc26xx-lpm
33  * @{
34  *
35  * Implementation of CC13xx/CC26xx low-power operation functionality
36  *
37  * @{
38  *
39  * \file
40  * Driver for CC13xx/CC26xx low-power operation
41  */
42 /*---------------------------------------------------------------------------*/
43 #include "prcm.h"
44 #include "contiki.h"
45 #include "ti-lib.h"
46 #include "lpm.h"
47 #include "sys/energest.h"
48 #include "lib/list.h"
49 #include "dev/aux-ctrl.h"
50 #include "dev/leds.h"
51 #include "dev/watchdog.h"
52 #include "dev/soc-rtc.h"
53 #include "dev/oscillators.h"
54 
55 #include <stdint.h>
56 #include <string.h>
57 #include <stdbool.h>
58 /*---------------------------------------------------------------------------*/
59 LIST(modules_list);
60 /*---------------------------------------------------------------------------*/
61 /* PDs that may stay on in deep sleep */
62 #define LOCKABLE_DOMAINS ((uint32_t)(PRCM_DOMAIN_SERIAL | PRCM_DOMAIN_PERIPH))
63 /*---------------------------------------------------------------------------*/
64 /*
65  * Don't consider standby mode if the next AON RTC event is scheduled to fire
66  * in less than STANDBY_MIN_DURATION rtimer ticks
67  */
68 #define STANDBY_MIN_DURATION (RTIMER_SECOND / 100) /* 10.0 ms */
69 
70 /* Wake up this much time earlier before the next rtimer */
71 #define SLEEP_GUARD_TIME (RTIMER_SECOND / 1000) /* 1.0 ms */
72 
73 /* Maximum allowed sleep-time, must be shorter than watchdog timeout */
74 #define MAX_SLEEP_TIME RTIMER_SECOND
75 
76 /* Minimal safe sleep-time */
77 #define MIN_SAFE_SCHEDULE 8u
78 /*---------------------------------------------------------------------------*/
79 /* Prototype of a function in clock.c. Called every time we come out of DS */
80 void clock_update(void);
81 /*---------------------------------------------------------------------------*/
82 void
83 lpm_shutdown(uint32_t wakeup_pin, uint32_t io_pull, uint32_t wake_on)
84 {
85  lpm_registered_module_t *module;
86  int i;
87  uint32_t io_cfg = (IOC_STD_INPUT & ~IOC_IOPULL_M) | io_pull | wake_on;
88  aux_consumer_module_t aux = { .clocks = AUX_WUC_OSCCTRL_CLOCK };
89 
90  /* This procedure may not be interrupted */
91  ti_lib_int_master_disable();
92 
93  /* Disable the RTC */
94  ti_lib_aon_rtc_disable();
95  ti_lib_aon_rtc_event_clear(AON_RTC_CH0);
96  ti_lib_aon_rtc_event_clear(AON_RTC_CH1);
97  ti_lib_aon_rtc_event_clear(AON_RTC_CH2);
98 
99  /* Reset AON even fabric to default wakeup sources */
100  for(i = AON_EVENT_MCU_WU0; i <= AON_EVENT_MCU_WU3; i++) {
101  ti_lib_aon_event_mcu_wake_up_set(i, AON_EVENT_NONE);
102  }
103  for(i = AON_EVENT_AUX_WU0; i <= AON_EVENT_AUX_WU2; i++) {
104  ti_lib_aon_event_aux_wake_up_set(i, AON_EVENT_NONE);
105  }
106 
107  ti_lib_sys_ctrl_aon_sync();
108 
110 
111  /* Notify all modules that we're shutting down */
112  for(module = list_head(modules_list); module != NULL;
113  module = module->next) {
114  if(module->shutdown) {
115  module->shutdown(LPM_MODE_SHUTDOWN);
116  }
117  }
118 
119  /* Configure the wakeup trigger */
120  if(wakeup_pin != IOID_UNUSED) {
121  ti_lib_gpio_set_output_enable_dio(wakeup_pin, GPIO_OUTPUT_DISABLE);
122  ti_lib_ioc_port_configure_set(wakeup_pin, IOC_PORT_GPIO, io_cfg);
123  }
124 
125  /* Freeze I/O latches in AON */
126  ti_lib_aon_ioc_freeze_enable();
127 
128  /* Turn off RFCORE, SERIAL and PERIPH PDs. This will happen immediately */
129  ti_lib_prcm_power_domain_off(PRCM_DOMAIN_RFCORE | PRCM_DOMAIN_SERIAL |
130  PRCM_DOMAIN_PERIPH);
131 
132  /* Register an aux-ctrl consumer to avoid powercycling AUX twice in a row */
136 
137  /* Configure clock sources for MCU: No clock */
138  ti_lib_aon_wuc_mcu_power_down_config(AONWUC_NO_CLOCK);
139 
140  /* Disable SRAM retention */
141  ti_lib_aon_wuc_mcu_sram_config(0);
142 
143  /*
144  * Request CPU, SYSBYS and VIMS PD off.
145  * This will only happen when the CM3 enters deep sleep
146  */
147  ti_lib_prcm_power_domain_off(PRCM_DOMAIN_CPU | PRCM_DOMAIN_VIMS |
148  PRCM_DOMAIN_SYSBUS);
149 
150  /* Request JTAG domain power off */
151  ti_lib_aon_wuc_jtag_power_off();
152 
153  /* Turn off AUX */
154  aux_ctrl_power_down(true);
155  ti_lib_aon_wuc_domain_power_down_enable();
156 
157  /*
158  * Request MCU VD power off.
159  * This will only happen when the CM3 enters deep sleep
160  */
161  ti_lib_prcm_mcu_power_off();
162 
163  /* Set MCU wakeup to immediate and disable virtual power off */
164  ti_lib_aon_wuc_mcu_wake_up_config(MCU_IMM_WAKE_UP);
165  ti_lib_aon_wuc_mcu_power_off_config(MCU_VIRT_PWOFF_DISABLE);
166 
167  /* Latch the IOs in the padring and enable I/O pad sleep mode */
168  ti_lib_aon_ioc_freeze_enable();
169  HWREG(AON_SYSCTL_BASE + AON_SYSCTL_O_SLEEPCTL) = 0;
170  ti_lib_sys_ctrl_aon_sync();
171 
172  /* Turn off VIMS cache, CRAM and TRAM - possibly not required */
173  ti_lib_prcm_cache_retention_disable();
174  ti_lib_vims_mode_set(VIMS_BASE, VIMS_MODE_OFF);
175 
176  /* Enable shutdown and sync AON */
177  ti_lib_aon_wuc_shut_down_enable();
178  ti_lib_sys_ctrl_aon_sync();
179 
180  /* Deep Sleep */
181  ti_lib_prcm_deep_sleep();
182 }
183 /*---------------------------------------------------------------------------*/
184 /*
185  * Notify all modules that we're back on and rely on them to restore clocks
186  * and power domains as required.
187  */
188 static void
189 wake_up(void)
190 {
191  lpm_registered_module_t *module;
192 
193  ENERGEST_SWITCH(ENERGEST_TYPE_DEEP_LPM, ENERGEST_TYPE_CPU);
194 
195  /* Sync so that we get the latest values before adjusting recharge settings */
196  ti_lib_sys_ctrl_aon_sync();
197 
198  /* Adjust recharge settings */
199  ti_lib_sys_ctrl_adjust_recharge_after_power_down();
200 
201  /*
202  * Release the request to the uLDO
203  * This is likely not required, since the switch to GLDO/DCDC is automatic
204  * when coming back from deep sleep
205  */
206  ti_lib_prcm_mcu_uldo_configure(false);
207 
208  /* Turn on cache again */
209  ti_lib_vims_mode_set(VIMS_BASE, VIMS_MODE_ENABLED);
210  ti_lib_prcm_cache_retention_enable();
211 
212  ti_lib_aon_ioc_freeze_disable();
213  ti_lib_sys_ctrl_aon_sync();
214 
215  /* Check operating conditions, optimally choose DCDC versus GLDO */
216  ti_lib_sys_ctrl_dcdc_voltage_conditional_control();
217 
218  /* Fire up AUX is the user has requested this */
220 
221  /*
222  * We may or may not have been woken up by an AON RTC tick. If not, we need
223  * to adjust our software tick counter
224  */
225  clock_update();
226 
228 
229  /* Notify all registered modules that we've just woken up */
230  for(module = list_head(modules_list); module != NULL;
231  module = module->next) {
232  if(module->wakeup) {
233  module->wakeup();
234  }
235  }
236 
237 #if CC2650_FAST_RADIO_STARTUP
238  /*
239  * Trigger a switch to the XOSC, so that we can subsequently use the RF FS
240  */
242 #endif
243 }
244 /*---------------------------------------------------------------------------*/
245 static uint8_t
246 check_next_rtimer(rtimer_clock_t now, rtimer_clock_t *next_rtimer, bool *next_rtimer_set)
247 {
248  uint8_t max_pm = LPM_MODE_MAX_SUPPORTED;
249 
250  if(ti_lib_aon_rtc_channel_active(AON_RTC_CH0)) {
251  *next_rtimer_set = true;
252 
253  /* find out the timer of the next rtimer interrupt */
254  *next_rtimer = ti_lib_aon_rtc_compare_value_get(AON_RTC_CH0);
255 
256  if(RTIMER_CLOCK_LT(*next_rtimer, now + 2)) {
257  max_pm = MIN(max_pm, LPM_MODE_AWAKE);
258  } else if(RTIMER_CLOCK_LT(*next_rtimer, now + STANDBY_MIN_DURATION)) {
259  max_pm = MIN(max_pm, LPM_MODE_SLEEP);
260  }
261  } else {
262  *next_rtimer_set = false;
263  }
264 
265  return max_pm;
266 }
267 /*---------------------------------------------------------------------------*/
268 static uint8_t
269 check_next_etimer(rtimer_clock_t now, rtimer_clock_t *next_etimer, bool *next_etimer_set)
270 {
271  uint8_t max_pm = LPM_MODE_MAX_SUPPORTED;
272 
273  *next_etimer_set = false;
274 
275  /* Find out the time of the next etimer */
276  if(etimer_pending()) {
277  int32_t until_next_etimer = (int32_t)etimer_next_expiration_time() - (int32_t)clock_time();
278  if(until_next_etimer < 1) {
279  max_pm = MIN(max_pm, LPM_MODE_AWAKE);
280  } else {
281  *next_etimer_set = true;
282  *next_etimer = soc_rtc_last_isr_time() + (until_next_etimer * (RTIMER_SECOND / CLOCK_SECOND));
283  if(RTIMER_CLOCK_LT(*next_etimer, now + STANDBY_MIN_DURATION)) {
284  max_pm = MIN(max_pm, LPM_MODE_SLEEP);
285  }
286  }
287  }
288 
289  return max_pm;
290 }
291 /*---------------------------------------------------------------------------*/
292 static uint8_t
293 setup_sleep_mode(void)
294 {
295  lpm_registered_module_t *module;
296  uint8_t max_pm = LPM_MODE_MAX_SUPPORTED;
297  uint8_t pm;
298 
299  rtimer_clock_t now;
300  rtimer_clock_t next_rtimer = 0;
301  rtimer_clock_t next_etimer = 0;
302  bool next_rtimer_set = false;
303  bool next_etimer_set = false;
304 
305  /* Check if any events fired before we turned interrupts off. If so, abort */
306  if(LPM_MODE_MAX_SUPPORTED == LPM_MODE_AWAKE || process_nevents()) {
307  return LPM_MODE_AWAKE;
308  }
309 
310  /* Collect max allowed PM permission from interested modules */
311  for(module = list_head(modules_list); module != NULL;
312  module = module->next) {
313  if(module->request_max_pm) {
314  uint8_t module_pm = module->request_max_pm();
315  if(module_pm < max_pm) {
316  max_pm = module_pm;
317  }
318  }
319  }
320 
321  now = RTIMER_NOW();
322 
323  pm = check_next_rtimer(now, &next_rtimer, &next_rtimer_set);
324  if(pm < max_pm) {
325  max_pm = pm;
326  }
327  pm = check_next_etimer(now, &next_etimer, &next_etimer_set);
328  if(pm < max_pm) {
329  max_pm = pm;
330  }
331 
332  if(max_pm == LPM_MODE_SLEEP) {
333  if(next_etimer_set) {
334  /* Schedule the next system wakeup due to etimer */
335  if(RTIMER_CLOCK_LT(next_etimer, now + MIN_SAFE_SCHEDULE)) {
336  /* Too soon in future, use this minimal interval instead */
337  next_etimer = now + MIN_SAFE_SCHEDULE;
338  } else if(RTIMER_CLOCK_LT(now + MAX_SLEEP_TIME, next_etimer)) {
339  /* Too far in future, use MAX_SLEEP_TIME instead */
340  next_etimer = now + MAX_SLEEP_TIME;
341  }
342  soc_rtc_schedule_one_shot(AON_RTC_CH1, next_etimer);
343  } else {
344  /* No etimers set. Since by default the CH1 RTC fires once every clock tick,
345  * need to explicitly schedule a wakeup in the future to save energy.
346  * But do not stay in this mode for too long, otherwise watchdog will be trigerred. */
347  soc_rtc_schedule_one_shot(AON_RTC_CH1, now + MAX_SLEEP_TIME);
348  }
349 
350  } else if(max_pm == LPM_MODE_DEEP_SLEEP) {
351  /* Watchdog is not enabled, so deep sleep can continue an arbitrary long time.
352  * On the other hand, if `CC2650_FAST_RADIO_STARTUP` is defined,
353  * early wakeup before the next rtimer should be scheduled. */
354 
355 #if CC2650_FAST_RADIO_STARTUP
356  if(next_rtimer_set) {
357  if(!next_etimer_set || RTIMER_CLOCK_LT(next_rtimer - SLEEP_GUARD_TIME, next_etimer)) {
358  /* schedule a wakeup briefly before the next rtimer to wake up the system */
359  soc_rtc_schedule_one_shot(AON_RTC_CH2, next_rtimer - SLEEP_GUARD_TIME);
360  }
361  }
362 #endif
363 
364  if(next_etimer_set) {
365  /* Schedule the next system wakeup due to etimer.
366  * No need to compare the `next_etimer` to `now` here as this branch
367  * is only entered when there's sufficient time for deep sleeping. */
368  soc_rtc_schedule_one_shot(AON_RTC_CH1, next_etimer);
369  } else {
370  /* Use the farthest possible wakeup time */
371  soc_rtc_schedule_one_shot(AON_RTC_CH1, now - 1);
372  }
373  }
374 
375  return max_pm;
376 }
377 /*---------------------------------------------------------------------------*/
378 void
380 {
381  ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_LPM);
382 
383  /* Just to be on the safe side, explicitly disable Deep Sleep */
384  HWREG(NVIC_SYS_CTRL) &= ~(NVIC_SYS_CTRL_SLEEPDEEP);
385 
386  ti_lib_prcm_sleep();
387 
388  /* Kick watchdog to ensure a full interval is available after sleep */
390 
391  ENERGEST_SWITCH(ENERGEST_TYPE_LPM, ENERGEST_TYPE_CPU);
392 }
393 /*---------------------------------------------------------------------------*/
394 static void
395 deep_sleep(void)
396 {
397  uint32_t domains = LOCKABLE_DOMAINS;
398  lpm_registered_module_t *module;
399 
400  /*
401  * Notify all registered modules that we are dropping to mode X. We do not
402  * need to do this for simple sleep.
403  *
404  * This is a chance for modules to delay us a little bit until an ongoing
405  * operation has finished (e.g. uart TX) or to configure themselves for
406  * deep sleep.
407  *
408  * At this stage, we also collect power domain locks, if any.
409  * The argument to PRCMPowerDomainOff() is a bitwise OR, so every time
410  * we encounter a lock we just clear the respective bits in the 'domains'
411  * variable as required by the lock. In the end the domains variable will
412  * just hold whatever has not been cleared
413  */
414  for(module = list_head(modules_list); module != NULL;
415  module = module->next) {
416  if(module->shutdown) {
417  module->shutdown(LPM_MODE_DEEP_SLEEP);
418  }
419 
420  /* Clear the bits specified in the lock */
421  domains &= ~module->domain_lock;
422  }
423 
424  /* Pat the dog: We don't want it to shout right after we wake up */
426 
427  /* Clear unacceptable bits, just in case a lock provided a bad value */
428  domains &= LOCKABLE_DOMAINS;
429 
430  /*
431  * Freeze the IOs on the boundary between MCU and AON. We only do this if
432  * PERIPH is not needed
433  */
434  if(domains & PRCM_DOMAIN_PERIPH) {
435  ti_lib_aon_ioc_freeze_enable();
436  }
437 
438  /*
439  * Among LOCKABLE_DOMAINS, turn off those that are not locked
440  *
441  * If domains is != 0, pass it as-is
442  */
443  if(domains) {
444  ti_lib_prcm_power_domain_off(domains);
445  }
446 
447  /*
448  * Before entering Deep Sleep, we must switch off the HF XOSC. The HF XOSC
449  * is predominantly controlled by the RF driver. In a build with radio
450  * cycling (e.g. ContikiMAC), the RF driver will request the XOSC before
451  * using the Freq. Synth, and switch back to the RC when it is about to
452  * turn back off.
453  *
454  * If the radio is on, we won't even reach here, and if it's off the HF
455  * clock source should already be the HF RC, unless CC2650_FAST_RADIO_STARTUP
456  * is defined.
457  *
458  * Nevertheless, request the switch to the HF RC explicitly here.
459  */
461 
462  /* Shut Down the AUX if the user application is not using it */
463  aux_ctrl_power_down(false);
464 
465  /* Configure clock sources for MCU: No clock */
466  ti_lib_aon_wuc_mcu_power_down_config(AONWUC_NO_CLOCK);
467 
468  /* Full RAM retention. */
469  ti_lib_aon_wuc_mcu_sram_config(MCU_RAM0_RETENTION | MCU_RAM1_RETENTION |
470  MCU_RAM2_RETENTION | MCU_RAM3_RETENTION);
471 
472  /*
473  * Always turn off RFCORE, CPU, SYSBUS and VIMS. RFCORE should be off
474  * already
475  */
476  ti_lib_prcm_power_domain_off(PRCM_DOMAIN_RFCORE | PRCM_DOMAIN_CPU |
477  PRCM_DOMAIN_VIMS | PRCM_DOMAIN_SYSBUS);
478 
479  /* Request JTAG domain power off */
480  ti_lib_aon_wuc_jtag_power_off();
481 
482  /* Allow MCU and AUX powerdown */
483  ti_lib_aon_wuc_domain_power_down_enable();
484 
485  /* Configure the recharge controller */
486  ti_lib_sys_ctrl_set_recharge_before_power_down(XOSC_IN_HIGH_POWER_MODE);
487 
488  /*
489  * If both PERIPH and SERIAL PDs are off, request the uLDO as the power
490  * source while in deep sleep.
491  */
492  if(domains == LOCKABLE_DOMAINS) {
493  ti_lib_pwr_ctrl_source_set(PWRCTRL_PWRSRC_ULDO);
494  }
495 
496  ENERGEST_SWITCH(ENERGEST_TYPE_CPU, ENERGEST_TYPE_DEEP_LPM);
497 
498  /* Sync the AON interface to ensure all writes have gone through. */
499  ti_lib_sys_ctrl_aon_sync();
500 
501  /*
502  * Explicitly turn off VIMS cache, CRAM and TRAM. Needed because of
503  * retention mismatch between VIMS logic and cache. We wait to do this
504  * until right before deep sleep to be able to use the cache for as long
505  * as possible.
506  */
507  ti_lib_prcm_cache_retention_disable();
508  ti_lib_vims_mode_set(VIMS_BASE, VIMS_MODE_OFF);
509 
510  /* Deep Sleep */
511  ti_lib_prcm_deep_sleep();
512 
513  /*
514  * When we reach here, some interrupt woke us up. The global interrupt
515  * flag is off, hence we have a chance to run things here. We will wake up
516  * the chip properly, and then we will enable the global interrupt without
517  * unpending events so the handlers can fire
518  */
519  wake_up();
520 
521  ti_lib_int_master_enable();
522 }
523 /*---------------------------------------------------------------------------*/
524 void
526 {
527  uint8_t max_pm;
528 
529  /* Critical. Don't get interrupted! */
530  ti_lib_int_master_disable();
531 
532  max_pm = setup_sleep_mode();
533 
534  /* Drop */
535  if(max_pm == LPM_MODE_SLEEP) {
536  lpm_sleep();
537  } else if(max_pm == LPM_MODE_DEEP_SLEEP) {
538  deep_sleep();
539  }
540 
541  ti_lib_int_master_enable();
542 }
543 /*---------------------------------------------------------------------------*/
544 void
545 lpm_register_module(lpm_registered_module_t *module)
546 {
547  list_add(modules_list, module);
548 }
549 /*---------------------------------------------------------------------------*/
550 void
551 lpm_unregister_module(lpm_registered_module_t *module)
552 {
553  list_remove(modules_list, module);
554 }
555 /*---------------------------------------------------------------------------*/
556 void
558 {
559  list_init(modules_list);
560 
561  /* Always wake up on any DIO edge detection */
562  ti_lib_aon_event_mcu_wake_up_set(AON_EVENT_MCU_WU3, AON_EVENT_IO);
563 }
564 /*---------------------------------------------------------------------------*/
565 void
567 {
568  if(ioid == IOID_UNUSED) {
569  return;
570  }
571 
572  ti_lib_ioc_port_configure_set(ioid, IOC_PORT_GPIO, IOC_STD_OUTPUT);
573  ti_lib_gpio_set_output_enable_dio(ioid, GPIO_OUTPUT_DISABLE);
574 }
575 /*---------------------------------------------------------------------------*/
576 /**
577  * @}
578  * @}
579  */
void oscillators_request_hf_xosc(void)
Requests the HF XOSC as the source for the HF clock, but does not perform the actual switch...
Definition: oscillators.c:94
void soc_rtc_schedule_one_shot(uint32_t channel, uint32_t ticks)
Schedule an AON RTC channel 0 one-shot compare event.
Definition: soc-rtc.c:125
void lpm_shutdown(uint32_t wakeup_pin, uint32_t io_pull, uint32_t wake_on)
Put the chip in shutdown power mode.
Definition: lpm.c:83
Header file with macros which rename TI CC26xxware functions.
Header file for the energy estimation mechanism
void lpm_sleep(void)
Enter sleep mode.
Definition: lpm.c:379
clock_time_t etimer_next_expiration_time(void)
Get next event timer expiration time.
Definition: etimer.c:237
#define RTIMER_SECOND
Number of rtimer ticks for 1 second.
Definition: rtimer.h:112
#define RTIMER_NOW()
Get the current clock time.
Definition: rtimer.h:185
Header file for the CC13xx/CC26xx oscillator control.
void lpm_drop()
Drop the cortex to sleep / deep sleep and shut down peripherals.
Definition: lpm.c:525
Header file for the management of CC13xx/CC26xx low-power operation.
void oscillators_switch_to_hf_rc(void)
Switches MF and HF clock source to be the HF RC OSC.
Definition: oscillators.c:134
#define CLOCK_SECOND
A second, measured in system clock time.
Definition: clock.h:82
Linked list manipulation routines.
void * list_head(list_t list)
Get a pointer to the first element of a list.
Definition: list.c:82
int etimer_pending(void)
Check if there are any non-expired event timers.
Definition: etimer.c:231
clock_time_t clock_time(void)
Get the current clock time.
Definition: clock.c:118
Header file for the management of the CC13xx/CC26xx AUX domain.
void list_add(list_t list, void *item)
Add an item at the end of a list.
Definition: list.c:142
void aux_ctrl_register_consumer(aux_consumer_module_t *consumer)
Register a module that no longer requires access to the AUX power domain.
Definition: aux-ctrl.c:44
void list_init(list_t list)
Initialize a list.
Definition: list.c:65
int process_nevents(void)
Number of events waiting to be processed.
Definition: process.c:316
#define LIST(name)
Declare a linked list.
Definition: list.h:89
void aux_ctrl_power_up()
Power-up the AUX power domain.
Definition: aux-ctrl.c:75
void aux_ctrl_power_down(bool force)
Power down the AUX power domain.
Definition: aux-ctrl.c:87
void lpm_init()
Initialise the low-power mode management module.
Definition: lpm.c:557
The data structure to be used for modules that require access to AUX.
Definition: aux-ctrl.h:62
void lpm_pin_set_default_state(uint32_t ioid)
Sets an IOID to a default state.
Definition: lpm.c:566
void watchdog_periodic(void)
Writes the WDT clear sequence.
Definition: watchdog.c:85
Header file for the CC13xx/CC26xx AON RTC driver.
Header file for the LED HAL.
void list_remove(list_t list, void *item)
Remove a specific element from a list.
Definition: list.c:237
void lpm_unregister_module(lpm_registered_module_t *module)
Unregister a module from LPM notifications.
Definition: lpm.c:551
void lpm_register_module(lpm_registered_module_t *module)
Register a module for LPM notifications.
Definition: lpm.c:545
void oscillators_select_lf_rcosc(void)
Set the LF clock source to be the LF RCOSC.
Definition: oscillators.c:73