RK3576 OV5648 Sensor 调试

文章目录

1、环境介绍

硬件:RK3576 板卡、OV5648 模组

软件:RK3576 原厂 SDK(buildroot 系统)

2、RK3576 VI

RK3576 ISP 属于 RK ISP v3.9 版本。RK3576 VI 作为视频输入模块总称,其中包含:

  • 接口以及数据采集部分:DPHY、DVP、CSI、VICAP
  • 图像处理部分:ISP、VPSS

2.1、Video Input Interface

2.1.1、MIPI CSI-2 接口

RK3576 支持 3 组 MIPI CSI-2 输入接口,其中包括 2 组 D-PHY 接口 和 1 组 C/D-PHY 接口。

RK3576 的 MIPI CSI-2 输入能力如下:

plain 复制代码
2 组 4-lane D-PHY v1.2 接口
1 组 4-lane D-PHY v2.0 / 3-trio C-PHY v1.1 接口

其中:

plain 复制代码
D-PHY v1.2:用于普通 MIPI CSI-2 摄像头输入
C/D-PHY:可配置为 D-PHY 或 C-PHY 模式

两组普通 D-PHY 接口均支持拆分模式:

plain 复制代码
每组 4-lane D-PHY 可配置为 2 个 2-lane port

因此从接口形态上看,RK3576 可支持:

plain 复制代码
2 组 4-lane D-PHY
或者
4 组 2-lane D-PHY + 1 组 C/D-PHY

也就是说,理论上最多可形成:

plain 复制代码
4 路 2-lane MIPI CSI + 1 路 C/D-PHY MIPI CSI

2.1.2、DVP 并口输入能力

plain 复制代码
支持 8 / 10 / 12 / 16-bit 数据宽度
最高 I/O 频率 150MHz
支持 BT.601 / BT.656 / BT.1120 视频输入接口
支持 pixel_clk / hsync / vsync 极性配置
支持 BT.656 / BT.1120 的 2/4 mux byte interleave 格式
支持 BT.656 / BT.1120 双边沿采样

2.2、VI 框图

2.3、AIQ 工作模式

ISP39 包括硬件算法实现及软件逻辑控制部分,RkAiq 即为软件逻辑控制部分的实现。

RkAiq 软件模块主要实现的功能为:从 ISP 驱动获取图像统计,结合 IQ Tuning 参数,使用一系列算法计算出新的ISP、Sensor 等硬件参数,不断迭代该过程,最终达到最优的图像效果。

ISP 硬件 pipeline 目前可工作在如下三种模式下:

  1. CIS -> VICAP -> ISP
  • 该模式 Sensor Raw 数据经 VICAP 采集后直通到 ISP,未经过 DDR 中转。应用于单摄情况,该方式为最省内存、带宽方式。
  1. CIS -> VICAP -> DDR -> ISP
  • 该模式 Sensor Raw 数据经 VICAP 采集后先存放在 DDR,ISP 再从 DDR 读取 Raw 数据进行处理。应用于多摄、超分辨率或者应用需要先处理 Raw 的情况。
  1. DDR->ISP
  • 该模式 Raw 数据不直接从 Sensor 来,可来源于文件系统或其他方式。将 Raw 数据放入 DDR 后,ISP 再从 DDR 读取 Raw 进行处理。该方式未实际接 Sensor,所以不需要控制 Sensor 曝光。

3、原理图查看

从原理可得:

  1. Sensor 时钟由 RK3576 提供,引脚 GPIO4_A1_d(CLK_MIPI_CAMERAOUT_M2)
  2. i2c 接口:i2c4_m3
  3. PWDN 脚:GPIO3_D4_d
  4. RESET 脚:GPIO3_D6_d
  5. LED 补光灯 EN 脚:GPIO3_D2_d

4、内核配置

OV5648 模组集成了一个 DW9714 对焦芯片,需要开启驱动。

plain 复制代码
CONFIG_VIDEO_OV5648=y
CONFIG_VIDEO_DW9714=y

5、设备树配置

设备树使用主设备树加模块设备树的形式,在主设备树中引入摄像头设备树:

plain 复制代码
rk3576-xfboard-dphy3-ov5648.dtsi
c 复制代码
/* dphy3 */
/* RST 			GPIO3_D6_d */
/* PWDN 		GPIO3_D4_d */
/* PWREN 		GPIO3_C6_d */
/* LED_PWREN 	GPIO3_D2_d */

&{/} {
	ov5648_avdd: ov5648-avdd-regulator {
		compatible = "regulator-fixed";
		gpio = <&gpio3 RK_PC6 GPIO_ACTIVE_HIGH>;
		pinctrl-names = "default";
		pinctrl-0 = <&ov5648_pwr>;
		regulator-name = "ov5648_avdd";
		enable-active-high;
	};

	ov5648_led_reg: ov5648-led-en {
		compatible = "regulator-fixed";
		gpio = <&gpio3 RK_PD2 GPIO_ACTIVE_HIGH>;
		pinctrl-names = "default";
		pinctrl-0 = <&ov5648_led_pwr>;
		regulator-name = "ov5648_led_en";
		enable-active-high;
		regulator-boot-on;
		regulator-always-on;
	};
};

&i2c4 {
	status = "okay";
	pinctrl-0 = <&i2c4m3_xfer>;

	dw9714: dw9714-0@c {
		status = "okay";
		compatible = "dongwoon,dw9714";
		reg = <0xc>;
		avdd-supply = <&ov5648_avdd>;
		rockchip,camera-module-index = <0>;
		rockchip,camera-module-facing = "back";
		rockchip,vcm-max-current = <120>;
		rockchip,vcm-start-current = <10>;
		rockchip,vcm-rated-current = <85>;
		rockchip,vcm-step-mode = <9>;
	};

	ov5648: ov5648-0@36 {
		compatible = "ovti,ov5648";
		status = "okay";
		reg = <0x36>;
		clocks = <&cru CLK_MIPI_CAMERAOUT_M2>;
		clock-names = "xvclk";
		pinctrl-names = "default";
		pinctrl-0 = <&cam_clk2m0_clk2
					 &ov5648_pwdn
                     &ov5648_rst>;
		reset-gpios = <&gpio3 RK_PD6 GPIO_ACTIVE_LOW>;
        pwdn-gpios = <&gpio3 RK_PD4 GPIO_ACTIVE_HIGH>;
		avdd-supply = <&ov5648_avdd>;
		rockchip,camera-module-index = <0>;
		rockchip,camera-module-facing = "back";
		rockchip,camera-module-name = "THDS11073";
		rockchip,camera-module-lens-name = "Largan-40122a1";
		lens-focus = <&dw9714>;
		port {
			/* MIPI CSI-2 bus endpoint */
			ov5648_dphy3_out: endpoint {
				remote-endpoint = <&dphy3_in_ov5648>;
				clock-lanes = <0>;
				data-lanes = <1 2>;
			};
		};
	};
};

/* sensor --> csi2_dphy3 --> mipi3_csi2 --> rkcif_mipi_lvds3 */
/* rkcif_mipi_lvds3_sditf --> rkisp_vir2 */
&csi2_dphy3 {
	status = "okay";

	ports {
		#address-cells = <1>;
		#size-cells = <0>;
		port@0 {
			reg = <0>;
			#address-cells = <1>;
			#size-cells = <0>;

			dphy3_in_ov5648: endpoint@1 {
				reg = <1>;
				remote-endpoint = <&ov5648_dphy3_out>;
				data-lanes = <1 2>;
			};
		};
		port@1 {
			reg = <1>;
			#address-cells = <1>;
			#size-cells = <0>;

			csidphy3_out: endpoint@0 {
				reg = <0>;
				remote-endpoint = <&mipi3_csi2_input>;
			};
		};
	};
};

&mipi3_csi2 {
	status = "okay";

	ports {
		#address-cells = <1>;
		#size-cells = <0>;

		port@0 {
			reg = <0>;
			#address-cells = <1>;
			#size-cells = <0>;

			mipi3_csi2_input: endpoint@1 {
				reg = <1>;
				remote-endpoint = <&csidphy3_out>;
			};
		};

		port@1 {
			reg = <1>;
			#address-cells = <1>;
			#size-cells = <0>;

			mipi3_csi2_output: endpoint@0 {
				reg = <0>;
				remote-endpoint = <&cif_mipi_in3>;
			};
		};
	};
};

&rkcif_mipi_lvds3 {
	status = "okay";

	port {
		cif_mipi_in3: endpoint {
			remote-endpoint = <&mipi3_csi2_output>;
		};
	};
};

&rkcif_mipi_lvds3_sditf {
	status = "okay";

	port {
		mipi3_lvds_sditf: endpoint {
			remote-endpoint = <&isp_vir2>;
		};
	};
};

&rkisp_vir2 {
	status = "okay";

	port {
		#address-cells = <1>;
		#size-cells = <0>;

		isp_vir2: endpoint@0 {
			reg = <0>;
			remote-endpoint = <&mipi3_lvds_sditf>;
		};
	};
};

&rkcif {
	status = "okay";
};

&rkcif_mmu {
	status = "okay";
};

&rkisp {
	status = "okay";
};

&rkisp_mmu {
	status = "okay";
};

&rkvpss {
	status = "okay";
};

&rkvpss_mmu {
	status = "okay";
};

&rkvpss_vir3 {
	status = "okay";
};

&pinctrl {
    ov5648 {
       	ov5648_led_pwr: ov5648-led-en {
			rockchip,pins =
				/* led power en */
				<3 RK_PD2 RK_FUNC_GPIO &pcfg_pull_none>;
		}; 

		ov5648_pwr: ov5648-pwr {
			rockchip,pins =
				/* camera power en */
				<3 RK_PC6 RK_FUNC_GPIO &pcfg_pull_none>;
		}; 

        ov5648_rst: ov5648-rst {
			rockchip,pins = 
				/* camera reset */
				<3 RK_PD6 RK_FUNC_GPIO &pcfg_pull_none>;
		};

		ov5648_pwdn: ov5648-pwdn {
			rockchip,pins = 
				/* camera power down */
				<3 RK_PD4 RK_FUNC_GPIO &pcfg_pull_none>;
		};
    };
};

6、测试

详细的抓图测试可以参考:摄像头应用编程(一):使用v4l2-ctl、media-ctl采集摄像头数据-CSDN博客

本次抓图的节点为 video11、video12:

以 video12 为例,抓图命令:

c 复制代码
v4l2-ctl --verbose -d /dev/video12 --set-fmt-video=width=640,height=480,pixelformat=NV21 --stream-mmap=4 --stream-skip=3 --stream-count=1 --stream-to=./video12.yuv --stream-poll
c 复制代码
root@rk3576-buildroot:/# v4l2-ctl --verbose -d /dev/video12 --set-fmt-video=width=640,height=480,pixelformat=NV21 --stream-mmap=4 --stream-ski              p=3 --stream-count=1 --stream-to=./video12.yuv --stream-poll
VIDIOC_QUERYCAP: ok
VIDIOC_G_FMT: ok
VIDIOC_S_FMT: ok
Format Video Capture Multiplanar:
        Width/Height      : 640/480
        Pixel Format      : 'NV21' (Y/VU 4:2:0)
        Field             : None
        Number of planes  : 1
        Flags             :
        Colorspace        : Default
        Transfer Function : Default
        YCbCr/HSV Encoding: Default
        Quantization      : Full Range
        Plane 0           :
           Bytes per Line : 640
           Size Image     : 460800
                VIDIOC_REQBUFS returned 0 (Success)
                VIDIOC_CREATE_BUFS returned 0 (Success)
                VIDIOC_QUERYBUF returned 0 (Success)
                VIDIOC_QUERYBUF returned 0 (Success)
[ 1574.217263] rkisp_hw 27c00000.isp: set isp clk = 396000000Hz
                VIDIOC_QUERYBUF returned 0 (Success)
                VIDIOC_QUERYBUF returned 0 (Success)
                VIDIOC_G_FMT returned 0 (Success)
                VIDIOC_QBUF returned 0 (Success)
                VIDIOC_QBUF returned 0 (Success)
                VIDIOC_QBUF returned 0 (Success)
                VIDIOC_QBUF returned 0 (Success)
[ 1574.229970] rkcif-mipi-lvds3: stream[0] start streaming
[ 1574.231418] rockchip-mipi-csi2 mipi3-csi2: stream on, src_sd: 000000004cc53e5a, sd_name:rockchip-csi2-dphy3
[ 1574.232849] rockchip-mipi-csi2 mipi3-csi2: stream ON
[ 1574.234428] rockchip-csi2-dphy3: dphy4, data_rate_mbps 420
[ 1574.235861] rockchip-csi2-dphy csi2-dphy3: csi2_dphy_s_stream stream on:1, dphy4, ret 0
[ 1574.237292] ov5648 4-0036: ov5648_s_stream(878) enter!
[ 1574.238709] ov5648 4-0036: stream on!!!
[ 1574.259778] ov5648 4-0036: ov5648_set_ctrl Unhandled id:0x9f0905, val:0x400
                VIDIOC_STREAMON returned 0 (Success)
cap dqbuf: 0 seq:      0 bytesused: 460800 ts: 1572.884470 field: Any (ts-monotonic, ts-src-eof)
cap dqbuf: 1 seq:      1 bytesused: 460800 ts: 1572.951033 delta: 66.563 ms field: Any (ts-monotonic, ts-src-eof)
cap dqbuf: 2 seq:      2 bytesused: 460800 ts: 1573.017541 delta: 66.508 ms field: Any (ts-monotonic, ts-src-eof)
cap dqbuf: 3 seq:      3 bytesused: 460800 ts: 1573.084043 delta: 66.502 ms field: Any (ts-monotonic, ts-src-eof)
[ 1574.595782] rkcif-mipi-lvds3: stream[0] start stopping, total mode 0x2, cur 0x2
[ 1574.662471] rockchip-mipi-csi2 mipi3-csi2: stream off, src_sd: 000000004cc53e5a, sd_name:rockchip-csi2-dphy3
[ 1574.668727] rockchip-mipi-csi2 mipi3-csi2: stream OFF
[ 1574.674856] rockchip-csi2-dphy csi2-dphy3: csi2_dphy_s_stream_stop stream stop, dphy4
[ 1574.680976] rockchip-csi2-dphy csi2-dphy3: csi2_dphy_s_stream stream on:0, dphy4, ret 0
[ 1574.687120] ov5648 4-0036: ov5648_s_stream(878) enter!
[ 1574.693220] ov5648 4-0036: stream off!!!
[ 1574.699776] rkcif-mipi-lvds3: stream[0] stopping finished, dma_en 0x0

windows 下使用 yuv player.exe 查看,这是没有 iqfile 的效果:

7、遇到的问题

7.1、系统启动后,内核概率性崩溃

c 复制代码
Starting irqbalance: OK
Starting system message bus: done
Failed to detect Wi-Fi/BT chip!
Starting bluetoothd: OK
Starting network: OK
Starting dhcpcd...
dhcpcd-10.1.0 starting
dev: loaded udev
no valid interfaces found
Starting chronyd: [   11.704973] ov5648 4-0036: write reg(0x100 val:0x0)failed !
[   11.706449] m00_b_ov5648 4-0036: could not set init registers
[   11.709296] ------------[ cut here ]------------
[   11.711001] WARNING: CPU: 4 PID: 601 at drivers/media/v4l2-core/v4l2-mc.c:475 pipeline_pm_power_one+0xfc/0x150
[   11.712603] Modules linked in:
[   11.714174] CPU: 4 PID: 601 Comm: rkaiq_3A_server Tainted: G        W          6.1.118 #8
[   11.715757] Hardware name: Rockchip RK3576 XFBoard (DT)
[   11.717324] pstate: a0000005 (NzCv daif -PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[   11.718886] pc : pipeline_pm_power_one+0xfc/0x150
[   11.720445] lr : pipeline_pm_power.part.0+0x5c/0xf0
[   11.721996] sp : ffffffc00d223ac0
[   11.723546] x29: ffffffc00d223ac0 x28: 0000000000000004 x27: 0000000000000000
[   11.725112] x26: 0000000000000000 x25: ffffff80c4b00958 x24: ffffffc00a7e4000
[   11.726669] x23: ffffff80c4b00958 x22: 00000000ffffffff x21: 00000000ffffffff
[   11.728230] x20: ffffff80c2116920 x19: 00000000ffffffff x18: 0000000000000000
[   11.729761] x17: 0000000000000000 x16: 0000000000000000 x15: 0000000000000000
[   11.731299] x14: 0000000000000000 x13: 0000000000000000 x12: 0000000000000000
[   11.732843] x11: 0000000000000000 x10: 0000000000000000 x9 : ffffffc008d5788c
[   11.734366] x8 : ffffff80c35f0588 x7 : 0000000000000000 x6 : ffffffc00a750520
[   11.735875] x5 : 0000000000007002 x4 : ffffff80c5390128 x3 : 0000000000000004
[   11.737386] x2 : 0000000000000002 x1 : 0000000000000002 x0 : ffffff80c2116920
[   11.738901] Call trace:
[   11.740415]  pipeline_pm_power_one+0xfc/0x150
[   11.741939]  pipeline_pm_power.part.0+0x5c/0xf0
[   11.743457]  v4l2_pipeline_pm_use+0x58/0x90
[   11.744979]  v4l2_pipeline_pm_put+0x18/0x30
[   11.746503]  sditf_s_power+0x148/0x244
[   11.748049]  pipeline_pm_power_one+0x148/0x150
[   11.749591]  pipeline_pm_power.part.0+0x5c/0xf0
[   11.751131]  v4l2_pipeline_pm_use+0x58/0x90
[   11.752673]  v4l2_pipeline_pm_put+0x18/0x30
[   11.754222]  rkisp_stats_fop_release+0x4c/0x5c
[   11.755753]  v4l2_release+0xbc/0xf0
[   11.757289]  __fput+0x84/0x260
[   11.758827]  ____fput+0x14/0x1c
[   11.760353]  task_work_run+0xb8/0x170
[   11.761875]  do_notify_resume+0x450/0xde0
[   11.763385]  el0_svc+0x6c/0x80
[   11.764908]  el0t_64_sync_handler+0xb0/0xb4
[   11.766420]  el0t_64_sync+0x158/0x15c

codex 说这是 /usr/lib/udev/rules.d/60-persistent-v4l.rules udev 规则文件的问题。修改 60-persistent-v4l.rules,将 v4l_id 调用限制在 USB video 设备上,避免 udev 冷启动阶段打开 Rockchip ISP/CIF摄像头节点,导致 OV5648 pipeline 被提前上电/下电并触发 v4l2_pipeline_pm_use warning。修改后的规则文件如下:

c 复制代码
# do not edit this file, it will be overwritten on update

ACTION=="remove", GOTO="persistent_v4l_end"
SUBSYSTEM!="video4linux", GOTO="persistent_v4l_end"
ENV{MAJOR}=="", GOTO="persistent_v4l_end"

# Only run v4l_id for USB cameras. Opening Rockchip ISP/CIF video nodes
# during udev coldplug may power-cycle the camera pipeline before userspace
# is ready and can trigger v4l2_pipeline_pm_use warnings.
SUBSYSTEMS=="usb", IMPORT{program}="v4l_id $devnode"

SUBSYSTEMS=="usb", IMPORT{builtin}="usb_id"
SUBSYSTEMS=="usb", KERNEL=="video*", ENV{ID_SERIAL}=="?*", SYMLINK+="v4l/by-id/$env{ID_BUS}-$env{ID_SERIAL}-video-index$attr{index}"

# check for valid "index" number
TEST!="index", GOTO="persistent_v4l_end"
ATTR{index}!="?*", GOTO="persistent_v4l_end"

IMPORT{builtin}="path_id"
ENV{ID_PATH}=="?*", KERNEL=="video*|vbi*", SYMLINK+="v4l/by-path/$env{ID_PATH}-video-index$attr{index}"
ENV{ID_PATH}=="?*", KERNEL=="audio*", SYMLINK+="v4l/by-path/$env{ID_PATH}-audio-index$attr{index}"

LABEL="persistent_v4l_end"

8、参考文章

无。

9、总结

无。

相关推荐
飘忽不定的bug19 天前
记录:RK3576 适配开源GPU驱动(panfrost)
linux·gpu·rk3576·panfrost
Suifqwu1 个月前
rk3576(7)之平台设备
rk3576
阿拉斯攀登2 个月前
第 11 篇 RK 平台安卓驱动实战 4:I2C 设备驱动开发,以 OLED 屏为例
android·驱动开发·i2c·瑞芯微·嵌入式驱动·rk3576·嵌入式安卓
阿拉斯攀登2 个月前
第 9 篇 RK 平台安卓驱动实战 2:中断驱动开发,按键中断的完整实现
驱动开发·嵌入式硬件·rk3568·中断·瑞芯微·rk3576·rk安卓驱动
阿拉斯攀登2 个月前
第 18 篇 综合项目实战:基于 RK3568 的安卓智能门禁系统,全栈开发
android·驱动开发·瑞芯微·嵌入式驱动·rk3576·安卓驱动
阿拉斯攀登2 个月前
第 10 篇 RK 平台安卓驱动实战 3:PWM 驱动开发,实现 LED 呼吸灯 + 电机调速
驱动开发·嵌入式硬件·pwm·瑞芯微·嵌入式驱动·rk3576·嵌入式安卓
AomanHao2 个月前
【ISP】搭载海思自研CIS,骁途S7Pro运动相机系列亮相AWE
数码相机·sensor·cmose
阿拉斯攀登2 个月前
【瑞芯微 RK 系列 + 安卓驱动全栈教程】博客系列
嵌入式硬件·安卓·瑞芯微·rk3576·嵌入式安卓·安卓驱动
Suifqwu2 个月前
rk3576(2)之添加qt以及添加linux旋转补丁
rk3576