From c79780f8b464a8c2dbf7589b298f22cc436764ea Mon Sep 17 00:00:00 2001 From: Arturo Buzarra Date: Mon, 3 Feb 2025 12:16:34 +0100 Subject: [PATCH] x-linux-ai: recipes-samples: fix CSI DCMIPP camera support This commit fixes several issues related to the initialization of AI demos when using CSI cameras (OV5640 and IMX335) with the DCMIPP peripheral. All configurations have been moved to an additional setup_camera.sh script and removed from the main demo launcher. https://onedigi.atlassian.net/browse/DEL-9486 Signed-off-by: Arturo Buzarra --- .../common/scripts/launch_npu_demo.sh | 14 +- .../resources/application-resources.bbappend | 1 + ...n_isp-fix-support-for-CSI-DCMIPP-cam.patch | 177 ++++++++++++++++++ 3 files changed, 179 insertions(+), 13 deletions(-) create mode 100644 meta-digi-dey/dynamic-layers/x-linux-ai/recipes-samples/resources/files/patches/0004-setup_camera_main_isp-fix-support-for-CSI-DCMIPP-cam.patch diff --git a/meta-digi-dey/dynamic-layers/x-linux-ai/recipes-samples/common/scripts/launch_npu_demo.sh b/meta-digi-dey/dynamic-layers/x-linux-ai/recipes-samples/common/scripts/launch_npu_demo.sh index 2e7f0842b..bd14f0b61 100644 --- a/meta-digi-dey/dynamic-layers/x-linux-ai/recipes-samples/common/scripts/launch_npu_demo.sh +++ b/meta-digi-dey/dynamic-layers/x-linux-ai/recipes-samples/common/scripts/launch_npu_demo.sh @@ -1,7 +1,7 @@ #!/bin/sh #=============================================================================== # -# Copyright (C) 2024 by Digi International Inc. +# Copyright (C) 2024,2025, by Digi International Inc. # All rights reserved. # # This program is free software; you can redistribute it and/or modify it @@ -16,18 +16,6 @@ # Default demo to launch. DEFAULT_DEMO="pose_estimation" -# Prepare MIPI camera. -media-ctl -d /dev/media0 --set-v4l2 "'ov5640 0-003c':0[fmt:SBGGR8_1X8/1280x720]" -media-ctl -d /dev/media0 --set-v4l2 "'48020000.csi':1[fmt:SBGGR8_1X8/1280x720]" -media-ctl -d /dev/media0 --set-v4l2 "'dcmipp_input':2[fmt:SBGGR8_1X8/1280x720]" -media-ctl -d /dev/media0 --set-v4l2 "'dcmipp_main_isp':1[fmt:RGB888_1X24/1280x720 field:none]" -media-ctl -d /dev/media0 --set-v4l2 "'dcmipp_main_postproc':0[compose:(0,0)/640x480]" -media-ctl -d /dev/media0 --set-v4l2 "'dcmipp_main_postproc':1[fmt:RGB565_2X8_LE/640x480]" - -# Mirror the image. -v4l2-ctl -d /dev/v4l-subdev6 --set-ctrl "horizontal_flip=1" -#v4l2-ctl -d /dev/v4l-subdev6 --set-ctrl "vertical_flip=1" - # Configure Wayland/Weston settings. export "DISPLAY=:0.0" export "XDG_RUNTIME_DIR=/run/user/0" diff --git a/meta-digi-dey/dynamic-layers/x-linux-ai/recipes-samples/resources/application-resources.bbappend b/meta-digi-dey/dynamic-layers/x-linux-ai/recipes-samples/resources/application-resources.bbappend index 79f319445..4db3150ba 100644 --- a/meta-digi-dey/dynamic-layers/x-linux-ai/recipes-samples/resources/application-resources.bbappend +++ b/meta-digi-dey/dynamic-layers/x-linux-ai/recipes-samples/resources/application-resources.bbappend @@ -6,4 +6,5 @@ SRC_URI += " \ file://patches/0001-config_board-add-support-to-STM32MP255-processor.patch \ file://patches/0002-config_board-fix-support-for-web-camera-with-STM32MP.patch \ file://patches/0003-setup_camera_main_isp-fix-support-for-web-camera.patch \ + file://patches/0004-setup_camera_main_isp-fix-support-for-CSI-DCMIPP-cam.patch \ " diff --git a/meta-digi-dey/dynamic-layers/x-linux-ai/recipes-samples/resources/files/patches/0004-setup_camera_main_isp-fix-support-for-CSI-DCMIPP-cam.patch b/meta-digi-dey/dynamic-layers/x-linux-ai/recipes-samples/resources/files/patches/0004-setup_camera_main_isp-fix-support-for-CSI-DCMIPP-cam.patch new file mode 100644 index 000000000..64b04d795 --- /dev/null +++ b/meta-digi-dey/dynamic-layers/x-linux-ai/recipes-samples/resources/files/patches/0004-setup_camera_main_isp-fix-support-for-CSI-DCMIPP-cam.patch @@ -0,0 +1,177 @@ +From f15237c3b2eaf73cdf1c1103c32f2373c003e7bb Mon Sep 17 00:00:00 2001 +From: Arturo Buzarra +Date: Mon, 3 Feb 2025 11:53:24 +0100 +Subject: [PATCH] setup_camera_main_isp: fix support for CSI DCMIPP cameras + +This commit fixes the configuration stream for CSI cameras connected to the +internal DCMIPP peripheral, including the following changes: + +- Since the /dev/media* indexes are not guaranteed by the Linux kernel and can + cause errors, this commit hardcodes the DCMIPP node to be used with the + media-ctl command + +- Keep the dynamic check to find the preferred resolution and format for the + IMX335 camera sensor. However, use hardcoded values for the OV5640 sensor, as + it occasionally reports incorrect values, causing capture failures. + +- Add support for applying horizontal mirror (flip) mode to the camera video + image. + +- Print configuration commands to display to the user the settings applied by + the script. + +https://onedigi.atlassian.net/browse/DEL-9486 + +Signed-off-by: Arturo Buzarra +--- + .../resources-files/setup_camera_main_isp.sh | 46 +++++++++++-------- + 1 file changed, 27 insertions(+), 19 deletions(-) + +diff --git a/resources-files/setup_camera_main_isp.sh b/resources-files/setup_camera_main_isp.sh +index 444bf37..466b9b3 100644 +--- a/resources-files/setup_camera_main_isp.sh ++++ b/resources-files/setup_camera_main_isp.sh +@@ -17,13 +17,15 @@ FMTdisplay=RGB16 + FMTnn=RGB + CAMERA_WIDTH=640 + CAMERA_HEIGHT=480 + displaybuscode=RGB565_2X8_LE + nnbuscode=RGB888_1X24 ++MEDIA_DCMIPP="platform:48030000.dcmipp" + + function cmd() { + cmd=$1 ++ echo "${cmd}" + eval $cmd > /dev/null 2>&1 + } + + function is_dcmipp_present() { + DCMIPP_SENSOR="NOTFOUND" +@@ -33,19 +35,18 @@ function is_dcmipp_present() { + if [ "$(cat $video/name)" = "dcmipp_aux_capture" ]; then + V4L_DEVICE_PREV="$(basename $video)" + echo "V4L_DEVICE_PREV="$V4L_DEVICE_PREV + fi + if [ "$(cat $video/name)" = "dcmipp_main_capture" ]; then +- cd $video/device/ +- mediadev=/dev/$(ls -d media*) +- cd - ++ mediadev=${MEDIA_DCMIPP} + for sub in $(find /sys/class/video4linux -name "v4l-subdev*" -type l); + do + subdev_name=$(tr -d '\0' < $sub/name | awk '{print $1}') + if [ "$subdev_name" = "ov5640" ] || [ "$subdev_name" = "imx335" ]; then + DCMIPP_SENSOR=$subdev_name + V4L_DEVICE="$(basename $video)" ++ sensorsubdevnode="$(basename $sub)" + sensorsubdev="$(tr -d '\0' < $sub/name)" + sensordev=$(media-ctl -d $mediadev -p -e "$sensorsubdev" | grep "node name" | awk -F\name '{print $2}') + #interface is connected to input of isp (":1 [ENABLED" with media-ctl -p) + interfacesubdev=$(media-ctl -d $mediadev -p -e "dcmipp_input" | grep ":1 \[ENABLED" | awk -F\" '{print $2}') + fi +@@ -90,20 +91,19 @@ if [ "$DEVICE" != "" ]; then + V4L_DEVICE_PREV="$(basename $video)" + echo "V4L_DEVICE_PREV="$V4L_DEVICE_PREV + fi + done + if [ "$(cat /sys/class/video4linux/$DEVICE/name)" = "dcmipp_dump_capture" ] || [ "$(cat /sys/class/video4linux/$DEVICE/name)" = "dcmipp_main_capture" ] ; then +- cd /sys/class/video4linux/$DEVICE/device/ +- mediadev=/dev/$(ls -d media*) +- cd - ++ mediadev=${MEDIA_DCMIPP} + for sub in $(find /sys/class/video4linux -name "v4l-subdev*" -type l); + do + subdev_name=$(tr -d '\0' < $sub/name | awk '{print $1}') + if [ "$subdev_name" = "imx335" ] || [ "$subdev_name" = "ov5640" ]; then + DCMIPP_SENSOR=$subdev_name + echo "DCMIPP_SENSOR="$DCMIPP_SENSOR + V4L_DEVICE="$(basename $DEVICE)" ++ sensorsubdevnode="$(basename $sub)" + sensorsubdev="$(tr -d '\0' < $sub/name)" + sensordev=$(media-ctl -d $mediadev -p -e "$sensorsubdev" | grep "node name" | awk -F\name '{print $2}') + #interface is connected to input of isp (":1 [ENABLED" with media-ctl -p) + interfacesubdev=$(media-ctl -d $mediadev -p -e "dcmipp_input" | grep ":1 \[ENABLED" | awk -F\" '{print $2}') + fi +@@ -126,12 +126,12 @@ if [ "$DCMIPP_SENSOR" != "NOTFOUND" ]; then + #Use sensor in raw-bayer format + sensorbuscode=`v4l2-ctl --list-subdev-mbus-codes -d $sensordev | grep SRGGB | awk -FMEDIA_BUS_FMT_ '{print $2}'` + + if [ "$DCMIPP_SENSOR" = "ov5640" ]; then + #OV5640 only support 720p with raw-bayer format +- CAMERA_WIDTH=1280 +- CAMERA_HEIGHT=720 ++ SENSORWIDTH=1280 ++ SENSORHEIGHT=720 + #OV5640 claims to support all raw bayer combinations but always output SBGGR8_1X8... + sensorbuscode=SBGGR8_1X8 + elif [ "$DCMIPP_SENSOR" = "imx335" ]; then + if [ $dual_pipe -eq 1 ]; then + aux_postproc=`media-ctl -d $mediadev -e dcmipp_aux_postproc` +@@ -139,21 +139,21 @@ if [ "$DCMIPP_SENSOR" != "NOTFOUND" ]; then + else + main_postproc=`media-ctl -d $mediadev -e dcmipp_main_postproc` + echo "main_postproc="$main_postproc + fi + sensorbuscode=SRGGB10_1X10 +- fi + +- #Let sensor return its prefered resolution & format +- media-ctl -d $mediadev --set-v4l2 "'$sensorsubdev':0[fmt:$sensorbuscode/${SENSORWIDTH}x${SENSORHEIGHT}@1/${FPS} field:none]" > /dev/null 2>&1 +- sensorfmt=`media-ctl -d $mediadev --get-v4l2 "'$sensorsubdev':0" | awk -F"fmt:" '{print $2}' | awk -F" " '{print $1}'` +- SENSORWIDTH=`echo $sensorfmt | awk -F"/" '{print $2}' | awk -F"x" '{print $1}'` +- SENSORHEIGHT=`echo $sensorfmt | awk -F"/" '{print $2}' | awk -F"x" '{print $2}' | awk -F" " '{print $1}' | awk -F"@" '{print $1}'` ++ #Let sensor return its prefered resolution & format ++ sensorfmt=`media-ctl -d $mediadev --get-v4l2 "'$sensorsubdev':0" | awk -F"fmt:" '{print $2}' | awk -F" " '{print $1}'` ++ SENSORWIDTH=`echo $sensorfmt | awk -F"/" '{print $2}' | awk -F"x" '{print $1}'` ++ SENSORHEIGHT=`echo $sensorfmt | awk -F"/" '{print $2}' | awk -F"x" '{print $2}' | awk -F" " '{print $1}' | awk -F"@" '{print $1}'` ++ fi + +- # echo "sensorsubdev="$sensorsubdev +- # echo "interfacesubdev="$interfacesubdev +- # echo "sensorbuscode="$sensorbuscode ++ echo "sensorsubdevnode="$sensorsubdevnode ++ echo "sensorsubdev="$sensorsubdev ++ echo "interfacesubdev="$interfacesubdev ++ echo "sensorbuscode="$sensorbuscode + + if [ $dual_pipe -eq 1 ]; then + #Use main pipe for debayering, scaling and color conversion + echo "Mediacontroller graph:" + +@@ -180,11 +180,15 @@ if [ "$DCMIPP_SENSOR" != "NOTFOUND" ]; then + # Configure Pipe2 PostProcessing to the display resolution + cmd " media-ctl -d $mediadev --set-v4l2 \"'dcmipp_aux_postproc':0[compose:(0,0)/${WIDTH}x${HEIGHT}]\"" + cmd " media-ctl -d $mediadev --set-v4l2 \"'dcmipp_aux_postproc':1[fmt:$displaybuscode/${WIDTH}x${HEIGHT}]\" -v" + echo "" + +- #v4l2-ctl -d /dev/v4l-subdev6 --set-ctrl=horizontal_flip=1 ++ echo "Video4linux driver:" ++ # Use to mirror(flip) the camera video image horizontally ++ cmd " v4l2-ctl -d /dev/$sensorsubdevnode --set-ctrl=horizontal_flip=1" ++ echo "" ++ + V4L2_CAPS_PREV="video/x-raw, format=$FMTdisplay, width=$WIDTH, height=$HEIGHT, framerate=$FPS/1" + V4L2_CAPS_NN="video/x-raw, format=$FMTnn, width=$RQ_NN_WIDTH, height=$RQ_NN_HEIGHT, framerate=$FPS/1" + V4L_OPT="" + echo "V4L_DEVICE_PREV="$V4L_DEVICE_PREV + echo "V4L_DEVICE_NN="$V4L_DEVICE +@@ -201,11 +205,15 @@ if [ "$DCMIPP_SENSOR" != "NOTFOUND" ]; then + cmd " media-ctl -d $mediadev --set-v4l2 \"'dcmipp_main_isp':1[fmt:RGB888_1X24/${SENSORWIDTH}x${SENSORHEIGHT} field:none]\"" + cmd " media-ctl -d $mediadev --set-v4l2 \"'dcmipp_main_postproc':0[compose:(0,0)/${WIDTH}x${HEIGHT}]\"" + cmd " media-ctl -d $mediadev --set-v4l2 \"'dcmipp_main_postproc':1[fmt:$displaybuscode/${WIDTH}x${HEIGHT}]\"" + echo "" + +- #v4l2-ctl -d /dev/v4l-subdev6 --set-ctrl=horizontal_flip=1 ++ echo "Video4linux driver:" ++ # Use to mirror(flip) the camera video image horizontally ++ cmd " v4l2-ctl -d /dev/$sensorsubdevnode --set-ctrl=horizontal_flip=1" ++ echo "" ++ + V4L2_CAPS="video/x-raw, format=$FMTdisplay, width=$WIDTH, height=$HEIGHT" + V4L_OPT="" + echo "V4L_DEVICE_PREV="$V4L_DEVICE + echo "V4L2_CAPS_PREV="$V4L2_CAPS + echo "DCMIPP_SENSOR="$DCMIPP_SENSOR +-- +2.34.1 +