From d4aab422eefd85a7faa9e475b88e9093b2eb19e3 Mon Sep 17 00:00:00 2001 From: Kamil Tomaszewski Date: Sat, 14 Jan 2023 20:31:06 +0100 Subject: [PATCH 1/6] spresense: update SDK to 2.6.0 --- ports/cxd56/README.md | 2 +- ports/cxd56/configs/circuitpython/defconfig | 1 + ports/cxd56/spresense-exported-sdk | 2 +- ports/cxd56/supervisor/port.c | 4 ++-- 4 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ports/cxd56/README.md b/ports/cxd56/README.md index 0656ad1f1a..4266c61c0c 100644 --- a/ports/cxd56/README.md +++ b/ports/cxd56/README.md @@ -75,7 +75,7 @@ Bootloader information: * You have to accept the End User License Agreement to be able to download and use the Spresense bootloader binary. -Download the spresense binaries zip archive from: [Spresense firmware v2-3-000](https://developer.sony.com/file/download/download-spresense-firmware-v2-3-000) +Download the spresense binaries zip archive from: [Spresense firmware v2-4-000](https://developer.sony.com/file/download/download-spresense-firmware-v2-4-000) Extract spresense binaries in your PC to ports/spresense/spresense-exported-sdk/firmware/ diff --git a/ports/cxd56/configs/circuitpython/defconfig b/ports/cxd56/configs/circuitpython/defconfig index 6a7c39cba8..92e282649b 100644 --- a/ports/cxd56/configs/circuitpython/defconfig +++ b/ports/cxd56/configs/circuitpython/defconfig @@ -113,4 +113,5 @@ CONFIG_USEC_PER_TICK=1000 CONFIG_USERMAIN_STACKSIZE=8192 CONFIG_USER_ENTRYPOINT="spresense_main" CONFIG_VIDEO_ISX012=y +CONFIG_VIDEO_ISX019=y CONFIG_VIDEO_STREAM=y diff --git a/ports/cxd56/spresense-exported-sdk b/ports/cxd56/spresense-exported-sdk index 6a148be849..4f902ca3ff 160000 --- a/ports/cxd56/spresense-exported-sdk +++ b/ports/cxd56/spresense-exported-sdk @@ -1 +1 @@ -Subproject commit 6a148be8497704d4afb5d14c175a12a592813fac +Subproject commit 4f902ca3ffeb327e6c325940ef5133eda588c2e4 diff --git a/ports/cxd56/supervisor/port.c b/ports/cxd56/supervisor/port.c index 10fa4112e8..dfd3cd6646 100644 --- a/ports/cxd56/supervisor/port.c +++ b/ports/cxd56/supervisor/port.c @@ -111,13 +111,13 @@ bool port_has_fixed_stack(void) { uint32_t *port_stack_get_limit(void) { struct tcb_s *rtcb = this_task(); - return rtcb->adj_stack_ptr - (uint32_t)rtcb->adj_stack_size; + return rtcb->stack_base_ptr; } uint32_t *port_stack_get_top(void) { struct tcb_s *rtcb = this_task(); - return rtcb->adj_stack_ptr; + return rtcb->stack_base_ptr + (uint32_t)rtcb->adj_stack_size; } uint32_t *port_heap_get_bottom(void) { From 3fdebd4f608a0973b3de6303a1367fbe12cd1575 Mon Sep 17 00:00:00 2001 From: Kamil Tomaszewski Date: Wed, 1 Feb 2023 12:37:29 +0100 Subject: [PATCH 2/6] spresense: Add HDR camera support --- ports/cxd56/common-hal/camera/Camera.c | 36 +++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/ports/cxd56/common-hal/camera/Camera.c b/ports/cxd56/common-hal/camera/Camera.c index f304ed8f74..606ad0f1e6 100644 --- a/ports/cxd56/common-hal/camera/Camera.c +++ b/ports/cxd56/common-hal/camera/Camera.c @@ -47,7 +47,7 @@ typedef struct { uint16_t height; } image_size_t; -STATIC const image_size_t image_size_table[] = { +STATIC const image_size_t isx012_image_size_table[] = { { VIDEO_HSIZE_QVGA, VIDEO_VSIZE_QVGA }, { VIDEO_HSIZE_VGA, VIDEO_VSIZE_VGA }, { VIDEO_HSIZE_HD, VIDEO_VSIZE_HD }, @@ -57,12 +57,40 @@ STATIC const image_size_t image_size_table[] = { { VIDEO_HSIZE_5M, VIDEO_VSIZE_5M }, }; +STATIC const image_size_t isx019_image_size_table[] = { + { VIDEO_HSIZE_QVGA, VIDEO_VSIZE_QVGA }, + { VIDEO_HSIZE_VGA, VIDEO_VSIZE_VGA }, + { VIDEO_HSIZE_HD, VIDEO_VSIZE_HD }, + { VIDEO_HSIZE_QUADVGA, VIDEO_VSIZE_QUADVGA }, +}; + +static const char *get_imgsensor_name() { + static struct v4l2_capability cap; + + ioctl(camera_dev.fd, VIDIOC_QUERYCAP, (unsigned long)&cap); + + return (const char *)cap.driver; +} + static bool camera_check_width_and_height(uint16_t width, uint16_t height) { - for (int i = 0; i < MP_ARRAY_SIZE(image_size_table); i++) { - if (image_size_table[i].width == width && image_size_table[i].height == height) { - return true; + const char *sensor; + + sensor = get_imgsensor_name(); + + if (strncmp(sensor, "ISX012", strlen("ISX012")) == 0) { + for (int i = 0; i < MP_ARRAY_SIZE(isx012_image_size_table); i++) { + if (isx012_image_size_table[i].width == width && isx012_image_size_table[i].height == height) { + return true; + } + } + } else if (strncmp(sensor, "ISX019", strlen("ISX019"))) { + for (int i = 0; i < MP_ARRAY_SIZE(isx019_image_size_table); i++) { + if (isx019_image_size_table[i].width == width && isx019_image_size_table[i].height == height) { + return true; + } } } + return false; } From b9f689adf407a0062c2d5d0e27883f2e978716b1 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Wed, 8 Feb 2023 16:18:45 -0600 Subject: [PATCH 3/6] Use lowest drive level for PIO --- ports/raspberrypi/common-hal/rp2pio/StateMachine.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ports/raspberrypi/common-hal/rp2pio/StateMachine.c b/ports/raspberrypi/common-hal/rp2pio/StateMachine.c index ecaee90cc2..e9cb3d34bb 100644 --- a/ports/raspberrypi/common-hal/rp2pio/StateMachine.c +++ b/ports/raspberrypi/common-hal/rp2pio/StateMachine.c @@ -289,6 +289,11 @@ bool rp2pio_statemachine_construct(rp2pio_statemachine_obj_t *self, } pio_gpio_init(self->pio, pin_number); } + + // Use lowest drive level for all State Machine outputs. (#7515 + // workaround). Remove if/when Pin objects get a drive_strength + // property and use that value instead. + gpio_set_drive_strength(pin_number, GPIO_DRIVE_STRENGTH_2MA); } pio_sm_config c = {0, 0, 0}; From 0d957fe15cbdca39d3d670129e0d891ca0f55b23 Mon Sep 17 00:00:00 2001 From: Jeff Epler Date: Fri, 10 Feb 2023 08:44:58 -0600 Subject: [PATCH 4/6] Fix several places where an exception could be chained wrongly If an exception's chain or context can refer to a pointer from a different VM, a crash would typically result. This couldn't turn up on UNIX testing because the VM is never torn down and rebuilt like it is on hardware. Because in the 'static' case the GeneratorObject is now fully initialized whenever it's raised, the initialization can be dropped, which reduces the flash size slightly. Closes: #7565 --- py/objexcept.c | 12 ++++++++++++ py/objexcept.h | 1 + py/objgenerator.c | 7 +++---- py/runtime.c | 8 ++------ 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/py/objexcept.c b/py/objexcept.c index 976535754b..24fb564e23 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -155,6 +155,12 @@ void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kin mp_obj_tuple_print(print, MP_OBJ_FROM_PTR(o->args), kind); } +void mp_obj_exception_initialize0(mp_obj_exception_t *o_exc, const mp_obj_type_t *type) { + o_exc->base.type = type; + o_exc->args = (mp_obj_tuple_t *)&mp_const_empty_tuple_obj; + mp_obj_exception_clear_traceback(o_exc); +} + mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type, size_t n_args, size_t n_kw, const mp_obj_t *args) { mp_arg_check_num(n_args, n_kw, 0, MP_OBJ_FUN_ARGS_MAX, false); @@ -583,6 +589,12 @@ void mp_obj_exception_clear_traceback(mp_obj_t self_in) { // just set the traceback to the empty traceback object // we don't want to call any memory management functions here self->traceback = (mp_obj_traceback_t *)&mp_const_empty_traceback_obj; + #if MICROPY_CPYTHON_EXCEPTION_CHAIN + self->cause = 0; + self->context = 0; + self->suppress_context = false; + self->marked = false; + #endif } void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, size_t line, qstr block) { diff --git a/py/objexcept.h b/py/objexcept.h index 77b338e951..1230fdf18a 100644 --- a/py/objexcept.h +++ b/py/objexcept.h @@ -43,6 +43,7 @@ typedef struct _mp_obj_exception_t { void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kind_t kind); void mp_obj_exception_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest); +void mp_obj_exception_initialize0(mp_obj_exception_t *o_exc, const mp_obj_type_t *type); mp_obj_exception_t *mp_obj_exception_get_native(mp_obj_t self_in); #define MP_DEFINE_EXCEPTION(exc_name, base_name) \ diff --git a/py/objgenerator.c b/py/objgenerator.c index 2256911e23..7c3ec99307 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -40,10 +40,11 @@ // Instance of GeneratorExit exception - needed by generator.close() #if MICROPY_CONST_GENERATOREXIT_OBJ const +mp_obj_exception_t mp_static_GeneratorExit_obj = {{&mp_type_GeneratorExit}, (mp_obj_tuple_t *)&mp_const_empty_tuple_obj, (mp_obj_traceback_t *)&mp_const_empty_traceback_obj}; #else static +mp_obj_exception_t mp_static_GeneratorExit_obj; #endif -mp_obj_exception_t mp_static_GeneratorExit_obj = {{&mp_type_GeneratorExit}, (mp_obj_tuple_t *)&mp_const_empty_tuple_obj, (mp_obj_traceback_t *)&mp_const_empty_traceback_obj}; /******************************************************************************/ /* generator wrapper */ @@ -370,9 +371,7 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(gen_instance_throw_obj, 2, 4, gen_ins static mp_obj_t generatorexit(void) { #if MICROPY_CPYTHON_EXCEPTION_CHAIN MP_STATIC_ASSERT(!MICROPY_CONST_GENERATOREXIT_OBJ); - mp_static_GeneratorExit_obj.context = NULL; - mp_static_GeneratorExit_obj.cause = NULL; - mp_static_GeneratorExit_obj.suppress_context = false; + mp_obj_exception_initialize0(&mp_static_GeneratorExit_obj, &mp_type_GeneratorExit); #endif return MP_OBJ_FROM_PTR(&mp_static_GeneratorExit_obj); } diff --git a/py/runtime.c b/py/runtime.c index 9779456d0c..9227594d83 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -78,14 +78,10 @@ void mp_init(void) { #if MICROPY_KBD_EXCEPTION // initialise the exception object for raising KeyboardInterrupt - MP_STATE_VM(mp_kbd_exception).base.type = &mp_type_KeyboardInterrupt; - MP_STATE_VM(mp_kbd_exception).args = (mp_obj_tuple_t *)&mp_const_empty_tuple_obj; - MP_STATE_VM(mp_kbd_exception).traceback = (mp_obj_traceback_t *)&mp_const_empty_traceback_obj; + mp_obj_exception_initialize0(&MP_STATE_VM(mp_kbd_exception), &mp_type_KeyboardInterrupt); #endif - MP_STATE_VM(mp_reload_exception).base.type = &mp_type_ReloadException; - MP_STATE_VM(mp_reload_exception).args = (mp_obj_tuple_t *)&mp_const_empty_tuple_obj; - MP_STATE_VM(mp_reload_exception).traceback = (mp_obj_traceback_t *)&mp_const_empty_traceback_obj; + mp_obj_exception_initialize0(&MP_STATE_VM(mp_reload_exception), &mp_type_ReloadException); // call port specific initialization if any #ifdef MICROPY_PORT_INIT_FUNC From cec36b62f1843901be0574fecc84e83ef5fa246a Mon Sep 17 00:00:00 2001 From: Neradoc Date: Fri, 10 Feb 2023 04:58:37 +0100 Subject: [PATCH 5/6] Update build_board_info.py to sh module 2.0.0 --- tools/build_board_info.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tools/build_board_info.py b/tools/build_board_info.py index f810d942a7..5209337b95 100755 --- a/tools/build_board_info.py +++ b/tools/build_board_info.py @@ -10,6 +10,7 @@ import subprocess import sys import sh import base64 +from io import StringIO from datetime import date from sh.contrib import git @@ -58,9 +59,13 @@ def get_languages(list_all=False): def get_version_info(): version = None - sha = git("rev-parse", "--short", "HEAD").stdout.decode("utf-8") + buffer = StringIO() + git("rev-parse", "--short", "HEAD", _out=buffer) + sha = buffer.getvalue().strip() try: - version = git("describe", "--tags", "--exact-match").stdout.decode("utf-8").strip() + buffer = StringIO() + git("describe", "--tags", "--exact-match", _out=buffer) + version = buffer.getvalue().strip() except sh.ErrorReturnCode_128: # No exact match pass From 3c93594563443a8e219f3df6c149f2169ec5bd6b Mon Sep 17 00:00:00 2001 From: Neradoc Date: Fri, 10 Feb 2023 19:54:10 +0100 Subject: [PATCH 6/6] Deinit the reset pin when displayio.I2CDisplay raises an exception --- shared-module/displayio/I2CDisplay.c | 1 + 1 file changed, 1 insertion(+) diff --git a/shared-module/displayio/I2CDisplay.c b/shared-module/displayio/I2CDisplay.c index 8fae5d31fd..f38e4d6296 100644 --- a/shared-module/displayio/I2CDisplay.c +++ b/shared-module/displayio/I2CDisplay.c @@ -54,6 +54,7 @@ void common_hal_displayio_i2cdisplay_construct(displayio_i2cdisplay_obj_t *self, // Probe the bus to see if a device acknowledges the given address. if (!common_hal_busio_i2c_probe(i2c, device_address)) { self->base.type = &mp_type_NoneType; + common_hal_displayio_i2cdisplay_deinit(self); mp_raise_ValueError_varg(translate("Unable to find I2C Display at %x"), device_address); }