2

我正在尝试将omnivision 的ov9724 相机与imx6dl 微控制器连接起来。相机只有一个单通道的mipi接口,我只使用一个通道进行通信(一个差分数据通道和一个差分时钟通道)。

iMx6dl pin          OV9724 pin
CSI0_MCLK(P4)  -    XCLK      -> Source clock: **24 MHz**
CSI_CLK0M(F4)  -    MCN    (MIPI_CLK_N)
CSI_CLK0P(F3)  -    MCP    (MIPI_CLK_P)
CSI_D0M(E4)    -    MDN0 (MIPI_D0_N)
CSI_D0P(E3)    -    MDP0 (MIPI_D0_P)

我在"git://git.freescale.com/imx/linux-2.6-imx.git"中移植了 ov5640 的相机驱动程序。由于相机只有 RAW-10 位输出,我根据我在网上找到的参考代码编辑了代码。

这是我编辑的相关 dts 配置。

ov9724_mipi: ov9724_mipi@10
{ 
compatible = "ovti,ov9724_mipi";
reg = <0x10>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ipu1_3>;
clocks = <&clks IMX6QDL_CLK_CKO>; //&clks 201 ??
clock-names = "csi_mclk";
DOVDD-supply = <&sw4_reg>; /* 1.8v */
AVDD-supply = <&vgen5_reg>; /* 2.8v, on rev C board is VGEN3,
on rev B board is VGEN5 */
DVDD-supply = <&vgen1_reg>; /* 1.5v*/
pwn-gpios = <&gpio6 2 GPIO_ACTIVE_LOW>; /* active low: CSI0_DAT16 -   PWRDWN*/ //REF MANUAL PG : 1523
stby-gpios = <&gpio6 0 GPIO_ACTIVE_LOW>; /* active low: CSI0_DAT14 -      STANDBY - XSHUTDOWN*/
csi_id = <0>;
mclk = <24000000>;
mclk_source = <0>;
};

&mipi_csi {
status = "okay";
ipu_id = <0>;
csi_id = <0>;
v_channel = <0>; //v_channel 0: CSI0_IPU1; v_channel1: CSI1_IPU1; 2:     CSI0_IPU2; 3: CSI1_IPU2
lanes = <1>;
};

v4l2_cap_0 {
compatible = "fsl,imx6q-v4l2-capture";
ipu_id = <0>;
csi_id = <0>;
mclk_source = <0>;
status = "okay";
};


v4l2_out {
compatible = "fsl,mxc_v4l2_output";
status = "okay";
};

我在下面附上错误日志。对我来说,这似乎是一个时钟问题,在提到错误时,我发现这两位是根据错误寄存器 1 中的数据表设置的。

位 4:虚拟通道 0 的帧开始与帧结束匹配错误

位 28:标头 ECC 包含 2 个错误。不可恢复。

我已将 imx 配置为使用 IPU - 1、CSI - 0、Virtual Channel - 0 和 Number of lanes - 1。请参阅下面的日志。

我认为这可能与时钟配置有关,但我不确定如何继续。我看到了“客户 MIPI 传感器的调试步骤”文档中提到的 dphy 寄存器设置,我认为作者是根据文档AN5305(第14页)中提供的信息创建的,我附在此处。

我将时钟配置如下。

根据数据表,在相机传感器端,Pixel clk = (ext_clk * pll_multiplier) / (sys_clk_div_pll * pre_pll_clk_div_pll * pix_clk_div_pll) = (24000000 * 0x3E) / (0x0A * 0x01 * 0x02) = 75.6 MHz

现在为了在 imx 端配置 mipi dphy 时钟,我使用了以下计算。(对于 30 fps 的 1280 x 720)(此计算基于此处附加的 AN5305 文档中的公式,第 3.4 节,第 13 页)。

像素时钟 = 1280 * 720 * 30 fps * 1 个周期/像素 * 1.35 消隐间隔 = 74.6 MHz

总 MIPI 数据速率 = 74.6 * 10 位 = 746 Mbps。 对于 1 通道接口,MIPI 时钟 = 746 /(通道数)/2 = 746 / 1 / 2 = 373 MHz。

MIPI_CSI2_PHY_TST_CTRL1 设置 = 373 MHz * 2(DDR 模式)= 746 MHz

基于此值,我通过参考 AN5305 第 14 页在 mxc_mipi_csi2.c 中编辑 mipi dphy 设置如下。

mipi_csi2_write(info, 0x00000001, MIPI_CSI2_PHY_TST_CTRL0);
mipi_csi2_write(info, 0x00000000, MIPI_CSI2_PHY_TST_CTRL1);
mipi_csi2_write(info, 0x00000000, MIPI_CSI2_PHY_TST_CTRL0);
mipi_csi2_write(info, 0x00000002, MIPI_CSI2_PHY_TST_CTRL0);
mipi_csi2_write(info, 0x00010044, MIPI_CSI2_PHY_TST_CTRL1);
mipi_csi2_write(info, 0x00000000, MIPI_CSI2_PHY_TST_CTRL0);
mipi_csi2_write(info, 0x00000012, MIPI_CSI2_PHY_TST_CTRL1); //750-800 MHz
mipi_csi2_write(info, 0x00000002, MIPI_CSI2_PHY_TST_CTRL0);
mipi_csi2_write(info, 0x00000000, MIPI_CSI2_PHY_TST_CTRL0);

我仍然不确定时钟设置是否正确。我也不清楚 AN5305 第 21 页中提到的 ov5640 的时钟设置。(我已将其作为图像附在此处 - AN5305.png 中的 MIPI CLK 设置)。他们为什么将 PLL5 设置为596 MHz

此外,ipu 和 mipi 配置如下。

mipi_csi: mipi_csi@021dc000 { /* MIPI-CSI */
compatible = "fsl,imx6q-mipi-csi2";
reg = <0x021dc000 0x4000>;
interrupts = <0 100 0x04>, <0 101 0x04>;
clocks = <&clks IMX6QDL_CLK_HSI_TX>,
<&clks IMX6QDL_CLK_EMI_SEL>,
<&clks IMX6QDL_CLK_VIDEO_27M>;
/* Note: clks 138 is hsi_tx, however, the dphy_c
* hsi_tx and pll_refclk use the same clk gate.
* In current clk driver, open/close clk gate do
* use hsi_tx for a temporary debug purpose.
*/
clock-names = "dphy_clk", "pixel_clk", "cfg_clk";
status = "disabled";
};



ipu1: ipu@02400000 {
#address-cells = <1>;
#size-cells = <0>;
compatible = "fsl,imx6q-ipu";
reg = <0x02400000 0x400000>;
interrupts = <0 6 IRQ_TYPE_LEVEL_HIGH>,
<0 5 IRQ_TYPE_LEVEL_HIGH>;
clocks = <&clks IMX6QDL_CLK_IPU1>,
<&clks IMX6QDL_CLK_IPU1_DI0>, <&clks IMX6QDL_CLK_IPU1_DI1>,
<&clks IMX6QDL_CLK_IPU1_DI0_SEL>, <&clks IMX6QDL_CLK_IPU1_DI1_SEL>,
<&clks IMX6QDL_CLK_LDB_DI0>, <&clks IMX6QDL_CLK_LDB_DI1>;
clock-names = "bus",
"di0", "di1",
"di0_sel", "di1_sel",
"ldb_di0", "ldb_di1";
resets = <&src 2>;
bypass_reset = <0>;
};

我打印了“dphy_clk”、“pixel_clk”和“cfg_clk”,如下所示。

sh-4.3# dmesg | grep 时钟

[ 0.259781] imx-ipuv3 2400000.ipu: ipu_clk = 270000000
MIPI CSI2 cfg_clk: **27000000**
MIPI CSI2 dphy_clk: **198000000**
MIPI CSI2 pixel_clk: **396000000**
[ 0.381171] imx-ipuv3 2400000.ipu: pixel clk = 30919000
[ 0.381240] imx-ipuv3 2400000.ipu: try ipu internal clk
[ 0.381253] imx-ipuv3 2400000.ipu: rounded pix clk:30000000
[ 0.381258] imx-ipuv3 2400000.ipu: try ipu ext di clk
[ 0.381477] #### clk_pllv3_av_set_rate : rate 989407992, parent_rate 24000000, val 0x0, mfn 0x37035 mfd 0xf4240
[ 0.381509] imx-ipuv3 2400000.ipu: di clk:30919000
[ 0.381525] imx-ipuv3 2400000.ipu: round pixel clk:30919000
[ 0.428329] imx-ipuv3 2400000.ipu: pixel clk = 30919000
[ 0.428387] imx-ipuv3 2400000.ipu: try ipu internal clk
[ 0.428402] imx-ipuv3 2400000.ipu: rounded pix clk:30000000
[ 0.428408] imx-ipuv3 2400000.ipu: try ipu ext di clk
[ 0.428429] imx-ipuv3 2400000.ipu: di clk:30919000
[ 0.428442] imx-ipuv3 2400000.ipu: round pixel clk:**30919000**
OV9724 Clock csi_mclk: 24000000
[ 2.879715] galcore: clk_get vg clock failed, disable vg!

看到pixel clk已经四舍五入到30919000,这部分我没看懂。这里的 dphy_clk 是 198 MHz。我是否必须更改任何额外的 pll 设置或其他内容?

内核调试日志显示 MIPI 错误

# ioctl_g_chip_ident #sensor chip is ov9724_mipi_camera
sensor supported frame size:
In mxc_v4l2_s_param
640x480
320x240
720x480
720x576
# ioctl_g_parm #
1280x720
1920x1080
2592x1944
176x144
1024x768
Current capabilities are 1001
sensor frame format: BG10
Current capturemode is 0 change to 0
sensor frame format: BG10
Current framerate is 30 change to 30
sensor frame format: BG10
sensor frame format:BG10
# ioctl_s_parm #
sensor frame format: BG10
sensor frame format: BG10
sensor frame format: BG10
sensor frame format: BG10
sensor frame format: BG10
# INIT MODE mode: 0 frame rate: 1 mode_original: 0 #
MIPI CSI2 Enable Status: 1
MIPI CSI2 Enable Status: 1
MIPI CSI2 Befor setting Lanes: info->lanes: 1
MIPI CSI2 Set Lanes: 0
MIPI CSI2 Set Datatype : 43 0x2b   --> RAW-10 datatype
Pixel Format is V4L2_PIX_FMT_SBGGR10

************ Changing to direct mode! Frame rate is : 1 Mode number is 0

Writing 0x24001b30 to register CSI_SENS_CONF Read Val: 0x4001b30
Writing 0x2cf04ff to register CSI_SENS_FRM_SIZE Read Val: 0x2cf04ff
Writing 0x2cf04ff to register CSI_ACT_FRM_SIZE Read Val: 0x2cf04ff
Writing 0xffffff2b to register IPU_CSI0_DI Read Val: 0xffffff2b
Writing 0x661 to register IPU_CONF Read Val: 0x661
Writing 0x2 to register CSI2IPU_SW_RST Read Val: 0x2

# OV9724 CHANGE MODE DIRECT # Frame Rate: 1 Mode : 4

@@@@@@@@@@@@@@@@@@@ STREAM OFF @@@@@@@@@@@@@@@@@@@@@@@
############## OV9724 REGISTER VALUES READBACK############## 
IPU_CONF = 0x661
IPU_CSI0_SENS_CONF_REG = 0x4001b30
IPU_CSI0_SENS_FRM_SIZE_REG = 0x2cf04ff
IPU_CSI0_ACT_FRM_SIZE_REG = 0x2cf04ff
IPU_CSI0_OUT_FRM_CTRL_REG = 0x0
IPU_CSI0_DI_REG = 0xffffff2b
IOMUXC_GPR1_REG = 0x48441005
CSI2IPU_SW_RST_REG = 0x2
@@@@@@@@@@@@@@@@@@@ STREAM ON @@@@@@@@@@@@@@@@@@@@@@@
Setting Virtual Channel to 0 Channel Reg Value: 2b
GEtting CSI Ready!!
############## OV9724 REGISTER VALUES ############## 
IPU_CONF = 0x661
IPU_CSI0_SENS_CONF_REG = 0x4001b30
IPU_CSI0_SENS_FRM_SIZE_REG = 0x2cf04ff
IPU_CSI0_ACT_FRM_SIZE_REG = 0x2cf04ff
IPU_CSI0_OUT_FRM_CTRL_REG = 0x0
IPU_CSI0_DI_REG = 0xffffff2b
IOMUXC_GPR1_REG = 0x48441005
CSI2IPU_SW_RST_REG = 0x2

MIPI CSI2 PHY_STATE : 0x300
MIPI_CSI2_VERSION : 0x3130302a
MIPI_CSI2_N_LANES : 0x0
MIPI_CSI2_PHY_SHUTDOWNZ : 0x1
MIPI_CSI2_DPHY_RSTZ : 0x1
MIPI_CSI2_DATA_IDS_1 : 0x0
MIPI_CSI2_DATA_IDS_2 : 0x0
MIPI_CSI2_PHY_TST_CTRL0 : 0x0
MIPI_CSI2_PHY_TST_CTRL1 : 0x2a2a

MIPI CSI2 ERROR1 : 0x10000010
MIPI CSI2 ERROR2 : 0x0
MIPI CSI2 ERROR1 : 0x10000000
MIPI CSI2 ERROR2 : 0x0
MIPI CSI2 ERROR1 : 0x10000000
MIPI CSI2 ERROR2 : 0x0
MIPI CSI2 ERROR1 : 0x10000010
MIPI CSI2 ERROR2 : 0x0
MIPI CSI2 ERROR1 : 0x10000010
MIPI CSI2 ERROR2 : 0x0
MIPI CSI2 ERROR1 : 0x10000010
MIPI CSI2 ERROR2 : 0x0
MIPI CSI2 ERROR1 : 0x10000000
MIPI CSI2 ERROR2 : 0x0
MIPI CSI2 ERROR1 : 0x10000010
MIPI CSI2 ERROR2 : 0x0
MIPI CSI2 ERROR1 : 0x10000010
MIPI CSI2 ERROR2 : 0x0
MIPI CSI2 ERROR1 : 0x10000010
MIPI CSI2 ERROR2 : 0x0
MIPI CSI2 ERROR1 : 0x10000000
MIPI CSI2 ERROR2 : 0x0
mipi csi2 can not receive data correctly!

我无法探测 clk 和数据线,因为我拥有的 DSO 只有 200 MHz。我观察到的波形附在下面。(黄色探头 - DATA_P,绿色探头 - DATA_N,蓝色 - CLK_P,粉色 - CLK_N)。打开流媒体时,我正在观察数据线上的数据,但最初在时钟线上没有看到任何东西。然后当我将时钟线的分压降低到 100mV(数据电压在 1V 左右)时,我在时钟中看到了一个波形模式,最初看起来像噪声。当数据存在时,似乎时钟存在。但是当我探测两条数据线时,时钟线看起来像噪声,如图 scope_15.bmp 所示。我不知道为什么时钟会这样 - 硬件问题?但在 imx 端,根据 MPHY MIPI CSI2 PHY_STATE 寄存器检测到 ddr 时钟。

我知道这是一篇很长的帖子,但我想包括迄今为止我所做的一切。我是 linux 的新手,基本上这是我的第一个项目。我将在下面总结我的问题。

  1. 日志中出现 MIPI CSI 错误的原因可能是什么?
  2. 波形中的时钟看起来正常吗?mipi 接口可以正常工作吗?
  3. 如果我的 dphy 时钟配置错误,如何同时配置 imx 和相机时钟?更重要的是,相机传感器时钟与 dphyclock 有什么关系?
  4. 在文档 AN5605 第 21 页中,时钟596MHz的意义是什么,我应该使用什么时钟?

请让我知道你的想法。

链接到AN5305文档 - http://www.nxp.com/assets/documents/data/en/application-notes/AN5305.pdf

scope_2.bmp

4

0 回答 0