Renesas Synergy™

FAQ 1007013 : ソフトウェアでの3線式シリアルのスレーブ機能検討(78K0S/Kx1+)

3線式シリアルは、ボード内のIC同士の通信に広く利用されていますが、78K0S/Kx1+のようにそのI/Fを内蔵していないマイコンもありま す。ここでは、ソフトウェアでポートを制御して、3線式シリアルのスレーブ機能を実現することを検討します。この場合に考慮すべき内容としては以下の4 点+1点が考えられます。
SCKの有効エッジに対するデータ取り込みの遅延(ソフトウェア対応特有)
バイトの切れ目での処理時間によるデータ間隔
CSIのデータ・クロック位相選択に対する対応
チップ・セレクト(SPI)への対応
ハンドシェイク信号

1. SCKの有効エッジからの遅延
これが通信速度の上限を決めます。3線式シリアル通信ではスレーブからマスタに対してウェイトをかけることができないため、通信クロック(SCK)を遅く することで対応する必要があります。(以下簡単のためにSCKの立ち下がりで送信、立ち上がりで受信するもの(タイプ1)として説明します。)
一番自由度が高いのは、1ビット毎にSCKの有効エッジを検出してベクタ割り込みで処理する方法です。



この場合には各ビットの処理に必ず割り込みのオーバヘッドが付加されるために通信速度が遅くなってしまいます(割り込みからデータ読み込みまで 78K0S/Kx1+では最大23クロック必要。その後の処理を含めると、1ビットを処理するのに70クロック程度必要と考えられます。これは他の処理方 法の約半分の転送速度になります)。
通信速度をできるだけ高くするには、通信を開始したら(例えば、チップ・セレクトを割り込みで検出するなどして通信の開始を確認)、その後はベクタ割り込みではなくポーリングで処理するか、HALTモードに設定して、割り込みでHALTモードを解除することが考えられます。さらに、送受信ではなく、送信のみ/受信のみの制限が必要になります。
(1)受信処理の場合の検討
HALTモードを用いた受信を考えると、1ビットに対して、以下の例のような処理となります。そうすると、1ビット当たり単純な処理時間は28クロックとなり、高速内蔵発振クロックを使用した8MHzでの動作で考えると3.5μsとなるので、約280kbps程度の通信速度となります。



このときのプログラム例として、SI入力からビット7を取り込む例を以下に示します。

HALT                                    ;2+4:SCKのエッジ検出待ち
BF      Port_SI,$Datais0                ; 10:データ確認
SET1    CSI.7                           ;  6:ビット7受信
Datais0:
CLR1    PIF0                            ;  6:割り込みフラグクリア

これをポーリングで処理する場合、SI信号とSCK信号を同じポートに割り振ったとすると、下記のプログラム例が考えられます。



LOOP:
MOV     A,Port_S ; 4:端子データの読み込み
BF      A.SCKbit,$LOOP ; 8:SCKの立ち上がり待ち
BF      A.SIbit,$Datais0 ; 8:SIデータの確認
SET1    CSI.7 ; 6:ビット7受信
Datais0:
BT      Port_SCK,$$ ;10:SCKがロウを確認

この例では受信データの反映までの処理(Datais0:の 前までの処理)は単純に計算すると26クロックとなり、計算すると約300kbps程度の通信速度となります。しかし、SCKの立ち上がりとその確認の同 期関係がないため、最悪では2回ループすると考えると36クロック必要になります。その後にSCKがロウ・レベルであることを確認すると、1ビットあたり 41クロック必要になります。これは200kbps弱の転送速度になります。これが安定して転送可能な値です(下記の最悪のタイミング例を参照してくださ い)。



より高速の転送が要求される場合には、転送速度に下限を設けることで、SCKのロウ・レベル状態の確認を省略して、ある程度は高速化対応が可能です。 SCKのハイ・レベル幅が20クロック未満(転送速度では約160kbps以上)の条件があれば、SCKの立ち上がり直後に確認できたとしても、次のビッ トのSCK確認までにはSCKは確実に立ち下がっているので、SCKがロウ・レベルであることの確認が省略できます。



この場合の動作タイミング例を以下に示します。この例のように、最初のSCKのチェックでハイ・レベルが確認できなくても、2回目のチェック(12クロック後)で確認できます。そこから26クロックで次のビットのSCKのチェック(及びSIデータの取り込み)を行いますが、そこから後では1回で済むので、転送速度は300kbps程度までは対応可能になります。



このように、ポーリングの場合には条件をつけることで、より高速の転送が可能になります。

コーヒー・ブレーク
同様の処理は以下のように記述しても実現は可能です。1ビットのデータを同じクロック数で処理でき、しかも信号を同じポートに配置する必要はありません。 ただし、SCKの立ち上がりの確認からSIの確認(読み込み)の間隔が必ず1命令分(10クロック)空いてしまいます。SCKの立ち上がりのタイミングと 確認のタイミングが非同期のためにSCK立ち上がりから最悪10クロック遅れで確認され、さらに10クロック遅れてSIが読まれることになります。そうな ると、SCKのハイ・レベル幅(実際にはSCKの立ち下がりに対するデータの保持時間)が20クロック必要になり、SCKのデューティが50%なら、1 ビットの処理に最悪40クロックかかる場合が考えられます。しかし、この場合には、条件をつけても高速化はできません。

LOOP:
BF      Port_SCK,$LOOP ;10:SCKの立ち上がり待ち
BF      Port_SI,$Datais0 ;10:SIデータの確認
SET1    CSI.7 ; 6:ビット7受信
Datais0:
BT      Port_SCK,$$

 


(2)送信処理の場合の検討
次に送信の場合を考えます。この場合には、以下のような処理が考えられます。

ROL     A,1 ; 2:出力データをキャリーへ
BC      $Data1 ; 6:データが1なら分岐
BT      Port_SCK,$$ ;10:SCK立ち下がり待ち
CLR1    Port_SO ; 6:送信
BR      $NEXTbit ; 6:次のビットへ
Data1:
BT      Port_SCK,$Data1 ;10:SCK立ち下がり待ち
SET1    Port_SO ; 6:送信
NEXTbit:
BF      Port_SCK,$$ ;10: SCK立ち上がり待ち

ここで、単純に時間を計算すると、最悪の場合では1ビットあたり42クロック必要になります。データのセット・アップ時間を考慮すると44クロック(約180kbps)程度の転送速度となります。



以上の考察より、送信/受信で対応できる最大の転送速度は180kbps程度と考えられます。(なお、125kbps以上の制限をつけると、250kbps程度までは対応できそうです)

(3)送受信処理の場合の検討
送受信を行う必要性は低いと考えられますが、一応検討だけはしておきます。これまでの検討結果より送信だけで1ビットあたり44クロック程度となるので、 受信処理はコーヒー・ブレークに記載した方法でも可能になります(これにより、Aレジスタは送信専用に使用できるようになります)。この場合の1バイトの 処理に必要なプログラムは以下の例のようになります。ここでは、プログラムの大きさを考慮して、8回ループすることで1バイトのデータを処理しています。

RTXBYTE:
MOV     B,#8                            ;ビット数をセット
LOOP:
CLR1    CY ; 2:次のビット用にクリア
ROLC    A,1 ; 2:出力データをキャリーへ
BC      $Data1 ; 6:データが1なら分岐
BT      Port_SCK,$$ ;10:SCK立ち下がり待ち
CLR1    Port_SO ; 6:送信
BF      Port_SCK,$$ ;10: SCK立ち上がり待ち
BF      Port_SI,$RDatais0 ;10:SIデータの確認
SET1    A.0 ; 6:ビット7から順に受信
DBNZ    B,$LOOP                         ; 6:8ビット分繰り返し
BR      $RTXEND
Data1:
BT      Port_SCK,$Data1 ;10:SCK立ち下がり待ち
SET1    Port_SO ; 6:送信
BF      Port_SCK,$$ ;10: SCK立ち上がり待ち
BF      Port_SI,$RDatais0 ;10:SIデータの確認
SET1    A.0 ; 6:ビット7から順に受信
RDatais0:
DBNZ    B,$LOOP                         ; 6:8ビット分繰り返し
RTXEND:

この例では必ず、立ち下がりと立ち上がりエッジを待って処理を行います。そのため、受信から次の送信までの処理が最悪64クロック必要(下記のタイミング例を参照)になり、これが全体のボトルネックになります。命令の並びを変更して、CLR1 CYROLC A,1を送信の直後に移動することで、SCKの立ち上がり検出から次のビット送信までの時間を4クロック短くできます。



これだけでは効果として少ないので、別の手段を考えます(実行する命令数を削減)。これまでのプログラム例はSCKの立ち上がりを確認してデータを取り込 んでいました。これを見直します。送信ではSCKの立ち下がり検出後データを出力していますが、その直後にデータを取り込んでしまうことを考えます。マスタからの送信はSCKの立ち下がりからせいぜい500nsで完了します。従って、SCKの立ち下がり検出後のデータ出力の直後にデータを取り込んでも正しいデータは読めることになります。これを反映すると、以下の例のようになります。

RTXBYTE:
MOV     B,#8                            ;ビット数をセット
LOOP:
CLR1    CY ; 2:次のビット用にクリア
ROLC    A,1 ; 2:出力データをキャリーへ
BC      $Data1 ; 6:データが1なら分岐
BT      Port_SCK,$$ ;10:SCK立ち下がり待ち
CLR1    Port_SO ; 6:送信
BF      Port_SI,$RDatais0 ;10:SIデータの確認
SET1    A.0 ; 6:ビット7から順に受信
BF      Port_SCK,$$ ;10: SCK立ち上がり待ち
DBNZ    B,$LOOP                         ; 6:8ビット分繰り返し
BR      $RTXEND
Data1:
BT      Port_SCK,$Data1 ;10:SCK立ち下がり待ち
SET1    Port_SO ; 6:送信
BF      Port_SI,$RDatais0 ;10:SIデータの確認
SET1    A.0 ; 6:ビット7受信
RDatais0:
BF      Port_SCK,$$ ;10: SCK立ち上がり待ち
DBNZ    B,$LOOP                         ; 6:8ビット分繰り返し
RTXEND:

この変更によりSCKの立ち上がり待ちでの不要なループを回さないようにします。これで10クロック分は処理を短くできます。これ以上短縮するには、転送速度に下限を設けることで、SCKの立ち上がり待ちそのものをなくす必要があります(SCKの立ち上がり待ちは次のビットのSCKの立ち下がりを検出するための処理です。転送速度の下限を設けることで必要なくなります)。そうすると、およそ170kbpsまでは対応できる可能性があります。

2. バイト切れ目での処理
マスタが連続転送のためのハードウェアを内蔵している場合には、データ転送の間隔を指定できます。従って、スレーブではどの程度の間隔が必要かを明確にするだけで十分です。
また、そのような機能を内蔵していないインターフェースの場合には、転送完了から次の転送を起動することになり、完全に切れ目なしでの転送はできません。このため、通常は転送クロックで1クロック分は間隔が空くと考えられます。
また、送受信データの取り扱いは上位のソフトの問題になるので、ここではハンドシェイクで対応することにします。「5. ハンドシェイク信号」も参照してください。

3. CSIのデータ・クロック位相
一つのプログラムでいくつもの通信タイプに対応するのは適切ではないと考えられます。どれか一つ(例えば、従来のSIOと互換のタイプ1)に絞り込む必要があります。
タイプ1とタイプ3についてはSCKの論理が反転しているだけなので、タイプ3への変更は比較的簡単に実現できます。
タイプ2と4はデータの受信についてはタイプ3や1と同じタイミングなので、問題はないと考えられますが、タイプ2と4の送信では注意が必要です。

4. チップ・セレクト(SPI)への対応
SPIの スレーブとしてはチップ・セレクトのサポートが必要ですが、チップ・セレクトがアクティブになってから実際に通信を開始できるまでの時間に制限がありま す。どのような方法でチップ・セレクトを検出するかでも変動しますが、ベクタ割り込みを用いて、そこから全ての準備を行う場合のプログラム例を以下に示し ます。この例では通信開始までに約10μs程度の時間が必要となります。SPIのスレーブとして使用する場合には、この時間に十分注意する必要があります。(ただし、ハンドシェイク信号を利用することで、回避することができます。)

__INTP1:
PUSH    AX                      ; 4:使用レジスタをセーブ
PUSH    HL                      ; 4:
SET1    P4.5                    ; 6:SOを1に
CLR1    PM4.5                   ; 6:SOを出力に
BF      TXFLAG,$RXDATA ;10:フラグが0なら受信処理へ
MOVW    AX,TXPOINTER            ; 6:送信ポインタ読み出し
MOVW    HL,AX                   ; 4:
TXLOOP:
MOV     A,[HL]                  ; 6:送信データ読み出し
INCW    HL                      ; 4:ポインタ更新
MOV     TXCOUNT,#8-1            ; 6:ビット長を設定
;
;  送信準備
;
LOOP0:
ROL     A,1                     ; 2:MSBをキャリーへ

この時間を短くするには、前もって通信(特に送信のデータ)準備を行い、ベクタ割り込みではなく、ポーリング等でチップ・セレクトの立下りを待つ必要があります。通信の手順やタイミング及び通信タイプが前もって決まっている場合には、そのような制限をつけることで、2~3μs程度の時間に短縮は可能です。
たとえば、送信データの最初のビットを前もって、SOに出力できるように出力ラッチにセットしておき、チップ・セレクトの立下りを検出したら、直ちにポー トを出力に設定します。そうすると、通信準備(実際には最初のビットの送信)までは割り込みオーバヘッド+6クロックで処理可能です。HALTと組み合わ せるとさらに応答時間を1μs強まで短くすることができます。

;
; 前もって、送信データの最初のビットをP4.5しておく、
;
__INTP1:
CLR1    PM4.5 ; 6:SOを1に
PUSH    AX                      ; 4:使用レジスタをセーブ
PUSH    HL                      ; 4:



このようにチップ・セレクトからの動作時間(出力)は通信動作に影響を与えないレベルまで小さくすることは可能ですが、チップ・セレクトが切れてからSOをハイ・インピーダンスにするまでの時間は、チップ・セレクト信号と次のデータ転送SCKの確認の時間が必要なために3~4μs程度の時間となります。この部分のプログラム例を以下に示します。

LOOP1:
BF      P4.0,$TXSTART0 ;10:SCKの立下りで送信へ
BF      P4.3,$LOOP1 ;10:CSがロウなら継続
;
;  送信処理完了
;
TXEXIT:
SET1    PM4.5 ; 6:SOをHi-Zに

この処理での最悪のタイミングを以下に示します。チップ・セレクトの立ち上がり確認のループ(20クロック)が遅延量を決定してしまいます(①ではロウ で、②でハイになったことを確認。これが20クロック)。そこからポートを入力に変更③します。SCKは④以降であれば無視されますが、③まではSOが出 力状態であるため、⑤以降でないと変化できません。



なお、SPIのマスタはチップ・セレクト信号を通常はポートを用いて制御すると考えられるので、ここらのタイミングをあまり厳密に検討する必要性は高くないと考えられます。

5. ハンドシェイク信号
3線式シリアルでは、マスタが通信を始める前に(SCKを出力する前に)、スレーブが動作可能になっている必要があります(マスタがSCKを出力する前に スレーブが動作開始していないと、マスタとスレーブでビットがずれてしまいます。ここらの詳細に関してはマイコンFAQの「78Kデバイス」-「シリアル 通信」-「ハンドシェイク[共通的な内容]」 も参照してください。)。スレーブが動作可能になっていることをマスタが確認するためには、スレーブは状態を示すためのハンドシェイク信号を出力する必要 があります。SPIでの複数のスレーブ接続を考慮すると、転送許可にオープン・ドレイン(+通常出力)のBUSY信号を使用することになります。チップ・ セレクト信号で選択されたスレーブが通信準備を完了したらBUSY信号をロウ・レベルにし、マスタに対して通信準備ができたことを知らせます。
このときのタイミング例を示します。

  マスタがチップ・セレクト信号でスレーブを選択します。スレーブがそれを認識するまでは、BUSY信号はハイ・インピーダンス状態です。
  選択されたことを認識して通信可能になるとBUSY信号を立ち下げます。BUSY信号が立ち下がったことを確認したら、マスタは通信を開始します。
  マスタからの通信がスタートすると、BUSY信号を立ち上げます。
  通信されたデータを処理して、次の通信準備が完了するとBUSY信号を立ち下げます。
  ③と同じ動作の繰り返しになります。
  ④と同じ動作の繰り返しになります。
  チップ・セレクト信号が切れると、BUSY信号を立ち上げて、ハイ・インピーダンス状態にして通信を終了します。


基本的にこのハンドシェイク信号が利用できれば、転送速度を除いてタイミングの問題は緩和されます。



[注意]
③や⑤のタイミングでBUSY信号は通信完了よりはるかに早いタイミングで立ち上がりますが、マスタの制御によっては実際の通信が始まる前に次の通信準備を行うことも考えられます。その場合にはBUSY信号の立ち下がりエッジを確認してから次の通信を行うようにする必要があります。

 

適用製品

78K0S/Kx1+
他にご質問がございましたら、リクエストを送信してください