STATIC void PRCMInterruptHandler (void) { // reading the interrupt status automatically clears the interrupt if (PRCM_INT_SLOW_CLK_CTR == MAP_PRCMIntStatus()) { // reconfigure it again (if repeat is true) pyb_rtc_repeat_alarm (pybsleep_data.rtc_obj); pybsleep_data.rtc_obj->irq_flags = PYB_RTC_ALARM0; // need to check if irq's are enabled from the user point of view if (pybsleep_data.rtc_obj->irq_enabled && (pybsleep_data.rtc_obj->pwrmode & PYB_PWR_MODE_ACTIVE)) { mp_irq_handler(pybsleep_data.rtc_obj->irq_obj); } pybsleep_data.rtc_obj->irq_flags = 0; } else { // interrupt has been triggered while waking up from LPDS switch (MAP_PRCMLPDSWakeupCauseGet()) { case PRCM_LPDS_HOST_IRQ: pybsleep_data.wlan_obj->irq_flags = MODWLAN_WIFI_EVENT_ANY; mp_irq_handler(pybsleep_data.wlan_obj->irq_obj); pybsleep_wake_reason = PYB_SLP_WAKED_BY_WLAN; pybsleep_data.wlan_obj->irq_flags = 0; break; case PRCM_LPDS_GPIO: mp_irq_handler(pybsleep_data.gpio_lpds_wake_cb); pybsleep_wake_reason = PYB_SLP_WAKED_BY_GPIO; break; case PRCM_LPDS_TIMER: // reconfigure it again if repeat is true pyb_rtc_repeat_alarm (pybsleep_data.rtc_obj); pybsleep_data.rtc_obj->irq_flags = PYB_RTC_ALARM0; // next one clears the wake cause flag MAP_PRCMLPDSWakeupSourceDisable(PRCM_LPDS_TIMER); mp_irq_handler(pybsleep_data.rtc_obj->irq_obj); pybsleep_data.rtc_obj->irq_flags = 0; pybsleep_wake_reason = PYB_SLP_WAKED_BY_RTC; break; default: break; } } }
// common interrupt handler STATIC void EXTI_Handler(uint port) { uint32_t bits = MAP_GPIOIntStatus(port, true); MAP_GPIOIntClear(port, bits); // might be that we have more than one pin interrupt pending // therefore we must loop through all of the 8 possible bits for (int i = 0; i < 8; i++) { uint32_t bit = (1 << i); if (bit & bits) { pin_obj_t *self = (pin_obj_t *)pin_find_pin_by_port_bit(&pin_board_pins_locals_dict, port, bit); if (self->irq_trigger == (PYB_PIN_FALLING_EDGE | PYB_PIN_RISING_EDGE)) { // read the pin value (hoping that the pin level has remained stable) self->irq_flags = MAP_GPIOPinRead(self->port, self->bit) ? PYB_PIN_RISING_EDGE : PYB_PIN_FALLING_EDGE; } else { // same as the triggers self->irq_flags = self->irq_trigger; } mp_irq_handler(mp_irq_find(self)); // always clear the flags after leaving the user handler self->irq_flags = 0; } } }
STATIC mp_obj_t mp_irq_call (mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, 0, false); mp_irq_handler (self_in); return mp_const_none; }