summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xmain.c2
-rw-r--r--ports/atmel-samd/background.c2
-rw-r--r--ports/atmel-samd/boards/grandcentral_m4_express/mpconfigboard.h2
-rw-r--r--ports/atmel-samd/boards/grandcentral_m4_express/pins.c2
-rw-r--r--ports/atmel-samd/boards/pyportal/mpconfigboard.h2
-rw-r--r--ports/atmel-samd/boards/pyportal/pins.c4
-rw-r--r--ports/atmel-samd/common-hal/busio/SPI.c13
-rw-r--r--ports/atmel-samd/common-hal/displayio/FourWire.c10
-rw-r--r--ports/atmel-samd/common-hal/displayio/FourWire.h1
-rw-r--r--ports/atmel-samd/common-hal/microcontroller/Pin.c2
-rw-r--r--shared-bindings/displayio/Display.c23
-rw-r--r--shared-bindings/displayio/FourWire.c23
-rw-r--r--shared-bindings/displayio/FourWire.h2
-rw-r--r--shared-bindings/displayio/ParallelBus.h2
-rw-r--r--shared-bindings/displayio/__init__.c16
-rw-r--r--shared-bindings/displayio/__init__.h4
-rw-r--r--shared-module/displayio/__init__.c220
-rw-r--r--shared-module/displayio/__init__.h7
18 files changed, 255 insertions, 82 deletions
diff --git a/main.c b/main.c
index d328fcaa4..02c832e67 100755
--- a/main.c
+++ b/main.c
@@ -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