Merge pull request #5422 from Neradoc/nera-secondary-I2C

Allow multiple board buses
This commit is contained in:
Scott Shawcroft 2022-01-21 11:08:14 -08:00 committed by GitHub
commit 9a353a4f56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 255 additions and 201 deletions

4
main.c
View File

@ -290,10 +290,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();

View File

@ -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,

View File

@ -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

View File

@ -51,7 +51,7 @@ uint8_t display_init_sequence[] = {
};
void board_init(void) {
busio_spi_obj_t *spi = common_hal_board_create_spi();
busio_spi_obj_t *spi = common_hal_board_create_spi(0);
displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus;
bus->base.type = &displayio_fourwire_type;
common_hal_displayio_fourwire_construct(bus,

View File

@ -78,7 +78,7 @@ void board_init(void) {
gpio_set_direction(21, GPIO_MODE_DEF_OUTPUT);
gpio_set_level(21, true);
busio_spi_obj_t *spi = common_hal_board_create_spi();
busio_spi_obj_t *spi = common_hal_board_create_spi(0);
displayio_fourwire_obj_t *bus = &displays[0].fourwire_bus;
bus->base.type = &displayio_fourwire_type;

View File

@ -4,12 +4,12 @@
#define MICROPY_HW_NEOPIXEL (&pin_GPIO12)
#define CIRCUITPY_STATUS_LED_POWER (&pin_GPIO11)
#define DEFAULT_I2C_BUS_SCL (&pin_GPIO25)
#define DEFAULT_I2C_BUS_SDA (&pin_GPIO24)
#define CIRCUITPY_BOARD_I2C (2)
#define CIRCUITPY_BOARD_I2C_PIN {{.scl = &pin_GPIO25, .sda = &pin_GPIO24}, \
{.scl = &pin_GPIO23, .sda = &pin_GPIO22}}
#define DEFAULT_SPI_BUS_SCK (&pin_GPIO6)
#define DEFAULT_SPI_BUS_MOSI (&pin_GPIO3)
#define DEFAULT_SPI_BUS_MISO (&pin_GPIO4)
#define CIRCUITPY_BOARD_SPI (1)
#define CIRCUITPY_BOARD_SPI_PIN {{.clock = &pin_GPIO6, .mosi = &pin_GPIO3, .miso = &pin_GPIO4}}
#define DEFAULT_UART_BUS_RX (&pin_GPIO5)
#define DEFAULT_UART_BUS_TX (&pin_GPIO20)
#define CIRCUITPY_BOARD_UART (1)
#define CIRCUITPY_BOARD_UART_PIN {{.tx = &pin_GPIO20, .rx = &pin_GPIO5}}

View File

@ -1,5 +1,7 @@
#include "shared-bindings/board/__init__.h"
CIRCUITPY_BOARD_BUS_SINGLETON(stemma_i2c, i2c, 1)
STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
CIRCUITPYTHON_BOARD_DICT_STANDARD_ITEMS
@ -47,5 +49,7 @@ STATIC const mp_rom_map_elem_t board_module_globals_table[] = {
{ MP_ROM_QSTR(MP_QSTR_I2C), MP_ROM_PTR(&board_i2c_obj) },
{ MP_ROM_QSTR(MP_QSTR_SPI), MP_ROM_PTR(&board_spi_obj) },
{ MP_ROM_QSTR(MP_QSTR_UART), MP_ROM_PTR(&board_uart_obj) },
{ MP_ROM_QSTR(MP_QSTR_STEMMA_I2C), MP_ROM_PTR(&board_stemma_i2c_obj) },
};
MP_DEFINE_CONST_DICT(board_module_globals, board_module_globals_table);

View File

@ -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)

View File

@ -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,57 @@
//| """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."""
//| """Returns the `busio.I2C` object for the board's designated I2C bus(es).
//| The object created is a singleton, and 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 (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();
#if CIRCUITPY_BOARD_I2C
STATIC mp_obj_t board_i2c_0(void) {
return common_hal_board_create_i2c(0);
}
#else
mp_obj_t board_i2c(void) {
STATIC mp_obj_t board_i2c_0(void) {
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_0(board_i2c_obj, board_i2c_0);
//| def SPI() -> busio.SPI:
//| """Returns the `busio.SPI` object for the board designated SCK, MOSI and MISO pins. It is a
//| singleton."""
//| """Returns the `busio.SPI` object for the board's designated SPI bus(es).
//| The object created is a singleton, and 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 (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();
#if CIRCUITPY_BOARD_SPI
STATIC mp_obj_t board_spi_0(void) {
return common_hal_board_create_spi(0);
}
#else
mp_obj_t board_spi(void) {
STATIC mp_obj_t board_spi_0(void) {
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_0(board_spi_obj, board_spi_0);
//| 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."""
//| """Returns the `busio.UART` object for the board's designated UART bus(es).
//| The object created is a singleton, and 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) {
return singleton;
}
assert_pin_free(DEFAULT_UART_BUS_RX);
assert_pin_free(DEFAULT_UART_BUS_TX);
return common_hal_board_create_uart();
#if CIRCUITPY_BOARD_UART
STATIC mp_obj_t board_uart_0(void) {
return common_hal_board_create_uart(0);
}
#else
mp_obj_t board_uart(void) {
STATIC mp_obj_t board_uart_0(void) {
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_0(board_uart_obj, board_uart_0);
const mp_obj_module_t board_module = {
.base = { &mp_type_module },

View File

@ -35,21 +35,29 @@
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);
bool common_hal_board_is_i2c(mp_obj_t obj);
mp_obj_t common_hal_board_get_i2c(const mp_int_t instance);
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_0(board_i2c_obj);
mp_obj_t common_hal_board_get_spi(void);
mp_obj_t common_hal_board_create_spi(void);
bool common_hal_board_is_spi(mp_obj_t obj);
mp_obj_t common_hal_board_get_spi(const mp_int_t instance);
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_0(board_spi_obj);
mp_obj_t common_hal_board_get_uart(void);
mp_obj_t common_hal_board_create_uart(void);
bool common_hal_board_is_uart(mp_obj_t obj);
mp_obj_t common_hal_board_get_uart(const mp_int_t instance);
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_0(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) { \
return common_hal_board_create_##bus(instance); \
} \
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) }, \

View File

@ -46,141 +46,189 @@
#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) {
const mp_obj_t singleton = common_hal_board_get_i2c(instance);
if (singleton != NULL && !common_hal_busio_i2c_deinited(singleton)) {
return singleton;
}
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) {
const mp_obj_t singleton = common_hal_board_get_spi(instance);
if (singleton != NULL && !common_hal_busio_spi_deinited(singleton)) {
return singleton;
}
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) {
const mp_obj_t singleton = common_hal_board_get_uart(instance);
if (singleton != NULL && !common_hal_busio_uart_deinited(singleton)) {
return singleton;
}
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
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_singleton) {
if (displays[i].bus_base.type == &displayio_i2cdisplay_type && displays[i].i2cdisplay_bus.bus == &i2c_obj[instance]) {
display_using_i2c = true;
break;
}
}
#endif
if (!common_hal_busio_i2c_deinited(&i2c_obj[instance])) {
// make sure I2C lock is not held over a soft reset
if (i2c_singleton != NULL) {
common_hal_busio_i2c_unlock(i2c_singleton);
common_hal_busio_i2c_unlock(&i2c_obj[instance]);
if (!display_using_i2c) {
common_hal_busio_i2c_deinit(i2c_singleton);
i2c_singleton = NULL;
common_hal_busio_i2c_deinit(&i2c_obj[instance]);
}
}
}
#endif
#if BOARD_SPI
#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_singleton) {
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_singleton) {
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
if (spi_singleton != NULL) {
common_hal_busio_spi_unlock(spi_singleton);
common_hal_busio_spi_unlock(&spi_obj[instance]);
if (!display_using_spi) {
common_hal_busio_spi_deinit(spi_singleton);
spi_singleton = NULL;
common_hal_busio_spi_deinit(&spi_obj[instance]);
}
}
}
#endif
#if BOARD_UART
MP_STATE_VM(shared_uart_bus) = NULL;
#if CIRCUITPY_BOARD_UART
for (uint8_t instance = 0; instance < CIRCUITPY_BOARD_UART; instance++) {
common_hal_busio_uart_deinit(&uart_obj[instance]);
}
#endif
}

View File

@ -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

View File

@ -24,7 +24,6 @@
* THE SOFTWARE.
*/
#include <string.h>
#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

View File

@ -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));