T527 MIPI CSI 调试

1、环境介绍

硬件:t527板卡

软件:原厂t527-tina5.0-aiot-v1.4 sdk(buildroot,Linux 5.15)

2、T527 Video Input 资源

T527 Video input 主要由接口协议部分(MIPI,parser)、图像处理单元(ISP/VIPP)以及数据存储

部分(bk)组成。

MIPI 与 parser(csi)模块主要实现视频图像数据的接收和解析。

ISP 模块实现 sensor raw data 数据的处理,包括 lens 补偿、去坏点、gain、gamma、de‑mosaic、de‑noise、color matrix 等以及一些 3A 的统计。

VIPP(scaler)模块能对图像进行缩小或添加水印的处理。VIPP 支持 bayer raw data 经过 ISP 处理后再缩小,也支持对一般的 YUV 格式的 sensor 图像直接缩小。

bk 模块通过直接内存访问技术(DMA)将采集到的图像数据搬运到内存中。

2.1、ISP(Image Signal Processor)

  • 数量:1 个(支持 TDM,逻辑扩展为 4 路虚 ISP)
  • 最大输入分辨率:3264×4224(约14MP)
  • 最大处理性能:8MP@30fps,RAW12,2F-WDR
  • 工作模式:在线(Online)/ 离线(Offline)
  • 图像算法:
    • WDR 合成(2F-WDR)、DRC、Gamma、DPC 坏点校正
    • 2D/3D 降噪、锐化、去伪色、插值、色彩增强
    • 3A 自动控制:AE 自动曝光 / AWB 自动白平衡 / AF 自动对焦
    • 统计功能:直方图、抗闪烁检测

2.2、VIPP(Video Input Pre Processor)

  • 数量:4 路(VIPP0~3)
  • 功能:裁剪、缩放(1/1~1/16)、镜像/翻转
  • 输出格式:YUV422 / YUV420
  • 每路支持最多 16 条 ORL 叠加区域

2.3、视频输入接口

2.3.1、MIPI CSI-2

最大支持 4 个 PHY(PHY A/B/C/D),支持 4Lane+4Lane、4Lane+2Lane+2Lane、2Lane+2Lane+2Lane+2Lane。

2.3.2、并口 CSI(DVP)

1 路(与 parser3 复用),支持 8/10/12/16-bit,BT.656/601/1120。

3、原理图查看

如下为 T527板卡 的 MIPI-CSI 接口原理图,使用 4Lane+2Lane+2Lane 的配置,支持3个摄像头:

4、内核配置

− Device Drivers 
    > Multimedia support[*] 
        > Video4Linux options 
            > V4L2 sub‑device userspace API[*]
            
− Allwinner BSP 
    > Device Drivers 
        > VIN (camera) Drivers 
        > sunxi video input (camera csi/mipi isp vipp)driver[M]
        
− Allwinner BSP 
    > Device Drivers 
        > VIN (camera) Drivers 
            > v4l2 new driver for SUNXI[M]

5、设备树节点介绍

请直接参考官方手册《AW_AIOT_Linux_Camera_开发指南.pdf》,以下主要对链路部分上的关键节点做个总结:

/* ISP时分复用功能(TDM),若需使用ISP时分复用功能,则需开启TDM离线模式 */
tdm0:tdm@5908000 {
    work_mode = <0>;	/* 0:在线模式,1:离线模式, 根据使用需求进行配置 */
};

/* 由于只有一个ISP实体,isp00(isp0)为普通在线模式下的唯一实体ISP,
* isp01/02/03为ISP时分复用(离线模式下)的ISP虚体,
* 而isp10(isp4)和isp20(isp5)则为纯虚拟出来的ISP虚体,不具备ISP功能,通常用于不使用ISP功能时做路由,如YUV sensor。
*/
isp00:isp@5900000 {
    work_mode = <0>;
};

/* scaler00/10/20/30为真实scaler(vipp) ,其他均为虚拟出来的vipp,与所用isp相对应 */
scaler00:scaler@5910000 {
    work_mode = <0>;
};

/* sensor节点 */
sensor0:sensor@5812000 {
}

/* vinc节点说明:
* 1. vinc@X对应/dev/videoX节点
* 2. vinc00/10/20/30/40/50(video0/4/8/12/16/17)对应真实的bk0/1/2/3/4/5,故在线模式下最多可支持6路视频输出
* 3. vinc01/02/03/11/12/13/21/22/23/31/32/33只在ISP时分复用(离线模式)的场景下才会使用。
*/
vinc00:vinc@5830000 {
}

5.1、Pipeline 典型场景

下面例举两种典型的 Pipeline 场景,一种为常见的在线模式 pipeline,另一种为开启 ISP 时分复用功能(离线模式)下的 pipeline。

5.1.1、在线模式

上图为一种在线模式下单路输入,4路输出的典型 pipeline 场景,下面简单描述一下数据从 sensor 到各 video 节点的过程:

  • mipi sensor 数据首先经过 MIPI CSI 协议传输到 SOC 端的 mipi0 中,主要完成数据接收和 MIPI

协议解包等工作;

  • mipiX 一般与 parserX 相连,数据经 parser 后进一步传输给 ISP;
  • 然后经过 isp00(即 isp0,为真实存在的 ISP 实体)的处理后,分 4 路输入到 vipp00/10/20/30 中,必要时进行图像缩小;
  • vipp、dma、video 为强关联(绑定), 数据经相应的 vipp 处理后,由 dma 将图像数据搬运到内存中;
  • 应用层通过 /dev/video 节点来读取图像数据,每个 video 节点的图像数据完全相同,应用层可用于显示、编码等。

5.1.2、离线模式

详细解释参考《AW_AIOT_Linux_Camera_开发指南.pdf》。

5.2、设备树节点配置小结

1、需要多个 sensor 同时出图就配置为离线模式。反之,配置为在线模式。

2、t527有1个isp实体、4个vipp实体、5个真实的bk后端处理资源(dma)。在线模式只能用这些真实存在的资源。

3、在线模式只可使用的节点有:

tdm0、isp00、

scaler00、scaler10、scaler20、scaler30、

vinc00、vinc10、vinc20、vinc30、vinc40、vinc50 。

# 举例
# 1个sensor对应一个video节点,scalerXX 和 vincXX 一一对应
sensor0 -> isp00 -> scaler00 -> vinc00(video0)
sensor1 -> isp00 -> scaler10 -> vinc10(video4)
sensor2 -> isp00 -> scaler20 -> vinc20(video8)
sensor3 -> isp00 -> scaler30 -> vinc30(video12)

# 1个sensor对应多个video节点,scalerXX 和 vincXX 一一对应
sensor0 -> isp00 -> scaler00 -> vinc00(video0)
                 -> scaler10 -> vinc10(video4)
                 -> scaler20 -> vinc20(video8)
                 -> scaler30 -> vinc30(video12)

vinc40、vinc50节点只支持在线模式,出的图为sensor原分辨率的图或者经过裁剪过的图,无法对图片进行缩放。

4、离线模式中,需要配置工作模式的节点有:

tdm0、isp00、scaler00、scaler10、scaler20、scaler30、vinc00、vinc10、vinc20、vinc30 。

对于isp00而言,isp00是实体,与isp01、isp02、isp03 时分复用。

对于scaler00而言,scaler00是实体,与scaler01、scaler02、scaler03 时分复用。

对于scaler10而言,scaler10是实体,与scaler11、scaler12、scaler13 时分复用。

对于scaler30而言,scaler30是实体,与scaler31、scaler32、scaler33 时分复用。

对于scaler40而言,scaler40是实体,与scaler41、scaler42、scaler43 时分复用。

对于vinc00而言,vinc00是实体,与vinc01、vinc02、vinc03 时分复用。

对于vinc10而言,vinc10是实体,与vinc11、vinc22、vinc33 时分复用。

对于vinc20而言,vinc20是实体,与vinc21、vinc22、vinc23 时分复用。

对于vinc30而言,vinc30是实体,与vinc31、vinc32、vinc33 时分复用。

# 举例
# 1个sensor对应一个video节点,scalerXX 和 vincXX 一一对应
sensor0 -> isp00 -> scaler00 -> vinc00(video0)
sensor1 -> isp01 -> scaler01 -> vinc01(video1)
sensor2 -> isp02 -> scaler02 -> vinc02(video2)
sensor3 -> isp03 -> scaler03 -> vinc03(video3)

# 1个sensor对应多个video节点,scalerXX 和 vincXX 一一对应
sensor0 -> isp00 -> scaler00 -> vinc00(video0)
                 -> scaler10 -> vinc10(video4)
                 -> scaler20 -> vinc20(video8)
                 -> scaler30 -> vinc30(video12)

sensor1 -> isp01 -> scaler01 -> vinc01(video1)
                 -> scaler11 -> vinc11(video5)
                 -> scaler21 -> vinc21(video9)
                 -> scaler31 -> vinc31(video13)

6、在线模式测试

6.1、设备树配置

以下将使用3个摄像头进行测试。portA接ov5648,portB和portC接ov8858。链路如下:

sensor0(ov5648) -> isp00 -> scaler00 -> vinc00(video0)
sensor1(ov8858) -> isp00 -> scaler10 -> vinc10(video4)
sensor2(ov8858) -> isp00 -> scaler20 -> vinc20(video8)

如下为t527源设备树,主要留意mipi节点的引脚配置,需要配置为4lane+2lane+2lane:

/* sun55iw3p1.dtsi */

vind0: vind@5800800 {
    
    ...
    
    mipi0: mipi@5810100 {
        compatible = "allwinner,sunxi-mipi";
        reg = <0x0 0x05810100 0x0 0x100>,
            <0x0 0x05811000 0x0 0x400>;
        interrupts = <GIC_SPI 137 IRQ_TYPE_LEVEL_HIGH>;
        pinctrl-names = "mipi0-default","mipi0-sleep",
                "mipi1-4lane-default","mipi1-4lane-sleep";
        pinctrl-0 = <&mipia_pins_a>;
        pinctrl-1 = <&mipia_pins_b>;
        pinctrl-2 = <&mipib_4lane_pins_a>;
        pinctrl-3 = <&mipib_4lane_pins_b>;
        device_id = <0>;
        status = "okay";
    };
    mipi1: mipi@5810200 {
        compatible = "allwinner,sunxi-mipi";
        reg = <0x0 0x05810200 0x0 0x100>,
            <0x0 0x05811400 0x0 0x400>;
        pinctrl-names = "mipi1-default","mipi1-sleep";
        pinctrl-0 = <&mipib_pins_a>;
        pinctrl-1 = <&mipib_pins_b>;
        device_id = <1>;
        status = "okay";
    };
    mipi2: mipi@5810300 {
        compatible = "allwinner,sunxi-mipi";
        reg = <0x0 0x05810300 0x0 0x100>,
            <0x0 0x05811800 0x0 0x400>;
        pinctrl-names = "mipi2-default","mipi2-sleep";
        pinctrl-0 = <&mipic_pins_a>;
        pinctrl-1 = <&mipic_pins_b>;
        device_id = <2>;
        status = "okay";
    };
    mipi3: mipi@5810400 {
        compatible = "allwinner,sunxi-mipi";
        reg = <0x0 0x05810400 0x0 0x100>,
            <0x0 0x05811C00 0x0 0x400>;
        pinctrl-names = "mipi3-default","mipi3-sleep";
        pinctrl-0 = <&mipid_pins_a>;
        pinctrl-1 = <&mipid_pins_b>;
        device_id = <3>;
        status = "okay";
    };

    ...
        
}

如下为板级设备树 board.dts(只展示vind节点):

/* board.dts */

&vind0 {
	csi_top = <360000000>;
	csi_isp = <300000000>;
	vind_mclkpin-supply = <&reg_dcdc4>; /* vcc-pe */	// 根据原理图实际情况填写
	vind_mclkpin_vol = <3300000>;						// 根据原理图实际情况填写
	vind_mcsipin-supply = <&reg_dcdc4>; /* vcc-pk */	// 根据原理图实际情况填写
	vind_mcsipin_vol = <3300000>;						// 根据原理图实际情况填写
	vind_mipipin-supply = <&reg_bldo3>; /* vcc-mcsi */	// 根据原理图实际情况填写
	vind_mipipin_vol = <1800000>;						// 根据原理图实际情况填写
	status = "okay";

	tdm0:tdm@5908000 {
		work_mode = <0>;		// 工作模式,0=在线模式,1=离线模式
	};

	isp00:isp@5900000 {
		work_mode = <0>;		// 工作模式,0=在线模式,1=离线模式
	};

	isp01:isp@58ffffc {
		status = "disabled";
	};

	isp02:isp@58ffff8 {
		status = "disabled";
	};

	isp03:isp@58ffff4 {
		status = "disabled";
	};

	isp10:isp@4 {
		status = "disabled";
	};

	isp20:isp@5 {
		status = "disabled";
	};

	scaler00:scaler@5910000 {
		work_mode = <0>;		// 工作模式,0=在线模式,1=离线模式
	};

	scaler01:scaler@590fffc {
		status = "disabled";
	};

	scaler02:scaler@590fff8 {
		status = "disabled";
	};

	scaler03:scaler@590fff4 {
		status = "disabled";
	};

	scaler10:scaler@5910400 {
		work_mode = <0>;		// 工作模式,0=在线模式,1=离线模式
	};

	scaler11:scaler@59103fc {
		status = "disabled";
	};

	scaler12:scaler@59103f8 {
		status = "disabled";
	};

	scaler13:scaler@59103f4 {
		status = "disabled";
	};

	scaler20:scaler@5910800 {
		work_mode = <0>;		// 工作模式,0=在线模式,1=离线模式
	};

	scaler21:scaler@59107fc {
		status = "disabled";
	};

	scaler22:scaler@59107f8 {
		status = "disabled";
	};

	scaler23:scaler@59107f4 {
		status = "disabled";
	};

	scaler30:scaler@5910c00 {
		work_mode = <0>;		// 工作模式,0=在线模式,1=离线模式
	};

	scaler31:scaler@5910bfc {
		status = "disabled";
	};

	scaler32:scaler@5910bf8 {
		status = "disabled";
	};

	scaler33:scaler@5910bf4 {
		status = "disabled";
	};

	sensor0:sensor@5812000 {
		device_type = "sensor0";
 		sensor0_mname = "ov5648_mipi";
		sensor0_twi_addr = <0x6c>; 		// sensor设备id
		sensor0_twi_cci_id = <3>;		// sensor的twi地址
		sensor0_pos = "rear";			// sensor的位置,前置还是后置,主要用在平板上,其他场景一般无需配置该项
		sensor0_isp_used = <1>;			// 该sensor是否需要使用ISP
		sensor0_fmt = <1>;				// sensor输出图像格式类型:0‑yuv,1‑bayer raw rgb
		sensor0_stby_mode = <0>;		// 0‑系统standby时sensor模组不掉电,1‑系统standby时sensor模组掉电
		sensor0_vflip = <0>;			// sensor画面垂直翻转使能开关
		sensor0_hflip = <0>;			// sensor画面水平翻转使能开关
		sensor0_reset = <&pio PE 6 GPIO_ACTIVE_HIGH>;	// 模组RESET复位GPIO配置,根据实际情况进行配置
		sensor0_pwdn = <&pio PM 0 GPIO_ACTIVE_HIGH>;	// 模组PWDN GPIO配置,根据实际情况进行配置
		device_id = <0>;
		status = "okay";
	};

	sensor1:sensor@5812010 {
		device_type = "sensor1";
		sensor1_mname = "ov8858_mipi_2lane";
		sensor1_twi_addr = <0x6c>; 
		sensor1_twi_cci_id = <1>;
		sensor1_pos = "front";
		sensor1_isp_used = <1>;
		sensor1_fmt = <1>;
		sensor1_stby_mode = <0>;
		sensor1_vflip = <0>;
		sensor1_hflip = <0>;
		sensor1_reset = <&pio PE 9 GPIO_ACTIVE_HIGH>;
		sensor1_pwdn = <&pio PE 10 GPIO_ACTIVE_HIGH>;
		device_id = <1>;
		status = "okay";
	};

	sensor2: sensor@5812020 {
		device_type = "sensor2";
		sensor2_mname = "ov8858_mipi_2lane_2";
		sensor2_twi_addr = <0x6c>; 
		sensor2_twi_cci_id = <0>;
		sensor2_pos = "rear";
		sensor2_isp_used = <1>;
		sensor2_fmt = <1>;
		sensor2_stby_mode = <0>;
		sensor2_vflip = <0>;
		sensor2_hflip = <0>;
		sensor2_reset = <&pio PG 14 GPIO_ACTIVE_HIGH>;
		sensor2_pwdn = <&pio PG 13 GPIO_ACTIVE_HIGH>;
		device_id = <2>;
		status= "okay";
	};

// camera1 : &sensor0 -> &mipi0 -> &csi0(parser0) -> &isp00 -> &scaler00(vipp00) -> (dma00) -> &vinc00(video0)
	vinc00:vinc@5830000 {
		vinc0_csi_sel = <0>;			// parser通道sel(填写对应节点的device_id)
		vinc0_mipi_sel = <0>;			// mipi通道sel
		vinc0_isp_sel = <0>;			// isp通道sel,在线模式只能配为0,离线模式可配置为0~3
		vinc0_isp_tx_ch = <0>;			// 配为0即可
		vinc0_tdm_rx_sel = <0>;			// 离线模式需配置为0~3,需要与isp_sel属性相同;在线模式可不配置
		vinc0_rear_sensor_sel = <0>;	// 后摄使用的sensor_sel
		vinc0_front_sensor_sel = <0>;	// 前摄使用的senosr_sel
		vinc0_sensor_list = <0>;		// 是否使用sensor_list功能,0:not_use 1:use
		device_id = <0>;				// video节点sel,不可修改
		work_mode = <0x0>;				// 工作模式,0=在线模式,1=离线模式
		status = "okay";
	};

	vinc01:vinc@582fffc {
		vinc1_csi_sel = <1>;
		vinc1_mipi_sel = <2>;
		vinc1_isp_sel = <1>;
		vinc1_isp_tx_ch = <0>;
		vinc1_tdm_rx_sel = <1>;
		vinc1_rear_sensor_sel = <1>;
		vinc1_front_sensor_sel = <1>;
		vinc1_sensor_list = <0>;
		device_id = <1>;
		status = "disabled";
	};

	vinc02:vinc@582fff8 {
		vinc2_csi_sel = <2>;
		vinc2_mipi_sel = <0xff>;
		vinc2_isp_sel = <2>;
		vinc2_isp_tx_ch = <2>;
		vinc2_tdm_rx_sel = <2>;
		vinc2_rear_sensor_sel = <0>;
		vinc2_front_sensor_sel = <0>;
		vinc2_sensor_list = <0>;
		device_id = <2>;
		status = "disabled";
	};

	vinc03:vinc@582fff4 {
		vinc3_csi_sel = <0>;
		vinc3_mipi_sel = <0xff>;
		vinc3_isp_sel = <0>;
		vinc3_isp_tx_ch = <0>;
		vinc3_tdm_rx_sel = <0>;
		vinc3_rear_sensor_sel = <1>;
		vinc3_front_sensor_sel = <1>;
		vinc3_sensor_list = <0>;
		device_id = <3>;
		status = "disabled";
	};

// camera2 : &sensor1 -> &mipi2 -> &csi2(parser2) -> &isp00 -> &scaler10(vipp10) -> (dma10) -> &vinc10(video4)
	vinc10:vinc@5831000 {
		vinc4_csi_sel = <2>;
		vinc4_mipi_sel = <2>;
		vinc4_isp_sel = <0>;
		vinc4_isp_tx_ch = <0>;
		vinc4_tdm_rx_sel = <0>;
		vinc4_rear_sensor_sel = <1>;
		vinc4_front_sensor_sel = <1>;
		vinc4_sensor_list = <0>;
		device_id = <4>;
		work_mode = <0x0>;
		status = "okay";
	};

	vinc11:vinc@5830ffc {
		vinc5_csi_sel = <2>;
		vinc5_mipi_sel = <0xff>;
		vinc5_isp_sel = <1>;
		vinc5_isp_tx_ch = <1>;
		vinc5_tdm_rx_sel = <1>;
		vinc5_rear_sensor_sel = <0>;
		vinc5_front_sensor_sel = <0>;
		vinc5_sensor_list = <0>;
		device_id = <5>;
		status = "disabled";
	};

	vinc12:vinc@5830ff8 {
		vinc6_csi_sel = <2>;
		vinc6_mipi_sel = <0xff>;
		vinc6_isp_sel = <0>;
		vinc6_isp_tx_ch = <0>;
		vinc6_tdm_rx_sel = <0>;
		vinc6_rear_sensor_sel = <0>;
		vinc6_front_sensor_sel = <0>;
		vinc6_sensor_list = <0>;
		device_id = <6>;
		status = "disabled";
	};

	vinc13:vinc@5830ff4 {
		vinc7_csi_sel = <2>;
		vinc7_mipi_sel = <0xff>;
		vinc7_isp_sel = <0>;
		vinc7_isp_tx_ch = <0>;
		vinc7_tdm_rx_sel = <0>;
		vinc7_rear_sensor_sel = <0>;
		vinc7_front_sensor_sel = <0>;
		vinc7_sensor_list = <0>;
		device_id = <7>;
		status = "disabled";
	};

// camera3 : &sensor2 -> &mipi3 -> &csi3(parser3) -> &isp00 -> &scaler20(vipp20) -> (dma20) -> &vinc20(video8)
	vinc20:vinc@5832000 {
		vinc8_csi_sel = <3>;
		vinc8_mipi_sel = <3>;
		vinc8_isp_sel = <0>;
		vinc8_isp_tx_ch = <0>;
		vinc8_tdm_rx_sel = <0>;
		vinc8_rear_sensor_sel = <2>;
		vinc8_front_sensor_sel = <2>;
		vinc8_sensor_list = <0>;
		device_id = <8>;
		work_mode = <0x0>;
		status = "okay";
	};

	vinc21:vinc@5831ffc {
		vinc9_csi_sel = <2>;
		vinc9_mipi_sel = <0xff>;
		vinc9_isp_sel = <0>;
		vinc9_isp_tx_ch = <0>;
		vinc9_tdm_rx_sel = <0>;
		vinc9_rear_sensor_sel = <0>;
		vinc9_front_sensor_sel = <0>;
		vinc9_sensor_list = <0>;
		device_id = <9>;
		status = "disabled";
	};

	vinc22:vinc@5831ff8 {
		vinc10_csi_sel = <2>;
		vinc10_mipi_sel = <0xff>;
		vinc10_isp_sel = <0>;
		vinc10_isp_tx_ch = <0>;
		vinc10_tdm_rx_sel = <0>;
		vinc10_rear_sensor_sel = <0>;
		vinc10_front_sensor_sel = <0>;
		vinc10_sensor_list = <0>;
		device_id = <10>;
		status = "disabled";
	};

	vinc23:vinc@5831ff4 {
		vinc11_csi_sel = <2>;
		vinc11_mipi_sel = <0xff>;
		vinc11_isp_sel = <0>;
		vinc11_isp_tx_ch = <0>;
		vinc11_tdm_rx_sel = <0>;
		vinc11_rear_sensor_sel = <0>;
		vinc11_front_sensor_sel = <0>;
		vinc11_sensor_list = <0>;
		device_id = <11>;
		status = "disabled";
	};

	vinc30:vinc@5833000 {
		vinc12_csi_sel = <3>;
		vinc12_mipi_sel = <3>;
		vinc12_isp_sel = <0>;
		vinc12_isp_tx_ch = <0>;
		vinc12_tdm_rx_sel = <0>;
		vinc12_rear_sensor_sel = <3>;
		vinc12_front_sensor_sel = <3>;
		vinc12_sensor_list = <0>;
		device_id = <12>;
		work_mode = <0x0>;
		status = "disabled";
	};

	vinc31:vinc@5832ffc {
		vinc13_csi_sel = <2>;
		vinc13_mipi_sel = <0xff>;
		vinc13_isp_sel = <0>;
		vinc13_isp_tx_ch = <0>;
		vinc13_tdm_rx_sel = <0>;
		vinc13_rear_sensor_sel = <0>;
		vinc13_front_sensor_sel = <0>;
		vinc13_sensor_list = <0>;
		device_id = <13>;
		status = "disabled";
	};

	vinc32:vinc@5832ff8 {
		vinc14_csi_sel = <2>;
		vinc14_mipi_sel = <0xff>;
		vinc14_isp_sel = <0>;
		vinc14_isp_tx_ch = <0>;
		vinc14_tdm_rx_sel = <0>;
		vinc14_rear_sensor_sel = <0>;
		vinc14_front_sensor_sel = <0>;
		vinc14_sensor_list = <0>;
		device_id = <14>;
		status = "disabled";
	};

	vinc33:vinc@5832ff4 {
		vinc15_csi_sel = <2>;
		vinc15_mipi_sel = <0xff>;
		vinc15_isp_sel = <0>;
		vinc15_isp_tx_ch = <0>;
		vinc15_tdm_rx_sel = <0>;
		vinc15_rear_sensor_sel = <0>;
		vinc15_front_sensor_sel = <0>;
		vinc15_sensor_list = <0>;
		device_id = <15>;
		status = "disabled";
	};

	vinc40:vinc@5834000 {
		vinc16_csi_sel = <2>;
		vinc16_mipi_sel = <0xff>;
		vinc16_isp_sel = <0>;
		vinc16_isp_tx_ch = <0>;
		vinc16_tdm_rx_sel = <0>;
		vinc16_rear_sensor_sel = <0>;
		vinc16_front_sensor_sel = <0>;
		vinc16_sensor_list = <0>;
		device_id = <16>;
		status = "disabled";
	};

	vinc50:vinc@5835000 {
		vinc17_csi_sel = <2>;
		vinc17_mipi_sel = <0xff>;
		vinc17_isp_sel = <0>;
		vinc17_isp_tx_ch = <0>;
		vinc17_tdm_rx_sel = <0>;
		vinc17_rear_sensor_sel = <0>;
		vinc17_front_sensor_sel = <0>;
		vinc17_sensor_list = <0>;
		device_id = <17>;
		status = "disabled";
	};
};

6.2、抓图测试

安装vin驱动:

insmod /lib/modules/5.15.147/videobuf2-dma-contig.ko
insmod /lib/modules/5.15.147/vin_io.ko
insmod /lib/modules/5.15.147/vin_v4l2.ko

安装vin驱动过程中,sensor 驱动会自动加载:

lsmod

查看 video 节点:

cam1(ov5648)抓图测试:

# csi_test_usrptr [video_X] [sub_dev] [] [] [保存位置] [颜色格式] [抓取帧数] [帧率]
# [videoX] [sub_dev]:X与/dev/videoX对应,sub_dev一般为0
# [] []:图片输出大小,如果不和摄像头分辨率一致,则会缩放输出。
# [颜色格式]:如下,如果没有输出可以换一种颜色格式再试
# 0 raw8
# 1 yuv420m
# 2 yuv420
# 3 nv12m
# 4 nv21
# 5 RAW10
# 6 RAW12
# 7 LBC2.5X
# [抓取帧数]:小于20保存为单帧图片,大于等于20保存为一个视频文件
# [帧率]:抓图的帧率
csi_test_usrptr 0 0 800 720 / 2 20 15

cam2(ov8858)和cam3(ov8858)抓图也是一样的:

# cam2
csi_test_usrptr 4 0 800 720 / 2 20 15
# cam3
csi_test_usrptr 8 0 800 720 / 2 20 15

其它核心调试接口:

cat /sys/kernel/debug/mpp/vi
cat /sys/kernel/debug/mpp/mipi

6.3、其它问题记录

略。

7、离线模式测试

7.1、设备树配置

以下将使用3个摄像头进行测试。portA接ov5648,portB和portC接ov8858。链路如下:

sensor0 -> isp00 -> scaler00 -> vinc00(video0)
sensor1 -> isp01 -> scaler01 -> vinc01(video1)
sensor2 -> isp02 -> scaler02 -> vinc02(video2)

如下为板级设备树 board.dts(只展示vind节点):

/* board.dts */

&vind0 {
	csi_top = <360000000>;
	csi_isp = <300000000>;
	vind_mclkpin-supply = <&reg_dcdc4>; /* vcc-pe */
	vind_mclkpin_vol = <3300000>;
	vind_mcsipin-supply = <&reg_dcdc4>; /* vcc-pk */
	vind_mcsipin_vol = <3300000>;
	vind_mipipin-supply = <&reg_bldo3>; /* vcc-mcsi */
	vind_mipipin_vol = <1800000>;
	status = "okay";

	tdm0:tdm@5908000 {
		work_mode = <1>;
	};

	isp00:isp@5900000 {
		work_mode = <1>;
	};

	isp01:isp@58ffffc {
		status = "okay";
	};

	isp02:isp@58ffff8 {
		status = "okay";
	};

	isp03:isp@58ffff4 {
		status = "disabled";
	};

	isp10:isp@4 {
		status = "disabled";
	};

	isp20:isp@5 {
		status = "disabled";
	};

	scaler00:scaler@5910000 {
		work_mode = <1>;
	};

	scaler01:scaler@590fffc {
		status = "okay";
	};

	scaler02:scaler@590fff8 {
		status = "okay";
	};

	scaler03:scaler@590fff4 {
		status = "disabled";
	};

	scaler10:scaler@5910400 {
		work_mode = <0>;
		status = "disabled";
	};

	scaler11:scaler@59103fc {
		status = "disabled";
	};

	scaler12:scaler@59103f8 {
		status = "disabled";
	};

	scaler13:scaler@59103f4 {
		status = "disabled";
	};

	scaler20:scaler@5910800 {
		work_mode = <0>;
		status = "disabled";
	};

	scaler21:scaler@59107fc {
		status = "disabled";
	};

	scaler22:scaler@59107f8 {
		status = "disabled";
	};

	scaler23:scaler@59107f4 {
		status = "disabled";
	};

	scaler30:scaler@5910c00 {
		work_mode = <0>;
		status = "disabled";
	};

	scaler31:scaler@5910bfc {
		status = "disabled";
	};

	scaler32:scaler@5910bf8 {
		status = "disabled";
	};

	scaler33:scaler@5910bf4 {
		status = "disabled";
	};

	sensor0:sensor@5812000 {
		device_type = "sensor0";
 		sensor0_mname = "ov5648_mipi";
		sensor0_twi_addr = <0x6c>; 
		sensor0_twi_cci_id = <3>;
		sensor0_pos = "rear";
		sensor0_isp_used = <1>;
		sensor0_fmt = <1>;
		sensor0_stby_mode = <0>;
		sensor0_vflip = <0>;
		sensor0_hflip = <0>;
		sensor0_reset = <&pio PE 6 GPIO_ACTIVE_HIGH>;
		sensor0_pwdn = <&pio PM 0 GPIO_ACTIVE_HIGH>;
		device_id = <0>;
		status = "okay";
	};

	sensor1:sensor@5812010 {
		device_type = "sensor1";
		sensor1_mname = "ov8858_mipi_2lane";
		sensor1_twi_addr = <0x6c>; 
		sensor1_twi_cci_id = <1>;
		sensor1_pos = "front";
		sensor1_isp_used = <1>;
		sensor1_fmt = <1>;
		sensor1_stby_mode = <0>;
		sensor1_vflip = <0>;
		sensor1_hflip = <0>;
		sensor1_reset = <&pio PE 9 GPIO_ACTIVE_HIGH>;
		sensor1_pwdn = <&pio PE 10 GPIO_ACTIVE_HIGH>;
		device_id = <1>;
		status = "okay";
	};

	sensor2: sensor@5812020 {
		device_type = "sensor2";
		sensor2_mname = "ov8858_mipi_2lane_2";
		sensor2_twi_addr = <0x6c>; 
		sensor2_twi_cci_id = <0>;
		sensor2_pos = "rear";
		sensor2_isp_used = <1>;
		sensor2_fmt = <1>;
		sensor2_stby_mode = <0>;
		sensor2_vflip = <0>;
		sensor2_hflip = <0>;
		sensor2_reset = <&pio PG 14 GPIO_ACTIVE_HIGH>;
		sensor2_pwdn = <&pio PG 13 GPIO_ACTIVE_HIGH>;
		device_id = <2>;
		status= "okay";
	};

/*
[Online mode]
camera1: &sensor0 -> &mipi0 -> &csi0(parser0) -> &isp00 -> &scaler00(vipp00) -> (dma00) -> &vinc00(video0)
camera3: &sensor1 -> &mipi2 -> &csi2(parser2) -> &isp00 -> &scaler10(vipp10) -> (dma10) -> &vinc10(video4)
camera4: &sensor2 -> &mipi3 -> &csi3(parser3) -> &isp00 -> &scaler20(vipp20) -> (dma20) -> &vinc20(video8)

[Offline mode]
camera1: &sensor0 -> &mipi0 -> &csi0(parser0) -> &isp00 -> &scaler00(vipp00) -> (dma00) -> &vinc00(video0)
camera3: &sensor1 -> &mipi2 -> &csi2(parser2) -> &isp01 -> &scaler01(vipp01) -> (dma01) -> &vinc01(video1)
camera4: &sensor1 -> &mipi3 -> &csi3(parser3) -> &isp02 -> &scaler02(vipp02) -> (dma02) -> &vinc02(video3)
*/
	vinc00:vinc@5830000 {
		vinc0_csi_sel = <0>;
		vinc0_mipi_sel = <0>;
		vinc0_isp_sel = <0>;
		vinc0_isp_tx_ch = <0>;
		vinc0_tdm_rx_sel = <0>;
		vinc0_rear_sensor_sel = <0>;
		vinc0_front_sensor_sel = <0>;
		vinc0_sensor_list = <0>;
		device_id = <0>;
		work_mode = <0x1>;
		status = "okay";
	};

	vinc01:vinc@582fffc {
		vinc1_csi_sel = <2>;
		vinc1_mipi_sel = <2>;
		vinc1_isp_sel = <1>;
		vinc1_isp_tx_ch = <0>;
		vinc1_tdm_rx_sel = <1>;
		vinc1_rear_sensor_sel = <1>;
		vinc1_front_sensor_sel = <1>;
		vinc1_sensor_list = <0>;
		device_id = <1>;
		status = "okay";
	};

	vinc02:vinc@582fff8 {
		vinc2_csi_sel = <3>;
		vinc2_mipi_sel = <3>;
		vinc2_isp_sel = <2>;
		vinc2_isp_tx_ch = <0>;
		vinc2_tdm_rx_sel = <2>;
		vinc2_rear_sensor_sel = <2>;
		vinc2_front_sensor_sel = <2>;
		vinc2_sensor_list = <0>;
		device_id = <2>;
		status = "okay";
	};

	vinc03:vinc@582fff4 {
		vinc3_csi_sel = <0>;
		vinc3_mipi_sel = <0xff>;
		vinc3_isp_sel = <0>;
		vinc3_isp_tx_ch = <0>;
		vinc3_tdm_rx_sel = <0>;
		vinc3_rear_sensor_sel = <1>;
		vinc3_front_sensor_sel = <1>;
		vinc3_sensor_list = <0>;
		device_id = <3>;
		status = "disabled";
	};

	vinc10:vinc@5831000 {
		vinc4_csi_sel = <2>;
		vinc4_mipi_sel = <2>;
		vinc4_isp_sel = <0>;
		vinc4_isp_tx_ch = <0>;
		vinc4_tdm_rx_sel = <0>;
		vinc4_rear_sensor_sel = <1>;
		vinc4_front_sensor_sel = <1>;
		vinc4_sensor_list = <0>;
		device_id = <4>;
		work_mode = <0x0>;
		status = "disabled";
	};

	vinc11:vinc@5830ffc {
		vinc5_csi_sel = <2>;
		vinc5_mipi_sel = <0xff>;
		vinc5_isp_sel = <1>;
		vinc5_isp_tx_ch = <1>;
		vinc5_tdm_rx_sel = <1>;
		vinc5_rear_sensor_sel = <0>;
		vinc5_front_sensor_sel = <0>;
		vinc5_sensor_list = <0>;
		device_id = <5>;
		status = "disabled";
	};

	vinc12:vinc@5830ff8 {
		vinc6_csi_sel = <2>;
		vinc6_mipi_sel = <0xff>;
		vinc6_isp_sel = <0>;
		vinc6_isp_tx_ch = <0>;
		vinc6_tdm_rx_sel = <0>;
		vinc6_rear_sensor_sel = <0>;
		vinc6_front_sensor_sel = <0>;
		vinc6_sensor_list = <0>;
		device_id = <6>;
		status = "disabled";
	};

	vinc13:vinc@5830ff4 {
		vinc7_csi_sel = <2>;
		vinc7_mipi_sel = <0xff>;
		vinc7_isp_sel = <0>;
		vinc7_isp_tx_ch = <0>;
		vinc7_tdm_rx_sel = <0>;
		vinc7_rear_sensor_sel = <0>;
		vinc7_front_sensor_sel = <0>;
		vinc7_sensor_list = <0>;
		device_id = <7>;
		status = "disabled";
	};

	vinc20:vinc@5832000 {
		vinc8_csi_sel = <3>;
		vinc8_mipi_sel = <3>;
		vinc8_isp_sel = <0>;
		vinc8_isp_tx_ch = <0>;
		vinc8_tdm_rx_sel = <0>;
		vinc8_rear_sensor_sel = <2>;
		vinc8_front_sensor_sel = <2>;
		vinc8_sensor_list = <0>;
		device_id = <8>;
		work_mode = <0x0>;
		status = "disabled";
	};

	vinc21:vinc@5831ffc {
		vinc9_csi_sel = <2>;
		vinc9_mipi_sel = <0xff>;
		vinc9_isp_sel = <0>;
		vinc9_isp_tx_ch = <0>;
		vinc9_tdm_rx_sel = <0>;
		vinc9_rear_sensor_sel = <0>;
		vinc9_front_sensor_sel = <0>;
		vinc9_sensor_list = <0>;
		device_id = <9>;
		status = "disabled";
	};

	vinc22:vinc@5831ff8 {
		vinc10_csi_sel = <2>;
		vinc10_mipi_sel = <0xff>;
		vinc10_isp_sel = <0>;
		vinc10_isp_tx_ch = <0>;
		vinc10_tdm_rx_sel = <0>;
		vinc10_rear_sensor_sel = <0>;
		vinc10_front_sensor_sel = <0>;
		vinc10_sensor_list = <0>;
		device_id = <10>;
		status = "disabled";
	};

	vinc23:vinc@5831ff4 {
		vinc11_csi_sel = <2>;
		vinc11_mipi_sel = <0xff>;
		vinc11_isp_sel = <0>;
		vinc11_isp_tx_ch = <0>;
		vinc11_tdm_rx_sel = <0>;
		vinc11_rear_sensor_sel = <0>;
		vinc11_front_sensor_sel = <0>;
		vinc11_sensor_list = <0>;
		device_id = <11>;
		status = "disabled";
	};

	vinc30:vinc@5833000 {
		vinc12_csi_sel = <3>;
		vinc12_mipi_sel = <3>;
		vinc12_isp_sel = <0>;
		vinc12_isp_tx_ch = <0>;
		vinc12_tdm_rx_sel = <0>;
		vinc12_rear_sensor_sel = <3>;
		vinc12_front_sensor_sel = <3>;
		vinc12_sensor_list = <0>;
		device_id = <12>;
		work_mode = <0x0>;
		status = "disabled";
	};

	vinc31:vinc@5832ffc {
		vinc13_csi_sel = <2>;
		vinc13_mipi_sel = <0xff>;
		vinc13_isp_sel = <0>;
		vinc13_isp_tx_ch = <0>;
		vinc13_tdm_rx_sel = <0>;
		vinc13_rear_sensor_sel = <0>;
		vinc13_front_sensor_sel = <0>;
		vinc13_sensor_list = <0>;
		device_id = <13>;
		status = "disabled";
	};

	vinc32:vinc@5832ff8 {
		vinc14_csi_sel = <2>;
		vinc14_mipi_sel = <0xff>;
		vinc14_isp_sel = <0>;
		vinc14_isp_tx_ch = <0>;
		vinc14_tdm_rx_sel = <0>;
		vinc14_rear_sensor_sel = <0>;
		vinc14_front_sensor_sel = <0>;
		vinc14_sensor_list = <0>;
		device_id = <14>;
		status = "disabled";
	};

	vinc33:vinc@5832ff4 {
		vinc15_csi_sel = <2>;
		vinc15_mipi_sel = <0xff>;
		vinc15_isp_sel = <0>;
		vinc15_isp_tx_ch = <0>;
		vinc15_tdm_rx_sel = <0>;
		vinc15_rear_sensor_sel = <0>;
		vinc15_front_sensor_sel = <0>;
		vinc15_sensor_list = <0>;
		device_id = <15>;
		status = "disabled";
	};

	vinc40:vinc@5834000 {
		vinc16_csi_sel = <2>;
		vinc16_mipi_sel = <0xff>;
		vinc16_isp_sel = <0>;
		vinc16_isp_tx_ch = <0>;
		vinc16_tdm_rx_sel = <0>;
		vinc16_rear_sensor_sel = <0>;
		vinc16_front_sensor_sel = <0>;
		vinc16_sensor_list = <0>;
		device_id = <16>;
		status = "disabled";
	};

	vinc50:vinc@5835000 {
		vinc17_csi_sel = <2>;
		vinc17_mipi_sel = <0xff>;
		vinc17_isp_sel = <0>;
		vinc17_isp_tx_ch = <0>;
		vinc17_tdm_rx_sel = <0>;
		vinc17_rear_sensor_sel = <0>;
		vinc17_front_sensor_sel = <0>;
		vinc17_sensor_list = <0>;
		device_id = <17>;
		status = "disabled";
	};
};

7.2、抓图测试

# cam1
csi_test_usrptr 0 0 800 720 / 2 20 15
# cam2
csi_test_usrptr 1 0 800 720 / 2 20 15
# cam3
csi_test_usrptr 2 0 800 720 / 2 20 15

暂未调试成功,待补充。

7.3、其它问题记录

略。

8、参考文章

全志一号通:

【FAQ1603】 TWI 没有ack应答报错

【FAQ1795】 V85X-Camera出图异常-SOC寄存器自检

【FAQ3462】 527/523 settle time调整方法

【FAQ3033】 T527 FPGA 输入调试

【FAQ1429】 A523 dts中vind节点配置

【FAQ1817】 机器正常老化运行中不出图问题的分析思路

【FAQ3479】 CSI模块输出MCLK频偏导致sensor出图异常

【FAQ1988】 V85x sensor点亮报fifo overflow

【FAQ3501】 t527 Tina sdk 应用拷贝CSI摄像头数据耗时长

9、总结

本文主要记录t527下关于mipi csi的链路调试。目前还存在一个问题就是,再抓图过程中,画面会出现横线的情况。暂未解决。
嵌入式Linux学习交流群:424571391

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值