Skip to content

Commit

Permalink
esp8266/machine_uart: Implement uart.flush() and uart.txdone().
Browse files Browse the repository at this point in the history
uart.flush()

flush() will wait until all characters but the last one have been sent.
It returns 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 the FIFO and the baud rate.

ret = uart.txdone()

ret is True if no transfer is in progress. It returns already True when
the last byte of a transfer is sent.
ret is False otherwise.
  • Loading branch information
robert-hh authored and dpgeorge committed Aug 30, 2022
1 parent 49e17c8 commit 8804993
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 0 deletions.
24 changes: 24 additions & 0 deletions ports/esp8266/machine_uart.c
Expand Up @@ -231,10 +231,20 @@ STATIC mp_obj_t pyb_uart_any(mp_obj_t self_in) {
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_any_obj, pyb_uart_any);

STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) {
pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);

return uart_txdone(self->uart_id) == true ? mp_const_true : mp_const_false;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone);

STATIC const mp_rom_map_elem_t pyb_uart_locals_dict_table[] = {
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_uart_init_obj) },

{ MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&pyb_uart_any_obj) },
{ MP_ROM_QSTR(MP_QSTR_txdone), MP_ROM_PTR(&machine_uart_txdone_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) },
Expand Down Expand Up @@ -305,6 +315,20 @@ STATIC mp_uint_t pyb_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t a
if ((flags & MP_STREAM_POLL_WR) && uart_tx_any_room(self->uart_id)) {
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 = (uint64_t)(3 + 127) * 13000000ll * 2 / self->baudrate
+ system_get_time();
do {
if (machine_uart_txdone((mp_obj_t)self) == mp_const_true) {
return 0;
}
MICROPY_EVENT_POLL_HOOK
} while (system_get_time() < timeout);

*errcode = MP_ETIMEDOUT;
ret = MP_STREAM_ERROR;
} else {
*errcode = MP_EINVAL;
ret = MP_STREAM_ERROR;
Expand Down
9 changes: 9 additions & 0 deletions ports/esp8266/uart.c
Expand Up @@ -111,6 +111,15 @@ void uart_tx_one_char(uint8 uart, uint8 TxChar) {
WRITE_PERI_REG(UART_FIFO(uart), TxChar);
}

int uart_txdone(uint8 uart) {
uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S);
if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) == 0) {
return true;
} else {
return false;
}
}

void uart_flush(uint8 uart) {
while (true) {
uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S);
Expand Down
1 change: 1 addition & 0 deletions ports/esp8266/uart.h
Expand Up @@ -101,6 +101,7 @@ bool uart_rx_wait(uint32_t timeout_us);
int uart_rx_char(void);
void uart_tx_one_char(uint8 uart, uint8 TxChar);
void uart_flush(uint8 uart);
int uart_txdone(uint8 uart);
void uart_os_config(int uart);
void uart_setup(uint8 uart);
int uart0_get_rxbuf_len(void);
Expand Down

0 comments on commit 8804993

Please sign in to comment.