Armadilloフォーラム

Armadillo-640 I2C通信 i2cdetectコマンドでスレーブアドレスが表示されない

sankyo_takada

2022年6月9日 11時17分

お世話になります。高田と申します。
Armadillo-640(以下、A640)のI2C-1を使用してマイコンと通信しようとしています。
A640をマスター、マイコンをスレーブとし、スレーブアドレスは0x20に設定しました。
A640でi2cdetectコマンドを実行すると以下の結果となり、スレーブデバイスが検出されません。

root@armadillo:~# i2cdetect -y 1
0 1 2 3 4 5 6 7 8 9 a b c d e f
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

SCL、SDAラインをオシロで測定したところ、信号は出力されており、スレーブからはACKが返っているように思えます。
参考にオシロ画像を添付します。
i2cdetect でスレーブデバイスが検出されない原因として何が考えられるでしょうか。
OSはDebian GNU/Linux 9 (stretch)を使用しています。

よろしくお願いいたします。

ファイル ファイルの説明
オシロ画像.PNG オシロ画像(CH1:SCL、CH2:SDA)
コメント

溝渕です。

> Armadillo-640(以下、A640)のI2C-1を使用してマイコンと通信しようとしています。
:(省略)
> root@armadillo:~# i2cdetect -y 1

I2C-1だと、"i2cdetect -y 0"になるかと思います。

ご確認ください。

溝渕様

ご連絡ありがとうございます。

> I2C-1だと、"i2cdetect -y 0"になるかと思います。
説明が悪くすみません。
I2C2を使用しております。
この場合、/dev/i2c-1と認識されると思いますので、"i2cdetect -y 1"で良い認識です。
なお、"i2cdetect -y 0"を実行すると以下のメッセージが表示されます。

root@armadillo:/home/ftp/test# i2cdetect -y 0
Error: Could not open file `/dev/i2c-0' or `/dev/i2c/0': No such file or directory

よろしくお願いいたします。

高田

溝渕です。

以下のコマンドの出力を教えていただけますか。

i2cdetect -F 1
i2cdetect -l
i2cget -f -y 1 0x20

溝渕様

コマンド実行結果は以下になります。

root@armadillo:~# i2cdetect -F 1
Functionalities implemented by /dev/i2c-1:
I2C yes
SMBus Quick Command yes
SMBus Send Byte yes
SMBus Receive Byte yes
SMBus Write Byte yes
SMBus Read Byte yes
SMBus Write Word yes
SMBus Read Word yes
SMBus Process Call yes
SMBus Block Write yes
SMBus Block Read yes
SMBus Block Process Call no
SMBus PEC yes
I2C Block Write yes
I2C Block Read yes

root@armadillo:~# i2cdetect -l
i2c-1 i2c 21a4000.i2c I2C adapter

root@armadillo:~# i2cget -f -y 1 0x20
Error: Read failed

よろしくお願いいたします。

高田

溝渕です。

ご確認ありがとうございます。

> root@armadillo:~# i2cget -f -y 1 0x20
> Error: Read failed

読めていませんね(デバイスによってレジスタアドレス指定やアクセス幅があるのでこれで正常かもしれませんが)。

いちおうですが、このコマンド実行時の波形を取得していただくことは可能ですか。

溝渕様

ご確認ありがとうございます。
i2cget実行時のオシロ画像を添付します。

よろしくお願いいたします。

高田

ファイル ファイルの説明
i2cget .PNG

溝渕です。

ご確認ありがとうございます。

確かにslaveはackを返していますね。

ちなみに、i2cget/setでのアクセスは可能ですか?

また、(ソースをちゃんと確認していないのであまり確信が持てませんが)i2cdetectは(masterから見て)出力のみ対応しているslaveは検出できないようなのですが、slaveはどのような仕様でしょうか?

溝渕様

> ちなみに、i2cget/setでのアクセスは可能ですか?
試してみましたが、どちらのコマンドも1byte目(スレーブアドレス)のあと、信号が変化せず通信できません。
(先ほど送付したオシロ画像のイメージです)

> また、(ソースをちゃんと確認していないのであまり確信が持てませんが)i2cdetectは(masterから見て)出力のみ対応しているslaveは検出できないようなのですが、slaveはどのような仕様でしょうか?
スレーブはマイコン(PIC)なのですが、送受信できる認識でおります。
スレーブアドレスは7bitモードで0x20を設定してあります。
クロックストレッチングが影響している可能性もあると思い、マイコン側で無効にしてみましたが状況は変わらずでした。
また、通信クロックは100kHzで試してダメだったので、現在は50kHzにしていますが、これも関係ないようです。
今回マイコン側のファームも新規設計しており、こちらに要因がある可能性も考えられますでしょうか。。。

廣畑と申します。
波形を見る限り、スレーブはACKを返していないのではないでしょうか。
LOWになっているのはホストがSTOP CONDITIONを生成したためかと思います。

溝渕です。

コメントありがとうございます。

> LOWになっているのはホストがSTOP CONDITIONを生成したためかと思います。

[start][slave addr(0x20)][R/W(R)][ack/nack(ack)][stop]
#"()"内は実際の値です

上記のように見えますが、誤認ありましたら、申し訳ございませんがご指摘お願いいたします。

> 今回マイコン側のファームも新規設計しており、こちらに要因がある可能性も考えられますでしょうか。。。

少し話は戻りますが、i2cdetectはbyte readできないと反応を返しません(writeにしか反応しないデバイスの場合は"-q"などのオプションが必要です)。なので、i2cdetectで反応しないことの本質は、i2cgetが失敗することと同じとみなせます。

添付していただいた波形は正常に見えますが、この後にREADの波形が出ているかと思います。少しレンジを長くして再度波形を取得してみていただけますか? その際にマイコンがnackを返しているのではないかと推測しています。

廣畑です。
> 波形を見る限り、スレーブはACKを返していないのではないでしょうか。
> LOWになっているのはホストがSTOP CONDITIONを生成したためかと思います。
すみません読み違いました。9ビット目はLでACKは出ています。
混乱の元を発信してしまい申し訳ありません。

溝渕です。

> すみません読み違いました。9ビット目はLでACKは出ています。
> 混乱の元を発信してしまい申し訳ありません。

いえ。ご指摘いただいたお陰でちゃんと波形を再確認できました。有難うございます。

溝渕 様
廣畑 様

ご確認ありがとうございます。

> 添付していただいた波形は正常に見えますが、この後にREADの波形が出ているかと思います。
> 少しレンジを長くして再度波形を取得してみていただけますか? その際にマイコンがnackを返しているのではないかと推測しています。

オシロのレンジを長く取って波形取得してみましたが、2byte目以降は出力されていないようです。
("i2cget -f -y 1 0x20"を実行しました)
画像添付します。
分かりにくいのですが、左から1目盛り目がアドレス信号で、その後180msの間は信号の変化がありません。
引き続きマイコン側も調べてみます。

高田

ファイル ファイルの説明
range_20ms.PNG

溝渕です。

> 分かりにくいのですが、左から1目盛り目がアドレス信号で、その後180msの間は信号の変化がありません。

すみません。すでに試しているかもしれませんが、オシロスコープのレンジを数100us〜1ms程度に設定してi2cgetを実行したと場合の結果をを見せていただけますか。

i2cgetのソースを確認したとこ、以前取得してもらった以下のログより、

root@armadillo:~# i2cget -f -y 1 0x20
Error: Read failed

スレーブアドレスの指定には成功しています。もし失敗したら次のログが出るはずだからです。

Warning - write failed

この挙動は今迄取得してもらった波形と一致しています。スレーブアドレス0x20がackを返しているという意味です。

i2cgetは、その後readしています。ここで初めてエラーとなるため、"Error: Read failed"というログを出力しています。

以上より、スレーブアドレスの指定後に、少なくともSCLは動いているのではないかと考えています。

溝渕様

詳細な調査、感謝申し上げます。
100us、200usレンジで測定した波形を添付します。
SCLは動いていないように見えますが、いかがでしょうか。

高田

ファイル ファイルの説明
range_100us.PNG
range_200us.PNG

溝渕です。

ご確認ありがとうございます。

> SCLは動いていないように見えますが、いかがでしょうか。

確かにSCLは動いていません。

マイコン側ですが、ACKを送出した後にバスを開放していますか? また、オープンドレイン出力になっていますか?

溝渕様

> マイコン側ですが、ACKを送出した後にバスを開放していますか? また、オープンドレイン出力になっていますか?
マイコン側のソースおよびデータシートを確認しましたが、アドレス検知後にSCLラインを開放していると思います。
(SCKラインをロック/開放するレジスタがあり、これを制御していることはデバッガを使用して確認しました)
この後はマスターからのSLC再開待ちかと思います。
また、PICの場合、SLC、SDAラインは入力設定にするようです。
念のため入出力やオープンドレインなど試してみましたが状況変わらずでした。

波形を見ると、1byte目の通信完了後にストップコンディションが出力されているように見えます。

i2cgetのソースを確認できていないのですが、"Error: Read failed"が出力される条件は何でしょうか。
(スレーブアドレス後にSCLを出力せずに上記エラーになるケース)
i2cgetのソースも確認したく、お手数ですがソースの場所もご教示いただけますと助かります。

また、出来るかわかりませんが、別のスレーブデバイスを接続して挙動を確認してみたいとも考えております。
デバイスが異なるのであまり参考にはならないかもしれませんが。。。

高田

溝渕です。

> i2cgetのソースも確認したく、お手数ですがソースの場所もご教示いただけますと助かります。

Armadillo-640上で次のコマンドを実行してみてください。

apt source i2c-tools

溝渕様

ご回答ありがとうございます。
ソースを確認することができました。

なお、その後の調査で少し進展があり、使用するチャンネルをI2C4(/dev/i2c-3)に変更したところ通信ができることを確認しました。

変更前はI2C2(/dev/i2c-1)を使用しており、試しにマイコン以外のスレーブデバイス(EEPROM)を接続してi2cdetectコマンドを試したのですが、
やはりA640がスレーブデバイスを認識してくれませんでした。(コマンド実行結果でスレーブアドレスが表示されない)
このため、A640側に要因があると思いI2C4で接続したところ、通信ができました。
(i2cdetectコマンドでスレーブアドレスが表示され、オシロで波形も確認しました)

I2C2が正常に機能しない要因としてカスタマイズ方法が間違っていたのではないかと考えています。
以下のマニュアルを参考に、I2C2を使用するためにat-dtwebを使用してデバイスツリーファイルをカスタマイズしました。
https://manual.atmark-techno.com/armadillo-640/armadillo-640_product_ma…

このとき、dtsiファイルのI2C2部は以下の記述になったのですが、問題となりそうな点はあるでしょうか。

	pinctrl_i2c2: i2c2grp {
		fsl,pins = <
			MX6UL_PAD_UART5_RX_DATA__I2C2_SDA	0x4001b8b0 // CON9_4
			MX6UL_PAD_UART5_TX_DATA__I2C2_SCL	0x4001b8b0 // CON9_6
 
			MX6UL_PAD_CSI_HSYNC__I2C2_SCL		0x4001b8b0 // CON11_48
			MX6UL_PAD_CSI_VSYNC__I2C2_SDA		0x4001b8b0 // CON11_49
		>;
	};

以下の点が気になっています。
・CON11_48、CON11_49の記述があっても問題が無いか
・ピンの設定を指定する"0x4001b8b0"部が適切か
 ⇒以下の記事では"0x40010808"を設定しているため
  参照URL:https://manual.atmark-techno.com/armadillo-guide-std/armadillo-guide-st…

よろしくお願いいたします。

高田

溝渕です。

> このとき、dtsiファイルのI2C2部は以下の記述になったのですが、問題となりそうな点はあるでしょうか。

あります。1つの機能を複数のピンに割り合てることはできません。

CON9_4/6を利用するのであれば、次のようにする必要があります。

	pinctrl_i2c2: i2c2grp {
		fsl,pins = <
			MX6UL_PAD_UART5_RX_DATA__I2C2_SDA	0x4001b8b0 // CON9_4
			MX6UL_PAD_UART5_TX_DATA__I2C2_SCL	0x4001b8b0 // CON9_6
		>;
	};

CON11_48/49を利用するのであれば、次のようにする必要があります。

	pinctrl_i2c2: i2c2grp {
		fsl,pins = <
			MX6UL_PAD_CSI_HSYNC__I2C2_SCL		0x4001b8b0 // CON11_48
			MX6UL_PAD_CSI_VSYNC__I2C2_SDA		0x4001b8b0 // CON11_49
		>;
	};

> ・ピンの設定を指定する"0x4001b8b0"部が適切か

これはハードウェア構成によるので、波形を見て適切な値にする必要があります。

立ち上がりやホールド時間など、要件を満たしていれば問題ありません。

溝渕様

返信が遅れまして申し訳ございません。
ようやく確認ができました。

ご指摘いただいたとおり、I2C2を複数ピンに設定していることが原因でした。
アサインを見直して確認したところ、スレーブデバイスから応答が返り、通信できることが確認できました。
迅速なご対応、感謝申し上げます。

高田