From e2eb5ba09de3ad346ef90814a2cbaa62e95a12bb Mon Sep 17 00:00:00 2001 From: RetiredWizard <github@retiredwizard.com> Date: Thu, 20 Mar 2025 21:34:08 -0400 Subject: [PATCH 01/14] Set CIRCUITPY_DISPLAY_LIMIT in settings.toml --- main.c | 5 ++ shared-module/board/__init__.c | 16 ++++- shared-module/displayio/__init__.c | 59 ++++++++++++------- shared-module/displayio/__init__.h | 7 ++- shared-module/epaperdisplay/EPaperDisplay.c | 12 +++- supervisor/shared/web_workflow/web_workflow.c | 15 +++-- 6 files changed, 84 insertions(+), 30 deletions(-) diff --git a/main.c b/main.c index c9c7acb11f7b..60844813fa60 100644 --- a/main.c +++ b/main.c @@ -1057,6 +1057,11 @@ int __attribute__((used)) main(void) { reset_devices(); reset_board(); + #if CIRCUITPY_DISPLAYIO + // If number of displays has been overriden in settings.toml allocate memory and dynamic memory + malloc_display_memory(); + #endif + // displays init after filesystem, since they could share the flash SPI board_init(); diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index 96735c8dbaa4..3ccd24e36d1e 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -10,6 +10,10 @@ #include "mpconfigboard.h" #include "py/runtime.h" +#if CIRCUITPY_OS_GETENV +#include "shared-module/os/__init__.h" +#endif + #if CIRCUITPY_BUSIO #include "shared-bindings/busio/I2C.h" #include "shared-bindings/busio/SPI.h" @@ -172,11 +176,19 @@ mp_obj_t common_hal_board_create_uart(const mp_int_t instance) { #endif void reset_board_buses(void) { + #if CIRCUITPY_BOARD_I2C || CIRCUITPY_BOARD_SPI + mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT; + + #if CIRCUITPY_OS_GETENV + (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays); + #endif + #endif + #if CIRCUITPY_BOARD_I2C for (uint8_t instance = 0; instance < CIRCUITPY_BOARD_I2C; instance++) { bool display_using_i2c = false; #if CIRCUITPY_I2CDISPLAYBUS - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + for (uint8_t i = 0; i < max_num_displays; i++) { if (display_buses[i].bus_base.type == &i2cdisplaybus_i2cdisplaybus_type && display_buses[i].i2cdisplay_bus.bus == &i2c_obj[instance]) { display_using_i2c = true; break; @@ -197,7 +209,7 @@ void reset_board_buses(void) { for (uint8_t instance = 0; instance < CIRCUITPY_BOARD_SPI; instance++) { bool display_using_spi = false; #if CIRCUITPY_FOURWIRE || CIRCUITPY_SHARPDISPLAY || CIRCUITPY_AURORA_EPAPER - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + for (uint8_t i = 0; i < max_num_displays; i++) { mp_const_obj_t bus_type = display_buses[i].bus_base.type; #if CIRCUITPY_FOURWIRE if (bus_type == &fourwire_fourwire_type && display_buses[i].fourwire_bus.bus == &spi_obj[instance]) { diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 4b467b75589d..f3e845ea973b 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -22,6 +22,10 @@ #include "py/mpconfig.h" +#if CIRCUITPY_OS_GETENV +#include "shared-module/os/__init__.h" +#endif + #if CIRCUITPY_BUSDISPLAY #include "shared-bindings/busdisplay/BusDisplay.h" #endif @@ -46,9 +50,12 @@ // The default indicates no primary display static int primary_display_number = -1; +static int max_num_displays = CIRCUITPY_DISPLAY_LIMIT; -primary_display_bus_t display_buses[CIRCUITPY_DISPLAY_LIMIT]; -primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; +primary_display_bus_t display_busesx[CIRCUITPY_DISPLAY_LIMIT]; +primary_display_t displaysx[CIRCUITPY_DISPLAY_LIMIT]; +primary_display_bus_t *display_buses = &display_busesx[0]; +primary_display_t *displays = &displaysx[0]; displayio_buffer_transform_t null_transform = { .x = 0, @@ -65,7 +72,7 @@ displayio_buffer_transform_t null_transform = { #if CIRCUITPY_RGBMATRIX || CIRCUITPY_IS31FL3741 || CIRCUITPY_VIDEOCORE || CIRCUITPY_PICODVI static bool any_display_uses_this_framebuffer(mp_obj_base_t *obj) { - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + for (uint8_t i = 0; i < max_num_displays; i++) { if (displays[i].display_base.type == &framebufferio_framebufferdisplay_type) { framebufferio_framebufferdisplay_obj_t *display = &displays[i].framebuffer_display; if (display->framebuffer == obj) { @@ -87,7 +94,7 @@ void displayio_background(void) { return; } - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + for (uint8_t i = 0; i < max_num_displays; i++) { mp_const_obj_t display_type = displays[i].display_base.type; if (display_type == NULL || display_type == &mp_type_NoneType) { // Skip null display. @@ -117,7 +124,7 @@ static void common_hal_displayio_release_displays_impl(bool keep_primary) { if (!keep_primary) { primary_display_number = -1; } - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + for (uint8_t i = 0; i < max_num_displays; i++) { if (i == primary_display_number) { continue; } @@ -139,7 +146,7 @@ static void common_hal_displayio_release_displays_impl(bool keep_primary) { } displays[i].display_base.type = &mp_type_NoneType; } - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + for (uint8_t i = 0; i < max_num_displays; i++) { mp_const_obj_t bus_type = display_buses[i].bus_base.type; if (bus_type == NULL || bus_type == &mp_type_NoneType) { continue; @@ -190,12 +197,24 @@ void common_hal_displayio_release_displays(void) { common_hal_displayio_release_displays_impl(false); } +void malloc_display_memory(void) { + #if CIRCUITPY_OS_GETENV + (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays); + if (max_num_displays > CIRCUITPY_DISPLAY_LIMIT) { + display_buses = (primary_display_bus_t*)port_malloc(sizeof(primary_display_bus_t) * max_num_displays, false); + displays = (primary_display_t*)port_malloc(sizeof(primary_display_t) * max_num_displays, false); + memcpy(display_buses, &display_busesx[0], sizeof(primary_display_bus_t) * max_num_displays); + memcpy(displays, &displaysx[0], sizeof(primary_display_t) * max_num_displays); + } + #endif +} + void reset_displays(void) { // In CircuitPython 10, release secondary displays before doing anything else: // common_hal_displayio_release_displays_impl(true); // 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++) { + for (uint8_t i = 0; i < max_num_displays; i++) { mp_const_obj_t display_bus_type = display_buses[i].bus_base.type; if (display_bus_type == NULL || display_bus_type == &mp_type_NoneType) { continue; @@ -203,7 +222,7 @@ void reset_displays(void) { } else if (display_bus_type == &fourwire_fourwire_type) { fourwire_fourwire_obj_t *fourwire = &display_buses[i].fourwire_bus; if (((size_t)fourwire->bus) < ((size_t)&display_buses) || - ((size_t)fourwire->bus) > ((size_t)&display_buses + CIRCUITPY_DISPLAY_LIMIT * sizeof(primary_display_bus_t))) { + ((size_t)fourwire->bus) > ((size_t)&display_buses + max_num_displays * sizeof(primary_display_bus_t))) { busio_spi_obj_t *original_spi = fourwire->bus; #if CIRCUITPY_BOARD_SPI // We don't need to move original_spi if it is a board.SPI object because it is @@ -221,7 +240,7 @@ void reset_displays(void) { memcpy(&fourwire->inline_bus, original_spi, sizeof(busio_spi_obj_t)); fourwire->bus = &fourwire->inline_bus; // Check for other display buses that use the same spi bus and swap them too. - for (uint8_t j = i + 1; j < CIRCUITPY_DISPLAY_LIMIT; j++) { + for (uint8_t j = i + 1; j < max_num_displays; j++) { if (display_buses[j].fourwire_bus.base.type == &fourwire_fourwire_type && display_buses[j].fourwire_bus.bus == original_spi) { display_buses[j].fourwire_bus.bus = &fourwire->inline_bus; @@ -234,7 +253,7 @@ void reset_displays(void) { i2cdisplaybus_i2cdisplaybus_obj_t *i2c = &display_buses[i].i2cdisplay_bus; // Check to see if we need to inline the I2C bus. if (((size_t)i2c->bus) < ((size_t)&display_buses) || - ((size_t)i2c->bus) > ((size_t)&display_buses + CIRCUITPY_DISPLAY_LIMIT * sizeof(primary_display_bus_t))) { + ((size_t)i2c->bus) > ((size_t)&display_buses + max_num_displays * sizeof(primary_display_bus_t))) { busio_i2c_obj_t *original_i2c = i2c->bus; #if CIRCUITPY_BOARD_I2C // We don't need to move original_i2c if it is a board.I2C object because it is @@ -247,7 +266,7 @@ void reset_displays(void) { memcpy(&i2c->inline_bus, original_i2c, sizeof(busio_i2c_obj_t)); i2c->bus = &i2c->inline_bus; // Check for other displays that use the same i2c bus and swap them too. - for (uint8_t j = i + 1; j < CIRCUITPY_DISPLAY_LIMIT; j++) { + for (uint8_t j = i + 1; j < max_num_displays; j++) { if (display_buses[j].i2cdisplay_bus.base.type == &i2cdisplaybus_i2cdisplaybus_type && display_buses[j].i2cdisplay_bus.bus == original_i2c) { display_buses[j].i2cdisplay_bus.bus = &i2c->inline_bus; @@ -271,7 +290,7 @@ void reset_displays(void) { is31fl3741_framebuffer_obj_t *is31fb = &display_buses[i].is31fl3741; if (((uint32_t)is31fb->is31fl3741->i2c) < ((uint32_t)&display_buses) || - ((uint32_t)is31fb->is31fl3741->i2c) > ((uint32_t)&display_buses + CIRCUITPY_DISPLAY_LIMIT)) { + ((uint32_t)is31fb->is31fl3741->i2c) > ((uint32_t)&display_buses + max_num_displays)) { #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 @@ -334,7 +353,7 @@ void reset_displays(void) { } } - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + for (uint8_t i = 0; i < max_num_displays; i++) { // Reset the displayed group. Only the first will get the terminal but // that's ok. mp_const_obj_t display_type = displays[i].display_base.type; @@ -358,7 +377,7 @@ void reset_displays(void) { } void displayio_gc_collect(void) { - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + for (uint8_t i = 0; i < max_num_displays; i++) { mp_const_obj_t display_bus_type = display_buses[i].bus_base.type; if (display_bus_type == NULL || display_bus_type == &mp_type_NoneType) { continue; @@ -385,7 +404,7 @@ void displayio_gc_collect(void) { #endif } - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + for (uint8_t i = 0; i < max_num_displays; i++) { mp_const_obj_t display_type = displays[i].display_base.type; if (display_type == NULL || display_type == &mp_type_NoneType) { continue; @@ -413,7 +432,7 @@ static bool is_display_active(mp_obj_base_t *display_maybe) { } primary_display_t *allocate_display(void) { - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + for (uint8_t i = 0; i < max_num_displays; i++) { if (!is_display_active(&displays[i].display_base)) { // Clear this memory so it is in a known state before init. memset(&displays[i], 0, sizeof(displays[i])); @@ -434,7 +453,7 @@ primary_display_t *allocate_display_or_raise(void) { } primary_display_bus_t *allocate_display_bus(void) { - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + for (uint8_t i = 0; i < max_num_displays; i++) { mp_const_obj_t display_bus_type = display_buses[i].bus_base.type; if (display_bus_type == NULL || display_bus_type == &mp_type_NoneType) { // Clear this memory so it is in a known state before init. @@ -455,7 +474,7 @@ primary_display_bus_t *allocate_display_bus_or_raise(void) { } mp_obj_t common_hal_displayio_get_primary_display(void) { - if (primary_display_number == -1 || primary_display_number >= CIRCUITPY_DISPLAY_LIMIT) { + if (primary_display_number == -1 || primary_display_number >= max_num_displays) { return mp_const_none; } mp_obj_base_t *primary_display = &displays[primary_display_number].display_base; @@ -470,7 +489,7 @@ void common_hal_displayio_set_primary_display(mp_obj_t new_primary_display) { primary_display_number = -1; return; } - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + for (uint8_t i = 0; i < max_num_displays; i++) { mp_obj_t display = MP_OBJ_FROM_PTR(&displays[i]); if (new_primary_display == display && is_display_active(display)) { primary_display_number = i; @@ -485,7 +504,7 @@ void common_hal_displayio_auto_primary_display(void) { if (primary_display_number != -1) { return; } - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + for (uint8_t i = 0; i < max_num_displays; i++) { if (is_display_active(&displays[i].display_base)) { primary_display_number = i; return; diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index 29b8c64c9724..c34d8ea6e960 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -99,13 +99,16 @@ typedef struct { }; } primary_display_t; -extern primary_display_bus_t display_buses[CIRCUITPY_DISPLAY_LIMIT]; -extern primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; +extern primary_display_bus_t display_busesx[]; +extern primary_display_t displaysx[]; +extern primary_display_bus_t *display_buses; +extern primary_display_t *displays; extern displayio_group_t circuitpython_splash; void displayio_background(void); void reset_displays(void); +void malloc_display_memory(void); void displayio_gc_collect(void); primary_display_t *allocate_display(void); diff --git a/shared-module/epaperdisplay/EPaperDisplay.c b/shared-module/epaperdisplay/EPaperDisplay.c index 14fbc3341b5f..41c1695dbca6 100644 --- a/shared-module/epaperdisplay/EPaperDisplay.c +++ b/shared-module/epaperdisplay/EPaperDisplay.c @@ -20,6 +20,10 @@ #include "supervisor/usb.h" #endif +#if CIRCUITPY_OS_GETENV +#include "shared-module/os/__init__.h" +#endif + #include <stdint.h> #include <string.h> @@ -501,7 +505,13 @@ void epaperdisplay_epaperdisplay_collect_ptrs(epaperdisplay_epaperdisplay_obj_t } size_t maybe_refresh_epaperdisplay(void) { - for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT; + + #if CIRCUITPY_OS_GETENV + (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays); + #endif + + for (uint8_t i = 0; i < max_num_displays; i++) { if (displays[i].epaper_display.base.type != &epaperdisplay_epaperdisplay_type || displays[i].epaper_display.core.current_group != &circuitpython_splash) { // Skip regular displays and those not showing the splash. diff --git a/supervisor/shared/web_workflow/web_workflow.c b/supervisor/shared/web_workflow/web_workflow.c index eea11bd5fb4a..584b4741e753 100644 --- a/supervisor/shared/web_workflow/web_workflow.c +++ b/supervisor/shared/web_workflow/web_workflow.c @@ -1554,24 +1554,29 @@ static void _process_request(socketpool_socket_obj_t *socket, _request *request) } static bool supervisor_filesystem_access_could_block(void) { + bool could_block = false; #if CIRCUITPY_FOURWIRE mp_vfs_mount_t *vfs = MP_STATE_VM(vfs_mount_table); if (!vfs->next) { // Assume that the CIRCUITPY root is not sharing a SPI bus with the display SPI bus return false; } - // Check display 0 to see if it's on a fourwire (SPI) bus. If it is, blocking is possible - // in theory other displays could block but also in reality there's generally 0 or 1 displays - for (size_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) { + + mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT; + #if CIRCUITPY_OS_GETENV + (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays); + #endif + // Check displays to see if it's on a fourwire (SPI) bus. If it is, blocking is possible + for (size_t i = 0; i < max_num_displays; i++) { if (display_buses[i].bus_base.type != &fourwire_fourwire_type) { continue; } if (!common_hal_fourwire_fourwire_bus_free(MP_OBJ_FROM_PTR(&display_buses[i].bus_base))) { - return true; + could_block = true; } } #endif - return false; + return could_block; } void supervisor_web_workflow_background(void *data) { From d6a55bbec47af02630f31fb7baaaa8fdc4c9e339 Mon Sep 17 00:00:00 2001 From: RetiredWizard <github@retiredwizard.com> Date: Thu, 20 Mar 2025 21:51:11 -0400 Subject: [PATCH 02/14] Document new parameter + pre-commit --- docs/environment.rst | 24 ++++++++++++++++++++++++ main.c | 2 +- shared-module/displayio/__init__.c | 6 +++--- 3 files changed, 28 insertions(+), 4 deletions(-) diff --git a/docs/environment.rst b/docs/environment.rst index 82d7e8790bcd..daa726c48f3d 100644 --- a/docs/environment.rst +++ b/docs/environment.rst @@ -190,3 +190,27 @@ flag has been set to 0. Currently this is primarily boards with limited flash in of the Atmel_samd boards based on the SAMD21/M0 microprocessor. `boards that the terminalio core module is available on <https://docs.circuitpython.org/en/latest/shared-bindings/terminalio/>`_ + +CIRCUITPY_DISPLAY_LIMIT +~~~~~~~~~~~~~~~~~~~~~~~ +Set the maximum supported number of displayio displays. This value overrides the +CIRCUITPY_DISPLAY_LIMIT compile-time flag defined in mpconfigport.h. +It specifies the maximum number of active display objects that can be supported simultaneously +on a CircuitPython board. This setting is used to manage memory and resource allocation for +display handling. + +By default, the value of CIRCUITPY_DISPLAY_LIMIT is set to 1 for most boards, meaning only +one display can be active at a time. Users can modify this value by adding a settings.toml entry +to support additional displays, depending on the hardware capabilities and available resources. + +The value of CIRCUITPY_DISPLAY_LIMIT should be set to a value that is supported by the +hardware and does not exceed the available memory and resources on the board. + +*** Note: Setting CIRCUITPY_DISPLAY_LIMIT to a value greater than 1 should be considered an +ALPHA feature and may result in unexpected behavior or crashes. *** + +Example: Set the maximum supported number of displayio displays to 2: + +.. code-block:: + + CIRCUITPY_DISPLAY_LIMIT=2 diff --git a/main.c b/main.c index 60844813fa60..74654e00d550 100644 --- a/main.c +++ b/main.c @@ -1058,7 +1058,7 @@ int __attribute__((used)) main(void) { reset_board(); #if CIRCUITPY_DISPLAYIO - // If number of displays has been overriden in settings.toml allocate memory and dynamic memory + // If number of displays has been overridden in settings.toml allocate memory and dynamic memory malloc_display_memory(); #endif diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index f3e845ea973b..ebe89ee0bfbd 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -201,10 +201,10 @@ void malloc_display_memory(void) { #if CIRCUITPY_OS_GETENV (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays); if (max_num_displays > CIRCUITPY_DISPLAY_LIMIT) { - display_buses = (primary_display_bus_t*)port_malloc(sizeof(primary_display_bus_t) * max_num_displays, false); - displays = (primary_display_t*)port_malloc(sizeof(primary_display_t) * max_num_displays, false); + display_buses = (primary_display_bus_t *)port_malloc(sizeof(primary_display_bus_t) * max_num_displays, false); + displays = (primary_display_t *)port_malloc(sizeof(primary_display_t) * max_num_displays, false); memcpy(display_buses, &display_busesx[0], sizeof(primary_display_bus_t) * max_num_displays); - memcpy(displays, &displaysx[0], sizeof(primary_display_t) * max_num_displays); + memcpy(displays, &displaysx[0], sizeof(primary_display_t) * max_num_displays); } #endif } From 088cf955b83cdeb0ae7def528df39026bdae6404 Mon Sep 17 00:00:00 2001 From: RetiredWizard <github@retiredwizard.com> Date: Thu, 20 Mar 2025 22:35:05 -0400 Subject: [PATCH 03/14] fix boar/__init__.c, move malloc slightly earlier --- docs/environment.rst | 5 ++--- main.c | 11 ++++++----- shared-module/board/__init__.c | 2 +- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/docs/environment.rst b/docs/environment.rst index daa726c48f3d..77eb4b5b6d18 100644 --- a/docs/environment.rst +++ b/docs/environment.rst @@ -196,12 +196,11 @@ CIRCUITPY_DISPLAY_LIMIT Set the maximum supported number of displayio displays. This value overrides the CIRCUITPY_DISPLAY_LIMIT compile-time flag defined in mpconfigport.h. It specifies the maximum number of active display objects that can be supported simultaneously -on a CircuitPython board. This setting is used to manage memory and resource allocation for -display handling. +on a CircuitPython board. By default, the value of CIRCUITPY_DISPLAY_LIMIT is set to 1 for most boards, meaning only one display can be active at a time. Users can modify this value by adding a settings.toml entry -to support additional displays, depending on the hardware capabilities and available resources. +to support additional displays. The value of CIRCUITPY_DISPLAY_LIMIT should be set to a value that is supported by the hardware and does not exceed the available memory and resources on the board. diff --git a/main.c b/main.c index 74654e00d550..16a16e653a47 100644 --- a/main.c +++ b/main.c @@ -1051,17 +1051,18 @@ int __attribute__((used)) main(void) { alarm_reset(); #endif + #if CIRCUITPY_DISPLAYIO + // If number of displays has been overridden in settings.toml allocate memory and + // move existing displays + malloc_display_memory(); + #endif + // Reset everything and prep MicroPython to run boot.py. reset_port(); // Port-independent devices, like CIRCUITPY_BLEIO_HCI. reset_devices(); reset_board(); - #if CIRCUITPY_DISPLAYIO - // If number of displays has been overridden in settings.toml allocate memory and dynamic memory - malloc_display_memory(); - #endif - // displays init after filesystem, since they could share the flash SPI board_init(); diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index 3ccd24e36d1e..4bf1521b7f31 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -185,7 +185,7 @@ void reset_board_buses(void) { #endif #if CIRCUITPY_BOARD_I2C - for (uint8_t instance = 0; instance < CIRCUITPY_BOARD_I2C; instance++) { + for (uint8_t instance = 0; instance < max_num_displays; instance++) { bool display_using_i2c = false; #if CIRCUITPY_I2CDISPLAYBUS for (uint8_t i = 0; i < max_num_displays; i++) { From 9b6219fca58b30b7e2a1764c7dcff094bc483cfb Mon Sep 17 00:00:00 2001 From: RetiredWizard <github@retiredwizard.com> Date: Thu, 20 Mar 2025 22:43:39 -0400 Subject: [PATCH 04/14] board/__init__: only declare max_num_displays when neeeded --- shared-module/board/__init__.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index 4bf1521b7f31..2488a492fb47 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -176,7 +176,7 @@ mp_obj_t common_hal_board_create_uart(const mp_int_t instance) { #endif void reset_board_buses(void) { - #if CIRCUITPY_BOARD_I2C || CIRCUITPY_BOARD_SPI + #if CIRCUITPY_BOARD_I2C || (CIRCUITPY_BOARD_SPI && (CIRCUITPY_FOURWIRE || CIRCUITPY_SHARPDISPLAY || CIRCUITPY_AURORA_EPAPER)) mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT; #if CIRCUITPY_OS_GETENV From ec349f631df22d5d5328fbe6a6009f7397aae8ca Mon Sep 17 00:00:00 2001 From: RetiredWizard <github@retiredwizard.com> Date: Fri, 21 Mar 2025 00:08:45 -0400 Subject: [PATCH 05/14] memcpy should only copy for length of compile time struct --- shared-module/displayio/__init__.c | 4 ++-- shared-module/displayio/__init__.h | 4 ++-- supervisor/shared/web_workflow/web_workflow.c | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index ebe89ee0bfbd..41b17042834e 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -203,8 +203,8 @@ void malloc_display_memory(void) { if (max_num_displays > CIRCUITPY_DISPLAY_LIMIT) { display_buses = (primary_display_bus_t *)port_malloc(sizeof(primary_display_bus_t) * max_num_displays, false); displays = (primary_display_t *)port_malloc(sizeof(primary_display_t) * max_num_displays, false); - memcpy(display_buses, &display_busesx[0], sizeof(primary_display_bus_t) * max_num_displays); - memcpy(displays, &displaysx[0], sizeof(primary_display_t) * max_num_displays); + memcpy(display_buses, &display_busesx[0], sizeof(primary_display_bus_t) * CIRCUITPY_DISPLAY_LIMIT); + memcpy(displays, &displaysx[0], sizeof(primary_display_t) * CIRCUITPY_DISPLAY_LIMIT); } #endif } diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index c34d8ea6e960..ccdc2887eda6 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -99,8 +99,8 @@ typedef struct { }; } primary_display_t; -extern primary_display_bus_t display_busesx[]; -extern primary_display_t displaysx[]; +extern primary_display_bus_t display_busesx[CIRCUITPY_DISPLAY_LIMIT]; +extern primary_display_t displaysx[CIRCUITPY_DISPLAY_LIMIT]; extern primary_display_bus_t *display_buses; extern primary_display_t *displays; diff --git a/supervisor/shared/web_workflow/web_workflow.c b/supervisor/shared/web_workflow/web_workflow.c index 584b4741e753..ea7e005b5918 100644 --- a/supervisor/shared/web_workflow/web_workflow.c +++ b/supervisor/shared/web_workflow/web_workflow.c @@ -1567,7 +1567,7 @@ static bool supervisor_filesystem_access_could_block(void) { (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays); #endif // Check displays to see if it's on a fourwire (SPI) bus. If it is, blocking is possible - for (size_t i = 0; i < max_num_displays; i++) { + for (mp_int_t i = 0; i < max_num_displays; i++) { if (display_buses[i].bus_base.type != &fourwire_fourwire_type) { continue; } From 17b1ce1619710f92935684fe8d1a9e84018e7f3a Mon Sep 17 00:00:00 2001 From: RetiredWizard <github@retiredwizard.com> Date: Fri, 21 Mar 2025 01:09:52 -0400 Subject: [PATCH 06/14] initalize dynamically allocated displays --- shared-module/displayio/__init__.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 41b17042834e..76252d7a9ce1 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -205,6 +205,12 @@ void malloc_display_memory(void) { displays = (primary_display_t *)port_malloc(sizeof(primary_display_t) * max_num_displays, false); memcpy(display_buses, &display_busesx[0], sizeof(primary_display_bus_t) * CIRCUITPY_DISPLAY_LIMIT); memcpy(displays, &displaysx[0], sizeof(primary_display_t) * CIRCUITPY_DISPLAY_LIMIT); + + for (uint8_t i=CIRCUITPY_DISPLAY_LIMIT; i<max_num_displays; i++) { + memset(&displays[i], 0, sizeof(displays[i])); + display_buses[i].bus_base.type = &mp_type_NoneType; + displays[i].display_base.type = &mp_type_NoneType; + } } #endif } From 6ed0bcab1fcb31748a8166bf096ebd914afa4631 Mon Sep 17 00:00:00 2001 From: RetiredWizard <github@retiredwizard.com> Date: Fri, 21 Mar 2025 01:11:25 -0400 Subject: [PATCH 07/14] local pre-commit :( --- shared-module/displayio/__init__.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 76252d7a9ce1..77c497cb65c1 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -206,7 +206,7 @@ void malloc_display_memory(void) { memcpy(display_buses, &display_busesx[0], sizeof(primary_display_bus_t) * CIRCUITPY_DISPLAY_LIMIT); memcpy(displays, &displaysx[0], sizeof(primary_display_t) * CIRCUITPY_DISPLAY_LIMIT); - for (uint8_t i=CIRCUITPY_DISPLAY_LIMIT; i<max_num_displays; i++) { + for (uint8_t i = CIRCUITPY_DISPLAY_LIMIT; i < max_num_displays; i++) { memset(&displays[i], 0, sizeof(displays[i])); display_buses[i].bus_base.type = &mp_type_NoneType; displays[i].display_base.type = &mp_type_NoneType; From a61fac69bb110dc07719123a35e05ef909ba6b65 Mon Sep 17 00:00:00 2001 From: RetiredWizard <github@retiredwizard.com> Date: Fri, 21 Mar 2025 01:14:04 -0400 Subject: [PATCH 08/14] Initialize display_buses as well --- shared-module/displayio/__init__.c | 1 + 1 file changed, 1 insertion(+) diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index 77c497cb65c1..ae675b0791ee 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -208,6 +208,7 @@ void malloc_display_memory(void) { for (uint8_t i = CIRCUITPY_DISPLAY_LIMIT; i < max_num_displays; i++) { memset(&displays[i], 0, sizeof(displays[i])); + memset(&display_buses[i], 0, sizeof(display_buses[i])); display_buses[i].bus_base.type = &mp_type_NoneType; displays[i].display_base.type = &mp_type_NoneType; } From 437e36ed63462589d97ccd2d6cd906ef84666a5e Mon Sep 17 00:00:00 2001 From: RetiredWizard <github@retiredwizard.com> Date: Fri, 21 Mar 2025 16:53:37 -0400 Subject: [PATCH 09/14] Use compile-time arrays AND additional dynamic memory --- main.c | 2 +- shared-module/board/__init__.c | 17 +- shared-module/displayio/__init__.c | 175 +++++++++++------- shared-module/displayio/__init__.h | 12 +- shared-module/epaperdisplay/EPaperDisplay.c | 28 ++- supervisor/shared/web_workflow/web_workflow.c | 9 +- 6 files changed, 157 insertions(+), 86 deletions(-) diff --git a/main.c b/main.c index 16a16e653a47..e2587a30fd44 100644 --- a/main.c +++ b/main.c @@ -1051,7 +1051,7 @@ int __attribute__((used)) main(void) { alarm_reset(); #endif - #if CIRCUITPY_DISPLAYIO + #if CIRCUITPY_DISPLAYIO && CIRCUITPY_OS_GETENV // If number of displays has been overridden in settings.toml allocate memory and // move existing displays malloc_display_memory(); diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index 2488a492fb47..4e9eb5f9b849 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -178,6 +178,11 @@ mp_obj_t common_hal_board_create_uart(const mp_int_t instance) { void reset_board_buses(void) { #if CIRCUITPY_BOARD_I2C || (CIRCUITPY_BOARD_SPI && (CIRCUITPY_FOURWIRE || CIRCUITPY_SHARPDISPLAY || CIRCUITPY_AURORA_EPAPER)) mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT; + #if CIRCUITPY_OS_GETENV + #define DYN_DISPLAY_BUSES(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? display_buses[indx] : display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT]) + #else + #define DYN_DISPLAY_BUSES(indx) (display_buses[indx]) + #endif #if CIRCUITPY_OS_GETENV (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays); @@ -185,11 +190,11 @@ void reset_board_buses(void) { #endif #if CIRCUITPY_BOARD_I2C - for (uint8_t instance = 0; instance < max_num_displays; instance++) { + for (uint8_t instance = 0; instance < CIRCUITPY_BOARD_I2C; instance++) { bool display_using_i2c = false; #if CIRCUITPY_I2CDISPLAYBUS for (uint8_t i = 0; i < max_num_displays; i++) { - if (display_buses[i].bus_base.type == &i2cdisplaybus_i2cdisplaybus_type && display_buses[i].i2cdisplay_bus.bus == &i2c_obj[instance]) { + if (DYN_DISPLAY_BUSES(i).bus_base.type == &i2cdisplaybus_i2cdisplaybus_type && DYN_DISPLAY_BUSES(i).i2cdisplay_bus.bus == &i2c_obj[instance]) { display_using_i2c = true; break; } @@ -210,21 +215,21 @@ void reset_board_buses(void) { bool display_using_spi = false; #if CIRCUITPY_FOURWIRE || CIRCUITPY_SHARPDISPLAY || CIRCUITPY_AURORA_EPAPER for (uint8_t i = 0; i < max_num_displays; i++) { - mp_const_obj_t bus_type = display_buses[i].bus_base.type; + mp_const_obj_t bus_type = DYN_DISPLAY_BUSES(i).bus_base.type; #if CIRCUITPY_FOURWIRE - if (bus_type == &fourwire_fourwire_type && display_buses[i].fourwire_bus.bus == &spi_obj[instance]) { + if (bus_type == &fourwire_fourwire_type && DYN_DISPLAY_BUSES(i).fourwire_bus.bus == &spi_obj[instance]) { display_using_spi = true; break; } #endif #if CIRCUITPY_SHARPDISPLAY - if (bus_type == &sharpdisplay_framebuffer_type && display_buses[i].sharpdisplay.bus == &spi_obj[instance]) { + if (bus_type == &sharpdisplay_framebuffer_type && DYN_DISPLAY_BUSES(i).sharpdisplay.bus == &spi_obj[instance]) { display_using_spi = true; break; } #endif #if CIRCUITPY_AURORA_EPAPER - if (bus_type == &aurora_epaper_framebuffer_type && display_buses[i].aurora_epaper.bus == &spi_obj[instance]) { + if (bus_type == &aurora_epaper_framebuffer_type && DYN_DISPLAY_BUSES(i).aurora_epaper.bus == &spi_obj[instance]) { display_using_spi = true; break; } diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index ae675b0791ee..a17f37e0dca2 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -52,10 +52,25 @@ static int primary_display_number = -1; static int max_num_displays = CIRCUITPY_DISPLAY_LIMIT; -primary_display_bus_t display_busesx[CIRCUITPY_DISPLAY_LIMIT]; -primary_display_t displaysx[CIRCUITPY_DISPLAY_LIMIT]; -primary_display_bus_t *display_buses = &display_busesx[0]; -primary_display_t *displays = &displaysx[0]; +primary_display_bus_t display_buses[CIRCUITPY_DISPLAY_LIMIT]; +primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; +#if CIRCUITPY_OS_GETENV +primary_display_bus_t *display_buses_dyn = &display_buses[0]; +primary_display_t *displays_dyn = &displays[0]; +#define DYN_DISPLAY_BUSES(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? display_buses[indx] : display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT]) +#define DYN_DISPLAY_BUSES_ADR(indx,membr) (indx < CIRCUITPY_DISPLAY_LIMIT ? &display_buses[indx].membr : &display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT].membr) +#define DYN_DISPLAY_BUSES_ADR0(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? &display_buses[indx] : &display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT]) +#define DYN_DISPLAYS(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? displays[indx] : displays_dyn[indx - CIRCUITPY_DISPLAY_LIMIT]) +#define DYN_DISPLAYS_ADR(indx,membr) (indx < CIRCUITPY_DISPLAY_LIMIT ? &displays[indx].membr : &displays_dyn[indx - CIRCUITPY_DISPLAY_LIMIT].membr) +#define DYN_DISPLAYS_ADR0(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? &displays[indx] : &displays_dyn[indx - CIRCUITPY_DISPLAY_LIMIT]) +#else +#define DYN_DISPLAY_BUSES(indx) (display_buses[indx]) +#define DYN_DISPLAY_BUSES_ADR(indx,membr) (&display_buses[indx].membr) +#define DYN_DISPLAY_BUSES_ADR0(indx) (&display_buses[indx]) +#define DYN_DISPLAYS(indx) (displays[indx]) +#define DYN_DISPLAYS_ADR(indx,membr) (&displays[indx].membr) +#define DYN_DISPLAYS_ADR0(indx) (&displays[indx]) +#endif displayio_buffer_transform_t null_transform = { .x = 0, @@ -73,8 +88,8 @@ displayio_buffer_transform_t null_transform = { #if CIRCUITPY_RGBMATRIX || CIRCUITPY_IS31FL3741 || CIRCUITPY_VIDEOCORE || CIRCUITPY_PICODVI static bool any_display_uses_this_framebuffer(mp_obj_base_t *obj) { for (uint8_t i = 0; i < max_num_displays; i++) { - if (displays[i].display_base.type == &framebufferio_framebufferdisplay_type) { - framebufferio_framebufferdisplay_obj_t *display = &displays[i].framebuffer_display; + if (DYN_DISPLAYS(i).display_base.type == &framebufferio_framebufferdisplay_type) { + framebufferio_framebufferdisplay_obj_t *display = DYN_DISPLAYS_ADR(i,framebuffer_display); if (display->framebuffer == obj) { return true; } @@ -95,7 +110,7 @@ void displayio_background(void) { } for (uint8_t i = 0; i < max_num_displays; i++) { - mp_const_obj_t display_type = displays[i].display_base.type; + mp_const_obj_t display_type = DYN_DISPLAYS(i).display_base.type; if (display_type == NULL || display_type == &mp_type_NoneType) { // Skip null display. continue; @@ -103,15 +118,15 @@ void displayio_background(void) { if (false) { #if CIRCUITPY_BUSDISPLAY } else if (display_type == &busdisplay_busdisplay_type) { - busdisplay_busdisplay_background(&displays[i].display); + busdisplay_busdisplay_background(DYN_DISPLAYS_ADR(i,display)); #endif #if CIRCUITPY_FRAMEBUFFERIO } else if (display_type == &framebufferio_framebufferdisplay_type) { - framebufferio_framebufferdisplay_background(&displays[i].framebuffer_display); + framebufferio_framebufferdisplay_background(DYN_DISPLAYS_ADR(i,framebuffer_display)); #endif #if CIRCUITPY_EPAPERDISPLAY } else if (display_type == &epaperdisplay_epaperdisplay_type) { - epaperdisplay_epaperdisplay_background(&displays[i].epaper_display); + epaperdisplay_epaperdisplay_background(DYN_DISPLAYS_ADR(i,epaper_display)); #endif } } @@ -128,66 +143,78 @@ static void common_hal_displayio_release_displays_impl(bool keep_primary) { if (i == primary_display_number) { continue; } - mp_const_obj_t display_type = displays[i].display_base.type; + mp_const_obj_t display_type = DYN_DISPLAYS(i).display_base.type; if (display_type == NULL || display_type == &mp_type_NoneType) { continue; #if CIRCUITPY_BUSDISPLAY } else if (display_type == &busdisplay_busdisplay_type) { - release_busdisplay(&displays[i].display); + release_busdisplay(DYN_DISPLAYS_ADR(i,display)); #endif #if CIRCUITPY_EPAPERDISPLAY } else if (display_type == &epaperdisplay_epaperdisplay_type) { - release_epaperdisplay(&displays[i].epaper_display); + release_epaperdisplay(DYN_DISPLAYS_ADR(i,epaper_display)); #endif #if CIRCUITPY_FRAMEBUFFERIO } else if (display_type == &framebufferio_framebufferdisplay_type) { - release_framebufferdisplay(&displays[i].framebuffer_display); + release_framebufferdisplay(DYN_DISPLAYS_ADR(i,framebuffer_display)); + #endif + } + if (i < CIRCUITPY_DISPLAY_LIMIT) { + displays[i].display_base.type = &mp_type_NoneType; + #if CIRCUITPY_OS_GETENV + } else { + displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].display_base.type = &mp_type_NoneType; #endif } - displays[i].display_base.type = &mp_type_NoneType; } for (uint8_t i = 0; i < max_num_displays; i++) { - mp_const_obj_t bus_type = display_buses[i].bus_base.type; + mp_const_obj_t bus_type = DYN_DISPLAY_BUSES(i).bus_base.type; if (bus_type == NULL || bus_type == &mp_type_NoneType) { continue; #if CIRCUITPY_FOURWIRE } else if (bus_type == &fourwire_fourwire_type) { - common_hal_fourwire_fourwire_deinit(&display_buses[i].fourwire_bus); + common_hal_fourwire_fourwire_deinit(DYN_DISPLAY_BUSES_ADR(i,fourwire_bus)); #endif #if CIRCUITPY_I2CDISPLAYBUS } else if (bus_type == &i2cdisplaybus_i2cdisplaybus_type) { - common_hal_i2cdisplaybus_i2cdisplaybus_deinit(&display_buses[i].i2cdisplay_bus); + common_hal_i2cdisplaybus_i2cdisplaybus_deinit(DYN_DISPLAY_BUSES_ADR(i,i2cdisplay_bus)); #endif #if CIRCUITPY_DOTCLOCKFRAMEBUFFER } else if (bus_type == &dotclockframebuffer_framebuffer_type) { - common_hal_dotclockframebuffer_framebuffer_deinit(&display_buses[i].dotclock); + common_hal_dotclockframebuffer_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i,dotclock)); #endif #if CIRCUITPY_PARALLELDISPLAYBUS } else if (bus_type == ¶lleldisplaybus_parallelbus_type) { - common_hal_paralleldisplaybus_parallelbus_deinit(&display_buses[i].parallel_bus); + common_hal_paralleldisplaybus_parallelbus_deinit(DYN_DISPLAY_BUSES_ADR(i,parallel_bus)); #endif #if CIRCUITPY_RGBMATRIX } else if (bus_type == &rgbmatrix_RGBMatrix_type) { - common_hal_rgbmatrix_rgbmatrix_deinit(&display_buses[i].rgbmatrix); + common_hal_rgbmatrix_rgbmatrix_deinit(DYN_DISPLAY_BUSES_ADR(i,rgbmatrix)); #endif #if CIRCUITPY_IS31FL3741 } else if (bus_type == &is31fl3741_framebuffer_type) { - common_hal_is31fl3741_framebuffer_deinit(&display_buses[i].is31fl3741); + common_hal_is31fl3741_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i,is31fl3741)); #endif #if CIRCUITPY_SHARPDISPLAY } else if (bus_type == &sharpdisplay_framebuffer_type) { - common_hal_sharpdisplay_framebuffer_deinit(&display_buses[i].sharpdisplay); + common_hal_sharpdisplay_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i,sharpdisplay)); #endif #if CIRCUITPY_VIDEOCORE } else if (bus_type == &videocore_framebuffer_type) { - common_hal_videocore_framebuffer_deinit(&display_buses[i].videocore); + common_hal_videocore_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i,videocore)); #endif #if CIRCUITPY_PICODVI } else if (bus_type == &picodvi_framebuffer_type) { - common_hal_picodvi_framebuffer_deinit(&display_buses[i].picodvi); + common_hal_picodvi_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i,picodvi)); + #endif + } + if (i < CIRCUITPY_DISPLAY_LIMIT) { + display_buses[i].bus_base.type = &mp_type_NoneType; + #if CIRCUITPY_OS_GETENV + } else { + display_buses_dyn[i - CIRCUITPY_DISPLAY_LIMIT].bus_base.type = &mp_type_NoneType; #endif } - display_buses[i].bus_base.type = &mp_type_NoneType; } supervisor_stop_terminal(); @@ -201,16 +228,14 @@ void malloc_display_memory(void) { #if CIRCUITPY_OS_GETENV (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays); if (max_num_displays > CIRCUITPY_DISPLAY_LIMIT) { - display_buses = (primary_display_bus_t *)port_malloc(sizeof(primary_display_bus_t) * max_num_displays, false); - displays = (primary_display_t *)port_malloc(sizeof(primary_display_t) * max_num_displays, false); - memcpy(display_buses, &display_busesx[0], sizeof(primary_display_bus_t) * CIRCUITPY_DISPLAY_LIMIT); - memcpy(displays, &displaysx[0], sizeof(primary_display_t) * CIRCUITPY_DISPLAY_LIMIT); - + display_buses_dyn = (primary_display_bus_t *)port_malloc(sizeof(primary_display_bus_t) * (max_num_displays - CIRCUITPY_DISPLAY_LIMIT), false); + displays_dyn = (primary_display_t *)port_malloc(sizeof(primary_display_t) * (max_num_displays - CIRCUITPY_DISPLAY_LIMIT), false); + for (uint8_t i = CIRCUITPY_DISPLAY_LIMIT; i < max_num_displays; i++) { - memset(&displays[i], 0, sizeof(displays[i])); - memset(&display_buses[i], 0, sizeof(display_buses[i])); - display_buses[i].bus_base.type = &mp_type_NoneType; - displays[i].display_base.type = &mp_type_NoneType; + memset(&displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT], 0, sizeof(displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT])); + memset(&display_buses_dyn[i - CIRCUITPY_DISPLAY_LIMIT], 0, sizeof(display_buses_dyn[i - CIRCUITPY_DISPLAY_LIMIT])); + display_buses_dyn[i - CIRCUITPY_DISPLAY_LIMIT].bus_base.type = &mp_type_NoneType; + displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].display_base.type = &mp_type_NoneType; } } #endif @@ -222,12 +247,12 @@ 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 < max_num_displays; i++) { - mp_const_obj_t display_bus_type = display_buses[i].bus_base.type; + mp_const_obj_t display_bus_type = DYN_DISPLAY_BUSES(i).bus_base.type; if (display_bus_type == NULL || display_bus_type == &mp_type_NoneType) { continue; #if CIRCUITPY_FOURWIRE } else if (display_bus_type == &fourwire_fourwire_type) { - fourwire_fourwire_obj_t *fourwire = &display_buses[i].fourwire_bus; + fourwire_fourwire_obj_t *fourwire = DYN_DISPLAY_BUSES_ADR(i,fourwire_bus); if (((size_t)fourwire->bus) < ((size_t)&display_buses) || ((size_t)fourwire->bus) > ((size_t)&display_buses + max_num_displays * sizeof(primary_display_bus_t))) { busio_spi_obj_t *original_spi = fourwire->bus; @@ -257,7 +282,7 @@ void reset_displays(void) { #endif #if CIRCUITPY_I2CDISPLAYBUS } else if (display_bus_type == &i2cdisplaybus_i2cdisplaybus_type) { - i2cdisplaybus_i2cdisplaybus_obj_t *i2c = &display_buses[i].i2cdisplay_bus; + i2cdisplaybus_i2cdisplaybus_obj_t *i2c = DYN_DISPLAY_BUSES_ADR(i,i2cdisplay_bus); // Check to see if we need to inline the I2C bus. if (((size_t)i2c->bus) < ((size_t)&display_buses) || ((size_t)i2c->bus) > ((size_t)&display_buses + max_num_displays * sizeof(primary_display_bus_t))) { @@ -285,7 +310,7 @@ void reset_displays(void) { #endif #if CIRCUITPY_RGBMATRIX } else if (display_bus_type == &rgbmatrix_RGBMatrix_type) { - rgbmatrix_rgbmatrix_obj_t *pm = &display_buses[i].rgbmatrix; + rgbmatrix_rgbmatrix_obj_t *pm = DYN_DISPLAY_BUSES_ADR(i,rgbmatrix); if (!any_display_uses_this_framebuffer(&pm->base)) { common_hal_rgbmatrix_rgbmatrix_deinit(pm); } else { @@ -294,7 +319,7 @@ void reset_displays(void) { #endif #if CIRCUITPY_IS31FL3741 } else if (display_bus_type == &is31fl3741_framebuffer_type) { - is31fl3741_framebuffer_obj_t *is31fb = &display_buses[i].is31fl3741; + is31fl3741_framebuffer_obj_t *is31fb = DYN_DISPLAY_BUSES_ADR(i,is31fl3741); if (((uint32_t)is31fb->is31fl3741->i2c) < ((uint32_t)&display_buses) || ((uint32_t)is31fb->is31fl3741->i2c) > ((uint32_t)&display_buses + max_num_displays)) { @@ -324,12 +349,12 @@ void reset_displays(void) { #endif #if CIRCUITPY_SHARPDISPLAY } else if (display_bus_type == &sharpdisplay_framebuffer_type) { - sharpdisplay_framebuffer_obj_t *sharp = &display_buses[i].sharpdisplay; + sharpdisplay_framebuffer_obj_t *sharp = DYN_DISPLAY_BUSES_ADR(i,sharpdisplay); common_hal_sharpdisplay_framebuffer_reset(sharp); #endif #if CIRCUITPY_VIDEOCORE } else if (display_bus_type == &videocore_framebuffer_type) { - videocore_framebuffer_obj_t *vc = &display_buses[i].videocore; + videocore_framebuffer_obj_t *vc = DYN_DISPLAY_BUSES_ADR(i,videocore); if (!any_display_uses_this_framebuffer(&vc->base)) { common_hal_videocore_framebuffer_deinit(vc); } @@ -338,7 +363,7 @@ void reset_displays(void) { #endif #if CIRCUITPY_PICODVI } else if (display_bus_type == &picodvi_framebuffer_type) { - picodvi_framebuffer_obj_t *vc = &display_buses[i].picodvi; + picodvi_framebuffer_obj_t *vc = DYN_DISPLAY_BUSES_ADR(i,picodvi); if (!any_display_uses_this_framebuffer(&vc->base)) { common_hal_picodvi_framebuffer_deinit(vc); } @@ -346,13 +371,13 @@ void reset_displays(void) { #if CIRCUITPY_AURORA_EPAPER } else if (display_bus_type == &aurora_framebuffer_type) { #if CIRCUITPY_BOARD_SPI - aurora_epaper_framebuffer_obj_t *aurora = &display_buses[i].aurora_epaper; + aurora_epaper_framebuffer_obj_t *aurora = DYN_DISPLAY_BUSES_ADR(i,aurora_epaper); if (common_hal_board_is_spi(aurora->bus)) { common_hal_aurora_epaper_framebuffer_set_free_bus(false); } #endif // Set to None, gets deinit'd up by display_base - display_buses[i].bus_base.type = &mp_type_NoneType; + DYN_DISPLAY_BUSES(i).bus_base.type = &mp_type_NoneType; #endif } else { // Not an active display bus. @@ -363,21 +388,21 @@ void reset_displays(void) { for (uint8_t i = 0; i < max_num_displays; i++) { // Reset the displayed group. Only the first will get the terminal but // that's ok. - mp_const_obj_t display_type = displays[i].display_base.type; + mp_const_obj_t display_type = DYN_DISPLAYS(i).display_base.type; if (display_type == NULL || display_type == &mp_type_NoneType) { continue; #if CIRCUITPY_BUSDISPLAY } else if (display_type == &busdisplay_busdisplay_type) { - reset_busdisplay(&displays[i].display); + reset_busdisplay(DYN_DISPLAYS_ADR(i,display)); #endif #if CIRCUITPY_EPAPERDISPLAY } else if (display_type == &epaperdisplay_epaperdisplay_type) { - epaperdisplay_epaperdisplay_obj_t *display = &displays[i].epaper_display; + epaperdisplay_epaperdisplay_obj_t *display = DYN_DISPLAYS_ADR(i,epaper_display); epaperdisplay_epaperdisplay_reset(display); #endif #if CIRCUITPY_FRAMEBUFFERIO } else if (display_type == &framebufferio_framebufferdisplay_type) { - framebufferio_framebufferdisplay_reset(&displays[i].framebuffer_display); + framebufferio_framebufferdisplay_reset(DYN_DISPLAYS_ADR(i,framebuffer_display)); #endif } } @@ -385,34 +410,34 @@ void reset_displays(void) { void displayio_gc_collect(void) { for (uint8_t i = 0; i < max_num_displays; i++) { - mp_const_obj_t display_bus_type = display_buses[i].bus_base.type; + mp_const_obj_t display_bus_type = DYN_DISPLAY_BUSES(i).bus_base.type; if (display_bus_type == NULL || display_bus_type == &mp_type_NoneType) { continue; } #if CIRCUITPY_RGBMATRIX if (display_bus_type == &rgbmatrix_RGBMatrix_type) { - rgbmatrix_rgbmatrix_collect_ptrs(&display_buses[i].rgbmatrix); + rgbmatrix_rgbmatrix_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i,rgbmatrix)); } #endif #if CIRCUITPY_IS31FL3741 if (display_bus_type == &is31fl3741_framebuffer_type) { - is31fl3741_framebuffer_collect_ptrs(&display_buses[i].is31fl3741); + is31fl3741_framebuffer_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i,is31fl3741)); } #endif #if CIRCUITPY_SHARPDISPLAY if (display_bus_type == &sharpdisplay_framebuffer_type) { - common_hal_sharpdisplay_framebuffer_collect_ptrs(&display_buses[i].sharpdisplay); + common_hal_sharpdisplay_framebuffer_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i,sharpdisplay)); } #endif #if CIRCUITPY_AURORA_EPAPER if (display_bus_type == &aurora_framebuffer_type) { - common_hal_aurora_epaper_framebuffer_collect_ptrs(&display_buses[i].aurora_epaper); + common_hal_aurora_epaper_framebuffer_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i,aurora_epaper)); } #endif } for (uint8_t i = 0; i < max_num_displays; i++) { - mp_const_obj_t display_type = displays[i].display_base.type; + mp_const_obj_t display_type = DYN_DISPLAYS(i).display_base.type; if (display_type == NULL || display_type == &mp_type_NoneType) { continue; @@ -420,15 +445,15 @@ void displayio_gc_collect(void) { // but this is more precise, and is the only field that needs marking. #if CIRCUITPY_BUSDISPLAY } else if (display_type == &busdisplay_busdisplay_type) { - busdisplay_busdisplay_collect_ptrs(&displays[i].display); + busdisplay_busdisplay_collect_ptrs(DYN_DISPLAYS_ADR(i,display)); #endif #if CIRCUITPY_FRAMEBUFFERIO } else if (display_type == &framebufferio_framebufferdisplay_type) { - framebufferio_framebufferdisplay_collect_ptrs(&displays[i].framebuffer_display); + framebufferio_framebufferdisplay_collect_ptrs(DYN_DISPLAYS_ADR(i,framebuffer_display)); #endif #if CIRCUITPY_EPAPERDISPLAY } else if (display_type == &epaperdisplay_epaperdisplay_type) { - epaperdisplay_epaperdisplay_collect_ptrs(&displays[i].epaper_display); + epaperdisplay_epaperdisplay_collect_ptrs(DYN_DISPLAYS_ADR(i,epaper_display)); #endif } } @@ -440,12 +465,19 @@ static bool is_display_active(mp_obj_base_t *display_maybe) { primary_display_t *allocate_display(void) { for (uint8_t i = 0; i < max_num_displays; i++) { - if (!is_display_active(&displays[i].display_base)) { + if (!is_display_active(DYN_DISPLAYS_ADR(i,display_base))) { // Clear this memory so it is in a known state before init. - memset(&displays[i], 0, sizeof(displays[i])); +// memset(DYN_DISPLAYS_ADR0(i), 0, sizeof(DYN_DISPLAYS(i))); + memset(DYN_DISPLAYS_ADR0(i), 0, sizeof(displays[0])); // Default to None so that it works as board.DISPLAY. - displays[i].display_base.type = &mp_type_NoneType; - return &displays[i]; + if (i < CIRCUITPY_DISPLAY_LIMIT) { + displays[i].display_base.type = &mp_type_NoneType; + #if CIRCUITPY_OS_GETENV + } else { + displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].display_base.type = &mp_type_NoneType; + #endif + } + return DYN_DISPLAYS_ADR0(i); } } return NULL; @@ -461,12 +493,19 @@ primary_display_t *allocate_display_or_raise(void) { primary_display_bus_t *allocate_display_bus(void) { for (uint8_t i = 0; i < max_num_displays; i++) { - mp_const_obj_t display_bus_type = display_buses[i].bus_base.type; + mp_const_obj_t display_bus_type = DYN_DISPLAY_BUSES(i).bus_base.type; if (display_bus_type == NULL || display_bus_type == &mp_type_NoneType) { // Clear this memory so it is in a known state before init. - memset(&display_buses[i], 0, sizeof(display_buses[i])); - display_buses[i].bus_base.type = &mp_type_NoneType; - return &display_buses[i]; +// memset(DYN_DISPLAY_BUSES_ADR0(i), 0, sizeof(DYN_DISPLAY_BUSES(i))); + memset(DYN_DISPLAY_BUSES_ADR0(i), 0, sizeof(display_buses[0])); + if (i < CIRCUITPY_DISPLAY_LIMIT) { + display_buses[i].bus_base.type = &mp_type_NoneType; + #if CIRCUITPY_OS_GETENV + } else { + display_buses_dyn[i - CIRCUITPY_DISPLAY_LIMIT].bus_base.type = &mp_type_NoneType; + #endif + } + return DYN_DISPLAY_BUSES_ADR0(i); } } return NULL; @@ -497,7 +536,7 @@ void common_hal_displayio_set_primary_display(mp_obj_t new_primary_display) { return; } for (uint8_t i = 0; i < max_num_displays; i++) { - mp_obj_t display = MP_OBJ_FROM_PTR(&displays[i]); + mp_obj_t display = MP_OBJ_FROM_PTR(DYN_DISPLAYS_ADR0(i)); if (new_primary_display == display && is_display_active(display)) { primary_display_number = i; return; @@ -512,7 +551,7 @@ void common_hal_displayio_auto_primary_display(void) { return; } for (uint8_t i = 0; i < max_num_displays; i++) { - if (is_display_active(&displays[i].display_base)) { + if (is_display_active(DYN_DISPLAYS_ADR(i,display_base))) { primary_display_number = i; return; } diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index ccdc2887eda6..9ddcbcef9eb7 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -99,16 +99,20 @@ typedef struct { }; } primary_display_t; -extern primary_display_bus_t display_busesx[CIRCUITPY_DISPLAY_LIMIT]; -extern primary_display_t displaysx[CIRCUITPY_DISPLAY_LIMIT]; -extern primary_display_bus_t *display_buses; -extern primary_display_t *displays; +extern primary_display_bus_t display_buses[CIRCUITPY_DISPLAY_LIMIT]; +extern primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; +#if CIRCUITPY_OS_GETENV +extern primary_display_bus_t *display_buses_dyn; +extern primary_display_t *displays_dyn; +#endif extern displayio_group_t circuitpython_splash; void displayio_background(void); void reset_displays(void); +#if CIRCUITPY_OS_GETENV void malloc_display_memory(void); +#endif void displayio_gc_collect(void); primary_display_t *allocate_display(void); diff --git a/shared-module/epaperdisplay/EPaperDisplay.c b/shared-module/epaperdisplay/EPaperDisplay.c index 41c1695dbca6..f7d6135b3ecb 100644 --- a/shared-module/epaperdisplay/EPaperDisplay.c +++ b/shared-module/epaperdisplay/EPaperDisplay.c @@ -512,12 +512,30 @@ size_t maybe_refresh_epaperdisplay(void) { #endif for (uint8_t i = 0; i < max_num_displays; i++) { - if (displays[i].epaper_display.base.type != &epaperdisplay_epaperdisplay_type || - displays[i].epaper_display.core.current_group != &circuitpython_splash) { - // Skip regular displays and those not showing the splash. - continue; + if (i < CIRCUITPY_DISPLAY_LIMIT) { + if (displays[i].epaper_display.base.type != &epaperdisplay_epaperdisplay_type || + displays[i].epaper_display.core.current_group != &circuitpython_splash) { + // Skip regular displays and those not showing the splash. + continue; + } + #if CIRCUITPY_OS_GETENV + } else { + if (displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].epaper_display.base.type != &epaperdisplay_epaperdisplay_type || + displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].epaper_display.core.current_group != &circuitpython_splash) { + // Skip regular displays and those not showing the splash. + continue; + } + #endif + } + + epaperdisplay_epaperdisplay_obj_t *display; + if (i < CIRCUITPY_DISPLAY_LIMIT) { + display = &displays[i].epaper_display; + #if CIRCUITPY_OS_GETENV + } else { + display = &displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].epaper_display; + #endif } - epaperdisplay_epaperdisplay_obj_t *display = &displays[i].epaper_display; size_t time_to_refresh = common_hal_epaperdisplay_epaperdisplay_get_time_to_refresh(display); if (time_to_refresh > 0) { return time_to_refresh; diff --git a/supervisor/shared/web_workflow/web_workflow.c b/supervisor/shared/web_workflow/web_workflow.c index ea7e005b5918..22957293219a 100644 --- a/supervisor/shared/web_workflow/web_workflow.c +++ b/supervisor/shared/web_workflow/web_workflow.c @@ -1565,13 +1565,18 @@ static bool supervisor_filesystem_access_could_block(void) { mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT; #if CIRCUITPY_OS_GETENV (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays); + #define DYN_DISPLAY_BUSES(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? display_buses[indx] : display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT]) + #define DYN_DISPLAY_BUSES_ADR(indx,membr) (indx < CIRCUITPY_DISPLAY_LIMIT ? &display_buses[indx].membr : &display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT].membr) + #else + #define DYN_DISPLAY_BUSES(indx) (display_buses[indx]) + #define DYN_DISPLAY_BUSES_ADR(indx,membr) (&display_buses[indx].membr) #endif // Check displays to see if it's on a fourwire (SPI) bus. If it is, blocking is possible for (mp_int_t i = 0; i < max_num_displays; i++) { - if (display_buses[i].bus_base.type != &fourwire_fourwire_type) { + if (DYN_DISPLAY_BUSES(i).bus_base.type != &fourwire_fourwire_type) { continue; } - if (!common_hal_fourwire_fourwire_bus_free(MP_OBJ_FROM_PTR(&display_buses[i].bus_base))) { + if (!common_hal_fourwire_fourwire_bus_free(MP_OBJ_FROM_PTR(DYN_DISPLAY_BUSES_ADR(i,bus_base)))) { could_block = true; } } From a82ddf4745eb421d24f9b74ac4fbdf0e79a7aab7 Mon Sep 17 00:00:00 2001 From: RetiredWizard <github@retiredwizard.com> Date: Fri, 21 Mar 2025 16:54:34 -0400 Subject: [PATCH 10/14] Local pre-commit.... --- shared-module/displayio/__init__.c | 82 +++++++++---------- shared-module/epaperdisplay/EPaperDisplay.c | 2 +- supervisor/shared/web_workflow/web_workflow.c | 6 +- 3 files changed, 45 insertions(+), 45 deletions(-) diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index a17f37e0dca2..f03e7c426e0c 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -58,17 +58,17 @@ primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; primary_display_bus_t *display_buses_dyn = &display_buses[0]; primary_display_t *displays_dyn = &displays[0]; #define DYN_DISPLAY_BUSES(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? display_buses[indx] : display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT]) -#define DYN_DISPLAY_BUSES_ADR(indx,membr) (indx < CIRCUITPY_DISPLAY_LIMIT ? &display_buses[indx].membr : &display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT].membr) +#define DYN_DISPLAY_BUSES_ADR(indx, membr) (indx < CIRCUITPY_DISPLAY_LIMIT ? &display_buses[indx].membr : &display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT].membr) #define DYN_DISPLAY_BUSES_ADR0(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? &display_buses[indx] : &display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT]) #define DYN_DISPLAYS(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? displays[indx] : displays_dyn[indx - CIRCUITPY_DISPLAY_LIMIT]) -#define DYN_DISPLAYS_ADR(indx,membr) (indx < CIRCUITPY_DISPLAY_LIMIT ? &displays[indx].membr : &displays_dyn[indx - CIRCUITPY_DISPLAY_LIMIT].membr) +#define DYN_DISPLAYS_ADR(indx, membr) (indx < CIRCUITPY_DISPLAY_LIMIT ? &displays[indx].membr : &displays_dyn[indx - CIRCUITPY_DISPLAY_LIMIT].membr) #define DYN_DISPLAYS_ADR0(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? &displays[indx] : &displays_dyn[indx - CIRCUITPY_DISPLAY_LIMIT]) #else #define DYN_DISPLAY_BUSES(indx) (display_buses[indx]) -#define DYN_DISPLAY_BUSES_ADR(indx,membr) (&display_buses[indx].membr) +#define DYN_DISPLAY_BUSES_ADR(indx, membr) (&display_buses[indx].membr) #define DYN_DISPLAY_BUSES_ADR0(indx) (&display_buses[indx]) #define DYN_DISPLAYS(indx) (displays[indx]) -#define DYN_DISPLAYS_ADR(indx,membr) (&displays[indx].membr) +#define DYN_DISPLAYS_ADR(indx, membr) (&displays[indx].membr) #define DYN_DISPLAYS_ADR0(indx) (&displays[indx]) #endif @@ -89,7 +89,7 @@ displayio_buffer_transform_t null_transform = { static bool any_display_uses_this_framebuffer(mp_obj_base_t *obj) { for (uint8_t i = 0; i < max_num_displays; i++) { if (DYN_DISPLAYS(i).display_base.type == &framebufferio_framebufferdisplay_type) { - framebufferio_framebufferdisplay_obj_t *display = DYN_DISPLAYS_ADR(i,framebuffer_display); + framebufferio_framebufferdisplay_obj_t *display = DYN_DISPLAYS_ADR(i, framebuffer_display); if (display->framebuffer == obj) { return true; } @@ -118,15 +118,15 @@ void displayio_background(void) { if (false) { #if CIRCUITPY_BUSDISPLAY } else if (display_type == &busdisplay_busdisplay_type) { - busdisplay_busdisplay_background(DYN_DISPLAYS_ADR(i,display)); + busdisplay_busdisplay_background(DYN_DISPLAYS_ADR(i, display)); #endif #if CIRCUITPY_FRAMEBUFFERIO } else if (display_type == &framebufferio_framebufferdisplay_type) { - framebufferio_framebufferdisplay_background(DYN_DISPLAYS_ADR(i,framebuffer_display)); + framebufferio_framebufferdisplay_background(DYN_DISPLAYS_ADR(i, framebuffer_display)); #endif #if CIRCUITPY_EPAPERDISPLAY } else if (display_type == &epaperdisplay_epaperdisplay_type) { - epaperdisplay_epaperdisplay_background(DYN_DISPLAYS_ADR(i,epaper_display)); + epaperdisplay_epaperdisplay_background(DYN_DISPLAYS_ADR(i, epaper_display)); #endif } } @@ -148,15 +148,15 @@ static void common_hal_displayio_release_displays_impl(bool keep_primary) { continue; #if CIRCUITPY_BUSDISPLAY } else if (display_type == &busdisplay_busdisplay_type) { - release_busdisplay(DYN_DISPLAYS_ADR(i,display)); + release_busdisplay(DYN_DISPLAYS_ADR(i, display)); #endif #if CIRCUITPY_EPAPERDISPLAY } else if (display_type == &epaperdisplay_epaperdisplay_type) { - release_epaperdisplay(DYN_DISPLAYS_ADR(i,epaper_display)); + release_epaperdisplay(DYN_DISPLAYS_ADR(i, epaper_display)); #endif #if CIRCUITPY_FRAMEBUFFERIO } else if (display_type == &framebufferio_framebufferdisplay_type) { - release_framebufferdisplay(DYN_DISPLAYS_ADR(i,framebuffer_display)); + release_framebufferdisplay(DYN_DISPLAYS_ADR(i, framebuffer_display)); #endif } if (i < CIRCUITPY_DISPLAY_LIMIT) { @@ -173,39 +173,39 @@ static void common_hal_displayio_release_displays_impl(bool keep_primary) { continue; #if CIRCUITPY_FOURWIRE } else if (bus_type == &fourwire_fourwire_type) { - common_hal_fourwire_fourwire_deinit(DYN_DISPLAY_BUSES_ADR(i,fourwire_bus)); + common_hal_fourwire_fourwire_deinit(DYN_DISPLAY_BUSES_ADR(i, fourwire_bus)); #endif #if CIRCUITPY_I2CDISPLAYBUS } else if (bus_type == &i2cdisplaybus_i2cdisplaybus_type) { - common_hal_i2cdisplaybus_i2cdisplaybus_deinit(DYN_DISPLAY_BUSES_ADR(i,i2cdisplay_bus)); + common_hal_i2cdisplaybus_i2cdisplaybus_deinit(DYN_DISPLAY_BUSES_ADR(i, i2cdisplay_bus)); #endif #if CIRCUITPY_DOTCLOCKFRAMEBUFFER } else if (bus_type == &dotclockframebuffer_framebuffer_type) { - common_hal_dotclockframebuffer_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i,dotclock)); + common_hal_dotclockframebuffer_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i, dotclock)); #endif #if CIRCUITPY_PARALLELDISPLAYBUS } else if (bus_type == ¶lleldisplaybus_parallelbus_type) { - common_hal_paralleldisplaybus_parallelbus_deinit(DYN_DISPLAY_BUSES_ADR(i,parallel_bus)); + common_hal_paralleldisplaybus_parallelbus_deinit(DYN_DISPLAY_BUSES_ADR(i, parallel_bus)); #endif #if CIRCUITPY_RGBMATRIX } else if (bus_type == &rgbmatrix_RGBMatrix_type) { - common_hal_rgbmatrix_rgbmatrix_deinit(DYN_DISPLAY_BUSES_ADR(i,rgbmatrix)); + common_hal_rgbmatrix_rgbmatrix_deinit(DYN_DISPLAY_BUSES_ADR(i, rgbmatrix)); #endif #if CIRCUITPY_IS31FL3741 } else if (bus_type == &is31fl3741_framebuffer_type) { - common_hal_is31fl3741_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i,is31fl3741)); + common_hal_is31fl3741_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i, is31fl3741)); #endif #if CIRCUITPY_SHARPDISPLAY } else if (bus_type == &sharpdisplay_framebuffer_type) { - common_hal_sharpdisplay_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i,sharpdisplay)); + common_hal_sharpdisplay_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i, sharpdisplay)); #endif #if CIRCUITPY_VIDEOCORE } else if (bus_type == &videocore_framebuffer_type) { - common_hal_videocore_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i,videocore)); + common_hal_videocore_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i, videocore)); #endif #if CIRCUITPY_PICODVI } else if (bus_type == &picodvi_framebuffer_type) { - common_hal_picodvi_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i,picodvi)); + common_hal_picodvi_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i, picodvi)); #endif } if (i < CIRCUITPY_DISPLAY_LIMIT) { @@ -230,7 +230,7 @@ void malloc_display_memory(void) { if (max_num_displays > CIRCUITPY_DISPLAY_LIMIT) { display_buses_dyn = (primary_display_bus_t *)port_malloc(sizeof(primary_display_bus_t) * (max_num_displays - CIRCUITPY_DISPLAY_LIMIT), false); displays_dyn = (primary_display_t *)port_malloc(sizeof(primary_display_t) * (max_num_displays - CIRCUITPY_DISPLAY_LIMIT), false); - + for (uint8_t i = CIRCUITPY_DISPLAY_LIMIT; i < max_num_displays; i++) { memset(&displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT], 0, sizeof(displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT])); memset(&display_buses_dyn[i - CIRCUITPY_DISPLAY_LIMIT], 0, sizeof(display_buses_dyn[i - CIRCUITPY_DISPLAY_LIMIT])); @@ -252,7 +252,7 @@ void reset_displays(void) { continue; #if CIRCUITPY_FOURWIRE } else if (display_bus_type == &fourwire_fourwire_type) { - fourwire_fourwire_obj_t *fourwire = DYN_DISPLAY_BUSES_ADR(i,fourwire_bus); + fourwire_fourwire_obj_t *fourwire = DYN_DISPLAY_BUSES_ADR(i, fourwire_bus); if (((size_t)fourwire->bus) < ((size_t)&display_buses) || ((size_t)fourwire->bus) > ((size_t)&display_buses + max_num_displays * sizeof(primary_display_bus_t))) { busio_spi_obj_t *original_spi = fourwire->bus; @@ -282,7 +282,7 @@ void reset_displays(void) { #endif #if CIRCUITPY_I2CDISPLAYBUS } else if (display_bus_type == &i2cdisplaybus_i2cdisplaybus_type) { - i2cdisplaybus_i2cdisplaybus_obj_t *i2c = DYN_DISPLAY_BUSES_ADR(i,i2cdisplay_bus); + i2cdisplaybus_i2cdisplaybus_obj_t *i2c = DYN_DISPLAY_BUSES_ADR(i, i2cdisplay_bus); // Check to see if we need to inline the I2C bus. if (((size_t)i2c->bus) < ((size_t)&display_buses) || ((size_t)i2c->bus) > ((size_t)&display_buses + max_num_displays * sizeof(primary_display_bus_t))) { @@ -310,7 +310,7 @@ void reset_displays(void) { #endif #if CIRCUITPY_RGBMATRIX } else if (display_bus_type == &rgbmatrix_RGBMatrix_type) { - rgbmatrix_rgbmatrix_obj_t *pm = DYN_DISPLAY_BUSES_ADR(i,rgbmatrix); + rgbmatrix_rgbmatrix_obj_t *pm = DYN_DISPLAY_BUSES_ADR(i, rgbmatrix); if (!any_display_uses_this_framebuffer(&pm->base)) { common_hal_rgbmatrix_rgbmatrix_deinit(pm); } else { @@ -319,7 +319,7 @@ void reset_displays(void) { #endif #if CIRCUITPY_IS31FL3741 } else if (display_bus_type == &is31fl3741_framebuffer_type) { - is31fl3741_framebuffer_obj_t *is31fb = DYN_DISPLAY_BUSES_ADR(i,is31fl3741); + is31fl3741_framebuffer_obj_t *is31fb = DYN_DISPLAY_BUSES_ADR(i, is31fl3741); if (((uint32_t)is31fb->is31fl3741->i2c) < ((uint32_t)&display_buses) || ((uint32_t)is31fb->is31fl3741->i2c) > ((uint32_t)&display_buses + max_num_displays)) { @@ -349,12 +349,12 @@ void reset_displays(void) { #endif #if CIRCUITPY_SHARPDISPLAY } else if (display_bus_type == &sharpdisplay_framebuffer_type) { - sharpdisplay_framebuffer_obj_t *sharp = DYN_DISPLAY_BUSES_ADR(i,sharpdisplay); + sharpdisplay_framebuffer_obj_t *sharp = DYN_DISPLAY_BUSES_ADR(i, sharpdisplay); common_hal_sharpdisplay_framebuffer_reset(sharp); #endif #if CIRCUITPY_VIDEOCORE } else if (display_bus_type == &videocore_framebuffer_type) { - videocore_framebuffer_obj_t *vc = DYN_DISPLAY_BUSES_ADR(i,videocore); + videocore_framebuffer_obj_t *vc = DYN_DISPLAY_BUSES_ADR(i, videocore); if (!any_display_uses_this_framebuffer(&vc->base)) { common_hal_videocore_framebuffer_deinit(vc); } @@ -363,7 +363,7 @@ void reset_displays(void) { #endif #if CIRCUITPY_PICODVI } else if (display_bus_type == &picodvi_framebuffer_type) { - picodvi_framebuffer_obj_t *vc = DYN_DISPLAY_BUSES_ADR(i,picodvi); + picodvi_framebuffer_obj_t *vc = DYN_DISPLAY_BUSES_ADR(i, picodvi); if (!any_display_uses_this_framebuffer(&vc->base)) { common_hal_picodvi_framebuffer_deinit(vc); } @@ -371,7 +371,7 @@ void reset_displays(void) { #if CIRCUITPY_AURORA_EPAPER } else if (display_bus_type == &aurora_framebuffer_type) { #if CIRCUITPY_BOARD_SPI - aurora_epaper_framebuffer_obj_t *aurora = DYN_DISPLAY_BUSES_ADR(i,aurora_epaper); + aurora_epaper_framebuffer_obj_t *aurora = DYN_DISPLAY_BUSES_ADR(i, aurora_epaper); if (common_hal_board_is_spi(aurora->bus)) { common_hal_aurora_epaper_framebuffer_set_free_bus(false); } @@ -393,16 +393,16 @@ void reset_displays(void) { continue; #if CIRCUITPY_BUSDISPLAY } else if (display_type == &busdisplay_busdisplay_type) { - reset_busdisplay(DYN_DISPLAYS_ADR(i,display)); + reset_busdisplay(DYN_DISPLAYS_ADR(i, display)); #endif #if CIRCUITPY_EPAPERDISPLAY } else if (display_type == &epaperdisplay_epaperdisplay_type) { - epaperdisplay_epaperdisplay_obj_t *display = DYN_DISPLAYS_ADR(i,epaper_display); + epaperdisplay_epaperdisplay_obj_t *display = DYN_DISPLAYS_ADR(i, epaper_display); epaperdisplay_epaperdisplay_reset(display); #endif #if CIRCUITPY_FRAMEBUFFERIO } else if (display_type == &framebufferio_framebufferdisplay_type) { - framebufferio_framebufferdisplay_reset(DYN_DISPLAYS_ADR(i,framebuffer_display)); + framebufferio_framebufferdisplay_reset(DYN_DISPLAYS_ADR(i, framebuffer_display)); #endif } } @@ -416,22 +416,22 @@ void displayio_gc_collect(void) { } #if CIRCUITPY_RGBMATRIX if (display_bus_type == &rgbmatrix_RGBMatrix_type) { - rgbmatrix_rgbmatrix_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i,rgbmatrix)); + rgbmatrix_rgbmatrix_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i, rgbmatrix)); } #endif #if CIRCUITPY_IS31FL3741 if (display_bus_type == &is31fl3741_framebuffer_type) { - is31fl3741_framebuffer_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i,is31fl3741)); + is31fl3741_framebuffer_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i, is31fl3741)); } #endif #if CIRCUITPY_SHARPDISPLAY if (display_bus_type == &sharpdisplay_framebuffer_type) { - common_hal_sharpdisplay_framebuffer_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i,sharpdisplay)); + common_hal_sharpdisplay_framebuffer_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i, sharpdisplay)); } #endif #if CIRCUITPY_AURORA_EPAPER if (display_bus_type == &aurora_framebuffer_type) { - common_hal_aurora_epaper_framebuffer_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i,aurora_epaper)); + common_hal_aurora_epaper_framebuffer_collect_ptrs(DYN_DISPLAY_BUSES_ADR(i, aurora_epaper)); } #endif } @@ -445,15 +445,15 @@ void displayio_gc_collect(void) { // but this is more precise, and is the only field that needs marking. #if CIRCUITPY_BUSDISPLAY } else if (display_type == &busdisplay_busdisplay_type) { - busdisplay_busdisplay_collect_ptrs(DYN_DISPLAYS_ADR(i,display)); + busdisplay_busdisplay_collect_ptrs(DYN_DISPLAYS_ADR(i, display)); #endif #if CIRCUITPY_FRAMEBUFFERIO } else if (display_type == &framebufferio_framebufferdisplay_type) { - framebufferio_framebufferdisplay_collect_ptrs(DYN_DISPLAYS_ADR(i,framebuffer_display)); + framebufferio_framebufferdisplay_collect_ptrs(DYN_DISPLAYS_ADR(i, framebuffer_display)); #endif #if CIRCUITPY_EPAPERDISPLAY } else if (display_type == &epaperdisplay_epaperdisplay_type) { - epaperdisplay_epaperdisplay_collect_ptrs(DYN_DISPLAYS_ADR(i,epaper_display)); + epaperdisplay_epaperdisplay_collect_ptrs(DYN_DISPLAYS_ADR(i, epaper_display)); #endif } } @@ -465,7 +465,7 @@ static bool is_display_active(mp_obj_base_t *display_maybe) { primary_display_t *allocate_display(void) { for (uint8_t i = 0; i < max_num_displays; i++) { - if (!is_display_active(DYN_DISPLAYS_ADR(i,display_base))) { + if (!is_display_active(DYN_DISPLAYS_ADR(i, display_base))) { // Clear this memory so it is in a known state before init. // memset(DYN_DISPLAYS_ADR0(i), 0, sizeof(DYN_DISPLAYS(i))); memset(DYN_DISPLAYS_ADR0(i), 0, sizeof(displays[0])); @@ -551,7 +551,7 @@ void common_hal_displayio_auto_primary_display(void) { return; } for (uint8_t i = 0; i < max_num_displays; i++) { - if (is_display_active(DYN_DISPLAYS_ADR(i,display_base))) { + if (is_display_active(DYN_DISPLAYS_ADR(i, display_base))) { primary_display_number = i; return; } diff --git a/shared-module/epaperdisplay/EPaperDisplay.c b/shared-module/epaperdisplay/EPaperDisplay.c index f7d6135b3ecb..da9b965f1524 100644 --- a/shared-module/epaperdisplay/EPaperDisplay.c +++ b/shared-module/epaperdisplay/EPaperDisplay.c @@ -525,7 +525,7 @@ size_t maybe_refresh_epaperdisplay(void) { // Skip regular displays and those not showing the splash. continue; } - #endif + #endif } epaperdisplay_epaperdisplay_obj_t *display; diff --git a/supervisor/shared/web_workflow/web_workflow.c b/supervisor/shared/web_workflow/web_workflow.c index 22957293219a..29f23e1cfe8f 100644 --- a/supervisor/shared/web_workflow/web_workflow.c +++ b/supervisor/shared/web_workflow/web_workflow.c @@ -1566,17 +1566,17 @@ static bool supervisor_filesystem_access_could_block(void) { #if CIRCUITPY_OS_GETENV (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays); #define DYN_DISPLAY_BUSES(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? display_buses[indx] : display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT]) - #define DYN_DISPLAY_BUSES_ADR(indx,membr) (indx < CIRCUITPY_DISPLAY_LIMIT ? &display_buses[indx].membr : &display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT].membr) + #define DYN_DISPLAY_BUSES_ADR(indx, membr) (indx < CIRCUITPY_DISPLAY_LIMIT ? &display_buses[indx].membr : &display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT].membr) #else #define DYN_DISPLAY_BUSES(indx) (display_buses[indx]) - #define DYN_DISPLAY_BUSES_ADR(indx,membr) (&display_buses[indx].membr) + #define DYN_DISPLAY_BUSES_ADR(indx, membr) (&display_buses[indx].membr) #endif // Check displays to see if it's on a fourwire (SPI) bus. If it is, blocking is possible for (mp_int_t i = 0; i < max_num_displays; i++) { if (DYN_DISPLAY_BUSES(i).bus_base.type != &fourwire_fourwire_type) { continue; } - if (!common_hal_fourwire_fourwire_bus_free(MP_OBJ_FROM_PTR(DYN_DISPLAY_BUSES_ADR(i,bus_base)))) { + if (!common_hal_fourwire_fourwire_bus_free(MP_OBJ_FROM_PTR(DYN_DISPLAY_BUSES_ADR(i, bus_base)))) { could_block = true; } } From 424ea8861e1a124c42e475c4545492c264c6e131 Mon Sep 17 00:00:00 2001 From: RetiredWizard <github@retiredwizard.com> Date: Fri, 21 Mar 2025 17:19:03 -0400 Subject: [PATCH 11/14] don't define max_num_displays when not needed --- shared-module/board/__init__.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index 4e9eb5f9b849..34df0053e0a9 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -176,7 +176,7 @@ mp_obj_t common_hal_board_create_uart(const mp_int_t instance) { #endif void reset_board_buses(void) { - #if CIRCUITPY_BOARD_I2C || (CIRCUITPY_BOARD_SPI && (CIRCUITPY_FOURWIRE || CIRCUITPY_SHARPDISPLAY || CIRCUITPY_AURORA_EPAPER)) + #if (CIRCUITPY_BOARD_I2C && CIRCUITPY_I2CDISPLAYBUS) || (CIRCUITPY_BOARD_SPI && (CIRCUITPY_FOURWIRE || CIRCUITPY_SHARPDISPLAY || CIRCUITPY_AURORA_EPAPER)) mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT; #if CIRCUITPY_OS_GETENV #define DYN_DISPLAY_BUSES(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? display_buses[indx] : display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT]) From 4c11d11647112c8ab3ab3f1aa90edf50c3328242 Mon Sep 17 00:00:00 2001 From: RetiredWizard <github@retiredwizard.com> Date: Fri, 21 Mar 2025 17:40:10 -0400 Subject: [PATCH 12/14] compile error fixes --- shared-module/displayio/__init__.c | 2 +- shared-module/displayio/__init__.h | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index f03e7c426e0c..a2c04c946ca3 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -50,7 +50,7 @@ // The default indicates no primary display static int primary_display_number = -1; -static int max_num_displays = CIRCUITPY_DISPLAY_LIMIT; +static mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT; primary_display_bus_t display_buses[CIRCUITPY_DISPLAY_LIMIT]; primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index 9ddcbcef9eb7..d6eaaf597cb3 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -110,9 +110,7 @@ extern displayio_group_t circuitpython_splash; void displayio_background(void); void reset_displays(void); -#if CIRCUITPY_OS_GETENV void malloc_display_memory(void); -#endif void displayio_gc_collect(void); primary_display_t *allocate_display(void); From 0c27bd87ff5af06767b221ce995310fc86ce6ce9 Mon Sep 17 00:00:00 2001 From: RetiredWizard <github@retiredwizard.com> Date: Fri, 21 Mar 2025 19:17:47 -0400 Subject: [PATCH 13/14] Add compile flag to remove code from smaller boards --- main.c | 2 +- ports/atmel-samd/mpconfigport.mk | 1 + .../stm32f411ve_discovery/mpconfigboard.mk | 1 + py/circuitpy_mpconfig.mk | 3 ++ shared-module/board/__init__.c | 9 ++---- shared-module/displayio/__init__.c | 30 ++++++++++++------- shared-module/displayio/__init__.h | 2 +- shared-module/epaperdisplay/EPaperDisplay.c | 20 +++++++++---- supervisor/shared/web_workflow/web_workflow.c | 2 +- 9 files changed, 44 insertions(+), 26 deletions(-) diff --git a/main.c b/main.c index e2587a30fd44..5f00371a2be5 100644 --- a/main.c +++ b/main.c @@ -1051,7 +1051,7 @@ int __attribute__((used)) main(void) { alarm_reset(); #endif - #if CIRCUITPY_DISPLAYIO && CIRCUITPY_OS_GETENV + #if CIRCUITPY_DISPLAYIO && CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT // If number of displays has been overridden in settings.toml allocate memory and // move existing displays malloc_display_memory(); diff --git a/ports/atmel-samd/mpconfigport.mk b/ports/atmel-samd/mpconfigport.mk index 15013b2d831c..d0831f70651c 100644 --- a/ports/atmel-samd/mpconfigport.mk +++ b/ports/atmel-samd/mpconfigport.mk @@ -12,6 +12,7 @@ CIRCUITPY_OPTIMIZE_PROPERTY_FLASH_SIZE ?= 1 CIRCUITPY_LTO = 1 CIRCUITPY_KEYPAD_DEMUX ?= 0 +CIRCUITPY_SET_DISPLAY_LIMIT ?= 0 ###################################################################### # Put samd21-only choices here. diff --git a/ports/stm/boards/stm32f411ve_discovery/mpconfigboard.mk b/ports/stm/boards/stm32f411ve_discovery/mpconfigboard.mk index f34fac4047a7..6d33abb05fa7 100644 --- a/ports/stm/boards/stm32f411ve_discovery/mpconfigboard.mk +++ b/ports/stm/boards/stm32f411ve_discovery/mpconfigboard.mk @@ -22,3 +22,4 @@ CIRCUITPY_BLEIO_HCI = 0 CIRCUITPY_CODEOP = 0 CIRCUITPY_MSGPACK = 0 CIRCUITPY_VECTORIO = 0 +CIRCUITPY_SET_DISPLAY_LIMIT = 0 diff --git a/py/circuitpy_mpconfig.mk b/py/circuitpy_mpconfig.mk index 831c1ec245fc..0c2b40bc70d9 100644 --- a/py/circuitpy_mpconfig.mk +++ b/py/circuitpy_mpconfig.mk @@ -227,6 +227,9 @@ CFLAGS += -DCIRCUITPY_COUNTIO=$(CIRCUITPY_COUNTIO) CIRCUITPY_DISPLAYIO ?= $(CIRCUITPY_FULL_BUILD) CFLAGS += -DCIRCUITPY_DISPLAYIO=$(CIRCUITPY_DISPLAYIO) +CIRCUITPY_SET_DISPLAY_LIMIT ?= $(CIRCUITPY_DISPLAYIO) +CFLAGS += -DCIRCUITPY_SET_DISPLAY_LIMIT=$(CIRCUITPY_SET_DISPLAY_LIMIT) + CIRCUITPY_BUSDISPLAY ?= $(CIRCUITPY_DISPLAYIO) CFLAGS += -DCIRCUITPY_BUSDISPLAY=$(CIRCUITPY_BUSDISPLAY) diff --git a/shared-module/board/__init__.c b/shared-module/board/__init__.c index 34df0053e0a9..78e25488006d 100644 --- a/shared-module/board/__init__.c +++ b/shared-module/board/__init__.c @@ -10,7 +10,7 @@ #include "mpconfigboard.h" #include "py/runtime.h" -#if CIRCUITPY_OS_GETENV +#if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT #include "shared-module/os/__init__.h" #endif @@ -178,15 +178,12 @@ mp_obj_t common_hal_board_create_uart(const mp_int_t instance) { void reset_board_buses(void) { #if (CIRCUITPY_BOARD_I2C && CIRCUITPY_I2CDISPLAYBUS) || (CIRCUITPY_BOARD_SPI && (CIRCUITPY_FOURWIRE || CIRCUITPY_SHARPDISPLAY || CIRCUITPY_AURORA_EPAPER)) mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT; - #if CIRCUITPY_OS_GETENV + #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT #define DYN_DISPLAY_BUSES(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? display_buses[indx] : display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT]) + (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays); #else #define DYN_DISPLAY_BUSES(indx) (display_buses[indx]) #endif - - #if CIRCUITPY_OS_GETENV - (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays); - #endif #endif #if CIRCUITPY_BOARD_I2C diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index a2c04c946ca3..da6bb3799d99 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -22,7 +22,7 @@ #include "py/mpconfig.h" -#if CIRCUITPY_OS_GETENV +#if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT #include "shared-module/os/__init__.h" #endif @@ -54,7 +54,7 @@ static mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT; primary_display_bus_t display_buses[CIRCUITPY_DISPLAY_LIMIT]; primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; -#if CIRCUITPY_OS_GETENV +#if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT primary_display_bus_t *display_buses_dyn = &display_buses[0]; primary_display_t *displays_dyn = &displays[0]; #define DYN_DISPLAY_BUSES(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? display_buses[indx] : display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT]) @@ -159,13 +159,15 @@ static void common_hal_displayio_release_displays_impl(bool keep_primary) { release_framebufferdisplay(DYN_DISPLAYS_ADR(i, framebuffer_display)); #endif } + #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT if (i < CIRCUITPY_DISPLAY_LIMIT) { displays[i].display_base.type = &mp_type_NoneType; - #if CIRCUITPY_OS_GETENV } else { displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].display_base.type = &mp_type_NoneType; - #endif } + #else + displays[i].display_base.type = &mp_type_NoneType; + #endif } for (uint8_t i = 0; i < max_num_displays; i++) { mp_const_obj_t bus_type = DYN_DISPLAY_BUSES(i).bus_base.type; @@ -208,13 +210,15 @@ static void common_hal_displayio_release_displays_impl(bool keep_primary) { common_hal_picodvi_framebuffer_deinit(DYN_DISPLAY_BUSES_ADR(i, picodvi)); #endif } + #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT if (i < CIRCUITPY_DISPLAY_LIMIT) { display_buses[i].bus_base.type = &mp_type_NoneType; - #if CIRCUITPY_OS_GETENV } else { display_buses_dyn[i - CIRCUITPY_DISPLAY_LIMIT].bus_base.type = &mp_type_NoneType; - #endif } + #else + display_buses[i].bus_base.type = &mp_type_NoneType; + #endif } supervisor_stop_terminal(); @@ -225,7 +229,7 @@ void common_hal_displayio_release_displays(void) { } void malloc_display_memory(void) { - #if CIRCUITPY_OS_GETENV + #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays); if (max_num_displays > CIRCUITPY_DISPLAY_LIMIT) { display_buses_dyn = (primary_display_bus_t *)port_malloc(sizeof(primary_display_bus_t) * (max_num_displays - CIRCUITPY_DISPLAY_LIMIT), false); @@ -470,13 +474,15 @@ primary_display_t *allocate_display(void) { // memset(DYN_DISPLAYS_ADR0(i), 0, sizeof(DYN_DISPLAYS(i))); memset(DYN_DISPLAYS_ADR0(i), 0, sizeof(displays[0])); // Default to None so that it works as board.DISPLAY. + #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT if (i < CIRCUITPY_DISPLAY_LIMIT) { displays[i].display_base.type = &mp_type_NoneType; - #if CIRCUITPY_OS_GETENV } else { displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].display_base.type = &mp_type_NoneType; - #endif } + #else + displays[i].display_base.type = &mp_type_NoneType; + #endif return DYN_DISPLAYS_ADR0(i); } } @@ -498,13 +504,15 @@ primary_display_bus_t *allocate_display_bus(void) { // Clear this memory so it is in a known state before init. // memset(DYN_DISPLAY_BUSES_ADR0(i), 0, sizeof(DYN_DISPLAY_BUSES(i))); memset(DYN_DISPLAY_BUSES_ADR0(i), 0, sizeof(display_buses[0])); + #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT if (i < CIRCUITPY_DISPLAY_LIMIT) { display_buses[i].bus_base.type = &mp_type_NoneType; - #if CIRCUITPY_OS_GETENV } else { display_buses_dyn[i - CIRCUITPY_DISPLAY_LIMIT].bus_base.type = &mp_type_NoneType; - #endif } + #else + display_buses[i].bus_base.type = &mp_type_NoneType; + #endif return DYN_DISPLAY_BUSES_ADR0(i); } } diff --git a/shared-module/displayio/__init__.h b/shared-module/displayio/__init__.h index d6eaaf597cb3..9d67fa32fd6a 100644 --- a/shared-module/displayio/__init__.h +++ b/shared-module/displayio/__init__.h @@ -101,7 +101,7 @@ typedef struct { extern primary_display_bus_t display_buses[CIRCUITPY_DISPLAY_LIMIT]; extern primary_display_t displays[CIRCUITPY_DISPLAY_LIMIT]; -#if CIRCUITPY_OS_GETENV +#if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT extern primary_display_bus_t *display_buses_dyn; extern primary_display_t *displays_dyn; #endif diff --git a/shared-module/epaperdisplay/EPaperDisplay.c b/shared-module/epaperdisplay/EPaperDisplay.c index da9b965f1524..dfb074cab8e7 100644 --- a/shared-module/epaperdisplay/EPaperDisplay.c +++ b/shared-module/epaperdisplay/EPaperDisplay.c @@ -20,7 +20,7 @@ #include "supervisor/usb.h" #endif -#if CIRCUITPY_OS_GETENV +#if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT #include "shared-module/os/__init__.h" #endif @@ -507,35 +507,43 @@ void epaperdisplay_epaperdisplay_collect_ptrs(epaperdisplay_epaperdisplay_obj_t size_t maybe_refresh_epaperdisplay(void) { mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT; - #if CIRCUITPY_OS_GETENV + #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays); #endif for (uint8_t i = 0; i < max_num_displays; i++) { + #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT if (i < CIRCUITPY_DISPLAY_LIMIT) { if (displays[i].epaper_display.base.type != &epaperdisplay_epaperdisplay_type || displays[i].epaper_display.core.current_group != &circuitpython_splash) { // Skip regular displays and those not showing the splash. continue; } - #if CIRCUITPY_OS_GETENV } else { if (displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].epaper_display.base.type != &epaperdisplay_epaperdisplay_type || displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].epaper_display.core.current_group != &circuitpython_splash) { // Skip regular displays and those not showing the splash. continue; } - #endif } + #else + if (displays[i].epaper_display.base.type != &epaperdisplay_epaperdisplay_type || + displays[i].epaper_display.core.current_group != &circuitpython_splash) { + // Skip regular displays and those not showing the splash. + continue; + } + #endif epaperdisplay_epaperdisplay_obj_t *display; + #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT if (i < CIRCUITPY_DISPLAY_LIMIT) { display = &displays[i].epaper_display; - #if CIRCUITPY_OS_GETENV } else { display = &displays_dyn[i - CIRCUITPY_DISPLAY_LIMIT].epaper_display; - #endif } + #else + display = &displays[i].epaper_display; + #endif size_t time_to_refresh = common_hal_epaperdisplay_epaperdisplay_get_time_to_refresh(display); if (time_to_refresh > 0) { return time_to_refresh; diff --git a/supervisor/shared/web_workflow/web_workflow.c b/supervisor/shared/web_workflow/web_workflow.c index 29f23e1cfe8f..31a6282c2802 100644 --- a/supervisor/shared/web_workflow/web_workflow.c +++ b/supervisor/shared/web_workflow/web_workflow.c @@ -1563,7 +1563,7 @@ static bool supervisor_filesystem_access_could_block(void) { } mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT; - #if CIRCUITPY_OS_GETENV + #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT (void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays); #define DYN_DISPLAY_BUSES(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? display_buses[indx] : display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT]) #define DYN_DISPLAY_BUSES_ADR(indx, membr) (indx < CIRCUITPY_DISPLAY_LIMIT ? &display_buses[indx].membr : &display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT].membr) From 68e3532291946f98b972d5436156aec0b16bacf2 Mon Sep 17 00:00:00 2001 From: RetiredWizard <github@retiredwizard.com> Date: Sun, 23 Mar 2025 14:15:59 -0400 Subject: [PATCH 14/14] Cleanup commented code --- shared-module/displayio/__init__.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/shared-module/displayio/__init__.c b/shared-module/displayio/__init__.c index da6bb3799d99..ed324e6c7f42 100644 --- a/shared-module/displayio/__init__.c +++ b/shared-module/displayio/__init__.c @@ -471,7 +471,6 @@ primary_display_t *allocate_display(void) { for (uint8_t i = 0; i < max_num_displays; i++) { if (!is_display_active(DYN_DISPLAYS_ADR(i, display_base))) { // Clear this memory so it is in a known state before init. -// memset(DYN_DISPLAYS_ADR0(i), 0, sizeof(DYN_DISPLAYS(i))); memset(DYN_DISPLAYS_ADR0(i), 0, sizeof(displays[0])); // Default to None so that it works as board.DISPLAY. #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT @@ -502,7 +501,6 @@ primary_display_bus_t *allocate_display_bus(void) { mp_const_obj_t display_bus_type = DYN_DISPLAY_BUSES(i).bus_base.type; if (display_bus_type == NULL || display_bus_type == &mp_type_NoneType) { // Clear this memory so it is in a known state before init. -// memset(DYN_DISPLAY_BUSES_ADR0(i), 0, sizeof(DYN_DISPLAY_BUSES(i))); memset(DYN_DISPLAY_BUSES_ADR0(i), 0, sizeof(display_buses[0])); #if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT if (i < CIRCUITPY_DISPLAY_LIMIT) {