2828#include <stddef.h>
2929#include <string.h>
3030
31- #include <stm32f4xx_hal.h>
32-
3331#include "py/nlr.h"
3432#include "py/runtime.h"
3533#include "py/gc.h"
@@ -101,13 +99,7 @@ typedef struct {
10199 mp_int_t line ;
102100} extint_obj_t ;
103101
104- typedef struct {
105- mp_obj_t callback_obj ;
106- void * param ;
107- uint32_t mode ;
108- } extint_vector_t ;
109-
110- STATIC extint_vector_t extint_vector [EXTI_NUM_VECTORS ];
102+ STATIC uint32_t pyb_extint_mode [EXTI_NUM_VECTORS ];
111103
112104#if !defined(ETH )
113105#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] = {
123115
124116// Set override_callback_obj to true if you want to unconditionally set the
125117// callback function.
126- //
127- // NOTE: param is for C callers. Python can use closure to get an object bound
128- // with the function.
129- 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 ) {
118+ uint extint_register (mp_obj_t pin_obj , uint32_t mode , uint32_t pull , mp_obj_t callback_obj , bool override_callback_obj ) {
130119 const pin_obj_t * pin = NULL ;
131120 uint v_line ;
132121
@@ -159,22 +148,21 @@ uint extint_register(mp_obj_t pin_obj, uint32_t mode, uint32_t pull, mp_obj_t ca
159148 nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_ValueError , "invalid ExtInt Pull: %d" , pull ));
160149 }
161150
162- extint_vector_t * v = & extint_vector [v_line ];
163- if (!override_callback_obj && v -> callback_obj != mp_const_none && callback_obj != mp_const_none ) {
151+ mp_obj_t * cb = & MP_STATE_PORT ( pyb_extint_callback ) [v_line ];
152+ if (!override_callback_obj && * cb != mp_const_none && callback_obj != mp_const_none ) {
164153 nlr_raise (mp_obj_new_exception_msg_varg (& mp_type_ValueError , "ExtInt vector %d is already in use" , v_line ));
165154 }
166155
167- // We need to update callback and param atomically, so we disable the line
156+ // We need to update callback atomically, so we disable the line
168157 // before we update anything.
169158
170159 extint_disable (v_line );
171160
172- v -> callback_obj = callback_obj ;
173- v -> param = param ;
174- v -> mode = (mode & 0x00010000 ) ? // GPIO_MODE_IT == 0x00010000
161+ * cb = callback_obj ;
162+ pyb_extint_mode [v_line ] = (mode & 0x00010000 ) ? // GPIO_MODE_IT == 0x00010000
175163 EXTI_Mode_Interrupt : EXTI_Mode_Event ;
176164
177- if (v -> callback_obj != mp_const_none ) {
165+ if (* cb != mp_const_none ) {
178166
179167 GPIO_InitTypeDef exti ;
180168 exti .Pin = pin -> pin_mask ;
@@ -199,7 +187,7 @@ void extint_enable(uint line) {
199187 // Since manipulating IMR/EMR is a read-modify-write, and we want this to
200188 // be atomic, we use the bit-band area to just affect the bit we're
201189 // interested in.
202- EXTI_MODE_BB (extint_vector [line ]. mode , line ) = 1 ;
190+ EXTI_MODE_BB (pyb_extint_mode [line ], line ) = 1 ;
203191}
204192
205193void 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_
303291
304292 extint_obj_t * self = m_new_obj (extint_obj_t );
305293 self -> base .type = type_in ;
306- self -> line = extint_register (vals [0 ].u_obj , vals [1 ].u_int , vals [2 ].u_int , vals [3 ].u_obj , false, NULL );
294+ self -> line = extint_register (vals [0 ].u_obj , vals [1 ].u_int , vals [2 ].u_int , vals [3 ].u_obj , false);
307295
308296 return self ;
309297}
@@ -343,30 +331,29 @@ const mp_obj_type_t extint_type = {
343331};
344332
345333void extint_init0 (void ) {
346- for (extint_vector_t * v = extint_vector ; v < & extint_vector [EXTI_NUM_VECTORS ]; v ++ ) {
347- v -> callback_obj = mp_const_none ;
348- v -> param = NULL ;
349- v -> mode = EXTI_Mode_Interrupt ;
350- }
334+ for (int i = 0 ; i < PYB_EXTI_NUM_VECTORS ; i ++ ) {
335+ MP_STATE_PORT (pyb_extint_callback )[i ] = mp_const_none ;
336+ pyb_extint_mode [i ] = EXTI_Mode_Interrupt ;
337+ }
351338}
352339
353340// Interrupt handler
354341void Handle_EXTI_Irq (uint32_t line ) {
355342 if (__HAL_GPIO_EXTI_GET_FLAG (1 << line )) {
356343 __HAL_GPIO_EXTI_CLEAR_FLAG (1 << line );
357344 if (line < EXTI_NUM_VECTORS ) {
358- extint_vector_t * v = & extint_vector [line ];
359- if (v -> callback_obj != mp_const_none ) {
345+ mp_obj_t * cb = & MP_STATE_PORT ( pyb_extint_callback ) [line ];
346+ if (* cb != mp_const_none ) {
360347 // When executing code within a handler we must lock the GC to prevent
361348 // any memory allocations. We must also catch any exceptions.
362349 gc_lock ();
363350 nlr_buf_t nlr ;
364351 if (nlr_push (& nlr ) == 0 ) {
365- mp_call_function_1 (v -> callback_obj , MP_OBJ_NEW_SMALL_INT (line ));
352+ mp_call_function_1 (* cb , MP_OBJ_NEW_SMALL_INT (line ));
366353 nlr_pop ();
367354 } else {
368355 // Uncaught exception; disable the callback so it doesn't run again.
369- v -> callback_obj = mp_const_none ;
356+ * cb = mp_const_none ;
370357 extint_disable (line );
371358 printf ("Uncaught exception in ExtInt interrupt handler line %lu\n" , line );
372359 mp_obj_print_exception (printf_wrapper , NULL , (mp_obj_t )nlr .ret_val );
0 commit comments