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
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 23 additions & 19 deletions boards/nxp/frdm_mcxn947/frdm_mcxn947.dtsi
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include "frdm_mcxn947-pinctrl.dtsi"
#include <zephyr/dt-bindings/i2c/i2c.h>
#include <zephyr/dt-bindings/input/input-event-codes.h>
#include <zephyr/dt-bindings/gpio/dvp-20pin-connector.h>

/ {
aliases{
Expand Down Expand Up @@ -95,38 +96,22 @@ nxp_8080_touch_panel_i2c: &flexcomm2_lpi2c2 {
pinctrl-0 = <&pinmux_flexcomm7_lpi2c>;
pinctrl-names = "default";
clock-frequency = <I2C_BITRATE_STANDARD>;
ov7670: ov7670@21 {
compatible = "ovti,ov7670";
reset-gpios = <&gpio1 19 GPIO_ACTIVE_HIGH>;
pwdn-gpios = <&gpio1 18 GPIO_ACTIVE_HIGH>;
reg = <0x21>;

port {
ov7670_ep_out: endpoint {
remote-endpoint-label = "sdma_ep_in";
};
};
};
};

/* SmartDMA is used for video driver on this board */
&smartdma {
/* Shields do not enable video-sdma parent node so enable it by default */
status = "okay";
program-mem = <0x4000000>;

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

port {
sdma_ep_in: endpoint {
remote-endpoint-label = "ov7670_ep_out";
};
};
};
};

Expand Down Expand Up @@ -300,3 +285,22 @@ zephyr_mipi_dbi_parallel: &flexio0_lcd {
pinctrl-0 = <&pinmux_sctimer>;
pinctrl-names = "default";
};

/*
* Connection with camera modules such as the dvp_20pin_ov7670 shield
*/

/ {
dvp_20pin_gpio: dvp-20pin-connector {
compatible = "arducam,dvp-20pin-connector";
#gpio-cells = <2>;
gpio-map-mask = <DVP_20PIN_MASK 0x0>;
gpio-map-pass-thru = <0x0 GPIO_DT_FLAGS_MASK>;
gpio-map = <DVP_20PIN_PEN 0 &gpio1 19 0>,
<DVP_20PIN_PDN 0 &gpio1 18 0>;
};
};

dvp_20pin_i2c: &flexcomm7_lpi2c7 {};

dvp_20pin_interface: &video_sdma {};
5 changes: 5 additions & 0 deletions boards/shields/dvp_20pin_ov7670/Kconfig.shield
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Copyright 2025 tinyVision.ai Inc.
# SPDX-License-Identifier: Apache-2.0

config SHIELD_DVP_20PIN_OV7670
def_bool $(shields_list_contains,SHIELD_DVP_20PIN_OV7670)
81 changes: 81 additions & 0 deletions boards/shields/dvp_20pin_ov7670/doc/index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
.. _dvp_20pin_ov7670:

DVP 20-pin OV7670 Camera Module
###############################

Overview
********

This series of shields supports the camera modules which use a 18-pin connector compatible with
the ``arducam,dvp-20pin-connector`` to connect a devkit to an OV7670 image sensor via DVP
(Digital Video Port), aka parallel interface.

Only 18 pins out of the 20-pin connector are present

It was originally produced by `Arducam`_ but is discontinuited, and now `Olimex`_ provides it.

Pins assignment
===============

+-----+--------------+-----+--------------+
| Pin | Function | Pin | Function |
+=====+==============+=====+==============+
| 1 | 3V3 | 2 | GND |
+-----+--------------+-----+--------------+
| 3 | SCL | 4 | SDA |
+-----+--------------+-----+--------------+
| 5 | VS | 6 | HS |
+-----+--------------+-----+--------------+
| 7 | PCLK | 8 | XCLK |
+-----+--------------+-----+--------------+
| 9 | D7 | 10 | D6 |
+-----+--------------+-----+--------------+
| 11 | D5 | 12 | D4 |
+-----+--------------+-----+--------------+
| 13 | D3 | 14 | D2 |
+-----+--------------+-----+--------------+
| 15 | D1 | 16 | D0 |
+-----+--------------+-----+--------------+
| 17 | POWER_EN | 18 | POWER_DOWN |
+-----+--------------+-----+--------------+

Requirements
************

This shield can be used with any board which provides a 18 or 20-pin header spread over two rows
of 9 or 10 pins each with the above pinout, such as the `arduino Giga R1`_, `NXP FRDM-MCXN947`_,
ST boards with the `ST-CAMS-OMV`_ adapter, or any other board with a compatible connector.

Alternatively, it is possible to use jumper wires to connect the module to any devkit that
exposes their camera parallel port to pin headers.

Programming
***********

Set ``--shield dvp_20pin_ov7670`` when you invoke ``west build``. For example:

.. zephyr-app-commands::
:zephyr-app: samples/drivers/video/capture
:board: frdm_mcxn947
:shield: dvp_20pin_ov7670
:goals: build

References
**********

.. target-notes::

.. _ST-CAMS-OMV:
https://www.st.com/en/evaluation-tools/b-cams-omv.html

.. _Arducam:
https://docs.arducam.com/DVP-Camera-Module/Arduino-GIGA/Arduino-GIGA/Quick-Start-Guide/

.. _Arduino Giga R1:
https://docs.arduino.cc/tutorials/giga-r1-wifi/giga-camera/

.. _NXP FRDM-MCXN947:
https://www.nxp.com/docs/en/application-note/AN14191.pdf

.. _Olimex:
https://www.olimex.com/Products/Components/Camera/CAMERA-OV7670/
37 changes: 37 additions & 0 deletions boards/shields/dvp_20pin_ov7670/dvp_20pin_ov7670.overlay
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright 2024 NXP
* Copyright 2025 tinyVision.ai Inc.
*
* SPDX-License-Identifier: Apache-2.0
*/

/ {
chosen {
zephyr,camera = &dvp_20pin_interface;
};
};

&dvp_20pin_i2c {
ov7670: ov7670@21 {
compatible = "ovti,ov7670";
reg = <0x21>;
reset-gpios = <&dvp_20pin_gpio DVP_20PIN_PEN GPIO_ACTIVE_HIGH>;
pwdn-gpios = <&dvp_20pin_gpio DVP_20PIN_PDN GPIO_ACTIVE_HIGH>;

port {
ov7670_ep_out: endpoint {
remote-endpoint-label = "dvp_20pin_ep_in";
};
};
};
};

&dvp_20pin_interface {
status = "okay";

port {
dvp_20pin_ep_in: endpoint {
remote-endpoint-label = "ov7670_ep_out";
};
};
};
47 changes: 47 additions & 0 deletions dts/bindings/gpio/arducam,dvp-20pin-connector.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# Copyright 2025 tinyVision.ai Inc.
# SPDX-License-Identifier: Apache-2.0

description: |
GPIO pins exposed on ArduCam 20-pin header camera connector,
originally designed to connect Arducam modules to Arduino Giga R1,
but further used by other vendors of camera and devkits.

The connector layout is depicted below:

1 3V3 2 GND
3 SCL 4 SDA
5 VS 6 HS
7 PCLK 8 XCLK
9 D7 10 D6
11 D5 12 D4
13 D3 14 D2
15 D1 16 D0
17 PEN 18 PDN
19 PEN 20 PDN

In many variants, the last row containing the pins 19 and 20 is
not present, and the pins 17 and 18 are used for the same purpose
instead.

The following node labels can be used for use in shields:

- 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.
Comment on lines +28 to +41
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!


See <zephyr/dt-bindings/gpio/dvp-20pin-gpio.h> for pin description.

compatible: "arducam,dvp-20pin-connector"

include: [gpio-nexus.yaml, base.yaml]
1 change: 1 addition & 0 deletions dts/bindings/vendor-prefixes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ arc Synopsys, Inc. (formerly ARC International PLC)
archermind ArcherMind Technology (Nanjing) Co., Ltd.
arctic Arctic Sand
arcx arcx Inc. / Archronix Inc.
arducam Arducam
arduino Arduino
aries Aries Embedded GmbH
arm ARM Ltd.
Expand Down
33 changes: 33 additions & 0 deletions include/zephyr/dt-bindings/gpio/dvp-20pin-connector.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
* Copyright (c) 2025 tinyVision.ai Inc.
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef INCLUDE_ZEPHYR_DT_BINDINGS_GPIO_DVP_20PIN_CONNECTOR_H_
#define INCLUDE_ZEPHYR_DT_BINDINGS_GPIO_DVP_20PIN_CONNECTOR_H_

/** Pin number mask (0..20). */
#define DVP_20PIN_MASK 0xff

/**
* @name Arducam DVP 20-pin or 18-pin connector pinout
* @{
*/
#define DVP_20PIN_SCL 3 /**< I2C pin */
#define DVP_20PIN_SDA 4 /**< I2C pin */
#define DVP_20PIN_VS 5 /**< Vertical sync */
#define DVP_20PIN_HS 6 /**< Horizontal sync */
#define DVP_20PIN_PCLK 7 /**< Pixel clock used to transmit the data */
#define DVP_20PIN_XCLK 8 /**< System clock often needed for I2C communication */
#define DVP_20PIN_D7 9 /**< Parallel port data */
#define DVP_20PIN_D6 10 /**< Parallel port data */
#define DVP_20PIN_D5 11 /**< Parallel port data */
#define DVP_20PIN_D4 12 /**< Parallel port data */
#define DVP_20PIN_D3 13 /**< Parallel port data */
#define DVP_20PIN_D2 14 /**< Parallel port data */
#define DVP_20PIN_D1 15 /**< Parallel port data */
#define DVP_20PIN_D0 16 /**< Parallel port data */
#define DVP_20PIN_PEN 17 /**< Power Enable, typicaly shorted with pin 19 */
#define DVP_20PIN_PDN 18 /**< Power Down, typicaly shorted with pin 20 */
/** @} */

#endif /* INCLUDE_ZEPHYR_DT_BINDINGS_GPIO_DVP_20PIN_CONNECTOR_H_ */
16 changes: 14 additions & 2 deletions samples/drivers/video/capture/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@ Supported camera modules on some i.MX RT boards can be found below.
- `Camera iMXRT`_

- :zephyr:board:`mimxrt1064_evk`
- `MT9M114 camera module`_
with a `MT9M114 camera module`_

- :zephyr:board:`mimxrt1170_evk`
- `OV5640 camera module`_
with an `OV5640 camera module`_

- :zephyr:board:`frdm_mcxn947`
with any ``arducam,dvp-20pin-connector`` camera module such as :ref:`dvp_20pin_ov7670`.

Also :zephyr:board:`arduino_nicla_vision` can be used in this sample as capture device, in that case
The user can transfer the captured frames through on board USB.
Expand Down Expand Up @@ -70,6 +73,15 @@ commands:
:goals: build
:compact:

For :zephyr:board:`frdm_mcxn947`, build this sample application with the following commands:

.. zephyr-app-commands::
:zephyr-app: samples/drivers/video/capture
:board: frdm_mcxn947/mcxn947/cpu0
:shield: dvp_20pin_ov7670
:goals: build
:compact:

For testing purpose without the need of any real video capture and/or display hardwares,
a video software pattern generator is supported by the above build commands without
specifying the shields.
Expand Down
11 changes: 0 additions & 11 deletions samples/drivers/video/capture/boards/frdm_mcxn947_cpu0.overlay

This file was deleted.

2 changes: 2 additions & 0 deletions samples/drivers/video/capture/sample.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ tests:
- platform:mimxrt1064_evk:SHIELD="dvp_fpc24_mt9m114;rk043fn66hs_ctg"
- platform:mimxrt1170_evk/mimxrt1176/cm7:SHIELD="nxp_btb44_ov5640;rk055hdmipi4ma0"
- platform:mimxrt1170_evk@B/mimxrt1176/cm7:SHIELD="nxp_btb44_ov5640;rk055hdmipi4ma0"
- platform:frdm_mcxn947/mcxn947/cpu0:SHIELD="dvp_20pin_ov7670"
extra_configs:
- CONFIG_TEST=y
- CONFIG_FPU=y
Expand All @@ -28,6 +29,7 @@ tests:
- mimxrt1064_evk
- mimxrt1170_evk/mimxrt1176/cm7
- mimxrt1170_evk@B/mimxrt1176/cm7
- frdm_mcxn947/mcxn947/cpu0
- mm_swiftio
- esp32s3_eye/esp32s3/procpu
depends_on: video
Expand Down