diff options
| -rwxr-xr-x | main.c | 2 | ||||
| -rw-r--r-- | ports/atmel-samd/background.c | 2 | ||||
| -rw-r--r-- | ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h | 2 | ||||
| -rw-r--r-- | ports/atmel-samd/boards/grandcentral_m4_express/pins.c | 2 | ||||
| -rw-r--r-- | ports/atmel-samd/boards/pyportal/mpconfigboard.h | 2 | ||||
| -rw-r--r-- | ports/atmel-samd/boards/pyportal/pins.c | 4 | ||||
| -rw-r--r-- | ports/atmel-samd/common-hal/busio/SPI.c | 13 | ||||
| -rw-r--r-- | ports/atmel-samd/common-hal/displayio/FourWire.c | 10 | ||||
| -rw-r--r-- | ports/atmel-samd/common-hal/displayio/FourWire.h | 1 | ||||
| -rw-r--r-- | ports/atmel-samd/common-hal/microcontroller/Pin.c | 2 | ||||
| -rw-r--r-- | shared-bindings/displayio/Display.c | 23 | ||||
| -rw-r--r-- | shared-bindings/displayio/FourWire.c | 23 | ||||
| -rw-r--r-- | shared-bindings/displayio/FourWire.h | 2 | ||||
| -rw-r--r-- | shared-bindings/displayio/ParallelBus.h | 2 | ||||
| -rw-r--r-- | shared-bindings/displayio/__init__.c | 16 | ||||
| -rw-r--r-- | shared-bindings/displayio/__init__.h | 4 | ||||
| -rw-r--r-- | shared-module/displayio/__init__.c | 220 | ||||
| -rw-r--r-- | shared-module/displayio/__init__.h | 7 |
18 files changed, 255 insertions, 82 deletions
@@ -201,7 +201,7 @@ bool run_code_py(safe_mode_t safe_mode) { } } // Turn off the display before the heap disappears. - reset_primary_display(); + reset_displays(); stop_mp(); free_memory(heap); diff --git a/ports/atmel-samd/background.c b/ports/atmel-samd/background.c index 439877d2e..59e03008a 100644 --- a/ports/atmel-samd/background.c +++ b/ports/atmel-samd/background.c @@ -44,7 +44,7 @@ void run_background_tasks(void) { audio_dma_background(); #endif #ifdef CIRCUITPY_DISPLAYIO - displayio_refresh_display(); + displayio_refresh_displays(); #endif #if MICROPY_PY_NETWORK diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h index e1bef0019..465c51b4a 100644 --- a/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h +++ b/ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h @@ -46,3 +46,5 @@ #define IGNORE_PIN_PA25 1 #define CIRCUITPY_I2CSLAVE +#define CIRCUITPY_DISPLAYIO (1) +#define CIRCUITPY_DISPLAY_LIMIT (3) diff --git a/ports/atmel-samd/boards/grandcentral_m4_express/pins.c b/ports/atmel-samd/boards/grandcentral_m4_express/pins.c index 081bb701e..0d19a63ef 100644 --- a/ports/atmel-samd/boards/grandcentral_m4_express/pins.c +++ b/ports/atmel-samd/boards/grandcentral_m4_express/pins.c @@ -1,6 +1,6 @@ #include "shared-bindings/board/__init__.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" // This mapping only includes functional names because pins broken // out on connectors are labeled with their MCU name available from diff --git a/ports/atmel-samd/boards/pyportal/mpconfigboard.h b/ports/atmel-samd/boards/pyportal/mpconfigboard.h index 847e2ba76..f02d4a372 100644 --- a/ports/atmel-samd/boards/pyportal/mpconfigboard.h +++ b/ports/atmel-samd/boards/pyportal/mpconfigboard.h @@ -13,7 +13,7 @@ // QSPI Data pins #define MICROPY_PORT_A ( PORT_PA08 | PORT_PA09 | PORT_PA10 | PORT_PA11 ) // QSPI CS, and QSPI SCK -#define MICROPY_PORT_B ( PORT_PB10 | PORT_PB11 ) +#define MICROPY_PORT_B ( PORT_PB10 | PORT_PB11 | PORT_PB22 ) #define MICROPY_PORT_C ( 0 ) #define MICROPY_PORT_D (0) diff --git a/ports/atmel-samd/boards/pyportal/pins.c b/ports/atmel-samd/boards/pyportal/pins.c index ddb8fa08a..4ddc10e52 100644 --- a/ports/atmel-samd/boards/pyportal/pins.c +++ b/ports/atmel-samd/boards/pyportal/pins.c @@ -1,7 +1,7 @@ #include "shared-bindings/board/__init__.h" #include "boards/board.h" -#include "board_busses.h" +#include "supervisor/shared/board_busses.h" // This mapping only includes functional names because pins broken // out on connectors are labeled with their MCU name available from @@ -72,7 +72,5 @@ STATIC const mp_map_elem_t board_global_dict_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_DISPLAY), MP_ROM_PTR(&board_display_obj)} }; MP_DEFINE_CONST_DICT(board_module_globals, board_global_dict_table); diff --git a/ports/atmel-samd/common-hal/busio/SPI.c b/ports/atmel-samd/common-hal/busio/SPI.c index 68382d405..8fb831a69 100644 --- a/ports/atmel-samd/common-hal/busio/SPI.c +++ b/ports/atmel-samd/common-hal/busio/SPI.c @@ -54,6 +54,17 @@ void never_reset_sercom(Sercom* sercom) { } } +void allow_reset_sercom(Sercom* sercom) { + // Reset all SERCOMs except the ones being used by on-board devices. + Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS; + for (int i = 0; i < SERCOM_INST_NUM; i++) { + if (sercom_instances[i] == sercom) { + never_reset_sercoms[i] = false; + break; + } + } +} + void reset_sercoms(void) { // Reset all SERCOMs except the ones being used by on-board devices. Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS; @@ -235,6 +246,8 @@ void common_hal_busio_spi_deinit(busio_spi_obj_t *self) { if (common_hal_busio_spi_deinited(self)) { return; } + allow_reset_sercom(self->spi_desc.dev.prvt); + spi_m_sync_disable(&self->spi_desc); spi_m_sync_deinit(&self->spi_desc); reset_pin_number(self->clock_pin); diff --git a/ports/atmel-samd/common-hal/displayio/FourWire.c b/ports/atmel-samd/common-hal/displayio/FourWire.c index 7a0bdd0c1..ab01e2609 100644 --- a/ports/atmel-samd/common-hal/displayio/FourWire.c +++ b/ports/atmel-samd/common-hal/displayio/FourWire.c @@ -53,6 +53,16 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, never_reset_pin_number(reset->number); } +void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self) { + if (self->bus == &self->inline_bus) { + common_hal_busio_spi_deinit(self->bus); + } + + reset_pin_number(self->command.pin->number); + reset_pin_number(self->chip_select.pin->number); + reset_pin_number(self->reset.pin->number); +} + bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t obj) { displayio_fourwire_obj_t* self = MP_OBJ_TO_PTR(obj); if (!common_hal_busio_spi_try_lock(self->bus)) { diff --git a/ports/atmel-samd/common-hal/displayio/FourWire.h b/ports/atmel-samd/common-hal/displayio/FourWire.h index e3ae5781b..234bcf794 100644 --- a/ports/atmel-samd/common-hal/displayio/FourWire.h +++ b/ports/atmel-samd/common-hal/displayio/FourWire.h @@ -34,6 +34,7 @@ typedef struct { mp_obj_base_t base; busio_spi_obj_t* bus; + busio_spi_obj_t inline_bus; digitalio_digitalinout_obj_t command; digitalio_digitalinout_obj_t chip_select; digitalio_digitalinout_obj_t reset; diff --git a/ports/atmel-samd/common-hal/microcontroller/Pin.c b/ports/atmel-samd/common-hal/microcontroller/Pin.c index 7d0d97758..b7d527d04 100644 --- a/ports/atmel-samd/common-hal/microcontroller/Pin.c +++ b/ports/atmel-samd/common-hal/microcontroller/Pin.c @@ -100,6 +100,8 @@ void never_reset_pin_number(uint8_t pin_number) { } void reset_pin_number(uint8_t pin_number) { + never_reset_pins[GPIO_PORT(pin_number)] &= ~(1 << GPIO_PIN(pin_number)); + if (pin_number >= PORT_BITS) { return; } diff --git a/shared-bindings/displayio/Display.c b/shared-bindings/displayio/Display.c index 5db470417..21f44965e 100644 --- a/shared-bindings/displayio/Display.c +++ b/shared-bindings/displayio/Display.c @@ -40,18 +40,19 @@ //| .. currentmodule:: displayio //| -//| :class:`FourWire` -- Manage updating a display over SPI four wire protocol +//| :class:`Display` -- Manage updating a display over a display bus //| ========================================================================== //| -//| Manage updating a display over SPI four wire protocol in the background while Python code runs. -//| It doesn't handle display initialization. +//| This initializes a display and connects it into CircuitPython. Unlike other +//| objects in CircuitPython, Display objects live until `displayio.release_displays()` +//| is called. This is done so that CircuitPython can use the display itself. //| //| .. warning:: This will be changed before 4.0.0. Consider it very experimental. //| //| .. class:: Display(display_bus, *, width, height, colstart=0, rowstart=0, color_depth=16, //| set_column_command=0x2a set_row_command=0x2b, write_ram_command=0x2c) //| -//| Create a FourWire object associated with the given pins. +//| Create a Display object. //| STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { enum { ARG_display_bus, ARG_init_sequence, ARG_width, ARG_height, ARG_colstart, ARG_rowstart, ARG_color_depth, ARG_set_column_command, ARG_set_row_command, ARG_write_ram_command }; @@ -80,11 +81,15 @@ STATIC mp_obj_t displayio_display_make_new(const mp_obj_type_t *type, size_t n_a mp_buffer_info_t bufinfo; mp_get_buffer_raise(args[ARG_init_sequence].u_obj, &bufinfo, MP_BUFFER_READ); - displayio_display_obj_t *self; - if (display_bus == &primary_display.fourwire_bus) { - self = &primary_display.display; - } else { - self = m_new_obj(displayio_display_obj_t); + displayio_display_obj_t *self = NULL; + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].display.base.type == NULL) { + self = &displays[i].display; + break; + } + } + if (self == NULL) { + mp_raise_RuntimeError(translate("Display limit reached")); } self->base.type = &displayio_display_type; common_hal_displayio_display_construct(self, diff --git a/shared-bindings/displayio/FourWire.c b/shared-bindings/displayio/FourWire.c index 674d1c900..9833fbc64 100644 --- a/shared-bindings/displayio/FourWire.c +++ b/shared-bindings/displayio/FourWire.c @@ -69,18 +69,21 @@ STATIC mp_obj_t displayio_fourwire_make_new(const mp_obj_type_t *type, size_t n_ if (command == mp_const_none || chip_select == mp_const_none) { mp_raise_ValueError(translate("Command and chip_select required")); } + assert_pin_free(command); + assert_pin_free(chip_select); + assert_pin_free(reset); - displayio_fourwire_obj_t* self; + displayio_fourwire_obj_t* self = NULL; mp_obj_t spi = args[ARG_spi_bus].u_obj; - if (board_spi() == spi && primary_display.bus_type == NULL) { - self = &primary_display.fourwire_bus; - primary_display.bus_type = &displayio_fourwire_type; - } else { - // TODO(tannewt): Always check pin free. For now we ignore the primary display. - assert_pin_free(command); - assert_pin_free(chip_select); - assert_pin_free(reset); - self = m_new_obj(displayio_fourwire_obj_t); + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].fourwire_bus.base.type== NULL) { + self = &displays[i].fourwire_bus; + self->base.type = &displayio_fourwire_type; + break; + } + } + if (self == NULL) { + mp_raise_RuntimeError(translate("Display bus limit reached")); } common_hal_displayio_fourwire_construct(self, diff --git a/shared-bindings/displayio/FourWire.h b/shared-bindings/displayio/FourWire.h index a9e1bf566..3a9f66d4c 100644 --- a/shared-bindings/displayio/FourWire.h +++ b/shared-bindings/displayio/FourWire.h @@ -39,6 +39,8 @@ void common_hal_displayio_fourwire_construct(displayio_fourwire_obj_t* self, busio_spi_obj_t* spi, const mcu_pin_obj_t* command, const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset); +void common_hal_displayio_fourwire_deinit(displayio_fourwire_obj_t* self); + bool common_hal_displayio_fourwire_begin_transaction(mp_obj_t self); void common_hal_displayio_fourwire_send(mp_obj_t self, bool command, uint8_t *data, uint32_t data_length); diff --git a/shared-bindings/displayio/ParallelBus.h b/shared-bindings/displayio/ParallelBus.h index f1d1656b1..c73934838 100644 --- a/shared-bindings/displayio/ParallelBus.h +++ b/shared-bindings/displayio/ParallelBus.h @@ -38,6 +38,8 @@ void common_hal_displayio_parallelbus_construct(displayio_parallelbus_obj_t* sel const mcu_pin_obj_t* data0, const mcu_pin_obj_t* command, const mcu_pin_obj_t* chip_select, const mcu_pin_obj_t* reset, const mcu_pin_obj_t* write); +void common_hal_displayio_parallelbus_deinit(displayio_parallelbus_obj_t* self); + bool common_hal_displayio_parallelbus_begin_transaction(mp_obj_t self); void common_hal_displayio_parallelbus_send(mp_obj_t self, bool command, uint8_t *data, uint32_t data_length); diff --git a/shared-bindings/displayio/__init__.c b/shared-bindings/displayio/__init__.c index d485d8095..66cf4d63d 100644 --- a/shared-bindings/displayio/__init__.c +++ b/shared-bindings/displayio/__init__.c @@ -32,6 +32,7 @@ #include "shared-bindings/displayio/__init__.h" #include "shared-bindings/displayio/Bitmap.h" #include "shared-bindings/displayio/ColorConverter.h" +#include "shared-bindings/displayio/Display.h" #include "shared-bindings/displayio/FourWire.h" #include "shared-bindings/displayio/Group.h" #include "shared-bindings/displayio/OnDiskBitmap.h" @@ -61,6 +62,7 @@ //| //| Bitmap //| ColorConverter +//| Display //| FourWire //| Group //| OnDiskBitmap @@ -71,10 +73,22 @@ //| All libraries change hardware state but are never deinit //| + +//| .. method:: release_displays() +//| +//| Releases any actively used displays so theis pins can be used again. +//| +STATIC mp_obj_t displayio_release_displays(void) { + common_hal_displayio_release_displays(); + return mp_const_none; +} +MP_DEFINE_CONST_FUN_OBJ_0(displayio_release_displays_obj, displayio_release_displays); + STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_displayio) }, { MP_ROM_QSTR(MP_QSTR_Bitmap), MP_ROM_PTR(&displayio_bitmap_type) }, { MP_ROM_QSTR(MP_QSTR_ColorConverter), MP_ROM_PTR(&displayio_colorconverter_type) }, + { MP_ROM_QSTR(MP_QSTR_Display), MP_ROM_PTR(&displayio_display_type) }, { MP_ROM_QSTR(MP_QSTR_Group), MP_ROM_PTR(&displayio_group_type) }, { MP_ROM_QSTR(MP_QSTR_OnDiskBitmap), MP_ROM_PTR(&displayio_ondiskbitmap_type) }, { MP_ROM_QSTR(MP_QSTR_Palette), MP_ROM_PTR(&displayio_palette_type) }, @@ -82,6 +96,8 @@ STATIC const mp_rom_map_elem_t displayio_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR_Sprite), MP_ROM_PTR(&displayio_sprite_type) }, { MP_ROM_QSTR(MP_QSTR_FourWire), MP_ROM_PTR(&displayio_fourwire_type) }, + + { MP_ROM_QSTR(MP_QSTR_release_displays), MP_ROM_PTR(&displayio_release_displays_obj) }, }; STATIC MP_DEFINE_CONST_DICT(displayio_module_globals, displayio_module_globals_table); diff --git a/shared-bindings/displayio/__init__.h b/shared-bindings/displayio/__init__.h index a6663bf57..427ddb47d 100644 --- a/shared-bindings/displayio/__init__.h +++ b/shared-bindings/displayio/__init__.h @@ -27,8 +27,6 @@ #ifndef MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H #define MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H -#include "py/obj.h" - -// Nothing now. +void common_hal_displayio_release_displays(void); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index b528c3289..48194f63f 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -1,68 +1,190 @@ +#include <string.h> #include "shared-module/displayio/__init__.h" +#include "shared-bindings/displayio/Bitmap.h" #include "shared-bindings/displayio/Display.h" +#include "shared-bindings/displayio/Group.h" +#include "shared-bindings/displayio/Palette.h" +#include "shared-bindings/displayio/Sprite.h" -primary_display_t primary_display; +primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; -void displayio_refresh_display(void) { - displayio_display_obj_t* display = &primary_display.display; +void displayio_refresh_displays(void) { + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].display.base.type == NULL) { + continue; + } + displayio_display_obj_t* display = &displays[i].display; - if (!displayio_display_frame_queued(display)) { - return; - } - if (displayio_display_refresh_queued(display)) { - PORT->Group[1].DIRSET.reg = 1 << 22; - - // We compute the pixels - uint16_t x0 = 0; - uint16_t y0 = 0; - uint16_t x1 = display->width; - uint16_t y1 = display->height; - size_t index = 0; - //size_t row_size = (x1 - x0); - uint16_t buffer_size = 256; - uint32_t buffer[buffer_size / 2]; - displayio_display_start_region_update(display, x0, y0, x1, y1); - for (uint16_t y = y0; y < y1; ++y) { - for (uint16_t x = x0; x < x1; ++x) { - uint16_t* pixel = &(((uint16_t*)buffer)[index]); - *pixel = 0; - - PORT->Group[1].OUTTGL.reg = 1 << 22; - - //if (index == 0) { - if (display->current_group != NULL) { - displayio_group_get_pixel(display->current_group, x, y, pixel); - } - // } else { - // *pixel = (((uint16_t*)buffer)[0]); - // } + if (!displayio_display_frame_queued(display)) { + return; + } + if (displayio_display_refresh_queued(display)) { + PORT->Group[1].DIRSET.reg = 1 << 22; + + // We compute the pixels + uint16_t x0 = 0; + uint16_t y0 = 0; + uint16_t x1 = display->width; + uint16_t y1 = display->height; + size_t index = 0; + //size_t row_size = (x1 - x0); + uint16_t buffer_size = 256; + uint32_t buffer[buffer_size / 2]; + displayio_display_start_region_update(display, x0, y0, x1, y1); + for (uint16_t y = y0; y < y1; ++y) { + for (uint16_t x = x0; x < x1; ++x) { + uint16_t* pixel = &(((uint16_t*)buffer)[index]); + *pixel = 0; + + PORT->Group[1].OUTTGL.reg = 1 << 22; + + //if (index == 0) { + if (display->current_group != NULL) { + displayio_group_get_pixel(display->current_group, x, y, pixel); + } + // } else { + // *pixel = (((uint16_t*)buffer)[0]); + // } - PORT->Group[1].OUTTGL.reg = 1 << 22; + PORT->Group[1].OUTTGL.reg = 1 << 22; - index += 1; - // The buffer is full, send it. - if (index >= buffer_size) { - if (!displayio_display_send_pixels(display, buffer, buffer_size / 2)) { - displayio_display_finish_region_update(display); - return; + index += 1; + // The buffer is full, send it. + if (index >= buffer_size) { + if (!displayio_display_send_pixels(display, buffer, buffer_size / 2)) { + displayio_display_finish_region_update(display); + return; + } + index = 0; } - index = 0; } } - } - // Send the remaining data. - if (index && !displayio_display_send_pixels(display, buffer, index * 2)) { + // Send the remaining data. + if (index && !displayio_display_send_pixels(display, buffer, index * 2)) { + displayio_display_finish_region_update(display); + return; + } displayio_display_finish_region_update(display); - return; } - displayio_display_finish_region_update(display); + displayio_display_finish_refresh(display); } - displayio_display_finish_refresh(display); } -void reset_primary_display(void) { - common_hal_displayio_display_show(&primary_display.display, NULL); +uint32_t blinka_bitmap_data[32] = { + 0x00000011, 0x11000000, + 0x00000111, 0x53100000, + 0x00000111, 0x56110000, + 0x00000111, 0x11140000, + 0x00000111, 0x20002000, + 0x00000011, 0x13000000, + 0x00000001, 0x11200000, + 0x00000000, 0x11330000, + 0x00000000, 0x01122000, + 0x00001111, 0x44133000, + 0x00032323, 0x24112200, + 0x00111114, 0x44113300, + 0x00323232, 0x34112200, + 0x11111144, 0x44443300, + 0x11111111, 0x11144401, + 0x23232323, 0x21111110 +}; + +displayio_bitmap_t blinka_bitmap = { + .base = {.type = &displayio_bitmap_type }, + .width = 16, + .height = 16, + .data = blinka_bitmap_data, + .stride = 2, + .bits_per_value = 4, + .x_shift = 3, + .x_mask = 0x7, + .bitmask = 0xf +}; + +uint32_t blinka_transparency[1] = {0x80000000}; +uint32_t blinka_colors[8] = {0x1e910000, 0x72dc722b, 0xffffb05a, 0x00000000, + 0x80000000, 0x00000000, 0x00000000, 0x00000000}; + +displayio_palette_t blinka_palette = { + .base = {.type = &displayio_palette_type }, + .opaque = blinka_transparency, + .colors = blinka_colors, + .color_count = 16, + .needs_refresh = false +}; + +displayio_sprite_t blinka_sprite = { + .base = {.type = &displayio_sprite_type }, + .bitmap = &blinka_bitmap, + .pixel_shader = &blinka_palette, + .x = 0, + .y = 0, + .width = 16, + .height = 16, + .needs_refresh = false +}; + +mp_obj_t splash_children[1] = { + &blinka_sprite, +}; + +displayio_group_t splash = { + .base = {.type = &displayio_group_type }, + .x = 0, + .y = 0, + .size = 1, + .max_size = 1, + .children = splash_children, + .needs_refresh = true +}; + +void reset_displays(void) { + // The SPI buses used by FourWires may be allocated on the heap so we need to move them inline. + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].fourwire_bus.base.type != &displayio_fourwire_type) { + continue; + } + displayio_fourwire_obj_t* fourwire = &displays[i].fourwire_bus; + if (((uint32_t) fourwire->bus) < ((uint32_t) &displays) || + ((uint32_t) fourwire->bus) > ((uint32_t) &displays + CIRCUITPY_DISPLAY_LIMIT)) { + busio_spi_obj_t* original_spi = fourwire->bus; + memcpy(&fourwire->inline_bus, original_spi, sizeof(busio_spi_obj_t)); + fourwire->bus = &fourwire->inline_bus; + // Check for other displays that use the same spi bus and swap them too. + for (uint8_t j = i + 1; j < CIRCUITPY_DISPLAY_LIMIT; j++) { + if (displays[i].fourwire_bus.bus == original_spi) { + displays[i].fourwire_bus.bus = &fourwire->inline_bus; + } + } + } + } + + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + if (displays[i].display.base.type == NULL) { + continue; + } + displayio_display_obj_t* display = &displays[i].display; + common_hal_displayio_display_show(display, &splash); + } +} + +void common_hal_displayio_release_displays(void) { + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + mp_const_obj_t bus_type = displays[i].fourwire_bus.base.type; + if (bus_type == NULL) { + continue; + } else if (bus_type == &displayio_fourwire_type) { + common_hal_displayio_fourwire_deinit(&displays[i].fourwire_bus); + } else if (bus_type == &displayio_parallelbus_type) { + //common_hal_displayio_parallelbus_deinit(&displays[i].parallel_bus); + } + displays[i].fourwire_bus.base.type = NULL; + } + for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + displays[i].display.base.type = NULL; + } + // TODO(tannewt): Clear the display datastructures and release everything used. } diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index 84db98fcc..fdabd4ec4 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -36,13 +36,12 @@ typedef struct { displayio_fourwire_obj_t fourwire_bus; displayio_parallelbus_obj_t parallel_bus; }; - mp_const_obj_t bus_type; displayio_display_obj_t display; } primary_display_t; -extern primary_display_t primary_display; +extern primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; -void displayio_refresh_display(void); -void reset_primary_display(void); +void displayio_refresh_displays(void); +void reset_displays(void); #endif // MICROPY_INCLUDED_SHARED_BINDINGS_DISPLAYIO___INIT___H |
