omnivision の ov9724 カメラを imx6dl マイクロコントローラーと接続しようとしています。カメラには単一レーンの mipi インターフェイスしかなく、通信には 1 つのレーン (1 つの差動データ レーンと 1 つの差動クロック レーン) のみを使用しています。
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";
};
以下にエラーログを添付します。エラーを参照すると、これらの 2 つのビットがエラー レジスタ 1 のデータシートに従って設定されていることがわかります。
ビット 4: 仮想チャネル 0 のフレーム開始とフレーム終了の一致エラー
ビット 28: ヘッダー ECC に 2 つのエラーが含まれています。回復不能。
IPU - 1、CSI - 0、仮想チャネル - 0、およびレーン数 - 1 を使用するように imx を構成しました。以下のログを参照してください。
クロック設定と関係があるのではないかと思いますが、先に進む方法がわかりません。「カスタマーMIPIセンサーのデバッグ手順」ドキュメントに記載されているdphyレジスタ設定を見ました。これは、ドキュメントAN5305(ページ14 )で入手可能な情報に基づいて作成したと思われます。これをここに添付します。
以下のようにクロックを設定しました。
データシートによると、カメラ センサー側では、ピクセル 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 clk
[ 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!
ピクセル 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!
私が所有している DSO は 200 MHz しかないため、clk およびデータ ラインをプローブできません。私が観測した波形を以下に添付します。(黄色のプローブ - DATA_P、緑色のプローブ - DATA_N、青色 - CLK_P、ピンク - CLK_N)。ストリーミングをオンにしたときにデータ ライン上のデータを観察していますが、最初はクロック ライン上に何も表示されませんでした。その後、クロックラインの分圧を100mV(データ電圧は1V程度)に下げたところ、クロックにノイズのような波形パターンが現れました。データが存在する場合、クロックが存在するようです。しかし、両方のデータ ラインを調べると、fig scope_15.bmp に示すように、クロック ラインがノイズのように見えます。なぜ時計がそのように動作するのかわかりません - ハードウェアの問題ですか? ただし、imx 側では、MPHY MIPI CSI2 PHY_STATE レジスタに従って ddr クロックが検出されます。
これが長い投稿であることは承知していますが、これまでに行ったことをすべて含めたいと思いました。私はLinuxの初心者で、基本的にこれが私の最初のプロジェクトです。以下に私の質問を要約します。
- ログに表示される MIPI CSI エラーの原因は何ですか?
- 波形のクロックは正常に見えますか? mipi インターフェイスが機能するのに十分ですか?
- dphy クロック設定が間違っている場合、imx とカメラ クロックの両方を設定する方法を教えてください。さらに重要なことは、カメラ センサー クロックが dphyclock にどのように関連しているかということです。
- ドキュメント AN5605 の 21 ページでは、Clock 596MHzの重要性と使用すべきクロックは何ですか?
考えを教えてください。
AN5305ドキュメント へのリンク - http://www.nxp.com/assets/documents/data/en/application-notes/AN5305.pdf