renesas-ra: Add the UART methods uart.txdone() and uart.flush().

This required to add two functions down the stack to uart.c and ra.sci.c.

- One for telling, whther the transmission is busy.
- One for reporting the size of the TX buffer.

Tested with a EK-RA6M2 board.
This commit is contained in:
robert-hh 2022-09-27 20:40:05 +02:00
parent 9e91764671
commit 988b6e2dae
6 changed files with 49 additions and 2 deletions

View File

@ -188,7 +188,7 @@ Methods
For the rp2, esp8266 and nrf ports the call returns while the last byte is sent. For the rp2, esp8266 and nrf ports the call returns while the last byte is sent.
If required, a one character wait time has to be added in the calling script. If required, a one character wait time has to be added in the calling script.
Availability: rp2, esp32, esp8266, mimxrt, cc3200, stm32, nrf ports Availability: rp2, esp32, esp8266, mimxrt, cc3200, stm32, nrf ports, renesas-ra
.. method:: UART.txdone() .. method:: UART.txdone()
@ -201,7 +201,7 @@ Methods
of a transfer is still being sent. If required, a one character wait time has to be of a transfer is still being sent. If required, a one character wait time has to be
added in the calling script. added in the calling script.
Availability: rp2, esp32, esp8266, mimxrt, cc3200, stm32, nrf ports Availability: rp2, esp32, esp8266, mimxrt, cc3200, stm32, nrf ports, renesas-ra
Constants Constants
--------- ---------

View File

@ -409,6 +409,14 @@ 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_DEFINE_CONST_FUN_OBJ_1(machine_uart_sendbreak_obj, machine_uart_sendbreak);
// \method uart.txdone()
// Return `True` if all characters have been sent.
STATIC mp_obj_t machine_uart_txdone(mp_obj_t self_in) {
machine_uart_obj_t *self = MP_OBJ_TO_PTR(self_in);
return uart_tx_busy(self) ? mp_const_false : mp_const_true;
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(machine_uart_txdone_obj, machine_uart_txdone);
// irq(handler, trigger, hard) // irq(handler, trigger, hard)
STATIC mp_obj_t machine_uart_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { STATIC mp_obj_t machine_uart_irq(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
mp_arg_val_t args[MP_IRQ_ARG_INIT_NUM_ARGS]; mp_arg_val_t args[MP_IRQ_ARG_INIT_NUM_ARGS];
@ -452,6 +460,8 @@ 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_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_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_any), MP_ROM_PTR(&machine_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) },
/// \method read([nbytes]) /// \method read([nbytes])
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) }, { MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
@ -557,6 +567,19 @@ STATIC mp_uint_t machine_uart_ioctl(mp_obj_t self_in, mp_uint_t request, uintptr
if ((flags & MP_STREAM_POLL_WR) && uart_tx_avail(self)) { if ((flags & MP_STREAM_POLL_WR) && uart_tx_avail(self)) {
ret |= MP_STREAM_POLL_WR; 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.
uint32_t timeout = mp_hal_ticks_ms() +
(uint32_t)(uart_tx_txbuf(self)) * 13000ll * 2 / self->baudrate;
do {
if (!uart_tx_busy(self)) {
return 0;
}
MICROPY_EVENT_POLL_HOOK
} while (mp_hal_ticks_ms() < timeout);
*errcode = MP_ETIMEDOUT;
ret = MP_STREAM_ERROR;
} else { } else {
*errcode = MP_EINVAL; *errcode = MP_EINVAL;
ret = MP_STREAM_ERROR; ret = MP_STREAM_ERROR;

View File

@ -1026,6 +1026,16 @@ int ra_sci_tx_wait(uint32_t ch) {
return (int)(tx_fifo[idx].len != (tx_fifo[idx].size - 1)); return (int)(tx_fifo[idx].len != (tx_fifo[idx].size - 1));
} }
int ra_sci_tx_busy(uint32_t ch) {
uint32_t idx = ch_to_idx[ch];
return (int)(tx_fifo[idx].busy);
}
int ra_sci_tx_bufsize(uint32_t ch) {
uint32_t idx = ch_to_idx[ch];
return (int)(tx_fifo[idx].size - 1);
}
void ra_sci_tx_break(uint32_t ch) { void ra_sci_tx_break(uint32_t ch) {
uint32_t idx = ch_to_idx[ch]; uint32_t idx = ch_to_idx[ch];
R_SCI0_Type *sci_reg = sci_regs[idx]; R_SCI0_Type *sci_reg = sci_regs[idx];

View File

@ -52,6 +52,8 @@ bool ra_sci_is_rxirq_enable(uint32_t ch);
void ra_sci_isr_te(uint32_t ch); void ra_sci_isr_te(uint32_t ch);
int ra_sci_rx_ch(uint32_t ch); int ra_sci_rx_ch(uint32_t ch);
int ra_sci_rx_any(uint32_t ch); int ra_sci_rx_any(uint32_t ch);
int ra_sci_tx_busy(uint32_t ch);
int ra_sci_tx_bufsize(uint32_t ch);
void ra_sci_tx_ch(uint32_t ch, int c); void ra_sci_tx_ch(uint32_t ch, int c);
int ra_sci_tx_wait(uint32_t ch); int ra_sci_tx_wait(uint32_t ch);
void ra_sci_tx_break(uint32_t ch); void ra_sci_tx_break(uint32_t ch);

View File

@ -420,6 +420,16 @@ mp_uint_t uart_tx_avail(machine_uart_obj_t *self) {
return ra_sci_tx_wait(ch); return ra_sci_tx_wait(ch);
} }
mp_uint_t uart_tx_busy(machine_uart_obj_t *self) {
int ch = (int)self->uart_id;
return ra_sci_tx_busy(ch);
}
mp_uint_t uart_tx_txbuf(machine_uart_obj_t *self) {
int ch = (int)self->uart_id;
return ra_sci_tx_bufsize(ch);
}
// Waits at most timeout milliseconds for at least 1 char to become ready for // Waits at most timeout milliseconds for at least 1 char to become ready for
// reading (from buf or for direct reading). // reading (from buf or for direct reading).
// Returns true if something available, false if not. // Returns true if something available, false if not.

View File

@ -106,6 +106,8 @@ void uart_attach_to_repl(machine_uart_obj_t *self, bool attached);
uint32_t uart_get_baudrate(machine_uart_obj_t *self); uint32_t uart_get_baudrate(machine_uart_obj_t *self);
mp_uint_t uart_rx_any(machine_uart_obj_t *uart_obj); mp_uint_t uart_rx_any(machine_uart_obj_t *uart_obj);
mp_uint_t uart_tx_avail(machine_uart_obj_t *uart_obj); mp_uint_t uart_tx_avail(machine_uart_obj_t *uart_obj);
mp_uint_t uart_tx_busy(machine_uart_obj_t *uart_obj);
mp_uint_t uart_tx_txbuf(machine_uart_obj_t *self);
bool uart_rx_wait(machine_uart_obj_t *self, uint32_t timeout); bool uart_rx_wait(machine_uart_obj_t *self, uint32_t timeout);
int uart_rx_char(machine_uart_obj_t *uart_obj); int uart_rx_char(machine_uart_obj_t *uart_obj);
bool uart_tx_wait(machine_uart_obj_t *self, uint32_t timeout); bool uart_tx_wait(machine_uart_obj_t *self, uint32_t timeout);