はじめに:
I2C(Inter-Integrated Circuit)バスは2線式シリアル・インターフェースの一種で、もともとはフィリップス社(Phillips Corporation)がコンスーマ向け製品用に開発したものです。これは、あらゆるICプロセス(NMOS、CMOS、バイポーラ)で容易に実装可能で、シンプルなIC間通信ができる双方向バスです。シリアル・データ・ライン(SDA)、シリアル・クロック・ライン(SCL)、および共通グラウンドのみですべての通信を行うことで、接続が最小限に抑えられています。I2Cはこれまでに広く受け入れられ、I2CのサブセットであるSMBus(System Management Bus)のプロトタイプとしての役割も果たしてきました。
設計
I2C通信プロトコルはマスタ/スレーブ階層に従っており、マスタは、バスへのクロック出力、スレーブのアドレス指定、そしてスレーブ内のレジスタに対してデータの読出し/書込みを行うデバイスとして定義されます。スレーブは、その固有アドレスを通じてマスタから質問信号が送られた場合にのみ応答するデバイスです。したがって、スレーブ間でのアドレスの重複は、絶対に避ける必要があります。スレーブからデータ転送を開始することはありません。
I2Cバスは、2本の双方向ライン、つまりシリアル・データ・ライン(SDA)とシリアル・クロック・ライン(SCL)のみを使用します。I2C対応デバイスは、ラインをローにするオープン・コレクタ・ピンまたはオープン・ドレイン・ピンを使ってバスに接続します。データの転送がない場合、I2Cバスラインはハイでアイドル状態になります。これらのラインは受動的にハイになっています。
転送は、ラインをトグルする、つまり一旦ローにプルダウンした後でハイに戻すことによって行われます。各ビットは、クロックの立下がりエッジに同期します。標準データ転送速度は100kビット/秒で、高速モードでの転送速度は400kビット/秒です。
I2Cバスは、スレーブとマスタの両方について、複数のデバイスをサポートすることができます。唯一の制約は、多数のデバイスを追加する場合のバス容量(400pF)とアドレス空間(128個の固有アドレス)です。
データ転送プロトコル
I2Cのデータ・パケットは、スレーブ・アドレス、レジスタ番号、転送データで構成される8ビット・バイト単位にまとめられます。バスを介したデータの転送は、読出し動作または書込み動作のいずれかです。読出しプロトコルと書込みプロトコルは、開始および停止条件、反復開始ビット、アドレス・バイト、データ転送ビット、アクノレッジ/ノット・アクノレッジ・ビットといった一連のサブプロトコルに基づいて構築されます。
開始および停止条件
その名が示すように、開始条件は常に転送の開始時にマスタ・デバイスによって使用されます。これによりバス上のアイドル状態のスレーブ・デバイスをウェイクします。SDAラインは、SCLがハイのときに状態を2回変化させることができますが、これがそのうちの1回です。開始条件を示すために、SCLがハイのときにSDAラインがハイ状態からロー状態へ遷移します。
停止条件は開始条件と同じようにデータ転送の終了時に使われ、やはりマスタによって生成されます。これは転送の終了を示すもので、スレーブ・デバイスに対し、アイドル状態に戻ること、SDAラインを解放すること、そしてデータをこれ以上バスへ送らないようにすることを指示するコマンドです。これが、SCLがハイのときにSDAラインが状態を変える2回目の例です。SDAラインは、SCLがハイのときにロー状態からハイ状態へ遷移して停止条件を示します。
他のすべての条件下では、SDAラインは、SCLラインがローのときにのみ状態を変えます。
反復開始
開始条件はデータ転送中に繰り返すことができ、この場合、停止条件を使って先に転送を終了させる必要はありません。これは反復開始と呼ばれる特別なケースで、転送方向の変更、転送の繰り返し、複数のICの同期などに使われるほか、シリアル・メモリの制御にも使用できます。
アドレス・バイト
スレーブ・アドレスはMSBファーストの8ビット・バイト・フォーマットで送信され、最後のビットは、そのトランザクションがスレーブからの読出しなのかスレーブへの書込みなのかを示します。実際には、上位7ビットがスレーブ・アドレスで、8番目のビットがREAD/WRITE#コマンド・ビットとして機能します。 したがって、大抵の場合、固有アドレス128個分のアドレス空間があり、最大128個のスレーブのアドレスを指定できます。
例えば、マスタは開始条件の後で、バス上にあるスレーブ・デバイスの固有アドレスに対応するアドレス・バイトを送ります。バス上のデバイスは、それぞれが固有の固定アドレスまたはプログラムされたアドレスを持っています。I2Cバス上のスレーブは、最初に送られたバイトの上位7ビットを能動的にリスニングすることによって、開始コマンドに応答します。上位7ビットがスレーブ・デバイスのアドレスと一致している場合、そのスレーブは、続けてアドレス・バイトの8番目のビット(READ/WRITE#ビット)を読み出します。それ以外のすべてのスレーブ・デバイスは、そのトランザクションの残り部分を無視します。READ/WRITE#ビットがローの場合は、アドレス指定したスレーブ・デバイスにマスタがデータを書き込むことを示し、ハイの場合はスレーブ・デバイスからマスタがデータを読み出すことを示しています。対応するスレーブによってアドレス・バイトが読み出されると、スレーブはその転送に対するアクノレッジを返します。具体的には、隣接するクロック・ハイ・パルスの間SDAをローにして、送信されてきたREAD/WRITE#ビットに応じてスレーブ送信またはスレーブ受信かを判定して、アクノレッジ・ビットを送信します。
この時点以降は、停止ビットが送信されない限り、アドレスが指定されたスレーブが、全ての通信は自分に向けたものとみなします。
アクノレッジ・ビットとノット・アクノレッジ・ビット(ACK/NACK)
受信デバイスは、バイトが転送されるごとにフィードバックとしてアクノレッジ・ビットまたはノット・アクノレッジ・ビットを送信します。アクノレッジ・ビットは、SCLがハイの間にSDAラインをローに保持することによって受信側が生成し、受信側がSDAラインを受動的にハイのままにして何も応答しないときはノット・アクノレッジビットが生成されます。このことから、アドレス・バイトへの応答においては、アドレスが一致しなかったすべてのスレーブが、応答しないことによってノット・アクノレッジ・ビットを送っていると考えることができます。
ACKは、バイト(アドレスまたはデータ)の送受信が正常に行われたこと、引き続き次のバイト転送や停止条件または反復開始の送信を行えることを示すために使われます(図4)。NACKは、通常、データ転送のどこかでエラーが発生したことを示すために受信側によって使われます。これは、送信を直ちに終了したり、反復開始を送信して別の処理を行うよう、送信デバイスを促すために使用されます。
マスタも、スレーブから読み出したい転送データの最終バイトの後にスレーブにNACKを送信して、転送を停止するよう合図を送ります。
データ・ビット
データ・ビットは、実際の転送データがコード化され、8ビット・バイト・フォーマットで転送されます。これはMSBから始まり、各ビットはクロック信号(SCL)に同期されます。転送するバイト数に制限はありませんが、各バイトの転送後には、そのデータの受信デバイスが生成するアクノレッジが必要です。
ビット転送を行うには、クロックがハイのときにSDAライン上のデータが安定した状態でなければなりません。データ・ラインがハイまたはローへ遷移できるのは、クロック信号がローのときに限られます。したがって、受信側はSCLがハイの間にデータ・ライン上のデータ・ビットを読み出し、送信側はSCLがローの間に新しいデータ・ビットをそれぞれアサートします。
コマンド・バイト
スレーブの特定のレジスタとの間で書込みや読出しを行う場合、スレーブのアドレス指定後、マスタは、先ずレジスタ・アドレスを書き込んで特定のレジスタを指定する必要があります。このレジスタ・アドレスはデータ・バイトと見なせますが、混乱を避けるために、多くの場合はコマンド・バイトに分類されます。例については、図6と図7を参照してください。
デバイスへの書込み
図6に、送信マスタから7ビット・アドレスを持つ受信スレーブへの、アドレス指定とデータ書込みを示します。送信される最初のビットは、通信を開始するための開始ビットです。その後のクロック・パルスに合わせてアドレス・バイトが送られます。この時点では、バス上のすべてのスレーブ・デバイスが、アドレス・バイトの上位7ビットを構成するデバイス・アドレスをリスニングしています。アドレスが一致することを確認したスレーブ・デバイスは、最終ビット(READ/WRITE#ビット)までリスニングを続けて、マスタが求めているのがスレーブからの読出しなのかスレーブへの書込みなのかを判定します。それ以外のすべてのスレーブ・デバイスは、NACKを送信する(定義によれば何もしない)ことによってその後の通信を無視します。
アドレスを指定されたデバイスは、アドレスと書込みコマンドを認識すると、マスタへのフィードバックとして、該当アドレスを持つスレーブ・デバイスがバス上に存在しその後の通信を待っていることを知らせるアクノレッジ・ビット(ACK)を送信します。これを受けてマスタは、バイト・フォーマットでデータを送信することによってデータ転送を開始します。マスタがスレーブ・デバイスの特定レジスタに書込みを行う場合、そのマスタは、データを送信する前に、対応するコマンド・バイトを書き込みます。各バイトの転送毎に、スレーブはACKを送信して応答します。マスタは、すべてのデータの転送を完了すると、停止条件を送信して転送を終了します。
デバイスからの読出し
図7は、マスタがスレーブのアドレスを指定して、そこからデータを読み出す過程を示しています。転送もまたマスタにより開始条件を使って開始され、開始後はそれ以降のクロック・パルスに合わせてアドレスが転送されます。アドレスを指定されたデバイスは、READ/WRITEビットを読み出してアクノレッジ・ビットで応答することにより、転送のリスニングを続けます。スレーブがアクノレッジを送信すると、そのスレーブがSDAの制御を引き受けて、マスタにデータを送信します。転送された各バイトに対し、マスタはアクノレッジ・ビットを送ります。マスタがそれ以上データを受け取る必要がなくなると、必要な最後のバイトを受信した後にNACKを返し、バスの制御を再開して停止条件を送り、転送を終了します。
SDAラインの制御はマスタからスレーブに渡され、その後再びマスタに返されますが、SCLラインは常にマスタの制御下にあります。つまり、データのクロック・インとクロック・アウトは常にマスタによって行われます。
転送プロトコルの組み合わせ
読み出しプロトコルと書込みプロトコルを別の形で組み合わせれば、複雑なI2Cトランザクションを実行できます。マスタは、1つのI2Cトランザクションの中で、スレーブへの書込みを行った後で同じスレーブから読出しを行ったり、新しいアドレスを指定して別のスレーブ・デバイスとやり取りをしたりすることができます。データが書き込まれていたデバイスから今度はデータが読み出されるというように、データの転送方向が変わります。これはすべて反復開始ビットを使うことによって行います。
例えば、エネルギー・モニタであるLTC2946には、特定のレジスタからデータを出力するように要求することができます。これには、次のようなI2Cトランザクションが必要です。すなわち最初にLTC2946のアドレスを指定して、コマンド・バイト(読出し対象となる特定レジスタのアドレスを含むデータ・バイト)を送ります。さらに反復開始を行い、読出しビットをセットしてもう一度デバイス・アドレスを送ってから、データを読み出します。このトランザクションでは、最初にマスタがLTC2946への書込みを行ってデータを読み出したいレジスタを知らせ、その後にマスタがスレーブ・アドレス・バイトの読出しビットをセットして反復開始を行った時点で、データの転送方向が変わります。図8はLTC2946のデータシートから抜粋したもので、この一般的なプロトコルを示しています。
ここで、
- S = 開始ビット
- P = 停止ビット
- R = 読出しビット
- W\ = 書込みビット
- A = アクノレッジ
- A\ = ノット・アクノレッジ
LTC2946のレジスタへの書込み例を図9に示します。開始条件の後にデバイス・アドレスが送られ、その後にコマンド・バイトがスレーブに書き込まれます(READ/WRITE#ビットを通知)。スレーブがアクノレッジを返すと、そのスレーブにデータが書き込まれます。
同様に、マスタが2つの異なるスレーブへ書き込む場合の例を図10に示します。
ここで取り上げなかった項目
この他にも、クイック・コマンド、拡張アドレス・モード、アービトレーション、マルチマスター、クロック・ストレッチングなど、ここでは触れなかったI2Cプロトコルがあります。これらのトピックは、本稿における検討の対象外であり、I2CをサポートするLTCデバイスとの通信を開始する際に必要となることはありません。