ArduinoでI2Cをいじって遊んでいたところ、そもそも最初のトリガーをEthernetかなにかで送らねばならず。
結局Raspberry Piにするか、もしくはArduino Yunにするのかと思っていたところ、いいものが見つかった。
サンハヤト: USB・I2C(SMBus)変換モジュール MM-CP2112B
CP2112というチップが載ったちんまいボードで、USBからI2C 1本とGPIO 8本が使える素敵な子。
しかもFreeBSDはCP2112のドライバを標準で積んでいて、kldloadするだけ。
買おうと思ったら、なぜか押し入れから発掘されたので、早速試してみた。(いつ買ったんだろうね??)
i2cデバイスは /dev/iic0
とかとして出現する。
制御には /usr/sbin/i2c
コマンドが用意されている。(man i2c(8))
試してみよう。
# kldload cp2112 # kldload iic # <ここでデバイスを挿す> # dmesg ... ugen0.6:at usbus0 cp2112hid0 on uhub0 cp2112hid0: on usbus0 cp2112hid0: part number 0x0c, version 0x03 gpio0: on cp2112hid0 gpiobus0: on gpio0 gpioc0: on gpio0 iichb0: on cp2112hid0 iicbus0: on iichb0 iichb0: unsolicited interrupt, ignored iic0: on iicbus0 # i2c -s -f /dev/iic0 Hardware may not support START/STOP scanning; trying less-reliable read method. Scanning I2C devices on /dev/iic0: 10
アドレス 0x10 のデバイスがあっさり検出された。
データを書いてみる。が、世の中そう甘くない。
# printf "\000" | i2c -a 0x10 -d w -c 1 ioctl: error sending start condition
ちなみに -a 0x10
はアドレス指定、-d w
は書き込みモード指定、-c 1
は書き込むバイト数、だ。
解決のヒントは先のスキャンで出ている Hardware may not support START/STOP scanning
というメッセージで、CP2112のドライバが一部のIOCTLに対応していないことにある。
manによるところの、
Some I2C bus hardware does not provide control over the individual start, repeat-start, and stop operations.
というやつに該当するのだ。(該当部分の処理)
なので、これもmanの通りに tr
モードを指定すればいい。
# printf "\000" | i2c -a 0x10 -d w -m tr -w 0 -c 1
これで成功。readも似たようなものなので、やりたい人はmanを読んでほしい。
※アドレスを間違えると i2c: ioctl(I2CRDWR) failed: No such file or directory
と言われる。
FileでもDirectoryでも無いよ!と叫びたいが、エラーコードは ENOENT なので、メッセージが悪いと言えよう。
ちなみに。
CP2112さんを引っこ抜くと、panicする。とても辛い。
※これはVMware Fusionでの実験結果。実機でも同様。
本稿を書くにあたって、Vadim Zaigrin氏の Working with I2C in FreeBSD on Raspberry Pi を参考にさせてもらった。
実はこの方と同じ原因(ドライバが一部のIOCTLに非対応) なのだが、割と最近(May 2019)になってtr
モードが追加されて、標準ツールでも使えるようになっていた。
もちろん、依然としてC言語で制御もできる。
i2cコマンドの実装や、Vadim Zaigrin氏の記事を参考にしてほしい。
Comments are closed.