Skip to content

Commit

Permalink
renesas-ra: Add the UART methods uart.txdone() and uart.flush().
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
robert-hh committed Dec 15, 2022
1 parent 9e91764 commit 988b6e2
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 2 deletions.
4 changes: 2 additions & 2 deletions docs/library/machine.UART.rst
Expand Up @@ -188,7 +188,7 @@ Methods
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.

Availability: rp2, esp32, esp8266, mimxrt, cc3200, stm32, nrf ports
Availability: rp2, esp32, esp8266, mimxrt, cc3200, stm32, nrf ports, renesas-ra

.. method:: UART.txdone()

Expand All @@ -201,7 +201,7 @@ Methods
of a transfer is still being sent. 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

Constants
---------
Expand Down
23 changes: 23 additions & 0 deletions ports/renesas-ra/machine_uart.c
Expand Up @@ -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);

// \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)
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];
Expand Down Expand Up @@ -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_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_txdone), MP_ROM_PTR(&machine_uart_txdone_obj) },
{ MP_ROM_QSTR(MP_QSTR_flush), MP_ROM_PTR(&mp_stream_flush_obj) },

/// \method read([nbytes])
{ MP_ROM_QSTR(MP_QSTR_read), MP_ROM_PTR(&mp_stream_read_obj) },
Expand Down Expand Up @@ -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)) {
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 {
*errcode = MP_EINVAL;
ret = MP_STREAM_ERROR;
Expand Down
10 changes: 10 additions & 0 deletions ports/renesas-ra/ra/ra_sci.c
Expand Up @@ -1026,6 +1026,16 @@ int ra_sci_tx_wait(uint32_t ch) {
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) {
uint32_t idx = ch_to_idx[ch];
R_SCI0_Type *sci_reg = sci_regs[idx];
Expand Down
2 changes: 2 additions & 0 deletions ports/renesas-ra/ra/ra_sci.h
Expand Up @@ -52,6 +52,8 @@ bool ra_sci_is_rxirq_enable(uint32_t ch);
void ra_sci_isr_te(uint32_t ch);
int ra_sci_rx_ch(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);
int ra_sci_tx_wait(uint32_t ch);
void ra_sci_tx_break(uint32_t ch);
Expand Down
10 changes: 10 additions & 0 deletions ports/renesas-ra/uart.c
Expand Up @@ -420,6 +420,16 @@ mp_uint_t uart_tx_avail(machine_uart_obj_t *self) {
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
// reading (from buf or for direct reading).
// Returns true if something available, false if not.
Expand Down
2 changes: 2 additions & 0 deletions ports/renesas-ra/uart.h
Expand Up @@ -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);
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_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);
int uart_rx_char(machine_uart_obj_t *uart_obj);
bool uart_tx_wait(machine_uart_obj_t *self, uint32_t timeout);
Expand Down

0 comments on commit 988b6e2

Please sign in to comment.