Merge pull request #8447 from tannewt/5.1_enable_rgbmatrix

Enable rgbmatrix on IDF 5.1
This commit is contained in:
Dan Halbert 2023-10-06 17:14:04 -04:00 committed by GitHub
commit c9d7195505
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 46 additions and 20 deletions

@ -1 +1 @@
Subproject commit c9c1189e9d6200bb09bf4a87d84be9459cae481b Subproject commit 98a2da6da4bdbfee8f3ab2334871e8c360dccae3

4
main.c
View File

@ -219,6 +219,10 @@ STATIC void stop_mp(void) {
usb_background(); usb_background();
#endif #endif
// Set the qstr pool back to the const pools. The heap allocated ones will
// be overwritten.
qstr_reset();
gc_deinit(); gc_deinit();
} }

View File

@ -7,7 +7,7 @@ IDF_TARGET = esp32s3
CIRCUITPY_ESP_FLASH_SIZE = 4MB CIRCUITPY_ESP_FLASH_SIZE = 4MB
CIRCUITPY_ESP_FLASH_MODE = qio CIRCUITPY_ESP_FLASH_MODE = qio
CIRCUITPY_ESP_FLASH_FREQ = 40m CIRCUITPY_ESP_FLASH_FREQ = 80m
CIRCUITPY_ESP_PSRAM_SIZE = 2MB CIRCUITPY_ESP_PSRAM_SIZE = 2MB
CIRCUITPY_ESP_PSRAM_MODE = qio CIRCUITPY_ESP_PSRAM_MODE = qio

View File

@ -39,8 +39,7 @@ CIRCUITPY_NVM ?= 1
# Turn off because it uses the old I2S driver which conflicts with the new ADC driver. # Turn off because it uses the old I2S driver which conflicts with the new ADC driver.
CIRCUITPY_PARALLELDISPLAY ?= 0 CIRCUITPY_PARALLELDISPLAY ?= 0
CIRCUITPY_PS2IO ?= 1 CIRCUITPY_PS2IO ?= 1
# Disabled temporarily CIRCUITPY_RGBMATRIX ?= 1
CIRCUITPY_RGBMATRIX ?= 0
CIRCUITPY_ROTARYIO ?= 1 CIRCUITPY_ROTARYIO ?= 1
CIRCUITPY_SYNTHIO_MAX_CHANNELS ?= 12 CIRCUITPY_SYNTHIO_MAX_CHANNELS ?= 12
CIRCUITPY_TOUCHIO_USE_NATIVE ?= 1 CIRCUITPY_TOUCHIO_USE_NATIVE ?= 1

View File

@ -122,9 +122,13 @@ extern const qstr_pool_t MICROPY_QSTR_EXTRA_POOL;
#define CONST_POOL mp_qstr_const_pool #define CONST_POOL mp_qstr_const_pool
#endif #endif
void qstr_init(void) { void qstr_reset(void) {
MP_STATE_VM(last_pool) = (qstr_pool_t *)&CONST_POOL; // we won't modify the const_pool since it has no allocated room left MP_STATE_VM(last_pool) = (qstr_pool_t *)&CONST_POOL; // we won't modify the const_pool since it has no allocated room left
MP_STATE_VM(qstr_last_chunk) = NULL; MP_STATE_VM(qstr_last_chunk) = NULL;
}
void qstr_init(void) {
qstr_reset();
#if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL #if MICROPY_PY_THREAD && !MICROPY_PY_THREAD_GIL
mp_thread_mutex_init(&MP_STATE_VM(qstr_mutex)); mp_thread_mutex_init(&MP_STATE_VM(qstr_mutex));

View File

@ -78,6 +78,7 @@ typedef struct _qstr_pool_t {
#define QSTR_TOTAL() (MP_STATE_VM(last_pool)->total_prev_len + MP_STATE_VM(last_pool)->len) #define QSTR_TOTAL() (MP_STATE_VM(last_pool)->total_prev_len + MP_STATE_VM(last_pool)->len)
void qstr_reset(void);
void qstr_init(void); void qstr_init(void);
mp_uint_t qstr_compute_hash(const byte *data, size_t len); mp_uint_t qstr_compute_hash(const byte *data, size_t len);

View File

@ -276,7 +276,7 @@ STATIC mp_obj_t displayio_display_obj_refresh(size_t n_args, const mp_obj_t *pos
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
displayio_display_obj_t *self = native_display(pos_args[0]); displayio_display_obj_t *self = native_display(pos_args[0]);
uint32_t maximum_ms_per_real_frame = 0xffffffff; uint32_t maximum_ms_per_real_frame = NO_FPS_LIMIT;
mp_int_t minimum_frames_per_second = args[ARG_minimum_frames_per_second].u_int; mp_int_t minimum_frames_per_second = args[ARG_minimum_frames_per_second].u_int;
if (minimum_frames_per_second > 0) { if (minimum_frames_per_second > 0) {
maximum_ms_per_real_frame = 1000 / minimum_frames_per_second; maximum_ms_per_real_frame = 1000 / minimum_frames_per_second;
@ -284,7 +284,7 @@ STATIC mp_obj_t displayio_display_obj_refresh(size_t n_args, const mp_obj_t *pos
uint32_t target_ms_per_frame; uint32_t target_ms_per_frame;
if (args[ARG_target_frames_per_second].u_obj == mp_const_none) { if (args[ARG_target_frames_per_second].u_obj == mp_const_none) {
target_ms_per_frame = 0xffffffff; target_ms_per_frame = NO_FPS_LIMIT;
} else { } else {
target_ms_per_frame = 1000 / mp_obj_get_int(args[ARG_target_frames_per_second].u_obj); target_ms_per_frame = 1000 / mp_obj_get_int(args[ARG_target_frames_per_second].u_obj);
} }

View File

@ -35,6 +35,7 @@
extern const mp_obj_type_t displayio_display_type; extern const mp_obj_type_t displayio_display_type;
#define NO_BRIGHTNESS_COMMAND 0x100 #define NO_BRIGHTNESS_COMMAND 0x100
#define NO_FPS_LIMIT 0xffffffff
void common_hal_displayio_display_construct(displayio_display_obj_t *self, void common_hal_displayio_display_construct(displayio_display_obj_t *self,
mp_obj_t bus, uint16_t width, uint16_t height, mp_obj_t bus, uint16_t width, uint16_t height,

View File

@ -100,39 +100,55 @@ static framebufferio_framebufferdisplay_obj_t *native_display(mp_obj_t display_o
} }
//| def refresh( //| def refresh(
//| self, *, target_frames_per_second: int = 60, minimum_frames_per_second: int = 1 //| self,
//| *,
//| target_frames_per_second: Optional[int] = None,
//| minimum_frames_per_second: int = 0
//| ) -> bool: //| ) -> bool:
//| """When auto refresh is off, waits for the target frame rate and then refreshes the display, //| """When auto_refresh is off, and :py:attr:`target_frames_per_second` is not `None` this waits
//| returning True. If the call has taken too long since the last refresh call for the given //| for the target frame rate and then refreshes the display,
//| target frame rate, then the refresh returns False immediately without updating the screen to //| returning `True`. If the call has taken too long since the last refresh call for the given
//| target frame rate, then the refresh returns `False` immediately without updating the screen to
//| hopefully help getting caught up. //| hopefully help getting caught up.
//| //|
//| If the time since the last successful refresh is below the minimum frame rate, then an //| If the time since the last successful refresh is below the minimum frame rate, then an
//| exception will be raised. Set minimum_frames_per_second to 0 to disable. //| exception will be raised. The default :py:attr:`minimum_frames_per_second` of 0 disables this behavior.
//| //|
//| When auto refresh is on, updates the display immediately. (The display will also update //| When auto_refresh is off, and :py:attr:`target_frames_per_second` is `None` this
//| will update the display immediately.
//|
//| When auto_refresh is on, updates the display immediately. (The display will also update
//| without calls to this.) //| without calls to this.)
//| //|
//| :param int target_frames_per_second: How many times a second `refresh` should be called and the screen updated. //| :param Optional[int] target_frames_per_second: The target frame rate that :py:func:`refresh` should try to
//| achieve. Set to `None` for immediate refresh.
//| :param int minimum_frames_per_second: The minimum number of times the screen should be updated per second. //| :param int minimum_frames_per_second: The minimum number of times the screen should be updated per second.
//| """ //| """
//| ... //| ...
STATIC mp_obj_t framebufferio_framebufferdisplay_obj_refresh(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) { STATIC mp_obj_t framebufferio_framebufferdisplay_obj_refresh(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
enum { ARG_target_frames_per_second, ARG_minimum_frames_per_second }; enum { ARG_target_frames_per_second, ARG_minimum_frames_per_second };
static const mp_arg_t allowed_args[] = { static const mp_arg_t allowed_args[] = {
{ MP_QSTR_target_frames_per_second, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 60} }, { MP_QSTR_target_frames_per_second, MP_ARG_OBJ | MP_ARG_KW_ONLY, {.u_obj = mp_const_none} },
{ MP_QSTR_minimum_frames_per_second, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 1} }, { MP_QSTR_minimum_frames_per_second, MP_ARG_KW_ONLY | MP_ARG_INT, {.u_int = 0} },
}; };
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)]; mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args); mp_arg_parse_all(n_args - 1, pos_args + 1, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
framebufferio_framebufferdisplay_obj_t *self = native_display(pos_args[0]); framebufferio_framebufferdisplay_obj_t *self = native_display(pos_args[0]);
uint32_t maximum_ms_per_real_frame = 0xffffffff; uint32_t maximum_ms_per_real_frame = NO_FPS_LIMIT;
mp_int_t minimum_frames_per_second = args[ARG_minimum_frames_per_second].u_int; mp_int_t minimum_frames_per_second = args[ARG_minimum_frames_per_second].u_int;
if (minimum_frames_per_second > 0) { if (minimum_frames_per_second > 0) {
maximum_ms_per_real_frame = 1000 / minimum_frames_per_second; maximum_ms_per_real_frame = 1000 / minimum_frames_per_second;
} }
return mp_obj_new_bool(common_hal_framebufferio_framebufferdisplay_refresh(self, 1000 / args[ARG_target_frames_per_second].u_int, maximum_ms_per_real_frame));
uint32_t target_ms_per_frame;
if (args[ARG_target_frames_per_second].u_obj == mp_const_none) {
target_ms_per_frame = NO_FPS_LIMIT;
} else {
target_ms_per_frame = 1000 / mp_obj_get_int(args[ARG_target_frames_per_second].u_obj);
}
return mp_obj_new_bool(common_hal_framebufferio_framebufferdisplay_refresh(self, target_ms_per_frame, maximum_ms_per_real_frame));
} }
MP_DEFINE_CONST_FUN_OBJ_KW(framebufferio_framebufferdisplay_refresh_obj, 1, framebufferio_framebufferdisplay_obj_refresh); MP_DEFINE_CONST_FUN_OBJ_KW(framebufferio_framebufferdisplay_refresh_obj, 1, framebufferio_framebufferdisplay_obj_refresh);

View File

@ -36,6 +36,7 @@
extern const mp_obj_type_t framebufferio_framebufferdisplay_type; extern const mp_obj_type_t framebufferio_framebufferdisplay_type;
#define NO_BRIGHTNESS_COMMAND 0x100 #define NO_BRIGHTNESS_COMMAND 0x100
#define NO_FPS_LIMIT 0xffffffff
void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebufferdisplay_obj_t *self, void common_hal_framebufferio_framebufferdisplay_construct(framebufferio_framebufferdisplay_obj_t *self,
mp_obj_t framebuffer, mp_obj_t framebuffer,

View File

@ -354,7 +354,7 @@ uint16_t common_hal_displayio_display_get_rotation(displayio_display_obj_t *self
bool common_hal_displayio_display_refresh(displayio_display_obj_t *self, uint32_t target_ms_per_frame, uint32_t maximum_ms_per_real_frame) { bool common_hal_displayio_display_refresh(displayio_display_obj_t *self, uint32_t target_ms_per_frame, uint32_t maximum_ms_per_real_frame) {
if (!self->auto_refresh && !self->first_manual_refresh && (target_ms_per_frame != 0xffffffff)) { if (!self->auto_refresh && !self->first_manual_refresh && (target_ms_per_frame != NO_FPS_LIMIT)) {
uint64_t current_time = supervisor_ticks_ms64(); uint64_t current_time = supervisor_ticks_ms64();
uint32_t current_ms_since_real_refresh = current_time - self->core.last_refresh; uint32_t current_ms_since_real_refresh = current_time - self->core.last_refresh;
// Test to see if the real frame time is below our minimum. // Test to see if the real frame time is below our minimum.

View File

@ -283,7 +283,7 @@ uint16_t common_hal_framebufferio_framebufferdisplay_get_rotation(framebufferio_
bool common_hal_framebufferio_framebufferdisplay_refresh(framebufferio_framebufferdisplay_obj_t *self, uint32_t target_ms_per_frame, uint32_t maximum_ms_per_real_frame) { bool common_hal_framebufferio_framebufferdisplay_refresh(framebufferio_framebufferdisplay_obj_t *self, uint32_t target_ms_per_frame, uint32_t maximum_ms_per_real_frame) {
if (!self->auto_refresh && !self->first_manual_refresh) { if (!self->auto_refresh && !self->first_manual_refresh && (target_ms_per_frame != NO_FPS_LIMIT)) {
uint64_t current_time = supervisor_ticks_ms64(); uint64_t current_time = supervisor_ticks_ms64();
uint32_t current_ms_since_real_refresh = current_time - self->core.last_refresh; uint32_t current_ms_since_real_refresh = current_time - self->core.last_refresh;
// Test to see if the real frame time is below our minimum. // Test to see if the real frame time is below our minimum.