summaryrefslogtreecommitdiffstatshomepage
path: root/cc3200/mods/pybsleep.c
diff options
context:
space:
mode:
Diffstat (limited to 'cc3200/mods/pybsleep.c')
-rw-r--r--cc3200/mods/pybsleep.c260
1 files changed, 100 insertions, 160 deletions
diff --git a/cc3200/mods/pybsleep.c b/cc3200/mods/pybsleep.c
index 2cdb10fd36..640a7269e0 100644
--- a/cc3200/mods/pybsleep.c
+++ b/cc3200/mods/pybsleep.c
@@ -72,7 +72,7 @@
#define WAKEUP_TIME_HIB (32768) // 1 s
#define FORCED_TIMER_INTERRUPT_MS (PYB_RTC_MIN_ALARM_TIME_MS)
-#define FAILED_SLEEP_DELAY_MS (FORCED_TIMER_INTERRUPT_MS * 2)
+#define FAILED_SLEEP_DELAY_MS (FORCED_TIMER_INTERRUPT_MS * 3)
/******************************************************************************
DECLARE PRIVATE TYPES
@@ -111,7 +111,7 @@ typedef struct {
mp_obj_base_t base;
mp_obj_t obj;
WakeUpCB_t wakeup;
-} pybsleep_obj_t;
+} pyb_sleep_obj_t;
typedef struct {
mp_obj_t gpio_lpds_wake_cb;
@@ -122,23 +122,26 @@ typedef struct {
/******************************************************************************
DECLARE PRIVATE DATA
******************************************************************************/
-STATIC const mp_obj_type_t pybsleep_type;
STATIC nvic_reg_store_t *nvic_reg_store;
STATIC pybsleep_data_t pybsleep_data = {NULL, NULL, NULL};
volatile arm_cm4_core_regs_t vault_arm_registers;
STATIC pybsleep_reset_cause_t pybsleep_reset_cause = PYB_SLP_PWRON_RESET;
STATIC pybsleep_wake_reason_t pybsleep_wake_reason = PYB_SLP_WAKED_PWRON;
+STATIC const mp_obj_type_t pyb_sleep_type = {
+ { &mp_type_type },
+ .name = MP_QSTR_sleep,
+};
/******************************************************************************
DECLARE PRIVATE FUNCTIONS
******************************************************************************/
-STATIC pybsleep_obj_t *pybsleep_find (mp_obj_t obj);
-STATIC void pybsleep_flash_powerdown (void);
-STATIC NORETURN void pybsleep_suspend_enter (void);
-void pybsleep_suspend_exit (void);
-STATIC void pybsleep_obj_wakeup (void);
+STATIC pyb_sleep_obj_t *pyb_sleep_find (mp_obj_t obj);
+STATIC void pyb_sleep_flash_powerdown (void);
+STATIC NORETURN void pyb_sleep_suspend_enter (void);
+void pyb_sleep_suspend_exit (void);
+STATIC void pyb_sleep_obj_wakeup (void);
STATIC void PRCMInterruptHandler (void);
-STATIC void pybsleep_iopark (bool hibernate);
+STATIC void pyb_sleep_iopark (bool hibernate);
STATIC bool setup_timer_lpds_wake (void);
STATIC bool setup_timer_hibernate_wake (void);
@@ -146,14 +149,14 @@ STATIC bool setup_timer_hibernate_wake (void);
DEFINE PUBLIC FUNCTIONS
******************************************************************************/
__attribute__ ((section (".boot")))
-void pybsleep_pre_init (void) {
+void pyb_sleep_pre_init (void) {
// allocate memory for nvic registers vault
ASSERT ((nvic_reg_store = mem_Malloc(sizeof(nvic_reg_store_t))) != NULL);
}
-void pybsleep_init0 (void) {
+void pyb_sleep_init0 (void) {
// initialize the sleep objects list
- mp_obj_list_init(&MP_STATE_PORT(pybsleep_obj_list), 0);
+ mp_obj_list_init(&MP_STATE_PORT(pyb_sleep_obj_list), 0);
// register and enable the PRCM interrupt
osi_InterruptRegister(INT_PRCM, (P_OSI_INTR_ENTRY)PRCMInterruptHandler, INT_PRIORITY_LVL_1);
@@ -204,50 +207,109 @@ void pybsleep_init0 (void) {
}
}
-void pybsleep_signal_soft_reset (void) {
+void pyb_sleep_signal_soft_reset (void) {
pybsleep_reset_cause = PYB_SLP_SOFT_RESET;
}
-void pybsleep_add (const mp_obj_t obj, WakeUpCB_t wakeup) {
- pybsleep_obj_t * sleep_obj = m_new_obj(pybsleep_obj_t);
- sleep_obj->base.type = &pybsleep_type;
+void pyb_sleep_add (const mp_obj_t obj, WakeUpCB_t wakeup) {
+ pyb_sleep_obj_t *sleep_obj = m_new_obj(pyb_sleep_obj_t);
+ sleep_obj->base.type = &pyb_sleep_type;
sleep_obj->obj = obj;
sleep_obj->wakeup = wakeup;
// remove it in case it was already registered
- pybsleep_remove (obj);
- mp_obj_list_append(&MP_STATE_PORT(pybsleep_obj_list), sleep_obj);
+ pyb_sleep_remove (obj);
+ mp_obj_list_append(&MP_STATE_PORT(pyb_sleep_obj_list), sleep_obj);
}
-void pybsleep_remove (const mp_obj_t obj) {
- pybsleep_obj_t *sleep_obj;
- if ((sleep_obj = pybsleep_find(obj))) {
- mp_obj_list_remove(&MP_STATE_PORT(pybsleep_obj_list), sleep_obj);
+void pyb_sleep_remove (const mp_obj_t obj) {
+ pyb_sleep_obj_t *sleep_obj;
+ if ((sleep_obj = pyb_sleep_find(obj))) {
+ mp_obj_list_remove(&MP_STATE_PORT(pyb_sleep_obj_list), sleep_obj);
}
}
-void pybsleep_set_gpio_lpds_callback (mp_obj_t cb_obj) {
+void pyb_sleep_set_gpio_lpds_callback (mp_obj_t cb_obj) {
pybsleep_data.gpio_lpds_wake_cb = cb_obj;
}
-void pybsleep_set_wlan_obj (mp_obj_t wlan_obj) {
+void pyb_sleep_set_wlan_obj (mp_obj_t wlan_obj) {
pybsleep_data.wlan_obj = (wlan_obj_t *)wlan_obj;
}
-void pybsleep_set_rtc_obj (mp_obj_t rtc_obj) {
+void pyb_sleep_set_rtc_obj (mp_obj_t rtc_obj) {
pybsleep_data.rtc_obj = (pyb_rtc_obj_t *)rtc_obj;
}
-pybsleep_reset_cause_t pybsleep_get_reset_cause (void) {
+void pyb_sleep_sleep (void) {
+ nlr_buf_t nlr;
+
+ // check if we should enable timer wake-up
+ if (pybsleep_data.rtc_obj->irq_enabled && (pybsleep_data.rtc_obj->pwrmode & PYB_PWR_MODE_LPDS)) {
+ if (!setup_timer_lpds_wake()) {
+ // lpds entering is not possible, wait for the forced interrupt and return
+ HAL_Delay (FAILED_SLEEP_DELAY_MS);
+ return;
+ }
+ } else {
+ // disable the timer as wake source
+ MAP_PRCMLPDSWakeupSourceDisable(PRCM_LPDS_TIMER);
+ }
+
+ // do we need network wake-up?
+ if (pybsleep_data.wlan_obj->irq_enabled) {
+ MAP_PRCMLPDSWakeupSourceEnable (PRCM_LPDS_HOST_IRQ);
+ server_sleep_sockets();
+ } else {
+ MAP_PRCMLPDSWakeupSourceDisable (PRCM_LPDS_HOST_IRQ);
+ }
+
+ // entering and exiting suspended mode must be an atomic operation
+ // therefore interrupts need to be disabled
+ uint primsk = disable_irq();
+ if (nlr_push(&nlr) == 0) {
+ pyb_sleep_suspend_enter();
+ nlr_pop();
+ }
+
+ // an exception is always raised when exiting suspend mode
+ enable_irq(primsk);
+}
+
+void pyb_sleep_deepsleep (void) {
+ // check if we should enable timer wake-up
+ if (pybsleep_data.rtc_obj->irq_enabled && (pybsleep_data.rtc_obj->pwrmode & PYB_PWR_MODE_HIBERNATE)) {
+ if (!setup_timer_hibernate_wake()) {
+ // hibernating is not possible, wait for the forced interrupt and return
+ HAL_Delay (FAILED_SLEEP_DELAY_MS);
+ return;
+ }
+ } else {
+ // disable the timer as hibernate wake source
+ MAP_PRCMLPDSWakeupSourceDisable(PRCM_HIB_SLOW_CLK_CTR);
+ }
+
+ wlan_stop(SL_STOP_TIMEOUT);
+ pyb_sleep_flash_powerdown();
+ // must be done just before entering hibernate mode
+ pyb_sleep_iopark(true);
+ MAP_PRCMHibernateEnter();
+}
+
+pybsleep_reset_cause_t pyb_sleep_get_reset_cause (void) {
return pybsleep_reset_cause;
}
+pybsleep_wake_reason_t pyb_sleep_get_wake_reason (void) {
+ return pybsleep_wake_reason;
+}
+
/******************************************************************************
DEFINE PRIVATE FUNCTIONS
******************************************************************************/
-STATIC pybsleep_obj_t *pybsleep_find (mp_obj_t obj) {
- for (mp_uint_t i = 0; i < MP_STATE_PORT(pybsleep_obj_list).len; i++) {
+STATIC pyb_sleep_obj_t *pyb_sleep_find (mp_obj_t obj) {
+ for (mp_uint_t i = 0; i < MP_STATE_PORT(pyb_sleep_obj_list).len; i++) {
// search for the object and then remove it
- pybsleep_obj_t *sleep_obj = ((pybsleep_obj_t *)(MP_STATE_PORT(pybsleep_obj_list).items[i]));
+ pyb_sleep_obj_t *sleep_obj = ((pyb_sleep_obj_t *)(MP_STATE_PORT(pyb_sleep_obj_list).items[i]));
if (sleep_obj->obj == obj) {
return sleep_obj;
}
@@ -255,7 +317,7 @@ STATIC pybsleep_obj_t *pybsleep_find (mp_obj_t obj) {
return NULL;
}
-STATIC void pybsleep_flash_powerdown (void) {
+STATIC void pyb_sleep_flash_powerdown (void) {
uint32_t status;
// Enable clock for SSPI module
@@ -300,7 +362,7 @@ STATIC void pybsleep_flash_powerdown (void) {
MAP_SPICSDisable(SSPI_BASE);
}
-STATIC NORETURN void pybsleep_suspend_enter (void) {
+STATIC NORETURN void pyb_sleep_suspend_enter (void) {
// enable full RAM retention
MAP_PRCMSRAMRetentionEnable(PRCM_SRAM_COL_1 | PRCM_SRAM_COL_2 | PRCM_SRAM_COL_3 | PRCM_SRAM_COL_4, PRCM_SRAM_LPDS_RET);
@@ -337,7 +399,7 @@ STATIC NORETURN void pybsleep_suspend_enter (void) {
mperror_heartbeat_switch_off();
// park the gpio pins
- pybsleep_iopark(false);
+ pyb_sleep_iopark(false);
// store the cpu registers
sleep_store();
@@ -350,7 +412,7 @@ STATIC NORETURN void pybsleep_suspend_enter (void) {
for ( ; ; );
}
-void pybsleep_suspend_exit (void) {
+void pyb_sleep_suspend_exit (void) {
// take the I2C semaphore
uint32_t reg = HWREG(COMMON_REG_BASE + COMMON_REG_O_I2C_Properties_Register);
reg = (reg & ~0x3) | 0x1;
@@ -404,7 +466,7 @@ void pybsleep_suspend_exit (void) {
sl_IfOpen (NULL, 0);
// restore the configuration of all active peripherals
- pybsleep_obj_wakeup();
+ pyb_sleep_obj_wakeup();
// reconfigure all the previously enabled interrupts
mp_irq_wake_all();
@@ -459,14 +521,14 @@ STATIC void PRCMInterruptHandler (void) {
}
}
-STATIC void pybsleep_obj_wakeup (void) {
- for (mp_uint_t i = 0; i < MP_STATE_PORT(pybsleep_obj_list).len; i++) {
- pybsleep_obj_t *sleep_obj = ((pybsleep_obj_t *)MP_STATE_PORT(pybsleep_obj_list).items[i]);
+STATIC void pyb_sleep_obj_wakeup (void) {
+ for (mp_uint_t i = 0; i < MP_STATE_PORT(pyb_sleep_obj_list).len; i++) {
+ pyb_sleep_obj_t *sleep_obj = ((pyb_sleep_obj_t *)MP_STATE_PORT(pyb_sleep_obj_list).items[i]);
sleep_obj->wakeup(sleep_obj->obj);
}
}
-STATIC void pybsleep_iopark (bool hibernate) {
+STATIC void pyb_sleep_iopark (bool hibernate) {
mp_map_t *named_map = mp_obj_dict_get_map((mp_obj_t)&pin_board_pins_locals_dict);
for (uint i = 0; i < named_map->used; i++) {
pin_obj_t * pin = (pin_obj_t *)named_map->table[i].value;
@@ -593,125 +655,3 @@ STATIC bool setup_timer_hibernate_wake (void) {
return false;
}
-/******************************************************************************/
-// Micro Python bindings; Sleep class
-
-/// \function idle()
-/// Gates the processor clock until an interrupt is triggered
-STATIC mp_obj_t pyb_sleep_idle (mp_obj_t self_in) {
- __WFI();
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sleep_idle_obj, pyb_sleep_idle);
-
-/// \function suspend(wlan)
-/// Enters suspended mode. Wake up sources should have been enable prior to
-/// calling this method.
-STATIC mp_obj_t pyb_sleep_suspend (mp_obj_t self_in) {
- nlr_buf_t nlr;
-
- // check if we should enable timer wake-up
- if (pybsleep_data.rtc_obj->irq_enabled && (pybsleep_data.rtc_obj->pwrmode & PYB_PWR_MODE_LPDS)) {
- if (!setup_timer_lpds_wake()) {
- // lpds entering is not possible, wait for the forced interrupt and return
- HAL_Delay (FAILED_SLEEP_DELAY_MS);
- return mp_const_none;
- }
- } else {
- // disable the timer as wake source
- MAP_PRCMLPDSWakeupSourceDisable(PRCM_LPDS_TIMER);
- }
-
- // do we need network wake-up?
- if (pybsleep_data.wlan_obj->irq_enabled) {
- MAP_PRCMLPDSWakeupSourceEnable (PRCM_LPDS_HOST_IRQ);
- server_sleep_sockets();
- } else {
- MAP_PRCMLPDSWakeupSourceDisable (PRCM_LPDS_HOST_IRQ);
- }
-
- // entering and exiting suspended mode must be an atomic operation
- // therefore interrupts need to be disabled
- uint primsk = disable_irq();
- if (nlr_push(&nlr) == 0) {
- pybsleep_suspend_enter();
- nlr_pop();
- }
-
- // an exception is always raised when exiting suspend mode
- enable_irq(primsk);
-
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sleep_suspend_obj, pyb_sleep_suspend);
-
-/// \function hibernate()
-/// Enters hibernate mode. Wake up sources should have been enable prior to
-/// calling this method.
-STATIC mp_obj_t pyb_sleep_hibernate (mp_obj_t self_in) {
- // check if we should enable timer wake-up
- if (pybsleep_data.rtc_obj->irq_enabled && (pybsleep_data.rtc_obj->pwrmode & PYB_PWR_MODE_HIBERNATE)) {
- if (!setup_timer_hibernate_wake()) {
- // hibernating is not possible, wait for the forced interrupt and return
- HAL_Delay (FAILED_SLEEP_DELAY_MS);
- return mp_const_none;
- }
- } else {
- // disable the timer as hibernate wake source
- MAP_PRCMLPDSWakeupSourceDisable(PRCM_HIB_SLOW_CLK_CTR);
- }
-
- wlan_stop(SL_STOP_TIMEOUT);
- pybsleep_flash_powerdown();
- // must be done just before entering hibernate mode
- pybsleep_iopark(true);
- MAP_PRCMHibernateEnter();
- return mp_const_none;
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sleep_hibernate_obj, pyb_sleep_hibernate);
-
-/// \function reset_cause()
-/// Returns the last reset casue
-STATIC mp_obj_t pyb_sleep_reset_cause (mp_obj_t self_in) {
- return MP_OBJ_NEW_SMALL_INT(pybsleep_reset_cause);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sleep_reset_cause_obj, pyb_sleep_reset_cause);
-
-/// \function wake_reason()
-/// Returns the wake up reson from ldps or hibernate
-STATIC mp_obj_t pyb_sleep_wake_reason (mp_obj_t self_in) {
- return MP_OBJ_NEW_SMALL_INT(pybsleep_wake_reason);
-}
-STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_sleep_wake_reason_obj, pyb_sleep_wake_reason);
-
-STATIC const mp_map_elem_t pybsleep_locals_dict_table[] = {
- // instance methods
- { MP_OBJ_NEW_QSTR(MP_QSTR_idle), (mp_obj_t)&pyb_sleep_idle_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_suspend), (mp_obj_t)&pyb_sleep_suspend_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_hibernate), (mp_obj_t)&pyb_sleep_hibernate_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_reset_cause), (mp_obj_t)&pyb_sleep_reset_cause_obj },
- { MP_OBJ_NEW_QSTR(MP_QSTR_wake_reason), (mp_obj_t)&pyb_sleep_wake_reason_obj },
-
- // class constants
- { MP_OBJ_NEW_QSTR(MP_QSTR_ACTIVE), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_ACTIVE) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SUSPENDED), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_LPDS) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_HIBERNATING), MP_OBJ_NEW_SMALL_INT(PYB_PWR_MODE_HIBERNATE) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_POWER_ON), MP_OBJ_NEW_SMALL_INT(PYB_SLP_PWRON_RESET) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_HARD_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_HARD_RESET) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_WDT_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WDT_RESET) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_HIB_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_HIB_RESET) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_SOFT_RESET), MP_OBJ_NEW_SMALL_INT(PYB_SLP_SOFT_RESET) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_WLAN_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_WLAN) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_PIN_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_GPIO) },
- { MP_OBJ_NEW_QSTR(MP_QSTR_RTC_WAKE), MP_OBJ_NEW_SMALL_INT(PYB_SLP_WAKED_BY_RTC) },
-};
-
-STATIC MP_DEFINE_CONST_DICT(pybsleep_locals_dict, pybsleep_locals_dict_table);
-
-STATIC const mp_obj_type_t pybsleep_type = {
- { &mp_type_type },
- .name = MP_QSTR_Sleep,
- .locals_dict = (mp_obj_t)&pybsleep_locals_dict,
-};
-
-const mp_obj_base_t pyb_sleep_obj = {&pybsleep_type};