ESP8266用ILI9341ライブラリの高速化
HSES-LCD24用のILI9341ライブラリとして、Humblesoft_ILI9341を使用している。これは、Adafruit_ILI9341を拡張したもので、Fontxを使った漢字描画機能、scroll機能などが追加されている。 実行速度面では、まったく改善されていない。HSES-LCD24用のデモプログラムを新たに作ろうと思うのだが、描画速度が遅いので、先に高速化を行うことにした。
Adafruit_ILI9341のexamplesにgraphicstestという各種描画機能の実行時間をマイクロ秒単位で表示してくれる。これを使い、実行時間を計測しながら高速化を行った。
最終的な結果の表を以下に示す。塗りつぶし系の描画では7倍前後、あまり高速化できなかったLines等でも1.5倍程度の高速化ができた。 文字の描画も4.68倍高速化されているが、これは若干説明を要する。
今回使用した高速化の手段を以下に示す。
- CS,D/C信号操作の高速化
- SPI大量データ転送の高速化
- クロックの高速化
- 文字描画の高速化
CS,DC信号操作の高速化
まず、Adafruit_ILI9341にある各種CPU対応のコードを削除し、ESP8266専用のコードにした。
次にLCDのCS信号DC信号の操作をdigitalWrite()ではなく、直接GPOS,GPOCレジスタへの描き込むように変更した。このためIO16はCS,DCに使用できなくなった。CS信号の操作を最小限に減らした。
この改造により,ほとんどの描画コマンドで50%程度高速化された。
SPI大量データ転送の高速化
ESP8266 ArdinoのSPIクラスのwriteBytes()メソッドを見てわかったのだが、ESP8266のSPIには64byteのFIFOバッファがあり、それを使うと連続してSPIから信号を出力できる。だが単純なFIFOではなく、専用のレジスタに書き込まねばならず若干面倒。SPI.write()で1byte出力したときはFIFOはつかわれない。SPI.write()を連続して呼び出しても、データの出力はとぎれとぎれで、速くはない。
Adafruit_ILI9341では、SPI.write()を使うのみでSPIのFIFOは使用していない。よって、データをまとめて送れるところは、まとめてSPI.writeBytes()で送るとかなりの高速化ができる。ILI9341の描画で、これができるのは fillScreen(),fillRect()等の矩形の塗りつぶし。あとdrawFastHline(),drawFastVline()も高速化できる。
この改造により関連する描画関数を約4倍、後述するクロックの高速化と合わせて約5倍の高速化ができた。実際のプログラムで画面クリアに使用するfillScreen()/fillRect()の高速化ができたのは効果が大きいと思う。
クロックの高速化
ILI9341のデータシートを調べるとSPIの最大速度(クロックの最大周波数)は10MHzと読める。Adafruit_ILI9341のSPIのクロックの設定は24MH。しかし、問題無く動いていた。調べるとESP8266のSPIクロックは最大80MHz。試しに80MHzでプログラムを動かすと、問題無く動いているように見える。他のプログラムで試した時、80MHzでは書込みミスが発生したので、最終的に40MHzにした。クロックの高速化の影響は、fill系の描画コマンドで大きく、それ以外では僅かしか速くならなかった。
文字描画の高速化
文字の描画は文字毎にフォントデータに従ってdrawPixel()を呼び出すことによって行われる。前景色でのみ描画する場合、SPIの連続書込みによる高速化は難しいが、背景色も塗潰す場合であれば、矩形領域の塗りつぶしとなるので連続書込みで高速化できそうである。最初 Adfruit_GFXクラスのvirtual関数 drawChar()をoverrideして高速化しようとしたが、フォントデータを読み出す方法が無いため諦めた。fontxフォントで背景色も描画する時のみ高速化することにし、Adafruit_GFXクラスのデフォルトのフォントglcdfontと同じフォントをfontxファイルで用意、graphicstestプログラムではtext描画時、fontxを使用し、背景色も描画するようにプログラムを改造した。このことをわかりやすくするためtextの背景色は青色にしてある。
この改造により、5倍近くの高速化が得られた。
改造前後の比較動画
改造の効果を実感するため、比較動画を作成した。
前の動作をみると、改造したくなった気持ちがわかってもらえるのではないかと思う。
さいごに
期待以上の高速化ができたので、あたらしいデモ・プログラム以外にも、いろいろとやってみたいことができた。 ESP8266のSPIで,まとめて送れば高速だが、そうでないと速くないということは覚えておく価値があるだろう。あとILI9341がクロック80MHzでも動作したというのは驚きだ。安全を見て40MHzで使っているが、データシートの記述(動作保証は10MHzまで)は何だったのだろうか。
最近のコメント