SPI3台使いは、ちょっと大変

d161117a2HSES-LCD24ではESP8266(ESP-WROOM-02)のSPIに3つのデバイスが接続されている。TFT LCDとTouchscreenとSDカードスロットの3つだ。1つづつの動作確認は済んでいるのだが、今回初めて3つのデバイスを同時に動作させるプログラムを作ろうとしてトラブった。

各デバイスのライブラリーは、いろいろ提供されている。、SPI接続のライブラリーは基本的にSPIに複数のデバイスが接続されていることをあまり考慮していないので、使用の際には注意が必要だ。

まず、SPIデバイスのCS信号に接続されている端子は、初期化時にHighを出力されるようにされるが、そのまま初期化処理を続行されてしまうので、デバイスの初期化処理(biginメソッド?)を順次呼び出すと、他のデバイスのCS信号が未初期化、INPUTモードでハイインピーダンス状態でSCLK/MOSI/MISOに信号が出てくることになりMISO信号の衝突がありえる。よって、全部のCS信号を自分でHigh出力状態にしてやる必要がある。

bk161117次に、定番!超軽量マイコン用ファイル・システムFatFs (TECH I シリーズ) を読み直してわかったのだが、SDカードは起動時SPIモードで動いていない。起動時はネイティブ・モードで、そこにコマンドを入力しSPIモードに遷移する。SDカードはSPIモードになるまでCS信号がHighでも反応してしまうので、他のSPIデバイスを初期化する前、一番最初に初期化する必要がある。あと、SPIモードでもCSをHighにした後、1byte分クロックをSCLKに送ってやらないとMISOを解放しないらしい。

というような、対応をしてみたが、まだうまくいかない。各デバイスのCS信号をオシロスコープで観測。TFT LCDの使用時、SDカードのCS信号(IO0)がバンバン変化する。調査の結果、Adafruit_ILI9341ライブラリのバグだった。gitHubでは4月にpull requestが出されて修正方法も議論されているように見えるのだが、修正されていない。

自分で以下の修正を行った。

$ git diff -U Adafruit_ILI9341.cpp
diff --git a/Adafruit_ILI9341.cpp b/Adafruit_ILI9341.cpp
index e1b571b..6a15d11 100644
--- a/Adafruit_ILI9341.cpp
+++ b/Adafruit_ILI9341.cpp
@@ -73,7 +73,8 @@ Adafruit_ILI9341::Adafruit_ILI9341(int8_t cs, int8_t dc, int8_t rst) : Adafruit_
   _dc   = dc;
   _rst  = rst;
   hwSPI = true;
-  _mosi  = _sclk = 0;
+  _mosi  = -1;
+  _sclk = -1;
 }

これでプログラム開発を進められる。

ota(Over the Air, WiFi経由のプログラム書き込み)は、とても便利。たまに自分のプログラムのバグで例外を引き起こし、Arduino IDEで書き込まなければならなくなるが、プログラム更新の速さはたまらない。スクロール表示機能も便利でデバッグに活用したくなる。

Leave a Reply

メールアドレスが公開されることはありません。