お知らせ:この記事はJLCPCBの提供でお送りしています。
前回はJLCPCBに発注したESP32+FPGAオーディオ基板を組み立てる過程を紹介しました。今回はまず基礎検討に使っていたユニバーサル基板のハードウェア構成を紹介し、その後にJLCPCBで作った基板のハードウェア構成について紹介したいと思います。
基礎検討用ユニバーサル基板
まずは基礎検討用ユニバーサル基板の紹介です。ブロック図を下に示します。
実際にはユニバーサル基板に直接上記のICが載っているわけではなく、下記の各種のブレイクアウトボードを経由して実装しています。
- FPGA(Lattice iCE40Ultra)のブレイクアウトボード(自作)
- ESP32ブレイクアウトボード(ESP-WROOM-32ブレイクアウトSD+)
- PCM5102Aブレイクアウトボード(Amazonで購入:AliExpressでもよく見かけます)
- SPI FlashメモリをDIP8ピン変換基板に実装したもの(ICソケット経由で実装)
- デバッグ用LED
を載せています。FPGAのブレイクアウトボードは過去に作ったものの再利用です。Profileのページによると2016年に作ったもののようです。
とりあえずTang Nano 9Kに昔書いた12bit PIC(https://t.co/2d3inXp3A2)を載せて動かすなど。RV32よりはるかにしょぼいコアでちょっと申し訳ないw pic.twitter.com/38fcROHe21
— JA1TYE/Ryota Suzuki (@JA1TYE) February 1, 2022
実のところ、このプロジェクトは2月に届いたSipeed Tang Nano 9Kを動かしてみたら久々にFPGAで遊びたくなってしまい始めたのでした。そのままTang Nano 9Kで開発を進めてもよかったのですが、どのみち外付け部品が必要ですし、Tang Nano 9Kは結構サイズが大きいこともあり、手持ち部品の消化も兼ねて在庫していたiCE40Ultraで基板を起こす前提で開発を始めました。長らく積んでいた自作ブレイクアウトボードも活用でき、一石二鳥でした。1
ユニバーサル基板での試作の最初期から、FPGAから音を出すものを、それもあらかじめ録音された音データを加工しながら出力するPCM音源を作ろうと考えていました。そこで、I2S規格2対応のオーディオ出力用DACであるTIのPCM5102Aと、音データを保存しておくためのSPI FlashメモリとしてGigaDeviceのGD25Q128CをFPGAの先に接続しています。音データは48kHzサンプリング、16bitで扱うことにしたので、今回搭載した128Mbit(16MByte)のSPI Flashメモリだと最大で3分弱(174秒)の音データを保存できる計算です。
和音を出力するときのように、複数の音を同時に発音しようとすると、ある時間内にメモリから読み出すべき音データの量が増えてきます。そのため、今回はFPGAとSPI Flashメモリの間のデータバスを1bit幅のSPI接続ではなく、4bit幅のQuad SPI接続とし、帯域幅を確保できるようにしました。
FPGAに回路情報を書き込むコンフィギュレーションは基板のサイズ比較のところで触れたとおり、外につないだ書き込みアダプタから行っています。
ESP32とFPGAの処理の分担については、汎用マイコンで間に合うような機能はできるだけESP32側で行い、FPGAはSPI経由でESP32から制御されるような設計としました。今回使っているiCE40UltraはLUT数が約4K個と少ないことから、FPGA側にCPUは入れず、シンプルに音を出す機能に専念してもらう想定です。
この基板を使って、ESP32からの指示に従いFPGAがSPI Flashメモリに書き込まれた音データを読み出してDACから出力するところまで一通り実装できたのですが、下記の通りいくつかの問題があったので、プリント基板化することにしました。
ケーブルが多すぎる
この基板は少なくとも、ESP32への書き込みやデバッグに使うUSB-UART向けのポート、FPGAのコンフィギュレーションのための書き込みアダプタ向けのポートの2つのUSBポートを要求します。FPGAの先に付いているSPI FlashメモリはFPGAを経由してESP32から制御できるようにはしていたのですが、ESP32からSPI Flashメモリに書き込むためのプログラムをきちんと作りこんでいなかったので、最初は都度基板からICを取り外し、ROMライタで書き込んでいました。この場合、ROMライタ用のUSBポートも必要になります。さらに書き込みアダプタと試作基板を繋ぐケーブルもあり、ごちゃごちゃとして不便でした。
足りない機能がある
この基板で使っているPCM5102Aブレイクアウトボードは基板上にイヤフォンジャックが載っているのですが、DACの出力とイヤフォンジャックの間にボリュームがないため、音量調節ができません。常に最大音量で聞き続けるわけにもいかないのでちょっと困っていました。また、キーボード類からのMIDI信号を受けてPCM音源を鳴らすために、ESP32にMIDIの受信回路を接続したいと考えていましたが、この基板では実装できていませんでした。
FPGAの動作周波数
今回使っているiCE40Ultraはモバイル機器向けの低消費電力なFPGAということもあり、FPGA内の回路を実装していく中で思っていたよりも動作周波数が上げられなさそうだということが分かりました。12.288MHz1を4倍した49.152MHzでFPGAの内部回路を駆動することにしたのですが、その場合だと同時発音数が16和音になります。動作周波数が一定という条件下で、同時発音数増加のボトルネックとなるのはSPI Flashメモリからのデータ読み出しであることはこの時点で分かっていたので、何か改善策を導入したいと考えていました。
とにかく大きい
そして最後になんだかんだ言ってもこれです。小さく作ってケースに入れて手軽に遊べるようにしたかったのでした。
今回作った基板
ユニバーサル基板での基礎検討結果を踏まえて、今回作った基板では下記のようなハードウェア構成としました。主な変更点は赤字にしています。
まず、PCとのケーブルでの接続はESP32のUART接続のみとしました。USB-UART変換ICには安くてコンパクトなCH340Kを使いました。また、ESP32とFPGAをつなぐSPIバスを、コンフィギュレーション、PCM音源制御、FPGAの先につながっているSPI Flashメモリの書き込みの3つの用途で兼用するような設計としました。これによって、FPGAの書き込みアダプタ用のUSBポートをなくすことができました。
今回の基板では、ESP32はPSRAMを搭載したESP-WROVER-32を使用しました。これは単にPSRAM非搭載版であるESP-WROOM-32よりもESP-WROVER-32の手持ち在庫の方が多かったからです。加えて、ESP32にはMIDI受信用のフォトカプラを使った回路を接続しました。MIDI入力端子は3.5mmジャックとしています。
さらに、SPI Flashメモリについても2個接続できるような設計としました。FPGAの動作周波数が上げられない分、同時に2個のメモリからデータを読み出して帯域幅を稼ぐ作戦です。また、SPI Flashメモリと同じパッケージで、バスの互換性もあるSPI PSRAMを取り付けることも想定しています。
その他、ユニバーサル基板版で課題となっていたDAC出力へのボリューム追加や、外へ出るコネクタを基板の一辺にまとめ、ケースを作りやすくする等の改善を盛り込みました。
まとめ
JLCPCB @JLCPCB_Japan で作った基板、紆余曲折はありましたが大体の機能の動作確認ができたなど。 pic.twitter.com/cW3uh8L5td
— JA1TYE/Ryota Suzuki (@JA1TYE) April 6, 2022
今回はESP32+FPGAオーディオ基板のハードウェア構成について紹介しました。ユニバーサル基板での基礎検討で出てきた課題点をフィードバックしプリント基板化することで、元の基板よりもコンパクトで高機能なオーディオ基板にできたと思います。
なお、前回の記事中でもちょっと言及しましたが、プリント基板を組み立てた後、いろいろデバッグに悪戦苦闘したりしました。ハードウェアのデバッグと、基礎検討基板用のソフトの移植が終わった時点で、とりあえず上のTweetの通りFlashメモリに書き込んだ音データを再生することができるようになりました。次回はこの音出しにたどり着くまでのデバッグの話と、ソフトウェアの話をしようと思います。お楽しみに!