[Armadillo:03949] Re: armadillo-500 sysfs経由でI2Cドライバ制御
g-kihara
email@hidden
2009年 1月 23日 (金) 14:09:27 JST
木原です。
お世話になっています。
誤記がありました。申し訳ございません。
弊社のデバイスについて、
任意のアドレスのデータを読む場合、
S| Slave | R/W=0 | ack | レジスタアドレス | ack | S | Slave | R/W=1 |
Data(n)| ack | Data(n+1) | ack | ・・・・・|ack| Stop |
となっています。
しかし、linux-2.6.13/Documentation/i2c/i2c-protocolの
i2c_transferに関する説明によると、
They are just like the above transactions, but instead of a stop bit P
a start bit S is sent and the transaction continues. An example of
a byte read, followed by a byte write:
S Addr Rd [A] [Data] NA S Addr Wr [A] Data [A] P
となっており、一番初めのスレーブアドレス発行後に"Read"、
次のスレーブアドレス発行後には"Write"を出力しており、
弊社の仕様と異なっています。
I2C_M_REV_DIR_ADDR フラグを使えば、 Read/Write フラグを切り替える
ことができるようですが・・・
> レジスタアドレスの送信(指定)はどこでしているのでしょうか?
下記のi2ctest_attach() の コメント//送信
以下のところでおこなっています。
(テストがうまくいったら、
この送受信テスト箇所は切り離す予定です。)
0xE1がレジスタアドレスで、0x23が書き込むデータです。
static int
i2ctest_attach(struct i2c_adapter *adap)
{
int ret;
char tx[2];
char rx[2];
DEBUG_FUNC();
printk("i2ctest_attach is called\n");
ret = i2c_probe(adap, &addr_data, &i2ctest_detect_client);
printk("i2c_probe=%d\n", ret);
// 送信テスト
tx[0] = 0xE1; //レジスタアドレス
tx[1] = 0x23; //書き込むデータ
i2ctest_TxData(tx, 2);
// 受信テスト
rx[0] = 0xE1; //レジスタアドレス
i2ctest_RxData(rx, 1);
printk("rx=%x\n", rx[0]);
printk("rx=%x\n", rx[1]);
return ret;
}
以上
----- Original Message -----
From: "日本電子システムテクノロジー/高木" <email@hidden>
To: "Armadillo series general discussion list"
<email@hidden>
Sent: Friday, January 23, 2009 10:09 AM
Subject: [Armadillo:03947] Re: armadillo-500 sysfs経由でI2Cドライバ制御
> お世話になっています。
> 高木です。
>
>
>> 木原です。
>> お世話になっています。
>> 早々のご返信ありがとうございます。
>>
>>> 通信の操作はターゲットとしているデバイスによって違う可能性があります。
>>> デバイスのマニュアルを確認してください。
>>
>> | START | スレーブアドレス | R/W = 1 | ACK | Data(n) | Data(n+1) |
>> ・・・・
>>
>> なので、アクセスしたいアドレスを送信してやれば、デバイスから
>> データがおくられてくるはずなのですが・・。
>>
>
> レジスタアドレスの送信(指定)はどこでしているのでしょうか?
>
> スレーブアドレスはI2Cデバイスが持つアドレスなので
> 別途アクセスしたいレジスタアドレスの指定が必要かと思います。
>
>
> ちなみに私がターゲットにしたデバイスでは次の操作になっています。
>
> Read Phase1(レジスタアドレス指定)
> START | スレーブアドレス | W=0 | ACK | レジスタアドレス | ACK | STOP
>
> Read Phase2(データRead)
> START | スレーブアドレス | R=1 | ACK | Data | ACK | STOP
>
>
>>>
>>> ちなみに私が扱ったデバイスではまず、アクセスしたいアドレスだけ送ります。
>>> この時はflag=0でi2c_transferを実行。
>>>
>>> 次にflag=I2C_M_RDとしてi2c_transferを実行することで
>>> buf[0]にデータが格納されました。
>>
>> ご教示いただいた手法でやってみましたが、期待した値はかえってきませんでし
>> た。
>>
>> そこで、下記に示したi2ctest_RxData()で受信テストを行ったところ、
>>
>> msgs[0].buf[0] ・・・ 0xff
>> msgs[0].buf[1]・・・ 0x1e
>> msgs[1].buf[0]・・・ 0xe1
>> msgs[1].buf[1]・・・ 0x23
>>
>> のようになっていることがわかりました。
>> msgs[1].buf[1]にわたしが期待するデータ(レジスタに書き込んだ値)が入って
>> いました。
>> なにゆえにmsgs[1]のbufにはいっているのか(^^; ?
>
> 以下のプログラムではmsgs[1].bufが初期化されていないのではないでしょうか?
> また、i2c_transferの最後の引数が1なのでmsgsの要素数は1で処理されていますので
>
> msgs[1]は何もされていないと思います。
>
>> 最初にダミーリードをおこなわないといけないということなのでしょうか?
>> 明日またトライしてみます。
>
> i2c_transfer関数でダミーリードの処理はされています。
>
> i2c_transferの実体のコードを読むとどのように処理されているかが判るので
> 一度確認してみてはいかがでしょうか。
>
> i2c_transferの実体はdrivers/i2c/busses/i2c-armadillo5x0.cの
> i2c_armadillo5x0_xferです。
>
>> int
>> i2ctest_RxData(char *rxData, int length)
>> {
>> int ret;
>> u8 buf[2];
>> struct i2c_msg msgs[2];
>>
>> msgs[0].addr = test_i2c_client.addr;
>> msgs[0].flags = I2C_M_RD;
>> msgs[0].len = 1;
>> msgs[0].buf = rxData;
>>
>> down(&mutex);
>> ret = i2c_transfer(test_i2c_client.adapter, msgs, 1);
>>
>> printk("RxData msgs[0].buf[0]=%x\n", msgs[0].buf[0]);
>> printk("RxData msgs[0].buf[1]=%x\n", msgs[0].buf[1]);
>> printk("RxData msgs[1].buf[0]=%x\n", msgs[1].buf[0]);
>> printk("RxData msgs[1].buf[1]=%x\n", msgs[1].buf[1]);
>>
>> if(ret == 1){
>> printk("RxData succedded!!!\n");
>> }else if (ret >= 0){
>> ret = -1;
>> printk("RxData failed!!!\n");
>> }
>> up(&mutex);
>>
>> return ret;
>> }
>>
>>
>> 以上
>>
>>
>>>
>>>
>>> ■転送
>>> static int XXX_i2c_write(struct i2c_client *c, unsigned char addr,
>>> unsigned char value)
>>> {
>>> struct i2c_msg msg[2];
>>> char buf[2];
>>> int ret;
>>>
>>> buf[0] = addr;
>>> buf[1] = value;
>>>
>>> msg[0].addr = c->addr;
>>> msg[0].len = 2;
>>> msg[0].buf = buf;
>>> msg[0].flags = 0;
>>>
>>> ret = i2c_transfer(c->adapter, msg, 1);
>>> if (ret >= 0)
>>> {
>>> return 0;
>>> }
>>>
>>> return ret;
>>> }
>>>
>>> ■受信
>>> static int XXX_i2c_read(struct i2c_client *c, unsigned char addr)
>>> {
>>> struct i2c_msg msg[2];
>>> char buf[2];
>>> int ret;
>>>
>>> buf[0] = addr;
>>>
>>> msg[0].addr = c->addr;
>>> msg[0].len = 1;
>>> msg[0].buf = buf;
>>> msg[0].flags = 0;
>>> ret = i2c_transfer(c->adapter, &msg[0], 1);
>>> if (ret >= 0)
>>> {
>>> }
>>> else
>>> {
>>> return ret;
>>> }
>>>
>>> msg[1].addr = c->addr;
>>> msg[1].len = 1;
>>> msg[1].buf = buf;
>>> msg[1].flags = I2C_M_RD;
>>>
>>> ret = i2c_transfer(c->adapter, &msg[1], 1);
>>> if (ret >= 0)
>>> {
>>> return buf[0];
>>> }
>>>
>>> return ret;
>>>
>>> }
>>>
>>>
>>>> いつもお世話になっております。
>>>> 山本です。
>>>>
>>>>> i2c_msg構造体のメンバflagsですが、
>>>>> i2c.hのi2c_msg構造体のコメントを読んだところ、どれにも該当
>>>>> しないので0としました。
>>>>
>>>> 送信時は0でよいですが、受信時は「I2C_M_RD」を使用するようです。
>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> armadillo mailing list
>>>> email@hidden
>>>> http://lists.atmark-techno.com/cgi-bin/mailman/listinfo/armadillo
>>>>
>>>>
>>>
>>>
>>> _______________________________________________
>>> armadillo mailing list
>>> email@hidden
>>> http://lists.atmark-techno.com/cgi-bin/mailman/listinfo/armadillo
>>
>> _______________________________________________
>> armadillo mailing list
>> email@hidden
>> http://lists.atmark-techno.com/cgi-bin/mailman/listinfo/armadillo
>>
>>
>
>
> _______________________________________________
> armadillo mailing list
> email@hidden
> http://lists.atmark-techno.com/cgi-bin/mailman/listinfo/armadillo
armadillo メーリングリストの案内