硬件框图

设备树配置
&i2c1 {
status = "okay";
pinctrl-0 = <&i2c1m3_pins>;
imx415: imx415@1a {
compatible = "sony,imx415";
reg = <0x1a>;
clocks = <&cru CLK_MIPI0_OUT2IO>;
clock-names = "xvclk";
power-gpios = <&gpio4 RK_PA6 GPIO_ACTIVE_HIGH>; /*1v2 2v8*/
reset-gpios = <&gpio4 RK_PA3 GPIO_ACTIVE_HIGH>;
pinctrl-names = "default";
pinctrl-0 = <&cam_clk0_pins>;
rockchip,camera-module-index = <0>;
rockchip,camera-module-facing = "back";
rockchip,camera-module-name = "default";
rockchip,camera-module-lens-name = "default";
rockchip,camera-hdr-mode = <0>; /*NO_HDR:0*/
port {
imx415_out: endpoint {
remote-endpoint = <&csi_dphy_input>;
data-lanes = <1 2 3 4>;
};
};
};
};
&csi2_dphy0 {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
csi_dphy_input: endpoint@2 {
reg = <2>;
remote-endpoint = <&imx415_out>;
data-lanes = <1 2 3 4>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
csidphy0_out: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi0_csi2_input>;
};
};
};
};
&mipi0_csi2 {
status = "okay";
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
#address-cells = <1>;
#size-cells = <0>;
mipi0_csi2_input: endpoint@1 {
reg = <1>;
remote-endpoint = <&csidphy0_out>;
};
};
port@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
mipi0_csi2_output: endpoint@0 {
reg = <0>;
remote-endpoint = <&cif_mipi_in0>;
};
};
};
};
&rkcif {
status = "okay";
};
&rkcif_mipi_lvds {
status = "okay";
port {
cif_mipi_in0: endpoint {
remote-endpoint = <&mipi0_csi2_output>;
};
};
};
&rkcif_mipi_lvds_sditf {
status = "okay";
port {
mipi_lvds_sditf: endpoint {
remote-endpoint = <&isp_vir0>;
};
};
};
&rkcif_mmu {
status = "okay";
};
&rkisp {
status = "okay";
};
&rkisp_mmu {
status = "okay";
};
&rkisp_vir0 {
status = "okay";
port {
#address-cells = <1>;
#size-cells = <0>;
isp_vir0: endpoint@0 {
reg = <0>;
remote-endpoint = <&mipi_lvds_sditf>;
};
};
};
&rkisp_vir0_sditf {
status = "okay";
};
&rkvpss {
status = "okay";
dvbm = <&rkdvbm>;
};
&rkvpss_mmu {
status = "okay";
};
&rkvpss_vir0 {
status = "okay";
};
驱动配置
1)rv1126bp kernel为6.1,drivers/media/i2c默认支持imx415的驱动
2)驱动中只需要配置上电与复位控制。
3)supported_modes配置列表是选择imx415输出的配置参数。
驱动测试
1)判断camera驱动是否加载成功
dmesg | grep Async
[ 0.682982] RKISP: Async subdev notifier completed
2)RKISP注册的video节点
grep "" /sys/class/video4linux/*/name
/sys/class/video4linux/v4l-subdev0/name:rkisp-vir0-sditf
/sys/class/video4linux/v4l-subdev1/name:rockchip-mipi-csi2
/sys/class/video4linux/v4l-subdev2/name:rockchip-csi2-dphy0
/sys/class/video4linux/v4l-subdev3/name:m00_b_imx415 1-001a
/sys/class/video4linux/v4l-subdev4/name:rkisp-isp-subdev
/sys/class/video4linux/v4l-subdev5/name:rkcif-mipi-lvds
/sys/class/video4linux/video0/name:stream_cif_mipi_id0
/sys/class/video4linux/video1/name:stream_cif_mipi_id1
/sys/class/video4linux/video10/name:rkcif_tools_id2
/sys/class/video4linux/video11/name:rkisp_mainpath
/sys/class/video4linux/video12/name:rkisp_selfpath
/sys/class/video4linux/video13/name:rkisp_iqtool
/sys/class/video4linux/video14/name:rkisp_rawrd0_m
/sys/class/video4linux/video15/name:rkisp_rawrd2_s
/sys/class/video4linux/video16/name:rkisp-statistics
/sys/class/video4linux/video17/name:rkisp-input-params
/sys/class/video4linux/video18/name:rkisp-pdaf
/sys/class/video4linux/video19/name:rkvpss-offline
/sys/class/video4linux/video2/name:stream_cif_mipi_id2
/sys/class/video4linux/video20/name:rkvpss_scale0
/sys/class/video4linux/video21/name:rkvpss_scale1
/sys/class/video4linux/video22/name:rkvpss_scale2
/sys/class/video4linux/video23/name:rkvpss_scale3
/sys/class/video4linux/video24/name:rkvpss_scale4
/sys/class/video4linux/video25/name:rkvpss_scale5
/sys/class/video4linux/video3/name:stream_cif_mipi_id3
/sys/class/video4linux/video4/name:rkcif_scale_ch0
/sys/class/video4linux/video5/name:rkcif_scale_ch1
/sys/class/video4linux/video6/name:rkcif_scale_ch2
/sys/class/video4linux/video7/name:rkcif_scale_ch3
/sys/class/video4linux/video8/name:rkcif_tools_id0
/sys/class/video4linux/video9/name:rkcif_tools_id1
3)查看/dev/video20支持的格式
v4l2-ctl --list-formats-ext --device /dev/video20
4)v4l2-ctl抓取nv12图
v4l2-ctl --verbose -d /dev/video20 \
--set-fmt-video=width=3840,height=2160,pixelformat='NV12' \
--stream-mmap=4 \
--set-selection=target=crop,flags=0,top=0,left=0,width=3840,height=2160 \
--stream-count=10 \
--stream-to=/tmp/out.yuv
测试用例
应用测试代码请参考external/samples/simple_test/simple_vi_get_frame_rkaiq.c进行编写。
测试时序
帧率测量
1)帧率


3)总结:帧率:30Hz, 33.3ms, vblank大致为300us, 数据实际传输时间为33.3ms - 0.3ms = 33ms
测量场高
现在已知一帧有效传输时间,我们如果能把一行的时间量出来,那么就知道一帧时间传了多少行。
一般情况下用10us,根据实际情况前后调整。能看到周期,这个是行周期,为15us。

算一下行是多少:33000us/15us = 2200 行
测量行宽

以上是测量到一行内的有效传输时间,为11us
在已知一行有效传输时间,如果能把一个像素的传输时间知道,那么就知道一行传输了多少个点了。
但是一个像素的时间从波形不能直观的看出来。
imx415传输raw10,所以一个点占用10个bit,每个像素分平均到了不同lane传输。
可以这样认为:
- 一行传输时间=一行总数据量/传输速率/lane数
- 一行总数据量=宽xbit数
- 宽=一行传输时间xlane数x传输速率/bit数
- 宽=11usx4x892mbps/10= 3924
代码配置
static const s64 link_freq_items[] = {
MIPI_FREQ_297M,
MIPI_FREQ_446M,
MIPI_FREQ_743M,
MIPI_FREQ_891M,
MIPI_FREQ_1188M,
};
static const struct imx415_mode supported_modes[] = {
/*
* frame rate = 1 / (Vtt * 1H) = 1 / (VMAX * 1H)
* VMAX >= (PIX_VWIDTH / 2) + 46 = height + 46
*/
{
.bus_fmt = MEDIA_BUS_FMT_SGBRG10_1X10,
.width = 3864,
.height = 2192,
.max_fps = {
.numerator = 10000,
.denominator = 300000,
},
.exp_def = 0x08ca - 0x08,
.hts_def = 0x044c * IMX415_4LANES * 2,
.vts_def = 0x08ca,
.global_reg_list = imx415_global_10bit_3864x2192_regs,
.reg_list = imx415_linear_10bit_3864x2192_891M_regs,
.hdr_mode = NO_HDR,
.mipi_freq_idx = 1,
.bpp = 10,
/*.vc[PAD0] = 0,*/
.xvclk = IMX415_XVCLK_FREQ_37M,
},
};
上面是imx415的参数是3864x2192@30.
测出帧率30非常精准,这个是示波器直接测出。
分辨率是3924x2200和实际的3864x2192有点差距,是因为测量多少有些偏差,另外就是这种计算没有考虑封包以及高低速模式之间切换的同步信号。一般情况下算出会比实际大一些。只要差不多接近即可
1338

被折叠的 条评论
为什么被折叠?



