Skip to content

boards: frdm_mcxn947: turn OV7670 into a shield #89131

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 3 commits into
base: main
Choose a base branch
from

Conversation

josuah
Copy link
Collaborator

@josuah josuah commented Apr 26, 2025

Dependencies:

The FRDM-MCXN board is featuring an Arducam connector originally designed for the Arduino GIGA R1, and spread broadly since then for inexpensive OmniVision and low-power Himax image sensor modules.

Other modules than the Olimex OV7670 can be used.

PXL_20250426_115548902
PXL_20250426_115605997
PXL_20250426_115649291

This also proposes an arducam,dvp-20pin-connector GPIO nexus:
https://github.com/zephyrproject-rtos/zephyr/pull/89131/files#diff-a39283efe7f5b76e206c8d2b9b65c4b45d130ceb1aa6bb8a0083486793172537

@josuah
Copy link
Collaborator Author

josuah commented Apr 26, 2025

Tested with UVC (by cherry-picking commits):

Before:

mpv-shot0001-before

After:

mpv-shot0001

It does not really look like correct data, but it is showing the same thing before and after, which shows the current PR does not break the sensor operation. :)

[EDIT: no problem with other hardware on UVC (i.e. Arducam Nicla or virtual source), I'll try with other sensors to debug this, which this PR helps doing]

@josuah josuah added the In progress For PRs: is work in progress and should not be merged yet. For issues: Is being worked on label Apr 26, 2025
@josuah josuah force-pushed the pr-frdm-mcxn947-shield branch from a0d81be to e03e9da Compare April 26, 2025 12:29
Comment on lines +28 to +41
- dvp_20pin_interface: the video interface that receives the video
feed and use with the zephyr,camera chosen node.
- dvp_20pin_ep_in: video endpoint of the devkit receiving the video
feed (see video-interfaces.yaml).
- dvp_20pin_ep_out: video endpoint of the camera module to interconnect
with this endpoint (see video-interfaces.yaml).
- dvp_20pin_i2c: the I2C device of the devkit on which the camera
module is instantiated.
- dvp_20pin_gpio: the gpio nexus using the arducam,dvp-20pin-connector
that defines the camera 'reset' pin, 'power-down' pin, etc.
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Shields does not talk about a zephyr_... prefix:

zephyr_camera_i2c: &i2c1 {
pinctrl-0 = <&i2c1_scl_pb8 &i2c1_sda_pb9>;
pinctrl-names = "default";
};
zephyr_camera_dvp: &dcmi {
pinctrl-0 = <&dcmi_hsync_pa4 &dcmi_pixclk_pa6 &dcmi_vsync_pb7
&dcmi_d0_pc6 &dcmi_d1_pc7 &dcmi_d2_pe0 &dcmi_d3_pe1
&dcmi_d4_pe4 &dcmi_d5_pd3 &dcmi_d6_pe5 &dcmi_d7_pe6>;
pinctrl-names = "default";
};

So I went with dvp_20pin_<sensorname> and dvp_20pin_<feature>.

Let me know if zephyr_camera_<...> is better!

@josuah josuah force-pushed the pr-frdm-mcxn947-shield branch from e03e9da to 283745b Compare April 26, 2025 13:24
@josuah josuah force-pushed the pr-frdm-mcxn947-shield branch from 283745b to d171799 Compare April 26, 2025 13:29
@josuah josuah removed the In progress For PRs: is work in progress and should not be merged yet. For issues: Is being worked on label Apr 26, 2025
Add the 20-pin camera connector used by at least Arducam, Waveshare,
Olimex, Arduino, NXP, ST, Adafruit that connects image sensor module
boards and devkits.

Signed-off-by: Josuah Demangeon <me@josuah.net>
@josuah josuah force-pushed the pr-frdm-mcxn947-shield branch from d171799 to c159802 Compare April 26, 2025 15:27
@josuah josuah marked this pull request as ready for review April 26, 2025 15:27
Copy link
Collaborator

@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.

Thanks for the added shield.
Did you test the video capture sample ? I think you need to update the frdm_mcxn947_cpu0.overlay in the sample as well because the camera is now moved out of the board.

Comment on lines 125 to 129
port {
sdma_ep_in: endpoint {
remote-endpoint-label = "ov7670_ep_out";
dvp_20pin_ep_in: endpoint {
remote-endpoint-label = "dvp_20pin_ep_out";
};
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

This should not be here but in the overlay as it is out of the board. If there are multiple ports / endpoints, you can reserve a port for it as below (but it's not the case here):

https://github.com/zephyrproject-rtos/zephyr/blob/main/dts/arm/nxp/nxp_rt11xx.dtsi#L911-#L934

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I removed the remote-endpoint-label = "dvp_20pin_ep_out"; and it still works!
Is that what I should remove?

I am not sure how to remove the label itself dvp_20pin_ep_in: as the shield cannot know where it should insert itself on every board, the board.dts has to provide a label for the shield insertion point?

Thank you for your help as I learn DTS further.

@josuah josuah force-pushed the pr-frdm-mcxn947-shield branch 2 times, most recently from 8f6cc03 to a094905 Compare April 27, 2025 00:06
@josuah
Copy link
Collaborator Author

josuah commented Apr 27, 2025

Did you test the video capture sample ? I think you need to update the frdm_mcxn947_cpu0.overlay in the sample as well

Good point! Now I can remove it as the shield would select the zephyr,camera = &dvp_20pin_interface;.

Trying again after enabling the debug logging:

...
[00:00:05.271,000] <dbg> main: main: Got frame 307! size: 19200; timestamp 5271 ms
[00:00:05.286,000] <dbg> main: main: Got frame 308! size: 19200; timestamp 5286 ms
[00:00:05.302,000] <dbg> main: main: Got frame 309! size: 19200; timestamp 5302 ms
[00:00:05.318,000] <dbg> main: main: Got frame 310! size: 19200; timestamp 5318 ms
[00:00:05.334,000] <dbg> main: main: Got frame 311! size: 19200; timestamp 5334 ms
[00:00:05.357,000] <dbg> main: main: Got frame 312! size: 19200; timestamp 5357 ms
[00:00:05.373,000] <dbg> main: main: Got frame 313! size: 19200; timestamp 5373 ms
[00:00:05.388,000] <dbg> main: main: Got frame 314! size: 19200; timestamp 5388 ms
[00:00:05.404,000] <dbg> main: main: Got frame 315! size: 19200; timestamp 5404 ms
[00:00:05.420,000] <dbg> main: main: Got frame 316! size: 19200; timestamp 5420 ms
...

@josuah josuah force-pushed the pr-frdm-mcxn947-shield branch from a094905 to ecee1dd Compare April 27, 2025 00:23
@josuah
Copy link
Collaborator Author

josuah commented Apr 27, 2025

Copy link
Collaborator

@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.

Thanks

Comment on lines 111 to 130
&smartdma {
status = "okay";
program-mem = <0x4000000>;
video_sdma: video-sdma {
status = "okay";
/* Shields do not enable video-sdma parent node */
status = "okay";

dvp_20pin_interface: video_sdma: video-sdma {
compatible = "nxp,video-smartdma";
pinctrl-0 = <&pinmux_smartdma_camera>;
pinctrl-names = "default";
vsync-pin = <4>;
hsync-pin = <11>;
pclk-pin = <5>;
status = "disabled";

port {
sdma_ep_in: endpoint {
remote-endpoint-label = "ov7670_ep_out";
dvp_20pin_ep_in: endpoint {
remote-endpoint-label = "empty";
};
};
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

Sorry, I am confused here. I think the right way is keeping the video sdma node and label it as a dvp_20pin_interface as in https://github.com/zephyrproject-rtos/zephyr/blob/main/boards/nxp/mimxrt1064_evk/mimxrt1064_evk.dts#L352-#L354

Comment on lines 28 to 37
&dvp_20pin_ep_in {
remote-endpoint-label = "dvp_20pin_ep_out";
};

&dvp_20pin_interface {
status = "okay";
};
Copy link
Collaborator

Choose a reason for hiding this comment

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

The endpoint should be inside the interface node.

@josuah josuah force-pushed the pr-frdm-mcxn947-shield branch from ecee1dd to dc57200 Compare April 27, 2025 11:01
josuah added 2 commits April 27, 2025 11:11
The OV7670 was defined as part of the FRDM-MCXN947 board attached to the
SmartDMA and I2C peripheral. Migrate the devicetree to a reusable shield
that can be swapped with other image sensors.

Signed-off-by: Josuah Demangeon <me@josuah.net>
Add FRDM-MCXN947 to the video capture sample documentation and twister
YAML configuration, using the DVP OV7670 camera module newly introduced.

Signed-off-by: Josuah Demangeon <me@josuah.net>
@josuah josuah force-pushed the pr-frdm-mcxn947-shield branch from 13ea982 to cb237fc Compare April 27, 2025 11:11
@josuah
Copy link
Collaborator Author

josuah commented Apr 27, 2025

Force-push:

  • Added a README entry for the video capture sample, preview soon available here or in the meantime here.
  • Modified the devicetree to use the same declaration style as mimxrt1064_evk

not sure if this 20-pin shield is generic and not specific only to NXP boards

It is the closest thing from a standard for DVP we might have, plenty of Arducam modules available via UCTRONICS, and some 3rd-party too, like the Olimex one for the OV7670. But a de-facto standard, no official document describing it.

This will help for testing all these drivers!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants