Skip to content

Add support for Renesas RA CEU (Capture Engine Unit) for RA8M1 and RA8D1 #92146

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from

Conversation

thaoluonguw
Copy link
Contributor

Add support for Renesas RA CEU (Capture Engine Unit):

  • Add video driver use CEU
  • Add dts for CEU on RA8M1 and RA8D1
  • Enable CEU support for EK-RA8D1
  • Add support for EK-RA8D1 on Video capture to LVGL sample.
    It works with OV7670 camera, and MIPI graphics expansion board included in the Kit

Copy link

github-actions bot commented Jun 25, 2025

The following west manifest projects have changed revision in this Pull Request:

Name Old Revision New Revision Diff
hal_renesas zephyrproject-rtos/hal_renesas@0769fe1 zephyrproject-rtos/hal_renesas@985d39b (main) zephyrproject-rtos/[email protected]

All manifest checks OK

Note: This message is automatically posted and updated by the Manifest GitHub Action.

@github-actions github-actions bot added manifest manifest-hal_renesas DNM (manifest) This PR should not be merged (controlled by action-manifest) labels Jun 25, 2025
Copy link
Contributor

@josuah josuah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for implementing the Renesas video driver!

The driver appears in a good shape WRT video APIs, with a few key points to modify (marked with :x), and a few proposal to improve it further, non-blocking (i.e. could be improved over time eventually, although appreciated if modified now).

Let me know if anything needs clarifications.

@josuah
Copy link
Contributor

josuah commented Jun 26, 2025

[blocking ❌]
In order to make sure this driver always compiles even after Video APIs are refactored, you may want to add it to this test that will run on CI on every video-related commit:
tests/drivers/build_all/video/app.overlay

}
}

static int video_renesas_ra_ceu_get_format(const struct device *dev, struct video_format *fmt)
Copy link
Contributor

@ngphibang ngphibang Jun 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Function name is rather long, could it be shorten like ra_ceu_get_format ?. Idem for others

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thaoluonguw : This is a small point but do you think it's better to shorten the function name a bit ? The prefix video_renesas_ seems not needed as all these functions are static, no worry that other functions will have the same name

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there is a _csi variant coming at some point. This would become ra_csi_get_format then I guess...

scrot_20250711_142621_1172x179

Update hal_renesas to support CEU on RA SoCs

Signed-off-by: Duy Vo <[email protected]>
Signed-off-by: Khanh Nguyen <[email protected]>
@thaoluonguw thaoluonguw force-pushed the support_renesas_ra_ceu branch from 92a4b3b to 03bdbce Compare July 4, 2025 04:15
@github-actions github-actions bot added the area: Shields Shields (add-on boards) label Jul 4, 2025
@github-actions github-actions bot requested review from avisconti and erwango July 4, 2025 04:16
@github-actions github-actions bot requested a review from jfischer-no July 4, 2025 04:16
@github-actions github-actions bot removed the DNM (manifest) This PR should not be merged (controlled by action-manifest) label Jul 4, 2025
Copy link
Contributor

@josuah josuah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the modifications!
I have "folded" the points it does resolve to allow you to keep track of feedback.
A few items left might need some adjustment (i.e. for CI), but I am looking forward to see this merged!

@thaoluonguw thaoluonguw force-pushed the support_renesas_ra_ceu branch from 03bdbce to c5ed982 Compare July 7, 2025 07:12
KhanhNguyen-RVC and others added 7 commits July 7, 2025 14:21
Add support for the Renesas RA Capture Engine Unit (CEU),
including driver source files, Kconfig options, and DTS bindings.

- Add initial implementation of the RA CEU driver
- Add dedicated Kconfig and CMake integration
- Provide Devicetree bindings for the RA CEU
- Update module Kconfig to include the new driver

This enables image capture functionality using the CEU peripheral
on Renesas RA series MCUs.

Signed-off-by: Duy Vo <[email protected]>
Signed-off-by: Khanh Nguyen <[email protected]>
Add pin definitions required by the RA Capture Engine Unit

Signed-off-by: Duy Vo <[email protected]>
Signed-off-by: Khanh Nguyen <[email protected]>
Add CEU to r7fa8d1xh.dtsi and r7fa8m1xh.dtsi

Signed-off-by: Khanh Nguyen <[email protected]>
- Add CEU pin configuration to ek_ra8d1-pinctrl.dtsi
- Enable CEU node and Arducam 20-pin connector in ek_ra8d1.dts
- Configure PWM3 as external XCLK via pwm-clock node
- Update board YAML to declare video support

Signed-off-by: Duy Vo <[email protected]>
Signed-off-by: Khanh Nguyen <[email protected]>
Support OV7670 DVP 20-pin shield on the EK-RA8D1 board

Signed-off-by: Khanh Nguyen <[email protected]>
Add EK-RA8D1 board support for capture and capture_to_lvgl samples

Signed-off-by: Khanh Nguyen <[email protected]>
Add SW1 configuration for using Camera Exapansion Port (J59)

Signed-off-by: Thao Luong <[email protected]>
@thaoluonguw thaoluonguw force-pushed the support_renesas_ra_ceu branch from c5ed982 to 356db7a Compare July 7, 2025 07:32
Copy link

sonarqubecloud bot commented Jul 7, 2025

@thaoluonguw
Copy link
Contributor Author

Thank you for the modifications! I have "folded" the points it does resolve to allow you to keep track of feedback. A few items left might need some adjustment (i.e. for CI), but I am looking forward to see this merged!

@josuah : Thank you so much for your review. And I am so sorry for my late responding to you.

@josuah
Copy link
Contributor

josuah commented Jul 7, 2025

No problem, it is possible to pause activity on PRs for as long as you need.

The last item I think is missing would be adding it to the build_all Twister test to make it easy to bulk test that all drivers still build well despite API changes.

Here is an example of how it can be done for renesas_ra_ceu:

[EDIT: see more recent version below]

diff --git a/tests/drivers/build_all/video/testcase.yaml b/tests/drivers/build_all/video/testcase.yaml

   [ see more recent version below ]
west twister -s drivers.video.renesas_ra_ceu.build
Renaming output directory to /home/tinyvision/zephyrproject/zephyr/twister-out.3
INFO    - Using Ninja..
INFO    - Zephyr version: v4.2.0-rc1-110-g356db7abcffd
INFO    - Using 'zephyr' toolchain.
INFO    - Selecting default platforms per testsuite scenario
INFO    - Building initial testsuite list...
INFO    - Writing JSON report /home/tinyvision/zephyrproject/zephyr/twister-out/testplan.json
INFO    - JOBS: 4
INFO    - Adding tasks to the queue...
INFO    - Added initial list of jobs to queue
INFO    - Total complete:    1/   1  100%  built (not run):    1, filtered:    0, failed:    0, error:    0
INFO    - 1 test scenarios (1 configurations) selected, 0 configurations filtered (0 by static filter, 0 at runtime).
INFO    - 0 of 1 executed test configurations passed (0.00%), 1 built (not run), 0 failed, 0 errored, with no warnings in 56.95 seconds.
INFO    - 0 of 0 executed test cases passed (0.00%) on 0 out of total 1115 platforms (0.00%).
INFO    - 1 selected test cases not executed: 1 not run (built only).
INFO    - 0 test configurations executed on platforms, 1 test configurations were only built.
INFO    - Saving reports...
INFO    - Writing JSON report /home/tinyvision/zephyrproject/zephyr/twister-out/twister.json
INFO    - Writing xunit report /home/tinyvision/zephyrproject/zephyr/twister-out/twister.xml...
INFO    - Writing xunit report /home/tinyvision/zephyrproject/zephyr/twister-out/twister_report.xml...
INFO    - Run completed

}
}

static int video_renesas_ra_ceu_get_format(const struct device *dev, struct video_format *fmt)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thaoluonguw : This is a small point but do you think it's better to shorten the function name a bit ? The prefix video_renesas_ seems not needed as all these functions are static, no worry that other functions will have the same name

Comment on lines +14 to +15
#include <soc.h>
#include <errno.h>
Copy link
Contributor

@ngphibang ngphibang Jul 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems better to sort the headers byte alphabetical order ?

/* Common header */
#include <errno.h>
#include <soc.h>

/* Zephyr header */

/* Local header */
#include "r_ceu.h"
#include "video_device.h"

Copy link
Contributor

@ngphibang ngphibang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a test case in build_all so that the driver build can be triggered by CI ?

diff --git a/tests/drivers/build_all/video/testcase.yaml b/tests/drivers/build_all/video/testcase.yaml
index c7a5e07161e..f8c03137bfa 100644
--- a/tests/drivers/build_all/video/testcase.yaml
+++ b/tests/drivers/build_all/video/testcase.yaml
@@ -36,3 +36,8 @@ tests:
       - stm32n6570_dk/stm32n657xx/sb
     extra_args:
       - platform:stm32n6570_dk/stm32n657xx/sb:SHIELD=st_b_cams_imx_mb1854
+  drivers.video.renesas_ra_ceu.build:
+    platform_allow:
+      - ek_ra8d1/r7fa8d1bhecbd
+    extra_args:
+      - platform:ek_ra8d1/r7fa8d1bhecbd:SHIELD="dvp_20pin_ov7670;rtkmipilcdb00000be"

Copy link
Contributor

@khoa-nguyen-18 khoa-nguyen-18 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have some comments regarding camera support on the board and in the shield layer

Comment on lines +269 to +283
&pwm3 {
pinctrl-0 = <&pwm3_default>;
pinctrl-names = "default";
interrupts = <51 12>, <52 12>;
interrupt-names = "gtioca", "overflow";

cam_clock: pwmclock {
compatible = "pwm-clock";
status = "disabled";
#clock-cells = <1>;
clock-frequency = <24000000>;
pwms = <&pwm3 0 PWM_KHZ(24000) PWM_POLARITY_NORMAL>;
};
};

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we define this pwm3 and cam_clock in the shield layer? I feel it's wasting two interrupt lines on the board when they're not used, and the cam_clock properties are specific to each shield.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As long as there is status = "disabled";, then the driver instance will not be generated, and the resources will not be used.

The clock-frequency belongs to the shield I agree. A new standard label name need to be chosen for it. For instance, dvp_20pin_xclk: instead of cam_clock for instance.

This way this devkit can be compatible with any future camera shield contributed, which only specify this:

&dvp_20pin_xclk {
    clock-frequency = <24000000>;
};

Thank you for raising this point!

Comment on lines +314 to +330
ceu_default: ceu_default {
group1 {
/* CEU */
psels = <RA_PSEL(RA_PSEL_CEU, 4, 0)>, /* VIO_D0 */
<RA_PSEL(RA_PSEL_CEU, 4, 1)>, /* VIO_D1 */
<RA_PSEL(RA_PSEL_CEU, 4, 5)>, /* VIO_D2 */
<RA_PSEL(RA_PSEL_CEU, 4, 6)>, /* VIO_D3 */
<RA_PSEL(RA_PSEL_CEU, 7, 0)>, /* VIO_D4 */
<RA_PSEL(RA_PSEL_CEU, 7, 1)>, /* VIO_D5 */
<RA_PSEL(RA_PSEL_CEU, 7, 2)>, /* VIO_D6 */
<RA_PSEL(RA_PSEL_CEU, 7, 3)>, /* VIO_D7 */
<RA_PSEL(RA_PSEL_CEU, 7, 8)>, /* VIO_CLK */
<RA_PSEL(RA_PSEL_CEU, 7, 9)>, /* VIO_HD */
<RA_PSEL(RA_PSEL_CEU, 7, 10)>; /* VIO_VD */
drive-strength = "high";
};
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, since the connector is already defined in the board dts, should we move this to shield layer?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The shield connector is nexus GPIO mapping, not related to this pinctrl define.
As my opinion, this pinctrl should be keeped at board layer due to it is board specific and the policy encourage enabling all the standard connector on board by default.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this pinctrl definition is placed in the board layer, I think it would be nice to include /omit-if-no-ref/

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It not necessary in this case. /omit-if-no-ref/ just have meaning in case you have multiple configuration for the pinctrl and actually use one in application. But with EK-RA8D1, the camera shield should only use the dvp_20pin connector on board.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/omit-if-no-ref/ just have meaning in case you have multiple configuration for the pinctrl and actually use one in application

From my view, the main reason is as below image - hardware/pinctrl page:

image

This ensures that when the ek_ra8d1 is built without the shield, the CEU pinctrl is not included. To minimize the DTS content, /omit-if-no-ref/ should be included.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CEU should have the default pinctrl, even with or without the shield

ceu: ceu@40348000 {
compatible = "renesas,ra-ceu";
reg = <0x40348000 0x8000>;
clocks = <&pclka MSTPC 16>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's missing clock-names here

Comment on lines +124 to +128
+-------------+-------------+--------------+------------+------------+------------+-------------+-----------+
| SW1-1 PMOD1 | SW1-2 TRACE | SW1-3 CAMERA | SW1-4 ETHA | SW1-5 ETHB | SW1-6 GLCD | SW1-7 SDRAM | SW1-8 I3C |
+-------------+-------------+--------------+------------+------------+------------+-------------+-----------+
| OFF | OFF | ON | OFF | OFF | OFF | ON | OFF |
+-------------+-------------+--------------+------------+------------+------------+-------------+-----------+
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we just set the OFF state for the conflicting SW and "don't care" state for the non-conflicting SW?

image

Copy link
Contributor

@thenguyenyf thenguyenyf left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a comment for nit. Others LGTM.

Comment on lines +52 to +56
group2 {
/* GTIOC3B */
psels = <RA_PSEL(RA_PSEL_GPT1, 4, 4)>;
drive-strength = "medium";
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Because there is only channel 0 to use with camera clock, the definition for GTIOC3B pincfg could be removed

Comment on lines +314 to +330
ceu_default: ceu_default {
group1 {
/* CEU */
psels = <RA_PSEL(RA_PSEL_CEU, 4, 0)>, /* VIO_D0 */
<RA_PSEL(RA_PSEL_CEU, 4, 1)>, /* VIO_D1 */
<RA_PSEL(RA_PSEL_CEU, 4, 5)>, /* VIO_D2 */
<RA_PSEL(RA_PSEL_CEU, 4, 6)>, /* VIO_D3 */
<RA_PSEL(RA_PSEL_CEU, 7, 0)>, /* VIO_D4 */
<RA_PSEL(RA_PSEL_CEU, 7, 1)>, /* VIO_D5 */
<RA_PSEL(RA_PSEL_CEU, 7, 2)>, /* VIO_D6 */
<RA_PSEL(RA_PSEL_CEU, 7, 3)>, /* VIO_D7 */
<RA_PSEL(RA_PSEL_CEU, 7, 8)>, /* VIO_CLK */
<RA_PSEL(RA_PSEL_CEU, 7, 9)>, /* VIO_HD */
<RA_PSEL(RA_PSEL_CEU, 7, 10)>; /* VIO_VD */
drive-strength = "high";
};
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The shield connector is nexus GPIO mapping, not related to this pinctrl define.
As my opinion, this pinctrl should be keeped at board layer due to it is board specific and the policy encourage enabling all the standard connector on board by default.

@josuah
Copy link
Contributor

josuah commented Jul 22, 2025

FYI, to summarize what allows this PR to be merged in practice:

  • The "change requests" are both to add this board to the "build-all" target so that CI keeps compiling the driver making sure it works in the future (comment)

  • A git conflict preventing it to be merged.

Then of course letting time for PR author to check all comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: Pinctrl area: Samples Samples area: Shields Shields (add-on boards) area: Video Video subsystem manifest manifest-hal_renesas platform: Renesas RA Renesas Electronics Corporation, RA
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants