From b32a9192df04c6fb36027b2b9b3e0e3a3548005a Mon Sep 17 00:00:00 2001 From: Dan Halbert Date: Wed, 27 Nov 2019 12:52:11 -0500 Subject: [PATCH] make UART.write be blocking on SAMD; add timeout property --- ports/atmel-samd/common-hal/busio/UART.c | 36 +++++---- ports/cxd56/common-hal/busio/UART.c | 12 ++- ports/cxd56/common-hal/busio/UART.h | 2 +- ports/nrf/common-hal/busio/UART.c | 24 +++--- ports/stm32f4/common-hal/busio/UART.c | 98 +++++++++++++----------- shared-bindings/board/__init__.c | 6 ++ shared-bindings/busio/UART.c | 46 +++++++++-- shared-bindings/busio/UART.h | 3 +- shared-module/board/__init__.c | 2 +- 9 files changed, 144 insertions(+), 85 deletions(-) diff --git a/ports/atmel-samd/common-hal/busio/UART.c b/ports/atmel-samd/common-hal/busio/UART.c index 2505e894af..d869f70ff4 100644 --- a/ports/atmel-samd/common-hal/busio/UART.c +++ b/ports/atmel-samd/common-hal/busio/UART.c @@ -323,29 +323,23 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, struct io_descriptor *io; usart_async_get_io_descriptor(usart_desc_p, &io); + // Start writing characters. This is non-blocking and will + // return immediately after setting up the write. if (io_write(io, data, len) < 0) { *errcode = MP_EAGAIN; return MP_STREAM_ERROR; } - // Wait until write is complete or timeout. - bool done = false; - uint64_t start_ticks = ticks_ms; - // Busy-wait for timeout. - while (ticks_ms - start_ticks < self->timeout_ms) { - if (usart_async_is_tx_empty(usart_desc_p)) { - done = true; + // Busy-wait until all characters transmitted. + struct usart_async_status async_status; + while (true) { + usart_async_get_status(usart_desc_p, &async_status); + if (async_status.txcnt >= len) { break; } RUN_BACKGROUND_TASKS; } - if (!done) { - *errcode = MP_EAGAIN; - return MP_STREAM_ERROR; - } - - // All the characters got written. return len; } @@ -368,6 +362,14 @@ void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrat self->baudrate = baudrate; } +mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self) { + return (mp_float_t) (self->timeout_ms / 1000.0f); +} + +void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout) { + self->timeout_ms = timeout * 1000; +} + uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { // This assignment is only here because the usart_async routines take a *const argument. struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc; @@ -383,12 +385,14 @@ void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) { } +// True if there are no characters still to be written. bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { if (self->tx_pin == NO_PIN) { return false; } // This assignment is only here because the usart_async routines take a *const argument. - const struct _usart_async_device * const usart_device_p = - (struct _usart_async_device * const) &self->usart_desc.device; - return _usart_async_is_byte_sent(usart_device_p); + struct usart_async_descriptor * const usart_desc_p = (struct usart_async_descriptor * const) &self->usart_desc; + struct usart_async_status async_status; + usart_async_get_status(usart_desc_p, &async_status); + return !(async_status.flags & USART_ASYNC_STATUS_BUSY); } diff --git a/ports/cxd56/common-hal/busio/UART.c b/ports/cxd56/common-hal/busio/UART.c index 4a1376f19a..6ae2403c13 100644 --- a/ports/cxd56/common-hal/busio/UART.c +++ b/ports/cxd56/common-hal/busio/UART.c @@ -102,7 +102,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t *self, self->tx_pin = tx; self->rx_pin = rx; self->baudrate = baudrate; - self->timeout = timeout; + self->timeout_us = timeout * 1000000; } void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { @@ -135,7 +135,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t FD_SET(busio_uart_dev[self->number].fd, &rfds); tv.tv_sec = 0; - tv.tv_usec = self->timeout * 1000; + tv.tv_usec = self->timeout_us; retval = select(busio_uart_dev[self->number].fd + 1, &rfds, NULL, NULL, &tv); @@ -172,6 +172,14 @@ void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrat ioctl(busio_uart_dev[self->number].fd, TCFLSH, (long unsigned int)NULL); } +mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self) { + return (mp_float_t) (self->timeout / 1000000.0f); +} + +void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout) { + self->timeout_us = timeout * 1000000; +} + uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { int count = 0; diff --git a/ports/cxd56/common-hal/busio/UART.h b/ports/cxd56/common-hal/busio/UART.h index e1d8161491..a69c470566 100644 --- a/ports/cxd56/common-hal/busio/UART.h +++ b/ports/cxd56/common-hal/busio/UART.h @@ -37,7 +37,7 @@ typedef struct { const mcu_pin_obj_t *tx_pin; const mcu_pin_obj_t *rx_pin; uint32_t baudrate; - uint32_t timeout; + uint32_t timeout_us; } busio_uart_obj_t; void busio_uart_reset(void); diff --git a/ports/nrf/common-hal/busio/UART.c b/ports/nrf/common-hal/busio/UART.c index 54a66ddbe7..a0ae8af00e 100644 --- a/ports/nrf/common-hal/busio/UART.c +++ b/ports/nrf/common-hal/busio/UART.c @@ -265,19 +265,6 @@ size_t common_hal_busio_uart_write (busio_uart_obj_t *self, const uint8_t *data, if ( len == 0 ) return 0; - uint64_t start_ticks = ticks_ms; - - // Wait for on-going transfer to complete - while ( nrfx_uarte_tx_in_progress(self->uarte) && (ticks_ms - start_ticks < self->timeout_ms) ) { - RUN_BACKGROUND_TASKS; - } - - // Time up - if ( !(ticks_ms - start_ticks < self->timeout_ms) ) { - *errcode = MP_EAGAIN; - return MP_STREAM_ERROR; - } - // EasyDMA can only access SRAM uint8_t * tx_buf = (uint8_t*) data; if ( !nrfx_is_in_ram(data) ) { @@ -290,7 +277,8 @@ size_t common_hal_busio_uart_write (busio_uart_obj_t *self, const uint8_t *data, _VERIFY_ERR(*errcode); (*errcode) = 0; - while ( nrfx_uarte_tx_in_progress(self->uarte) && (ticks_ms - start_ticks < self->timeout_ms) ) { + // Wait for write to complete. + while ( nrfx_uarte_tx_in_progress(self->uarte) ) { RUN_BACKGROUND_TASKS; } @@ -310,6 +298,14 @@ void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrat nrf_uarte_baudrate_set(self->uarte->p_reg, get_nrf_baud(baudrate)); } +mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self) { + return (mp_float_t) (self->timeout_ms / 1000.0f); +} + +void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout) { + self->timeout_ms = timeout * 1000; +} + uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { return ringbuf_count(&self->rbuf); } diff --git a/ports/stm32f4/common-hal/busio/UART.c b/ports/stm32f4/common-hal/busio/UART.c index c4ab237cd1..f0e0cc9eb4 100644 --- a/ports/stm32f4/common-hal/busio/UART.c +++ b/ports/stm32f4/common-hal/busio/UART.c @@ -36,7 +36,7 @@ #include "supervisor/shared/translate.h" #include "tick.h" -#include "stm32f4xx_hal.h" +#include "stm32f4xx_hal.h" #define ALL_UARTS 0xFFFF @@ -55,7 +55,7 @@ void uart_reset(void) { uart_clock_disable(ALL_UARTS); } -STATIC USART_TypeDef * assign_uart_or_throw(busio_uart_obj_t* self, bool pin_eval, +STATIC USART_TypeDef * assign_uart_or_throw(busio_uart_obj_t* self, bool pin_eval, int uart_index, bool uart_taken) { if (pin_eval) { //assign a root pointer pointer for IRQ @@ -82,7 +82,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t* self, uint8_t rx_len = sizeof(mcu_uart_rx_list)/sizeof(*mcu_uart_rx_list); bool uart_taken = false; uint8_t uart_index = 0; //origin 0 corrected - + //Can have both pins, or either if ((tx != mp_const_none) && (rx != mp_const_none)) { //normal find loop if both pins exist @@ -90,7 +90,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t* self, if (mcu_uart_tx_list[i].pin == tx) { //rx for (uint j = 0; j < rx_len; j++) { - if (mcu_uart_rx_list[j].pin == rx + if (mcu_uart_rx_list[j].pin == rx && mcu_uart_rx_list[j].uart_index == mcu_uart_tx_list[i].uart_index) { //keep looking if the UART is taken, edge case if (reserved_uart[mcu_uart_tx_list[i].uart_index - 1]) { @@ -106,7 +106,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t* self, } } uart_index = self->tx->uart_index - 1; - USARTx = assign_uart_or_throw(self, (self->tx != NULL && self->rx != NULL), + USARTx = assign_uart_or_throw(self, (self->tx != NULL && self->rx != NULL), uart_index, uart_taken); } else if (tx == mp_const_none) { //If there is no tx, run only rx @@ -123,7 +123,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t* self, } } uart_index = self->rx->uart_index - 1; - USARTx = assign_uart_or_throw(self, (self->rx != NULL), + USARTx = assign_uart_or_throw(self, (self->rx != NULL), uart_index, uart_taken); } else if (rx == mp_const_none) { //If there is no rx, run only tx @@ -140,7 +140,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t* self, } } uart_index = self->tx->uart_index - 1; - USARTx = assign_uart_or_throw(self, (self->tx != NULL), + USARTx = assign_uart_or_throw(self, (self->tx != NULL), uart_index, uart_taken); } else { //both pins cannot be empty @@ -173,7 +173,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t* self, GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; GPIO_InitStruct.Pull = GPIO_PULLUP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = self->rx->altfn_index; + GPIO_InitStruct.Alternate = self->rx->altfn_index; HAL_GPIO_Init(pin_port(rx->port), &GPIO_InitStruct); } @@ -186,7 +186,7 @@ void common_hal_busio_uart_construct(busio_uart_obj_t* self, self->handle.Init.BaudRate = baudrate; self->handle.Init.WordLength = (bits == 9) ? UART_WORDLENGTH_9B : UART_WORDLENGTH_8B; self->handle.Init.StopBits = (stop > 1) ? UART_STOPBITS_2 : UART_STOPBITS_1; - self->handle.Init.Parity = (parity == PARITY_ODD) ? UART_PARITY_ODD : + self->handle.Init.Parity = (parity == PARITY_ODD) ? UART_PARITY_ODD : (parity == PARITY_EVEN) ? UART_PARITY_EVEN : UART_PARITY_NONE; self->handle.Init.Mode = (self->tx != NULL && self->rx != NULL) ? UART_MODE_TX_RX : @@ -234,7 +234,7 @@ bool common_hal_busio_uart_deinited(busio_uart_obj_t *self) { void common_hal_busio_uart_deinit(busio_uart_obj_t *self) { if (common_hal_busio_uart_deinited(self)) return; - + reset_pin_number(self->tx->pin->port,self->tx->pin->number); reset_pin_number(self->rx->pin->port,self->rx->pin->number); self->tx = mp_const_none; @@ -279,7 +279,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t *errcode = EAGAIN; return MP_STREAM_ERROR; } - return rx_bytes; + return rx_bytes; } // Write characters. @@ -290,13 +290,15 @@ size_t common_hal_busio_uart_write(busio_uart_obj_t *self, const uint8_t *data, bool write_err = false; //write error shouldn't disable interrupts HAL_NVIC_DisableIRQ(self->irq); - if (HAL_UART_Transmit(&self->handle, (uint8_t*)data, len, self->timeout_ms) != HAL_OK) { + if (HAL_UART_Transmit(&self->handle, (uint8_t*)data, len, HAL_MAX_DELAY) != HAL_OK) { write_err = true; } HAL_UART_Receive_IT(&self->handle, &self->rx_char, 1); HAL_NVIC_EnableIRQ(self->irq); - if (write_err) mp_raise_ValueError(translate("UART write error")); + if (write_err) { + mp_raise_ValueError(translate("UART write error")); + } return len; } @@ -312,7 +314,7 @@ void HAL_UART_RxCpltCallback(UART_HandleTypeDef *handle) } ringbuf_put_n(&context->rbuf, &context->rx_char, 1); errflag = HAL_UART_Receive_IT(handle, &context->rx_char, 1); - + return; } } @@ -360,6 +362,14 @@ void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrat self->baudrate = baudrate; } +mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self) { + return (mp_float_t) (self->timeout_ms / 1000.0f); +} + +void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout) { + self->timeout_ms = timeout * 1000; +} + uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { return ringbuf_count(&self->rbuf); } @@ -414,71 +424,71 @@ STATIC void uart_clock_enable(uint16_t mask) { if (mask & (1 << 0)) { __HAL_RCC_USART1_FORCE_RESET(); __HAL_RCC_USART1_RELEASE_RESET(); - __HAL_RCC_USART1_CLK_ENABLE(); + __HAL_RCC_USART1_CLK_ENABLE(); } #endif #ifdef USART2 if (mask & (1 << 1)) { __HAL_RCC_USART2_FORCE_RESET(); __HAL_RCC_USART2_RELEASE_RESET(); - __HAL_RCC_USART2_CLK_ENABLE(); + __HAL_RCC_USART2_CLK_ENABLE(); } #endif #ifdef USART3 if (mask & (1 << 2)) { __HAL_RCC_USART3_FORCE_RESET(); __HAL_RCC_USART3_RELEASE_RESET(); - __HAL_RCC_USART3_CLK_ENABLE(); + __HAL_RCC_USART3_CLK_ENABLE(); } #endif #ifdef UART4 if (mask & (1 << 3)) { __HAL_RCC_UART4_FORCE_RESET(); __HAL_RCC_UART4_RELEASE_RESET(); - __HAL_RCC_UART4_CLK_ENABLE(); + __HAL_RCC_UART4_CLK_ENABLE(); } #endif #ifdef UART5 if (mask & (1 << 4)) { __HAL_RCC_UART5_FORCE_RESET(); __HAL_RCC_UART5_RELEASE_RESET(); - __HAL_RCC_UART5_CLK_ENABLE(); + __HAL_RCC_UART5_CLK_ENABLE(); } #endif #ifdef USART6 if (mask & (1 << 5)) { __HAL_RCC_USART6_FORCE_RESET(); __HAL_RCC_USART6_RELEASE_RESET(); - __HAL_RCC_USART6_CLK_ENABLE(); - } + __HAL_RCC_USART6_CLK_ENABLE(); + } #endif #ifdef UART7 if (mask & (1 << 6)) { __HAL_RCC_UART7_FORCE_RESET(); __HAL_RCC_UART7_RELEASE_RESET(); - __HAL_RCC_UART7_CLK_ENABLE(); - } + __HAL_RCC_UART7_CLK_ENABLE(); + } #endif #ifdef UART8 if (mask & (1 << 7)) { __HAL_RCC_UART8_FORCE_RESET(); __HAL_RCC_UART8_RELEASE_RESET(); - __HAL_RCC_UART8_CLK_ENABLE(); - } + __HAL_RCC_UART8_CLK_ENABLE(); + } #endif #ifdef UART9 if (mask & (1 << 8)) { __HAL_RCC_UART9_FORCE_RESET(); __HAL_RCC_UART9_RELEASE_RESET(); - __HAL_RCC_UART9_CLK_ENABLE(); - } + __HAL_RCC_UART9_CLK_ENABLE(); + } #endif #ifdef UART10 if (mask & (1 << 9)) { __HAL_RCC_UART10_FORCE_RESET(); __HAL_RCC_UART10_RELEASE_RESET(); - __HAL_RCC_UART10_CLK_ENABLE(); - } + __HAL_RCC_UART10_CLK_ENABLE(); + } #endif } @@ -487,71 +497,71 @@ STATIC void uart_clock_disable(uint16_t mask) { if (mask & (1 << 0)) { __HAL_RCC_USART1_FORCE_RESET(); __HAL_RCC_USART1_RELEASE_RESET(); - __HAL_RCC_USART1_CLK_DISABLE(); + __HAL_RCC_USART1_CLK_DISABLE(); } #endif #ifdef USART2 if (mask & (1 << 1)) { __HAL_RCC_USART2_FORCE_RESET(); __HAL_RCC_USART2_RELEASE_RESET(); - __HAL_RCC_USART2_CLK_DISABLE(); + __HAL_RCC_USART2_CLK_DISABLE(); } #endif #ifdef USART3 if (mask & (1 << 2)) { __HAL_RCC_USART3_FORCE_RESET(); __HAL_RCC_USART3_RELEASE_RESET(); - __HAL_RCC_USART3_CLK_DISABLE(); + __HAL_RCC_USART3_CLK_DISABLE(); } #endif #ifdef UART4 if (mask & (1 << 3)) { __HAL_RCC_UART4_FORCE_RESET(); __HAL_RCC_UART4_RELEASE_RESET(); - __HAL_RCC_UART4_CLK_DISABLE(); + __HAL_RCC_UART4_CLK_DISABLE(); } #endif #ifdef UART5 if (mask & (1 << 4)) { __HAL_RCC_UART5_FORCE_RESET(); __HAL_RCC_UART5_RELEASE_RESET(); - __HAL_RCC_UART5_CLK_DISABLE(); + __HAL_RCC_UART5_CLK_DISABLE(); } #endif #ifdef USART6 if (mask & (1 << 5)) { __HAL_RCC_USART6_FORCE_RESET(); __HAL_RCC_USART6_RELEASE_RESET(); - __HAL_RCC_USART6_CLK_DISABLE(); - } + __HAL_RCC_USART6_CLK_DISABLE(); + } #endif #ifdef UART7 if (mask & (1 << 6)) { __HAL_RCC_UART7_FORCE_RESET(); __HAL_RCC_UART7_RELEASE_RESET(); - __HAL_RCC_UART7_CLK_DISABLE(); - } + __HAL_RCC_UART7_CLK_DISABLE(); + } #endif #ifdef UART8 if (mask & (1 << 7)) { __HAL_RCC_UART8_FORCE_RESET(); __HAL_RCC_UART8_RELEASE_RESET(); - __HAL_RCC_UART8_CLK_DISABLE(); - } + __HAL_RCC_UART8_CLK_DISABLE(); + } #endif #ifdef UART9 if (mask & (1 << 8)) { __HAL_RCC_UART9_FORCE_RESET(); __HAL_RCC_UART9_RELEASE_RESET(); - __HAL_RCC_UART9_CLK_DISABLE(); - } + __HAL_RCC_UART9_CLK_DISABLE(); + } #endif #ifdef UART10 if (mask & (1 << 9)) { __HAL_RCC_UART10_FORCE_RESET(); __HAL_RCC_UART10_RELEASE_RESET(); - __HAL_RCC_UART10_CLK_DISABLE(); - } + __HAL_RCC_UART10_CLK_DISABLE(); + } #endif } diff --git a/shared-bindings/board/__init__.c b/shared-bindings/board/__init__.c index 47e2d64bc8..3dda59fb8e 100644 --- a/shared-bindings/board/__init__.c +++ b/shared-bindings/board/__init__.c @@ -93,6 +93,12 @@ MP_DEFINE_CONST_FUN_OBJ_0(board_spi_obj, board_spi); //| //| Returns the `busio.UART` object for the board designated TX and RX pins. It is a singleton. //| +//| The object created uses the default parameter values for `busio.UART`. If you need to set +//| parameters that are not changeable after creation, such as ``receiver_buffer_size``, +//| do not use `board.UART()`; instead create a `busio.UART` object explicitly with the +//| desired parameters. +//| +//| #if BOARD_UART mp_obj_t board_uart(void) { mp_obj_t singleton = common_hal_board_get_uart(); diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c index c7eef8c438..9606c77e9e 100644 --- a/shared-bindings/busio/UART.c +++ b/shared-bindings/busio/UART.c @@ -57,7 +57,7 @@ //| :param int bits: the number of bits per byte, 7, 8 or 9. //| :param Parity parity: the parity used for error checking. //| :param int stop: the number of stop bits, 1 or 2. -//| :param float timeout: the timeout in seconds to wait for the first character and between subsequent characters. Raises ``ValueError`` if timeout >100 seconds. +//| :param float timeout: the timeout in seconds to wait for the first character and between subsequent characters when reading. Raises ``ValueError`` if timeout >100 seconds. //| :param int receiver_buffer_size: the character length of the read buffer (0 to disable). (When a character is 9 bits the buffer will be 2 * receiver_buffer_size bytes.) //| //| *New in CircuitPython 4.0:* ``timeout`` has incompatibly changed units from milliseconds to seconds. @@ -69,6 +69,12 @@ typedef struct { extern const busio_uart_parity_obj_t busio_uart_parity_even_obj; extern const busio_uart_parity_obj_t busio_uart_parity_odd_obj; +STATIC void validate_timeout(mp_float_t timeout) { + if (timeout < (mp_float_t) 0.0f || timeout > (mp_float_t) 100.0f) { + mp_raise_ValueError(translate("timeout must be 0.0-100.0 (units are now seconds, not msecs)")); + } +} + STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { // Always initially allocate the UART object within the long-lived heap. // This is needed to avoid crashes with certain UART implementations which @@ -116,9 +122,7 @@ STATIC mp_obj_t busio_uart_make_new(const mp_obj_type_t *type, size_t n_args, co } mp_float_t timeout = mp_obj_get_float(args[ARG_timeout].u_obj); - if (timeout > (mp_float_t)100.0) { - mp_raise_ValueError(translate("timeout >100 (units are now seconds, not msecs)")); - } + validate_timeout(timeout); common_hal_busio_uart_construct(self, tx, rx, args[ARG_baudrate].u_int, bits, parity, stop, timeout, @@ -286,6 +290,35 @@ const mp_obj_property_t busio_uart_in_waiting_obj = { (mp_obj_t)&mp_const_none_obj}, }; +//| .. attribute:: timeout +//| +//| The current timeout, in seconds (float). +//| +STATIC mp_obj_t busio_uart_obj_get_timeout(mp_obj_t self_in) { + busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + return mp_obj_new_float(common_hal_busio_uart_get_timeout(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_get_timeout_obj, busio_uart_obj_get_timeout); + +STATIC mp_obj_t busio_uart_obj_set_timeout(mp_obj_t self_in, mp_obj_t timeout) { + busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + check_for_deinit(self); + mp_float_t timeout_float = mp_obj_get_float(timeout); + validate_timeout(timeout_float); + common_hal_busio_uart_set_timeout(self, timeout_float); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_2(busio_uart_set_timeout_obj, busio_uart_obj_set_timeout); + + +const mp_obj_property_t busio_uart_timeout_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&busio_uart_get_timeout_obj, + (mp_obj_t)&busio_uart_set_timeout_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + //| .. method:: reset_input_buffer() //| //| Discard any unread characters in the input buffer. @@ -355,8 +388,9 @@ STATIC const mp_rom_map_elem_t busio_uart_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_reset_input_buffer), MP_ROM_PTR(&busio_uart_reset_input_buffer_obj) }, // Properties - { MP_ROM_QSTR(MP_QSTR_baudrate), MP_ROM_PTR(&busio_uart_baudrate_obj) }, - { MP_ROM_QSTR(MP_QSTR_in_waiting), MP_ROM_PTR(&busio_uart_in_waiting_obj) }, + { MP_ROM_QSTR(MP_QSTR_baudrate), MP_ROM_PTR(&busio_uart_baudrate_obj) }, + { MP_ROM_QSTR(MP_QSTR_in_waiting), MP_ROM_PTR(&busio_uart_in_waiting_obj) }, + { MP_ROM_QSTR(MP_QSTR_timeout), MP_ROM_PTR(&busio_uart_timeout_obj) }, // Nested Enum-like Classes. { MP_ROM_QSTR(MP_QSTR_Parity), MP_ROM_PTR(&busio_uart_parity_type) }, diff --git a/shared-bindings/busio/UART.h b/shared-bindings/busio/UART.h index 776a996be8..cfd2c800c3 100644 --- a/shared-bindings/busio/UART.h +++ b/shared-bindings/busio/UART.h @@ -57,7 +57,8 @@ extern size_t common_hal_busio_uart_write(busio_uart_obj_t *self, extern uint32_t common_hal_busio_uart_get_baudrate(busio_uart_obj_t *self); extern void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrate); - +extern mp_float_t common_hal_busio_uart_get_timeout(busio_uart_obj_t *self); +extern void common_hal_busio_uart_set_timeout(busio_uart_obj_t *self, mp_float_t timeout); extern uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self); extern void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self); diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index dd07d7190c..914bc43137 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -101,7 +101,7 @@ mp_obj_t common_hal_board_create_uart(void) { const mcu_pin_obj_t* rx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RX); const mcu_pin_obj_t* tx = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_TX); - common_hal_busio_uart_construct(self, tx, rx, 9600, 8, PARITY_NONE, 1, 1000, 64); + common_hal_busio_uart_construct(self, tx, rx, 9600, 8, PARITY_NONE, 1, 1.0f, 64); MP_STATE_VM(shared_uart_bus) = MP_OBJ_FROM_PTR(self); return MP_STATE_VM(shared_uart_bus); }