ZephyrのI2C scannerサンプルを動かしてみる
はじめに
I2Cデバイスを使いたいので、手始めにZephyrのI2C scannerサンプルを動かしてみます。 ターゲットSoCはnRF52840です。
サンプルプロジェクトを確認
|> zephyr/samples/drivers/i2c_scanner
nRF52x系は、overlayする設定ファイルが用意されています。
|> overlay-nrf52.nrf
CONFIG_I2C_NRFX=y CONFIG_I2C_0=y
今回は、I2C1を使うので、I2C1に変更しておきます。
CONFIG_I2C_NRFX=y CONFIG_I2C_1=y
ソースコードをざっと確認します。
#include <errno.h> #include <zephyr.h> #include <misc/printk.h> #include <device.h> #include <i2c.h> #ifdef ARDUINO_I2C_LABEL #define I2C_DEV ARDUINO_I2C_LABEL #else #define I2C_DEV "I2C_1" #endif /** * @file This app scans I2C bus for any devices present */ void main(void) { struct device *i2c_dev; printk("Starting i2c scanner...\n"); i2c_dev = device_get_binding(I2C_DEV); if (!i2c_dev) { printk("I2C: Device driver not found.\n"); return; } for (u8_t i = 4; i <= 0x77; i++) { struct i2c_msg msgs[1]; u8_t dst; /* Send the address to read from */ msgs[0].buf = &dst; msgs[0].len = 0U; msgs[0].flags = I2C_MSG_WRITE | I2C_MSG_STOP; if (i2c_transfer(i2c_dev, &msgs[0], 1, i) == 0) { printk("0x%2x FOUND\n", i); } } }
全アドレス順番にreadしていって、値が読めたら、見つかった判定しています。 まぁこんなもんでしょう。
動作確認
動かしてみましょう。
Starting i2c scanner... [00:00:10.125,366] <err> i2c_nrfx_twi: Error 195952641 occurred for message 0 [00:00:22.562,713] <err> i2c_nrfx_twi: Error 195952641 occurred for message 0 [00:00:25.425,384] <err> i2c_nrfx_twi: Error 195952641 occurred for message 0 [00:00:29.490,722] <err> i2c_nrfx_twi: Error 195952641 occurred for message 0 [00:00:31.948,394] <err> i2c_nrfx_twi: Error 195952641 occurred for message 0 [00:00:33.013,885] <err> i2c_nrfx_twi: Error 195952641 occurred for message 0 ... [00:01:22.722,534] <err> i2c_nrfx_twi: Error 195952641 occurred for message 0 --- 18 messages dropped --- [00:01:22.725,891] <err> i2c_nrfx_twi: Error 195952641 occurred for message 0 ...
ありゃ、途中でRTTのメッセージがdropしていますね。 I2Cのアドレスを一通り舐めていて、デバイスが見つからなかった時のエラーが多すぎる、ということなのでしょう。
一応見落としがないようにするため、GDBを使って手動でループを回します。
... [00:00:14.157,165] <err> i2c_nrfx_twi: Error 195952641 occurred for message 0 0x51 FOUND [00:00:14.360,198] <err> i2c_nrfx_twi: Error 195952641 occurred for message 0 ... [00:00:16.207,885] <err> i2c_nrfx_twi: Error 195952641 occurred for message 0 0x64 FOUND [00:00:16.414,978] <err> i2c_nrfx_twi: Error 195952641 occurred for message 0 ...
今、繋がっているI2Cデバイスのアドレスは、0x51と0x64なので、OKですね!