nrf/uart: Change UART driver to be non-blocking and use IRQs.
As part of this, ctrl-C is now able to interrupt a running program.
This commit is contained in:
parent
d80abd035e
commit
302ffdba7f
@ -35,8 +35,10 @@
|
||||
#include "py/stream.h"
|
||||
#include "py/mperrno.h"
|
||||
#include "py/mphal.h"
|
||||
#include "py/ringbuf.h"
|
||||
#include "pin.h"
|
||||
#include "genhdr/pins.h"
|
||||
#include "lib/utils/interrupt_char.h"
|
||||
|
||||
#include "uart.h"
|
||||
#include "mpconfigboard.h"
|
||||
@ -47,15 +49,25 @@
|
||||
|
||||
#if MICROPY_PY_MACHINE_UART
|
||||
|
||||
typedef struct _machine_hard_uart_buf_t {
|
||||
uint8_t tx_buf[1];
|
||||
uint8_t rx_buf[1];
|
||||
uint8_t rx_ringbuf_array[64];
|
||||
volatile ringbuf_t rx_ringbuf;
|
||||
} machine_hard_uart_buf_t;
|
||||
|
||||
typedef struct _machine_hard_uart_obj_t {
|
||||
mp_obj_base_t base;
|
||||
const nrfx_uart_t * p_uart; // Driver instance
|
||||
machine_hard_uart_buf_t *buf;
|
||||
} machine_hard_uart_obj_t;
|
||||
|
||||
static const nrfx_uart_t instance0 = NRFX_UART_INSTANCE(0);
|
||||
|
||||
STATIC machine_hard_uart_buf_t machine_hard_uart_buf[1];
|
||||
|
||||
STATIC const machine_hard_uart_obj_t machine_hard_uart_obj[] = {
|
||||
{{&machine_hard_uart_type}, .p_uart = &instance0},
|
||||
{{&machine_hard_uart_type}, .p_uart = &instance0, .buf = &machine_hard_uart_buf[0]},
|
||||
};
|
||||
|
||||
void uart_init0(void) {
|
||||
@ -70,27 +82,36 @@ STATIC int uart_find(mp_obj_t id) {
|
||||
mp_raise_ValueError("UART doesn't exist");
|
||||
}
|
||||
|
||||
void uart_irq_handler(mp_uint_t uart_id) {
|
||||
|
||||
STATIC void uart_event_handler(nrfx_uart_event_t const *p_event, void *p_context) {
|
||||
machine_hard_uart_obj_t *self = p_context;
|
||||
if (p_event->type == NRFX_UART_EVT_RX_DONE) {
|
||||
int chr = self->buf->rx_buf[0];
|
||||
nrfx_uart_rx(self->p_uart, &self->buf->rx_buf[0], 1);
|
||||
#if !MICROPY_PY_BLE_NUS && MICROPY_KBD_EXCEPTION
|
||||
if (chr == mp_interrupt_char) {
|
||||
mp_keyboard_interrupt();
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
ringbuf_put((ringbuf_t*)&self->buf->rx_ringbuf, chr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool uart_rx_any(const machine_hard_uart_obj_t *uart_obj) {
|
||||
// TODO: uart will block for now.
|
||||
return true;
|
||||
bool uart_rx_any(const machine_hard_uart_obj_t *self) {
|
||||
return self->buf->rx_ringbuf.iput != self->buf->rx_ringbuf.iget;
|
||||
}
|
||||
|
||||
int uart_rx_char(const machine_hard_uart_obj_t * self) {
|
||||
uint8_t ch;
|
||||
nrfx_uart_rx(self->p_uart, &ch, 1);
|
||||
return (int)ch;
|
||||
return ringbuf_get((ringbuf_t*)&self->buf->rx_ringbuf);
|
||||
}
|
||||
|
||||
STATIC nrfx_err_t uart_tx_char(const machine_hard_uart_obj_t * self, int c) {
|
||||
while (nrfx_uart_tx_in_progress(self->p_uart)) {
|
||||
;
|
||||
}
|
||||
|
||||
return nrfx_uart_tx(self->p_uart, (uint8_t *)&c, 1);
|
||||
self->buf->tx_buf[0] = c;
|
||||
return nrfx_uart_tx(self->p_uart, &self->buf->tx_buf[0], 1);
|
||||
}
|
||||
|
||||
|
||||
@ -181,9 +202,15 @@ STATIC mp_obj_t machine_hard_uart_make_new(const mp_obj_type_t *type, size_t n_a
|
||||
// Set context to this instance of UART
|
||||
config.p_context = (void *)self;
|
||||
|
||||
// Set NULL as callback function to keep it blocking
|
||||
nrfx_uart_init(self->p_uart, &config, NULL);
|
||||
// Initialise ring buffer
|
||||
self->buf->rx_ringbuf.buf = self->buf->rx_ringbuf_array;
|
||||
self->buf->rx_ringbuf.size = sizeof(self->buf->rx_ringbuf_array);
|
||||
self->buf->rx_ringbuf.iget = 0;
|
||||
self->buf->rx_ringbuf.iput = 0;
|
||||
|
||||
// Enable event callback and start asynchronous receive
|
||||
nrfx_uart_init(self->p_uart, &config, uart_event_handler);
|
||||
nrfx_uart_rx(self->p_uart, &self->buf->rx_buf[0], 1);
|
||||
nrfx_uart_rx_enable(self->p_uart);
|
||||
|
||||
return MP_OBJ_FROM_PTR(self);
|
||||
@ -250,6 +277,8 @@ STATIC mp_uint_t machine_hard_uart_read(mp_obj_t self_in, void *buf_in, mp_uint_
|
||||
|
||||
// read the data
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
while (!uart_rx_any(self)) {
|
||||
}
|
||||
buf[i] = uart_rx_char(self);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user