Skip to content

Commit 8804993

Browse files
robert-hhdpgeorge
authored andcommitted
esp8266/machine_uart: Implement uart.flush() and uart.txdone().
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.
1 parent 49e17c8 commit 8804993

File tree

3 files changed

+34
-0
lines changed

3 files changed

+34
-0
lines changed

ports/esp8266/machine_uart.c

+24
Original file line numberDiff line numberDiff line change
@@ -231,10 +231,20 @@ STATIC mp_obj_t pyb_uart_any(mp_obj_t self_in) {
231231
}
232232
STATIC MP_DEFINE_CONST_FUN_OBJ_1(pyb_uart_any_obj, pyb_uart_any);
233233

234+
STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) {
235+
pyb_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
236+
237+
return uart_txdone(self->uart_id) == true ? mp_const_true : mp_const_false;
238+
}
239+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone);
240+
234241
STATIC const mp_rom_map_elem_t pyb_uart_locals_dict_table[] = {
235242
{ MP_ROM_QSTR(MP_QSTR_init), MP_ROM_PTR(&pyb_uart_init_obj) },
236243

237244
{ MP_ROM_QSTR(MP_QSTR_any), MP_ROM_PTR(&pyb_uart_any_obj) },
245+
{ MP_ROM_QSTR(MP_QSTR_txdone), MP_ROM_PTR(&machine_uart_txdone_obj) },
246+
247+
{ MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) },
238248
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
239249
{ MP_ROM_QSTR(MP_QSTR_readline), MP_ROM_PTR(&mp_stream_unbuffered_readline_obj) },
240250
{ MP_ROM_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) },
@@ -305,6 +315,20 @@ STATIC mp_uint_t pyb_uart_ioctl(mp_obj_t self_in, mp_uint_t request, mp_uint_t a
305315
if ((flags & MP_STREAM_POLL_WR) && uart_tx_any_room(self->uart_id)) {
306316
ret |= MP_STREAM_POLL_WR;
307317
}
318+
} else if (request == MP_STREAM_FLUSH) {
319+
// The timeout is estimated using the buffer size and the baudrate.
320+
// Take the worst case assumptions at 13 bit symbol size times 2.
321+
uint64_t timeout = (uint64_t)(3 + 127) * 13000000ll * 2 / self->baudrate
322+
+ system_get_time();
323+
do {
324+
if (machine_uart_txdone((mp_obj_t)self) == mp_const_true) {
325+
return 0;
326+
}
327+
MICROPY_EVENT_POLL_HOOK
328+
} while (system_get_time() < timeout);
329+
330+
*errcode = MP_ETIMEDOUT;
331+
ret = MP_STREAM_ERROR;
308332
} else {
309333
*errcode = MP_EINVAL;
310334
ret = MP_STREAM_ERROR;

ports/esp8266/uart.c

+9
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,15 @@ void uart_tx_one_char(uint8 uart, uint8 TxChar) {
111111
WRITE_PERI_REG(UART_FIFO(uart), TxChar);
112112
}
113113

114+
int uart_txdone(uint8 uart) {
115+
uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S);
116+
if ((fifo_cnt >> UART_TXFIFO_CNT_S & UART_TXFIFO_CNT) == 0) {
117+
return true;
118+
} else {
119+
return false;
120+
}
121+
}
122+
114123
void uart_flush(uint8 uart) {
115124
while (true) {
116125
uint32 fifo_cnt = READ_PERI_REG(UART_STATUS(uart)) & (UART_TXFIFO_CNT << UART_TXFIFO_CNT_S);

ports/esp8266/uart.h

+1
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ bool uart_rx_wait(uint32_t timeout_us);
101101
int uart_rx_char(void);
102102
void uart_tx_one_char(uint8 uart, uint8 TxChar);
103103
void uart_flush(uint8 uart);
104+
int uart_txdone(uint8 uart);
104105
void uart_os_config(int uart);
105106
void uart_setup(uint8 uart);
106107
int uart0_get_rxbuf_len(void);

0 commit comments

Comments
 (0)