summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrobert-hh <robert@hammelrath.com>2022-08-26 12:47:34 +0200
committerDamien George <damien@micropython.org>2022-08-31 00:17:54 +1000
commit2488311dc2f5ef259a03b871620fd6d3f45a1086 (patch)
tree3193d12b7d8b5ba9464aef3d89fa1e3cf6516c4a
parent53ebbf10e56dd4cc33aec6cc6d0590c66fd1948e (diff)
rp2/machine_uart: Implement uart.flush() and uart.txdone().
uart.flush() flush() will wait until all characters have been sent. It may return while the last character is sent. if needed, the calling code has to add one character wait time. To avoid a permanent lock, a timeout applies depending on the size of txbuf and the baud rate. ret = uart.txdone() ret is True if no transfer is in progress. It may return True if the last byte of a transfer is sent. ret is False otherwise.
-rw-r--r--ports/rp2/machine_uart.c27
1 files changed, 27 insertions, 0 deletions
diff --git a/ports/rp2/machine_uart.c b/ports/rp2/machine_uart.c
index 77ccdb5f5..f7e44b6b2 100644
--- a/ports/rp2/machine_uart.c
+++ b/ports/rp2/machine_uart.c
@@ -435,17 +435,31 @@ STATIC mp_obj_t machine_uart_sendbreak(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_sendbreak_obj, machine_uart_sendbreak);
+STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) {
+ machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
+
+ if (ringbuf_avail(&self->write_buffer) == 0 &&
+ uart_get_hw(self->uart)->fr & UART_UARTFR_TXFE_BITS) {
+ return mp_const_true;
+ } else {
+ return mp_const_false;
+ }
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone);
+
STATIC const mp_rom_map_elem_t machine_uart_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&machine_uart_init_obj) },
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&machine_uart_deinit_obj) },
{ MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&machine_uart_any_obj) },
+ { MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) },
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
{ MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
{ MP_ROM_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) },
{ MP_ROM_QSTR(MP_QSTR_sendbreak), MP_ROM_PTR(&machine_uart_sendbreak_obj) },
+ { MP_ROM_QSTR(MP_QSTR_txdone), MP_ROM_PTR(&machine_uart_txdone_obj) },
{ MP_ROM_QSTR(MP_QSTR_INV_TX), MP_ROM_INT(UART_INVERT_TX) },
{ MP_ROM_QSTR(MP_QSTR_INV_RX), MP_ROM_INT(UART_INVERT_RX) },
@@ -538,6 +552,19 @@ STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint
if ((flags & MP_STREAM_POLL_WR) && ringbuf_free(&self->write_buffer) > 0) {
ret |= MP_STREAM_POLL_WR;
}
+ } else if (request == MP_STREAM_FLUSH) {
+ // The timeout is estimated using the buffer size and the baudrate.
+ // Take the worst case assumptions at 13 bit symbol size times 2.
+ uint64_t timeout = time_us_64() +
+ (uint64_t)(33 + self->write_buffer.size) * 13000000ll * 2 / self->baudrate;
+ do {
+ if (machine_uart_txdone((mp_obj_t)self) == mp_const_true) {
+ return 0;
+ }
+ MICROPY_EVENT_POLL_HOOK
+ } while (time_us_64() < timeout);
+ *errcode = MP_ETIMEDOUT;
+ ret = MP_STREAM_ERROR;
} else {
*errcode = MP_EINVAL;
ret = MP_STREAM_ERROR;