第一次接触RK3588的DVP摄像头接口时,我对着开发板上那排密密麻麻的引脚发呆了半天。DVP(Digital Video Port)这种并行接口在嵌入式领域其实很常见,但每个平台的实现细节总有差异。RK3588的DTS配置看似简单,实际藏着不少硬件工程师才知道的"暗坑"。
DVP接口本质上是通过并行总线传输图像数据,包含以下几组关键信号:
在RK3588的硬件设计中,这些信号线需要与SoC的CIF(Camera Interface)模块对接。有个容易混淆的点是:虽然内核文档里都叫CIF接口,但实际硬件连接时用的就是DVP引脚。我刚开始就因为这个误解,在原理图设计阶段浪费了半天时间。
打开RK3588的pinctrl文件(一般是rk3588s-pinctrl.dtsi),会看到这样的配置段:
dts复制cif {
/omit-if-no-ref/ cif_dvp_clk: cif-dvp-clk {
rockchip,pins =
/* cif_clkin */ <4 RK_PB0 1 &pcfg_pull_none>,
/* cif_href */ <4 RK_PB2 1 &pcfg_pull_none>,
/* cif_vsync */ <4 RK_PB3 1 &pcfg_pull_none>;
};
/omit-if-no-ref/ cif_dvp_bus8: cif-dvp-bus8 {
rockchip,pins =
/* cif_d0 */ <4 RK_PA0 1 &pcfg_pull_none>,
/* cif_d1 */ <4 RK_PA1 1 &pcfg_pull_none>,
/* cif_d2 */ <4 RK_PA2 1 &pcfg_pull_none>,
/* cif_d3 */ <4 RK_PA3 1 &pcfg_pull_none>,
/* cif_d4 */ <4 RK_PA4 1 &pcfg_pull_none>,
/* cif_d5 */ <4 RK_PA5 1 &pcfg_pull_none>,
/* cif_d6 */ <4 RK_PA6 1 &pcfg_pull_none>,
/* cif_d7 */ <4 RK_PA7 1 &pcfg_pull_none>;
};
}
这里有个实战经验:即使你的摄像头支持16位模式,也建议先用8位调试。16位模式对PCB布线要求更高,容易因信号完整性问题导致图像错位。我曾经有个项目因为用了16位模式,不得不重新打板。
所有DVP摄像头都必须挂载到I2C总线,这是RK3588驱动框架的强制要求。即使摄像头本身不需要I2C配置(比如某些模拟摄像头),也得在设备树里声明:
dts复制&i2c1 {
status = "okay";
pinctrl-names = "default";
pinctrl-0 = <&i2c1m2_xfer>;
gc2145: gc2145@30 {
status = "okay";
compatible = "galaxycore,gc2145";
reg = <0x30>;
clocks = <&cru CLK_CIFOUT_OUT>;
clock-names = "xvclk";
power-domains = <&power RK3588_PD_VI>;
pinctrl-names = "default";
pinctrl-0 = <&cif_dvp_clk &cif_dvp_bus8>;
port {
gc2145_out: endpoint {
remote-endpoint = <&dvp_in_bcam1>;
};
};
};
}
注意这几个关键参数:
DVP最让人头疼的就是同步信号极性配置。不同厂家的摄像头可能使用不同的同步极性,配置错误会导致图像撕裂或完全无法采集。在设备树中这样定义:
dts复制dvp_in_bcam1: endpoint@1 {
reg = <1>;
remote-endpoint = <&gc2145_out>;
bus-width = <8>;
vsync-active = <0>; /* 0-低电平有效 1-高电平有效 */
hsync-active = <1>; /* 同上 */
};
如何确定极性?我的经验方法是:
有个快速验证的技巧:先设置vsync-active = <0>,如果图像上下颠倒,就改为<1>。同理适用于水平同步。
确保内核已开启相关驱动:
bash复制make menuconfig
需要确认以下选项:
code复制Device Drivers -> Multimedia support -> V4L platform devices ->
Rockchip Video Capture Host Driver (CONFIG_VIDEO_ROCKCHIP_CIF)
Rockchip ISP1 driver (CONFIG_VIDEO_ROCKCHIP_ISP1)
加载驱动后,通过dmesg查看关键信息:
bash复制dmesg | grep -i cif
正常应该看到类似输出:
code复制rkcif ff950000.cif: Linked as a consumer to ff870000.iommu
rkcif ff950000.cif: Registered rockchip-cif as /dev/video0
如果出现"failed to get cif clock"之类的错误,检查:
使用v4l2-ctl工具测试:
bash复制v4l2-ctl --list-devices # 查看设备节点
v4l2-ctl --set-fmt-video=width=640,height=480,pixelformat=YUYV
v4l2-ctl --stream-mmap=3 --stream-count=10 --stream-to=test.raw
如果图像出现条纹或颜色异常,很可能是:
可能原因:
典型错误:"probe of gc2145 failed with error -121"
排查步骤:
调试方法:
bash复制v4l2-ctl --get-parm
dts复制clocks = <&cru CLK_CIFOUT_OUT>;
clock-frequency = <24000000>; /* 根据摄像头规格调整 */
最后分享几个硬件层面的经验:
线序检查:DVP接口的引脚定义没有统一标准,不同厂家的摄像头可能线序不同。我遇到过同一个型号不同批次的摄像头,数据线D0-D7的顺序居然相反。
信号完整性:
电源设计:
记得第一次调试GC2145时,因为没注意电源纹波,图像总是出现周期性噪点。后来在电源端加了LC滤波电路才解决问题。这些经验都是踩坑踩出来的,希望你能少走些弯路。