一日中プログラミング。
I2CでシリアルEEPROMへの読み書きで開始アドレスが16の整数倍でないとデータが変な場所に記録されてしまう現象はEEPROMの仕様が原因だった。この現象、昨日は読み出し時に起こっていると思ったが、よく調べてみると書き込み時に既に変なアドレスに書き込まれていた。
起こったのは、例えばアドレス7に"abcdefghijklmnopq"という文字列を書き込むことを考える。

        abcdefghijklmn
|       :        |                |
0       7        15               31

この場合、

|       abcdefghijklmn            |
0       7        15               31

のようになると良いのだが、実際には

klmn    abcdefghij                |
0       7        15               31

のように、'k'以降がアドレスゼロから記録される。

改めてEEPROMのマニュアルをよく読んでみると、今使っている連続書き込み方式では1ワード(16バイト)単位でしか書き込みができないと書かれている。連続書き込み方式では、1バイト書き込むごとにメモリ内部でアドレスカウンタが自動的にインクリメントされ、これによって毎回アドレスを指定しなくても次々にデータを書き込んでいくことができる。ところが、このカウンタは4ビットのデータ幅しかないため、カウント値が15を超えると桁があふれて値がゼロに戻ってしまう。
別の書き込み方式にすればこれを回避することはできるが、このままでも今回の仕様には差し支えないので当面はそのままにしておく。
とにかくこれでEEPROMの読み書きがようやくできるようになった。先週中にはこれくらいは終わると思っていたのだが、割り込みの使い方や通信の仕様を変更せざるを得なくなったりで予想以上に時間をくった。ただ、デバッグのしにくい部分はこれであらかた終わったので、この後はそれほど引っかかることは無いだろう。