MIPI CSI 使用

简介

MIPI接口分为2两类:DSI(Display Serial Interface)和CSI(Camer Serial Interface)。作为一款高性能嵌入式开发平台,ROC-RK3399-PC 开发板带有2个专用和1个复用 MIPI 接口,其中 MIPI CSI 最高支持支持4K拍照,并支持1080P 30FPS以上视频录制。MIPI接口如下所示:

  • MIPI_DSI_0

  • MIPI_CSI_0

  • MIPI_CSI_1/MIPI_DSI_1

接口实物图

_images/roc-rk3399-pc6.jpg

OV13850 配置

本文以 驱动OV13850 摄像头为例,rk3399 MIPI 和 ISP的调用过程。

_images/MIPI-CSI_ts.jpg

如图所知,cpu通过MIPI-CSI接口获取OV13850等image sensor的数据,从sensor获取到的数据不能直接使用,需要通过自带的ISP模块进行图像信号处理(该过程包含图像降噪、白平衡和曝光等过程)。

参考官方资料可知《MIPI Alliance Specification for Camera Serial Interface 2》MIPI摄像头是通过 I2C 来传输控制信号。结合ROC-RK3399-PC 的原理图可知,MIPI 接口支持高达4个数据 LAN 的信号传输,满足如今摄像头高带宽的硬件需求。综上所述,ov13850 DTS配置需满足以下需求:

1. 将ov13850节点挂载到相应I2C下,此处为i2c1

2. 引脚属性配置

  • 配置reset和pwdn gpio引脚

  • pinctrl信息

  • 配置rockchip,camera-module-(index facing name **)

  • 电源引脚信息

3. isp输出端点

  • port

  • remote-endpoint

ov13850 DTS配置如下所示:

&i2c1 {
  status = "okay";
  ...
  ov13850: ov13850@36 {
    compatible = "ovti,ov13850";
    status = "disabled";
    reg = <0x36>;
    clocks = <&cru SCLK_CIF_OUT>;
    clock-names = "xvclk";

    /* conflict with csi-ctl-gpios */
    reset-gpios = <&gpio0 8 GPIO_ACTIVE_HIGH>;	/*GPIO0_B0 MIP_RST*/
    pwdn-gpios = <&gpio2 2 GPIO_ACTIVE_HIGH>;	/*GPIO2_A2 DVP_PDN0*/

    pinctrl-names = "rockchip,camera_default", "rockchip,camera_sleep";
    //pinctrl-0 = <&cif_clkout>;
    pinctrl-0 = <&pwdn_cam0 &mipi_rst>;
    pinctrl-1 = <&cam0_default_pins>;
    pinctrl-2 = <&cam0_sleep_pins>;

    rockchip,camera-module-index = <0>;
    rockchip,camera-module-facing = "back";
    rockchip,camera-module-name = "CMK-CT0116";
    rockchip,camera-module-lens-name = "Largan-50013A1";

    avdd-supply = <&vcc_mipi>; /* GPIO1_C6 CIF_PWR  AGND*/
    dovdd-supply = <&vcc_mipi>; /* GPIO1_C6 CIF_PWR  AGND */
    dvdd-supply = <&dvdd_1v2>; /* GPIO1_C7 DVP_PWR DVDD_1V2 */

    port {
      ucam_out0: endpoint {
        remote-endpoint = <&mipi_in_ucam0>;
        data-lanes = <1 2>;
      };
    };
  };
  ...
};

ISP 和端点配置

如图所示,sensor 的数据通过 MIPI 通过传送到 ISP ,经过ISP 处理后得到可直接利用的数据,在DTS中需要设置输入输出端点,来表示数据的流向。

_images/MIPI-CSI_isp_process.jpg

ov13850: ov13850@36 {
  .. .
	port {//输出端点
		ucam_out0: endpoint {
      //数据从(输出端点)ucam_out0流向 ->(输入端点)mipi_in_ucam0
			remote-endpoint = <&mipi_in_ucam0>;
			data-lanes = <1 2>;
		};
	};
};

---------------------------------------------------
&mipi_dphy_rx0 {
...
  port@0 {
    ...
    mipi_in_ucam0: endpoint@1 {//与ucam_out0: endpoint配对
      reg = <1>;
      remote-endpoint = <&ucam_out0>;
      data-lanes = <1 2>;
    };
  };

  port@1 {
    ...
    dphy_rx0_out: endpoint@0 {//MIPI输出端点->ISP输入端点
      reg = <0>;
      remote-endpoint = <&isp0_mipi_in>;
    };
  };
};
---------------------------------------------------

rkisp1_0: rkisp1@ff910000 {
    compatible = "rockchip,rk3399-rkisp1";
        port {
        isp0_mipi_in: endpoint@0 {
            reg = <0>;
            remote-endpoint = <&dphy_rx0_out>;  //ISP的输出端点
        };
    };
};

MIPI-CIS 接口

_images/MIPI-CSI_layer_def.jpg _images/MIPI-CSI_hw.jpg

MIPI传输数据是通过一个控制LAN和若干个数据LAN传输数据,同理数据LAN越多传输的总带宽就越高,MIPI的配置在原厂已经配置好了,一般情况是无需更改直接使用。RockChip把MIPI 的DSI接口写在dw-mipi-dsi.c,但是CSI接口却没有独立出来写,而是把它写在drivers/phy/rockchip/phy-rockchip-mipi-rx.c 物理接口上。

drivers/gpu/drm/rockchip/dw-mipi-dsi.c:1999:    { .compatible = "rockchip,rk3399-mipi-dsi", .data = &rk3399_socdata, },
drivers/phy/rockchip/phy-rockchip-mipi-rx.c:1338:               .compatible = "rockchip,rk3399-mipi-dphy",

DTS的配置如下:

mipi_dphy_rx0: mipi-dphy-rx0 {
    compatible = "rockchip,rk3399-mipi-dphy";
    clocks = <&cru SCLK_MIPIDPHY_REF>,
        <&cru SCLK_DPHY_RX0_CFG>,
        <&cru PCLK_VIO_GRF>;
    clock-names = "dphy-ref", "dphy-cfg", "grf";
    power-domains = <&power RK3399_PD_VIO>;
    status = "disabled";
};

&mipi_dphy_rx0 {
	status = "okay";
	ports {
		#address-cells = <1>;
		#size-cells = <0>;

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

			mipi_in_ucam0: endpoint@1 {
				reg = <1>;
				remote-endpoint = <&ucam_out0>;
				data-lanes = <1 2>;
			};
		};

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

			dphy_rx0_out: endpoint@0 {
				reg = <0>;
				remote-endpoint = <&isp0_mipi_in>;
			};
		};
	};
};

调试方法

在终端切换到root用户,使用一下命令可在屏幕上实时显示摄像头所拍摄的图像:

source /usr/local/bin/dual-camera-rkisp.sh

FAQs

1.无法打开摄像头,首先确定sensor I2C是否通信。若不通则可检查mclk以及供电是否正常(Power/PowerDown/Reset/Mclk/I2cBus)分别排查 2.支持列表ː 13Mː OV13850/IMX214-0AQH5 8Mː OV8825/OV8820/OV8858-Z(R1A)/OV8858-R2A 5Mː OV5648/OV5640 2Mː OV2680 详细资料可查询SDK/RKDocs

参考资料

  • 《MIPI Alliance Specification for Camera Serial Interface 2》

  • arch/arm64/boot/dts/rockchip/rk3399-roc-pc.dts