概要
esp-idfを用いてI2C通信しようとしたところかなり時間を食ったので、その備忘録です。
追記
I2Cの仕様上当たり前の話でした。
自分への戒めのため残しておきます。
環境
- framework-espidf 3.40200.210118 (4.2.0)
- tool-cmake 3.16.4
- tool-esptoolpy 1.30000.201119 (3.0.0)
- tool-idf 1.0.1
- tool-mconf 1.4060000.20190628 (406.0.0)
- tool-ninja 1.9.0
- toolchain-esp32ulp 1.22851.191205 (2.28.51)
- toolchain-xtensa32 2.80400.210211 (8.4.0)
- ESP32 (240MHz, 320KB RAM, 4MB Flash)
問題
スレーブのレジスタアドレスを指定したreadのやり方が
公式マニュアルに無い。
解決策
int8_t i2c_read_reg(uint8_t device_address, uint8_t register_address, uint8_t *data, uint8_t size)
{
i2c_cmd_handle_t cmd_handle = i2c_cmd_link_create();
i2c_master_start(cmd_handle);
i2c_master_write_byte(cmd_handle,
(device_address << 1) | I2C_MASTER_WRITE,
true);
/* readするレジスタアドレスをwriteするため追加。 */
i2c_master_write_byte(cmd_handle, register_address, true);
/* これも追加 */
i2c_master_start(cmd_handle);
i2c_master_write_byte(cmd_handle,
(CCS811_DEV_ADDR << 1) | I2C_MASTER_READ,
ENABLE_ACK_CHECK);
i2c_master_read(cmd_handle, data, size-1, true);
i2c_master_read_byte(cmd_handle, data+size-a, true);
i2c_master_stop(cmd_handle);
i2c_master_cmd_begin(I2C_NUM_0, cmd_handle, 10 / portTICK_PERIOD_MS);
i2c_cmd_link_delete(cmd_handle);
return 0;
}
エラーハンドリング等は適宜行ってください。
最後に
公式ではレジスタアドレスを指定しない方法のみしか記載されていないように見受けられました。単純にレジスタアドレスwrite行を追加するだけだとエラーになると思います。
Arduinoフレームワークの情報はそこそこあるのですが、ESP-IDFは少ないと思い投稿しました。間違い等あればコメントお願いします。