Skip to content

Commit 6e1b516

Browse files
committed
Allow setting of CIRCUITPY_DISPLAY_LIMIT in settings.toml
1 parent 61ed7c7 commit 6e1b516

File tree

10 files changed

+240
-67
lines changed

10 files changed

+240
-67
lines changed

docs/environment.rst

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,27 @@ Example: Configure the display to 640x480 black and white (1 bit per pixel):
179179
`Adafruit Feather RP2350 <https://circuitpython.org/board/adafruit_feather_rp2350/>`_
180180
`Adafruit Metro RP2350 <https://circuitpython.org/board/adafruit_metro_rp2350/>`_
181181

182+
CIRCUITPY_DISPLAY_LIMIT
183+
~~~~~~~~~~~~~~~~~~~~~~~
184+
Set the maximum supported number of displayio displays. This value overrides the
185+
CIRCUITPY_DISPLAY_LIMIT compile-time flag defined in mpconfigport.h.
186+
It specifies the maximum number of active display objects that can be supported simultaneously
187+
on a CircuitPython board.
188+
189+
By default, the value of CIRCUITPY_DISPLAY_LIMIT is set to 1 for most boards, meaning only
190+
one display can be active at a time. Users can modify this value by adding a settings.toml entry
191+
to support additional displays.
192+
193+
The value of CIRCUITPY_DISPLAY_LIMIT should be set to a value that is supported by the
194+
hardware and does not exceed the available memory and resources on the board. Setting the
195+
value too high may result in unexpected behavior or crashes.
196+
197+
Example: Set the maximum supported number of displayio displays to 2:
198+
199+
.. code-block::
200+
201+
CIRCUITPY_DISPLAY_LIMIT=2
202+
182203
CIRCUITPY_TERMINAL_SCALE
183204
~~~~~~~~~~~~~~~~~~~~~~~~
184205
Allows the entry of a display scaling factor used during the terminalio console construction.

main.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,12 @@ int __attribute__((used)) main(void) {
10511051
alarm_reset();
10521052
#endif
10531053

1054+
#if CIRCUITPY_DISPLAYIO && CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT
1055+
// If number of displays has been overridden in settings.toml allocate memory and
1056+
// move existing displays
1057+
malloc_display_memory();
1058+
#endif
1059+
10541060
// Reset everything and prep MicroPython to run boot.py.
10551061
reset_port();
10561062
// Port-independent devices, like CIRCUITPY_BLEIO_HCI.

ports/atmel-samd/mpconfigport.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ CIRCUITPY_LTO = 1
1313

1414
CIRCUITPY_KEYPAD_DEMUX ?= 0
1515
CIRCUITPY_LVFONTIO ?= 0
16+
CIRCUITPY_SET_DISPLAY_LIMIT ?= 0
1617

1718
######################################################################
1819
# Put samd21-only choices here.

ports/stm/boards/stm32f411ve_discovery/mpconfigboard.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,4 @@ CIRCUITPY_BLEIO_HCI = 0
2424
CIRCUITPY_CODEOP = 0
2525
CIRCUITPY_MSGPACK = 0
2626
CIRCUITPY_VECTORIO = 0
27+
CIRCUITPY_SET_DISPLAY_LIMIT = 0

py/circuitpy_mpconfig.mk

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,9 @@ CFLAGS += -DCIRCUITPY_COUNTIO=$(CIRCUITPY_COUNTIO)
227227
CIRCUITPY_DISPLAYIO ?= $(CIRCUITPY_FULL_BUILD)
228228
CFLAGS += -DCIRCUITPY_DISPLAYIO=$(CIRCUITPY_DISPLAYIO)
229229

230+
CIRCUITPY_SET_DISPLAY_LIMIT ?= $(CIRCUITPY_DISPLAYIO)
231+
CFLAGS += -DCIRCUITPY_SET_DISPLAY_LIMIT=$(CIRCUITPY_SET_DISPLAY_LIMIT)
232+
230233
CIRCUITPY_BUSDISPLAY ?= $(CIRCUITPY_DISPLAYIO)
231234
CFLAGS += -DCIRCUITPY_BUSDISPLAY=$(CIRCUITPY_BUSDISPLAY)
232235

shared-module/board/__init__.c

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@
1010
#include "mpconfigboard.h"
1111
#include "py/runtime.h"
1212

13+
#if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT
14+
#include "shared-module/os/__init__.h"
15+
#endif
16+
1317
#if CIRCUITPY_BUSIO
1418
#include "shared-bindings/busio/I2C.h"
1519
#include "shared-bindings/busio/SPI.h"
@@ -172,12 +176,22 @@ mp_obj_t common_hal_board_create_uart(const mp_int_t instance) {
172176
#endif
173177

174178
void reset_board_buses(void) {
179+
#if (CIRCUITPY_BOARD_I2C && CIRCUITPY_I2CDISPLAYBUS) || (CIRCUITPY_BOARD_SPI && (CIRCUITPY_FOURWIRE || CIRCUITPY_SHARPDISPLAY || CIRCUITPY_AURORA_EPAPER))
180+
mp_int_t max_num_displays = CIRCUITPY_DISPLAY_LIMIT;
181+
#if CIRCUITPY_OS_GETENV && CIRCUITPY_SET_DISPLAY_LIMIT
182+
#define DYN_DISPLAY_BUSES(indx) (indx < CIRCUITPY_DISPLAY_LIMIT ? display_buses[indx] : display_buses_dyn[indx - CIRCUITPY_DISPLAY_LIMIT])
183+
(void)common_hal_os_getenv_int("CIRCUITPY_DISPLAY_LIMIT", &max_num_displays);
184+
#else
185+
#define DYN_DISPLAY_BUSES(indx) (display_buses[indx])
186+
#endif
187+
#endif
188+
175189
#if CIRCUITPY_BOARD_I2C
176190
for (uint8_t instance = 0; instance < CIRCUITPY_BOARD_I2C; instance++) {
177191
bool display_using_i2c = false;
178192
#if CIRCUITPY_I2CDISPLAYBUS
179-
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
180-
if (display_buses[i].bus_base.type == &i2cdisplaybus_i2cdisplaybus_type && display_buses[i].i2cdisplay_bus.bus == &i2c_obj[instance]) {
193+
for (uint8_t i = 0; i < max_num_displays; i++) {
194+
if (DYN_DISPLAY_BUSES(i).bus_base.type == &i2cdisplaybus_i2cdisplaybus_type && DYN_DISPLAY_BUSES(i).i2cdisplay_bus.bus == &i2c_obj[instance]) {
181195
display_using_i2c = true;
182196
break;
183197
}
@@ -197,22 +211,22 @@ void reset_board_buses(void) {
197211
for (uint8_t instance = 0; instance < CIRCUITPY_BOARD_SPI; instance++) {
198212
bool display_using_spi = false;
199213
#if CIRCUITPY_FOURWIRE || CIRCUITPY_SHARPDISPLAY || CIRCUITPY_AURORA_EPAPER
200-
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
201-
mp_const_obj_t bus_type = display_buses[i].bus_base.type;
214+
for (uint8_t i = 0; i < max_num_displays; i++) {
215+
mp_const_obj_t bus_type = DYN_DISPLAY_BUSES(i).bus_base.type;
202216
#if CIRCUITPY_FOURWIRE
203-
if (bus_type == &fourwire_fourwire_type && display_buses[i].fourwire_bus.bus == &spi_obj[instance]) {
217+
if (bus_type == &fourwire_fourwire_type && DYN_DISPLAY_BUSES(i).fourwire_bus.bus == &spi_obj[instance]) {
204218
display_using_spi = true;
205219
break;
206220
}
207221
#endif
208222
#if CIRCUITPY_SHARPDISPLAY
209-
if (bus_type == &sharpdisplay_framebuffer_type && display_buses[i].sharpdisplay.bus == &spi_obj[instance]) {
223+
if (bus_type == &sharpdisplay_framebuffer_type && DYN_DISPLAY_BUSES(i).sharpdisplay.bus == &spi_obj[instance]) {
210224
display_using_spi = true;
211225
break;
212226
}
213227
#endif
214228
#if CIRCUITPY_AURORA_EPAPER
215-
if (bus_type == &aurora_epaper_framebuffer_type && display_buses[i].aurora_epaper.bus == &spi_obj[instance]) {
229+
if (bus_type == &aurora_epaper_framebuffer_type && DYN_DISPLAY_BUSES(i).aurora_epaper.bus == &spi_obj[instance]) {
216230
display_using_spi = true;
217231
break;
218232
}

0 commit comments

Comments
 (0)