TT Lab
はじめる
学ぶ 学習パス コース

センサーは正常なのに、ボードが聞き取れない

配線は合っているのに値だけが二倍

TT Labで続きを見る

一言でいうと

SPIにはクロックの線があるので、速度の問題がありません。その代わり、どのエッジで読むかが設定として残っていて、その設定がずれると、1ビットずつずれた値が出ます。

なぜ必要なのか

新しいフラッシュチップでメーカーIDを読んだら、見当違いの値が出ます。配線を3回確認しましたし、クロックも入っていて、チップも応答します。値だけがおかしいのです。こうした形は、たいてい配線ではなくモードです。そしてモードは、データシートの表の1マスにしか書かれていないので、目で見落としやすいです。

SPIは、規格書のない事実上の標準なので、用語もメーカーごとに少しずつ違います。そのため、なおさら「ドキュメントに何と書いてあるか」より、「波形が何と言っているか」のほうが早いです。幸い、SPIの波形は、モードを自分で語ってくれます。

どう動くのか

線は4本です。選択線(CSまたはSS)、クロック(SCLK)、マスターが送るMOSI、スレーブが送るMISO。選択線がローの間だけが転送で、クロックのエッジごとに、ビットが1つ行き来します。双方向が同時に起きるので、読み取りのコマンドを送るときも、MOSIには何かが載っている必要があります。

設定は2つだけです。CPOLは、休んでいるときにクロックがハイかローか、CPHAは、前のエッジで読むか後ろのエッジで読むかです。2つを組み合わせて、モード0から3と呼びます。TIのSPIのユーザーガイドも、この2つの値を、別々の設定として扱っています(SPRUGP2)。sigrokのSPIデコーダーが受け取る設定も、cs_polarity、cpol、cpha、bitorder、wordsizeの5つです(ドキュメント)。波形だけでは決められないものが何かを、このリストが語っています。

CPOL=0 CPHA=0 (모드 0)            CPOL=1 CPHA=1 (모드 3)
SCLK  __/‾\_/‾\_/‾\__            SCLK  ‾‾\_/‾\_/‾\_/‾‾
읽는 곳  ^   ^   ^                읽는 곳   ^   ^   ^
         상승 모서리                        상승 모서리

ここに、初心者をつまずかせる事実が1つあります。モード0とモード3は、同じエッジで読みます。上の図で、どちらも立ち上がりエッジです。モード1とモード2も同様に、互いに同じエッジ(立ち下がり)を使います。そのため、クロックのエッジだけを見て、4つのモードを区別することはできません。残り半分の情報は、休んでいるときにクロックがどこにあるか、つまりCPOLです。波形からモードを決めるには、2つを別々に見る必要があります。

CPHAを決める方法は、もっとおもしろいです。実際の素子は、クロックのエッジですぐにデータを変えるのではなく、出力有効遅延のあとで変えます。そのため、波形でMOSIが動く時刻の直前のクロックのエッジを探すと、そのエッジは読むエッジではない側です。読むエッジは反対側で、それがアイドルから離れる前のエッジならCPHA=0、そうでなければCPHA=1です。データが変わるエッジで読むと、直前のビットを拾ってしまうので、全体が1つずれた値が出ます。先ほど言った「見当違いのID」の正体です。

選択線のタイミングも、静かな故障を生みます。CSが最初のクロックエッジよりも遅く下がると、そのエッジは転送に含まれません。スレーブは最初のビットを受け取れなかったのに、マスターは送ったと信じています。波形では、CSがローの間のサンプルのエッジの数が、8の倍数ではないことで明らかになります。このコースのキャプチャでは、24個あるべきエッジが23個で、7ビットが余ります。余るビットがあるということは、バイトの境界がずれたという意味で、値ではなく個数が先に語ってくれます。

バイトの順序も、確認の対象です。大部分は上位から送りますが、下位から送る素子があり、波形だけではどちらかわかりません。これは、ドキュメントを見る必要がある項目です。

最後に、クロックの周波数は、故障の原因になりにくいです。SPIはクロックの線をあわせて送るので、マスターがゆっくり揺らせば、スレーブもゆっくりついてきます。UARTと違って、「速度が合わない」という言い方は成り立たず、その代わり、素子が耐えられる最大の周波数だけが、データシートに書かれています。そのため、SPIで値がおかしければ、速度よりも、エッジと選択線を先に見ます。

現場での姿

最もよくある報告は、「読んだ値が2倍か半分」です。1ビットずれた値は、16進数で見ると、まさにそう見えます。0x9Fを1ビット左にずらすと0x3E、右にずらすと0x4Fです。値を見て「2倍くらいだな」という感じがしたら、モードから疑うほうが早いです。

複数のスレーブが1本のバスを分け合って使うボードでは、モードが混ざる事故が起きます。各スレーブは自分のモードを要求するのに、ドライバーが転送ごとにモードを切り替えてくれなければ、読めるチップと読めないチップが出ます。「このセンサーだけ動かない」という報告の相当数が、ここです。

次のクイズで確認すること

CPOLとCPHAがそれぞれ何を決めるのか、なぜエッジだけを見て4つのモードを見分けられないのか、データが変わるエッジでCPHAをどう決めるのか、選択線が遅れたときに、波形のどの数字が先におかしくなるのかを問います。