Up "I2C bus lock up" 作成: 2021-04-10
更新: 2021-04-10


    J. Greene : 「I 2C リセットの追加」, AN-686, Analog Devices から引用:
    I2C バスは、多くのシステムで制御用に採用されている高集積度で堅牢なシリアル・バスです。
    システムの主な構成要素は、少なくとも1 個のマスターと1 個のスレーブです。

    通常状態では全てがうまく機能しますが、問題を発生するのは異常状態です。
    問題が発生した場合には、デバイスまたはシステムに関係した問題があるか、あるいは両方の組み合わせの問題があるか、という2 つの疑問が生じます。
    いずれにせよ、この場合何ができるかです。


    ハードウェア故障の発見は比較的容易です。
    機能しなくなり、電源のオン/オフにより問題が解決せず、ピンがハイ・レベルまたはロー・レベルに固定されるなどになります。

    システムに関係する問題はデバイス故障と見誤られることがあり、さらに悪いときには断続的に発生することもあります。
    このアプリケーション・ノートでは、バス故障状態の大部分を占める後者の領域について調べます。


    マスター(通常マイクロコントローラまたはゲート・アレイ)は、I2Cスレーブとの通信の途中に頻繁に割込まれ、リターンしたときに、バスのスタックに遭遇します。
    最初、これはデバイスの問題のように見えますが、違います。
    スレーブは、マスターから要求されたデータの残りを送信するために待ち続けます。

    問題は、割込みまたはリセットが発生したときにマスターが何処にいたかを忘れることです。
    プロセッサで外部リセットが発生すると、一般にこの状態が発生し、特にプロセッサが自分のステータスを待避できないときに発生します。

    この時点で、スレーブは次のビットをSDAラインに出力して (リセットでSCL ラインがロー・レベルにされるめ)、SCL 上の次のクロックを待ちます。
    もちろん、プロセッサはクロックを送信しないため、このスレーブは待ち続けることになります。
    スレーブがSDA ラインへ出力したビットが0 の場合、新しくウェイクアップしたプロセッサからは、バスがハングしたように見えます。
    バスは非動作モードにありますが、これはスレーブに起因するものではありません。
    これは、プロセッサが開始したメッセージを終了しないことによる,プロセッサの故障です。
    これから抜け出すリセットの発生は、このアプリケーション・ノートの範囲外です。

    何をすべきでしょうか。
    スレーブにこの最後のバイトの送信を終了させるか、または外部からリセットする必要があります。


    ソリューション1:問題時にクロックを発生
    1 つ目のソリューション (スレーブを終了させる) は、ソフトウェアで実現されるため、ハードウェアの追加は不要です。
    この方法は非常に効果的ですが、すべてのメーカのデバイスで常にバスのハングを解決できるとは限りらないことに注意してください (I2C ステート・マシンのデザインによりこのクロック発生法の有効性が決まります)。

    この方法は非常にシンプルです。
    バスを回復して制御をメイン・プログラムへ戻すのはマスターの仕事です。
    SDA ラインがロー・レベルに固定されているのをマスターが検出したとき、追加クロックを送信してストップ条件を発生させるだけで済みます。

    追加クロックは何個必要でしょうか。
    この個数は、スレーブから送信する残りのビット数に応じて変わります。
    最大は9 個です。
    この値はワーストケースの場合で、プロセッサがACK をスレーブへ送信した直後にリセットされる場合です。
    スレーブは、8 ビットのデータを送信して、ACK (またはバス回復時はNAK)を受信できるようになります。

    手順は次のようになります。
    1) マスタは、ロジック1 をSDA ラインに出力しようとします。
    2) マスタは依然ロジック0 を検出するため、SCL 上でクロック・パルスを発生します (1→0→1 の変化)
    3) マスタはSDA をチェックします。
    SDA = 0 の場合、ステップ2 へ進みます。
    SDA = 1 の場合、ステップ4 へ進みます。
    4) ストップ条件を発生させます。

    クリアされたSDA ラインは、実は1 であった次のビットがクリアされている可能性があるため、このプロセスを繰り返す必要がある可能性に注意してください。

    この追加クロック発生とストップ発生が他のペリフェラルへ与える影響について懸念があるかと思いますが、悪影響はありません。
    他のスレーブはアドレス指定されていないため、これに関与しないためです。
    メッセージを中断されたスレーブのみがクロックに応答します。

    この手順は、SDA = 0 のバス故障が発生した場合に、原因に無関係に、バスの回復を支援するシステム・コードで役立ちます。


    I2C バスについて簡単に説明します。
    I2C (Inter Integrated Circuit)バスは、Philips 社が開発して特許を取得しています。
    このバスを使うと、デバイスがオープン・ドレイン(またはオープン・コレクタ)の2 線式シリアル・バスを介して通信することができます。
    インターフェースはシンプルで、回路ボードに入出力するのは、シリアル・データ(SDA)とシリアル・クロック(SCL)の2 信号だけです。

    配線に関係した低速問題(文字どおりDC〜400 kB/s)のために、伝送線効果と整合の問題は生じません。
    制約要因は、バス容量であり400 pF に制限されています。

    次の用語が、I2C バスの規定に使用されています。

    マスタ―
    メッセージを開始するデバイスで、I2C バスの方向を決定します。
    マスターはクロック(SCL)も発生します(1 バイトあたり9 クロックで、8 個がデータ用、1 個がアクノリッジ用です)。

    スレーブ
    アドレスを持つデバイス。
    このアドレスがマスターからアドレス指定されます。

    スタート
    SCL ラインがハイ・レベルの間にSDA ラインがハイ・レベルからロー・レベルへ変化するバス条件。
    この条件がバスの最初の動作で、次に必ずアドレスが続きます。
    最下位(LSB)ビットにより、バス方向が指定されます。
    LSB = 1 で、バスが読み出し動作を行うことをスレーブに通知し、LSB = 0 で、指定したアドレスへ書き込み動作を行うことを通知します。

    ストップ
    スタートと反対の条件。
    この条件では、SCL ラインがハイ・レベルの間にSDA ラインがロー・レベルからハイ・レベルに変わります。
    この条件は、バイトを受信した後に送信を終了する唯一の方法です。

    バイト幅
    すべてのバイトは8 ビット幅で、例外はありません。

    メッセージ長
    技術的にはメッセージ最大長の制限はありません。
    最小メッセージは2 バイト(アドレス・バイトとデータ・バイト)で構成されます。

    ウエイト状態
    この条件はほとんど使用されませんが、理解しておく価値があります。
    SCL ラインがロー・レベルになった後に、デバイスはそのロー・レベルを続けることにより、ウエイト状態を指定することができます。
    このウエイト状態を使うと、低速デバイスが送信デバイスとの同期を失わないようにすることができます。
    例としては、多くのバイトをE2PROM へ書き込むときや、プロセッサが割込みを処理するためにスレーブからのデータを遅らせるときなどがあります。

    アクノリッジ
    “ACK”条件では、マスターがSCL ライン上に9 番目のクロック・パルスを発生し(各バイトに対して)、この間に受信デバイスがSDA ラインをロー・レベルにして、直前のバイトを受信したことを通知します。
    “NAK”は、追加送信するデータがないことをスレーブに通知するときに、マスターからのみ発生します。
    NAK をストップの前に使用して、マスターが通信を終了しようとしているときにスレーブが追加データをバスへ出力してしまうのを防止します。