diff options
Diffstat (limited to 'stmhal/extint.c')
-rw-r--r-- | stmhal/extint.c | 49 |
1 files changed, 18 insertions, 31 deletions
diff --git a/stmhal/extint.c b/stmhal/extint.c index 78bc17be0f..40254ac4dd 100644 --- a/stmhal/extint.c +++ b/stmhal/extint.c @@ -28,8 +28,6 @@ #include <stddef.h> #include <string.h> -#include <stm32f4xx_hal.h> - #include "py/nlr.h" #include "py/runtime.h" #include "py/gc.h" @@ -101,13 +99,7 @@ typedef struct { mp_int_t line; } extint_obj_t; -typedef struct { - mp_obj_t callback_obj; - void *param; - uint32_t mode; -} extint_vector_t; - -STATIC extint_vector_t extint_vector[EXTI_NUM_VECTORS]; +STATIC uint32_t pyb_extint_mode[EXTI_NUM_VECTORS]; #if !defined(ETH) #define ETH_WKUP_IRQn 62 // The 405 doesn't have ETH, but we want a value to put in our table @@ -123,10 +115,7 @@ STATIC const uint8_t nvic_irq_channel[EXTI_NUM_VECTORS] = { // 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 extint_register(mp_obj_t pin_obj, uint32_t mode, uint32_t pull, mp_obj_t callback_obj, bool override_callback_obj, void *param) { +uint extint_register(mp_obj_t pin_obj, uint32_t mode, uint32_t pull, mp_obj_t callback_obj, bool override_callback_obj) { const pin_obj_t *pin = NULL; uint v_line; @@ -159,22 +148,21 @@ uint extint_register(mp_obj_t pin_obj, uint32_t mode, uint32_t pull, mp_obj_t ca nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid ExtInt Pull: %d", pull)); } - extint_vector_t *v = &extint_vector[v_line]; - if (!override_callback_obj && v->callback_obj != mp_const_none && callback_obj != mp_const_none) { + mp_obj_t *cb = &MP_STATE_PORT(pyb_extint_callback)[v_line]; + if (!override_callback_obj && *cb != mp_const_none && callback_obj != mp_const_none) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "ExtInt vector %d is already in use", v_line)); } - // We need to update callback and param atomically, so we disable the line + // We need to update callback atomically, so we disable the line // before we update anything. extint_disable(v_line); - v->callback_obj = callback_obj; - v->param = param; - v->mode = (mode & 0x00010000) ? // GPIO_MODE_IT == 0x00010000 + *cb = callback_obj; + pyb_extint_mode[v_line] = (mode & 0x00010000) ? // GPIO_MODE_IT == 0x00010000 EXTI_Mode_Interrupt : EXTI_Mode_Event; - if (v->callback_obj != mp_const_none) { + if (*cb != mp_const_none) { GPIO_InitTypeDef exti; exti.Pin = pin->pin_mask; @@ -199,7 +187,7 @@ void extint_enable(uint line) { // Since manipulating IMR/EMR is a read-modify-write, and we want this to // be atomic, we use the bit-band area to just affect the bit we're // interested in. - EXTI_MODE_BB(extint_vector[line].mode, line) = 1; + EXTI_MODE_BB(pyb_extint_mode[line], line) = 1; } void extint_disable(uint line) { @@ -303,7 +291,7 @@ STATIC mp_obj_t extint_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_ extint_obj_t *self = m_new_obj(extint_obj_t); self->base.type = type_in; - self->line = extint_register(vals[0].u_obj, vals[1].u_int, vals[2].u_int, vals[3].u_obj, false, NULL); + self->line = extint_register(vals[0].u_obj, vals[1].u_int, vals[2].u_int, vals[3].u_obj, false); return self; } @@ -343,11 +331,10 @@ const mp_obj_type_t extint_type = { }; void extint_init0(void) { - for (extint_vector_t *v = extint_vector; v < &extint_vector[EXTI_NUM_VECTORS]; v++) { - v->callback_obj = mp_const_none; - v->param = NULL; - v->mode = EXTI_Mode_Interrupt; - } + for (int i = 0; i < PYB_EXTI_NUM_VECTORS; i++) { + MP_STATE_PORT(pyb_extint_callback)[i] = mp_const_none; + pyb_extint_mode[i] = EXTI_Mode_Interrupt; + } } // Interrupt handler @@ -355,18 +342,18 @@ void Handle_EXTI_Irq(uint32_t line) { if (__HAL_GPIO_EXTI_GET_FLAG(1 << line)) { __HAL_GPIO_EXTI_CLEAR_FLAG(1 << line); if (line < EXTI_NUM_VECTORS) { - extint_vector_t *v = &extint_vector[line]; - if (v->callback_obj != mp_const_none) { + mp_obj_t *cb = &MP_STATE_PORT(pyb_extint_callback)[line]; + if (*cb != mp_const_none) { // When executing code within a handler we must lock the GC to prevent // any memory allocations. We must also catch any exceptions. gc_lock(); nlr_buf_t nlr; if (nlr_push(&nlr) == 0) { - mp_call_function_1(v->callback_obj, MP_OBJ_NEW_SMALL_INT(line)); + mp_call_function_1(*cb, MP_OBJ_NEW_SMALL_INT(line)); nlr_pop(); } else { // Uncaught exception; disable the callback so it doesn't run again. - v->callback_obj = mp_const_none; + *cb = mp_const_none; extint_disable(line); printf("Uncaught exception in ExtInt interrupt handler line %lu\n", line); mp_obj_print_exception(printf_wrapper, NULL, (mp_obj_t)nlr.ret_val); |