Beispiel #1
0
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);
    }
}
Beispiel #2
0
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;
        }
    }
}
Beispiel #3
0
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);
}
Beispiel #4
0
/* 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;
}