通常は問題ないのだが開始条件発行後 ACK = 1 だった時、うまくいかない。
当然、停止条件発行後 開始条件を再発行するのだが開始条件再発行後の TEND が確認できない。
IIC2.ICCR2.BIT.IICRST でリセットしてもだめだ。
ハードウェアリセットしかない。
IIC の機能を使わず I/O で制御すると問題ないから、やはり何らかの不具合を持っているのだろう。
つまり、IIC コントローラに ACK = 1 を認識させてはだめだということか?
困った、腫れ物に触るような使い方をしなければならないらしい。
さて、次は SH7080 グループ ハードウェアマニュアルの図18.19 マスタ受信モードのフローチャート例 を見てみよう。
[1] SCL、SDAラインの状態判定
[2] マスタ送信モードに設定
[3] 開始条件発行
[4] 第1バイト(スレーブアドレス+R/W)の送信データの設定
[5] 1バイト送信終了待ち
[6] 指定したスレーブデバイスからのアクノリッジの判定
[1] TENDをクリア、マスタ受信モードに設定 その後TDREをクリア *
[2] 送信デバイスへのアクノリッジを設定 *
[3] ICDRRダミーリード *
[4] 1バイト受信完了待ち
[5] (最後の受信−1)判定
[6] 受信データをリード
[7] 最終バイトのアクノリッジ設定。 連続受信禁止(RCVD=1)に設定
[8] (最終バイト−1)の受信データをリード
[9] 最終バイトの受信完了待ち
[10] STOPフラグクリア
[11] 停止条件発行
[12] 停止条件生成待ち
[13] 最終バイトの受信データをリード
[14] RCVDをクリア
[15] スレーブ受信モードに設定
【注】 * [1]〜[3]の処理中に割り込みが入らないようにしてください。
【補足】 1バイト受信の場合は[1]の後、[2]〜[6]を省略し、[7]の処理へジャンプします。
[8]はICDRRダミーリードとなります。
これもスムーズに行かない気がする。
同様に、組み込んでみよう。
[1] while( IIC2.ICCR2.BIT.BBSY!=0 );
[2] IIC2.ICCR1.BIT.MST = 1;
IIC2.ICCR1.BIT.TRS = 1;
[3] IIC2.ICCR2.BIT.BBSY = 1;
IIC2.ICCR2.BIT.SCP = 0;
[4] IIC2.ICDRT = SlaveAddress | IIC_DATA_W;
[5] while ((IIC2.ICSR.BIT.TEND) == 0) ;
[6] if(IIC2.ICIER.BIT.ACKBR != 0)
return (1);
IIC2.ICDRT = (unsigned char)((Address>>8) & 0xff);
while ((IIC2.ICSR.BIT.TDRE) == 0) ;
IIC2.ICDRT = (unsigned char)(Address & 0xff);
while ((IIC2.ICSR.BIT.TDRE) == 0) ;
IIC2.ICCR1.BIT.TRS = 1;
IIC2.ICCR2.BIT.BBSY = 1;
IIC2.ICCR2.BIT.SCP = 0;
IIC2.ICDRT = SlaveAddress | IIC_DATA_R;
while ((IIC2.ICSR.BIT.TEND) == 0) ;
if(IIC2.ICIER.BIT.ACKBR != 0)
return (1);
[1] IIC2.ICSR.BIT.TEND = 0;
IIC2.ICCR1.BIT.TRS = 0;
IIC2.ICSR.BIT.TDRE = 0;
[7] IIC2.ICIER.BIT.ACKBT = 1;
IIC2.ICCR1.BIT.RCVD = 1;
[8] dummy = IIC2.ICDRR;
[9] while( (IIC2.ICSR.BIT.RDRF)==0 );
[10] IIC2.ICSR.BIT.STOP &= 0;
[11] IIC2.ICCR2.BIT.BBSY = 0;
IIC2.ICCR2.BIT.SCP = 0;
[12] while ((IIC2.ICSR.BIT.STOP)==0) ;
[13] data = IIC2.ICDRR;
[14] IIC2.ICCR1.BIT.RCVD = 0;
[15] IIC2.ICCR1.BIT.MST = 0;
IIC2.ICCR1.BIT.TRS = 0;
次第に自信がなくなってきたが、これでどうだ!
セコメントをする