MacからI2C制御
MacからGPIO制御の続編。今回は、データシートの説明がたくさんあって長いです。ご勘弁を。
用いたデバイスおよびソフトウェア
USB to I2Cボード
前回と同じボード
I2Cの対象
光センサーを使う。I2Cアドレスはここから、0x29とわかる。
シリアル通信用ソフトウェア
前回と同じCooltermを利用。
SC18IM700(USB to I2C chip)を読み解く
データシートを理解。
USB経由で(Macから)送るコマンド
- 0x53 (I2C start)
- 0x50 (I2C stop)
- 0x52 (Read internal register)
を使う。
I2Cの状態をInternal Registerから取得する
Registerを読むコマンドのフォーマット
Register一覧
I2Cの状態は0x0A(I2CStat)から読む。
正常の場合は0xF0、異常(NACK)の場合は0xF1となる。
よって、HEX表記で
52 0A 50 (Read internal register('R')+Register value+Stop('P'))
をMacからこのボードに送ると、I2Cの状態を取得できる。
I2Cアドレス
光センサーのI2Cアドレスは0x29(7Bit表記で0101001)。I2Cでのデータ書き込みは'0'、データ読み込みは'1'。これらをI2Cアドレスの最後に加える。データ上ではHEX表記で、
- Write: 52 (01010010)
- Read: 53 (01010011)
となる。
デバイスにコマンドを送ってレスポンスを得る(Write & Read)
例えば、今回のケースでは、HEX表記で
53 52 01 00 53 53 01 50 ('S'+Write address+Length+Data+'S'+Read address+Length+'P')
とすると、1バイトのデータ'00'を送って(Write)、1バイトのデータを読み込み(Read)を行うことになる。こんな感じ。
データ'00'が読み込んだデータ。ここでInternal Registerを読んでみると
'F0'という正常値がもどってきている。
ここで接続されていないI2Cアドレス(例えば7bit表記で0x03)に対して、おなじことをやってみる。(この場合は、Write Addressが0x06、Read Addressが0x07となる。)
応答なし。このときのInternal Registerを読んでみると
'F1'というNACKがもどってきている。接続されていないI2Cアドレスなので期待値どおり。
デバイスへコマンドを送る(Writeのみ行う)
あとで使うのでここに書いておく。
例えば2バイトを書き込む場合、HEX表記で
53 52 02 xx yy 50 ('S'+Write address+Length+1st Data(xx)+2nd Data(yy)+'P')
となる。
光センサーを読み解く
搭載されているTSL2561のデータシートを理解。
コマンド
CMD bitは'1'、ADDRESSは次の表に従い、その他は'0'とする。
今回は
- Control (0x80 (= 1000xxxx | 0h))
- DATA0LOW (0x8C (= 1000xxxx | Ch))
- DATA0HIGH (0x8D (= 1000xxxx | Dh))
- DATA1LOW (0x8E (= 1000xxxx | Dh))
- DATA1HIGH (0x8F (= 1000xxxx | Eh))
を使う。
コマンドフォーマット
Start Condition('S')、Stop Condition('P')、長さ(Byte Count)は、SC18IM700の制御でカバーされている様子。Acknowledgeも同様だろう。
Control(0x80)
0x03書き込みでデバイススタート(Power Up)、0x00(Power Down)でストップとなる。
Data0LOW(0x8C), DATA0HIGH(0x8D), DATA1LOW(0x8E), DATA1HIGH(0x8F)
センサーデータの読み込み。正確なデータ算出ための変換式は省略(データシート参照)。
実験
センサーON
上述(SC18IM700およびTLS2561のデータシート読み解き)からHEX表記で
53 52 02 80 03 50 ('S'+Write address+Length+Control+Power Up+'P')
となる。
応答なしだが、問題なしと思われる。
データ取得
Data0LOW(0x8C)を読み込むにはHEX表記で
53 52 01 8C 53 53 01 50 ('S'+Write address+Length+Data0LOW+'S'+Read address+Length+'P')
となる。
取得したデータは'4A'。引き続き他のデータ(0x8D,0x8E,0x8F)を取得する。
Data0の値が0x024A、Data1の値が0x0058となる。
センサーの上に紙をおいてみた。
ここで同じようにセンサー値を読み取ると、
"A6 00 23 00"となり、Data0の値が0x00A6、Data1の値が0x0023となる。紙を置く前の値より小さい(当たり前)。
センサーOFF
ControlでPower Down、HEX表記で
53 52 02 80 00 50 ('S'+Write address+Length+Control+Power Down+'P')
を送る。
応答なしだが、問題なしと思われる。この後、データを取得してみたが、
データは'00'であった。動いていない。