STATIC void pin_irq_enable (mp_obj_t self_in) { const pin_obj_t *self = self_in; uint hib_pin, idx; pin_get_hibernate_pin_and_idx (self, &hib_pin, &idx); if (idx < PYBPIN_NUM_WAKE_PINS) { if (pybpin_wake_pin[idx].lpds != PYBPIN_WAKES_NOT) { // enable GPIO as a wake source during LPDS MAP_PRCMLPDSWakeUpGPIOSelect(idx, pybpin_wake_pin[idx].lpds); MAP_PRCMLPDSWakeupSourceEnable(PRCM_LPDS_GPIO); } if (pybpin_wake_pin[idx].hib != PYBPIN_WAKES_NOT) { // enable GPIO as a wake source during hibernate MAP_PRCMHibernateWakeUpGPIOSelect(hib_pin, pybpin_wake_pin[idx].hib); MAP_PRCMHibernateWakeupSourceEnable(hib_pin); } else { MAP_PRCMHibernateWakeupSourceDisable(hib_pin); } } // if idx is invalid, the pin supports active interrupts for sure if (idx >= PYBPIN_NUM_WAKE_PINS || pybpin_wake_pin[idx].active) { MAP_GPIOIntClear(self->port, self->bit); MAP_GPIOIntEnable(self->port, self->bit); } // in case it was enabled before else if (idx < PYBPIN_NUM_WAKE_PINS && !pybpin_wake_pin[idx].active) { MAP_GPIOIntDisable(self->port, self->bit); } }
void pyb_sleep_init0 (void) { // initialize the sleep objects list 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); // disable all LPDS and hibernate wake up sources (WLAN is disabed/enabled before entering LDPS mode) MAP_PRCMLPDSWakeupSourceDisable(PRCM_LPDS_GPIO); MAP_PRCMLPDSWakeupSourceDisable(PRCM_LPDS_TIMER); MAP_PRCMHibernateWakeupSourceDisable(PRCM_HIB_SLOW_CLK_CTR | PRCM_HIB_GPIO2 | PRCM_HIB_GPIO4 | PRCM_HIB_GPIO13 | PRCM_HIB_GPIO17 | PRCM_HIB_GPIO11 | PRCM_HIB_GPIO24 | PRCM_HIB_GPIO26); // check the reset casue (if it's soft reset, leave it as it is) if (pybsleep_reset_cause != PYB_SLP_SOFT_RESET) { switch (MAP_PRCMSysResetCauseGet()) { case PRCM_POWER_ON: pybsleep_reset_cause = PYB_SLP_PWRON_RESET; break; case PRCM_CORE_RESET: case PRCM_MCU_RESET: case PRCM_SOC_RESET: pybsleep_reset_cause = PYB_SLP_HARD_RESET; break; case PRCM_WDT_RESET: pybsleep_reset_cause = PYB_SLP_WDT_RESET; break; case PRCM_HIB_EXIT: if (PRCMGetSpecialBit(PRCM_WDT_RESET_BIT)) { pybsleep_reset_cause = PYB_SLP_WDT_RESET; } else { pybsleep_reset_cause = PYB_SLP_HIB_RESET; // set the correct wake reason switch (MAP_PRCMHibernateWakeupCauseGet()) { case PRCM_HIB_WAKEUP_CAUSE_SLOW_CLOCK: pybsleep_wake_reason = PYB_SLP_WAKED_BY_RTC; // TODO repeat the alarm break; case PRCM_HIB_WAKEUP_CAUSE_GPIO: pybsleep_wake_reason = PYB_SLP_WAKED_BY_GPIO; break; default: break; } } break; default: break; } } }
STATIC void pin_irq_disable (mp_obj_t self_in) { const pin_obj_t *self = self_in; uint hib_pin, idx; pin_get_hibernate_pin_and_idx (self, &hib_pin, &idx); if (idx < PYBPIN_NUM_WAKE_PINS) { if (pybpin_wake_pin[idx].lpds != PYBPIN_WAKES_NOT) { // disable GPIO as a wake source during LPDS MAP_PRCMLPDSWakeupSourceDisable(PRCM_LPDS_GPIO); } if (pybpin_wake_pin[idx].hib != PYBPIN_WAKES_NOT) { // disable GPIO as a wake source during hibernate MAP_PRCMHibernateWakeupSourceDisable(hib_pin); } } // not need to check for the active flag, it's safe to disable it anyway MAP_GPIOIntDisable(self->port, self->bit); }
/* Timer based wakeup from S4 (HIB) */ static i32 check_n_setup_S4_wakeup_from_timer() { u64 scc_match, scc_curr, scc_remaining; /* Check if there is an alarm set */ if(cc_rtc_has_alarm()) { /* Get the time remaining for the RTC timer to expire */ scc_match = MAP_PRCMSlowClkCtrMatchGet(); scc_curr = MAP_PRCMSlowClkCtrGet(); if(scc_match > scc_curr) { /* Get the time remaining in terms of slow clocks */ scc_remaining = (scc_match - scc_curr); if(scc_remaining > WAKEUP_TIME_HIB) { /* Subtract the time it takes for wakeup from S4 (HIB) */ scc_remaining -= WAKEUP_TIME_HIB; /* Setup the HIB wake time */ MAP_PRCMHibernateIntervalSet(scc_remaining); /* Enable the wake source to be RTC */ MAP_PRCMHibernateWakeupSourceEnable( PRCM_HIB_SLOW_CLK_CTR); } else { /* Cannot enter HIB */ return ERR_TIMER_TO_WAKE; } } else { return -1; } } else { /* Disable Timer as wake source */ MAP_PRCMHibernateWakeupSourceDisable(PRCM_HIB_SLOW_CLK_CTR); return -1; } return 0; }