summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ports/nrf/modules/machine/pin.c25
-rw-r--r--ports/nrf/modules/machine/uart.c8
2 files changed, 27 insertions, 6 deletions
diff --git a/ports/nrf/modules/machine/pin.c b/ports/nrf/modules/machine/pin.c
index f86d878d1..2191cc952 100644
--- a/ports/nrf/modules/machine/pin.c
+++ b/ports/nrf/modules/machine/pin.c
@@ -33,6 +33,7 @@
#include "py/nlr.h"
#include "py/runtime.h"
#include "py/mphal.h"
+#include "py/gc.h"
#include "pin.h"
#include "nrf_gpio.h"
#include "nrfx_gpiote.h"
@@ -498,7 +499,29 @@ static void pin_common_irq_handler(nrfx_gpiote_pin_t pin, nrf_gpiote_polarity_t
mp_obj_t pin_number = MP_OBJ_NEW_SMALL_INT(pin);
const pin_obj_t *pin_obj = pin_find(pin_number);
- mp_call_function_1(pin_handler, (mp_obj_t)pin_obj);
+ if (pin_handler != mp_const_none) {
+ #if MICROPY_ENABLE_SCHEDULER
+ mp_sched_lock();
+ #endif
+ // 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(pin_handler, (mp_obj_t)pin_obj);
+ nlr_pop();
+ } else {
+ // Uncaught exception; disable the callback so it doesn't run again.
+ MP_STATE_PORT(pin_irq_handlers)[pin] = mp_const_none;
+ nrfx_gpiote_in_uninit(pin);
+ mp_printf(MICROPY_ERROR_PRINTER, "uncaught exception in interrupt handler for Pin('%q')\n", pin_obj->name);
+ mp_obj_print_exception(&mp_plat_print, MP_OBJ_FROM_PTR(nlr.ret_val));
+ }
+ gc_unlock();
+ #if MICROPY_ENABLE_SCHEDULER
+ mp_sched_unlock();
+ #endif
+ }
}
static mp_obj_t pin_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
diff --git a/ports/nrf/modules/machine/uart.c b/ports/nrf/modules/machine/uart.c
index 9e502941a..de26fa1b1 100644
--- a/ports/nrf/modules/machine/uart.c
+++ b/ports/nrf/modules/machine/uart.c
@@ -214,11 +214,9 @@ static mp_obj_t mp_machine_uart_make_new(const mp_obj_type_t *type, size_t n_arg
config.hal_cfg.parity = NRF_UART_PARITY_EXCLUDED;
- #if (BLUETOOTH_SD == 100)
- config.interrupt_priority = 3;
- #else
- config.interrupt_priority = 6;
- #endif
+ // Higher priority than pin interrupts, otherwise printing exceptions from
+ // interrupt handlers gets stuck.
+ config.interrupt_priority = NRFX_GPIOTE_DEFAULT_CONFIG_IRQ_PRIORITY - 1;
// These baudrates are not supported, it seems.
if (args[ARG_baudrate].u_int < 1200 || args[ARG_baudrate].u_int > 1000000) {