LoginSignup
3
3

Jetson Orin Nano DevKitとCSIカメラを繋ぐ

Last updated at Posted at 2023-05-03

今回の機材

Camera Module 2 接続

XavierNXまではraspberrypiと同じ15ピン 1.0mmピッチのコネクタでしたが、Orin Nanoから22ピン 0.5mmピッチに変わっており、XavierNXまでで使えていたCSIカメラをそのまま繋ぐことは出来ません。
ですが、22ピン 0.5mmピッチはRaspberry Pi Zero Wと同じタイプです。
おおよそ同じピン配置なのでPi cameraの15-pin to 22-pin FFC cableが使えます。

RaspberryPiのコネクタのpin配置はarducamのサイトにわかりやすく図も乗っています。

画像を引用しました。
Pin#15から3V3、I2Cとなっています。

RaspberryPiCamera配線図

15-22pinの場合は以下の図の通り、間にある2レーン分を未接続にしてつないでいます。
image.png

Orin NanoについてはJetson Download CenterのCarrier Board Specificationを参照しましょう。

OrinNanoの場合はButtomHeaderがある方がPin#1で、こちらから3V3, I2Cとなっています。
PinNoはRaspberryPiとは逆ですが、並びは同じなのでこの図にある通り、基板側に電極が来るようにつなげればOKです。
image.png

スライドを引き、少し上に持ち上げ、FFC電極面がキャリアボード側を向くように差して止めます。
差し込み感がわかりにくいですがJetsonHacks Using the Jetson Orin Nano with CSI Cameras
に動画があるのでそちらも参考にしてください。

とりあえずCAM0につないでRebootをするとdmesgに次のようなログがあるはずです

これでドライバのロードもされてIMX219が認識されているはずです

imx219 9-0010: tegracam sensor driver:imx219_v2.0.6
tegra-camrtc-capture-vi tegra-capture-vi: subdev imx219 9-0010 bound
v4l2-ctl --list-devices
NVIDIA Tegra Video Input Device (platform:tegra-camrtc-ca):
        /dev/media0

vi-output, imx219 9-0010 (platform:tegra-capture-vi:1):
        /dev/video0

撮影

失敗編(CAM0)

撮影してみましょう。
RAW画像をそのまま保存してみます。

v4l2-ctl -d /dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat=RG10 --set-ctrl bypass_mode=0,sensor_mode=0 --stream-mmap --stream-count=1 --stream-to=test.raw

結果が出てこない場合はdmesgを見ましょう。
エラーに uncorr_err: request timed out after 2500 ms とある場合、ビデオ入力を受け取るtegra-capture-viが入力のシグナルを受け付けなかったというエラーです。
実はこれ35.3.1ではデバイスツリーの設定不具合があって基本的に成功しません。
諦めてCAM1を使いましょう。

tegra-camrtc-capture-vi tegra-capture-vi: uncorr_err: request timed out after 2500 ms
tegra-camrtc-capture-vi tegra-capture-vi: err_rec: attempting to reset the capture channel
(NULL device *): vi_capture_control_message: NULL VI channel received
t194-nvcsi 13e40000.host1x:nvcsi@15a00000: csi5_stream_close: Error in closing stream_id=0, csi_port=0
(NULL device *): vi_capture_control_message: NULL VI channel received
t194-nvcsi 13e40000.host1x:nvcsi@15a00000: csi5_stream_open: VI channel not found for stream- 0 vc- 0
tegra-camrtc-capture-vi tegra-capture-vi: err_rec: successfully reset the capture channel

成功編(CAM1)

CAM1につなぐとカメラ imx219 9-0010 -> imx219 10-0010となって認識できます。

imx219 10-0010: tegracam sensor driver:imx219_v2.0.6
tegra-camrtc-capture-vi tegra-capture-vi: subdev imx219 10-0010 bound
$ v4l2-ctl --list-devices
NVIDIA Tegra Video Input Device (platform:tegra-camrtc-ca):
        /dev/media0

vi-output, imx219 10-0010 (platform:tegra-capture-vi:2):
        /dev/video0

RAW取得コマンドも以前とことなり正常に終了してRAWデータが得られています。

$ v4l2-ctl -d /dev/video0 --set-fmt-video=width=1920,height=1080,pixelformat=RG10 --set-ctrl bypass_mode=0,sensor_mode=0 --stream-mmap --stream-count=1 --stream-to=test.raw
<

Argus

実際の映像も確認しましょう。
Jetson Orin NanoにもISPが乗っているのでArgusAPI経由でデベイヤーした画像が得られます。

argus_camera(実機)

argus_cameraで動作確認します。
以下のようなMakefileでmake setupを実行したら、argus_cameraのバイナリが実行したディレクトリにできます。
実行したらカメラの画像が見れると思います。

なお、SSHでX11 Forwardしている場合はArgusAPIを叩くときにEGLの周りでエラーで動かないことがあります。
実機で見るか、unset DISPLAY してGStreamerで動画記録の方法をおすすめします。

.PHONY: setup
setup:
	sudo apt update
	sudo apt install -y nvidia-l4t-jetson-multimedia-api \
	cmake build-essential pkg-config libx11-dev libgtk-3-dev \
	libexpat1-dev libjpeg-dev libgstreamer1.0-dev v4l-utils tree
	cp -r /usr/src/jetson_multimedia_api .
	cd jetson_multimedia_api/argus/ && \
		mkdir -p build && \
		cd build && \
		cmake ..  && \
		make
	cp jetson_multimedia_api/argus/build/apps/camera/ui/camera/argus_camera .

Record Video by GStreamer

リモートでするならgstreamerからファイル保存をするのも楽です。
残念ながらOrinNanoにHW Encoderは載っていないのでx264encを使います。
出来たファイルをLocalMachineに持ってきて撮影できているか確認してください。

gst-launch-1.0 nvarguscamerasrc num-buffers=30 ! nvvidconv ! x264enc ! mp4mux ! filesink location=test.mp4

まとめ

  1. 15-pin to 22-pin FFC cableがあればRaspberryPiのカメラが使える
    1. switch-scienceで買うならRPI-A-003
  2. CAM0ポートでは動作しない
    1. L4T35.3.1のデフォルトのデバイスツリーでは動かない設定でした
    2. 下記原因究明編を参照してください

余談

XavierNXのキャリアボードからピンのアサインと関わっていました。
今回のピン配置ですが以下のとおりです。
左からIMX219カメラの15pinを22pin変換したもの、OrinのCAM0,1とXavierNXのJ1(CAM1とスクリーン印刷されていますが実際にはCAM0)
XavierNXのときにはCSI0がつながっていましたがOrinNanoではCSI1になっています。

Pin # IMX219 Camera with Cable Orin Nano CAM0 Orin Nano CAM1 XavierNX J1
1 3V3 3V3 3V3 3V3
2 CAM_SDA CAM_I2C_SDA CAM_I2C_SDA CAM_I2C_SDA
3 CAM_SCL CAM_I2C_SCL CAM_I2C_SCL CAM_I2C_SCL
4 GND GND GND
5 CAM_IO1 CAM0_MCLK CAM0_MCLK CAM0_MCLK
6 CAM_IO0 CAM0_PWDN CAM0_PWDN CAM0_PWDN
7 GND GND
8 CSI0_D1_P CSI3_D1_P
9 CSI0_D1_N CSI3_D1_N
10 GND GND
11 CSI0_D0_P CSI3_D0_P
12 CSI0_D0_N CSI3_D0_N
13 GND GND GND GND
14 CAM_CK_P CSI1_CLK_P CSI2_CLK_P CSI0_D1_P
15 CAM_CK_N CSI1_CLK_N CSI2_CLK_N CSI0_D1_N
16 GND GND GND GND
17 CAM_D1_P CSI1_D1_P CSI2_D1_P CSI0_D0_P
18 CAM_D1_N CSI1_D1_N CSI2_D1_N CSI0_D0_N
19 GND GND GND GND
20 CAM_D0_P CSI1_D0_P CSI2_D0_P CSI0_CLK_P
21 CAM_D0_N CSI1_D0_N CSI2_D0_N CSI0_CLK_N
22 GND GND GND GND

またOrinシリーズのCSI0,1はデータレーンの極性がswapしているので特別な指定が必要となってます。
L4Tソースのtegra234-p3768-0000-a0.dtsiにその記述があるので、カメラドライバを移植する時は変更をお忘れなく。

hardware/nvidia/platform/t23x/p3768/kernel-dts/cvb/tegra234-p3768-0000-a0.dtsi
tegra-capture-vi  {
	ports {
		port@0 {
			endpoint {
				port-index = <1>;
			};
		};
	};
};

host1x@13e00000 {
	nvcsi@15a00000 {
		csi_chan0 {
			ports {
				port@0 {
					endpoint@0 {
						port-index = <1>;
					};
				};
			};
		};
	};
};

cam_i2cmux{
		i2c@0 {
			rbpcv2_imx219_a@10 {
				mode0 {
                    # CSI1(CSI-B)を指定
					tegra_sinterface = "serial_b";
                    # CSIx_D1とCSIx_D0のスワップ
					lane_polarity = "6";
				};
				mode1 {
					tegra_sinterface = "serial_b";
					lane_polarity = "6";
				};
				mode2 {
					tegra_sinterface = "serial_b";
					lane_polarity = "6";
				};
				mode3 {
					tegra_sinterface = "serial_b";
					lane_polarity = "6";
				};
				mode4 {
					tegra_sinterface = "serial_b";
					lane_polarity = "6";
				};
				ports {
					port@0 {
						endpoint {
							port-index = <1>;
						};
					};
				};
			};

			rbpcv3_imx477_a@1a {
				mode0 {
					tegra_sinterface = "serial_b";
					lane_polarity = "6";
				};
				mode1 {
					tegra_sinterface = "serial_b";
					lane_polarity = "6";
				};
				ports {
					port@0 {
						endpoint {
							port-index = <1>;
						};
					};
				};
			};
		};
	};
};

CAM0原因究明編

なぜCAM0だけ機能しないのでしょう。
それはOrinNanoDevKitのピン設定と上のデバイスツリー設定に原因があります。

CAM0ポートは従来と違ってCSI1(別名CSI-B)が繋がっています。
TRMの接続経路を見てみると以下のようにCSI-AB Pad -> RX SCIL0 -> PP1 -> VIへと入力されます。

DP-10508-002_v1.0p | Page 538より引用
image.png

従来とはroutingが異なるわけですね。
それを反映するのが上のデバイスツリーです。
大本のデバイスツリーではport_index=<0>だったものを<1>に書き換えることで、OrinNXとOrinNanoの両方に対応しているわけですね。

で、上の設定には一箇所だけ設定不具合があり、以下が正しい設定となります。

host1x@13e00000 {
	nvcsi@15a00000 {
- 		csi_chan0 {
+		channel@0 {
			ports {
				port@0 {
					endpoint@0 {
						port-index = <1>;
					};
				};
			};
		};
	};
};

csi_chan0はシンボルなので実ツリーの指定が必要というわけでした。
ブロック単位でのroutingは正しくともPAD設定が繋がっていなかったのでデータ無しのエラーだったということです。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3