参考: SPI Master (VHDL) - Logic - Engineering and Component Solution Forum - TechForum │ Digi-Key
上のリンクに紹介されているSPIマスターを試してみる。
非公式訳:
SPIマスター
特徴
- (略)
- スレーブの個数が指定できる。
- データ幅が指定できる。
- 極性、位相がスレーブごとに選択できる。
- クロック速度がスレーブごとに選択できる。
はじめに
(略)
基本情報
(略)
(略)
SPIには、クロック極性(CPOL)とクロック位相(CPHA)という2つのパラメーターによって決まる4つの動作モードがあります。マスターとスレーブとで同じモードを使わないと正しい通信はできません。CPOLが0の場合、SCLKは通常Loであり、最初のクロックエッジがrising edgeです。CPOLが1の場合、SCLKは通常Hiであり、最初のクロックエッジがfalling edgeです。CPHAはデータの配置を規定するパラメーターです。CPHAが0の場合、SS信号のfalling edgeで最初のデータビットが通信ラインに書き出され、最初のSCLKエッジ(訳註: CPOL次第でrinsing edge、falling edgeのどちらか)でそのでデータビットが通信ラインから読み取られます。CPHAが1の場合、最初のSCLKエッジ(訳註: CPOL次第でrinsing edge、falling edgeのどちらか)でデータビットが通信ラインに書き出され、その次のSCLKエッジ(訳註: 前のエッジがrisingならfalling、fallingならrising)でそのデータビットが通信ラインから読み取られまれます。図2のタイミング図に4つのSPIモードを示します。
訳註: 要するに、
CPOL=0はクロックが正論理
CPOL=1はクロックが負論理
CPHA=0はSCLKのleading edgeでラインから読取、trailingでラインへ書出(一発目だけSSのfallingでラインへ書出)
CPHA=1はSCLKのleading edgeでラインへ書出、trailingでラインから読取
ポートの説明
SPIマスターの各ポートについて表1で説明します。スレーブの個数はgeneric
パラメーターslaves
としてentity
で宣言しています。送受信のデータバス幅はgeneric
パラメーターd_width
としてentity
で宣言しています。
Mがデータ幅、Nがスレーブの個数
クロック動作
clock
、clk_div
の2つの入力によってSCLK (SPIのデータレート)の周波数が決まります。clock
は、コンポーネント内部の同期ロジックの動作に使うシステムクロックです。clk_div
の整数入力で、相対的な処理速度が設定できます。clk_div
は、式1に表現したように、SCLKの半周期におけるシステムクロックのクロック数のことです。
(1) fsclk = fclock / (2 * clk_div)
clk_div
ポートを1にすると、SCLK周波数はclock
周波数の半分になり、今回のVHDLでの最大のデータレートに設定されます。clk_div
の値は、1回のトランザクションが始まるたびにenable
ポートによってラッチされるため、複数あるスレーブごとにデータレートを変えることができます。
clk_div
ポートを定数に設定すればデータレートは固定されます。clk_div
を0に設定しても、それは1と見なされます。したがってclk_div
ポートをLoに配線しておけば常に最大速度で動作します。
極性と位相と
enable
ポートは、1回のトランザクションが始まるたびに、cpol
、cpha
の値をラッチする働きをします。そのため、複数あるスレーブごとに別々のSPIモードで通信ができます。すべてのスレーブが同じモードでよければ、それに応じたロジックレベルにcpol
、cpha
を配線しておくだけで構いません。
トランザクション
busy
出力ポートがLoであれば、コマンドの受け容れ準備が整っています。enable
入力ポートがアサートされた状態であれば、clock
の最初のrising edgeのところで、トランザクションのための各種設定、アドレス、データがラッチされます。その次のclock
でbusy
信号がアサートされ、トランザクションが始まります。トランザクションが完了すれば、受信したデータがrx_data
ポートに出力されます。このデータは、そのあとのトランザクションから新たなデータを受信するまではrx_data
ポートに出力されたままです。このときbusy
信号はLoですので、データが受信されたことがわかるとともに、すぐに別の命令に応じられる状態にあることも分かります。
図3に、典型的なトランザクションのタイミング図を示します。スレーブは4個、4ビットデータ幅で実体化してあります。ここでは、SPIモード3 (CPOL=1,CPHA=1)で動作していスレーブ2へ向けて"1001"というデータを送信しています。マスターは"1010"というデータを受信しています。
連続モード
SPIマスターは、最後の受信ビットのところでcont
フラグを読み取ります。それがLoの場合は上記のとおり通信が完了します。それがHiの場合、SPIマスターはtx_data
ポートのデータをラッチし、現在のデータが尽きたらとぎれずにすぐに新しいデータで送信を続けます。現在のデータの最後のビットが終了したら(すなわち新しいデータの最初のビットがmosiポートに現れたら)、SPIマスターは、受信データの最初のブロックをrx_data
ポートに出力し、busy
信号を1 clock
サイクルだけアサート解除して、この受信データが取得できるようになったことを示します。新たなデータ通信が完了して後続の受信データブロックが取得できるようになるまでは、rx_data
ポートのデータは変化しません。
図4は、連続モードを使ったトランザクションのタイミング図です。SPIマスターは、スレーブ4個、2ビットデータ幅として実体化してあります。SPIマスターが、最初のデータ"10"
をラッチするとすぐに、cont
ポートがHiになって、tx_data
ポートには新たなデータ"01"
が現れます。SPIマスターは、その新たなデータをラッチしたあと、busy
ポートをLoにすることで、cont
ポートとtx_data
ポートとをクリアして構わないという合図を出すとともに、最初の受信データ"01"
がrx_data
ポートに現れたということも示します。トランザクションが完了すると、busy
信号は再度アサート解除され、新たなrx_data
である"10"
が取得できる状態となります。
連続モードは、常時オンにしておけば、非常に長いデータストリームのトランザクションを可能にします。cont
ポートをLoに配線すれば連続モードは無効化されます。
リセット
(略)
まとめ
(略)