Skip to content

Commit 292d209

Browse files
committed
Better reasoned allocations
1 parent d2dcfec commit 292d209

File tree

6 files changed

+50
-24
lines changed

6 files changed

+50
-24
lines changed

ports/espressif/common-hal/mipidsi/Bus.c

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ void common_hal_mipidsi_bus_construct(mipidsi_bus_obj_t *self, mp_uint_t frequen
1414
self->num_data_lanes = num_lanes;
1515
self->bus_handle = NULL;
1616

17+
if (self->use_count > 0) {
18+
mp_raise_ValueError_varg(MP_ERROR_TEXT("%q in use"), MP_QSTR_mipidsi);
19+
}
20+
1721
esp_ldo_channel_handle_t ldo_mipi_phy = NULL;
1822
esp_ldo_channel_config_t ldo_mipi_phy_config = {
1923
.chan_id = 3,
@@ -33,6 +37,9 @@ void common_hal_mipidsi_bus_construct(mipidsi_bus_obj_t *self, mp_uint_t frequen
3337
}
3438

3539
void common_hal_mipidsi_bus_deinit(mipidsi_bus_obj_t *self) {
40+
if (self->use_count > 0) {
41+
mp_raise_ValueError_varg(MP_ERROR_TEXT("%q in use"), MP_QSTR_Bus);
42+
}
3643
if (common_hal_mipidsi_bus_deinited(self)) {
3744
return;
3845
}
@@ -50,3 +57,13 @@ void common_hal_mipidsi_bus_deinit(mipidsi_bus_obj_t *self) {
5057
bool common_hal_mipidsi_bus_deinited(mipidsi_bus_obj_t *self) {
5158
return self->bus_handle == NULL;
5259
}
60+
61+
void mipidsi_bus_increment_use_count(mipidsi_bus_obj_t *self) {
62+
self->use_count++;
63+
}
64+
void mipidsi_bus_decrement_use_count(mipidsi_bus_obj_t *self) {
65+
self->use_count--;
66+
if (self->use_count == 0) {
67+
common_hal_mipidsi_bus_deinit(self);
68+
}
69+
}

ports/espressif/common-hal/mipidsi/Bus.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,8 @@ typedef struct {
1414
mp_uint_t frequency;
1515
esp_lcd_dsi_bus_handle_t bus_handle;
1616
uint8_t num_data_lanes;
17+
uint8_t use_count; // Up to 4 displays
1718
} mipidsi_bus_obj_t;
19+
20+
void mipidsi_bus_increment_use_count(mipidsi_bus_obj_t *self);
21+
void mipidsi_bus_decrement_use_count(mipidsi_bus_obj_t *self);

ports/espressif/common-hal/mipidsi/Display.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ void common_hal_mipidsi_display_construct(mipidsi_display_obj_t *self,
6767
color_format = LCD_COLOR_FMT_RGB888;
6868
} else {
6969
common_hal_mipidsi_display_deinit(self);
70-
mp_raise_ValueError(MP_ERROR_TEXT("Color depth must be 16 or 24"));
70+
mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_color_depth);
7171
}
7272

7373
// Create the DPI panel for sending pixel data
@@ -173,6 +173,7 @@ void common_hal_mipidsi_display_construct(mipidsi_display_obj_t *self,
173173
common_hal_digitalio_digitalinout_set_value(&self->backlight_inout, on);
174174
}
175175
}
176+
mipidsi_bus_increment_use_count(self->bus);
176177
}
177178

178179
void common_hal_mipidsi_display_deinit(mipidsi_display_obj_t *self) {
@@ -202,6 +203,7 @@ void common_hal_mipidsi_display_deinit(mipidsi_display_obj_t *self) {
202203
self->dbi_io_handle = NULL;
203204
}
204205

206+
mipidsi_bus_decrement_use_count(self->bus);
205207
self->bus = NULL;
206208
self->framebuffer = NULL;
207209
}

shared-bindings/mipidsi/Bus.c

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,13 @@
2828
//| :param int num_lanes: the number of data lanes to use (default 2, range 1-4)
2929
//| """
3030
//|
31+
//
32+
//
33+
// All MCUs we support only have one DSI bus but it can be shared between multiple displays. One
34+
// display may live longer than the VM, so we need to allocate the bus outside the VM. To simplify
35+
// memory tracking, we use a global object for the bus.
36+
//
37+
static mipidsi_bus_obj_t _mipidsi_bus_obj;
3138

3239
static mp_obj_t mipidsi_bus_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *all_args) {
3340
enum { ARG_frequency, ARG_num_lanes };
@@ -38,7 +45,8 @@ static mp_obj_t mipidsi_bus_make_new(const mp_obj_type_t *type, size_t n_args, s
3845
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
3946
mp_arg_parse_all_kw_array(n_args, n_kw, all_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
4047

41-
mipidsi_bus_obj_t *self = mp_obj_malloc(mipidsi_bus_obj_t, &mipidsi_bus_type);
48+
_mipidsi_bus_obj.base.type = &mipidsi_bus_type;
49+
mipidsi_bus_obj_t *self = &_mipidsi_bus_obj;
4250

4351
mp_uint_t frequency = (mp_uint_t)mp_arg_validate_int_min(args[ARG_frequency].u_int, 1, MP_QSTR_frequency);
4452
uint8_t num_lanes = (uint8_t)mp_arg_validate_int_range(args[ARG_num_lanes].u_int, 1, 4, MP_QSTR_num_lanes);
@@ -62,28 +70,8 @@ static mp_obj_t mipidsi_bus_deinit(mp_obj_t self_in) {
6270

6371
static MP_DEFINE_CONST_FUN_OBJ_1(mipidsi_bus_deinit_obj, mipidsi_bus_deinit);
6472

65-
//| def __enter__(self) -> Bus:
66-
//| """No-op used by Context Managers."""
67-
//| ...
68-
//|
69-
// Provided by context manager helper.
70-
71-
//| def __exit__(self) -> None:
72-
//| """Automatically deinitializes the hardware when exiting a context. See
73-
//| :ref:`lifetime-and-contextmanagers` for more info."""
74-
//| ...
75-
//|
76-
static mp_obj_t mipidsi_bus_obj___exit__(size_t n_args, const mp_obj_t *args) {
77-
(void)n_args;
78-
common_hal_mipidsi_bus_deinit(args[0]);
79-
return mp_const_none;
80-
}
81-
static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mipidsi_bus___exit___obj, 4, 4, mipidsi_bus_obj___exit__);
82-
8373
static const mp_rom_map_elem_t mipidsi_bus_locals_dict_table[] = {
8474
{ MP_ROM_QSTR(MP_QSTR_deinit), MP_ROM_PTR(&mipidsi_bus_deinit_obj) },
85-
{ MP_ROM_QSTR(MP_QSTR___enter__), MP_ROM_PTR(&default___enter___obj) },
86-
{ MP_ROM_QSTR(MP_QSTR___exit__), MP_ROM_PTR(&mipidsi_bus___exit___obj) },
8775
};
8876
static MP_DEFINE_CONST_DICT(mipidsi_bus_locals_dict, mipidsi_bus_locals_dict_table);
8977

shared-bindings/mipidsi/Display.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ static mp_obj_t mipidsi_display_make_new(const mp_obj_type_t *type, size_t n_arg
124124
mp_uint_t height = (mp_uint_t)mp_arg_validate_int_min(args[ARG_height].u_int, 0, MP_QSTR_height);
125125
mp_uint_t color_depth = args[ARG_color_depth].u_int;
126126

127-
if (color_depth != 8 && color_depth != 16 && color_depth != 24) {
127+
if (color_depth != 16 && color_depth != 24) {
128128
mp_raise_ValueError_varg(MP_ERROR_TEXT("Invalid %q"), MP_QSTR_color_depth);
129129
}
130130

shared-module/displayio/__init__.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,10 @@
4141
#include "shared-module/aurora_epaper/aurora_framebuffer.h"
4242
#endif
4343

44+
#if CIRCUITPY_MIPIDSI
45+
#include "shared-bindings/mipidsi/Display.h"
46+
#endif
47+
4448
#ifdef BOARD_USE_INTERNAL_SPI
4549
#include "supervisor/spi_flash_api.h"
4650
#endif
@@ -64,7 +68,7 @@ displayio_buffer_transform_t null_transform = {
6468
.transpose_xy = false
6569
};
6670

67-
#if CIRCUITPY_RGBMATRIX || CIRCUITPY_IS31FL3741 || CIRCUITPY_VIDEOCORE || CIRCUITPY_PICODVI
71+
#if CIRCUITPY_RGBMATRIX || CIRCUITPY_IS31FL3741 || CIRCUITPY_VIDEOCORE || CIRCUITPY_PICODVI || CIRCUITPY_MIPIDSI
6872
static bool any_display_uses_this_framebuffer(mp_obj_base_t *obj) {
6973
for (uint8_t i = 0; i < CIRCUITPY_DISPLAY_LIMIT; i++) {
7074
if (displays[i].display_base.type == &framebufferio_framebufferdisplay_type) {
@@ -180,6 +184,10 @@ static void common_hal_displayio_release_displays_impl(bool keep_primary) {
180184
} else if (bus_type == &picodvi_framebuffer_type) {
181185
common_hal_picodvi_framebuffer_deinit(&display_buses[i].picodvi);
182186
#endif
187+
#if CIRCUITPY_MIPIDSI
188+
} else if (bus_type == &mipidsi_display_type) {
189+
common_hal_mipidsi_display_deinit(&display_buses[i].mipidsi);
190+
#endif
183191
}
184192
display_buses[i].bus_base.type = &mp_type_NoneType;
185193
}
@@ -333,6 +341,13 @@ void reset_displays(void) {
333341
// Set to None, gets deinit'd up by display_base
334342
display_buses[i].bus_base.type = &mp_type_NoneType;
335343
#endif
344+
#if CIRCUITPY_MIPIDSI
345+
} else if (display_bus_type == &mipidsi_display_type) {
346+
mipidsi_display_obj_t *display = &display_buses[i].mipidsi;
347+
if (!any_display_uses_this_framebuffer(&display->base)) {
348+
common_hal_mipidsi_display_deinit(display);
349+
}
350+
#endif
336351
} else {
337352
// Not an active display bus.
338353
continue;

0 commit comments

Comments
 (0)