Ishimotoさん
<質問> つまりI2Cは完成はしているけど、我々の使い方が間違えているという意味ですね
<回答> いや、現在のGR-PEACH用I2Cライブラリーには間違いなくBugがあります(断言)
少し調べた内容を途中報告します。
先ずは、I2Cラインへの書き込みだけで済めば動作しそうです。少なくてもLCDで下記のサンプルプログラムが動きました。
秋月のキャラクタLCD/AQM0802を接続して動作確認しました(mbed-srcはrevision427(12月6日21:04JST最新))。
[Repository '/users/kenjiArai/code/GR-PEACH_i2C_LCD/' not found]
しかしI2Cラインを読み込もうとすると問題があります。
例えば、センサーデータの読み込みのような動作は問題があります(少なくても前述のGyro/L3GD20は動いていません)。
0x0bのデバイスアドレスでACKが返り、0x0fでIDが格納されているアドレスを設定して、次の読み出しで0x0fのレジスタを読みに行ってますがGR-PEACHがSTOP信号を出して自ら通信を終わりにしています(と解釈できます)
に関しては、やはり下記に問題があります。読み込み部分です。
\mbed-src\targets\hal\TRAGET_RZ_A1H\TAGET_MBED_MBRZA1H\i2c_api.c
int i2c_read(i2c_t *obj, int address, char *data, int length, int stop) {
int count = 0;
int status;
int value;
volatile uint32_t work_reg = 0;
// DELETE PART OF LINES
/* wati RDRF */
i2c_wait_RDRF(obj);
/* check ACK/NACK */
if ((REG(SR2.UINT32) & (1 << 4) == 1)) {
/* Slave sends NACK */
i2c_stop(obj);
return I2C_ERROR_NO_SLAVE;
}
// ???????????????????? length == 1?
// Read in all except last byte
if (length > 1) {
for (count = 0; count < (length - 1); count++) {
if (count == (length - 2)) {
value = i2c_do_read(obj, 1);
} else if ((length >= 3) && (count == (length - 3))) {
value = i2c_do_read(obj, 2);
} else {
value = i2c_do_read(obj, 0);
}
status = i2c_status(obj);
if (status & 0x10) {
i2c_stop(obj);
return count;
}
data[count] = (char) value;
}
}
// read in last byte
i2c_wait_RDRF(obj);
/* RIICnSR2.STOP = 0 */
REG(SR2.UINT32) &= ~(1 << 3);
// DELETE PART OF LINES
return length;
}
I2CはSPIに比べて格段に難易度が高いライブラリーだと思います。
私のGyroライブラリーが動かないのは、上記length == 1の取り扱いです。元のプログラムではクロックが発生しないで、そのまま何も行われていません。
下記のようにすると、少なくともコンストラクタ宣言部分の初期化ルーチンを無事通過をします(チップが認識され初期化完了)。
しかし、main()に制御が移った後もまだ問題があり、途中で止まってしまいます。
日本酒を飲みながらのDebugではここまでが限界です。
if ((REG(SR2.UINT32) & (1 << 4) == 1)) {
/* Slave sends NACK */
i2c_stop(obj);
return I2C_ERROR_NO_SLAVE;
}
if (length == 1) { // need clock output
if (obj->dummy) {
volatile int dummy = REG(DRR.UINT32);
obj->dummy = 0;
}
} else if (length > 1) {
for (count = 0; count < (length - 1); count++) {
if (count == (length - 2)) {
value = i2c_do_read(obj, 1);
} else if ((length >= 3) && (count == (length - 3))) {
value = i2c_do_read(obj, 2);
} else {
value = i2c_do_read(obj, 0);
}
GR-PEACHのI2C(master)が使用できるようになりました。
ご自身のプロジェクトの mbed-src を右クリックして update を選択すると、使用可能になります。
以下の端子に対応しています。
D14とI2C_SDAはP1_3の別名です。
D15とI2C_SCLはP1_2の別名です。