From 334d91c3c28b3ad62473e1506ab1622902f84b0b Mon Sep 17 00:00:00 2001 From: Mike S Date: Sun, 8 Jun 2025 09:27:37 -0400 Subject: [PATCH 1/5] Upate Camera support to reflect changes in API --- libraries/Camera/src/camera.cpp | 20 +++++++++++--------- loader/llext_exports.c | 1 + 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/libraries/Camera/src/camera.cpp b/libraries/Camera/src/camera.cpp index af00dbfb0..fd4ac2acc 100644 --- a/libraries/Camera/src/camera.cpp +++ b/libraries/Camera/src/camera.cpp @@ -70,8 +70,8 @@ bool Camera::begin(uint32_t width, uint32_t height, uint32_t pixformat, bool byt } // Get capabilities - struct video_caps caps = {0}; - if (video_get_caps(this->vdev, VIDEO_EP_OUT, &caps)) { + struct video_caps caps; + if (video_get_caps(this->vdev, &caps)) { return false; } @@ -96,7 +96,7 @@ bool Camera::begin(uint32_t width, uint32_t height, uint32_t pixformat, bool byt .pitch = width * 2, }; - if (video_set_format(this->vdev, VIDEO_EP_OUT, &fmt)) { + if (video_set_format(this->vdev, &fmt)) { Serial.println("Failed to set video format"); return false; } @@ -110,11 +110,11 @@ bool Camera::begin(uint32_t width, uint32_t height, uint32_t pixformat, bool byt Serial.println("Failed to allocate video buffers"); return false; } - video_enqueue(this->vdev, VIDEO_EP_OUT, this->vbuf[i]); + video_enqueue(this->vdev, this->vbuf[i]); } // Start video capture - if (video_stream_start(this->vdev)) { + if (video_stream_start(this->vdev, VIDEO_BUF_TYPE_OUTPUT)) { Serial.println("Failed to start capture"); return false; } @@ -127,7 +127,7 @@ bool Camera::grabFrame(FrameBuffer &fb, uint32_t timeout) { return false; } - if (video_dequeue(this->vdev, VIDEO_EP_OUT, &fb.vbuf, K_MSEC(timeout))) { + if (video_dequeue(this->vdev, &fb.vbuf, K_MSEC(timeout))) { return false; } @@ -154,7 +154,7 @@ bool Camera::releaseFrame(FrameBuffer &fb) { return false; } - if (video_enqueue(this->vdev, VIDEO_EP_OUT, fb.vbuf)) { + if (video_enqueue(this->vdev, fb.vbuf)) { return false; } @@ -162,9 +162,11 @@ bool Camera::releaseFrame(FrameBuffer &fb) { } bool Camera::setVerticalFlip(bool flip_enable) { - return video_set_ctrl(this->vdev, VIDEO_CID_VFLIP, (void *) flip_enable) == 0; + struct video_control ctrl = {.id = VIDEO_CID_VFLIP, .val = flip_enable}; + return video_set_ctrl(this->vdev, &ctrl) == 0; } bool Camera::setHorizontalMirror(bool mirror_enable) { - return video_set_ctrl(this->vdev, VIDEO_CID_HFLIP, (void *) mirror_enable) == 0; + struct video_control ctrl = {.id = VIDEO_CID_HFLIP, .val = mirror_enable}; + return video_set_ctrl(this->vdev, &ctrl) == 0; } diff --git a/loader/llext_exports.c b/loader/llext_exports.c index 52d214c17..f6f8c85ec 100644 --- a/loader/llext_exports.c +++ b/loader/llext_exports.c @@ -129,6 +129,7 @@ FORCE_EXPORT_SYM(__stack_chk_fail); FORCE_EXPORT_SYM(video_buffer_aligned_alloc); FORCE_EXPORT_SYM(video_buffer_alloc); FORCE_EXPORT_SYM(video_buffer_release); +FORCE_EXPORT_SYM(video_set_ctrl); #endif #if defined(CONFIG_SHARED_MULTI_HEAP) From 66757bc85532cb0a9db56e6943303782e0a42637 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Wed, 30 Apr 2025 10:03:08 +0300 Subject: [PATCH 2/5] loader/fixup: Fix SMH init priority. Probably a copy&paste error. --- loader/fixups.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/loader/fixups.c b/loader/fixups.c index 5832319cf..cf5e60cd1 100644 --- a/loader/fixups.c +++ b/loader/fixups.c @@ -99,7 +99,7 @@ int smh_init(void) { return 0; } -SYS_INIT(smh_init, POST_KERNEL, CONFIG_CLOCK_CONTROL_PWM_INIT_PRIORITY); +SYS_INIT(smh_init, POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT); #endif #if defined(CONFIG_BOARD_ARDUINO_PORTENTA_C33) && defined(CONFIG_LLEXT) @@ -144,4 +144,4 @@ int maybe_flash_bootloader(void) SYS_INIT(maybe_flash_bootloader, POST_KERNEL, CONFIG_FILE_SYSTEM_INIT_PRIORITY); -#endif \ No newline at end of file +#endif From 946f426720b88683172955227fe1c333a4f77c9f Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Wed, 30 Apr 2025 10:06:11 +0300 Subject: [PATCH 3/5] variants/arduino_giga_r1_stm32h747xx_m7: Enable SMH for display. The LTDC will have its own SMH option, and the upstream shield config will Not enable this by default. --- .../arduino_giga_r1_stm32h747xx_m7.conf | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/variants/arduino_giga_r1_stm32h747xx_m7/arduino_giga_r1_stm32h747xx_m7.conf b/variants/arduino_giga_r1_stm32h747xx_m7/arduino_giga_r1_stm32h747xx_m7.conf index 5ffbcf1b6..1305dea14 100644 --- a/variants/arduino_giga_r1_stm32h747xx_m7/arduino_giga_r1_stm32h747xx_m7.conf +++ b/variants/arduino_giga_r1_stm32h747xx_m7/arduino_giga_r1_stm32h747xx_m7.conf @@ -45,4 +45,6 @@ CONFIG_VIDEO_BUFFER_SMH_ATTRIBUTE=2 CONFIG_VIDEO_GC2145=y CONFIG_DISPLAY=y -CONFIG_INPUT=y \ No newline at end of file +CONFIG_INPUT=y +CONFIG_STM32_LTDC_FB_USE_SHARED_MULTI_HEAP=y +CONFIG_STM32_LTDC_FB_SMH_ATTRIBUTE=2 From 8d40a219a8863177c572dfe0bc5de945935c8b4c Mon Sep 17 00:00:00 2001 From: Kurt Eckhardt Date: Thu, 5 Jun 2025 08:05:07 -0700 Subject: [PATCH 4/5] Beginning touch support Add a callback function for the touch device within the fixups for the GIGA. This callback simply remembers the last touch that happened and sets a semaphore. There is also a function added to retrieve this data. Needed to add the callback function into the exports file. --- loader/fixups.c | 48 ++++++++++++++++++++++++++++++++++++++++++ loader/llext_exports.c | 3 +++ 2 files changed, 51 insertions(+) diff --git a/loader/fixups.c b/loader/fixups.c index cf5e60cd1..8249218ea 100644 --- a/loader/fixups.c +++ b/loader/fixups.c @@ -45,10 +45,58 @@ SYS_INIT(disable_mpu_rasr_xn, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT) #include #include +#include + +// experiment to try to capture touch screen events +typedef struct { + int32_t x; + int32_t y; + int32_t pressed; +} touch_point_t; + +touch_point_t last_touch_point; + +static struct k_sem touch_event_sync; + +bool getVideoTouchEvent(touch_point_t *tp, k_timeout_t timeout) { + if (k_sem_take(&touch_event_sync, timeout) != 0) return false; + // BUGBUG: should probably put stuff in to return only + // data from whole event, but first see if anything works + memcpy(tp, &last_touch_point, sizeof(touch_point_t)); + return true; +} + + +void touch_event_callback(struct input_event *evt, void *user_data) +{ + //printk("touch_event_callback(%p %p): %p %u %u %u %d\n", evt, user_data, + // evt->dev, evt->sync, evt->type, evt->code, evt->value); + if (evt->code == INPUT_ABS_X) { + last_touch_point.x = evt->value; + } + if (evt->code == INPUT_ABS_Y) { + last_touch_point.y = evt->value; + } + if (evt->code == INPUT_BTN_TOUCH) { + last_touch_point.pressed = evt->value; + } + if (evt->sync) { + k_sem_give(&touch_event_sync); + } +} +static const struct device *const touch_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_touch)); +INPUT_CALLBACK_DEFINE(touch_dev, touch_event_callback, NULL); + + int camera_ext_clock_enable(void) { int ret; uint32_t rate; + + // Hack in init semaphore for touch events + k_sem_init(&touch_event_sync, 0, 1); + + const struct device *cam_ext_clk_dev = DEVICE_DT_GET(DT_NODELABEL(pwmclock)); if (!device_is_ready(cam_ext_clk_dev)) { diff --git a/loader/llext_exports.c b/loader/llext_exports.c index f6f8c85ec..310079cb2 100644 --- a/loader/llext_exports.c +++ b/loader/llext_exports.c @@ -131,6 +131,9 @@ FORCE_EXPORT_SYM(video_buffer_alloc); FORCE_EXPORT_SYM(video_buffer_release); FORCE_EXPORT_SYM(video_set_ctrl); #endif +#if defined(CONFIG_BOARD_ARDUINO_GIGA_R1) && defined(CONFIG_VIDEO) +FORCE_EXPORT_SYM(getVideoTouchEvent) +#endif #if defined(CONFIG_SHARED_MULTI_HEAP) FORCE_EXPORT_SYM(shared_multi_heap_aligned_alloc); From a046e8dd046273b63b0bb4454f907e8f749e4ea0 Mon Sep 17 00:00:00 2001 From: kurte Date: Sat, 7 Jun 2025 05:24:47 -0700 Subject: [PATCH 5/5] GIGA touch - convert callback to simple forward instead of processing in the fixups.c Also add clear out the callback in the initVariant such that if new program is launched it does not use old address --- loader/fixups.c | 36 ++++++++++++++++--- loader/llext_exports.c | 4 ++- .../variant.cpp | 7 ++++ 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/loader/fixups.c b/loader/fixups.c index 8249218ea..2e79c4615 100644 --- a/loader/fixups.c +++ b/loader/fixups.c @@ -48,10 +48,34 @@ SYS_INIT(disable_mpu_rasr_xn, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT) #include // experiment to try to capture touch screen events +#define GIGA_TOUCH_SET_CB +#ifdef GIGA_TOUCH_SET_CB +// This version we just register a callback function with the zephyr +// object, which then allows are Arduino Code to register a call back +// to be called... + + +void (*_giga_touch_callback)(struct input_event *evt, void *user_data) = 0; + +void registerGigaTouchCallback(void (*cb)(struct input_event *evt, void *user_data)) { + _giga_touch_callback = cb; +} + + +void touch_event_callback(struct input_event *evt, void *user_data) +{ + //printk("touch_event_callback(%p %p): %p %u %u %u %d\n", evt, user_data, + // evt->dev, evt->sync, evt->type, evt->code, evt->value); + if (_giga_touch_callback) { + (*_giga_touch_callback)(evt, user_data); + + } +} +#else typedef struct { - int32_t x; - int32_t y; - int32_t pressed; + size_t x; + size_t y; + bool pressed; } touch_point_t; touch_point_t last_touch_point; @@ -84,18 +108,22 @@ void touch_event_callback(struct input_event *evt, void *user_data) k_sem_give(&touch_event_sync); } } +#endif + static const struct device *const touch_dev = DEVICE_DT_GET(DT_CHOSEN(zephyr_touch)); INPUT_CALLBACK_DEFINE(touch_dev, touch_event_callback, NULL); + int camera_ext_clock_enable(void) { int ret; uint32_t rate; +#ifndef GIGA_TOUCH_SET_CB // Hack in init semaphore for touch events k_sem_init(&touch_event_sync, 0, 1); - +#endif const struct device *cam_ext_clk_dev = DEVICE_DT_GET(DT_NODELABEL(pwmclock)); diff --git a/loader/llext_exports.c b/loader/llext_exports.c index 310079cb2..f2a8bc0bd 100644 --- a/loader/llext_exports.c +++ b/loader/llext_exports.c @@ -132,7 +132,9 @@ FORCE_EXPORT_SYM(video_buffer_release); FORCE_EXPORT_SYM(video_set_ctrl); #endif #if defined(CONFIG_BOARD_ARDUINO_GIGA_R1) && defined(CONFIG_VIDEO) -FORCE_EXPORT_SYM(getVideoTouchEvent) +//FORCE_EXPORT_SYM(getVideoTouchEvent); +FORCE_EXPORT_SYM(registerGigaTouchCallback); + #endif #if defined(CONFIG_SHARED_MULTI_HEAP) diff --git a/variants/arduino_giga_r1_stm32h747xx_m7/variant.cpp b/variants/arduino_giga_r1_stm32h747xx_m7/variant.cpp index 786c9712f..b62b4a8b6 100644 --- a/variants/arduino_giga_r1_stm32h747xx_m7/variant.cpp +++ b/variants/arduino_giga_r1_stm32h747xx_m7/variant.cpp @@ -6,3 +6,10 @@ void _on_1200_bps() { *(__IO uint32_t *)tmp = (uint32_t)0xDF59; NVIC_SystemReset(); } + +extern "C" void registerGigaTouchCallback(void (*cb)(struct input_event *evt, void *user_data)); +void initVariant(void) { + // Make sure to set to NULL in case previous sketch or pvevious build of sketch + // set a callback, whoes pointer may not be valid + registerGigaTouchCallback(nullptr); +}