FreeBSDでSPIの液晶を制御するためのmrbgemとして作りました。当初は汎用のmruby-bsdspiとmruby-bsdgpioを使っていましたが、最適化のためと初期化などを共通化しています。
これまではmrbgemはCでしか書いてなかったのですが、Cとrubyコードを使うようにしました。理由は忘れてしまったのですが、mruby-bsdspiは継承せずにobjectからのクラスになっています。CコードはOSへのアクセスや最適化が必要な部分でrubyコードは初期化などテスト用のスクリプトで書いたものを入れました。
変数の処理もCコードで実装してrubyコードからはselfでアクセスできるようにしています。
サポート対象は以下の三種類です。
チップ | メーカー | サイズ | 信号線 | 入手先 |
---|---|---|---|---|
S6D0151 | SAMSUNG ELECTRONICS | 128x160 | 4本 | aitendo |
ST7735 | Sitronix Technology | 128x160 | 5本 | aitendo |
ILI9341 | ILI TECHNOLOGY | 240x320 | 6本 | Amazon |
S6D0151はSPIのCLK,MOSI,CSとRESETだけで操作できます。他の二つはコマンドとデータを区別するRS信号が必要になってます。ILI9341は読み出しの信号がありますが、他の二つはありません。ST7735はいくつかタイプがあるようなので、動かないものがあるかもしれません。
S6D0151の接続は以下のようになります。
MOSI,CLK,CSはspigenで処理してRESETはgpioctlで処理する事になります。
簡単な使い方を書きます。
tft = BsdTft.new(1, 0, BsdTft::S6D0151)
newの最初のパラーメータはspigenデバイスの番号で、二つ目はGPIOの番号、三つ目は液晶モデルになります。
tft.setsize(W, H)
tft.setreset(RST)
tft.init
画面サイズや、RESET信号のGPIOピンを設定して初期化します。
tft.lcdcopy(c.get_data)
Cairoで書いた画面を液晶に転送します。テストスクリプトでは、rubyコードで処理していたのですが、処理が遅かったので、rubyでは処理せずポインター渡しにしました。240x320で2秒弱で128x160は1秒弱で再描画できます。もう少し早いと良いのですが、開発を始めた当時に比べるとかなり早くなっています。
小型液晶のFreeBSDでの利用はST7735が最初だったのですが、このクラスは最初にS6D0151用として作り、ST7735も取り込みました。
ST7735はBigEndianのAtherosのSOCで試していて、他の二つはLittleEndianのRalinkで試しました。RalinkのセカンドSPIのサポートはこのために作りました。
Ralink(mips/mediatek)のSPIのコードはFlashに依存したコードになっていて、spigenを使ったら動きませんでした。本来は整理すべきだとおもうのですが、ちょっといじったら動かなくなってしまい、見通せてない部分があるのと、問題があると起動できなくなるなど、影響範囲が大きいのでアドホックな修正になっています。このことは指摘されたのですが、adrianさんが状況を理解してくれてコミットしてもらいました。
Atherosの方はrayが作ったGPIOのBitbangのSPIでのアクセスで処理しています。
このクラスは三種類のチップを透過に扱えSOCにも依存していません。ILI9325のパラレルIF用にmruby-gpiotftというクラスも作ったのですが、これはGPIOの32ビットアクセスを使用していてAllwinnerのA10や接続に依存している部分があり、あまり汎用的になっていません。
液晶コントローラーは他にもありますが、この三種類は日本で手に入りやすい方だと思います。
野ざらしの基板だとホコリまみれになるので、なにかに収めてすぐに試せるようにしたいが、妙案がありません。
240x320な液晶ではアウトラインフォントなどを使いたいのでストレージが無限に使えるUSBがついたターゲットが良い気がします。128x160な液晶ではビットマップフォントだけで良いので8M Flashなターゲットでもいろいろできそうです。
AR2315でmruby-bsdspiを試したところreadが上手く出来ませんでした。spiコマンドでも同じだったので、spigenの問題のようです。tftの処理は書き込みで完結していて、これは問題ないのだが。なんでだろう?(2923/10/14)