21. 2線式シリアル・インターフェース

21.1 機能

21.2 2線式シリアル・インターフェース・バスについて

2線式シリアル・インターフェース(TWI)は、マイクロコントローラーが使われる多くの用途に適した理想的なインターフェースです。 TWIのプロトコルでは、わずか二本の双方向バス・ライン、クロック(SCL)とデータ(SDA)、だけを使用して、128個までの異なるデバイスを接続するシステム設計が可能です。 外付けで必要なハードウェアはTWIバス・ラインそれぞれに接続する一本ずつのプルアップ抵抗だけです。 バスに接続されたデバイスは全て個々のアドレスをもち、バス競合を解決するしくみはTWIプロトコル内に実装されています。

Figure 21-1. TWIバスの接続

21.2.1 TWIに関する用語

下の表は、この章で頻繁に用いる用語の定義です。

Table 21-1. TWIの用語
用語 説明
マスター データ転送の開始と終了を行うデバイス。
マスターはSCLクロックの生成も行います。
スレーブ マスターによってアドレス指定されるデバイス
送信(デバイス) バス上にデータを送り出す(デバイス)
受信(デバイス) バス上からデータを受け取る(デバイス)

2線式インターフェースを有効にするためには、「消費電力を最小にするために」(p.40)の説明にあるPRTWIビットをゼロにしておく必要があります。

21.2.2 電気的接続

Figure 21-1に描かれているように、二本のバス・ラインはプルアップ抵抗を通して電源のプラス側に接続します。 TWI互換のデバイスのバス・ドライバは全て、オープン・ドレイン、あるいはオープン・コレクタ出力になっています。 この接続により、2線式インターフェースの動作に不可欠なワイアードAND機能が実装されています。 一つ以上のTWIデバイスがゼロを出力しているときに、バス・ラインがLow状態になります。 すべてのTWIデバイスがハイ・インピーダンス出力になっているとき、プルアップ抵抗がバスをHighに引き上げ、バス・ラインがHigh状態になります。 TWIバスに接続されるAVRデバイスは全て、バス操作を行う場合、必ず電源を供給されていなければなりません。

バスに接続できるデバイスの数の上限は、バスの容量成分の制限である400pFと、7ビットのスレーブ用アドレス空間によってのみ制限されます。 TWIの詳細な電気的特性の仕様については、「2線式シリアル・インターフェースの特性」(p.307)に記載されています。 バス・スピードが100kHz未満の場合に適用されるものと、400kHzまでの条件で適用される、二種類の異なる仕様があります。

21.3 データ転送とフレーム・フォーマット

21.3.1 ビットの転送

TWIバス上では、各データのビットはクロック・ライン上のパルスをともなって転送されます。 データ・ラインの電圧レベルはクロック・ラインがHighのときには安定していなければなりません。 唯一の例外はスタート・コンディション、ストップ・コンディションが発生する場合です。

Figure 21-2. 有効なデータ信号

21.3.2 スタート・コンディション、ストップ・コンディション

マスターがデータ転送の開始と終了を行います。 マスターがスタート・コンディションをバス上に発効するときが転送の開始であり、マスターがストップ・コンディションを発効するときが転送の終了です。 スタート・コンディションとストップ・コンディションの間の時間帯は、バスはビジー状態であるとみなされ、他のマスターはバスの制御権を取得しようとするべきではありません。 スタート・コンディションとストップ・コンディションの間に、新たなスタート・コンディションが発効される特別な場合があります。 これは、再スタート・コンディションといい、マスターがバスの制御権を放棄せずに、新たな転送を行おうとする場合に使われます。 再スタート・コンディションの直後から、次にストップ・コンディションが現れるまで、バスはビジー状態とみなされます。 これは、スタート・コンディション時の動作と同一であり、したがって、この章の以後の部分では「スタート・コンディション」と記載されている部分では、特に記載の無い場合、スタート・コンディションと再スタート・コンディションの両方についての説明とします。 下記の図のとおり、スタート・コンディションとストップ・コンディションはSCLラインがHighのときにSDAラインのレベルを変化させることにより伝達されます。

Figure 21-3. スタート・コンディション、再スタート・コンディション、ストップ・コンディション

21.3.3 アドレス・パケット・フォーマット

TWIバス上のアドレス・パケットはすべて9ビットの長さを持ち、7ビットのアドレス・ビット、1ビットのリード/ライト・コントロール、1ビットのアクノレッジ・ビットから成り立っています。 リード/ライト・ビットがセットされているときはリード動作が行われ、そうでない場合はライト動作が行われます。 スレーブ・デバイスがアドレス指定を受けたと認識した場合、SCLの第9サイクル(ACK)にSDAをLowにします。 アドレス指定を受けたスレーブがビジー状態であるか、他の理由によりマスターからの要求に応答できない場合、ACKクロック・サイクルでSDAラインをHighのままにしておきます。 その後、マスターはストップ・コンディションを送信するか、再スタート・コンディションを送信して、新しいデータ転送を開始します。 スレーブ・アドレスとリードまたはライト・ビットから成るアドレス・パケットをそれぞれ、SLA+R、SLA+Wとよびます。

アドレス・バイトでは、MSBから送信が行われます。スレーブ・アドレスは設計者により自由に値を割り当てることができますが、0000 000のアドレスは、ジェネラル・コールとして予約されています。

ジェネラル・コールが送信された場合、すべてのスレーブ・デバイスはACKサイクルでSDAラインをLowにして応答しなければなりません。 ジェネラル・コールは、システム上の複数のスレーブに同一のメッセージを送信しようとする場合に使います。 バス上にジェネラル・コールが送信され、それにライト・ビットが続いている場合、ジェネラル・コールに応答するよう設定されている全てのスレーブは、ACKサイクルでSDAラインをLowにします。

ライト・ビットをともなうジェネラル・コールに続いて送信されるデータ・パケットは、ジェネラル・コールに応答したスレーブ全てが受信します。 なお、ジェネラル・コール・アドレスにリード・ビットを続けて送信することには意味がありません。複数のスレーブが異なるデータの送信を開始するとバス競合が発生するからです。

1111 xxxの形式を持つアドレスは全て将来のための予約となっています。

Figure 21-4. アドレス・パケット・フォーマット

21.3.4 データ・パケット・フォーマット

TWIバス上で転送されるデータ・パケットは全て9ビットの長さを持ち、1バイトのデータ・バイトと1ビットのアクノレッジ・ビットが含まれています。 データ転送中は、マスターはクロック信号とスタート・コンディション、ストップ・コンディションを生成し、受信デバイスは受信に対するアクノレッジ(確認動作)を行う必要があります。 アクノレッジ(ACK)の発信は、受信デバイスが第9SCLサイクルにおいてSDAラインをLowに下げることにより行われます。 受信デバイスがSDAラインをHighのままにしている場合は、NACKが発信されたことになります。 受信デバイスが最後のバイトを受信したとき、あるいは、何らかの理由によりそれ以上のバイト・データを受けとることができない場合、最後のバイト・データを受信した後に、送信デバイスに対してNACKを発信して知らせる必要があります。 データ・バイトはMSBから先に送信されます。

Figure 21-5. データ・パケット・フォーマット

21.3.5 アドレス・パケットとデータ・パケットを組み合わせて転送する

データの転送は、基本的にスタート・コンディション、SLA+R/W、一つ以上のデータ・パケット、そしてストップ・コンディションで構成されています。 スタート・コンディションの直後にストップ・コンディションが続く、空のメッセージは不正な動作とみなされます。 SCLラインのワイアードAND接続によって、マスターとスレーブのハンド・シェーク動作を実装することができます。 スレーブはSCLラインをLowに下げて、SCL = Lowの時間を延長することができます。 マスターが設定しているクロック・スピードがスレーブにとって速すぎる場合や、スレーブがデータ転送とデータ転送の間で処理を行うための時間が必要な場合に、この動作を利用することができます。 スレーブによるSCLのLow期間の延長は、SCLのHigh期間の動作に影響しません。これは、マスターによって制御されるからです。 結果的に、スレーブはSCLのデューティー比を延長することによってTWIのデータ転送速度を下げることができます。

Figure 21-6に一般的によく用いられるデータ転送の例を示します。 なお、アプリケーション・ソフトウェアによるプロトコルの実装に応じて、SLA+R/Wとストップ・コンディションの間では複数のデータ・バイトが転送できます。

Figure 21-6. データ転送の例

21.4 マルチ・マスター・バス・システム、調停と同期

TWIプロトコルでは、バス・システム上に複数のマスターが存在することが可能です。 二つ以上のマスターが同時に転送を開始したとしても、データ転送が通常どおりに行われるように、特別な設計上の配慮がなされています。 マルチ・マスター・システムでは二つの問題が発生します。

バス・ラインのワイアードAND接続の利用によって、この二つの問題を解決します。 全てのマスターからくるシリアル・クロックはワイアードANDされることで、合成されたクロックのHigh状態の期間は、最も短いHigh期間をもつマスターのものと同じになります。 合成されたクロックのLow状態の期間は最も長いLow期間をもつマスターのものと同じになります。 全てのマスターはSCLラインの状態を監視しているので、合成されたSCLラインの信号がHighまたはLowになり次第、SCLのHighおよびLowのタイムアウト時間のカウントを開始します。

Figure 21-7. 複数のマスター間でのSCLの同期

全てのマスターが、データを出力してから絶えずSDAラインを監視することにより、バス調停が行われます。 SDAラインから読み取った値がマスターから出力した値と一致していない場合、そのマスターは調停によりバス権を得られなかったと判断します。 あるマスターが調停によりバス権を放棄させられる条件は、そのマスターがSDAにHighを出力している時に他のマスターがLowを出力している場合だけです。 バス調停で権利を放棄したマスターは即座にスレーブ・モードに移行し、バス権を得たマスターによってアドレス指定されているかどうかをチェックしなければなりません。 SDAラインはHighのままにしておく必要がありますが、バス権を得ることができなかったマスターは、その時点で出力していたデータ・パケットやアドレス・パケットの終了までクロック信号を生成することが容認されています。 バス調停動作は、マスターが一つだけになるまで続行され、この動作には多数のビットが消費される可能性があります。 複数のマスターが同一アドレスのスレーブを指定しようとしている場合、調停動作はデータ・パケットまで続くことになります。

Figure 21-8. 二つのマスター間での調停動作

なお、下記の場合における調停動作は許可されていません。

これらの不正な条件での調停動作が絶対に行われないように、ユーザー・ソフトウェアを設計する必要があります。 このことは、マルチ・マスターのシステムでは全てのデータ転送はSLA+R/Wとデータ・パケットからなる同一の構成を使用しなければならないということです。 別の言い方をすると、全てのデータ転送は同じ数のデータ・パケットを含んでいなければならず、そうしないと調停動作の結果が不定となってしまいます。

21.5 TWIモジュールの概要

Figure 21-9に示すとおり、TWIモジュールはいくつかのサブ・モジュールから成り立っています。 太線で描かれたレジスタは全てAVRデータ・バスからアクセス可能なものです。

Figure 21-9. TWIモジュールの概要

21.5.1 SCL、およびSDA端子

これらの端子はTWIバスとMCUシステムの他の部分とのインターフェースの役割をもっています。 出力ドライバには、TWIの仕様に準拠するためのスルーレートの制限が設けられています。 入力側にはスパイク・ノイズ抑制ユニットがあり、50nSよりも短いスパイク・ノイズを除去します。 なお、I/Oポートの章で説明されているように、AVRの外部接続端子の内蔵プルアップ抵抗を、SC、SDA端子に対応する各ポートの設定ビットによって有効にすることができます。 この内蔵ブルアップ抵抗を使うことで、外付けの抵抗が不要になる場合もあります。

21.5.2 ビット・レート生成ユニット

このユニットは、マスター・モード動作でのSCLの周期を制御します。 SCLの周期はTWIビットレート・レジスタ(TWBR)の設定値と、TWIステータス・レジスタ(TWSR)の分周比設定ビットによって設定します。 スレーブ動作では、ビットレートや分周比の設定は関係ありませんが、スレーブ・デバイスのCPUクロック周波数は少なくともSCLクロック周波数の16倍よりも大きな値でなければなりません。 なお、スレーブはSCLのLow期間を延長することでTWIバスのクロック周期の平均値を下げることができます。 SCLクロックの周波数は下記の式により計算されます。

SCL_frequency = \frac{CPU_Clock_frequency}{16 + 2*(TWBR)*(PrescalerValue}

注意: プルアップ抵抗の値はSCLの周波数とバス・ライン負荷のキャパシタンス成分に基づいた設計をする必要があります。プルアップ抵抗の値については、Table 28-5 (p.307)を参照してください。

21.5.3 バス・インターフェース・ユニット

このユニットには、データ・アドレスのシフト・レジスタ(TWDR)、スタート/ストップ制御、およびバス調停検出を行うハードウェアが含まれます。 TWDRレジスタには、送信するアドレスやデータ・バイトや受信したアドレスやデータ・バイトが格納されます。 8ビットのTWDRに加えて、バス・インターフェース・ユニットには送信または受信する(N)ACKビットを格納するレジスタがあります。 この(N)ACKビット・レジスタはアプリケーション・ソフトウェアから直接アクセスすることができません。 ただし、受信時にTWIコントロール・レジスタ(TWCR)を操作することによってセット/クリアすることができます。 送信モードでは、受信した(N)ACKビットの値は、TWSRレジスタの値によって判定できます。

スタート/ストップ制御回路の役割は、スタート・コンディション、再スタート・コンディションおよびストップ・コンディションの生成と検出です。 AVR MCUのスリープ・モードでは、スタート/ストップ制御回路がスタート・コンディション、ストップ・コンディションの検出を行うことができ、マスターによってアドレス指定を受けたときにスリープ・モードからMCUをウェークアップすることができます。

TWIモジュールがマスターとしてデータ転送を開始した場合、バス調停検出ハードウェアは転送状態を絶えず監視して、バス調停が発生したかどうか判定します。 TWIモジュールが調停によりバス権を失った場合、そのことがコントロール・ユニットに伝達されて適正な動作が行われ、適切なステータス・コードが生成されます。

21.5.4 アドレス・マッチ・ユニット

アドレス・マッチ・ユニットは、受信したアドレス・バイトがTWIアドレス・レジスタ(TWAR)に設定されている7ビットのアドレスと一致しているかどうかをチェックします。 TWARレジスタのTWIジェネラル・コール検出機能有効(TWGCE)ビットが1にセットされている場合は、全ての受信アドレス・ビットとジェネラル・コール・アドレスとの比較も行います。 アドレス・マッチが発生すると、コントロール・ユニットに伝達され、適正な動作が行われます。 アドレスに対するTWIモジュールのアクノレッジ動作は、TWCRレジスタの設定に応じて、する場合としない場合があります。

アドレス・マッチ・ユニットはAVR MCUがスリープ・モードにある場合でもアドレス比較を行うことができ、マスターからアドレス指定を受けた際にMCUをウェークアップすることが可能です。 スリープ中のTWIアドレス・マッチとCPUのウェークアップ中に他の割込み(例えば、INT0)が発生した場合、TWIは動作を中断して待機状態に戻ります。 この動作によって問題が発生する場合は、パワーダウン・モードに入る際にTWIアドレス・マッチだけが有効な割込みになっているように設定してください。

21.5.5 コントロール・ユニット

コントロール・ユニットはTWIバスを監視し、TWIコントロール・レジスタ(TWCR)の設定に応じた応答を行います。 アプリケーションが注意する必要のあるイベントがTWIバス上で発生した場合、TWI割込みフラグ(TWINT)がセットされます。 それにつづくクロック・サイクルで、TWIステータス・レジスタ(TWSR)が更新され、発生したイベントを特定するステータス・コードが格納されます。 TWSRレジスタは、TWI割込みフラグが発効(セット)された時点でのステータス情報のみを保存しています。 それ以外の時間では、TWSRレジスタには、特に相当するステータス情報が無いことを示すコードが格納されています。 TWINTフラグがセットされている間、SCLラインはLowのままになります。 この動作により、TWIのデータ転送の続行される前にアプリケーション・ソフトウェアが必要な処理を完了することができます。

TWINTフラグは、以下の状況でセットされます。

21.6 TWIの使い方

AVR TWIインターフェースは、バイト単位で動作し、割り込みによって使用するように設計されています。 割り込みは全てのバス・イベント、例えば、1バイト受信や、スタート・コンディションの転送の直後に発生します。 TWIインターフェースは割り込みを使って動作するので、アプリケーション・ソフトウェアは、TWIがバイト・データを転送している間、他の処理を行うことができます。 なお、TWCRレジスタのTWI割り込み有効(TWIE)ビットとSREGのグローバル割り込み有効ビットの設定によって、TWINTフラグによって割り込み要求を発生させるかどうかをアプリケーションが決定することができます。 TWIEビットがクリアされている場合、TWINTフラグをポーリング処理して、TWIバス上で行われている動作をアプリケーションが検出しなければなりません。

TWINTフラグが発効されると、TWIインターフェースは現在の動作を完了してアプリケーションによる応答を待ちます。 この場合、TWIステータス・レジスタ(TWSR)には、TWIバスの現在のステータスを示す値が保存されています。 アプリケーション・ソフトウェアは、TWCRレジスタとTWDRレジスタを操作することにより、次のTWIバス・サイクルでTWIインターフェースがどのような動作を行うかを決定することができます。

Figure 21-10は、アプリケーションがTWIのハードウェアとどのようなやりとりを行うことができるかを簡潔に示した例です。 この例では、マスターは1バイトのデータ・バイトをスレーブに送ろうとしています。 この図は非常に抽象的に描かれていますが、より詳しい説明が本章の後半にあります。 目的とする操作をどのように実装するか、についての簡潔なコーディング例も掲載されています。

Figure 21-10. 一般的な転送におけるアプリケーションとTWIインターフェースのやりとり

1. TWIの転送の最初の手順は、スタート・コンディションの送信から始まります。 これは、TWCRレジスタに特定の値を書き込むことによって行われ、TWIハードウェアにスタート・コンディションの送信を行うよう命令します。 具体的にどのような値を書き込むかについては後述しますが、ここで重要なのは、TWINTビットが書き込む値においてセットされていることです。 TWINTビットに1を書き込むことにより、同フラグをクリアします。 TWCRレジスタのTWINTビットがセットされている間は、TWIはいかなる動作も開始しません。 アプリケーションがTWINTビットをクリアすると、直ちにTWIはスタート・コンディションの転送を開始します。

2. スタート・コンディションが転送されると、TWCRレジスタのTWINTフラグがセットされ、TWSRレジスタにスタート・コンディションが正しく送信されたことを示すステータス・コードが書き込まれます。

3. 次にアプリケーション・ソフトウェアはTWSRレジスタの値を検査し、スタート・コンディションが正しく送信されたことを確認します。 TWSRレジスタが異常を示している場合、アプリケーション・ソフトウェアがエラー処理を行うなど、特別な操作をしなければならない場合があります。 ステータス・コードが期待通りであった場合、アプリケーションはSLA+WパケットをTWDRレジスタに書き込む必要があります。 TWDRレジスタはアドレスとデータの両方に使用されることにご注意ください。 TWDRに送信するSLA+Wパケットをロードした後、TWCRレジスタに特定の値を書き込み、TWDRレジスタに格納されているSLA+Wパケットを送信するようTWIハードウェアに命令します。 具体的にどのような値を書き込むかについては後述します。

ここで重要なのは、TWINTビットが書き込む値においてセットされていることです。 TWINTビットに1を書き込むことにより、同フラグをクリアします。 TWCRレジスタのTWINTビットがセットされている間は、TWIはいかなる動作も開始しません。 アプリケーションがTWINTビットをクリアすると、直ちにTWIはアドレス・パケットの転送を開始します。

4. アドレス・パケットが転送されると、TWCRレジスタのTWINTフラグがセットされ、アドレス・パケットが正しく送信されたことを示すステータス・コードがTWSRレジスタに格納されます。 このステータス・コードには、スレーブによってパケットがアクノレッジされたかどうかについての情報も含まれています。

5. 次にアプリケーション・ソフトウェアはTWSRレジスタの値を検査してアドレス・パケットが正しく送信されて、ACKビットが期待していた値になっていることを確認する必要があります。 TWSRレジスタが異常を示している場合、アプリケーション・ソフトウェアがエラー処理を行うなど、特別な操作をしなければならない場合があります。 ステータス・コードが期待通りであった場合、アプリケーションはデータ・パケットをTWDRレジスタに書き込む必要があります。 ひきつづき、TWCRレジスタに特定の値を書き込み、TWDRレジスタに格納されているデータ・パケットを送信するよう、TWIハードウェアに命令します。 具体的にどのような値を書き込むかについては後述しますが、ここで重要なのは、TWINTビットが書き込む値においてセットされていることです。 TWINTビットに1を書き込むことにより、同フラグをクリアします。 TWCRレジスタのTWINTビットがセットされている間は、TWIはいかなる動作も開始しません。 アプリケーションがTWINTビットをクリアすると、直ちにTWIはデータ・パケットの転送を開始します。

6. データ・パケットが転送されると、TWCRレジスタのTWINTフラグがセットされ、データ・パケットが正しく送信されたことを示すステータス・コードがTWSRレジスタに格納されます。 このステータス・コードには、スレーブによってパケットがアクノレッジされたかどうかについての情報も含まれています。

7. 次にアプリケーション・ソフトウェアはTWSRレジスタの値を検査してデータ・パケットが正しく送信されて、ACKビットが期待していた値になっていることを確認する必要があります。 TWSRレジスタが異常を示している場合、アプリケーション・ソフトウェアがエラー処理を行うなど、特別な操作をしなければならない場合があります。 ステータス・コードが期待通りであった場合、アプリケーションはTWCRレジスタに特定の値を書き込み、ストップ・コンディションを送信するよう、TWIハードウェアに命令します。 具体的にどのような値を書き込むかについては後述しますが、ここで重要なのは、TWINTビットが書き込む値においてセットされていることです。 TWINTビットに1を書き込むことにより、同フラグをクリアします。 TWCRレジスタのTWINTビットがセットされている間は、TWIはいかなる動作も開始しません。 アプリケーションがTWINTビットをクリアすると、直ちにTWIはストップ・コンディションの転送を開始します。 ストップ・コンディションの送信の後では、TWINTはセットされないことにご注意ください。

この例は簡潔ではあるものの、TWIにおける全ての転送動作の動作原理について示しています。

以上の動作は、下記のように要約することができます。

下記には、アセンブリ言語とC言語による実装例が示されています。 以下のコードでは、インクルード・ファイルなどにより、必要な定数の定義が行われているものと仮定しています。

アセンブリ言語の例 C言語の例 説明
1
  ldi  r16,  (1<<TWINT)|(1<<TWSTA)|(1<<TWEN)
  out  TWCR, r16
  TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
スタート・コンディションの送信
2
  wait1:
  in   r16, TWCR
  sbrs r16, TWINT
  rjmp wait1  
  while (!(TWCR & (1<<TWINT)))
    ;
TWINTフラグがセットされるのを待つ。 同フラグはスタート・コンディションが送信されたことを表す。
3
  in   r16, TWSR
  andi r16, 0xF8
  cpi  r16, START
  brne ERROR
  if ((TWSR & 0xF8) != START)
    ERROR();
TWIステータス・レジスタを検査。 分周比設定ビットをマスクする。 ステータスがSTARTと異なっていたらエラー。
  ldi  r16,  SLA_W
  out  TWDR, r16
  ldi  r16,  (1<<TWINT)|(1<<TWEN)
  out  TWCR, r16
  TWDR = SLA_W;
  TWCR = (1<<TWINT)|(1<<TWEN);
SLA_WをTWDRレジスタにロード。 TWCRレジスタのTWINTフラグをクリアして、アドレス・パケットの転送開始。
4
  wait2:
  in   r16,  TWCR
  sbrs r16,  TWINT
  rjmp wait2
  while (!(TWCR & (1<<TWINT)))
    ;
TWINTフラグがセットされるのを待つ。 同フラグはSLA+Wパケットがが送信され、ACK/NACKが受信されたことを表す。
5
  in   r16,  TWSR
  andi r16,  0xF8
  cpi  r16,  MT_SLA_ACK
  brne ERROR
  if ((TWSR & 0xF8) != MT_SLA_ACK)
    ERROR();
WIステータス・レジスタを検査。 分周比設定ビットをマスクする。 ステータスがMT_SLA_ACKと異なっていたらエラー。
  ldi  r16,  DATA
  out  TWR,  r16
  ldi  r16,  (1<<TWINT)|(1<<TWEN)
  out  TWCR, r16
  TWDR = DATA;
  TWCR = (1<<TWINT)|(1<<TWEN);
DATAをTWDRレジスタにロード。 TWCRレジスタのTWINTフラグをクリアし、データ・パケットの転送開始。
6
  wait3:
  in   r16,  TWCR
  sbrs r16,  TWINT
  rjmp wait3
  while (!(TWCR & (1<<TWINT)))
    ;
TWINTフラグがセットされるのを待つ。 同フラグはデータ・パケットがが送信され、ACK/NACKが受信されたことを表す。
7
  in   r16,  TWSR
  andi r16,  0xF8
  cpi  r16,  MT_DATA_ACK
  brne ERROR
  if ((TWSR & 0xF8) != MT_DATA_ACK)
    ERROR();
TWIステータス・レジスタを検査。 分周比設定ビットをマスクする。 ステータスがMT_DATA_ACKと異なっていたらエラー。
  ldi  r16,  (1<<TWINT) | (1<<TWEN) | (1<<TWSTO)
  out  TWCR, r16
  TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);
ストップ・コンディションの送信

21.7 転送モード

TWIインターフェースは、主要な4つのモードのいずれかで動作します。 このモードには、マスター送信(MT)、マスター受信(MR)、スレーブ送信(ST)、スレーブ受信(SR)があります。 同一のアプリケーション内で複数のモードを使うことができます。 たとえば、TWIのMTモードを用いてTWI EEPROMにデータを書き込み、MRモードを用いてEEPROMからデータを読み戻す、といった使い方です。 システム上に他のマスターが存在し、そのデバイスがTWIにデータを送信する場合には、SRモードを用いることになります。 どのモードを用いるのが適正であるかは、アプリケーション・ソフトウェアの判断により決まります。

この節の以降の部分では、それぞれのモードについて説明をします。 各モードでのデータ転送の詳細図とともに、発生する可能性のあるステータス・コードが説明されています。 この図では、以下の省略記号が使われています。

S: スタート・コンディション
Rs: 再スタート・コンディション
R: リード・ビット (SDAはHighレベル)
W: ライト・ビット (SDAはLowレベル)
A: アクノレッジ・ビット (SDAはLowレベル)
A: ノット・アクノレッジ・ビット (SDAはHighレベル)
Data: 8ビットのデータ・バイト
P: ストップ・コンディション
SLA: スレーブ・アドレス

Figure 21-12からFigure 21-18では、丸い記号が描かれている部分でTWINTフラグがセットされることを表しています。 丸の中の数字はTWSRレジスタに格納されるステータス・コードを、分周比設定ビットをゼロにマスクした値で表しています。 この時点で、TWI転送を続行するか完了するかの動作をアプリケーションが行う必要があります。 TWINTフラグがソフトウェアによってクリアされるまで、TWI転送は中断されたままになります。

TWINTフラグがセットされたとき、TWSRレジスタのステータス・コードを用いてアプリケーション・ソフトウェアの動作を決定します。 それぞれのステータス・コードについて、必要なソフトウェア処理と、それに引き続いて行われるシリアル転送の詳細がTable 21-2Table 21-5に掲載されています。 各テーブル中では分周比設定ビットはゼロにマスクされていることにご注意ください。

21.7.1 マスター送信モード

マスター送信モードでは、複数のデータ・バイトがスレーブ受信デバイスへ転送されます(Figure 21-11を参照)。 マスター・モードを開始するには、スタート・コンディションを送信する必要があります。

続いて転送されるアドレス・パケットによって、マスター送信(MT)モードとマスター受信(MR)モードのどちらを開始するかが決まります。 SLA+Wパケットが送信された場合MTモードとなり、SLA+Rパケットが送信された場合MRモードとなります。 この節では、ステータス・コードについての説明はすべて、分周比設定ビットをゼロに設定、またはゼロにマスクしたものという前提で書かれています。

Figure 21-11. マスター送信モードでのデータ転送

スタート・コンディションは、下記の値をTWCRレジスタに書き込むことで送信されます。

TWCR TWINT TWEA TWSTA TWSTO TWWC TWEN - TWIE
1 X 1 0 X 1 0 X

2線式シリアル・インターフェースを有効にするため、TWENビットを1にします。 TWSTAビットには、スタート・コンディションを送信するため1を書き込み、TWINTビットに1を書き込んでTWINTフラグをクリアします。 この書き込みにより、TWIは2線式シリアル・バスの状態を調べ、バスが開放されると直ちにスタート・コンディションを生成します。 スタート・コンディションが送信された後、TWINTフラグがハードウェアによってセットされ、TWSRレジスタのステータス・コードは0x08 (Table 21-2を参照)になります。 MTモードを開始するためには、SLA+Wパケットを送信するため、TWDRレジスタにSLA+Wを書き込む必要があります。 その後、TWINTビットを(1を書き込むことによって)クリアして転送を続行します。 TWCRレジスタに下記の値を書き込むことにより、この動作が行われます。

TWCR TWINT TWEA TWSTA TWSTO TWWC TWEN - TWIE
1 X 0 0 X 1 0 X

SLA+Wパケットが送信されアクノレッジ・ビットを受信すると、TWINTビットが再びセットされ、TWSRレジスタのステータス・コードは状態に応じた値となります。 マスター・モードで可能性のあるステータス・コードは、0x18、0x20、0x38です。 それぞれのステータス・コードに対して行うべき動作の詳細を、Table 21-2に説明します。

SLA+Wパケットが正しく送信された場合、データ・パケットを送信するため、TWDRレジスタにデータ・バイトを書き込みます。 TWDRレジスタへの書き込みを行ってよいのは、TWINTビットがHighになっている間だけです。 それ以外の場合、同レジスタへのアクセスは破棄され、TWCRレジスタの書き込み衝突ビット(TWWC)がセットされます。 TWDRレジスタを更新した後、TWINTビットを(1を書き込むことによって)クリアし、転送を続行します。 TWCRレジスタに下記の値を書き込むことにより、この動作が行われます。

TWCR TWINT TWEA TWSTA TWSTO TWWC TWEN - TWIE
1 X 0 0 X 1 0 X

この一連の動作は、最後のバイトが送信され、ストップ・コンディションや再スタートコンディションの生成により転送が終了するまで繰り返されます。 ストップ・コンディションは、TWCRレジスタに下記の値を書き込むことによって生成することができます。

TWCR TWINT TWEA TWSTA TWSTO TWWC TWEN - TWIE
1 X 0 1 X 1 0 X

再スタート・コンディションは、TWCRレジスタに下記の値を書き込むことによって生成することができます。

TWCR TWINT TWEA TWSTA TWSTO TWWC TWEN - TWIE
1 X 1 0 X 1 0 X

再スタート・コンディション(ステート 0x10)の後では、2線式シリアル・インターフェースは、ストップ・コンディションを送ることなく、同じスレーブに再びアクセスするか、別のスレーブにアクセスすることができます。 再スタート・コンディションの使用により、マスターがバス権を失うことなく、スレーブを変更してデータを送信したり、マスター送信モードとマスター受信モードを切り換えたりできます。

Table 21-2. マスター送信モードのステータス・コード
ステータス・コード(TWSR)
分数比設定ビットはゼロ
2線式シリアル・バス、およびハードウェアの状態 ソフトウェアによる応答 TWIハードウェアにより行われる次の動作
TWDRレジスタの読み書き TWCRレジスタへの書き込み
STA STO TWINT TWEA
0x08 スタート・コンディションが送信された SLA+Wをロード 0 0 1 X SLA+Wパケットを送信、ACK/NOT ACKを受信
0x10 再スタート・コンディションが送信された SLA+Wをロード 0 0 1 X SLA+Wパケットを送信、ACK/NACKを受信
SLA+Rをロード 0 0 1 X SLA+Rパケットを送信、マスター受信に切り換え
0x18 SLA+Wパケットが送信され、ACKを受信した データ・バイトをロード 0 0 1 X データ・バイトを送信し、ACK/NACKを受信
TWDRの操作なし 1 0 1 X 再スタート・コンディションを送信
TWDRの操作なし 0 1 1 X ストップ・コンディションを送信し、TWSTOフラグをリセット
TWDRの操作なし 1 1 1 X ストップ・コンディションに続けてスタート・コンディションを送信し、TWSTOフラグをリセット
0x20 SLA+Wパケットを送信し、NACKを受信した データ・バイトをロード 0 0 1 X データ・バイトを送信し、ACK/NACKを受信
TWDRの操作なし 1 0 1 X 再スタート・コンディションを送信
TWDRの操作なし 0 1 1 X ストップ・コンディションを送信し、TWSTOフラグをリセット
TWDRの操作なし 1 1 1 X ストップ・コンディションに続けてスタート・コンディションを送信し、TWSTOフラグをリセット
0x28 データ・パケットを送信し、ACKを受信した データ・バイトをロード 0 0 1 X データ・バイトを送信し、ACK/NACKを受信
TWDRの操作なし 1 0 1 X 再スタート・コンディションを送信
TWDRの操作なし 0 1 1 X ストップ・コンディションを送信し、TWSTOフラグをリセット
TWDRの操作なし 1 1 1 X ストップ・コンディションに続けてスタート・コンディションを送信し、TWSTOフラグをリセット
0x30 データ・パケットを送信し、NACKを受信した データ・バイトをロード 0 0 1 X データ・バイトを送信し、ACK/NACKを受信
TWDRの操作なし 1 0 1 X 再スタート・コンディションを送信
TWDRの操作なし 0 1 1 X ストップ・コンディションを送信し、TWSTOフラグをリセット
TWDRの操作なし 1 1 1 X ストップ・コンディションに続けてスタート・コンディションを送信し、TWSTOフラグをリセット
0x38 SLA+Wパケット、またはデータ・パケット中に調停動作によりバス権が失われた TWDRの操作なし 0 0 1 X 2線式シリアル・バスを開放、アドレス指定を受けていない状態のスレーブ・モードになる
TWDRの操作なし 1 0 1 X バスが開放されたときに、スタート・コンディションを送信する
Figure 21-12. マスター送信モードの転送フォーマットとステータス

21.7.2 マスター受信モード

マスター受信モードでは、複数のデータ・バイトがスレーブ送信デバイスから転送されます(Figure 21-13を参照)。 マスター・モードを開始するには、スタート・コンディションを送信する必要があります。

続いて転送されるアドレス・パケットによって、マスター送信(MT)モードとマスター受信(MR)モードのどちらを開始するかが決まります。 SLA+Wパケットが送信された場合MTモードとなり、SLA+Rパケットが送信された場合MRモードとなります。 この節では、ステータス・コードについての説明はすべて、分周比設定ビットをゼロに設定、またはゼロにマスクしたものという前提で書かれています。

Figure 21-13. マスター受信モードでのデータ転送

スタート・コンディションは、下記の値をTWCRレジスタに書き込むことで送信されます。

TWCR TWINT TWEA TWSTA TWSTO TWWC TWEN - TWIE
1 X 1 0 X 1 0 X

2線式シリアル・インターフェースを有効にするため、TWENビットを1にします。 TWSTAビットには、スタート・コンディションを送信するため1を書き込み、TWINTビットに1を書き込んでTWINTフラグをクリアします。 この書き込みにより、TWIは2線式シリアル・バスの状態を調べ、バスが開放されると直ちにスタート・コンディションを生成します。 スタート・コンディションが送信された後、TWINTフラグがハードウェアによってセットされ、TWSRレジスタのステータス・コードは0x08 (Table 21-2を参照)になります。 MRモードを開始するためには、SLA+Rパケットを送信するため、TWDRレジスタにSLA+Rを書き込む必要があります。 その後、TWINTビットを(1を書き込むことによって)クリアして転送を続行します。 TWCRレジスタに下記の値を書き込むことにより、この動作が行われます。

TWCR TWINT TWEA TWSTA TWSTO TWWC TWEN - TWIE
1 X 0 0 X 1 0 X

SLA+Rパケットが送信されアクノレッジ・ビットを受信すると、TWINTビットが再びセットされ、TWSRレジスタのステータス・コードは状態に応じた値となります。 マスター・モードで可能性のあるステータス・コードは、0x38、0x40、0x48です。 それぞれのステータス・コードに対して行うべき動作の詳細を、Table 21-3に説明します。 TWINTフラグがハードウェアによりセットされているとき、受信したデータをTWDRレジスタから読み取ることができます。 この手順を最後のバイトを受信するまで繰り返します。

最後のバイトを受信した後、マスター受信デバイス(MR)は、NACKを最後の受信データ・バイトを送ってスレーブ送信デバイス(ST)に通知する必要があります。 データ転送はストップ・コンディション、または再スタート・コンディションを生成することで終了します。 ストップ・コンディションは、TWCRレジスタに下記の値を書き込むことによって生成することができます。

TWCR TWINT TWEA TWSTA TWSTO TWWC TWEN - TWIE
1 X 0 1 X 1 0 X

再スタート・コンディションは、TWCRレジスタに下記の値を書き込むことによって生成することができます。

TWCR TWINT TWEA TWSTA TWSTO TWWC TWEN - TWIE
1 X 1 0 X 1 0 X

再スタート・コンディション(ステート 0x10)の後では、2線式シリアル・インターフェースは、ストップ・コンディションを送ることなく、同じスレーブに再びアクセスするか、別のスレーブにアクセスすることができます。 再スタート・コンディションの使用により、マスターがバス権を失うことなく、スレーブを変更してデータを送信したり、マスター送信モードとマスター受信モードを切り換えたりできます。

Table 21-3. マスター受信モードのステータス・コード
ステータス・コード(TWSR)
分数比設定ビットはゼロ
2線式シリアル・バス、およびハードウェアの状態 ソフトウェアによる応答 TWIハードウェアにより行われる次の動作
TWDRレジスタの読み書き TWCRレジスタへの書き込み
STA STO TWINT TWEA
0x08 スタート・コンディションが送信された SLA+Rをロード 0 0 1 X SLA+Rパケットを送信、ACK/NOT ACKを受信
0x10 再スタート・コンディションが送信された SLA+Rをロード 0 0 1 X SLA+Rパケットを送信、ACK/NACKを受信
SLA+Wをロード 0 0 1 X SLA+Wパケットを送信、マスター送信に切り換え
0x38 SLA+Rパケット中のバス調停、またはNACKによりバス権が失われた TWDRの操作なし 0 0 1 X 2線式シリアル・バスを開放、アドレス指定を受けていない状態のスレーブ・モードになる
TWDRの操作なし 1 0 1 X バスが開放されたときに、スタート・コンディションを送信する
0x40 SLA+Rパケットが送信され、ACKを受信した TWDRの操作なし 0 0 1 0 データ・バイトを受信し、NACKを返す
TWDRの操作なし 0 0 1 1 データバイトを受信し、ACKを返す
0x48 SLA+Rパケットが送信され、NACKを受信した TWDRの操作なし 1 0 1 X 再スタート・コンディションを送信
TWDRの操作なし 0 1 1 X ストップ・コンディションを送信し、TWSTOフラグをリセット
TWDRの操作なし 1 1 1 X ストップ・コンディションに続けてスタート・コンディションを送信し、TWSTOフラグをリセット
0x50 データ・バイトを受信し、ACKを返信した データ・バイトの読みとり 0 0 1 0 データ・バイトを受信し、NACKを返信する
データ・バイトの読みとり 0 0 1 1 データバイトを受信し、ACKを返信する
0x58 データ・バイトを受信し、NACKを返信した データ・バイトの読みとり 1 0 1 X 再スタート・コンディションを送信
データ・バイトの読みとり 0 1 1 X ストップ・コンディションを送信し、TWSTOフラグをリセット
データ・バイトの読みとり 1 1 1 X ストップ・コンディションに続けてスタート・コンディションを送信し、TWSTOフラグをリセット
Figure 21-14. マスター受信モードの転送フォーマットとステータス

21.7.3 スレーブ受信モード

スレーブ受信モードでは、複数のデータ・バイトがマスター送信デバイスから転送されます(Figure 21-15を参照)。 この節では、ステータス・コードについての説明はすべて、分周比設定ビットをゼロに設定、またはゼロにマスクしたものという前提で書かれています。

Figure 21-15. スレーブ受信モードでのデータ転送

スレーブ受信モードを開始するには、TWARレジスタ、TWCRレジスタを下記のように初期化する必要があります。

TWAR TWA6 TWA5 TWA4 TWA3 TWA2 TWA1 TWA0 TWGCE
デバイス自身のスレーブ・アドレス

上位7ビットは2線式インターフェースがマスターにアドレス指定を受けて応答するためのアドレス設定です。 LSBがセットされている場合、TWIはジェネラル・コール・アドレス(0x00)に応答し、セットされていない場合はジェネラル・コールを無視します。

TWCR TWINT TWEA TWSTA TWSTO TWWC TWEN - TWIE
0 1 0 0 0 1 0 X

2線式シリアル・インターフェースを有効にするため、TWENビットを1にします。 TWEAビットに1を書き込み、デバイス自身のスレーブ・アドレスやジェネラル・コール・アドレスに対するアクノレッジの応答を有効にします。 TWSTAビット、TWSTOビットには0を書き込んでください。

TWARレジスタ、TWCRレジスタを初期化すると、TWIはデバイス自身のスレーブ・アドレス(または、有効であればジェネラル・コール・アドレス)によりアドレス指定を受け、データ方向ビットを受信するまで待機します。 方向ビットが"0"(ライト)の場合、TWIはスレーブ受信(SR)モードの動作を開始し、そうでない場合はスレーブ送信(ST)モードを開始します。 デバイス自身のスレーブ・アドレスとライト・ビットを受信した後、TWINTフラグがセットされ、TWSRレジスタにセットされたステータス・コードを読み取ることができます。 ステータス・コードを用いて、ソフトウェアがどのような応答をする必要があるか判断します。 各ステータス・コードに対する適切な応答動作については、Table 21-4に詳細が記載されています。

スレーブ受信モードは、TWIがマスター動作を行っているときに調停動作によりバス権を失った場合に、開始される場合があります(ステータス 0x68と0x78を参照)。

TWEAビットが転送動作中にリセットされた場合、TWIインターフェースはその直後の受信データ・バイトの末尾に「ノット・アクノレッジ(NACK、"1")」をSDAラインに返信します。 この動作を用いてスレーブがこれ以上データ・バイトを受信できないことを通知することができます。 TWEAビットが0になっている間、TWIインターフェースは、デバイス自身のスレーブ・アドレスのアクノレッジ動作を行いません。 ただし、2線式シリアル・バスの監視は継続され、TWEAをセットした時点でアドレス認識を再開することができます。 つまり、TWEAビットを使うことによって、TWIインターフェースを2線式シリアル・バスから一時的に切り離すことができます。

アイドル・モード以外の全てのスリープ・モードにおいて、TWIインターフェースへのクロック供給は停止しています。 TWEAビットがセットされている場合、TWIインターフェースは2線式シリアル・バスのクロックで動作することによって、デバイス自身のスレーブ・アドレスやジェネラル・コール・アドレスの認識動作をすることができます。 アドレスが一致すると、デバイスはスリープ・モードからウェークアップ動作を行い、ウェークアップが完了してTWINTフラグを(1を書き込むことにより)クリアするまで、TWIインターフェースはSCLクロックをLowのまま保持します。 AVRのクロックが通常どおり動作を開始すれば、以降のデータ受信は通常どおり行われます。 AVRに長いスタートアップ時間を設定している場合、SCLラインが長時間にわたってLowに保持され、その間バス上で他のデータ転送ができなくなるので、ご注意ください。

各スリープ・モードからウェークアップしたとき、2線式シリアル・インターフェース・データ・レジスタ(TWDR)には、スリープ前にバス上にあったバイト値が保存されていないことにご注意ください。

Table 21-4. スレーブ受信モードのステータス・コード
ステータス・コード(TWSR)
分数比設定ビットはゼロ
2線式シリアル・バス、およびハードウェアの状態 ソフトウェアによる応答 TWIハードウェアにより行われる次の動作
TWDRレジスタの読み書き TWCRレジスタへの書き込み
STA STO TWINT TWEA
0x60 デバイス自身を指定するSLA+Wパケットを受信し、 ACKを返信した TWDRの操作なし X 0 1 0 データ・バイトを受信し、NACKを返信する
TWDRの操作なし X 0 1 1 データ・バイトを受信し、ACKを返信する
0x68 マスター動作中のSLA+R/Wパケットで調停によりバス権を失い、 自身を指すSLA+Wパケットを受信した。 ACKを返信した。 TWDRの操作なし X 0 1 0 データ・バイトを受信し、NACKを返信する
TWDRの操作なし X 0 1 1 データ・バイトを受信し、ACKを返信する
0x70 ジェネラル・コール・アドレスを受信し、ACKを返信した TWDRの操作なし X 0 1 0 データ・バイトを受信し、NACKを返信する
TWDRの操作なし X 0 1 1 データ・バイトを受信し、ACKを返信する
0x78 マスター動作中のSLA+R/Wパケットで調停によりバス権を失い、 ジェネラル・コール・アドレスを受信した。 ACKを返信した。 TWDRの操作なし X 0 1 0 データ・バイトを受信し、NACKを返信する
TWDRの操作なし X 0 1 1 データ・バイトを受信し、ACKを返信する
0x80 すでにSLA+Wパケットでアドレス指定を受けている。 データ・パケットを受信した。 ACKを返信した。 データ・バイトを読みとる X 0 1 0 データ・バイトを受信し、NACKを返信する
TWDRの操作なし X 0 1 1 データ・バイトを受信し、ACKを返信する
0x88 すでにSLA+Wパケットでアドレス指定を受けている。 データ・パケットを受信した。 NACKを返信した。 データ・バイトを読みとる 0 0 1 0 アドレス指定を受けていないスレーブ・モードへ切り換え、 自身のアドレス指定やジェネラル・コール・アドレスの認識をしない。
データ・バイトを読みとる 0 0 1 1 アドレス指定を受けていないスレーブ・モードへ切り換え、 自身のアドレス指定の認識を行う。 TWGCE = 1ならば、ジェネラル・コール・アドレスの認識も行う。
データ・バイトを読みとる 1 0 1 0 アドレス指定を受けていないスレーブ・モードへ切り換え、 自身のアドレス指定やジェネラル・コール・アドレスの認識をしない。 バスが開放されたら、スタート・コンディションを送信する
データ・バイトを読みとる 1 0 1 1 アドレス指定を受けていないスレーブ・モードへ切り換え、 自身のアドレス指定の認識を行う。 TWGCE = 1ならば、ジェネラル・コール・アドレスの認識も行う。 バスが開放されたら、スタート・コンディションを送信する
0x90 すでにジェネラル・コールによるアドレス指定をうけている。 データ・パケットを受信し、ACKを返信した。 データ・バイトを読みとる X 0 1 0 データ・バイトを受信し、NACKを返信する
データ・バイトを読みとる X 0 1 1 データ・バイトを受信し、ACKを返信する
0x98 すでにジェネラル・コールによるアドレス指定をうけている。 データ・パケットを受信し、NACKを返信した。 データ・バイトを読みとる 0 0 1 0 アドレス指定を受けていないスレーブ・モードへ切り換え、 自身のアドレス指定やジェネラル・コール・アドレスの認識をしない。
データ・バイトを読みとる 0 0 1 1 アドレス指定を受けていないスレーブ・モードへ切り換え、 自身のアドレス指定の認識を行う。 TWGCE = 1ならば、ジェネラル・コール・アドレスの認識も行う。
データ・バイトを読みとる 1 0 1 0 アドレス指定を受けていないスレーブ・モードへ切り換え、 自身のアドレス指定やジェネラル・コール・アドレスの認識をしない。 バスが開放されたら、スタート・コンディションを送信する
データ・バイトを読みとる 1 0 1 1 アドレス指定を受けていないスレーブ・モードへ切り換え、 自身のアドレス指定の認識を行う。 TWGCE = 1ならば、ジェネラル・コール・アドレスの認識も行う。 バスが開放されたら、スタート・コンディションを送信する
0xA0 スレーブとしてアドレス指定を受けている状態で、 ストップ・コンディション、または再スタート・コンディションを受信した。 操作なし 0 0 1 0 アドレス指定を受けていないスレーブ・モードへ切り換え、 自身のアドレス指定やジェネラル・コール・アドレスの認識をしない。
0 0 1 1 アドレス指定を受けていないスレーブ・モードへ切り換え、 自身のアドレス指定の認識を行う。 TWGCE = 1ならば、ジェネラル・コール・アドレスの認識も行う。
1 0 1 0 アドレス指定を受けていないスレーブ・モードへ切り換え、 自身のアドレス指定やジェネラル・コール・アドレスの認識をしない。 バスが開放されたら、スタート・コンディションを送信する
1 0 1 1 アドレス指定を受けていないスレーブ・モードへ切り換え、 自身のアドレス指定の認識を行う。 TWGCE = 1ならば、ジェネラル・コール・アドレスの認識も行う。 バスが開放されたら、スタート・コンディションを送信する
Figure 21-16. スレーブ受信モードのデータ転送フォーマットとステータス

21.7.4 スレーブ送信モード

スレーブ送信モードでは、複数のデータ・バイトがマスター受信デバイスへ転送されます(Figure 21-17を参照)。 この節では、ステータス・コードについての説明はすべて、分周比設定ビットをゼロに設定、またはゼロにマスクしたものという前提で書かれています。

Figure 21-17. スレーブ送信モードでのデータ転送

スレーブ送信モードを開始するには、TWARレジスタ、TWCRレジスタを下記のように初期化する必要があります。

TWAR TWA6 TWA5 TWA4 TWA3 TWA2 TWA1 TWA0 TWGCE
デバイス自身のスレーブ・アドレス

上位7ビットは2線式インターフェースがマスターにアドレス指定を受けて応答するためのアドレス設定です。 LSBがセットされている場合、TWIはジェネラル・コール・アドレス(0x00)に応答し、セットされていない場合はジェネラル・コールを無視します。

TWCR TWINT TWEA TWSTA TWSTO TWWC TWEN - TWIE
0 1 0 0 0 1 0 X

2線式シリアル・インターフェースを有効にするため、TWENビットを1にします。 TWEAビットに1を書き込み、デバイス自身のスレーブ・アドレスやジェネラル・コール・アドレスに対するアクノレッジの応答を有効にします。 TWSTAビット、TWSTOビットには0を書き込んでください。

TWARレジスタ、TWCRレジスタを初期化すると、TWIはデバイス自身のスレーブ・アドレス(または、有効であればジェネラル・コール・アドレス)によりアドレス指定を受け、データ方向ビットを受信するまで待機します。 方向ビットが"1"(リード)の場合、TWIはスレーブ受信(ST)モードの動作を開始し、そうでない場合はスレーブ送信(SR)モードを開始します。 デバイス自身のスレーブ・アドレスとライト・ビットを受信した後、TWINTフラグがセットされ、TWSRレジスタにセットされたステータス・コードを読み取ることができます。 ステータス・コードを用いて、ソフトウェアがどのような応答をする必要があるか判断します。 各ステータス・コードに対する適切な応答動作については、Table 21-5に詳細が記載されています。

スレーブ送信モードは、TWIがマスター動作を行っているときに調停動作によりバス権を失った場合に、開始される場合があります(ステータス 0xB0を参照)。

データ転送中にTWEAビットに0が書き込まれた場合、TWIインターフェースは最後の転送バイトを送信します。 最後のバイト送信に対してマスター受信デバイスがNACKを返信したか、ACKを返信したかにより、ステータスは0xC0、または0xC8になります。 TWIインターフェースはアドレス指定を受けていない状態のスレーブ・モードに切り換わり、マスターが転送を継続していても無視します。 したがって、この場合、マスター受信デバイスは全ビットが"1"のシリアル・データを受けとることになります。 スレーブが最終バイトを送信した(TWEAビットを0にして、マスターからのNACKを待っている状態)にもかかわらず、マスターがデータ・バイトをさらに要求している場合(ACKを返信している場合)、ステータスは0xC8になります。

TWEAビットが0になっている間、TWIインターフェースは、デバイス自身のスレーブ・アドレスへの応答動作を行いません。 ただし、2線式シリアル・バスの監視は継続され、TWEAをセットした時点でアドレス認識を再開することができます。 つまり、TWEAビットを使うことによって、TWIインターフェースを2線式シリアル・バスから一時的に切り離すことができます。

アイドル・モード以外の全てのスリープ・モードにおいて、TWIインターフェースへのクロック供給は停止しています。 TWEAビットがセットされている場合、TWIインターフェースは2線式シリアル・バスのクロックで動作することによって、デバイス自身のスレーブ・アドレスやジェネラル・コール・アドレスの認識動作をすることができます。 アドレスが一致すると、デバイスはスリープ・モードからウェークアップ動作を行い、ウェークアップが完了してTWINTフラグを(1を書き込むことにより)クリアするまで、TWIインターフェースはSCLクロックをLowのまま保持します。 AVRのクロックが通常どおり動作を開始すれば、以降のデータ受信は通常どおり行われます。 AVRに長いスタートアップ時間を設定している場合、SCLラインが長時間にわたってLowに保持され、その間バス上で他のデータ転送ができなくなるので、ご注意ください。

各スリープ・モードからウェークアップしたとき、2線式シリアル・インターフェース・データ・レジスタ(TWDR)には、スリープ前にバス上にあったバイト値が保存されていないことにご注意ください。

Table 21-5. スレーブ送信モードのステータス・コード
ステータス・コード(TWSR)
分数比設定ビットはゼロ
2線式シリアル・バス、およびハードウェアの状態 ソフトウェアによる応答 TWIハードウェアにより行われる次の動作
TWDRレジスタの読み書き TWCRレジスタへの書き込み
STA STO TWINT TWEA
0xA8 デバイス自身を指すSLA+Rパケットを受信し、ACKを返信した データ・バイトをロード X 0 1 0 最後のデータ・バイトを送信し、NACKの返信を待つ
データ・バイトをロード X 0 1 1 データ・バイトを送信し、ACKの返信を待つ
0xB0 マスター動作中のSLA+R/Wパケットで調停によりバス権を失い、 SLA+Rによるアドレス指定を受けた。 ACKを返信した。 データ・バイトをロード X 0 1 0 最後のデータ・バイトを送信し、NACKの返信を待つ
データ・バイトをロード X 0 1 1 データ・バイトを送信し、ACKの返信を待つ
0xB8 TWDRのデータ・バイトを送信し、ACKを受信した データ・バイトをロード X 0 1 0 最後のデータ・バイトを送信し、NACKの返信を待つ
データ・バイトをロード X 0 1 1 データ・バイトを送信し、ACKの返信を待つ
0xC0 TWDRのデータ・バイトを送信し、NACKを受信した TWDRの操作なし 0 0 1 0 アドレス指定を受けていないスレーブ・モードへ切り換え、 自身のアドレス指定やジェネラル・コール・アドレスの認識をしない。
TWDRの操作なし 0 0 1 1 アドレス指定を受けていないスレーブ・モードへ切り換え、 自身のアドレス指定の認識を行う。 TWGCE = 1ならば、ジェネラル・コール・アドレスの認識も行う。
TWDRの操作なし 1 0 1 0 アドレス指定を受けていないスレーブ・モードへ切り換え、 自身のアドレス指定やジェネラル・コール・アドレスの認識をしない。 バスが開放されたら、スタート・コンディションを送信する
TWDRの操作なし 1 0 1 1 アドレス指定を受けていないスレーブ・モードへ切り換え、 自身のアドレス指定の認識を行う。 TWGCE = 1ならば、ジェネラル・コール・アドレスの認識も行う。 バスが開放されたら、スタート・コンディションを送信する
0xC8 TWDRの最終データ・バイトを送信(TWEA = "0")し、 ACKを受信した。 TWDRの操作なし 0 0 1 0 アドレス指定を受けていないスレーブ・モードへ切り換え、 自身のアドレス指定やジェネラル・コール・アドレスの認識をしない。
TWDRの操作なし 0 0 1 1 アドレス指定を受けていないスレーブ・モードへ切り換え、 自身のアドレス指定の認識を行う。 TWGCE = 1ならば、ジェネラル・コール・アドレスの認識も行う。
TWDRの操作なし 1 0 1 0 アドレス指定を受けていないスレーブ・モードへ切り換え、 自身のアドレス指定やジェネラル・コール・アドレスの認識をしない。 バスが開放されたら、スタート・コンディションを送信する
TWDRの操作なし 1 0 1 1 アドレス指定を受けていないスレーブ・モードへ切り換え、 自身のアドレス指定の認識を行う。 TWGCE = 1ならば、ジェネラル・コール・アドレスの認識も行う。 バスが開放されたら、スタート・コンディションを送信する
Figure 21-18. スレーブ送信モードの転送フォーマットとステータス

21.7.5 その他の状態

TWIで定義されているどの状態にも当てはまらないステータス・コードが二つあります。Table 21-6を参照してください。

ステータス 0xF8は、TWINTフラグがセットされていないので有効な情報が存在しないことを表します。 この状態は、他のステータスとステータスの間の時間帯において、TWIインターフェースがシリアル・転送に関わっていない場合に発生します。

ステータス 0x00は、2線式シリアル・バスの転送動作中にバス・エラーが発生したことを表します。 バス・エラーはスタート・コンディションやストップ・コンディションがフレーム・フォーマットの不正な位置で発生した場合に起こります。

不正な位置の例としては、アドレス・バイト、データ・バイト、アクノレッジ・ビットのシリアル転送中があげられます。 バス・エラーが発生した場合、TWINTがセットされます、 バス・エラーから復帰するためには、TWSTOフラグをセットし、TWINTフラグに1を書き込んでクリアしなければなりません。 この操作により、TWIインターフェースはアドレス指定を受けていない状態のスレーブ・モードとなり、TWSTOフラグがクリアされます(TWCRレジスタの他のビットに影響はありません)。 SDAとSCLラインが開放され、ストップ・コンディションの送信は行われません。

Table 21-6. その他のステータス
ステータス・コード(TWSR)
分数比設定ビットはゼロ
2線式シリアル・バス、およびハードウェアの状態 ソフトウェアによる応答 TWIハードウェアにより行われる次の動作
TWDRレジスタの読み書き TWCRレジスタへの書き込み
STA STO TWINT TWEA
0xF8 有効なステータス情報なし。TWINT="0" TWDRの操作なし TWCRの操作なし 待機、または現在の転送動作を継続する
0x00 不正なスタート・コンディション、またはストップ・コンディションによるバス・エラー TWDRの操作なし 0 1 1 X 内部のハードウェアだけの動作。ストップ・コンディションの送信はしない。どの状態であっても、バスを開放し、TWSTOビットをクリアする。

21.7.6 複数のTWIモードを組み合わせる

大抵の場合、TWIの複数のモードを組み合わせて、目的とする動作を行います。

シリアルEEPROMからデータを読みとる場合を考えてみましょう。 一般に、このデータ転送には下記のような手順が含まれています。

データの転送方向は、マスターからスレーブへ、また、その逆へと行われることに注意してください。 マスターからスレーブに読み取りアドレスを指定するため、マスター送信(MT)モードが必要となります。 つづいて、データをスレーブから読みとるため、マスター受信(MR)モードを使用します。 したがって、転送の方向を切り換える必要があります。 この間、マスター・デバイスはバスの制御権を保持して、一連の処理を分割不能な動作として実行しなければなりません。 複数のマスターが存在するシステムで、この原則を守らない場合、他のマスターによって手順2と手順3の間にEEPROMのデータ・ポインタが変更される可能性があり、マスターは間違ったアドレスのデータを読みとることになります。 こういった転送方向の変更は、アドレス・バイトの送信とデータ・バイトの受信の間で再スタート・コンディションを使うことで実現できます。 再スタート・コンディションの直後では、マスターはバス権を保持しています。 下記の図に、このデータ転送の流れを示します。

Figure 21-19. 複数のTWIのモードを組み合わせて、シリアルEEPROMにアクセスする

21.8 マルチ・マスター・システムとバスの調停

複数のマスター・デバイスが同一のバス上に接続されている場合、転送動作が一つ以上のマスターにより同時に開始される可能性があります。 このような場合、マスターのうち一つだけが転送を許可され、データが転送動作の途中で失われないように、TWIの規格にしたがって確実に処理します。 バス調停が起こる状況の例を下記に示します。ここでは、二つのマスター・デバイスが、スレーブ受信デバイスにデータの送信をしようとしています。

Figure 21-20. バス調停動作の例

下記のように、バス調停ではいくつかの異なるシナリオが想定されます。

この動作をFigure 21-21にまとめます。 ステータス・コードがとりうる値は丸の中に記されています。

Figure 21-21. バス調停により発生する可能性のあるステータス・コード

21.9 各レジスタ詳細

21.9.1 TWBR – TWIビット・レート・レジスタ

ビット 7 6 5 4 3 2 1 0
(0xB8) TWBR7 TWBR6 TWBR5 TWBR4 TWBR3 TWBR2 TWBR1 TWBR0 TWBR
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
初期値 0 0 0 0 0 0 0 0

21.9.2 TWCR — TWIコントロール・レジスタ

ビット 7 6 5 4 3 2 1 0
(0xBC) TWINT TWEA TWSTA TWSTO TWWC TWEN - TWIE TWCR
Read/Write R/W R/W R/W R/W R R/W R R/W
初期値 0 0 0 0 0 0 0 0

TWCRレジスタを使って、TWIの動作を制御します。 TWIインターフェースの有効化、スタート・コンディションをバス上に送ることによるマスター動作の開始、受信モードでのアクノレッジの生成、ストップ・コンディションの生成、TWDRレジスタに送信データを書き込んでいる間のバスの停止を行うためにTWCRレジスタを使用します。 TWDRレジスタへのアクセス不可の状態で書き込みを行おうとした場合に起こる書き込み衝突の有無も表しています。

21.9.3 TWSR – TWIステータス・レジスタ

ビット 7 6 5 4 3 2 1 0
(0xB9) TWS7 TWS6 TWS5 TWS4 TWS3 - TWPS1 TWPS0 TWSR
Read/Write R R R R R R R/W R/W
初期値 1 1 1 1 1 0 0 0

21.9.4 TWDR – TWIデータ・レジスタ

ビット 7 6 5 4 3 2 1 0
(0xBB) TWD7 TWD6 TWD5 TWD4 TWD3 TWD2 TWD1 TWD0 TWDR
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
初期値 1 1 1 1 1 1 1 1

送信モードでは、TWDRレジスタには次に送信するバイトが格納されます。 受信モードでは、TWDRレジスタに最後に受信したバイトが保存されます。 TWIインターフェースがバイトのシフト操作を行っていないとき、このレジスタに書き込みができます。

TWI割り込みフラグ(TWINT)がハードウェアによってセットされることで、レジスタへの書き込みが可能になります。 データ・レジスタは最初の割り込みが発生するまでは、ユーザーによって初期化することができないことにご注意ください。 TWDRレジスタ中のデータはTWINTビットがセットされている限り、変化することなく保持されます。 データがシフト出力されている間、バス上のデータが同時にシフト入力されます。 スリープ・モードからTWI割り込みでウェークアップした場合をのぞき、TWDRレジスタには常にバス上にあった最後のバイトが保存されています。 ウェークアップ時のTWDRレジスタの内容は未定義状態です。 調停によりバス権を失った場合でも、マスターからスレーブへのステータス移行によってデータが失われることはありません。 ACKビットの処理はTWI制御回路により自動的に行われており、CPUが直接ACKビットにアクセスすることは出来ません。

21.9.5 TWAR – TWI (スレーブ)アドレス・レジスタ

ビット 7 6 5 4 3 2 1 0
(0xBA) TWA6 TWA5 TWA4 TWA3 TWA2 TWA1 TWA0 TWGCE TWAR
Read/Write R/W R/W R/W R/W R/W R/W R/W R/W
初期値 1 1 1 1 1 1 1 0

TWARレジスタには、TWIインターフェースがスレーブ送信(ST)モード、スレーブ受信(SR)モードとして応答する場合に用いる、7ビットのスレーブ・アドレス(TWARレジスタの上位7ビット)をロードします。 このアドレスはマスター・モードの動作では必要ありません。 複数のマスターが存在するシステムでは、他のマスターからスレーブとしてアドレス指定を受けるために、マスターにTWARレジスタを設定する必要があります。

TWARレジスタのLSBは、ジェネラル・コール・アドレス(0x00)の認識を有効にするために使用します。 受信したシリアル・アドレス中のスレーブ・アドレス(または、有効になっていれば、ジェネラル・コール・アドレス)を監視するアドレス比較回路があり、アドレスの一致を検出した場合、割り込み要求が発生します。

21.9.6 TWAMR – TWI (スレーブ)アドレス・マスク・レジスタ

ビット 7 6 5 4 3 2 1 0
(0xBD) TWAM[6:0] - TWAMR
Read/Write R/W R/W R/W R/W R/W R/W R/W R
初期値 0 0 0 0 0 0 0 0

目次に戻る