Skip to content

Commit 32c65ad

Browse files
committed
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 <[email protected]>
1 parent d5db8f0 commit 32c65ad

File tree

4 files changed

+33
-14
lines changed

4 files changed

+33
-14
lines changed

ports/nrf/main.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "py/gc.h"
4141
#include "py/compile.h"
4242
#include "py/persistentcode.h"
43+
#include "extmod/misc.h"
4344
#include "extmod/modmachine.h"
4445
#include "shared/runtime/pyexec.h"
4546
#include "readline.h"
@@ -172,7 +173,8 @@ void MP_NORETURN _start(void) {
172173
MP_OBJ_NEW_SMALL_INT(MICROPY_HW_UART_REPL),
173174
MP_OBJ_NEW_SMALL_INT(MICROPY_HW_UART_REPL_BAUD),
174175
};
175-
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);
176+
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);
177+
mp_os_dupterm_obj.fun.var(1, &uart);
176178
}
177179
#endif
178180

ports/nrf/modules/machine/uart.c

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ typedef struct _machine_uart_obj_t {
104104
uint16_t timeout_char; // timeout waiting between chars (in ms)
105105
uint8_t uart_id;
106106
bool initialized; // static flag. Initialized to False
107+
bool attached_to_repl;
107108
#if MICROPY_PY_MACHINE_UART_IRQ
108109
uint16_t mp_irq_trigger; // user IRQ trigger mask
109110
uint16_t mp_irq_flags; // user IRQ active IRQ flags
@@ -118,6 +119,13 @@ static machine_uart_obj_t machine_uart_obj[] = {
118119
};
119120

120121
void uart_init0(void) {
122+
for (int i = 0; i < MP_ARRAY_SIZE(machine_uart_obj); i++) {
123+
machine_uart_obj[i].attached_to_repl = false;
124+
}
125+
}
126+
127+
void uart_attach_to_repl(machine_uart_obj_t *self, bool attached) {
128+
self->attached_to_repl = attached;
121129
}
122130

123131
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
137145
if (p_event->type == NRFX_UART_EVT_RX_DONE) {
138146
nrfx_uart_rx(self->p_uart, &self->buf.rx_buf[0], 1);
139147
int chr = self->buf.rx_buf[0];
140-
#if !MICROPY_PY_BLE_NUS && MICROPY_KBD_EXCEPTION
141-
if (chr == mp_interrupt_char) {
142-
self->buf.rx_ringbuf.iget = 0;
143-
self->buf.rx_ringbuf.iput = 0;
144-
mp_sched_keyboard_interrupt();
145-
} else
146-
#endif
147-
{
148+
if (self->attached_to_repl) {
149+
#if MICROPY_KBD_EXCEPTION
150+
if (chr == mp_interrupt_char) {
151+
mp_sched_keyboard_interrupt();
152+
} else
153+
#endif
154+
{
155+
ringbuf_put((ringbuf_t *)&stdin_ringbuf, chr);
156+
}
157+
} else {
148158
ringbuf_put((ringbuf_t *)&self->buf.rx_ringbuf, chr);
149159
}
150160
#if MICROPY_PY_MACHINE_UART_IRQ

ports/nrf/modules/machine/uart.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@
3434
typedef struct _machine_uart_obj_t machine_uart_obj_t;
3535

3636
void uart_init0(void);
37-
void uart_deinit(void);
38-
void uart_irq_handler(mp_uint_t uart_id);
37+
void uart_attach_to_repl(machine_uart_obj_t *self, bool attached);
3938

4039
bool uart_rx_any(machine_uart_obj_t *uart_obj);
4140
int uart_rx_char(machine_uart_obj_t *uart_obj);

ports/nrf/modules/os/modos.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "py/runtime.h"
3131
#include "extmod/modmachine.h"
3232
#include "drivers/rng.h"
33+
#include "modules/machine/uart.h"
3334

3435
#if MICROPY_PY_OS_URANDOM
3536
// 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);
4647
#endif
4748

4849
#if MICROPY_PY_OS_DUPTERM
49-
// TODO should accept any object with read/write methods.
5050
void mp_os_dupterm_stream_detached_attached(mp_obj_t stream_detached, mp_obj_t stream_attached) {
51-
if (!(stream_attached == mp_const_none || mp_obj_get_type(stream_attached) == &machine_uart_type)) {
52-
mp_raise_ValueError(MP_ERROR_TEXT("need a UART object"));
51+
#if MICROPY_PY_MACHINE_UART
52+
if (mp_obj_get_type(stream_detached) == &machine_uart_type) {
53+
uart_attach_to_repl(MP_OBJ_TO_PTR(stream_detached), false);
5354
}
55+
#endif
56+
57+
#if MICROPY_PY_MACHINE_UART
58+
if (mp_obj_get_type(stream_attached) == &machine_uart_type) {
59+
uart_attach_to_repl(MP_OBJ_TO_PTR(stream_attached), true);
60+
}
61+
#endif
5462
}
5563
#endif // MICROPY_PY_OS_DUPTERM

0 commit comments

Comments
 (0)