帰らざるMOS回路(37) SPIのタイミングチャートをWaveDromで描く

Joseph Halfmoon

前回、フリーのタイミングチャート描画ツールを3種類お試し。どれも特徴があり一長一短デス。その中でWaveDromというツールを使って実際に「ありがち」なタイミングチャートを描いてみることにいたしました。JSONベースのテキストファイルをパースして「よくある」感じのタイミングチャートにしてくれるツールです。

※かえらざるMOS回路 投稿順 INDEX

WaveDromの使い方の参照ページ

WaveDromを使ってタイミングチャートを描く場合、以下のチュートリアルを読むのが良いようです。

Hitchhiker’s Guide to the WaveDrom

まあ、ドキュメントといっても大した長さは無いのですが、必要なところは網羅しているような気がします(個人の感想です。)でもま “Hitchhiker’s Guide”とあるように、コマケーところは自分でいろいろやってみろよ、ってな感じでしょうか。

SPI

SPIは同期式シリアルインタフェース規格の一つです。ほとんどのマイコンにはSPI通信のための周辺回路が搭載されとります。同じくほとんどのマイコンに搭載されている同期式シリアルインタフェースであるI2C規格と比べると、インテリジェンスに若干欠ける(個人の感想です)のですが、より高速な転送が可能です。接続先はメモリやドットマトリックス・ディスプレイなどの比較的高速な転送が必要とされる周辺装置が多いと思います。

SPI自体は、結構「ゆるゆる」した規格じゃないかと思います。標準的には以下の4本の信号で接続することが多いじゃないかと思います。信号名はデバイスにより多少変わるかと。

    1. CS
    2. SCK
    3. MOSI
    4. MISO

CSは「チップセレクト」です。マスタから出力される1組のSPI配線を複数のスレーブデバイスに接続する場合に、「次はお前だ」とスレーブを指定するためのセレクト信号デス。デバイスによっては、1対1なら配線しないという手もありそうですが、デバイスによってはCSがアクティブ(Low)になることで何か内部でアクション始めるものもあるので、お相手次第です。

SCKは同期式シリアルのキモであるクロック信号です。マスタからスレーブへ一方通行です。

MOSIは、マスタからの出力、スレーブへの入力信号です。MISOは、マスタへの入力、スレーブからの出力信号です。2本の信号は独立しているので、通信相手によっては同時に入出力することも信号線上は可能。できるかどうかは、これまたお相手次第です。

「ゆるゆる」というのは、SCKのサンプリングエッジが立ち上がりなのか立下りなのか、停止状態がロウなのかハイなのかなどどれ使っても良いということにも表れてます。今回それを決定する4モード全てをタイミングチャートにしてみました。また、転送するビット順もMSBファーストでもLSBファーストでもありです。スレーブ側は自分によって都合が良いモードだけをサポートしてることが多いと思うのですが、マスタ側はどのような相手でも通信できないとマズイので切り替えられるようになっている筈。SPI使う場合には、データシートを読んで対応するモードや転送順など確かめないとなりまへん。

ブツブツ書き連ねていてもせんないので、アナデバ様のSPIの解説ページへのリンクを貼っておきます。「易しい」日本語ドキュメントね。

SPIの基本を学ぶ

WaveDromでのwaveの記述

SPIモード0(LSBファースト)の場合を例に8ビットの転送を行う場合をタイミングチャートにしてみました。SCKは通常ロウ。立ち上がりエッジでサンプリングするモードです。ツール画面はこんな感じ。SpiMode0_LsbFirst_EC

レンダリングに使ったJSONファイルは以下です。

{signal: [
  {name: 'cs#', wave: 'hl........h'},
  {name: 'sck', wave: 'l.P.......l'},
  {name: 'mosi', wave: 'x.22222222x', data: ['b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7'], phase: 0.5},
  {name: 'miso', wave: 'z.22222222z', data: ['b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7'], phase: 0.5},
],
  head: {
  	text: 'SPI mode 0, LSB first',
  }}
    • 一文字=1クロックが基本

上記のJSONを見ると分かるように、「波形」は wave というプロパティの値の文字列をパースして描かれます。1文字が1クロック分です(WaveDromはクロック同期のフツーのロジック世界用、ということっすね。)

しかし信号によっては逆相にして~とかあるでしょう。そのために phase というプロパティがあり、0.5などとすれば、位相が180度前倒しされるみたいです。これを使ってタイミングは出し入れしてくれってことかい。

また、びっちり文字を並べると分かりずらいと思ったのか、「ピリオド」が使われてます。”.” で左どなりの文字を繰り返したことになるみたいです。

1クロック期間変化しない値を決定するには以下が使えます。

    • h(H) または 1、信号の値はハイ
    • l (L)または 0、信号の値はロー
    • x、unknown
    • z、ハイインピーダンス
    • =、ハイ、ロー2本の並行線

なお、大文字のHとLを使うと変化点に立ち上がり、もしくは立下りの矢印を描けるようです。

一方、1クロック期間でハイ、ローが現れる「クロック」信号としては以下が使えるようです。

    • p, P、ポジティブパルス
    • n, N、ネガティブパルス

大文字のP、Nを使うと、クロック期間の先頭の立ち上がりまたは立下りが矢印になります。

また、2から9の数字を使うとバスなどの信号の背景色を変更することも可能でした(今回使ってないケド。)

SPIモード1(LSBファースト)

SPIモード1、SCKの立下りエッジでサンプリングするモードです。

{signal: [
  {name: 'cs#', wave: 'hl........h'},
  {name: 'sck', wave: 'l.nN......L', phase: 0.5},
  {name: 'mosi', wave: 'x.22222222x', data: ['b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7'], phase: 0.5},
  {name: 'miso', wave: 'z.22222222z', data: ['b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7'], phase: 0.5},
],
  head: {
  	text: 'SPI mode 1, LSB first',
  }}

描画したものが以下に。SpiMode1_LsbFirst

 

SPIモード2(LSBファースト)

SPIモード2、このモードではインアクティブ時のSCKはハイとなります。SCKの立下りエッジでサンプリングするモードです。

{signal: [
  {name: 'cs#', wave: 'hl........h'},
  {name: 'sck', wave: 'h.nN......Lh', phase: 0.5},
  {name: 'mosi', wave: 'x.22222222x', data: ['b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7'], phase: 0.5},
  {name: 'miso', wave: 'z.22222222z', data: ['b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7'], phase: 0.5},
],
  head: {
  	text: 'SPI mode 2, LSB first',
  }}

描画したものが以下に。SpiMode2_LsbFirst

 

SPIモード3(LSBファースト)

SPIモード3はインアクティブ時のSCKはハイ、SCKの立ち上がりエッジでサンプリングです。

{signal: [
  {name: 'cs#', wave: 'hl........h'},
  {name: 'sck', wave: 'hpP.......h'},
  {name: 'mosi', wave: 'x.22222222x', data: ['b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7'], phase: 0.5},
  {name: 'miso', wave: 'z.22222222z', data: ['b0', 'b1', 'b2', 'b3', 'b4', 'b5', 'b6', 'b7'], phase: 0.5},
],
  head: {
  	text: 'SPI mode 3, LSB first',
  }}

描画したものが以下に。SpiMode3_LsbFirst

 

SPIモード0(MSBファースト)

折角なので、SPIモード0の時の、MSBファースト転送も描いてみました。ソースは以下に。

{signal: [
  {name: 'cs#', wave: 'hl........h'},
  {name: 'sck', wave: 'l.P.......l'},
  {name: 'mosi', wave: 'x.22222222x', data: ['b7', 'b6', 'b5', 'b4', 'b3', 'b2', 'b1', 'b0'], phase: 0.5},
  {name: 'miso', wave: 'z.22222222z', data: ['b7', 'b6', 'b5', 'b4', 'b3', 'b2', 'b1', 'b0'], phase: 0.5},
],
  head: {
  	text: 'SPI mode 0, MSB first',
  }}

描画結果が以下に。SpiMode0_MsbFirst

簡単なタイミングチャートなら描けそうな気がしてきた。大丈夫か?

帰らざるMOS回路(36) タイミングチャートを描きて~ ツールは何? へ戻る

帰らざるMOS回路(38) タイミングチャートにsetup/holdを書き込む へ進む