FabGLとmruby-ESP32ボードの構想

Project, TechEmbedded, ESP32, Japanese, mruby

何気なくTwitterを見ていたら、気になるツイートを発見しました。

ESP32でVGA出力して、PS/2キーボードが繋がる!

自分もESP32で映像出力する方法を考えていたのですが、そのものずばりのライブラリで、感動しました。

イタリアのFabrizioさんという方が作った、FabGLというESP32 Arduino core用のライブラリです。

https://github.com/fdivitto/fabgl

VGA出力に関しては、こちらの方の手法もありました。色数が多いため出力ピンをほぼ全て使い果たすので、自分の目的には適していませんでしたが、方針は同じようなので、減色するように改造すれば同様にOKかと思います。

同じ方がNTSC出力についても取り組まれていましたが、こちらはアナログ信号の出力になるので、ハードルが高そうでした。

手元で試してみた結果

手元のVGA入力可能なディスプレイに繋いでみました。PS/2キーボードもつないでいます。
抵抗挟んでRGB信号の合成しているので、簡単な変換基板を作っています。

インベーダーゲームのデモを動かしてみました。

さくさく動いています! すごい!

最初、USBからPS/2に変換するキーボード使ってうまく行かず、PS/2ネイティブのキーボード使ってみたらうまくいきました。
IchigoJamでも同じような相性の問題があったようで、最小限のコマンド通信だとうまく初期化されないキーボードがいるようです。

https://fukuno.jig.jp/1177

PS/2のソフト処理の部分を手直しするとうまくいくようになりそうです。

FabGLの仕組み

VGA出力の基本的な方針は、I2Sの信号出力機能を使ってRGB信号を同期を取って出力することにあります。
I2Sを使うメリットとして、以下の点があると思います。

  • DMA転送によってCPUの処理リソースを消費せずに自動的に信号を出力できる
  • I2Sの機能で所定の周期でパラレルに信号を複数のPINから出力できる

2つ目については自分もそういうことができるとは知らなかったので、調べているときに気づきました。

PS/2については、基本的に信号受信タスクを作って、キー入力を検知、キーコードに変換しているようです。
ULPのメモリを使っている箇所があったのですが、理由がよくわからなかったので引き続き確認必要です。

単なるVGA出力だけでなく、文字画像や、スプライトなどのゲームにも使える基本的な描画系APIがすでにそろっていて、すぐにでもゲーム作れそうです。
またターミナルのサンプルアプリもあって、スタンドアローンなコンソールとしても利用できます。

mrubyボード構想

ESP32 WROVER-Bの発売を知ったときから、mruby専用ボード作ってみたいな、という構想が昨年からありましたが、映像出力のハードルが高くて足踏みしていました。そこに一番の技術課題を解決してくれる素晴らしいライブラリが現れました。

構想は、もともとIchigoJamや、MachiKaniaを知って、mruby版を作ってみたい、思ったところから始まっています。

もう一つのきっかけは、中学生のころ学校に置いてあったFM-TOWNSのF-BASIC386にあります。
私は、F-BASIC386でプログラミングの楽しさを知ったので、ああいう環境が作れないかな、ずっと昔から思っていました。

F-BASIC386の良いところは、当時流行りの「マルチメディア」に強かったことがあります。MMLで音楽を再生したり、画像を読み込んだり、描画したり、スプライトを動かしたり、複数レイヤーの描画とか、CDの再生とかが、BASICの関数として提供されていて、ちょっとしたゲームを作るのに最高の環境でした。

最近はパソコンさえあれば無料でプロ並みの開発環境が整う時代になりましたが、自由度が高いぶん、ちょっとキャラクターを動かしてみたり、音を出してみたりするのに、何らかのライブラリのインストールをしたり、どうしてもひと手間掛かってしまいます。
オールインワンの環境でそんなハードルを下げたいな、というのが基本的なモチベーションです。
これはきっと、IchigoJamとも近いものだと思います。

BASICは先駆者がおられるので、じゃあ、自分はmrubyでやってみようかと思ったわけです。

設計はじめ

最大の技術課題が解決しそうなので、具体的な設計を始めてみました。
まずESP32の入出力の割り当てです。

my plan for mruby board
my plan for mruby board

64色出力すると、出力PINがかなり厳しいです。

PIN map for my project
PIN map for my project

細かく割り当て考えて見ました。あと出力が一つあればI2Cで機能拡張できそうなのですが、難しそうです。

残りのハード関連課題

  • 音楽
    やはりゲームに音楽は欠かせません。I2Sがまだ1チャンネル余っているはずなので、I2S→DACで音声出力したいです。ファミコン音源の仕様を真似しようと思っています。ここがうまくいくかどうかが次のハードルです。
  • SDカード
    スクリプトやデータの保存場所として、内蔵のフラッシュだけだと心もとないので、SDカードを使いたいと思います。ライブラリもあるので、SPIモードで接続するのはきっとすんなりうまくいくと期待しています
  • 量産
    今回のこれは何かのイベントでHW頒布することを目標にしてるので、量産方法の検討も必要です。部品実装の外注にもトライしてみたいと思っています。

そして、次にmrubyの移植と、システム周りのアプリ実装、ボード固有のAPIをmrubyのmrbgemとしてラップする作業があります。