diff --git a/cpu/cc26xx/dev/cc26xx-rf.c b/cpu/cc26xx/dev/cc26xx-rf.c index e034cc830..87ade4186 100644 --- a/cpu/cc26xx/dev/cc26xx-rf.c +++ b/cpu/cc26xx/dev/cc26xx-rf.c @@ -1150,7 +1150,7 @@ request(void) return LPM_MODE_MAX_SUPPORTED; } /*---------------------------------------------------------------------------*/ -LPM_MODULE(cc26xx_rf_lpm_module, request, NULL, NULL); +LPM_MODULE(cc26xx_rf_lpm_module, request, NULL, NULL, LPM_DOMAIN_NONE); /*---------------------------------------------------------------------------*/ static int init(void) diff --git a/cpu/cc26xx/lpm.c b/cpu/cc26xx/lpm.c index 6526a8eeb..320ccdd03 100644 --- a/cpu/cc26xx/lpm.c +++ b/cpu/cc26xx/lpm.c @@ -64,9 +64,6 @@ static unsigned long irq_energest = 0; /*---------------------------------------------------------------------------*/ LIST(modules_list); /*---------------------------------------------------------------------------*/ -/* Control what power domains we are allow to run under what mode */ -LIST(power_domain_locks_list); - /* PDs that may stay on in deep sleep */ #define LOCKABLE_DOMAINS ((uint32_t)(PRCM_DOMAIN_SERIAL | PRCM_DOMAIN_PERIPH)) /*---------------------------------------------------------------------------*/ @@ -399,7 +396,6 @@ void lpm_init() { list_init(modules_list); - list_init(power_domain_locks_list); } /*---------------------------------------------------------------------------*/ void diff --git a/cpu/cc26xx/lpm.h b/cpu/cc26xx/lpm.h index eaecebb16..8b701baff 100644 --- a/cpu/cc26xx/lpm.h +++ b/cpu/cc26xx/lpm.h @@ -49,17 +49,22 @@ #include /*---------------------------------------------------------------------------*/ -#define LPM_MODE_SLEEP PWRCTRL_ACTIVE -#define LPM_MODE_DEEP_SLEEP PWRCTRL_POWER_DOWN -#define LPM_MODE_SHUTDOWN PWRCTRL_SHUTDOWN +#define LPM_MODE_SLEEP 1 +#define LPM_MODE_DEEP_SLEEP 2 +#define LPM_MODE_SHUTDOWN 3 #define LPM_MODE_MAX_SUPPORTED LPM_MODE_DEEP_SLEEP /*---------------------------------------------------------------------------*/ +#define LPM_DOMAIN_NONE 0 +#define LPM_DOMAIN_SERIAL PRCM_DOMAIN_SERIAL +#define LPM_DOMAIN_PERIPH PRCM_DOMAIN_PERIPH +/*---------------------------------------------------------------------------*/ typedef struct lpm_registered_module { struct lpm_registered_module *next; uint8_t (*request_max_pm)(void); void (*shutdown)(uint8_t mode); void (*wakeup)(void); + uint32_t domain_lock; } lpm_registered_module_t; /*---------------------------------------------------------------------------*/ /** @@ -78,46 +83,14 @@ typedef struct lpm_registered_module { * woken up. This can be used to e.g. turn a peripheral back on. This * function is in charge of turning power domains back on. This * function will normally be called within an interrupt context. + * \param l Power domain locks, if any are required. The module can request + * that the SERIAL or PERIPH PD be kept powered up at the transition + * to deep sleep. This field can be a bitwise OR of LPM_DOMAIN_x, so + * if required multiple domains can be kept powered. */ -#define LPM_MODULE(n, m, s, w) static lpm_registered_module_t n = \ - { NULL, m, s, w } +#define LPM_MODULE(n, m, s, w, l) static lpm_registered_module_t n = \ + { NULL, m, s, w, l } /*---------------------------------------------------------------------------*/ -/** - * - * \brief Data type used to control whether a PD will get shut down when the - * CM3 drops to deep sleep - * - * Modules using these facilities must allocate a variable of this type, but - * they must not try to manipulate it directly. Instead, the respective - * functions must be used - * - * \sa lpm_pd_lock_obtain(), lpm_pd_lock_release() - */ -typedef struct lpm_power_domain_lock { - struct lpm_power_domain_lock *next; - uint32_t domains; -} lpm_power_domain_lock_t; -/*---------------------------------------------------------------------------*/ -/** - * \brief Prohibit a PD from turning off in standby mode - * \param lock A pointer to a lpm_power_domain_lock_t - * \param domains Bitwise OR from PRCM_DOMAIN_PERIPH, PRCM_DOMAIN_SERIAL - * - * The caller is responsible for allocating lpm_power_domain_lock_t - * - * Only the domains listed above can be locked / released, but a single lock - * can be used for multiple domains - */ -void lpm_pd_lock_obtain(lpm_power_domain_lock_t *lock, uint32_t domains); - -/** - * \brief Permit a PD to turn off in standby mode - * \param pd A pointer to a previously used lock - * - * \sa lpm_pd_lock_obtain() - */ -void lpm_pd_lock_release(lpm_power_domain_lock_t *pd); - /** * \brief Drop the cortex to sleep / deep sleep and shut down peripherals * diff --git a/cpu/cc26xx/slip-arch.c b/cpu/cc26xx/slip-arch.c index 268c84548..ebd6f91c8 100644 --- a/cpu/cc26xx/slip-arch.c +++ b/cpu/cc26xx/slip-arch.c @@ -58,6 +58,10 @@ slip_arch_writeb(unsigned char c) void slip_arch_init(unsigned long ubr) { + /* + * Enable an input handler. In doing so, the driver will make sure that UART + * RX stays operational during deep sleep + */ cc26xx_uart_set_input(slip_input_byte); } /*---------------------------------------------------------------------------*/ diff --git a/examples/cc26xx/cc26xx-demo.c b/examples/cc26xx/cc26xx-demo.c index ff7ea9a38..de5ce5810 100644 --- a/examples/cc26xx/cc26xx-demo.c +++ b/examples/cc26xx/cc26xx-demo.c @@ -100,7 +100,6 @@ #include "button-sensor.h" #include "batmon-sensor.h" #include "board-peripherals.h" -#include "lpm.h" #include "cc26xx-rf.h" #include "ti-lib.h" @@ -368,26 +367,6 @@ init_sensor_readings(void) #endif } /*---------------------------------------------------------------------------*/ -static lpm_power_domain_lock_t lock; -/*---------------------------------------------------------------------------*/ -/* - * In order to maintain UART input operation: - * - Keep the uart clocked in sleep and deep sleep - * - Keep the serial PD on in deep sleep - */ -static void -keep_uart_on(void) -{ - /* Keep the serial PD on */ - lpm_pd_lock_obtain(&lock, PRCM_DOMAIN_SERIAL); - - /* Keep the UART clock on during Sleep and Deep Sleep */ - ti_lib_prcm_peripheral_sleep_enable(PRCM_PERIPH_UART0); - ti_lib_prcm_peripheral_deep_sleep_enable(PRCM_PERIPH_UART0); - ti_lib_prcm_load_set(); - while(!ti_lib_prcm_load_get()); -} -/*---------------------------------------------------------------------------*/ PROCESS_THREAD(cc26xx_demo_process, ev, data) { diff --git a/examples/cc26xx/cc26xx-web-demo/net-uart.c b/examples/cc26xx/cc26xx-web-demo/net-uart.c index 96463aee0..a0ddf1263 100644 --- a/examples/cc26xx/cc26xx-web-demo/net-uart.c +++ b/examples/cc26xx/cc26xx-web-demo/net-uart.c @@ -59,10 +59,10 @@ #include "contiki-conf.h" #include "sys/process.h" #include "dev/serial-line.h" +#include "dev/cc26xx-uart.h" #include "net/ip/uip.h" #include "net/ip/uip-udp-packet.h" #include "net/ip/uiplib.h" -#include "lpm.h" #include "net-uart.h" #include "httpd-simple.h" @@ -148,37 +148,16 @@ net_input(void) return; } /*---------------------------------------------------------------------------*/ -/* - * In order to maintain UART input operation: - * - Keep the uart clocked in sleep and deep sleep - * - Keep the serial PD on in deep sleep - */ -static lpm_power_domain_lock_t lock; -/*---------------------------------------------------------------------------*/ static void release_uart(void) { - /* Release serial PD lock */ - lpm_pd_lock_release(&lock); - - /* Let the UART turn off during Sleep and Deep Sleep */ - ti_lib_prcm_peripheral_sleep_disable(PRCM_PERIPH_UART0); - ti_lib_prcm_peripheral_deep_sleep_disable(PRCM_PERIPH_UART0); - ti_lib_prcm_load_set(); - while(!ti_lib_prcm_load_get()); + cc26xx_uart_set_input(NULL); } /*---------------------------------------------------------------------------*/ static void keep_uart_on(void) { - /* Keep the serial PD on */ - lpm_pd_lock_obtain(&lock, PRCM_DOMAIN_SERIAL); - - /* Keep the UART clock on during Sleep and Deep Sleep */ - ti_lib_prcm_peripheral_sleep_enable(PRCM_PERIPH_UART0); - ti_lib_prcm_peripheral_deep_sleep_enable(PRCM_PERIPH_UART0); - ti_lib_prcm_load_set(); - while(!ti_lib_prcm_load_get()); + cc26xx_uart_set_input(serial_line_input_byte); } /*---------------------------------------------------------------------------*/ static int diff --git a/platform/srf06-cc26xx/sensortag/board.c b/platform/srf06-cc26xx/sensortag/board.c index 096e8e5fc..e421c734c 100644 --- a/platform/srf06-cc26xx/sensortag/board.c +++ b/platform/srf06-cc26xx/sensortag/board.c @@ -88,7 +88,8 @@ shutdown_handler(uint8_t mode) * wake up so we can turn power domains back on for I2C and SSI, and to make * sure everything on the board is off before CM3 shutdown. */ -LPM_MODULE(sensortag_module, NULL, shutdown_handler, lpm_wakeup_handler); +LPM_MODULE(sensortag_module, NULL, shutdown_handler, lpm_wakeup_handler, + LPM_DOMAIN_NONE); /*---------------------------------------------------------------------------*/ void board_init() diff --git a/platform/srf06-cc26xx/sensortag/buzzer.c b/platform/srf06-cc26xx/sensortag/buzzer.c index 57d063897..a5c9001a5 100644 --- a/platform/srf06-cc26xx/sensortag/buzzer.c +++ b/platform/srf06-cc26xx/sensortag/buzzer.c @@ -46,7 +46,7 @@ #include /*---------------------------------------------------------------------------*/ static uint8_t buzzer_on; -static lpm_power_domain_lock_t lock; +LPM_MODULE(buzzer_module, NULL, NULL, NULL, LPM_DOMAIN_PERIPH); /*---------------------------------------------------------------------------*/ void buzzer_init() @@ -74,7 +74,12 @@ buzzer_start(int freq) buzzer_on = 1; - lpm_pd_lock_obtain(&lock, PRCM_DOMAIN_PERIPH); + /* + * Register ourself with LPM. This will keep the PERIPH PD powered on + * during deep sleep, allowing the buzzer to keep working while the chip is + * being power-cycled + */ + lpm_register_module(&buzzer_module); /* Stop the timer */ ti_lib_timer_disable(GPT0_BASE, TIMER_A); @@ -101,7 +106,12 @@ buzzer_stop() { buzzer_on = 0; - lpm_pd_lock_release(&lock); + /* + * Unregister the buzzer module from LPM. This will effectively release our + * lock for the PERIPH PD allowing it to be powered down (unless some other + * module keeps it on) + */ + lpm_unregister_module(&buzzer_module); /* Stop the timer */ ti_lib_timer_disable(GPT0_BASE, TIMER_A); diff --git a/platform/srf06-cc26xx/srf06/board.c b/platform/srf06-cc26xx/srf06/board.c index b7555f0a6..62122cdd0 100644 --- a/platform/srf06-cc26xx/srf06/board.c +++ b/platform/srf06-cc26xx/srf06/board.c @@ -60,7 +60,7 @@ wakeup_handler(void) * getting notified before deep sleep. All we need is to be notified when we * wake up so we can turn power domains back on */ -LPM_MODULE(srf_module, NULL, NULL, lpm_wakeup_handler); +LPM_MODULE(srf_module, NULL, NULL, wakeup_handler, LPM_DOMAIN_NONE); /*---------------------------------------------------------------------------*/ static void configure_unused_pins(void)