summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2025-04-22 11:51:35 +1000
committerDamien George <damien@micropython.org>2025-05-21 13:10:01 +1000
commit32c65ad4552d7e7d88c06e94fd903dcea5080c5f (patch)
treed844969767f7267a62cdb89ec284e5b64133928f
parentd5db8f04613b6a7e6f3d55dd8d618e8ccdaecdfa (diff)
nrf: Only process interrupt chars on UARTs used for REPL.
This commit adds an `attached_to_repl` property to each UART, and makes sure that property is correctly set/unset when the UART is attached to or detached from the REPL. That property is then used to make sure incoming characters on the UART are only checked for the interrupt character if the UART is attached to the REPL. Otherwise a board without REPL on UART can have its code interrupted if ctrl-C is received on the UART. Also, put incoming UART characters on to `stdin_ringbuf` instead of the UARTs ring buffer (the former is much larger than the latter). Signed-off-by: Damien George <damien@micropython.org>
-rw-r--r--ports/nrf/main.c4
-rw-r--r--ports/nrf/modules/machine/uart.c26
-rw-r--r--ports/nrf/modules/machine/uart.h3
-rw-r--r--ports/nrf/modules/os/modos.c14
4 files changed, 33 insertions, 14 deletions
diff --git a/ports/nrf/main.c b/ports/nrf/main.c
index 784a031ce..21a71c7c9 100644
--- a/ports/nrf/main.c
+++ b/ports/nrf/main.c
@@ -40,6 +40,7 @@
#include "py/gc.h"
#include "py/compile.h"
#include "py/persistentcode.h"
+#include "extmod/misc.h"
#include "extmod/modmachine.h"
#include "shared/runtime/pyexec.h"
#include "readline.h"
@@ -172,7 +173,8 @@ soft_reset:
MP_OBJ_NEW_SMALL_INT(MICROPY_HW_UART_REPL),
MP_OBJ_NEW_SMALL_INT(MICROPY_HW_UART_REPL_BAUD),
};
- MP_STATE_VM(dupterm_objs[0]) = MP_OBJ_TYPE_GET_SLOT(&machine_uart_type, make_new)((mp_obj_t)&machine_uart_type, MP_ARRAY_SIZE(args), 0, args);
+ mp_obj_t uart = MP_OBJ_TYPE_GET_SLOT(&machine_uart_type, make_new)((mp_obj_t)&machine_uart_type, MP_ARRAY_SIZE(args), 0, args);
+ mp_os_dupterm_obj.fun.var(1, &uart);
}
#endif
diff --git a/ports/nrf/modules/machine/uart.c b/ports/nrf/modules/machine/uart.c
index 8d5a73e09..45c79cda1 100644
--- a/ports/nrf/modules/machine/uart.c
+++ b/ports/nrf/modules/machine/uart.c
@@ -104,6 +104,7 @@ typedef struct _machine_uart_obj_t {
uint16_t timeout_char; // timeout waiting between chars (in ms)
uint8_t uart_id;
bool initialized; // static flag. Initialized to False
+ bool attached_to_repl;
#if MICROPY_PY_MACHINE_UART_IRQ
uint16_t mp_irq_trigger; // user IRQ trigger mask
uint16_t mp_irq_flags; // user IRQ active IRQ flags
@@ -118,6 +119,13 @@ static machine_uart_obj_t machine_uart_obj[] = {
};
void uart_init0(void) {
+ for (int i = 0; i < MP_ARRAY_SIZE(machine_uart_obj); i++) {
+ machine_uart_obj[i].attached_to_repl = false;
+ }
+}
+
+void uart_attach_to_repl(machine_uart_obj_t *self, bool attached) {
+ self->attached_to_repl = attached;
}
static int uart_find(mp_obj_t id) {
@@ -137,14 +145,16 @@ static void uart_event_handler(nrfx_uart_event_t const *p_event, void *p_context
if (p_event->type == NRFX_UART_EVT_RX_DONE) {
nrfx_uart_rx(self->p_uart, &self->buf.rx_buf[0], 1);
int chr = self->buf.rx_buf[0];
- #if !MICROPY_PY_BLE_NUS && MICROPY_KBD_EXCEPTION
- if (chr == mp_interrupt_char) {
- self->buf.rx_ringbuf.iget = 0;
- self->buf.rx_ringbuf.iput = 0;
- mp_sched_keyboard_interrupt();
- } else
- #endif
- {
+ if (self->attached_to_repl) {
+ #if MICROPY_KBD_EXCEPTION
+ if (chr == mp_interrupt_char) {
+ mp_sched_keyboard_interrupt();
+ } else
+ #endif
+ {
+ ringbuf_put((ringbuf_t *)&stdin_ringbuf, chr);
+ }
+ } else {
ringbuf_put((ringbuf_t *)&self->buf.rx_ringbuf, chr);
}
#if MICROPY_PY_MACHINE_UART_IRQ
diff --git a/ports/nrf/modules/machine/uart.h b/ports/nrf/modules/machine/uart.h
index 741473ab7..85c209245 100644
--- a/ports/nrf/modules/machine/uart.h
+++ b/ports/nrf/modules/machine/uart.h
@@ -34,8 +34,7 @@
typedef struct _machine_uart_obj_t machine_uart_obj_t;
void uart_init0(void);
-void uart_deinit(void);
-void uart_irq_handler(mp_uint_t uart_id);
+void uart_attach_to_repl(machine_uart_obj_t *self, bool attached);
bool uart_rx_any(machine_uart_obj_t *uart_obj);
int uart_rx_char(machine_uart_obj_t *uart_obj);
diff --git a/ports/nrf/modules/os/modos.c b/ports/nrf/modules/os/modos.c
index f000e1eeb..97ed1e1ba 100644
--- a/ports/nrf/modules/os/modos.c
+++ b/ports/nrf/modules/os/modos.c
@@ -30,6 +30,7 @@
#include "py/runtime.h"
#include "extmod/modmachine.h"
#include "drivers/rng.h"
+#include "modules/machine/uart.h"
#if MICROPY_PY_OS_URANDOM
// Return a bytes object with n random bytes, generated by the hardware random number generator.
@@ -46,10 +47,17 @@ static MP_DEFINE_CONST_FUN_OBJ_1(mp_os_urandom_obj, mp_os_urandom);
#endif
#if MICROPY_PY_OS_DUPTERM
-// TODO should accept any object with read/write methods.
void mp_os_dupterm_stream_detached_attached(mp_obj_t stream_detached, mp_obj_t stream_attached) {
- if (!(stream_attached == mp_const_none || mp_obj_get_type(stream_attached) == &machine_uart_type)) {
- mp_raise_ValueError(MP_ERROR_TEXT("need a UART object"));
+ #if MICROPY_PY_MACHINE_UART
+ if (mp_obj_get_type(stream_detached) == &machine_uart_type) {
+ uart_attach_to_repl(MP_OBJ_TO_PTR(stream_detached), false);
}
+ #endif
+
+ #if MICROPY_PY_MACHINE_UART
+ if (mp_obj_get_type(stream_attached) == &machine_uart_type) {
+ uart_attach_to_repl(MP_OBJ_TO_PTR(stream_attached), true);
+ }
+ #endif
}
#endif // MICROPY_PY_OS_DUPTERM