diff --git a/ports/atmel-samd/Makefile b/ports/atmel-samd/Makefile index 62f058c3d7..865210e2f5 100644 --- a/ports/atmel-samd/Makefile +++ b/ports/atmel-samd/Makefile @@ -115,7 +115,7 @@ else # -finline-limit=80 or so is similar to not having it on. # There is no simple default value, though. ifdef INTERNAL_FLASH_FILESYSTEM - CFLAGS += -finline-limit=55 + CFLAGS += -finline-limit=50 endif ifdef CFLAGS_INLINE_LIMIT CFLAGS += -finline-limit=$(CFLAGS_INLINE_LIMIT) diff --git a/ports/atmel-samd/board_busses.c b/ports/atmel-samd/board_busses.c index 4bf1a40faf..6a4c4a84d6 100644 --- a/ports/atmel-samd/board_busses.c +++ b/ports/atmel-samd/board_busses.c @@ -33,81 +33,96 @@ #include "samd/pins.h" #include "py/runtime.h" -#if !defined(DEFAULT_I2C_BUS_SDA) || !defined(DEFAULT_I2C_BUS_SCL) - STATIC mp_obj_t board_i2c(void) { - mp_raise_NotImplementedError("No default I2C bus"); - return NULL; +#define BOARD_I2C (defined(DEFAULT_I2C_BUS_SDA) && defined(DEFAULT_I2C_BUS_SCL)) +#define BOARD_SPI (defined(DEFAULT_SPI_BUS_SCK) && defined(DEFAULT_SPI_BUS_MISO) && defined(DEFAULT_SPI_BUS_MOSI)) +#define BOARD_UART (defined(DEFAULT_UART_BUS_RX) && defined(DEFAULT_UART_BUS_TX)) + +#if BOARD_I2C +STATIC mp_obj_t i2c_singleton = NULL; + +STATIC mp_obj_t board_i2c(void) { + + if (i2c_singleton == NULL) { + busio_i2c_obj_t *self = m_new_obj(busio_i2c_obj_t); + self->base.type = &busio_i2c_type; + + assert_pin_free(DEFAULT_I2C_BUS_SDA); + assert_pin_free(DEFAULT_I2C_BUS_SCL); + common_hal_busio_i2c_construct(self, DEFAULT_I2C_BUS_SCL, DEFAULT_I2C_BUS_SDA, 400000, 0); + i2c_singleton = (mp_obj_t)self; } + return i2c_singleton; +} #else - STATIC mp_obj_t i2c_singleton = NULL; - - STATIC mp_obj_t board_i2c(void) { - - if (i2c_singleton == NULL) { - busio_i2c_obj_t *self = m_new_obj(busio_i2c_obj_t); - self->base.type = &busio_i2c_type; - - assert_pin_free(DEFAULT_I2C_BUS_SDA); - assert_pin_free(DEFAULT_I2C_BUS_SCL); - common_hal_busio_i2c_construct(self, DEFAULT_I2C_BUS_SCL, DEFAULT_I2C_BUS_SDA, 400000, 0); - i2c_singleton = (mp_obj_t)self; - } - return i2c_singleton; - - } +STATIC mp_obj_t board_i2c(void) { + mp_raise_NotImplementedError("No default I2C bus"); + return NULL; +} #endif MP_DEFINE_CONST_FUN_OBJ_0(board_i2c_obj, board_i2c); -#if !defined(DEFAULT_SPI_BUS_SCK) || !defined(DEFAULT_SPI_BUS_MISO) || !defined(DEFAULT_SPI_BUS_MOSI) - STATIC mp_obj_t board_spi(void) { - mp_raise_NotImplementedError("No default SPI bus"); - return NULL; +#if BOARD_SPI +STATIC mp_obj_t spi_singleton = NULL; + +STATIC mp_obj_t board_spi(void) { + if (spi_singleton == NULL) { + busio_spi_obj_t *self = m_new_obj(busio_spi_obj_t); + self->base.type = &busio_spi_type; + assert_pin_free(DEFAULT_SPI_BUS_SCK); + assert_pin_free(DEFAULT_SPI_BUS_MOSI); + assert_pin_free(DEFAULT_SPI_BUS_MISO); + const mcu_pin_obj_t* clock = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_SCK); + const mcu_pin_obj_t* mosi = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MOSI); + const mcu_pin_obj_t* miso = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MISO); + common_hal_busio_spi_construct(self, clock, mosi, miso); + spi_singleton = (mp_obj_t)self; } + return spi_singleton; +} #else - STATIC mp_obj_t spi_singleton = NULL; - - STATIC mp_obj_t board_spi(void) { - - if (spi_singleton == NULL) { - busio_spi_obj_t *self = m_new_obj(busio_spi_obj_t); - self->base.type = &busio_spi_type; - assert_pin_free(DEFAULT_SPI_BUS_SCK); - assert_pin_free(DEFAULT_SPI_BUS_MOSI); - assert_pin_free(DEFAULT_SPI_BUS_MISO); - const mcu_pin_obj_t* clock = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_SCK); - const mcu_pin_obj_t* mosi = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MOSI); - const mcu_pin_obj_t* miso = MP_OBJ_TO_PTR(DEFAULT_SPI_BUS_MISO); - common_hal_busio_spi_construct(self, clock, mosi, miso); - spi_singleton = (mp_obj_t)self; - } - return spi_singleton; - } +STATIC mp_obj_t board_spi(void) { + mp_raise_NotImplementedError("No default SPI bus"); + return NULL; +} #endif MP_DEFINE_CONST_FUN_OBJ_0(board_spi_obj, board_spi); -#if !defined(DEFAULT_UART_BUS_RX) || !defined(DEFAULT_UART_BUS_TX) - STATIC mp_obj_t board_uart(void) { - mp_raise_NotImplementedError("No default UART bus"); - return NULL; +#if BOARD_UART +STATIC mp_obj_t uart_singleton = NULL; + +STATIC mp_obj_t board_uart(void) { + if (uart_singleton == NULL) { + busio_uart_obj_t *self = m_new_obj(busio_uart_obj_t); + self->base.type = &busio_uart_type; + + assert_pin_free(DEFAULT_UART_BUS_RX); + assert_pin_free(DEFAULT_UART_BUS_TX); + + 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); + uart_singleton = (mp_obj_t)self; } + return uart_singleton; +} #else - STATIC mp_obj_t uart_singleton = NULL; - - STATIC mp_obj_t board_uart(void) { - if (uart_singleton == NULL) { - busio_uart_obj_t *self = m_new_obj(busio_uart_obj_t); - self->base.type = &busio_uart_type; - - assert_pin_free(DEFAULT_UART_BUS_RX); - assert_pin_free(DEFAULT_UART_BUS_TX); - - 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); - uart_singleton = (mp_obj_t)self; - } - return uart_singleton; - } +STATIC mp_obj_t board_uart(void) { + mp_raise_NotImplementedError("No default UART bus"); + return NULL; +} #endif MP_DEFINE_CONST_FUN_OBJ_0(board_uart_obj, board_uart); + + +void reset_board_busses(void) { +#if BOARD_I2C + i2c_singleton = NULL; +#endif +#if BOARD_SPI + spi_singleton = NULL; +#endif +#if BOARD_UART + uart_singleton = NULL; +#endif +} diff --git a/ports/atmel-samd/board_busses.h b/ports/atmel-samd/board_busses.h index a368885a58..08dd1aae12 100644 --- a/ports/atmel-samd/board_busses.h +++ b/ports/atmel-samd/board_busses.h @@ -36,4 +36,6 @@ extern mp_obj_fun_builtin_fixed_t board_spi_obj; void board_uart(void); extern mp_obj_fun_builtin_fixed_t board_uart_obj; +void reset_board_busses(void); + #endif // MICROPY_INCLUDED_ATMEL_SAMD_BOARD_BUSSES_H diff --git a/ports/atmel-samd/common-hal/busio/UART.c b/ports/atmel-samd/common-hal/busio/UART.c index fbed1d506b..b8b0ce74ca 100644 --- a/ports/atmel-samd/common-hal/busio/UART.c +++ b/ports/atmel-samd/common-hal/busio/UART.c @@ -273,7 +273,7 @@ size_t common_hal_busio_uart_read(busio_uart_obj_t *self, uint8_t *data, size_t #ifdef MICROPY_VM_HOOK_LOOP MICROPY_VM_HOOK_LOOP #endif - // If we are zero timeout, make sure we don't loop again (in the event + // If we are zero timeout, make sure we don't loop again (in the event // we read in under 1ms) if (self->timeout_ms == 0) break; @@ -349,7 +349,18 @@ void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t baudrat } uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { - return self->buffer_size; + // 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; + struct usart_async_status async_status; + usart_async_get_status(usart_desc_p, &async_status); + return async_status.rxcnt; +} + +void common_hal_busio_uart_clear_rx_buffer(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; + usart_async_flush_rx_buffer(usart_desc_p); + } bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { diff --git a/ports/atmel-samd/common-hal/busio/UART.h b/ports/atmel-samd/common-hal/busio/UART.h index 685755a5d1..f94df040f8 100644 --- a/ports/atmel-samd/common-hal/busio/UART.h +++ b/ports/atmel-samd/common-hal/busio/UART.h @@ -42,10 +42,6 @@ typedef struct { bool rx_error; uint32_t baudrate; uint32_t timeout_ms; - // Index of the oldest received character. - uint32_t buffer_start; - // Index of the next available spot to store a character. - uint32_t buffer_size; uint32_t buffer_length; uint8_t* buffer; } busio_uart_obj_t; diff --git a/ports/atmel-samd/supervisor/port.c b/ports/atmel-samd/supervisor/port.c index 422bf1f64c..a63b85a9f7 100644 --- a/ports/atmel-samd/supervisor/port.c +++ b/ports/atmel-samd/supervisor/port.c @@ -61,6 +61,7 @@ #include "samd/external_interrupts.h" #include "samd/dma.h" #include "shared-bindings/rtc/__init__.h" +#include "board_busses.h" #include "tick.h" #include "usb.h" @@ -270,6 +271,8 @@ void reset_port(void) { reset_all_pins(); + reset_board_busses(); + // Output clocks for debugging. // not supported by SAMD51G; uncomment for SAMD51J or update for 51G // #ifdef SAMD51 diff --git a/ports/esp8266/common-hal/busio/UART.c b/ports/esp8266/common-hal/busio/UART.c index 9b5d86ef5c..8b5bb49d42 100644 --- a/ports/esp8266/common-hal/busio/UART.c +++ b/ports/esp8266/common-hal/busio/UART.c @@ -137,6 +137,9 @@ uint32_t common_hal_busio_uart_rx_characters_available(busio_uart_obj_t *self) { return 0; } +void common_hal_busio_uart_clear_rx_buffer(busio_uart_obj_t *self) { +} + bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self) { return true; } diff --git a/shared-bindings/busio/UART.c b/shared-bindings/busio/UART.c index 9bad2468e5..864fb974a2 100644 --- a/shared-bindings/busio/UART.c +++ b/shared-bindings/busio/UART.c @@ -252,6 +252,36 @@ const mp_obj_property_t busio_uart_baudrate_obj = { (mp_obj_t)&mp_const_none_obj}, }; +//| .. attribute:: in_waiting +//| +//| The number of bytes in the input buffer, available to be read +//| +STATIC mp_obj_t busio_uart_obj_get_in_waiting(mp_obj_t self_in) { + busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_busio_uart_deinited(self)); + return MP_OBJ_NEW_SMALL_INT(common_hal_busio_uart_rx_characters_available(self)); +} +MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_get_in_waiting_obj, busio_uart_obj_get_in_waiting); + +const mp_obj_property_t busio_uart_in_waiting_obj = { + .base.type = &mp_type_property, + .proxy = {(mp_obj_t)&busio_uart_get_in_waiting_obj, + (mp_obj_t)&mp_const_none_obj, + (mp_obj_t)&mp_const_none_obj}, +}; + +//| .. method:: reset_input_buffer() +//| +//| Discard any unread characters in the input buffer. +//| +STATIC mp_obj_t busio_uart_obj_reset_input_buffer(mp_obj_t self_in) { + busio_uart_obj_t *self = MP_OBJ_TO_PTR(self_in); + raise_error_if_deinited(common_hal_busio_uart_deinited(self)); + common_hal_busio_uart_clear_rx_buffer(self); + return mp_const_none; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(busio_uart_reset_input_buffer_obj, busio_uart_obj_reset_input_buffer); + //| .. class:: busio.UART.Parity //| //| Enum-like class to define the parity used to verify correct data transfer. @@ -306,9 +336,12 @@ STATIC const mp_rom_map_elem_t busio_uart_locals_dict_table[] = { { MP_OBJ_NEW_QSTR(MP_QSTR_readinto), MP_ROM_PTR(&mp_stream_readinto_obj) }, { MP_OBJ_NEW_QSTR(MP_QSTR_write), MP_ROM_PTR(&mp_stream_write_obj) }, + { 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) }, + // 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 fa39d8ad5f..513ff50c83 100644 --- a/shared-bindings/busio/UART.h +++ b/shared-bindings/busio/UART.h @@ -60,6 +60,7 @@ extern void common_hal_busio_uart_set_baudrate(busio_uart_obj_t *self, uint32_t 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); extern bool common_hal_busio_uart_ready_to_tx(busio_uart_obj_t *self); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_BUSIO_UART_H