-
Notifications
You must be signed in to change notification settings - Fork 7.6k
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
base: main
Are you sure you want to change the base?
Add support for Renesas RA CEU (Capture Engine Unit) for RA8M1 and RA8D1 #92146
Conversation
Update hal_renesas to support CEU on RA SoCs Signed-off-by: Duy Vo <[email protected]> Signed-off-by: Khanh Nguyen <[email protected]>
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]>
Add EK-RA8D1 board support for the capture_to_lvgl sample - Add board-specific configuration in ek_ra8d1.conf - Add Devicetree overlay enabling CEU and display path Signed-off-by: Duy Vo <[email protected]> Signed-off-by: Khanh Nguyen <[email protected]>
Add SW1 configuration for using Camera Exapansion Port (J59) Signed-off-by: Thao Luong <[email protected]>
The following west manifest projects have changed revision in this Pull Request:
⛔ DNM label due to: 1 project with PR revision Note: This message is automatically posted and updated by the Manifest GitHub Action. |
|
There was a problem hiding this 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.
config VIDEO_RENESAS_BUFFER_SDRAM | ||
bool "Allocate the video buffer into SDRAM" | ||
depends on VIDEO_RENESAS_RA_CEU | ||
select MEMC | ||
help | ||
Allocate the video buffer into SDRAM |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[non-blocking]
If interested, there is another mechanism to select the type of memory for use as video buffer memory: Shared Multi-Heap (SMH).
Here is an example that compares how this was implemented in both ST and Espressif side for information:
56e69e5
This gives the user the final choice of what memory source to use.
if (fmt->width % CEU_WIDTH_ALIGN) { | ||
LOG_DBG("Width %d not a multiple of %d", fmt->width, CEU_WIDTH_ALIGN); | ||
return -ENOTSUP; | ||
} | ||
if (fmt->height % CEU_HEIGHT_ALIGN) { | ||
LOG_DBG("Height %d not a multiple of %d", fmt->height, CEU_HEIGHT_ALIGN); | ||
return -ENOTSUP; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[non-blocking]
To help with compliance effort in the future, is it possible to compare against 0 so that the expression is a boolean?
if (fmt->width % CEU_WIDTH_ALIGN) { | |
LOG_DBG("Width %d not a multiple of %d", fmt->width, CEU_WIDTH_ALIGN); | |
return -ENOTSUP; | |
} | |
if (fmt->height % CEU_HEIGHT_ALIGN) { | |
LOG_DBG("Height %d not a multiple of %d", fmt->height, CEU_HEIGHT_ALIGN); | |
return -ENOTSUP; | |
} | |
if (fmt->width % CEU_WIDTH_ALIGN != 0) { |
The subset of MISRA recommended for Zephyr developers is listed here.
if (!enable) { | ||
if (video_stream_stop(config->source_dev, type)) { | ||
LOG_DBG("Failed to stop source device stream"); | ||
return -EIO; | ||
} | ||
|
||
data->is_streaming = false; | ||
R_CEU->CAPSR = R_CEU_CAPSR_CPKIL_Msk; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[non-blocking]
If enable == false
, then the if will execute, but what is after it as well as there is no return 0;
, maybe this was not intentional.
if (video_stream_start(config->source_dev, type)) { | ||
LOG_DBG("Failed to start source device stream"); | ||
return -EIO; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[non-blocking]
While this code is working, the following would be slightly more conventional:
if (video_stream_start(config->source_dev, type)) { | |
LOG_DBG("Failed to start source device stream"); | |
return -EIO; | |
} | |
int ret; | |
... | |
ret = video_stream_start(config->source_dev, type) | |
if (ret < 0) { | |
LOG_DBG("Failed to start source device stream"); | |
return ret; | |
} |
if (video_stream_stop(config->source_dev, type)) { | ||
LOG_DBG("Failed to stop source device stream"); | ||
return -EIO; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[non-blocking]
While this code is working, the following would be slightly more conventional:
if (video_stream_stop(config->source_dev, type)) { | |
LOG_DBG("Failed to stop source device stream"); | |
return -EIO; | |
} | |
int ret; | |
... | |
video_stream_stop(config->source_dev, type); | |
if (ret < 0) { | |
LOG_DBG("Failed to stop source device stream"); | |
return ret; | |
} |
There does not seem to be any policy for use of ret
vs err
or ret < 0
vs ret != 0
.
One possible way to handle error codes from the HAL and error codes from Zephyr is to use err
for HAL errors and ret
for Zephyr errors.
Coding guidelines are non-blocking at the moment, however! This is only anticipating the moment where certification would video drivers.
bus-width = <8>; | ||
hsync-active = <1>; | ||
vsync-active = <1>; | ||
pclk-sample = <1>; | ||
hsync-sample = <0>; | ||
vsync-sample = <0>; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[non-blocking]
It seems like all these properties are specific to the ov7670 more than specific to this board. For instance, if the user wants to try with a different image sensor shield, they might need different values at this place.
It might be possible to move these properties to boards/shields/dvp_20pin_ov7670/dvp_20pin_ov7670.overlay
:
&dvp_20pin_ep_in {
bus-width = <8>;
hsync-active = <1>;
vsync-active = <1>;
pclk-sample = <1>;
hsync-sample = <0>;
vsync-sample = <0>;
};
All these properties are expected to always exist, even if they are not used by drivers, so this is not expected t to break the other boards... Except for hsync-sample
and vsync-sample
not defined on dts/bindings/video/video-interfaces.yaml
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Then, on boards/renesas/ek_ra8d1/ek_ra8d1.dts
, it is possible to define an empty endpoint, just for the purpose of declaring the label:
&ceu {
...
port {
dvp_20pin_ep_in: endpoint {
remote-endpoint-label = "";
};
};
};
}; | ||
|
||
&dvp_20pin_i2c { | ||
status = "okay"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[non-blocking]
status = "okay";
should have been enabled in the ov7670 module: a bug in the module definition.
Do feel free to move this line to here if you wish, otherwise I will open a new pull request to fix OV7670:
&dvp_20pin_i2c { |
&dvp_20pin_connector { | ||
status = "okay"; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[blocking ❌]
The connector is a mere mapping of GPIO pins usually without an associated device.
It is also not status = "disabled";
by the boards/renesas/ek_ra8d1/ek_ra8d1.dts
where it is defined.
As far as I understand, this is redundant. Let me know if I missed something.
&dvp_20pin_interface { | ||
status = "okay"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[non-blocking]
The status = "okay";
is already performed by the shield, and does not seems necessary there.
zephyr/boards/shields/dvp_20pin_ov7670/dvp_20pin_ov7670.overlay
Lines 29 to 30 in c906d4a
&dvp_20pin_interface { | |
status = "okay"; |
swap-8bits; | ||
swap-16bits; | ||
swap-32bits; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[non-blocking]
The remaining properties may be added to the shield-specific configuration file.
It will be possible to add a /boards/shields/dvp_20pin_ov7670/boards/ek_ra8d1.overlay
that contains all the board-specific integration with a module.
This way, you do not need to re-define these parameters on every sample, and users can select any sensor.
[blocking ❌] |
} | ||
} | ||
|
||
static int video_renesas_ra_ceu_get_format(const struct device *dev, struct video_format *fmt) |
There was a problem hiding this comment.
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
fsp_err_t err; | ||
int ret; | ||
|
||
fmt->pitch = fmt->width * video_bits_per_pixel(fmt->pixelformat) / BITS_PER_BYTE; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not a big deal but fmt->pitch
should be computed at the end when everything is OK as it is the value that application will read back.
child-binding: | ||
child-binding: | ||
include: video-interfaces.yaml | ||
|
||
properties: | ||
hsync-active: | ||
required: true | ||
|
||
vsync-active: | ||
required: true | ||
|
||
pclk-sample: | ||
required: true | ||
|
||
vsync-sample: | ||
required: true | ||
type: int | ||
enum: | ||
- 0 # Falling edge | ||
- 1 # Rising edge | ||
description: | | ||
Sample on the falling or rising edge of the vsync signal. | ||
|
||
hsync-sample: | ||
required: true | ||
type: int | ||
enum: | ||
- 0 # Falling edge | ||
- 1 # Rising edge | ||
description: | | ||
Sample on the falling or rising edge of the hsync signal. | ||
|
||
bus-width: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do you redefine many properties that are already defined in video-interfaces.yaml
?
Add support for Renesas RA CEU (Capture Engine Unit):
It works with OV7670 camera, and MIPI graphics expansion board included in the Kit