[Armadillo:07120] Re: [Armadillo-440] I2C通信で失敗する

下村智範 email@hidden
2011年 4月 20日 (水) 15:56:00 JST


下村です。

引き続き、I2C通信を見ています。

新しいバージョンのKernelで動作確認してみましたが
結果は同じでした。
エラー内容もまったく同じです。

何か動作しない手がかりはないものかと、独自機器の
I2Cのスタータスフラグを監視していたところ
Bus Busy Bit が立っていました。

Armadilloよりも先に独自機器の電源をONし、ステータスを
確認すると、Bus Busy Bitは立っていません。
この状態でArmadilloの電源をONすると、即座にBus Busy Bitが
立ちます。

Androidが立ち上がったところで、I2CをOpenし、readを行うと
タイムアウトで通信失敗です。
Bus Busy Bitは立ったままです。

ここで不思議なことに、独自機器のステータスを監視していると
・スレーブアドレス一致フラグ
・ゼネラルコールフラグ
・受信データフルフラグ
が立ちます。
受信データフルなので受信バッファを取得したのですが「0」です。
本来ならば、ここでスレーブアドレスがReadできるはずです。

逆に、Armadilloの方から電源をONした場合も見てみました。
Androidが起動してから、独自機器の電源をONしました。
電源ONした直後から、Bus Busy Bit が立っていました。
その状態で、I2CをOpenし、readを行っても結果は同じで
タイムアウトで通信失敗です。

しかし、独自機器の
・スレーブアドレス一致フラグ
・ゼネラルコールフラグ
・受信データフルフラグ
が立つことはありませんでした。

電源をどちらから先に投入するかで若干結果が異なっています。
Armadilloの電源投入時に行われる、I2Cポートに対しての
ダミー初期化(!?)の処理で何か追加してあげなければいけない
処理がございますでしょうか。
I2Cモジュールのリセット?のような処理はございませんでしょうか。

タイムアウトが発生する前に、「Could not grab Bus ownership」の
メッセージも出力されております。
なんとなく、Armadillo側のI2Cモジュールが何か動作しっぱなしに
なっているような感じがしますが、いかがでしょうか?

独自機器の方の処理も再度確認しておりますが、I2C通信開始の
スタートコンディションシーケンス中は、I2Cモジュールの管轄のため
レジスタの設定を見直すぐらいしか行えません。
I2Cモジュールの不具合の可能性もありますが。。。

もう少しで完全に行き詰まりそうです。。。
何か少しでも情報がございましたら、いただけると大変助かります。

以上、よろしくお願いいたします。


2011年4月19日16:50 下村智範 <email@hidden>:
> 下村です。
>
> ご回答ありがとうございます。
>
>> linux-2.6.26-at8 (linux-a400-1.01.bin.gz) 以降では、デフォルトの設定で CON14 を I2C2
>> として使用するようになっています。
> Kernelバージョンは、linux-2.6.26-at7でした。
>
>
>>>> 2. I2Cのクロックを400Kに変更する。
>> ソースコードの変更箇所も、具体的に教えていただけると、助かります。
> 変更したソースコードを添付いたします。
> //shimomura ----->
> #if 0
>  修正前コード
> #else
>  修正後コード
> #endif
> //shimomura -----<
>
> 修正後のコードが変更した値になります。
>
>
>>>> 3. オープンする。
>> "/dev/i2c-1"は存在する、ということですね。
> はい、存在します。
> /dev/i2c-1を確認しております。
> 起動時のdmesgログを確認すると、i2c-1に対してダミー初期化(?)のような処理が
> 行われております。
> dmesgを添付いたします。
> (原因特定のために、crの値とsrの値も出力するように追加しております。
>  crとsrの値の分、通常よりも少しログが多くなっています)
>
>>>> 4. スレーブアドレスを設定。
>>>> 独自機器では、0x22と0x44のどちらを設定すべきでしょうか?
>> 独自機器がどのようなものか分からないので、なんとも言えないですね。
> 独自の機器は特に関係ないと考えております。
> スレーブデバイスには、スレーブアドレスを自由に設定できますので、何をセットすれば良いか
> という疑問だけになります。
> 現在は、0x22に設定しておりますが、マスターにスレーブデバイス=0x22と設定すると
> アドレスが一致しません。
> スレーブが0x22ならば、マスターにはスレーブアドレス=0x11をセットしなければ
> いけないと理解いたしました。
> I2Cの実装は今まで何回か行っているのですが、シフトして云々というのは初めて見ました。
>
>
>>>> 5. データを 20byte 取得する。
>> 本当にアドレスが送信できていないのか、I2Cスレーブデバイス(独自機器)側でデータを受け取れていないのか、
>> オシロスコープやロジックアナライザなどで、実際の波形を見て確認してみるのが、確実ではないかと思います。
>>
> 残念ながら、そこまで機材がそろっておりません。
> 入手可能か検討してみます・・・。
>
>>> <7>Could not grab Bus ownership
>> このメッセージが出るときは、同じI2Cバス(I2C2)上につながっている他のデバイスが
>> SDAをドライブしているのかもしれません。回路の方も確認してみてください。
> 自分のその他のデバイスが、I2C2に繋がっていると考えました。
> しかし、現在独自機器一つしかI2C機器は接続しておりません。
> RTCモジュールと重複している可能性はありませんか?
>
> 以上、よろしくお願いいたします。
>
>
>
> 2011年4月19日15:57 Takenoshita Koyo <email@hidden>:
>> 竹之下です。
>>
>>>> 1. I2Cを有効にする。
>>>>    ⇒ デフォルトではCON14(i2c-1)は無効になっているためKernel configで有効にしました。
>> Linuxカーネルは、バージョンいくつをご使用でしょうか?
>> linux-2.6.26-at8 (linux-a400-1.01.bin.gz) 以降では、デフォルトの設定で CON14 を I2C2
>> として使用するようになっています。
>>
>> 使用している環境を具体的に教えてください。
>>
>>>> 2. I2Cのクロックを400Kに変更する。
>>>>  ⇒ kernel/arch/arm/mach-mx25/armadillo440.c  の i2c-1(I2C2) のbpsを
>>>> 4000bps ⇒ 40000bps へ変更しました。
>>
>> 以下のように変更した、ということで間違いないでしょうか?
>>
>> --- a/arch/arm/mach-mx25/armadillo400.c
>> +++ b/arch/arm/mach-mx25/armadillo400.c
>> @@ -592,7 +592,7 @@ static struct i2c_board_info armadillo400_i2c2_board_info[] __initdata = {
>>  };
>>
>>  static struct mxc_i2c_platform_data armadillo400_i2c2_data = {
>> -       .i2c_clk = 40000,
>> +       .i2c_clk = 400000,
>>  };
>>  #endif /* defined(CONFIG_I2C_MXC_SELECT2) */
>>
>> * 本当に、"4000bps ⇒ 40000bps"にしたのでしょうか? (40000 から 400000 への変更ではありませんか?)
>> * 変更したのは、armadillo400_i2c2_data で間違いないでしょうか? (armadillo400_i2c1_data を変更していないでしょうか?)
>>
>> ソースコードの変更箇所も、具体的に教えていただけると、助かります。
>>
>>>> 3. オープンする。
>>>>    ⇒ fd = open( /dev/i2c-1, O_RDWR ); は成功し、正しい戻り値がもらえています。
>> "/dev/i2c-1"は存在する、ということですね。
>>
>>>> 4. スレーブアドレスを設定。
>>>>  ⇒ ioctl( fd, I2C_SLAVE, 0x22 ); も成功しました。
>>
>>>> また、mxc_i2c.cの処理み見てみたところ、スレーブアドレスの扱いでちょっと気になりました。
>>>> ioctl()で渡したスレーブアドレスを1ビットシフトし、R/Wビットを付与していました。
>>>> 0x22で渡せば、実際にスレーブアドレスが発行されるときには、Rの場合= 0x45, Wの場合= 0x44に
>>>> なります。
>>>> 独自機器では、0x22と0x44のどちらを設定すべきでしょうか?
>> 独自機器がどのようなものか分からないので、なんとも言えないですね。
>>
>> ご指摘の通り、ドライバ内で1ビット左シフトしてからR/Wビットを付け足すので、
>> ioctl(fd, I2C_SLAVE, )に渡すアドレスは、I2Cスレーブデバイスが期待しているアドレスを
>> 1ビット右シフトしたものを指定すると、双方の意図しているアドレスが一致するかもしれません。
>>
>>>> 5. データを 20byte 取得する。
>>>>  ⇒ read( fd, pBuf, 20 ) で、Remote I/O error が発生します。
>>>>
>>>> ※ 実際には、Timeoutエラーです。
>>>>
>>>> 独自の機器の方は、ある程度デバッグが可能ですので、I2Cのステータスを監視していたところ
>>>> マスターからデータ通信要求は行われていましたが、実際のデータが取得できていませんでした。
>>>> 独自機器の受信バッファを読んでも"0"です。
>>>> 本来ならば、スレーブアドレスが入っているはずです。
>>>> 試しに、writeを行ってみましたが、結果は同じで、スレーブアドレスが正常に送信できません。
>> 本当にアドレスが送信できていないのか、I2Cスレーブデバイス(独自機器)側でデータを受け取れていないのか、
>> オシロスコープやロジックアナライザなどで、実際の波形を見て確認してみるのが、確実ではないかと思います。
>>
>>> もう一点気になっている箇所がございました。
>>>
>>> read()を行って失敗した時のdmesgを取得しまいした。
>>> -------------------------------------------------------------------------------------
>>> <7>i2c-adapter i2c-1: ioctl, cmd=0x703, arg=0x22
>>> <7>i2c-dev: i2c-1 reading 20 bytes.
>>> <7>i2c-adapter i2c-1: master_xfer[0] R, addr=0x22, len=20
>>> <7>cr = 0xE0
>>> <7>Could not grab Bus ownership
>>> <7>cr = 0xF0
>>> <7>addr = 0x45
>>> <7>Data not transmitted
>>> -------------------------------------------------------------------------------------
>>
>>> <7>Could not grab Bus ownership
>> このメッセージが出るときは、同じI2Cバス(I2C2)上につながっている他のデバイスが
>> SDAをドライブしているのかもしれません。回路の方も確認してみてください。
>>
>> --
>> Koyo Takenoshita
>>
>> _______________________________________________
>> armadillo mailing list
>> email@hidden
>> http://lists.atmark-techno.com/cgi-bin/mailman/listinfo/armadillo
>>
>



armadillo メーリングリストの案内