MacからI2C制御

# MacからI2C制御
[MacからGPIO制御](https://qiita.com/infinite1oop/items/444b2b963daceb550c26)の続編。今回は、データシートの説明がたくさんあって長いです。ご勘弁を。
## 用いたデバイスおよびソフトウェア
### USB to I2Cボード
前回と同じ[ボード](https://www.switch-science.com/catalog/6214/)
### I2Cの対象
[光センサー](https://www.switch-science.com/catalog/1174/)を使う。I2Cアドレスは[ここ](https://wiki.seeedstudio.com/Grove-Digital_Light_Sensor/)から、0x29とわかる。
### シリアル通信用ソフトウェア
前回と同じ[Coolterm](https://freeware.the-meiers.org/)を利用。

## SC18IM700(USB to I2C chip)を読み解く
[データシート](https://www.nxp.com/docs/en/data-sheet/SC18IM700.pdf)を理解。
### USB経由で(Macから)送るコマンド
![Command.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/389eb4e8-e38c-92c8-f723-8212fda467d0.png)
今回は、
- 0x53 (I2C start)
- 0x50 (I2C stop)
- 0x52 (Read internal register)
を使う。
### I2Cの状態をInternal Registerから取得する
Registerを読むコマンドのフォーマット
![Read Register.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/07dbc31e-4225-7529-f405-e7e495a06180.png)
Register一覧
![Register List.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/51041c25-102a-e743-e9fe-e18404388323.png)
I2Cの状態は0x0A(I2CStat)から読む。
![I2CStat.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/9af757dc-64c3-13d0-1f0b-6ec5b77d8b09.png)
正常の場合は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）
![I2Creadafterwrite1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/f1d7bc46-a87b-9818-7fa1-fdb2c8fa8a2b.png)
![I2Cereadafterwrite2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/f7636885-31a8-5e66-5ded-3a647606dc2e.png)
例えば、今回のケースでは、HEX表記で
　53 52 01 00 53 53 01 50  ('S'+Write address+Length+Data+'S'+Read address+Length+'P')
とすると、１バイトのデータ'00'を送って(Write)、１バイトのデータを読み込み(Read)を行うことになる。こんな感じ。
![DeviceSearchOK1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/7877f5eb-7958-2ad1-d6d0-ec09a1554082.png)
データ'00'が読み込んだデータ。ここでInternal Registerを読んでみると
![DeviceSearchOK2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/3e27e506-d936-1cee-106d-7bc01b1714be.png)
'F0'という正常値がもどってきている。
ここで接続されていないI2Cアドレス(例えば7bit表記で0x03)に対して、おなじことをやってみる。（この場合は、Write Addressが0x06、Read Addressが0x07となる。）
![DeviceSearchNG1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/9fbb4318-8469-241c-c865-d69ea17bd66b.png)
応答なし。このときのInternal Registerを読んでみると
![DeviceSearchNG2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/9a0b8d14-1cdc-842c-facd-49b741487cc6.png)
'F1'というNACKがもどってきている。接続されていないI2Cアドレスなので期待値どおり。

### デバイスへコマンドを送る（Writeのみ行う）
あとで使うのでここに書いておく。
![I2Cwrite1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/158dbca9-7959-86e9-5c43-b3e8798bfcc5.png)
![I2Cwrite2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/b88b4b1f-ac34-a1b1-de52-7b342321ddd6.png)
例えば２バイトを書き込む場合、HEX表記で
　53 52 02 xx yy 50  ('S'+Write address+Length+1st Data(xx)+2nd Data(yy)+'P')
となる。

## 光センサーを読み解く
搭載されているTSL2561の[データシート](https://raw.githubusercontent.com/SeeedDocument/Grove-Digital_Light_Sensor/master/res/TSL2561T.pdf)を理解。

### コマンド
![TSL2561command.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/9c5c4a7d-4407-f6c9-0423-06d407f53d3f.png)
CMD bitは'1'、ADDRESSは次の表に従い、その他は'0'とする。
![TSL2561register.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/41ecd522-0575-f179-f0e0-14e36ae65b6d.png)
今回は
- Control (0x80 (= 1000xxxx | 0h))
- DATA0LOW　(0x8C (= 1000xxxx | Ch))
- DATA0HIGH　(0x8D (= 1000xxxx | Dh))
- DATA1LOW　(0x8E (= 1000xxxx | Dh))
- DATA1HIGH　(0x8F (= 1000xxxx | Eh))
を使う。

### コマンドフォーマット
![TSL2561write&read.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/543d54d1-dc1d-c666-1a13-a59be33d5ab1.png)
Start Condition('S')、Stop Condition('P')、長さ(Byte Count)は、SC18IM700の制御でカバーされている様子。Acknowledgeも同様だろう。

### Control(0x80)
![TSL2561control(start&end).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/fde04cf4-24a3-826b-55df-a0c62cefc275.png)
0x03書き込みでデバイススタート(Power Up)、0x00(Power Down)でストップとなる。

### Data0LOW(0x8C), DATA0HIGH(0x8D), DATA1LOW(0x8E), DATA1HIGH(0x8F)
![TSL2561data.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/a77b7edf-6c71-cd7d-c384-c4b9df19669c.png)
センサーデータの読み込み。正確なデータ算出ための変換式は省略（データシート参照）。

## 実験
### センサーON
上述（SC18IM700およびTLS2561のデータシート読み解き）からHEX表記で
　53 52 02 80 03 50  ('S'+Write address+Length+Control+Power Up+'P')
となる。
![Start(Up).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/077eadb5-c390-3c4b-f541-07cc894142dc.png)
応答なしだが、問題なしと思われる。
### データ取得
左側が光センサー、右側がUSB-to-I2Cボード。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/1ade9858-871e-56d1-1eff-3c89456dacc6.png", width=70%>

Data0LOW(0x8C)を読み込むにはHEX表記で
　53 52 01 8C 53 53 01 50  ('S'+Write address+Length+Data0LOW+'S'+Read address+Length+'P')
となる。
![1stData.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/76d285e0-25f0-5aeb-7d6a-2ad93712e4d7.png)
取得したデータは'4A'。引き続き他のデータ(0x8D,0x8E,0x8F)を取得する。
![AllData.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/b0e2bb0c-26ff-95e6-ec40-7fc192e35a9f.png)
Data0の値が0x024A、Data1の値が0x0058となる。

センサーの上に紙をおいてみた。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/3e5a4a3d-a9d0-a942-6b55-96e81c707209.png", width=70%>
ここで同じようにセンサー値を読み取ると、
![DataComparison.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/403b301f-f448-2b43-6bfe-095a4a2ef701.png)
"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')
を送る。
![End(Down).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/2f0b115b-a69a-a2cd-1f88-4fbaccbbc2d0.png)
応答なしだが、問題なしと思われる。この後、データを取得してみたが、
![NoData(afterDown).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634816/e7304c9e-cd84-e736-a253-2762f6edef94.png)
データは'00'であった。動いていない。

## 参考
[製造元のソースコード](https://github.com/meerstern/USBSerial_I2C_Converter/blob/master/SampleTeratermMacro/I2C_Dev_Search/I2C_search.ttl)