Skip to content

Commit fc772b4

Browse files
authored
Merge pull request micropython#2063 from tannewt/fix_i2cdisplay
Fix I2CDisplay lifecycle and splash lifecycle.
2 parents 583392a + b3de7ef commit fc772b4

File tree

4 files changed

+44
-20
lines changed

4 files changed

+44
-20
lines changed

py/circuitpy_mpconfig.h

+1-9
Original file line numberDiff line numberDiff line change
@@ -273,13 +273,7 @@ extern const struct _mp_obj_module_t board_module;
273273
#define BOARD_SPI (defined(DEFAULT_SPI_BUS_SCK) && defined(DEFAULT_SPI_BUS_MISO) && defined(DEFAULT_SPI_BUS_MOSI))
274274
#define BOARD_UART (defined(DEFAULT_UART_BUS_RX) && defined(DEFAULT_UART_BUS_TX))
275275

276-
#if BOARD_I2C
277-
#define BOARD_I2C_ROOT_POINTER mp_obj_t shared_i2c_bus;
278-
#else
279-
#define BOARD_I2C_ROOT_POINTER
280-
#endif
281-
282-
// SPI is always allocated off the heap.
276+
// I2C and SPI are always allocated off the heap.
283277

284278
#if BOARD_UART
285279
#define BOARD_UART_ROOT_POINTER mp_obj_t shared_uart_bus;
@@ -289,7 +283,6 @@ extern const struct _mp_obj_module_t board_module;
289283

290284
#else
291285
#define BOARD_MODULE
292-
#define BOARD_I2C_ROOT_POINTER
293286
#define BOARD_UART_ROOT_POINTER
294287
#endif
295288

@@ -647,7 +640,6 @@ extern const struct _mp_obj_module_t ustack_module;
647640
GAMEPAD_ROOT_POINTERS \
648641
mp_obj_t pew_singleton; \
649642
mp_obj_t terminal_tilegrid_tiles; \
650-
BOARD_I2C_ROOT_POINTER \
651643
BOARD_UART_ROOT_POINTER \
652644
FLASH_ROOT_POINTERS \
653645
NETWORK_ROOT_POINTERS \

shared-module/board/__init__.c

+24-5
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,25 @@
4040
#endif
4141

4242
#if BOARD_I2C
43+
// Statically allocate the I2C object so it can live past the end of the heap and into the next VM.
44+
// That way it can be used by built-in I2CDisplay displays and be accessible through board.I2C().
45+
STATIC busio_i2c_obj_t i2c_obj;
46+
STATIC mp_obj_t i2c_singleton = NULL;
47+
4348
mp_obj_t common_hal_board_get_i2c(void) {
44-
return MP_STATE_VM(shared_i2c_bus);
49+
return i2c_singleton;
4550
}
4651

4752
mp_obj_t common_hal_board_create_i2c(void) {
48-
busio_i2c_obj_t *self = m_new_ll_obj(busio_i2c_obj_t);
53+
if (i2c_singleton != NULL) {
54+
return i2c_singleton;
55+
}
56+
busio_i2c_obj_t *self = &i2c_obj;
4957
self->base.type = &busio_i2c_type;
5058

5159
common_hal_busio_i2c_construct(self, DEFAULT_I2C_BUS_SCL, DEFAULT_I2C_BUS_SDA, 400000, 0);
52-
MP_STATE_VM(shared_i2c_bus) = MP_OBJ_FROM_PTR(self);
53-
return MP_STATE_VM(shared_i2c_bus);
60+
i2c_singleton = (mp_obj_t)self;
61+
return i2c_singleton;
5462
}
5563
#endif
5664

@@ -101,7 +109,18 @@ mp_obj_t common_hal_board_create_uart(void) {
101109

102110
void reset_board_busses(void) {
103111
#if BOARD_I2C
104-
MP_STATE_VM(shared_i2c_bus) = NULL;
112+
bool display_using_i2c = false;
113+
#if CIRCUITPY_DISPLAYIO
114+
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
115+
if (displays[i].i2cdisplay_bus.bus == i2c_singleton) {
116+
display_using_i2c = true;
117+
break;
118+
}
119+
}
120+
#endif
121+
if (!display_using_i2c) {
122+
i2c_singleton = NULL;
123+
}
105124
#endif
106125
#if BOARD_SPI
107126
bool display_using_spi = false;

shared-module/displayio/Display.c

+15-4
Original file line numberDiff line numberDiff line change
@@ -199,19 +199,26 @@ void common_hal_displayio_display_construct(displayio_display_obj_t* self,
199199

200200
bool common_hal_displayio_display_show(displayio_display_obj_t* self, displayio_group_t* root_group) {
201201
if (root_group == NULL) {
202-
root_group = &circuitpython_splash;
202+
if (!circuitpython_splash.in_group) {
203+
root_group = &circuitpython_splash;
204+
} else if (self->current_group == &circuitpython_splash) {
205+
return false;
206+
}
203207
}
204208
if (root_group == self->current_group) {
205209
return true;
206210
}
207-
if (root_group->in_group) {
211+
if (root_group != NULL && root_group->in_group) {
208212
return false;
209213
}
210214
if (self->current_group != NULL) {
211215
self->current_group->in_group = false;
212216
}
213-
displayio_group_update_transform(root_group, &self->transform);
214-
root_group->in_group = true;
217+
218+
if (root_group != NULL) {
219+
displayio_group_update_transform(root_group, &self->transform);
220+
root_group->in_group = true;
221+
}
215222
self->current_group = root_group;
216223
self->full_refresh = true;
217224
common_hal_displayio_display_refresh_soon(self);
@@ -402,6 +409,10 @@ void displayio_display_update_backlight(displayio_display_obj_t* self) {
402409
}
403410

404411
void release_display(displayio_display_obj_t* self) {
412+
if (self->current_group != NULL) {
413+
self->current_group->in_group = false;
414+
}
415+
405416
if (self->backlight_pwm.base.type == &pulseio_pwmout_type) {
406417
common_hal_pulseio_pwmout_reset_ok(&self->backlight_pwm);
407418
common_hal_pulseio_pwmout_deinit(&self->backlight_pwm);

shared-module/displayio/__init__.c

+4-2
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ void displayio_refresh_displays(void) {
163163
void common_hal_displayio_release_displays(void) {
164164
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
165165
mp_const_obj_t bus_type = displays[i].fourwire_bus.base.type;
166-
if (bus_type == NULL) {
166+
if (bus_type == NULL || bus_type == &mp_type_NoneType) {
167167
continue;
168168
} else if (bus_type == &displayio_fourwire_type) {
169169
common_hal_displayio_fourwire_deinit(&displays[i].fourwire_bus);
@@ -235,12 +235,14 @@ void reset_displays(void) {
235235
// Not an active display.
236236
continue;
237237
}
238+
}
238239

240+
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
239241
// Reset the displayed group. Only the first will get the terminal but
240242
// that's ok.
241243
displayio_display_obj_t* display = &displays[i].display;
242244
display->auto_brightness = true;
243-
common_hal_displayio_display_show(display, &circuitpython_splash);
245+
common_hal_displayio_display_show(display, NULL);
244246
}
245247
}
246248

0 commit comments

Comments
 (0)