From 9b93ffba16778f7960a87241f1ffdf89626758e4 Mon Sep 17 00:00:00 2001 From: Charles Dias Date: Tue, 3 Sep 2024 15:03:45 -0300 Subject: [PATCH 1/2] boards: shields: add suport for weact_ov2640_cam_module Add support for WeAct Studio MiniSTM32H7xx OV2640 camera sensor. Signed-off-by: Charles Dias --- .../weact_ov2640_cam_module/Kconfig.shield | 5 ++ .../boards/mini_stm32h743.conf | 8 ++ .../boards/mini_stm32h743.overlay | 59 +++++++++++++ .../weact_ov2640_cam_module/doc/index.rst | 82 ++++++++++++++++++ .../weact_ov2640_cam_module/doc/ov2640.webp | Bin 0 -> 38306 bytes .../weact_ov2640_cam_module.overlay | 44 ++++++++++ .../weact/mini_stm32h743/mini_stm32h743.dts | 35 ++++++++ .../gpio/weact,dcmi-camera-connector.yaml | 24 +++++ 8 files changed, 257 insertions(+) create mode 100644 boards/shields/weact_ov2640_cam_module/Kconfig.shield create mode 100644 boards/shields/weact_ov2640_cam_module/boards/mini_stm32h743.conf create mode 100644 boards/shields/weact_ov2640_cam_module/boards/mini_stm32h743.overlay create mode 100644 boards/shields/weact_ov2640_cam_module/doc/index.rst create mode 100644 boards/shields/weact_ov2640_cam_module/doc/ov2640.webp create mode 100644 boards/shields/weact_ov2640_cam_module/weact_ov2640_cam_module.overlay create mode 100644 dts/bindings/gpio/weact,dcmi-camera-connector.yaml 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 0000000000000000000000000000000000000000..8043befcf75b02b27fe4fb66723b6e2fc71f3d2e GIT binary patch literal 38306 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 C6d*?c literal 0 HcmV?d00001 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] From 36bde7ef1ed54eb90ac4cb7db23398189bd1c613 Mon Sep 17 00:00:00 2001 From: Charles Dias Date: Thu, 24 Oct 2024 19:33:58 +0100 Subject: [PATCH 2/2] samples: drivers: video: capture_to_lvgl: add menu and update the YAML Add the Kconfig menu to the sample configuration. Update sample.yaml by adding the shield configuration. Signed-off-by: Charles Dias --- samples/drivers/video/capture_to_lvgl/Kconfig | 8 +++++++- samples/drivers/video/capture_to_lvgl/sample.yaml | 13 ++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) 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