要約
1つのマスタと複数のスレーブで構成される標準的なSPIシステムでは、専用のチップセレクト信号を使用して個々のスレーブにアクセスします。スレーブの数が増えると、それだけチップセレクトラインの数も増えることになります。この状況では、システムの基板レイアウトが非常に難しくなる場合があります。
その代わりとなるレイアウトの1つが、デイジーチェーン接続です。この記事では、デイジーチェーン接続されたSPIシステムの詳細について説明し、ソフトウェアを使って一連のスレーブ間にコマンドを伝播させる方法を示します。
標準SPI/QSPI/MICROWIRE対応マイクロコントローラは、3線式または4線式シリアルインタフェースを通してスレーブデバイスと通信します。標準的なインタフェースには、チップセレクト信号(アクティブローCS)、シリアルクロック(SCLK)、およびデータ入力信号(DIN)が含まれ、ときにはデータ出力信号(DOUT)が含まれる場合もあります。個別にアクセス可能なデバイス(I2Cシステムではそれが普通です)は、バス上の単一デバイスと容易に通信を行うことができます。
基本的なシリアル通信インタフェース
多くのSPIデバイスは、個別にアクセス可能ではありません。そのため、それらのデバイスとバス上の単一デバイスの間の通信には、追加のハードウェアまたはソフトウェア構造が必要になります。図1は、1個のマイクロコントローラが複数のスレーブデバイスと通信するシステムを示しています。
上のシステムでは、マイクロコントローラが1つのシリアルクロック出力(SCK)と1つのマスタアウト/スレーブイン信号線(MOSI)を使用して、すべてのスレーブを制御しています。マイクロコントローラは各スレーブデバイスに独立したスレーブセレクト信号(アクティブローSS_)を割り当てて、個別にアクセスすることができるようにしています。すべてのスレーブが単一のクロックとデータラインを共有しているため、アクティブローCS入力をローにアサートされているスレーブだけが、シリアルクロックおよびデータライン上のアクティビティに対するアクノリッジを行い、応答を返します。このシステムは、システム中にごく少数のスレーブデバイスしか存在しない場合には、実装が容易です。多数のスレーブデバイスを含んだシステムでは、マイクロコントローラにスレーブ数と同じ数のアクティブローSS_出力が必要になります。このアーキテクチャでは、ハードウェアとレイアウトの複雑性が増大します。
デイジーチェーンを用いる代替案
ハードウェア面の制約から、図1の手法では現実的でなく、実装が困難な場合があります。それに代わるシリアルインタフェースアプリケーションの手法の1つが、デイジーチェーンです。これは、一列に繋いだデバイス間でコマンドを伝播させる方式です。図2に、N個のデバイスをデイジーチェーン構成にしたシステムを示します。
単一のアクティブローSS (またはアクティブローCS)信号が、すべてのスレーブのアクティブローCS入力を制御します。すべてのスレーブが、同じクロック信号を受け取ります。チェーン中の最初のスレーブ(SLAVE 1)だけがマイクロコントローラから直接コマンドデータを受け取ります。ネットワークに属する他のスレーブは、それぞれチェーン中で1つ前に位置するスレーブのDOUT出力から、そのDINデータを受け取ります。
デイジーチェーンが正しく動作するためには、特定のコマンドサイクル(1つのコマンドを送り込むのに必要なクロックパルス数で定義されます)でスレーブがDINからコマンドを入力し、その次のコマンドサイクルで同じコマンドをDOUTに出力することができなければなりません。簡単に言うと、DINからDOUTまでに1コマンドサイクルの遅延が存在します。さらに、スレーブはアクティブローCSの立上りエッジで書かれたコマンドだけを実行しなければなりません。すなわち、アクティブローCSがローである限り、スレーブはそのコマンドを無視して、次のコマンドサイクルでそのコマンドをDOUTに出力します。あるコマンドサイクルの後でアクティブローCSがハイになった場合、すべてのスレーブがその直前にそれぞれのDIN入力に書き込まれたコマンドを実行します。アクティブローCSがハイになると、データはDOUTに出力されなくなります。このプロセスによって、チェーン内の各スレーブがそれぞれ異なるコマンドを実行することが可能になります。デイジーチェーンのこれらの要件が満たされている限り、マイクロコントローラがネットワーク内の全スレーブを制御するために必要なのは、3つの信号(アクティブローSS、SCK、およびMOSI)だけです。
どのようにデイジーチェーンが達成されるか
デイジーチェーン接続されたシステム(図2)において、SLAVE 1は直接マイクロコントローラからデータを受け取ります。このデータは、SLAVE 1の内部シフトレジスタに送り込まれます。アクティブローCS (またはアクティブローSS)がローである限り、このデータはそのままSLAVE 1のDOUT出力に伝播されます。SLAVE 1のDOUTはSLAVE 2のDINに接続されているため、SLAVE 1のDOUT出力に現れた通りのデータが、SLAVE 2の内部シフトレジスタに送り込まれます。SLAVE 2がSLAVE 1からデータを受け取っている間に、マイクロコントローラはそれと並行して別のコマンドをSLAVE 1に送信することができます。この新しいコマンドは、SLAVE 1のシフトレジスタ内にある以前のデータを上書きします。アクティブローCSがローである限り、各スレーブデバイスがそれぞれ自分宛のコマンドを受け取るまで、データがデイジーチェーン全体を通して伝播します。各スレーブのシフトレジスタに格納されたコマンドは、アクティブローCSの立上りエッジで実行されます。以下の例では、MAX5233とMAX5290を使用してデイジーチェーン接続の具体例を示します。
回路例その1
図3は、3個のMAX5233 ICをデイジーチェーン構成で接続したものです。MAX5233は、デュアル10ビットDACです(2つのDACチャネル、AおよびBを内蔵)。RSTVをVDDに接続することで、起動時のアナログ出力はミッドスケールになります。
図4は、IC1 (A1およびB1)、IC2 (A2およびB2)、およびIC3 (A3およびB3)の出力を、それぞれゼロスケール、ミッドスケール、およびフルスケールに設定するコマンドシーケンスを示しています。この例では、以下のコマンドを使用しています。
- 0x7FF8—IC3のDACレジスタにフルスケールデータをロードし、両出力(A3、B3)をフルスケールに設定する
- 0x7000—IC2のDACレジスタにミッドスケールデータをロードし、両出力(A2、B2)をミッドスケールに設定する
- 0x6000—IC1のDACレジスタにゼロスケールデータをロードし、両出力(A1、B1)をゼロスケールに設定する
最初のコマンドサイクル(SCLKパルス16個分)の間に、0x7FF8がIC1のシフトレジスタにロードされます。アクティブローCSがローのままであるため、このデータはIC1を通って伝播し、次のコマンドサイクルでDOUT1に出力されます。この2番目のコマンドサイクルの間に、DOUT1からのデータが直接DIN2に移動し、0x7FF8がIC2のシフトレジスタにロードされます。それと同時に、新しいコマンド(0x7000)がIC1のシフトレジスタにロードされ、以前のコマンドを上書きします。
3番目のコマンドサイクルで、最初のコマンド(0x7FF8)はIC3のシフトレジスタにロードされます。第2のコマンド(0x7000)はIC2にロードされ、IC1は新しいコマンド(0x6000)を受け取ります。これで3つすべてのICが、デイジーチェーンを通してシフトレジスタ内にコマンドを受け取ったことになります。アクティブローCSがハイになると、ロードされたコマンドが実行されます。すなわち、A1とB1がゼロスケールに設定され、A2とB2がミッドスケールに設定され、A3とB3がフルスケールに設定されます。
図5は、より複雑なコマンドシーケンスの例を示しています。以下のコマンドが使用されています(詳細についてはMAX5233のデータシートをご覧ください)。
- 0x3FF8—入力レジスタAにフルスケールデータをロード、DACのレジスタと出力は変化しない
- 0x3000—入力レジスタAにミッドスケールデータをロード、DACのレジスタと出力は変化しない
- 0x2000—入力レジスタAにゼロスケールデータをロード、DACのレジスタと出力は変化しない
- 0xBFF8—入力レジスタBにフルスケールデータをロード、DACのレジスタと出力は変化しない
- 0xB000—入力レジスタBにミッドスケールデータをロード、DACのレジスタと出力は変化しない
- 0xA000—入力レジスタBにゼロスケールデータをロード、DACのレジスタと出力は変化しない
- 0x0000—NO-OP (動作なし)
最初の3つのコマンドサイクルで、デイジーチェーン接続された3つのICはそれぞれシフトレジスタ内にコマンドを受け取ります。IC1、IC2、およびIC3用のコマンドは、それぞれ0xB000、0xBFF8、および0xBFF8です。これらのコマンドは、アクティブローCSの立上りエッジで実行されます(1回目の実行)。1回目の実行の後、IC1、IC2、およびIC3の入力レジスタBに、ミッドスケール用、フルスケール用、フルスケール用のデータがそれぞれロードされます。この時点では、各ICのDACレジスタBが変化しないため、B1、B2、B3は変化しません。
続く3つのコマンドサイクルでは、入力レジスタAだけをロードするコマンドが各ICのシフトレジスタに書き込まれます。DACレジスタAおよびその出力は変化しません。アクティブローCSの立上りエッジで、IC1、IC2、およびIC3の入力レジスタAに、フルスケール用、ゼロスケール用、ミッドスケール用のデータがそれぞれロードされます。この時点では、入力レジスタAだけが更新され、DACレジスタAは更新されないため、A1、A2、およびA3は変化しません。
2回目の実行の後、ハードウェアアクティブローLDACコマンド(アクティブローLDACをローに駆動)によって、すべてのDACレジスタにそれぞれの入力レジスタのデータがロードされます。DAC出力が更新され、それぞれに対応するDACレジスタのデータが出力されます。A1、B2、およびB3がフルスケールになります。A2はゼロスケールになり、A3はミッドスケールのままです。
3セット目のコマンドサイクル群で、IC2とIC3にはNO-OPコマンド(0x0000)が与えられ、IC1は入力レジスタBにゼロスケールのデータをロードする0xA000コマンドを受け取ります。3回目の実行の後、すべての出力は変化しません。
4セット目のコマンドサイクル群で、IC1とIC2はNO-OPコマンドを受け取り、IC3は0x3FF8を受け取ります。4回目の実行の後、IC3の入力レジスタAにはフルスケールのデータがロードされます。再びハードウェアアクティブローLDACコマンドが発行され、DACレジスタに入力レジスタのデータがロードされます。これによって、B1がミッドスケールからゼロスケールに、A3がミッドスケールからフルスケールに変化します。他の出力はすべて変化しません。
Analog Output Name | State of Output | |||
After Power-Up (RSTV = VDD) | First Hardware Active Low LDAC | Second Hardware Active Low LDAC | ||
IC1 | A1 | Midscale | Full Scale | Full Scale |
B1 | Midscale | Midscale | Zero Scale | |
IC2 | A2 | Midscale | Zero Scale | Zero Scale |
B2 | Midscale | Full Scale | Full Scale | |
IC3 | A3 | Midscale | Midscale | Full Scale |
B3 | Midscale | Full Scale | Full Scale |
回路例その2
図6は、3個のMAX5290デュアル12ビットDACをデイジーチェーン構成にしたものです。PUをDVDDに接続することで、起動時のアナログ出力はフルスケールになります。MAX5290は、デイジーチェーン専用のディジタル出力を備えていません。代わりに、シリアルインタフェースによって2つのUPIO (user-programmable input/output)端子の1つをDOUTDC_モード用にプログラムする必要があります。詳細についてはMAX5290のデータシートをご覧ください。
図7はコマンドシーケンスの例を示したものであり、以下のコマンドが使用されています(詳細についてはMAX5290のデータシートをご覧ください)。
- 0xDFFF—すべての入力およびDACレジスタにフルスケールデータをロード、DACのAおよびB出力は更新される
- 0xD800—すべての入力およびDACレジスタにミッドスケールデータをロード、DACのAおよびB出力は更新される
- 0xD000—すべての入力およびDACレジスタにゼロスケールデータをロード、DACのAおよびB出力は更新される
- 0xE400—DAC AおよびDAC Bをシャットダウンモードにする
- 0xE40F—DAC AおよびDAC Bをシャットダウンモードから復帰させる
- 0xFFFF—NO-OP (動作なし)
各デバイスのシフトレジスタにロードされたコマンドは、アクティブローCSの立上りエッジで実行されます。1回目の実行で、すべてのDAC出力が更新されます。IC1のDAC出力はゼロスケールになり、IC2のDAC出力はミッドスケールになり、IC3のDAC出力はフルスケールデータになります。
2番目のコマンドサイクルで、コマンド0xE400によってIC2のDAC AとBの両方がシャットダウンモードに入ります。NO-OPコマンドを受け取ったIC1とIC3は変化しません。3回目のコマンドサイクルの後、IC1の出力はフルスケールに変化し、IC3の出力はゼロスケールに変化します。IC2の出力はシャットダウンのままですが、データは内部の入力およびDACレジスタの中で更新されます。IC2は最後のコマンドサイクルで通常の動作モードに復帰し、出力がフルスケールになります。
Analog Output Name | State of Output | |||||
After Power-Up (PU = VDD) | After First Execution | After Second Execution | After Third Execution | After Fourth Execution | ||
IC1 | A1 | Full Scale | Zero Scale | Zero Scale | Full Scale | Full Scale |
B1 | Full Scale | Zero Scale | Zero Scale | Full Scale | Full Scale | |
IC2 | A2 | Full Scale | Mid Scale | Shutdown | Shutdown | Full Scale |
B2 | Full Scale | Mid Scale | Shutdown | Shutdown | Full Scale | |
IC3 | A3 | Full Scale | Full Scale | Full Scale | Zero Scale | Zero Scale |
B3 | Full Scale | Full Scale | Full Scale | Zero Scale | Zero Scale |
同様の記事が、EE Timesの2006年9月号に掲載されています。
{{modalTitle}}
{{modalDescription}}
{{dropdownTitle}}
- {{defaultSelectedText}} {{#each projectNames}}
- {{name}} {{/each}} {{#if newProjectText}}
- {{newProjectText}} {{/if}}
{{newProjectTitle}}
{{projectNameErrorText}}