Cmod A7ボード(FPGA)を使って、オリジナル16ビットCPUコアMoscoviumの開発を進めています。
前回までに、SPI-TFT表示器をCmod A7ボードのPMODコネクタに接続するアダプタボードや、その状態でSPI-TFT表示器を制御するためのハードウェア(SPI-TFT制御STFT61ユニット)を設計完了しました(下図)。
今回は、ソフトウェア視点👁️からSPI-TFTを使い易くするため、Blockly for Moscoviumにカスタムブロックを追加して行こうと思います。
まず、SPI-TFT表示器を制御するのに最低限必要なブロックを考え、そこから、あると便利なブロックへと考えを巡らせながら、まとめてみました。
SPI-TFT制御用カスタムブロック目標仕様:
描画ルーチンは、最低限の点描画ブロックと、矩形描画ブロックだけ作っておきますので、その他の描画機能(円や直線など)は、各自作成!で、お願いいたしますm(1^_^;)m。
目標仕様に基づき、具体的イメージに落とし込んで作成したカスタムブロックは、以下図の様になりました。
詳細は、こちらのリンクからご確認ください。
Blockly.XML→Moscovium.ASM変換スクリプトおよび、ランタイムライブラリを更新すると共に、SPI-TFTを制御するライブラリファイルを追加しました。まとめて、こちらからダウンロードしてください。
Blockly for Moscovium開発環境の構築については、こちらの記事をご参照ください。既に環境を立ち上げ済みの場合でも、今回の拡張に伴い、以下のファイルを更新する必要があります。
今回追加したSPI-TFT制御ライブラリでは、ラスタグラフィックスの基本である点描画機能と、矩形描画機能に対応しています。応用でSPI-TFTに図形を描画する時、斜めの直線くらいは引きたくなるだろうと想像し、Blocklyで直線描画関数を起こしておきました。
直線描画アルゴリズムについて、以下に解説しておきます。
直線描画アルゴリズム:
上のアルゴリズムで、一応、それらしき線は描画できます。ただし、ほぼ水平だったり、ほぼ垂直の線を描画する場合等、均整の取れた綺麗な線とは、ならない場合があります。また、ドット毎に乗・除算を実行しているため、描画も、あまり速くありません。
ラスタグラフィックスの直線描画アルゴリズムは、Bresenham直線描画が有名です。Bresenhamの方が速いし、線も綺麗なので、本格的に綺麗な線を引きたいなら、Bresenhamを学習する事を推奨いたします。筆者のアルゴリズムだと、まだ、4〜5歩足りてません(1^_^;)。
BlocklyでSPI-TFTを制御する参考プログラムを以下にリンクしておきます。
参考プログラム:blky_spi_tft.xml
※ブラウザによっては、XMLファイルをレンダリングして表示してしまうので、「右クリック ⇒ リンク先を保存」などしてください。
Blockly for MoscoviumのXMLタブに貼り付けて、ご覧ください。
Blockly.XML→Moscovium.ASM変換手順を参照して、Moscoviumマイコンに書き込んでください。
プログラムが大きくなったせいで、アセンブル時間が増大しています。手元の環境では10分以上かかっていますので、気長にお待ちください。
プログラムを書き込んだMoscoviumマイコンが起動すると、シリアルモニタから以下のコマンドを受け付ける様になっています。
シリアルモニタコマンド仕様:
SPI-TFT制御ブロックの動作確認用なので、特に何の機能も御座いません。各【demo】コマンドによって、今回実装したSPI-TFT制御ブロックを粗方使っています。これをCmod A7ボード(FPGA)へ書き込み、実際の動作で確認するのが目的です。
こちらを参照して、SPI-TFT制御STFT61ユニットを搭載したマイコンMSOC115TF3208をCmod A7ボード(FPGA)に書き込んでください。
Cmod A7ボード、アダプタボード、SPI-TFTを、こちらと同様に接続して実験します。Blocklyで作成したこちらのプログラムを書き込んだら準備完了です。
以下図に、実験中の様子を示します。
実験を進めて行きましょう。
実験サンプル:【 】内はシリアルモニタからの送信データ
【demo】
OK+ demo,1
OK+ pix(32,32)=0x041f (0x041f=orange)
OK+ demo,2
OK+ pix(64,64)=0x8410 (0x8410=gray)
OK+ demo,3
OK+ pix(0x89,0xab,0xcd)=0xcd51 (0xcd51)
OK+ chars N=10765
OK+ demo,4
OK+ pix(0x80,0x40,0x20)=0x2210 (0x2210)
OK+ dots N=0x8a2e
OK+ demo,5
OK+ pix(0x12,0x34,0x56)=0x51a2 (0x51a2)
OK+ boxes N=1332
OK+ demo,6
OK+ pix(0x3f,0xff,0x7f)=0x7fe7 (0x7fe7)
OK+ lines N=2238
OK+ demo,7
OK+ demo,8
OK+ demo,9
OK: demo
SPI-TFTへの日本語文字列描画や図形描画に混じって、時折、SPI-TFTのビデオRAMからピクセル値を読み出したり、RGB888からBGR565ピクセルに変換したりした結果をシリアルモニタへ送信して来ます。……動作検証を兼ねたデモであるためです。
丸括弧「()」の中が机上計算した期待値なので、期待通りの値が読み出せていることが判ります。
ランダムに描画するデモでは、5s間に描画した図形の数(N=?)を報告して来ます。それぞれ、乱数を使っており、描画サイズによって描画時間が異なるため参考データですが、以下にまとめておきます。
では、デモの様子を動画でご確認ください。
実時間再生(早送り無し)の動画ですので、描画速度にもご注目ください。
SPI-TFT表示器(ドライバチップはST7735R)のビデオRAM(V-RAM)からデータを読み出すと、RGB666(約26万色)データとなります。ST7735Rデータシートによると、V-RAMから読み出したデータは1ドット当たり、8ビットデータ×3個(R,G,B)です。各データは8ビットの左詰めで上位ビットから6ビットが有効な値と記載されています。
だがしかし、実際に読み出してみたところ、確かに8ビットデータ×3個が読み出せるのですが、データは中途半端に、ビット6〜1の6ビットが有効だと判明しました。かつ、範囲外のビットも0ではなく、と言って1でもなく、ごみ(?)が乗っている様に見えます。
と、言う事で、データシートの言う通りに実装してしまうと正しいデータが読み出しできないため、実際の動作に合わせてSPI-TFT制御ライブラリを実装してあります。
以下コード部分が、データシート記載内容と祖語のある部分です。
_stft_getpix_r1_r0:
:
: (中略)
:
# ATTN! The ST7735R datasheet states that the pixel data
# in the RAMRD command is left aligned RGB666 in RGB888 format,
# but the actual response seems to not be.
lsli r0,1
lsli r1,1
lsli r2,1
andi r0,0xfc
andi r1,0xfc
andi r2,0xfc
#
あんまり、V-RAMからのデータ読み出しなんて使わないかもしれませんね?ですが、V-RAMからの読み出しができると、背景の図形に重ねてアイコンや文字を描画するとか、半透明な図形を描画するとか、描画した図形データをSPI-TFTから読み出して保存するとか、使い道は有るので、実装しておきました。
FPGAボードで開発中のオリジナル16ビットCPUコアMoscoviumで使いたいと思い、購入したSPI-TFTですが、アダプタボードや開発環境(Blockly)でのサポートによって、圧倒的に使い易くなりました。美味。