前两天用某个厂家的rk3399开发板调试了OV13850的摄像头,其中遇到了一些问题来做一下记录。
在读完相关的手册之后想必大家也都知道,RK对很多摄像头的驱动都做了相应的支持。需要我们二次开发的东西很少,只需要对相应的cam_board.xml文件进行配置就可以了。
配置文件路径和内容如下:android8_1\hardware\rockchip\camera\Config\cam_board_rk3399.xml
<Sensor>
<SensorName name="OV13850" ></SensorName>
<SensorLens name="50013A1"></SensorLens>
<SensorDevID IDname="CAMSYS_DEVID_SENSOR_1A"></SensorDevID>
<SensorHostDevID busnum="CAMSYS_DEVID_MARVIN" ></SensorHostDevID>
<SensorI2cBusNum busnum="1"></SensorI2cBusNum>
<SensorI2cAddrByte byte="2"></SensorI2cAddrByte>
<SensorI2cRate rate="100000"></SensorI2cRate>
<SensorAvdd name="NC" min="28000000" max="28000000" delay="0"></SensorAvdd>
<SensorDvdd name="NC" min="12000000" max="12000000" delay="0"></SensorDvdd>
<SensorDovdd name="NC" min="18000000" max="18000000" delay="5000"></SensorDovdd>
<SensorMclk mclk="24000000" delay="1000"></SensorMclk>
<SensorGpioPwen ioname="NC" active="1" delay="1000"></SensorGpioPwen>
<!--<SensorGpioRst ioname="RK30_PIN2_PD3" active="0" delay="1000"></SensorGpioRst>-->
<SensorGpioRst ioname="RK30_PIN1_PB5" active="0" delay="1000"></SensorGpioRst>
<SensorGpioPwdn ioname="RK30_PIN0_PA2" active="0" delay="0"></SensorGpioPwdn>
<SensorFacing facing="back"></SensorFacing>
<SensorInterface interface="MIPI"></SensorInterface>
<SensorMirrorFlip mirror="0"></SensorMirrorFlip>
<SensorOrientation orientation="180"></SensorOrientation>
<SensorPowerupSequence seq="1234"></SensorPowerupSequence>
<SensorFovParemeter h="60.0" v="60.0"></SensorFovParemeter>
<SensorAWB_Frame_Skip fps="15"></SensorAWB_Frame_Skip>
<SensorPhy phyMode="CamSys_Phy_Mipi" lane="2" phyIndex="0" sensorFmt="CamSys_Fmt_Raw_10b"></SensorPhy>
</Sensor>
因为做了块转接板接入摄像头,有的个别引脚发生变动需要重新配置。其他的内容由于源码中给出的示例就是OV13850,所以基本不需要什么变动。其他的按照瑞芯微官方提供的烧录调试手册一步一步来。整个过程出现一下两个问题:
(1)mclk信号线没有输出
一切准备就绪,编译,烧录,上电出现以下错误。
由上图可知摄像头对开发办板出的命令并没有响应。分析原因,可能是摄像头I2C供电有问题。经测量其他引脚均正常,只有对应的mclk没有输出。因为mclk线不在我们改动的那几根引脚之中,所以怀疑是配置问题。从上面配置文件可知mclk配置的输出是24MHz,没什么问题。
经过上述分析怀疑是硬件问题,烧入厂家提供的原始镜像进行对比发现可以输出对应的mclk。最后定位到设备树上。跟厂家提出问题后由厂家重新提供一份设备树文件使用对比工具后发现mclk信号线确实缺失了一部分。对比修改后的内容如下:
isp0: isp@ff910000 {
compatible = "rockchip,rk3399-isp", "rockchip,isp";
reg = <0x0 0xff910000 0x0 0x4000>;
interrupts = <GIC_SPI 43 IRQ_TYPE_LEVEL_HIGH 0>;
clocks =
<&cru SCLK_CIF_OUT>, <&cru SCLK_CIF_OUT>,
<&cru SCLK_DPHY_TX1RX1_CFG>, <&cru SCLK_MIPIDPHY_REF>,
<&cru ACLK_ISP0_NOC>, <&cru ACLK_ISP0_WRAPPER>,
<&cru HCLK_ISP0_NOC>, <&cru HCLK_ISP0_WRAPPER>,
<&cru SCLK_ISP0>, <&cru SCLK_DPHY_RX0_CFG>;
clock-names =
"clk_cif_out", "clk_cif_pll",
"pclk_dphytxrx", "pclk_dphy_ref",
"aclk_isp0_noc", "aclk_isp0_wrapper",
"hclk_isp0_noc", "hclk_isp0_wrapper",
"clk_isp0", "pclk_dphyrx";
pinctrl-names =
"cif_clkout", "isp_dvp8bit0", "isp_mipi_fl",
"isp_mipi_fl_prefl", "isp_flash_as_gpio",
"isp_flash_as_trigger_out";
pinctrl-0 = <&cif_clkout>;
pinctrl-1 = <&cif_clkout &isp_dvp_d0d7>;
pinctrl-2 = <&cif_clkout>;
pinctrl-3 = <&cif_clkout &isp_prelight>;
pinctrl-4 = <&isp_flash_trigger_as_gpio>;
pinctrl-5 = <&isp_flash_trigger>;
rockchip,isp,mipiphy = <2>;
rockchip,isp,cifphy = <1>;
rockchip,isp,dsiphy,reg = <0xff968000 0x8000>;
rockchip,grf = <&grf>;
rockchip,cru = <&cru>;
//rockchip,gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
rockchip,isp,iommu-enable = <1>;
power-domains = <&power RK3399_PD_ISP0>;
iommus = <&isp0_mmu>;
status = "disabled";
};
isp1: isp@ff920000 {
compatible = "rockchip,rk3399-isp", "rockchip,isp";
reg = <0x0 0xff920000 0x0 0x4000>;
interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH 0>;
clocks =
<&cru ACLK_ISP1_NOC>, <&cru ACLK_ISP1_WRAPPER>,
<&cru HCLK_ISP1_NOC>, <&cru HCLK_ISP1_WRAPPER>,
<&cru SCLK_ISP1>, <&cru SCLK_CIF_OUT>,
<&cru SCLK_CIF_OUT>, <&cru SCLK_DPHY_TX1RX1_CFG>,
<&cru SCLK_MIPIDPHY_REF>, <&cru PCLK_ISP1_WRAPPER>,
<&cru SCLK_DPHY_RX0_CFG>, <&cru PCLK_MIPI_DSI1>,
<&cru SCLK_MIPIDPHY_CFG>;
clock-names =
"aclk_isp1_noc", "aclk_isp1_wrapper",
"hclk_isp1_noc", "hclk_isp1_wrapper",
"clk_isp1", "clk_cif_out",
"clk_cif_pll", "pclk_dphytxrx",
"pclk_dphy_ref", "pclk_isp1",
"pclk_dphyrx", "pclk_mipi_dsi",
"mipi_dphy_cfg";
pinctrl-names =
"cif_clkout", "isp_dvp8bit0", "isp_mipi_fl",
"isp_mipi_fl_prefl", "isp_flash_as_gpio",
"isp_flash_as_trigger_out";
pinctrl-0 = <&cif_clkout>;
pinctrl-1 = <&isp_dvp_d0d7>;
pinctrl-2 = <&cif_clkout>;
pinctrl-3 = <&isp_prelight>;
pinctrl-4 = <&isp_flash_trigger_as_gpio>;
pinctrl-5 = <&isp_flash_trigger>;
rockchip,isp,mipiphy = <2>;
rockchip,isp,cifphy = <1>;
rockchip,isp,dsiphy,reg = <0xff968000 0x8000>;
rockchip,grf = <&grf>;
rockchip,cru = <&cru>;
//rockchip,gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
rockchip,isp,iommu-enable = <1>;
power-domains = <&power RK3399_PD_ISP1>;
iommus = <&isp1_mmu>;
status = "disabled";
};
isp_flash_trigger: isp-flash-trigger {
rockchip,pins = <1 3 RK_FUNC_1 &pcfg_pull_none>;
};
isp_prelight: isp-prelight {
/*ISP_PRELIGHTTRIG*/
rockchip,pins = <1 4 RK_FUNC_1 &pcfg_pull_none>;
};
isp_flash_trigger_as_gpio: isp_flash_trigger_as_gpio {
rockchip,pins =
<1 3 RK_FUNC_GPIO &pcfg_pull_none>;
};
重新编译烧录后mclk输出正常。
上面设备树代码在厂家提供的安卓源码中被厂家或注释或删减了一部分。可能是厂家在调试其他功能时修改的,发布时忘了改回来。因为一开始厂家那边说底层不需要我们改动,所以就没往这方面想。
(2)对焦传感器供电异常
上面的问题解决后mclk终于有输出了,紧接着出现了下面这个问题:
camsys_i2c_write(84): i2c write dev(addr:0x18) failed!,err = -6
这不是和上面一样的吗,就换了个地址,结合之前调试问题一时的经验,这个地址有点眼熟:
这不就是除了两个摄像头设备地址之外的另外的一个AF的地址吗。这是摄像头对焦功能模块的地址,这个模块供电的IO好像被我调试第一个问题的时候拉走了。
问题找到,重新焊上引脚配置好IO,编译,烧录,上电,摄像正常工作,问题解决。
以上就是调试摄像头的时候遇到的两个问题以及解决方法,希望可以给遇到类似问题的小伙伴提供一个解决问题的思路。