Skip to content

Commit b044881

Browse files
committed
stmhal: Make USRSW re-register the EXTI callback each time it's set.
1 parent 348435d commit b044881

3 files changed

Lines changed: 22 additions & 13 deletions

File tree

stmhal/exti.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,12 @@ STATIC const uint8_t nvic_irq_channel[EXTI_NUM_VECTORS] = {
105105
OTG_HS_WKUP_IRQn, TAMP_STAMP_IRQn, RTC_WKUP_IRQn
106106
};
107107

108+
// Set override_callback_obj to true if you want to unconditionally set the
109+
// callback function.
110+
//
108111
// NOTE: param is for C callers. Python can use closure to get an object bound
109112
// with the function.
110-
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) {
113+
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) {
111114
const pin_obj_t *pin = NULL;
112115
uint v_line;
113116

@@ -143,7 +146,7 @@ uint exti_register(mp_obj_t pin_obj, mp_obj_t mode_obj, mp_obj_t pull_obj, mp_ob
143146
}
144147

145148
exti_vector_t *v = &exti_vector[v_line];
146-
if (v->callback_obj != mp_const_none && callback_obj != mp_const_none) {
149+
if (!override_callback_obj && v->callback_obj != mp_const_none && callback_obj != mp_const_none) {
147150
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "EXTI vector %d is already in use", v_line));
148151
}
149152

@@ -272,7 +275,7 @@ STATIC mp_obj_t exti_make_new(mp_obj_t type_in, uint n_args, uint n_kw, const mp
272275
mp_obj_t mode_obj = args[1];
273276
mp_obj_t trigger_obj = args[2];
274277
mp_obj_t callback_obj = args[3];
275-
self->line = exti_register(line_obj, mode_obj, trigger_obj, callback_obj, NULL);
278+
self->line = exti_register(line_obj, mode_obj, trigger_obj, callback_obj, false, NULL);
276279

277280
return self;
278281
}
@@ -315,7 +318,8 @@ void Handle_EXTI_Irq(uint32_t line) {
315318
} else {
316319
// Uncaught exception; disable the callback so it doesn't run again.
317320
v->callback_obj = mp_const_none;
318-
printf("Uncaught exception in EXTI interrupt handler on line %lu\n", line);
321+
exti_disable(line);
322+
printf("Uncaught exception in EXTI interrupt handler line %lu\n", line);
319323
mp_obj_print_exception((mp_obj_t)nlr.ret_val);
320324
}
321325
gc_unlock();

stmhal/exti.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
void exti_init(void);
2424

25-
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);
25+
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);
2626

2727
void exti_enable(uint line);
2828
void exti_disable(uint line);

stmhal/usrsw.c

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,9 @@ void switch_init0(void) {
4949
HAL_GPIO_Init(MICROPY_HW_USRSW_PIN.gpio, &init);
5050
}
5151

52-
// this function inits the callback and EXTI function of the switch
52+
// this function inits the callback pointer
5353
void switch_init(void) {
5454
switch_user_callback_obj = mp_const_none;
55-
exti_register((mp_obj_t)&MICROPY_HW_USRSW_PIN,
56-
MP_OBJ_NEW_SMALL_INT(MICROPY_HW_USRSW_EXTI_MODE),
57-
MP_OBJ_NEW_SMALL_INT(MICROPY_HW_USRSW_PULL),
58-
(mp_obj_t)&switch_callback_obj,
59-
NULL);
6055
}
6156

6257
int switch_get(void) {
@@ -70,9 +65,19 @@ int switch_get(void) {
7065
static mp_obj_t pyb_switch(uint n_args, mp_obj_t *args) {
7166
if (n_args == 0) {
7267
return switch_get() ? mp_const_true : mp_const_false;
68+
} else {
69+
switch_user_callback_obj = args[0];
70+
// Init the EXTI each time this function is called, since the EXTI
71+
// may have been disabled by an exception in the interrupt, or the
72+
// user disabling the line explicitly.
73+
exti_register((mp_obj_t)&MICROPY_HW_USRSW_PIN,
74+
MP_OBJ_NEW_SMALL_INT(MICROPY_HW_USRSW_EXTI_MODE),
75+
MP_OBJ_NEW_SMALL_INT(MICROPY_HW_USRSW_PULL),
76+
switch_user_callback_obj == mp_const_none ? mp_const_none : (mp_obj_t)&switch_callback_obj,
77+
true,
78+
NULL);
79+
return mp_const_none;
7380
}
74-
switch_user_callback_obj = args[0];
75-
return mp_const_none;
7681
}
7782

7883
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(pyb_switch_obj, 0, 1, pyb_switch);

0 commit comments

Comments
 (0)