本記事の概要
以前の記事から、外部から受信した動画像の映像信号をZynqで受信し、それを外部に出力するHDMI入出力デモサンプルを試しています。
以下の記事では、Vivado上でハードウェアデザインを読み込み、ブロックデザインの構成と動作原理を確認しました。
統合ソフトウェア開発環境「Vitis」上で、アプリケーションプロジェクトの作成方法について3回の記事に分けて説明していきます。
前回の記事ではディスプレイへの送信系を作成しました。引き続き、HDMI送信機からの受信系を作成します。本記事ではHDMIケーブルを接続し、信号を受信したときに発生する割り込みの構成について理解することをめざします。
それでは、興味のある方はぜひ最後までご覧ください!
目標と工程
開発目標
本記事全体の目標は次の通りです:
統合ソフトウェア開発環境VitisとFPGA設計環境Vivadoを用いて
「HDMI信号を受信しDDRメモリに保存し、それを外部ディスプレイに出力する」
アプリケーションを作成する
開発工程
デバイス構成
Zynqの構成
Zynqは外部から映像信号を受信し、PL(Programmable Logic)部からDDRメモリに映像信号を書き込みます。PL内部のIPコアの構成を説明します。HDMI入出力編(1)では、以下の図のようなブロック図の構成に基づき、Vivadoのブロックデザインを作成しました。
構成は大きく、「(a)送信系(ディスプレイ側)」と「(b)受信系(ビデオ側)」の2つに分けることができます。
本記事では、「(b)受信系(ビデオ側)」を動かすためのアプリケーションを作成します。
受信系では、HDMIケーブルを繋ぎ外部から映像信号を受信したときに、VTCにおいて映像のタイミング信号を検出し、VDMAにおいて映像をDDRメモリへ格納する必要があります。「HDMIケーブルの接続」をトリガーに特定のプログラムを動作させるために、「割り込み」をかける処理を行います。
HDMI入力I/Oの構成
まず、HDMIケーブルをZyboに接続したときの回路の動作を整理しましよう。
上の図はHDMI送信機(ソースと呼ばれる;本記事ではPC)と受信機(シンクと呼ばれる;本記事ではZybo)のブロック図です。
HDMIケーブルとの接続に用いる信号線は以下の4種類です。今回、Vivadoのブロックダイアグラム上では、CECは使用せずに、他の3種類のI/Oポートを設定しました。
余談ですが、Vivadoで作成したブロックダイアグラムには、HDMI_OENという出力を設けています。この出力に応じて、Zyboを受信機にするか(HDMI_OEN=0)、送信機にするか(HDMI_OEN=1)を設定することが可能です。以下のZyboのマニュアルの、HDMI_OUT_ENが該当します。
HDMIケーブルを接続したときの動作
フローチャート
では、HDMIケーブルを接続したときの動作を順を追ってみていきましょう。
HDMIケーブルを接続すると、HPDチャネルを介してシンク機器からソース機器に、HDMI接続されたことを認識する信号が送られます(図中1の矢印)。シンク機器、すなわちZynqではGPIOチャネル1を常にHigh状態にしておき、物理的にHDMIケーブルを接続したときにソース機器のHPDチャネルがHigh状態にアサートされるようにしました。
ソース機器は、HPDの接続を認識すると映像の情報を含むデータ信号とクロック信号をTMDSチャネルを通じてシンク機器に送信します。データ信号はDVI形式で送信されます。Zynqで受信したDVI形式のデータ信号は、Digilent社提供のdvi2rgb IPによりrgb信号に変換されます。dvi2rgb IPの使用方法は以下のリファレンス資料を参考にしました。
https://github.com/Digilent/vivado-library/blob/master/ip/dvi2rgb/docs/dvi2rgb.pdf
データ信号とクロック信号を受信し、問題なく通信のクロック動作が確立すると、aPixelClkLckdがHigh状態にアサートされます(図中2の矢印)。このアサートをGPIOチャネル2が検出し、割り込み信号をCPUに送るようにしています。この割り込み信号が「HDMIケーブルが接続され、外部からデータ信号を受信した」というトリガーとなります。これをトリガーに、VTCによるタイミング検出を開始します。
RGB信号は映像信号とタイミング信号とに分けられ、それぞれVDMA IPとVTC IP(ビデオ側)とに送信されます。
今回、VTC IPコアを2つ使用しています。一つは、ディスプレイに映像をVGA出力するためのタイミング信号の生成に用いられています。もう一つは、ソース機器からデータを受信してタイミング信号を検出するのに用いられています。前者をVTC IP(ディスプレイ側)、後者をVTC IP(ビデオ側)と呼び、区別することにしました。
VDMA IPとVTC IP(ビデオ側)のうち、VTC IP(ビデオ側)でのタイミング検出をまず最初に行います。この理由は、VDMA IPで映像信号をメモリに格納する際に、その映像のサイズをビデオ側VTC IPで検出したタイミング信号をもとに設定したいからです。VTC IP(ビデオ側)でのタイミング信号の検出が完了すると、VTC IPがロック(locked)状態になり、かつ割り込み信号がCPUに送られます(図中3の矢印)。割り込み信号を受信してから、VDMA IPの映像受信時の設定を行い、DMA(Direct Memory Access)動作を開始します。
以上のHDMI送信機(ソース)をZynqに接続したときの、Zynqの動作をフローチャートにまとめました。
VTCの割り込みハンドラ
VTC IPで発生した割り込み要求に対する割り込みハンドラを実行するとき、CPUではAXI4-Liteを通じてVTC IPのIRQ Enable Registerを参照します。IRQ Enable Registerの値から割り込み要求の要因を区別し、その要因に応じて実行する割り込みハンドラを分岐することができます。
例えば、今回はVTCにおけるIRQ Enable Registerでは、”Lock”というビットがHigh状態になります。下表は、XilinxのVTC(Video timing controller) IPのリファレンスマニュアルから抜粋したIRQ Enable Registerのレジスタマップです。VTC IPでの検出が完了すると、レジスタの8ビット目がイネーブルされます。
受信系の状態遷移図
Zynqの動作を示すフローチャートと合わせて、割り込み要求を受信するたびに状態がどのように遷移するかを状態遷移図にまとめました。
HDMIケーブルを接続し、GPIOの割り込みが発生すると、VTC IP(ビデオ側)によるタイミング検出を行い、VTC IP(ビデオ側)の検出が完了するのを待ちます。
VTC IP(ビデオ側)の検出が完了し割り込みが発生すると、DMA動作が開始され、HDMI映像が外部ディスプレイに表示されるようになります。
今回の記事では、映像を出力するところまでを行います。
しかし、例えば、「HDMI映像出力中」の状態からHDMIケーブルを抜き、信号を切断することも想定されます。このとき、「静止画出力中」の状態に戻すのが一つの選択肢なのですが、今回はそこまでは行いません。
割り込みハンドラ表の構成
最後に、デバイスの構成に基づいて、割り込みハンドラ表の構成を計画します。
デバイス上で割り込み要求の発生源となるIPは2つ、GPIO IPとVTC IP(ビデオ側)です。それぞれの割り込み信号はApplication Processor Unit (APU)内のGIC(Generic Interrupt Controller; 汎用割り込みコントローラ)を介して、CPUに割り込み要求をかけます。
このように、割り込み要求を発生させる要因が一つではないとき、種々の割り込み要因に対して、対応する割り込みハンドラへと分岐することが必要です。この対応する割り込みハンドラへ分岐するための手続きを記述したプログラムは、割り込みベクタテーブルと呼ばれています。割り込みベクタテーブルには、予め「割り込みハンドラの関数ポインタ(Handler)」と「割り込みハンドラに送る引数(CallBackRef)」を登録しておきます。
割り込みハンドラの分岐を行うときに、アプリケーションに入力される割り込み信号の分岐だけではなく、GICの入力源に対しても割り込み要求を分類し、適切な割り込みハンドラに分岐させることが可能です。GICインスタンスには、割り込みベクタテーブルと同様の、割り込みハンドラテーブルが用意されています。
下の図のように、GICインスタンスと実際のGICを紐付けておき、GICの入力源に従って対応する割り込みハンドラを登録しておけば、割り込み要求に応じて適切な割り込みハンドラへと分岐させることが可能になります。
さらに、前述の通り、VTC IPコアでもIRQ Enable Registerを参照し、割り込み要求の要因に応じて、割り込みハンドラを区別することが可能です。VTCから割り込み要求を受けたときは、割り込み要求の要因に応じて分岐を設定すると、複雑な処理が理解しやすくなります。
まとめると、以下の通りです。割り込みハンドラが分岐して、適切なプログラムが実行されます。
今回は、HDMIケーブルを接続したときの割り込み動作を解説しました。
次回の記事では、このフローチャートと割り込みハンドラ表の分岐に基づいて、ソースコード例とその解説をまとめていきます。
最後までご覧いただきありがとうございました。
コメント