SPIとLEDディスプレイのデバッグ備忘録

午後3時まで調子が出てやってたデバッグ作業について、忘れないうちにメモ。
例によって思い込み≒アレゲ


問題点の概要

  • AVRのSPIのディレクションは一部ユーザー定義が必要
  • SSを入力にしておくとLでスレーブに自動切り替わりが行われる
  • HCMS-27XXのレジスタロードのタイミング
  • リセット後はスリープになっている
  • BLANKの極性
  • 制御レジスタの構成

SPIのディレクションの設定

AVRのペリフェラルは基本的に、"ペリフェラルON→I/Oポートオーバーライド信号でI/Oポートのディレクションと値を乗っ取って動作開始"というタイプだと認識していたので、SPIも同じようにしてSPIイネーブルをONにしたが、信号が出てこない。
実はSPIはマスタ/スレーブともに一部の信号の方向はユーザー定義が必要になっているということをマニュアルを読んで知った。
マスタの場合、入力になるMISOは入力固定だが、MOSIとSCK、SSはPORTレジスタを明示的に出力にしないと出力ができない。
これを行っていなかったので、値が浮いていてテスタで測ったら不定値な感じになっていた。

スレーブモードへの自動切り替え

SPIのディレクションと同じような問題だが、SS(PB2)ポートが入力になっている状態で、SSがLになるとSPIの動作モードがスレーブに切り替わる。
スレーブに切り替わると、クロックの入出力が逆になったり、SPIの割り込みフラグが立ったりするため、割り込みフラグを監視して動いていると誤動作が発生したりする。
これを避けるためには、SSの信号を出力で使う必要がある。今回はもともと別のピンに割り当てていたLEDディスプレイモジュールのCEをSSピンに割り当てることで解決した。
マスタで使ってるからSSは関係ないだろうと思っていたら引っかかった。
スレーブデバイスが1つしかない場合はSSをセレクトピンに使い、複数ある場合でもSSは最初に使うようにした方がよさそう。

HCMS-27XXのレジスタロードタイミング

HCMS-27XXのレジスタはCEが↑のタイミングではなく、CEがHかつ、CLOCKが↓のタイミングでシフトレジスタからロードされる。
等価ブロックダイアグラムにはそのことは書いて無く、信号タイミングの波形例の下に注意書きとして書いてある。
これはもともとAVRのSPIのように必要な時だけクロックが動くタイプではなく、クロックが常時動いていてそれに合わせて信号が出てくるようなものを想定しているからっぽい。
CEをHにした後、SPDRにダミーデータを書き込み、クロックを動かしたことでロードされるようになった。

リセット後はスリープになっている

リセット信号によってコントロールレジスタはALL0になり、その状態ではスリープモードになる。
スリープモードではクロックの発振が止まり、表示もディスエーブルされるので全く動いていないように見える。
始めにこの状態を知らず、さらにロードタイミングの問題も解決していなかったため、表示が全く出てこない状態から長らく抜け出せなかったので、心労(吹っ飛ばしたんじゃないか…)で疲れた。

BLANKの極性

表示を止めるBLANK信号が有効になるのはHのときかLのときか、データシートからはどちらとも取れたので、実際に試したところ、BLANK=Hで消灯/Hで点灯だった。

制御レジスタの構成

4文字ごとに制御レジスタがある。8文字の場合、データ信号がシリーズ接続(DOUT→DIN)され、それ以外の信号はパラレルで接続されているっぽい。そのため、制御レジスタに書き込む場合は、値を複数回(今回の8文字×2の場合は4回)書く必要がある。
レジスタ設定ですべての制御レジスタを並列接続して、一括更新するモードにも切り換えられるらしいが、まだ試してない。


表示が出てしまえば、苦労もいい思い出。
今はwhile Loopで行っている待ち合わせにタスク制御関数を入れて待ち時間に別タスクが走るようにしよう。
その前にfosc/128で動いている現状をもう少し早くすることから始めるか。