FlashAir使った非同期転送テスト
FlashAirがGPIOとして使えるらしいという話は聞いていたが,まったく弄ってなかったので先週のFPGAエクストリーム・コンピューティング第6回に外れた悲しさからブラウザ上からBASYS3の7セグに文字を表示するサンプルを作ってみることにした.
FlashAirの仕様確認
まずは,FlashAir仕様を確認.
公式 FlashAir Developers - ドキュメント - APIガイド - command.cgi の他に FlashAirのGPIO機能を使った回路の制御ソフトを組んでみた。: じむの(とりあえず)やってみたの巻 と,次のスライドを参考にさせていただきました.
まとめると,
- 電源電圧は3.3V(BASYS3のPmodのVDDと同じ).
- 入出力できるピン数は5bit.
- 特定のURLにアクセスして端子をON/OFF.
- 特定のディレクトリにHTMLファイルを置くと,http://flashair/でアクセスできる.
とりあえず,FPGA(Slave)はVerilog HDLでブラウザ(Master)はhtml+javascriptでとりあえず書いてみることにする.
データ転送プロトコル
データは多くても1回に5bitまでしか送れないので,例えば7セグに16進数で0000~FFFFまで表示しようとすると16bit必要なので,最低4回(5bit x4)の転送が必要となる. FlashAirの各ピンがそれぞれ同時にON/OFFされるかどうかとか,配線やネットワーク遅延とか考えるのが面倒だったので, FlashAirの出力4bit(Data),入力1bit(Ack)としてクロックを使わない完全非同期でFPGAにデータを送ることにする.
ここで,使用するデータ転送方式として,4相2線(4-phase dual-rail)エンコーディングによる非同期データ転送を採用した. 4相2線で1bitを転送する場合,表のエンコードを行い,下記のような転送となる.
Code word(T,F) | |
---|---|
Data 0 | '01' |
Data 1 | '10' |
Spacer | '00' |
Invalid | '11' |
- Data(0)+Req.を送る
- Ack.が立ち上がる
- Spacerを送る
- Ack.が立ち下がる
このように,Req-Ackでハンドシェークを行い,4つのステップでデータを送るため4相と言われる.
また,1bitのデータ転送に2線(dual-rail)用い,Tが1なら1,Fが1なら0という情報を送ると同時にリクエストとしての情報も送る方式である.DataとDataの間にはSpacerを必ず送信する必要もある.
この方式であれば,遅延時間によらず正しいデータを確実に送ることが可能(Delay Insensitive)である.
多ビット転送の場合も基本的には同じで,すべてのビットのReqが来たらAckを返し,すべてのビットのSpacerが来たら,Ackを下げればよい.
今回は,16bitの情報を4線(2線x2)使って2bitずつ送るので,8回転送を送る必要がある.
回路構成
u_async でFPGAに非同期で入ってきた4相2線 x2の信号を内部クロックで同期化して,データの取り込みとAckの生成を行う.
u_fifo は2bit入力のシフトレジスタ.得られた2bitのデータを2bitずつシフトしながら入れて7セグ表示用の16bit信号を生成する.
u_seg7は,7セグ表示用の回路.16bitのデータをBASYS3の7セグ4文字分として表示する.
動作確認
Pmod端子をブレッドボードに挿せれるようにするアダプタを作成して, ブレッドボードを介してFlashAirを挿したSDカードアダプタを接続する.
iPadからFlashAirにアクセスして,16進数で"BEEF"を送ると,FPGAの7セグにiPadの数字が表示されることを確認.
接続状況によってはスムーズに転送できるときもあれば, なんか止まって途中進まなくなったりもするけど, Delay Insensitiveな非同期転送なので, 転送時間がどれくらいになるか不明だけど, 暫く待てば最終的には正しい値が転送できている.
dual-railな方法だとスペーサを無くした,2相2線という方式もあるので, そちらで作ると転送速度は4相の2倍なので,もう少し実用的な転送になるかな?