diff --git a/boards/shields/weact_ov2640_cam_module/Kconfig.shield b/boards/shields/weact_ov2640_cam_module/Kconfig.shield new file mode 100644 index 0000000000000..a00d675d780e4 --- /dev/null +++ b/boards/shields/weact_ov2640_cam_module/Kconfig.shield @@ -0,0 +1,5 @@ +# Copyright (c) 2024 Charles Dias +# SPDX-License-Identifier: Apache-2.0 + +config SHIELD_WEACT_OV2640_CAM_MODULE + def_bool $(shields_list_contains,weact_ov2640_cam_module) diff --git a/boards/shields/weact_ov2640_cam_module/boards/mini_stm32h743.conf b/boards/shields/weact_ov2640_cam_module/boards/mini_stm32h743.conf new file mode 100644 index 0000000000000..48b3a8db88d7a --- /dev/null +++ b/boards/shields/weact_ov2640_cam_module/boards/mini_stm32h743.conf @@ -0,0 +1,8 @@ +# +# Copyright (c) 2024 Charles Dias +# +# SPDX-License-Identifier: Apache-2.0 +# + +CONFIG_VIDEO_HFLIP=y +CONFIG_VIDEO_VFLIP=y diff --git a/boards/shields/weact_ov2640_cam_module/boards/mini_stm32h743.overlay b/boards/shields/weact_ov2640_cam_module/boards/mini_stm32h743.overlay new file mode 100644 index 0000000000000..e99237276078b --- /dev/null +++ b/boards/shields/weact_ov2640_cam_module/boards/mini_stm32h743.overlay @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2024 Charles Dias + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/* AHB clocks must respect the minimum ratio AHB / DCMI_PIXCLK of 2.5 (AN5020 - Rev 3). + * The OV2640 PCLK is around 72 MHz for QQVGA resolution (160x120) with MCO1_SEL_HSI48 + * and MCO1_PRE_DIV_4. + */ +&rcc { + clocks = <&pll>; + clock-frequency = ; + d1cpre = <1>; + hpre = <1>; + d1ppre = <2>; + d2ppre1 = <2>; + d2ppre2 = <2>; + d3ppre = <2>; +}; + +/* See reference manual (RM0433 Rev 8) page 390: + * 100: HSI48 clock selected (hsi48_ck) + */ +#define MCO1_SEL_HSI48 4 + + /* See reference manual (RM0433 Rev 8) page 391: + * 0100: division by 4 + */ +#define MCO1_PRE_DIV_4 4 + +&mco1 { + status = "okay"; + clocks = <&rcc STM32_SRC_HSI48 MCO1_SEL(MCO1_SEL_HSI48)>; + prescaler = ; + pinctrl-0 = <&rcc_mco_1_pa8>; + pinctrl-names = "default"; +}; + +&zephyr_camera_i2c { + ov2640: ov2640@30 { + supply-gpios = <&dcmi_camera_connector 8 GPIO_ACTIVE_HIGH>; + clock-rate-control = <0x80>; + }; +}; + +&zephyr_camera_dvp { + dmas = <&dma1 0 75 (STM32_DMA_PERIPH_TO_MEMORY | STM32_DMA_PERIPH_NO_INC | + STM32_DMA_MEM_INC | STM32_DMA_PERIPH_8BITS | STM32_DMA_MEM_32BITS | + STM32_DMA_PRIORITY_HIGH) STM32_DMA_FIFO_1_4>; +}; + +&dma1 { + status = "okay"; +}; + +&dmamux1 { + status = "okay"; +}; diff --git a/boards/shields/weact_ov2640_cam_module/doc/index.rst b/boards/shields/weact_ov2640_cam_module/doc/index.rst new file mode 100644 index 0000000000000..1609fc5a23d94 --- /dev/null +++ b/boards/shields/weact_ov2640_cam_module/doc/index.rst @@ -0,0 +1,82 @@ +.. _weact_ov2640_cam_module: + +WeAct Studio MiniSTM32H7xx OV2640 Camera Sensor +############################################### + +Overview +******** + +The OV2640 camera sensor is designed to interface with the WeAct Studio +MiniSTM32H7xx boards, providing camera sensor capabilities. This shield +integrates the OV2640 camera module, which is capable of capturing images +and video with a resolution of up to 2 megapixels. + +.. figure:: ov2640.webp + :align: center + :alt: OV2640 Camera Sensor + +More information about the OV2640 camera sensor can be found on the +`MiniSTM32H7xx GitHub`_ and in the `OV2640 datasheet`_. + +Requirements +************ + +Your board needs to have a ``zephyr_camera_dvp`` device tree label to work with this shield. + +Pin Assignments +=============== + +The shield connects to the WeAct Studio MiniSTM32H7xx board via the +following pins: + ++--------------+-----------+-----------------------------+ +| Shield Pin | Board Pin | Function | ++==============+===========+=============================+ +| DCMI_D0 | PC6 | DCMI Data Line 0 | ++--------------+-----------+-----------------------------+ +| DCMI_D1 | PC7 | DCMI Data Line 1 | ++--------------+-----------+-----------------------------+ +| DCMI_D2 | PE0 | DCMI Data Line 2 | ++--------------+-----------+-----------------------------+ +| DCMI_D3 | PE1 | DCMI Data Line 3 | ++--------------+-----------+-----------------------------+ +| DCMI_D4 | PE4 | DCMI Data Line 4 | ++--------------+-----------+-----------------------------+ +| DCMI_D5 | PD3 | DCMI Data Line 5 | ++--------------+-----------+-----------------------------+ +| DCMI_D6 | PE5 | DCMI Data Line 6 | ++--------------+-----------+-----------------------------+ +| DCMI_D7 | PE6 | DCMI Data Line 7 | ++--------------+-----------+-----------------------------+ +| DCMI_HSYNC | PA4 | DCMI HSYNC | ++--------------+-----------+-----------------------------+ +| DCMI_VSYNC | PB7 | DCMI VSYNC | ++--------------+-----------+-----------------------------+ +| DCMI_PIXCLK | PA6 | DCMI Pixel Clock | ++--------------+-----------+-----------------------------+ +| I2C_SDA | PB9 | I2C Data Line | ++--------------+-----------+-----------------------------+ +| I2C_SCL | PB8 | I2C Clock Line | ++--------------+-----------+-----------------------------+ +| RCC_MCO1 | PA8 | Clock Output | ++--------------+-----------+-----------------------------+ +| SUPPLY | PA7 | Power Supply Control (GPIO) | ++--------------+-----------+-----------------------------+ + +Programming +*********** + +Set ``--shield weact_ov2640_cam_module`` when you invoke ``west build``. For example: + +.. zephyr-app-commands:: + :zephyr-app: samples/drivers/video/capture_to_lvgl/ + :board: mini_stm32h743 + :shield: weact_ov2640_cam_module + :gen-args: -DCONFIG_BOOT_DELAY=2000 + :goals: build + +.. _MiniSTM32H7xx GitHub: + https://github.com/WeActStudio/MiniSTM32H7xx + +.. _OV2640 datasheet: + https://www.uctronics.com/download/cam_module/OV2640DS.pdf diff --git a/boards/shields/weact_ov2640_cam_module/doc/ov2640.webp b/boards/shields/weact_ov2640_cam_module/doc/ov2640.webp new file mode 100644 index 0000000000000..8043befcf75b0 Binary files /dev/null and b/boards/shields/weact_ov2640_cam_module/doc/ov2640.webp differ diff --git a/boards/shields/weact_ov2640_cam_module/weact_ov2640_cam_module.overlay b/boards/shields/weact_ov2640_cam_module/weact_ov2640_cam_module.overlay new file mode 100644 index 0000000000000..bc8c6ebddb288 --- /dev/null +++ b/boards/shields/weact_ov2640_cam_module/weact_ov2640_cam_module.overlay @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2024 Charles Dias + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + chosen { + zephyr,camera = &zephyr_camera_dvp; + }; +}; + +&zephyr_camera_i2c { + status = "okay"; + clock-frequency = ; + + ov2640: ov2640@30 { + compatible = "ovti,ov2640"; + reg = <0x30>; + status = "okay"; + + port { + ov2640_ep_out: endpoint { + remote-endpoint = <&zephyr_camera_dvp_in>; + }; + }; + }; +}; + +&zephyr_camera_dvp { + status = "okay"; + sensor = <&ov2640>; + bus-width = <8>; + hsync-active = <0>; + vsync-active = <0>; + pixelclk-active = <1>; + capture-rate = <1>; + + port { + zephyr_camera_dvp_in: endpoint { + remote-endpoint = <&ov2640_ep_out>; + }; + }; +}; diff --git a/boards/weact/mini_stm32h743/mini_stm32h743.dts b/boards/weact/mini_stm32h743/mini_stm32h743.dts index 9968b82d7d7b4..c4e649714ba35 100644 --- a/boards/weact/mini_stm32h743/mini_stm32h743.dts +++ b/boards/weact/mini_stm32h743/mini_stm32h743.dts @@ -83,6 +83,29 @@ watchdog0 = &iwdg; sdhc0 = &sdmmc1; }; + + dcmi_camera_connector: connector_dcmi_camera { + compatible = "weact,dcmi-camera-connector"; + #gpio-cells = <2>; + gpio-map-mask = <0xffffffff 0xffffffc0>; + gpio-map-pass-thru = <0 0x3f>; + + gpio-map = <3 0 &gpiob 9 0>, /* DVP_SDA (I2C1_SDA) */ + <5 0 &gpiob 8 0>, /* DVP_SCL (I2C1_SCL) */ + <7 0 &gpiob 7 0>, /* DVP_VSYNC */ + <8 0 &gpioa 7 0>, /* DVP_PWDN */ + <9 0 &gpioa 4 0>, /* DVP_HSYNC */ + <12 0 &gpioe 6 0>, /* DVP_D7 */ + <13 0 &gpioa 8 0>, /* DVP_XCLK (RCC_MCO1) */ + <14 0 &gpioe 5 0>, /* DVP_D6 */ + <16 0 &gpiod 3 0>, /* DVP_D5 */ + <17 0 &gpioa 6 0>, /* DVP_PCLK */ + <18 0 &gpioe 4 0>, /* DVP_D4 */ + <19 0 &gpioc 6 0>, /* DVP_D0 */ + <20 0 &gpioe 1 0>, /* DVP_D3 */ + <21 0 &gpioc 7 0>, /* DVP_D1 */ + <22 0 &gpioe 0 0>; /* DVP_D2 */ + }; }; &clk_lsi { @@ -220,3 +243,15 @@ zephyr_udc0: &usbotg_fs { &iwdg1 { status = "okay"; }; + +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"; +}; diff --git a/dts/bindings/gpio/weact,dcmi-camera-connector.yaml b/dts/bindings/gpio/weact,dcmi-camera-connector.yaml new file mode 100644 index 0000000000000..786ecc915374a --- /dev/null +++ b/dts/bindings/gpio/weact,dcmi-camera-connector.yaml @@ -0,0 +1,24 @@ +# SPDX-License-Identifier: Apache-2.0 + +description: | + GPIO pins exposed on the DCMI camera connector used for interfacing + with the OV2640, OV7670, and OV5640 camera sensors. + + Connector layout (not mapped GPIOs in parentheses): + + (1) OV_STROBE (Unused) (2) AGND + 3 DVP_SDA (4) AVDD-2V8 + 5 DVP_SCL (6) DVP_RST + 7 DVP_VSYNC 8 DVP_PWDN + 9 DVP_HSYNC (10) DVDD-1V5 + (11) 2V8 12 DVP_D7 + 13 DVP_XCLK 14 DVP_D6 + (15) GND 16 DVP_D5 + 17 DVP_PCLK 18 DVP_D4 + 19 DVP_D0 20 DVP_D3 + 21 DVP_D1 22 DVP_D2 + (23) AF-2V8 (24) GND + +compatible: "weact,dcmi-camera-connector" + +include: [gpio-nexus.yaml, base.yaml] diff --git a/samples/drivers/video/capture_to_lvgl/Kconfig b/samples/drivers/video/capture_to_lvgl/Kconfig index 541ca33e1d35f..edff9ffbc3708 100644 --- a/samples/drivers/video/capture_to_lvgl/Kconfig +++ b/samples/drivers/video/capture_to_lvgl/Kconfig @@ -3,7 +3,9 @@ # Copyright (c) 2024 Charles Dias # SPDX-License-Identifier: Apache-2.0 -source "Kconfig.zephyr" +mainmenu "Video capture to LVGL sample application" + +menu "Video capture configuration" config VIDEO_WIDTH int "Define the width of the video" @@ -20,3 +22,7 @@ config VIDEO_HFLIP config VIDEO_VFLIP bool "Vertical flip" default n + +endmenu + +source "Kconfig.zephyr" diff --git a/samples/drivers/video/capture_to_lvgl/sample.yaml b/samples/drivers/video/capture_to_lvgl/sample.yaml index 39d722403f8a8..64b2396a5e8d9 100644 --- a/samples/drivers/video/capture_to_lvgl/sample.yaml +++ b/samples/drivers/video/capture_to_lvgl/sample.yaml @@ -1,10 +1,21 @@ sample: name: Video capture to LVGL tests: - sample.video.capture_to_lvgl: + sample.video.capture_to_lvgl.shield.weact_ov2640_cam_module: tags: - video + - shield - samples + extra_args: SHIELD=weact_ov2640_cam_module + harness: console + harness_config: + fixture: fixture_camera + type: multi_line + ordered: true + regex: + - "Device name" + - "Format" + - "Capture started" platform_allow: - mini_stm32h743 depends_on: video