I2Cメモリの連続アクセスと個別アクセスの問題に遭遇した

STM32を使った測定器開発案件で、i2Cデバイスで2つのメモリ領域を持つデバイスの対応で嵌った。I2Cで用いるHAL層は以下の関数なのだが、領域全体をアクセスする場合と個別をアクセスする場合とでズレるのだ。ちなみに個別アクセスした場合には正しくアクセスできるが、連続アクセスした場合には1番地ズレた形でアクセスされて、最終領域に先頭データが読み込まれた。

HAL_StatusTypeDef HAL_I2C_Mem_Read(I2C_HandleTypeDef *hi2c, uint16_t DevAddress, uint16_t MemAddress, uint16_t MemAddSize, uint8_t *pData, uint16_t Size, uint32_t Timeout)

そう、HAL層に違いはないのだ。

この事例では0x50(0xA0)と0x51(0xA2)のI2Cアドレスを持ち、それぞれに256バイトの空間を持つデバイスでした。以下のAPIを変えて実行してみると結果が異なった。

HAL_I2C_Mem_Read(&hi2c1, 0xA0, 0, 0x100, BUF, 256, 100)
1番地から読み出されて最後に0番地の内容が得られる

for(i=0;i<256;i++){
HAL_I2C_Mem_Read(&hi2c1, 0xA0, i, 1, &BUF[i], 1 , 100)
}
正しく読みだされる

CubeMXのバージョン違いを確認してHAL層のコードとしては違いはなかった。
i2Cの仕様として、メモリデバイスとそうでないものをMemAddSizeにて処理を分けている。今回のデバイスはどうも、メモリデバイスではあるもののそのプロトコルの実装に問題があるようだ。

I2Cの評価用ツールをお客様がお持ちだったのでその内容と検証して後者の実装で
逐一アドレス指定をする形での実装を行った。デバイスの検証は必要なステップだと改めて感じた。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください