From b6858e4ca7158b68074aef5082a46a1058f42079 Mon Sep 17 00:00:00 2001 From: microDev <70126934+microDev1@users.noreply.github.com> Date: Sat, 11 Dec 2021 21:33:12 +0530 Subject: [PATCH] allow multiple board buses Co-authored-by: Neradoc --- main.c | 4 +- .../boards/hallowing_m0_express/board.c | 2 +- ports/atmel-samd/boards/ugame10/board.c | 2 +- py/circuitpy_mpconfig.h | 47 +++- shared-bindings/board/__init__.c | 94 +++---- shared-bindings/board/__init__.h | 33 ++- shared-module/board/__init__.c | 239 ++++++++++-------- shared-module/board/__init__.h | 2 +- shared-module/displayio/__init__.c | 17 +- .../sharpdisplay/SharpMemoryFramebuffer.c | 4 +- 10 files changed, 254 insertions(+), 190 deletions(-) diff --git a/main.c b/main.c index c019237362..c219885412 100644 --- a/main.c +++ b/main.c @@ -289,10 +289,10 @@ STATIC void cleanup_after_vm(supervisor_allocation *heap, mp_obj_t exception) { keypad_reset(); #endif - // reset_board_busses() first because it may release pins from the never_reset state, so that + // reset_board_buses() first because it may release pins from the never_reset state, so that // reset_port() can reset them. #if CIRCUITPY_BOARD - reset_board_busses(); + reset_board_buses(); #endif reset_port(); reset_board(); diff --git a/ports/atmel-samd/boards/hallowing_m0_express/board.c b/ports/atmel-samd/boards/hallowing_m0_express/board.c index dfa60a5da6..aace060b01 100644 --- a/ports/atmel-samd/boards/hallowing_m0_express/board.c +++ b/ports/atmel-samd/boards/hallowing_m0_express/board.c @@ -71,7 +71,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus; bus->base.type = &displayio_fourwire_type; - busio_spi_obj_t *spi = common_hal_board_create_spi(); + busio_spi_obj_t *spi = common_hal_board_create_spi(0); common_hal_busio_spi_never_reset(spi); common_hal_displayio_fourwire_construct(bus, spi, diff --git a/ports/atmel-samd/boards/ugame10/board.c b/ports/atmel-samd/boards/ugame10/board.c index b732d259db..d75841be54 100644 --- a/ports/atmel-samd/boards/ugame10/board.c +++ b/ports/atmel-samd/boards/ugame10/board.c @@ -72,7 +72,7 @@ uint8_t display_init_sequence[] = { void board_init(void) { displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus; bus->base.type = &displayio_fourwire_type; - busio_spi_obj_t *spi = common_hal_board_create_spi(); + busio_spi_obj_t *spi = common_hal_board_create_spi(0); common_hal_displayio_fourwire_construct(bus, spi, &pin_PA09, // Command or data diff --git a/py/circuitpy_mpconfig.h b/py/circuitpy_mpconfig.h index 6efc341fce..9e8fb076fb 100644 --- a/py/circuitpy_mpconfig.h +++ b/py/circuitpy_mpconfig.h @@ -259,23 +259,42 @@ typedef long mp_off_t; #error No *_FLASH_FILESYSTEM set! #endif +// Default board buses. + +#ifndef CIRCUITPY_BOARD_I2C +#if defined(DEFAULT_I2C_BUS_SCL) && defined(DEFAULT_I2C_BUS_SDA) +#define CIRCUITPY_BOARD_I2C (1) +#define CIRCUITPY_BOARD_I2C_PIN {{.scl = DEFAULT_I2C_BUS_SCL, .sda = DEFAULT_I2C_BUS_SDA}} +#else +#define CIRCUITPY_BOARD_I2C (0) +#endif +#endif + +#ifndef CIRCUITPY_BOARD_SPI +#if defined(DEFAULT_SPI_BUS_SCK) && defined(DEFAULT_SPI_BUS_MOSI) && defined(DEFAULT_SPI_BUS_MISO) +#define CIRCUITPY_BOARD_SPI (1) +#define CIRCUITPY_BOARD_SPI_PIN {{.clock = DEFAULT_SPI_BUS_SCK, .mosi = DEFAULT_SPI_BUS_MOSI, .miso = DEFAULT_SPI_BUS_MISO}} +#else +#define CIRCUITPY_BOARD_SPI (0) +#endif +#endif + +#ifndef CIRCUITPY_BOARD_UART +#if defined(DEFAULT_UART_BUS_TX) && defined(DEFAULT_UART_BUS_RX) +#define CIRCUITPY_BOARD_UART (1) +#define CIRCUITPY_BOARD_UART_PIN {{.tx = DEFAULT_UART_BUS_TX, .rx = DEFAULT_UART_BUS_RX}} +#define BOARD_UART_ROOT_POINTER mp_obj_t board_uart_bus; +#else +#define CIRCUITPY_BOARD_UART (0) +#define BOARD_UART_ROOT_POINTER +#endif +#else +#define BOARD_UART_ROOT_POINTER mp_obj_t board_uart_bus; +#endif + // These CIRCUITPY_xxx values should all be defined in the *.mk files as being on or off. // So if any are not defined in *.mk, they'll throw an error here. -#if CIRCUITPY_BOARD -#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)) -// I2C and SPI are always allocated off the heap. -#if BOARD_UART -#define BOARD_UART_ROOT_POINTER mp_obj_t shared_uart_bus; -#else -#define BOARD_UART_ROOT_POINTER -#endif -#else -#define BOARD_UART_ROOT_POINTER -#endif - #if CIRCUITPY_DISPLAYIO #ifndef CIRCUITPY_DISPLAY_LIMIT #define CIRCUITPY_DISPLAY_LIMIT (1) diff --git a/shared-bindings/board/__init__.c b/shared-bindings/board/__init__.c index bb273c61a9..4edd455b44 100644 --- a/shared-bindings/board/__init__.c +++ b/shared-bindings/board/__init__.c @@ -28,12 +28,15 @@ #include "py/runtime.h" #include "shared-bindings/board/__init__.h" -#if BOARD_I2C +#if CIRCUITPY_BOARD_I2C #include "shared-bindings/busio/I2C.h" #endif -#if BOARD_SPI +#if CIRCUITPY_BOARD_SPI #include "shared-bindings/busio/SPI.h" #endif +#if CIRCUITPY_BOARD_UART +#include "shared-bindings/busio/UART.h" +#endif //| """Board specific pin names //| @@ -47,84 +50,85 @@ //| """Board ID string. The unique identifier for the board model in //| circuitpython, as well as on circuitpython.org. //| Example: "hallowing_m0_express".""" -//| -//| def I2C() -> busio.I2C: -//| """Returns the `busio.I2C` object for the board designated SDA and SCL pins. It is a singleton.""" +#if CIRCUITPY_BOARD_I2C || CIRCUITPY_BOARD_SPI || CIRCUITPY_BOARD_UART +STATIC mp_int_t board_get_instance(size_t n_args, const mp_obj_t *args, const mp_int_t bus_in) { + if (n_args == 0) { + return 0; + } + const mp_int_t instance = mp_obj_get_int(args[0]); + if (instance >= bus_in || instance < 0) { + mp_raise_ValueError_varg(translate("No default %q bus"), MP_QSTR_UART); + } + return instance; +} +#endif + +//| def I2C(instance: Optional[int] = 0) -> busio.I2C: +//| """Returns the `busio.I2C` object for the board's designated I2C bus(es). It is a singleton. +//| The object created uses the default parameter values for `busio.I2C`.""" //| ... //| - -#if BOARD_I2C -mp_obj_t board_i2c(void) { - mp_obj_t singleton = common_hal_board_get_i2c(); +#if CIRCUITPY_BOARD_I2C +mp_obj_t board_i2c(size_t n_args, const mp_obj_t *args) { + const mp_int_t instance = board_get_instance(n_args, args, CIRCUITPY_BOARD_I2C); + const mp_obj_t singleton = common_hal_board_get_i2c(instance); if (singleton != NULL && !common_hal_busio_i2c_deinited(singleton)) { return singleton; } - assert_pin_free(DEFAULT_I2C_BUS_SDA); - assert_pin_free(DEFAULT_I2C_BUS_SCL); - return common_hal_board_create_i2c(); + return common_hal_board_create_i2c(instance); } #else -mp_obj_t board_i2c(void) { +mp_obj_t board_i2c(size_t n_args, const mp_obj_t *args) { mp_raise_NotImplementedError_varg(translate("No default %q bus"), MP_QSTR_I2C); return MP_ROM_NONE; } #endif -MP_DEFINE_CONST_FUN_OBJ_0(board_i2c_obj, board_i2c); +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(board_i2c_obj, 0, 1, board_i2c); - -//| def SPI() -> busio.SPI: -//| """Returns the `busio.SPI` object for the board designated SCK, MOSI and MISO pins. It is a -//| singleton.""" +//| def SPI(instance: Optional[int] = 0) -> busio.SPI: +//| """Returns the `busio.SPI` object for the board's designated SPI bus(es). It is a singleton. +//| The object created uses the default parameter values for `busio.SPI`.""" //| ... //| -#if BOARD_SPI -mp_obj_t board_spi(void) { - mp_obj_t singleton = common_hal_board_get_spi(); +#if CIRCUITPY_BOARD_SPI +mp_obj_t board_spi(size_t n_args, const mp_obj_t *args) { + const mp_int_t instance = board_get_instance(n_args, args, CIRCUITPY_BOARD_SPI); + const mp_obj_t singleton = common_hal_board_get_spi(instance); if (singleton != NULL && !common_hal_busio_spi_deinited(singleton)) { return singleton; } - assert_pin_free(DEFAULT_SPI_BUS_SCK); - assert_pin_free(DEFAULT_SPI_BUS_MOSI); - assert_pin_free(DEFAULT_SPI_BUS_MISO); - return common_hal_board_create_spi(); + return common_hal_board_create_spi(instance); } #else -mp_obj_t board_spi(void) { +mp_obj_t board_spi(size_t n_args, const mp_obj_t *args) { mp_raise_NotImplementedError_varg(translate("No default %q bus"), MP_QSTR_SPI); return MP_ROM_NONE; } #endif -MP_DEFINE_CONST_FUN_OBJ_0(board_spi_obj, board_spi); +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(board_spi_obj, 0, 1, board_spi); -//| def UART() -> busio.UART: -//| """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.""" +//| def UART(instance: Optional[int] = 0) -> busio.UART: +//| """Returns the `busio.UART` object for the board's designated UART bus(es). It is a singleton. +//| The object created uses the default parameter values for `busio.UART`.""" //| ... //| -#if BOARD_UART -mp_obj_t board_uart(void) { - mp_obj_t singleton = common_hal_board_get_uart(); - if (singleton != NULL) { +#if CIRCUITPY_BOARD_UART +mp_obj_t board_uart(size_t n_args, const mp_obj_t *args) { + const mp_int_t instance = board_get_instance(n_args, args, CIRCUITPY_BOARD_UART); + const mp_obj_t singleton = common_hal_board_get_uart(instance); + if (singleton != NULL && !common_hal_busio_uart_deinited(singleton)) { return singleton; } - - assert_pin_free(DEFAULT_UART_BUS_RX); - assert_pin_free(DEFAULT_UART_BUS_TX); - - return common_hal_board_create_uart(); + return common_hal_board_create_uart(instance); } #else -mp_obj_t board_uart(void) { +mp_obj_t board_uart(size_t n_args, const mp_obj_t *args) { mp_raise_NotImplementedError_varg(translate("No default %q bus"), MP_QSTR_UART); return MP_ROM_NONE; } #endif -MP_DEFINE_CONST_FUN_OBJ_0(board_uart_obj, board_uart); +MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(board_uart_obj, 0, 1, board_uart); const mp_obj_module_t board_module = { .base = { &mp_type_module }, diff --git a/shared-bindings/board/__init__.h b/shared-bindings/board/__init__.h index bc4d7df61f..78428c46e4 100644 --- a/shared-bindings/board/__init__.h +++ b/shared-bindings/board/__init__.h @@ -35,21 +35,30 @@ extern const mp_obj_dict_t board_module_globals; STATIC const MP_DEFINE_STR_OBJ(board_module_id_obj, CIRCUITPY_BOARD_ID); -mp_obj_t common_hal_board_get_i2c(void); -mp_obj_t common_hal_board_create_i2c(void); -MP_DECLARE_CONST_FUN_OBJ_0(board_i2c_obj); +bool common_hal_board_is_i2c(mp_obj_t obj); +mp_obj_t common_hal_board_get_i2c(const mp_int_t insatnce); +mp_obj_t common_hal_board_create_i2c(const mp_int_t instance); +mp_obj_t board_i2c(size_t n_args, const mp_obj_t *args); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(board_i2c_obj); -mp_obj_t common_hal_board_get_spi(void); -mp_obj_t common_hal_board_create_spi(void); -MP_DECLARE_CONST_FUN_OBJ_0(board_spi_obj); +bool common_hal_board_is_spi(mp_obj_t obj); +mp_obj_t common_hal_board_get_spi(const mp_int_t insatnce); +mp_obj_t common_hal_board_create_spi(const mp_int_t instance); +mp_obj_t board_spi(size_t n_args, const mp_obj_t *args); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(board_spi_obj); -mp_obj_t common_hal_board_get_uart(void); -mp_obj_t common_hal_board_create_uart(void); -MP_DECLARE_CONST_FUN_OBJ_0(board_uart_obj); +bool common_hal_board_is_uart(mp_obj_t obj); +mp_obj_t common_hal_board_get_uart(const mp_int_t insatnce); +mp_obj_t common_hal_board_create_uart(const mp_int_t instance); +mp_obj_t board_uart(size_t n_args, const mp_obj_t *args); +MP_DECLARE_CONST_FUN_OBJ_VAR_BETWEEN(board_uart_obj); -mp_obj_t board_i2c(void); -mp_obj_t board_spi(void); -mp_obj_t board_uart(void); +#define CIRCUITPY_BOARD_BUS_SINGLETON(name, bus, instance) \ + STATIC mp_obj_t board_##name(void) { \ + const mp_obj_t inst = mp_obj_new_int_from_uint(instance); \ + return board_##bus(1, &inst); \ + } \ + MP_DEFINE_CONST_FUN_OBJ_0(board_##name##_obj, board_##name); #define CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS \ { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_board) }, \ diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index 19d9e7ece0..f062531978 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -46,141 +46,174 @@ #include "shared-module/sharpdisplay/SharpMemoryFramebuffer.h" #endif -#if BOARD_I2C +#if CIRCUITPY_BOARD_I2C // Statically allocate the I2C object so it can live past the end of the heap and into the next VM. // That way it can be used by built-in I2CDisplay displays and be accessible through board.I2C(). -STATIC busio_i2c_obj_t i2c_obj; -STATIC mp_obj_t i2c_singleton = NULL; -mp_obj_t common_hal_board_get_i2c(void) { - return i2c_singleton; +typedef struct { + const mcu_pin_obj_t *scl; + const mcu_pin_obj_t *sda; +} board_i2c_pin_t; + +static const board_i2c_pin_t i2c_pin[CIRCUITPY_BOARD_I2C] = CIRCUITPY_BOARD_I2C_PIN; +static busio_i2c_obj_t i2c_obj[CIRCUITPY_BOARD_I2C]; + +bool common_hal_board_is_i2c(mp_obj_t obj) { + for (uint8_t instance = 0; instance < CIRCUITPY_BOARD_I2C; instance++) { + if (obj == &i2c_obj[instance]) { + return true; + } + } + return false; } -mp_obj_t common_hal_board_create_i2c(void) { - // All callers have either already verified this or come so early that it can't be otherwise. - assert(i2c_singleton == NULL || common_hal_busio_i2c_deinited(i2c_singleton)); - busio_i2c_obj_t *self = &i2c_obj; +mp_obj_t common_hal_board_get_i2c(const mp_int_t instance) { + return &i2c_obj[instance]; +} + +mp_obj_t common_hal_board_create_i2c(const mp_int_t instance) { + busio_i2c_obj_t *self = &i2c_obj[instance]; self->base.type = &busio_i2c_type; - common_hal_busio_i2c_construct(self, DEFAULT_I2C_BUS_SCL, DEFAULT_I2C_BUS_SDA, 100000, 255); - i2c_singleton = (mp_obj_t)self; - return i2c_singleton; + assert_pin_free(i2c_pin[instance].scl); + assert_pin_free(i2c_pin[instance].sda); + + common_hal_busio_i2c_construct(self, i2c_pin[instance].scl, i2c_pin[instance].sda, 100000, 255); + + return &i2c_obj[instance]; } #endif - -#if BOARD_SPI +#if CIRCUITPY_BOARD_SPI // Statically allocate the SPI object so it can live past the end of the heap and into the next VM. // That way it can be used by built-in FourWire displays and be accessible through board.SPI(). -STATIC busio_spi_obj_t spi_obj; -STATIC mp_obj_t spi_singleton = NULL; -mp_obj_t common_hal_board_get_spi(void) { - return spi_singleton; +typedef struct { + const mcu_pin_obj_t *clock; + const mcu_pin_obj_t *mosi; + const mcu_pin_obj_t *miso; +} board_spi_pin_t; + +static const board_spi_pin_t spi_pin[CIRCUITPY_BOARD_SPI] = CIRCUITPY_BOARD_SPI_PIN; +static busio_spi_obj_t spi_obj[CIRCUITPY_BOARD_SPI]; + +bool common_hal_board_is_spi(mp_obj_t obj) { + for (uint8_t instance = 0; instance < CIRCUITPY_BOARD_SPI; instance++) { + if (obj == &spi_obj[instance]) { + return true; + } + } + return false; } -mp_obj_t common_hal_board_create_spi(void) { - // All callers have either already verified this or come so early that it can't be otherwise. - assert(spi_singleton == NULL || common_hal_busio_spi_deinited(spi_singleton)); - busio_spi_obj_t *self = &spi_obj; +mp_obj_t common_hal_board_get_spi(const mp_int_t instance) { + return &spi_obj[instance]; +} + +mp_obj_t common_hal_board_create_spi(const mp_int_t instance) { + busio_spi_obj_t *self = &spi_obj[instance]; self->base.type = &busio_spi_type; - 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; + assert_pin_free(spi_pin[instance].clock); + assert_pin_free(spi_pin[instance].mosi); + assert_pin_free(spi_pin[instance].miso); + + common_hal_busio_spi_construct(self, spi_pin[instance].clock, spi_pin[instance].mosi, spi_pin[instance].miso); + + return &spi_obj[instance]; } #endif -#if BOARD_UART -mp_obj_t common_hal_board_get_uart(void) { - return MP_STATE_VM(shared_uart_bus); +#if CIRCUITPY_BOARD_UART + +typedef struct { + const mcu_pin_obj_t *tx; + const mcu_pin_obj_t *rx; +} board_uart_pin_t; + +static const board_uart_pin_t uart_pin[CIRCUITPY_BOARD_UART] = CIRCUITPY_BOARD_UART_PIN; +static busio_uart_obj_t uart_obj[CIRCUITPY_BOARD_UART]; + +bool common_hal_board_is_uart(mp_obj_t obj) { + for (uint8_t instance = 0; instance < CIRCUITPY_BOARD_UART; instance++) { + if (obj == &uart_obj[instance]) { + return true; + } + } + return false; } -mp_obj_t common_hal_board_create_uart(void) { - busio_uart_obj_t *self = m_new_ll_obj(busio_uart_obj_t); +mp_obj_t common_hal_board_get_uart(const mp_int_t instance) { + return &uart_obj[instance]; +} + +mp_obj_t common_hal_board_create_uart(const mp_int_t instance) { + busio_uart_obj_t *self = &uart_obj[instance]; self->base.type = &busio_uart_type; - 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); - #ifdef DEFAULT_UART_BUS_RTS - const mcu_pin_obj_t *rts = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RTS); - #else - const mcu_pin_obj_t *rts = NULL; - #endif - #ifdef DEFAULT_UART_BUS_CTS - const mcu_pin_obj_t *cts = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_CTS); - #else - const mcu_pin_obj_t *cts = NULL; - #endif - #ifdef DEFAULT_UART_IS_RS485 - const mcu_pin_obj_t *rs485_dir = MP_OBJ_TO_PTR(DEFAULT_UART_BUS_RS485DIR); - #ifdef DEFAULT_UART_RS485_INVERT - const bool rs485_invert = true; - #else - const bool rs485_invert = false; - #endif - #else - const mcu_pin_obj_t *rs485_dir = NULL; - const bool rs485_invert = false; - #endif + MP_STATE_VM(board_uart_bus) = &uart_obj; - common_hal_busio_uart_construct(self, tx, rx, rts, cts, rs485_dir, rs485_invert, - 9600, 8, BUSIO_UART_PARITY_NONE, 1, 1.0f, 64, NULL, false); - MP_STATE_VM(shared_uart_bus) = MP_OBJ_FROM_PTR(self); - return MP_STATE_VM(shared_uart_bus); + assert_pin_free(uart_pin[instance].tx); + assert_pin_free(uart_pin[instance].rx); + + common_hal_busio_uart_construct(self, uart_pin[instance].tx, uart_pin[instance].rx, + NULL, NULL, NULL, false, 9600, 8, BUSIO_UART_PARITY_NONE, 1, 1.0f, 64, NULL, false); + + return &uart_obj[instance]; } #endif -void reset_board_busses(void) { - #if BOARD_I2C - bool display_using_i2c = false; - #if CIRCUITPY_DISPLAYIO - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - if (displays[i].bus_base.type == &displayio_i2cdisplay_type && displays[i].i2cdisplay_bus.bus == i2c_singleton) { - display_using_i2c = true; - break; - } - } - #endif - // make sure I2C lock is not held over a soft reset - if (i2c_singleton != NULL) { - common_hal_busio_i2c_unlock(i2c_singleton); - if (!display_using_i2c) { - common_hal_busio_i2c_deinit(i2c_singleton); - i2c_singleton = NULL; - } - } - #endif - #if BOARD_SPI - bool display_using_spi = false; - #if CIRCUITPY_DISPLAYIO - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { - mp_const_obj_t bus_type = displays[i].bus_base.type; - if (bus_type == &displayio_fourwire_type && displays[i].fourwire_bus.bus == spi_singleton) { - display_using_spi = true; - break; - } - #if CIRCUITPY_SHARPDISPLAY - if (displays[i].bus_base.type == &sharpdisplay_framebuffer_type && displays[i].sharpdisplay.bus == spi_singleton) { - display_using_spi = true; - break; +void reset_board_buses(void) { + #if CIRCUITPY_BOARD_I2C + for (uint8_t instance = 0; instance < CIRCUITPY_BOARD_I2C; instance++) { + bool display_using_i2c = false; + #if CIRCUITPY_DISPLAYIO + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].bus_base.type == &displayio_i2cdisplay_type && displays[i].i2cdisplay_bus.bus == &i2c_obj[instance]) { + display_using_i2c = true; + break; + } } #endif - } - #endif - // make sure SPI lock is not held over a soft reset - if (spi_singleton != NULL) { - common_hal_busio_spi_unlock(spi_singleton); - if (!display_using_spi) { - common_hal_busio_spi_deinit(spi_singleton); - spi_singleton = NULL; + if (!common_hal_busio_i2c_deinited(&i2c_obj[instance])) { + // make sure I2C lock is not held over a soft reset + common_hal_busio_i2c_unlock(&i2c_obj[instance]); + if (!display_using_i2c) { + common_hal_busio_i2c_deinit(&i2c_obj[instance]); + } } } #endif - #if BOARD_UART - MP_STATE_VM(shared_uart_bus) = NULL; + #if CIRCUITPY_BOARD_SPI + for (uint8_t instance = 0; instance < CIRCUITPY_BOARD_SPI; instance++) { + bool display_using_spi = false; + #if CIRCUITPY_DISPLAYIO + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + mp_const_obj_t bus_type = displays[i].bus_base.type; + if (bus_type == &displayio_fourwire_type && displays[i].fourwire_bus.bus == &spi_obj[instance]) { + display_using_spi = true; + break; + } + #if CIRCUITPY_SHARPDISPLAY + if (displays[i].bus_base.type == &sharpdisplay_framebuffer_type && displays[i].sharpdisplay.bus == &spi_obj[instance]) { + display_using_spi = true; + break; + } + #endif + } + #endif + if (!common_hal_busio_spi_deinited(&spi_obj[instance])) { + // make sure SPI lock is not held over a soft reset + common_hal_busio_spi_unlock(&spi_obj[instance]); + if (!display_using_spi) { + common_hal_busio_spi_deinit(&spi_obj[instance]); + } + } + } + #endif + #if CIRCUITPY_BOARD_UART + for (uint8_t instance = 0; instance < CIRCUITPY_BOARD_UART; instance++) { + common_hal_busio_uart_deinit(&uart_obj[instance]); + } #endif } diff --git a/shared-module/board/__init__.h b/shared-module/board/__init__.h index f7eecd4170..8b3723bdda 100644 --- a/shared-module/board/__init__.h +++ b/shared-module/board/__init__.h @@ -27,6 +27,6 @@ #ifndef MICROPY_INCLUDED_SHARED_MODULE_BOARD__INIT__H #define MICROPY_INCLUDED_SHARED_MODULE_BOARD__INIT__H -void reset_board_busses(void); +void reset_board_buses(void); #endif // MICROPY_INCLUDED_SHARED_MODULE_BOARD__INIT__H diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index ff085d45ef..6fa3aac15c 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -24,7 +24,6 @@ * THE SOFTWARE. */ - #include #include "shared-module/displayio/__init__.h" @@ -169,11 +168,11 @@ void reset_displays(void) { if (((size_t)fourwire->bus) < ((size_t)&displays) || ((size_t)fourwire->bus) > ((size_t)&displays + CIRCUITPY_DISPLAY_LIMIT)) { busio_spi_obj_t *original_spi = fourwire->bus; - #if BOARD_SPI - // We don't need to move original_spi if it is the board.SPI object because it is + #if CIRCUITPY_BOARD_SPI + // We don't need to move original_spi if it is a board.SPI object because it is // statically allocated already. (Doing so would also make it impossible to reference in // a subsequent VM run.) - if (original_spi == common_hal_board_get_spi()) { + if (common_hal_board_is_spi(original_spi)) { continue; } #endif @@ -197,11 +196,11 @@ void reset_displays(void) { if (((size_t)i2c->bus) < ((size_t)&displays) || ((size_t)i2c->bus) > ((size_t)&displays + CIRCUITPY_DISPLAY_LIMIT)) { busio_i2c_obj_t *original_i2c = i2c->bus; - #if BOARD_I2C - // We don't need to move original_i2c if it is the board.I2C object because it is + #if CIRCUITPY_BOARD_I2C + // We don't need to move original_i2c if it is a board.I2C object because it is // statically allocated already. (Doing so would also make it impossible to reference in // a subsequent VM run.) - if (original_i2c == common_hal_board_get_i2c()) { + if (common_hal_board_is_i2c(original_i2c)) { continue; } #endif @@ -230,11 +229,11 @@ void reset_displays(void) { if (((uint32_t)is31->i2c) < ((uint32_t)&displays) || ((uint32_t)is31->i2c) > ((uint32_t)&displays + CIRCUITPY_DISPLAY_LIMIT)) { busio_i2c_obj_t *original_i2c = is31->i2c; - #if BOARD_I2C + #if CIRCUITPY_BOARD_I2C // We don't need to move original_i2c if it is the board.I2C object because it is // statically allocated already. (Doing so would also make it impossible to reference in // a subsequent VM run.) - if (original_i2c == common_hal_board_get_i2c()) { + if (common_hal_board_is_i2c(original_i2c)) { continue; } #endif diff --git a/shared-module/sharpdisplay/SharpMemoryFramebuffer.c b/shared-module/sharpdisplay/SharpMemoryFramebuffer.c index ba0e0f2d69..285abb1dbe 100644 --- a/shared-module/sharpdisplay/SharpMemoryFramebuffer.c +++ b/shared-module/sharpdisplay/SharpMemoryFramebuffer.c @@ -71,8 +71,8 @@ STATIC bool common_hal_sharpdisplay_framebuffer_get_pixels_in_byte_share_row(sha void common_hal_sharpdisplay_framebuffer_reset(sharpdisplay_framebuffer_obj_t *self) { if (self->bus != &self->inline_bus - #if BOARD_SPI - && self->bus != common_hal_board_get_spi() + #if CIRCUITPY_BOARD_SPI + && !common_hal_board_is_spi(self->bus) #endif ) { memcpy(&self->inline_bus, self->bus, sizeof(busio_spi_obj_t));