Skip to content

Commit d4913b0

Browse files
committed
rgbmatrix: update protomatter
and re-organize so that esp32 s2/s3 don't do as much at reset .. it's not necessary (because most data is in esp-idf managed memory) and doing this saves me from having to debug why reconstruct isn't working properly on that platform. This needs to be tested on other platforms again before being merged!
1 parent ce84ecf commit d4913b0

File tree

9 files changed

+87
-46
lines changed

9 files changed

+87
-46
lines changed

ports/espressif/common-hal/rgbmatrix/RGBMatrix.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#include "peripherals/timer.h"
3232

3333
void *common_hal_rgbmatrix_timer_allocate(rgbmatrix_rgbmatrix_obj_t *self) {
34-
const timer_config_t config = {
34+
static const timer_config_t config = {
3535
.alarm_en = false,
3636
.counter_en = false,
3737
.intr_type = TIMER_INTR_LEVEL,
@@ -43,6 +43,7 @@ void *common_hal_rgbmatrix_timer_allocate(rgbmatrix_rgbmatrix_obj_t *self) {
4343
timer_index_t *timer = malloc(sizeof(timer_index_t));
4444
bool res = peripherals_timer_init(&config, timer);
4545
if (!res) {
46+
free(timer);
4647
return NULL;
4748
}
4849
peripherals_timer_never_reset(timer);
@@ -52,6 +53,11 @@ void *common_hal_rgbmatrix_timer_allocate(rgbmatrix_rgbmatrix_obj_t *self) {
5253
extern bool _PM_esp32timerCallback(void *arg);
5354

5455
void common_hal_rgbmatrix_timer_enable(void *ptr) {
56+
timer_index_t *timer = (timer_index_t *)ptr;
57+
if (timer->idx == TIMER_MAX) {
58+
return;
59+
}
60+
timer_start(timer->group, timer->idx);
5561
}
5662

5763
void common_hal_rgbmatrix_timer_disable(void *ptr) {
@@ -60,8 +66,6 @@ void common_hal_rgbmatrix_timer_disable(void *ptr) {
6066
return;
6167
}
6268
timer_pause(timer->group, timer->idx);
63-
timer_disable_intr(timer->group, timer->idx);
64-
timer_isr_callback_remove(timer->group, timer->idx);
6569
}
6670

6771
void common_hal_rgbmatrix_timer_free(void *ptr) {
@@ -70,6 +74,8 @@ void common_hal_rgbmatrix_timer_free(void *ptr) {
7074
return;
7175
}
7276
common_hal_rgbmatrix_timer_disable(ptr);
77+
timer_disable_intr(timer->group, timer->idx);
78+
timer_isr_callback_remove(timer->group, timer->idx);
7379
peripherals_timer_deinit(timer);
74-
timer->idx = TIMER_MAX;
80+
free(timer);
7581
}

ports/espressif/mpconfigport.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,12 @@ CIRCUITPY_USB = 0
7070
else ifeq ($(IDF_TARGET),esp32s2)
7171
# Modules
7272
CIRCUITPY_BLEIO = 0
73+
CIRCUITPY_RGBMATRIX_USES_SUPERVISOR_ALLOCATION = 0
7374

7475
else ifeq ($(IDF_TARGET),esp32s3)
7576
# Modules
7677
CIRCUITPY_PARALLELDISPLAY = 0
78+
CIRCUITPY_RGBMATRIX_USES_SUPERVISOR_ALLOCATION = 0
7779
endif
7880

7981
# No room for dualbank on boards with 2MB flash

py/circuitpy_mpconfig.mk

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,8 @@ CFLAGS += -DCIRCUITPY_RP2PIO=$(CIRCUITPY_RP2PIO)
385385

386386
CIRCUITPY_RGBMATRIX ?= 0
387387
CFLAGS += -DCIRCUITPY_RGBMATRIX=$(CIRCUITPY_RGBMATRIX)
388+
CIRCUITPY_RGBMATRIX_USES_SUPERVISOR_ALLOCATION ?= 1
389+
CFLAGS += -DCIRCUITPY_RGBMATRIX_USES_SUPERVISOR_ALLOCATION=$(CIRCUITPY_RGBMATRIX_USES_SUPERVISOR_ALLOCATION)
388390

389391
CIRCUITPY_ROTARYIO ?= 1
390392
CFLAGS += -DCIRCUITPY_ROTARYIO=$(CIRCUITPY_ROTARYIO)

shared-bindings/rgbmatrix/RGBMatrix.c

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -62,13 +62,16 @@ STATIC void claim_and_never_reset_pins(mp_obj_t seq) {
6262
}
6363

6464
STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_t rgb_pin_count, bool allow_inefficient) {
65-
uint32_t port = clock_pin / 32;
66-
uint32_t bit_mask = 1 << (clock_pin % 32);
67-
6865
if (rgb_pin_count <= 0 || rgb_pin_count % 6 != 0 || rgb_pin_count > 30) {
6966
mp_raise_ValueError_varg(translate("The length of rgb_pins must be 6, 12, 18, 24, or 30"));
7067
}
7168

69+
// Most ports have a strict requirement for how the rgbmatrix pins are laid
70+
// out; these two micros don't. Special-case it here.
71+
#if !defined(CONFIG_IDF_TARGET_ESP32S3) && !defined(CONFIG_IDF_TARGET_ESP32S2)
72+
uint32_t port = clock_pin / 32;
73+
uint32_t bit_mask = 1 << (clock_pin % 32);
74+
7275
for (uint8_t i = 0; i < rgb_pin_count; i++) {
7376
uint32_t pin_port = rgb_pins[i] / 32;
7477

@@ -130,6 +133,7 @@ STATIC void preflight_pins_or_throw(uint8_t clock_pin, uint8_t *rgb_pins, uint8_
130133
translate("Pinout uses %d bytes per element, which consumes more than the ideal %d bytes. If this cannot be avoided, pass allow_inefficient=True to the constructor"),
131134
bytes_per_element, ideal_bytes_per_element);
132135
}
136+
#endif
133137
}
134138

135139
//| def __init__(
@@ -236,20 +240,14 @@ STATIC mp_obj_t rgbmatrix_rgbmatrix_make_new(const mp_obj_type_t *type, size_t n
236240

237241
preflight_pins_or_throw(clock_pin, rgb_pins, rgb_count, true);
238242

239-
mp_obj_t framebuffer = args[ARG_framebuffer].u_obj;
240-
if (framebuffer == mp_const_none) {
241-
int bufsize = 2 * width * computed_height;
242-
framebuffer = mp_obj_new_bytearray_of_zeros(bufsize);
243-
}
244-
245243
common_hal_rgbmatrix_rgbmatrix_construct(self,
246244
width,
247245
bit_depth,
248246
rgb_count, rgb_pins,
249247
addr_count, addr_pins,
250248
clock_pin, latch_pin, output_enable_pin,
251249
args[ARG_doublebuffer].u_bool,
252-
framebuffer, tile, args[ARG_serpentine].u_bool, NULL);
250+
args[ARG_framebuffer].u_obj, tile, args[ARG_serpentine].u_bool, NULL);
253251

254252
claim_and_never_reset_pins(args[ARG_rgb_list].u_obj);
255253
claim_and_never_reset_pins(args[ARG_addr_list].u_obj);
@@ -353,7 +351,6 @@ STATIC MP_DEFINE_CONST_DICT(rgbmatrix_rgbmatrix_locals_dict, rgbmatrix_rgbmatrix
353351

354352
STATIC void rgbmatrix_rgbmatrix_get_bufinfo(mp_obj_t self_in, mp_buffer_info_t *bufinfo) {
355353
rgbmatrix_rgbmatrix_obj_t *self = (rgbmatrix_rgbmatrix_obj_t *)self_in;
356-
check_for_deinit(self);
357354

358355
*bufinfo = self->bufinfo;
359356
}

shared-bindings/rgbmatrix/RGBMatrix.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ extern const mp_obj_type_t rgbmatrix_RGBMatrix_type;
3434
void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, int width, int bit_depth, uint8_t rgb_count, uint8_t *rgb_pins, uint8_t addr_count, uint8_t *addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, int8_t tile, bool serpentine, void *timer);
3535
void common_hal_rgbmatrix_rgbmatrix_deinit(rgbmatrix_rgbmatrix_obj_t *);
3636
void rgbmatrix_rgbmatrix_collect_ptrs(rgbmatrix_rgbmatrix_obj_t *);
37-
void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t *self, mp_obj_t framebuffer);
37+
void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t *self);
3838
void common_hal_rgbmatrix_rgbmatrix_set_paused(rgbmatrix_rgbmatrix_obj_t *self, bool paused);
3939
bool common_hal_rgbmatrix_rgbmatrix_get_paused(rgbmatrix_rgbmatrix_obj_t *self);
4040
void common_hal_rgbmatrix_rgbmatrix_refresh(rgbmatrix_rgbmatrix_obj_t *self);

shared-module/rgbmatrix/RGBMatrix.c

Lines changed: 54 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242

4343
extern Protomatter_core *_PM_protoPtr;
4444

45+
STATIC void common_hal_rgbmatrix_rgbmatrix_construct1(rgbmatrix_rgbmatrix_obj_t *self, mp_obj_t framebuffer);
46+
4547
void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, int width, int bit_depth, uint8_t rgb_count, uint8_t *rgb_pins, uint8_t addr_count, uint8_t *addr_pins, uint8_t clock_pin, uint8_t latch_pin, uint8_t oe_pin, bool doublebuffer, mp_obj_t framebuffer, int8_t tile, bool serpentine, void *timer) {
4648
self->width = width;
4749
self->bit_depth = bit_depth;
@@ -64,15 +66,11 @@ void common_hal_rgbmatrix_rgbmatrix_construct(rgbmatrix_rgbmatrix_obj_t *self, i
6466
self->width = width;
6567
self->bufsize = 2 * width * common_hal_rgbmatrix_rgbmatrix_get_height(self);
6668

67-
common_hal_rgbmatrix_rgbmatrix_reconstruct(self, framebuffer);
69+
common_hal_rgbmatrix_rgbmatrix_construct1(self, framebuffer);
6870
}
6971

70-
void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t *self, mp_obj_t framebuffer) {
71-
self->paused = 1;
72-
73-
common_hal_rgbmatrix_timer_disable(self->timer);
74-
if (framebuffer) {
75-
self->framebuffer = framebuffer;
72+
STATIC void common_hal_rgbmatrix_rgbmatrix_construct1(rgbmatrix_rgbmatrix_obj_t *self, mp_obj_t framebuffer) {
73+
if (framebuffer != mp_const_none) {
7674
mp_get_buffer_raise(self->framebuffer, &self->bufinfo, MP_BUFFER_READ);
7775
if (mp_get_buffer(self->framebuffer, &self->bufinfo, MP_BUFFER_RW)) {
7876
self->bufinfo.typecode = 'H' | MP_OBJ_ARRAY_TYPECODE_FLAG_RW;
@@ -82,16 +80,11 @@ void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t *self,
8280
// verify that the matrix is big enough
8381
mp_get_index(mp_obj_get_type(self->framebuffer), self->bufinfo.len, MP_OBJ_NEW_SMALL_INT(self->bufsize - 1), false);
8482
} else {
85-
common_hal_rgbmatrix_free_impl(self->bufinfo.buf);
86-
common_hal_rgbmatrix_free_impl(self->protomatter.rgbPins);
87-
common_hal_rgbmatrix_free_impl(self->protomatter.addr);
88-
common_hal_rgbmatrix_free_impl(self->protomatter.screenData);
89-
90-
self->framebuffer = NULL;
9183
self->bufinfo.buf = common_hal_rgbmatrix_allocator_impl(self->bufsize);
9284
self->bufinfo.len = self->bufsize;
9385
self->bufinfo.typecode = 'H' | MP_OBJ_ARRAY_TYPECODE_FLAG_RW;
9486
}
87+
self->framebuffer = framebuffer;
9588

9689
memset(&self->protomatter, 0, sizeof(self->protomatter));
9790
ProtomatterStatus stat = _PM_init(&self->protomatter,
@@ -115,6 +108,9 @@ void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t *self,
115108

116109
if (stat != PROTOMATTER_OK) {
117110
common_hal_rgbmatrix_rgbmatrix_deinit(self);
111+
if (!gc_alloc_possible()) {
112+
return;
113+
}
118114
switch (stat) {
119115
case PROTOMATTER_ERR_PINS:
120116
raise_ValueError_invalid_pin();
@@ -148,35 +144,65 @@ STATIC void free_pin_seq(uint8_t *seq, int count) {
148144
}
149145
}
150146

151-
void common_hal_rgbmatrix_rgbmatrix_deinit(rgbmatrix_rgbmatrix_obj_t *self) {
152-
if (self->timer) {
153-
common_hal_rgbmatrix_timer_free(self->timer);
154-
self->timer = 0;
155-
}
147+
extern int pm_row_count;
148+
STATIC void common_hal_rgbmatrix_rgbmatrix_deinit1(rgbmatrix_rgbmatrix_obj_t *self) {
149+
common_hal_rgbmatrix_timer_disable(self->timer);
156150

157151
if (_PM_protoPtr == &self->protomatter) {
158152
_PM_protoPtr = NULL;
159153
}
160154

161-
free_pin_seq(self->rgb_pins, self->rgb_count);
162-
free_pin_seq(self->addr_pins, self->addr_count);
163-
free_pin(&self->clock_pin);
164-
free_pin(&self->latch_pin);
165-
free_pin(&self->oe_pin);
166-
167155
if (self->protomatter.rgbPins) {
168156
_PM_deallocate(&self->protomatter);
169157
}
158+
170159
memset(&self->protomatter, 0, sizeof(self->protomatter));
171160

172161
// If it was supervisor-allocated, it is supervisor-freed and the pointer
173162
// is zeroed, otherwise the pointer is just zeroed
174-
_PM_free(self->bufinfo.buf);
175-
self->base.type = NULL;
163+
if (self->bufinfo.buf) {
164+
common_hal_rgbmatrix_free_impl(self->bufinfo.buf);
165+
self->bufinfo.buf = NULL;
166+
}
167+
176168

177-
// If a framebuffer was passed in to the constructor, NULL the reference
169+
// If a framebuffer was passed in to the constructor, clear the reference
178170
// here so that it will become GC'able
179-
self->framebuffer = NULL;
171+
self->framebuffer = mp_const_none;
172+
}
173+
174+
void common_hal_rgbmatrix_rgbmatrix_deinit(rgbmatrix_rgbmatrix_obj_t *self) {
175+
common_hal_rgbmatrix_rgbmatrix_deinit1(self);
176+
if (self->timer) {
177+
common_hal_rgbmatrix_timer_free(self->timer);
178+
self->timer = 0;
179+
}
180+
181+
free_pin_seq(self->rgb_pins, self->rgb_count);
182+
free_pin_seq(self->addr_pins, self->addr_count);
183+
free_pin(&self->clock_pin);
184+
free_pin(&self->latch_pin);
185+
free_pin(&self->oe_pin);
186+
187+
self->base.type = &mp_type_NoneType;
188+
}
189+
190+
void common_hal_rgbmatrix_rgbmatrix_reconstruct(rgbmatrix_rgbmatrix_obj_t *self) {
191+
if (self->framebuffer != mp_const_none) {
192+
memset(&self->bufinfo, 0, sizeof(self->bufinfo));
193+
}
194+
#if CIRCUITPY_RGBMATRIX_USES_SUPERVISOR_ALLOCATION
195+
common_hal_rgbmatrix_rgbmatrix_set_paused(self, true);
196+
common_hal_rgbmatrix_rgbmatrix_deinit1(self);
197+
common_hal_rgbmatrix_rgbmatrix_construct1(self, mp_const_none);
198+
#endif
199+
if (self->bufinfo.buf == NULL) {
200+
self->bufinfo.buf = common_hal_rgbmatrix_allocator_impl(self->bufsize);
201+
self->bufinfo.len = self->bufsize;
202+
self->bufinfo.typecode = 'H' | MP_OBJ_ARRAY_TYPECODE_FLAG_RW;
203+
}
204+
memset(self->bufinfo.buf, 0, self->bufinfo.len);
205+
common_hal_rgbmatrix_rgbmatrix_set_paused(self, false);
180206
}
181207

182208
void rgbmatrix_rgbmatrix_collect_ptrs(rgbmatrix_rgbmatrix_obj_t *self) {

shared-module/rgbmatrix/allocator.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,15 @@
3131
#include "py/misc.h"
3232
#include "supervisor/memory.h"
3333

34+
#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32S2)
35+
// Use DMA-capable RAM (not PSRAM) for framebuffer:
36+
#include "components/heap/include/esp_heap_caps.h"
37+
#define _PM_allocate(x) heap_caps_malloc(x, MALLOC_CAP_DMA | MALLOC_CAP_8BIT)
38+
#define _PM_free(x) heap_caps_free(x)
39+
#else
3440
#define _PM_allocate common_hal_rgbmatrix_allocator_impl
3541
#define _PM_free(x) (common_hal_rgbmatrix_free_impl((x)), (x) = NULL, (void)0)
42+
#endif
43+
3644
extern void *common_hal_rgbmatrix_allocator_impl(size_t sz);
3745
extern void common_hal_rgbmatrix_free_impl(void *);

supervisor/shared/display.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -191,7 +191,7 @@ void supervisor_display_move_memory(void) {
191191
#if CIRCUITPY_RGBMATRIX
192192
if (display_buses[i].rgbmatrix.base.type == &rgbmatrix_RGBMatrix_type) {
193193
rgbmatrix_rgbmatrix_obj_t *pm = &display_buses[i].rgbmatrix;
194-
common_hal_rgbmatrix_rgbmatrix_reconstruct(pm, NULL);
194+
common_hal_rgbmatrix_rgbmatrix_reconstruct(pm);
195195
}
196196
#endif
197197
#if CIRCUITPY_SHARPDISPLAY

0 commit comments

Comments
 (0)