diff --git a/stmhal/exti.c b/stmhal/exti.c index 552efdf080..5ea3db62bb 100644 --- a/stmhal/exti.c +++ b/stmhal/exti.c @@ -105,9 +105,12 @@ STATIC const uint8_t nvic_irq_channel[EXTI_NUM_VECTORS] = { OTG_HS_WKUP_IRQn, TAMP_STAMP_IRQn, RTC_WKUP_IRQn }; +// Set override_callback_obj to true if you want to unconditionally set the +// callback function. +// // NOTE: param is for C callers. Python can use closure to get an object bound // with the function. -uint exti_register(mp_obj_t pin_obj, mp_obj_t mode_obj, mp_obj_t pull_obj, mp_obj_t callback_obj, void *param) { +uint exti_register(mp_obj_t pin_obj, mp_obj_t mode_obj, mp_obj_t pull_obj, mp_obj_t callback_obj, bool override_callback_obj, void *param) { const pin_obj_t *pin = NULL; uint v_line; @@ -143,7 +146,7 @@ uint exti_register(mp_obj_t pin_obj, mp_obj_t mode_obj, mp_obj_t pull_obj, mp_ob } exti_vector_t *v = &exti_vector[v_line]; - if (v->callback_obj != mp_const_none && callback_obj != mp_const_none) { + if (!override_callback_obj && v->callback_obj != mp_const_none && callback_obj != mp_const_none) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "EXTI vector %d is already in use", v_line)); } @@ -272,7 +275,7 @@ STATIC mp_obj_t exti_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp mp_obj_t mode_obj = args[1]; mp_obj_t trigger_obj = args[2]; mp_obj_t callback_obj = args[3]; - self->line = exti_register(line_obj, mode_obj, trigger_obj, callback_obj, NULL); + self->line = exti_register(line_obj, mode_obj, trigger_obj, callback_obj, false, NULL); return self; } @@ -315,7 +318,8 @@ void Handle_EXTI_Irq(uint32_t line) { } else { // Uncaught exception; disable the callback so it doesn't run again. v->callback_obj = mp_const_none; - printf("Uncaught exception in EXTI interrupt handler on line %lu\n", line); + exti_disable(line); + printf("Uncaught exception in EXTI interrupt handler line %lu\n", line); mp_obj_print_exception((mp_obj_t)nlr.ret_val); } gc_unlock(); diff --git a/stmhal/exti.h b/stmhal/exti.h index a6b50b26e8..6feb9dceaf 100644 --- a/stmhal/exti.h +++ b/stmhal/exti.h @@ -22,7 +22,7 @@ void exti_init(void); -uint exti_register(mp_obj_t pin_obj, mp_obj_t mode_obj, mp_obj_t trigger_obj, mp_obj_t callback_obj, void *param); +uint exti_register(mp_obj_t pin_obj, mp_obj_t mode_obj, mp_obj_t trigger_obj, mp_obj_t callback_obj, bool override_callback_obj, void *param); void exti_enable(uint line); void exti_disable(uint line); diff --git a/stmhal/usrsw.c b/stmhal/usrsw.c index 453c3dfa82..5133392ccd 100644 --- a/stmhal/usrsw.c +++ b/stmhal/usrsw.c @@ -49,14 +49,9 @@ void switch_init0(void) { HAL_GPIO_Init(MICROPY_HW_USRSW_PIN.gpio, &init); } -// this function inits the callback and EXTI function of the switch +// this function inits the callback pointer void switch_init(void) { switch_user_callback_obj = mp_const_none; - exti_register((mp_obj_t)&MICROPY_HW_USRSW_PIN, - MP_OBJ_NEW_SMALL_INT(MICROPY_HW_USRSW_EXTI_MODE), - MP_OBJ_NEW_SMALL_INT(MICROPY_HW_USRSW_PULL), - (mp_obj_t)&switch_callback_obj, - NULL); } int switch_get(void) { @@ -70,9 +65,19 @@ int switch_get(void) { static mp_obj_t pyb_switch(uint n_args, mp_obj_t *args) { if (n_args == 0) { return switch_get() ? mp_const_true : mp_const_false; + } else { + switch_user_callback_obj = args[0]; + // Init the EXTI each time this function is called, since the EXTI + // may have been disabled by an exception in the interrupt, or the + // user disabling the line explicitly. + exti_register((mp_obj_t)&MICROPY_HW_USRSW_PIN, + MP_OBJ_NEW_SMALL_INT(MICROPY_HW_USRSW_EXTI_MODE), + MP_OBJ_NEW_SMALL_INT(MICROPY_HW_USRSW_PULL), + switch_user_callback_obj == mp_const_none ? mp_const_none : (mp_obj_t)&switch_callback_obj, + true, + NULL); + return mp_const_none; } - switch_user_callback_obj = args[0]; - return mp_const_none; } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_switch_obj, 0, 1, pyb_switch);