[NEEK][動画再生]表示用SGDMAリードデータ欠落を解消
これまでalt_video_display.cを利用してディスクリプタチェーンを
作成し、うまく行ってると思われたが、画面表示される画像は
砂嵐のような画像。
1Frame分のディスクリプタチェーンがちゃんと作成出来ていれば、
常にDDRメモリの同じアドレスからリードするから画面はズレないはず。
しかし、実際には砂嵐のように画面がズレル。
画面が動く原因を探るが、実機では手がかり掴めず、Simulationで
地道にやるが、DDR High Performance Controller(以下DDRC)や
PLLを追加してからやたら遅い。
100ms程度のSimulationを1日以上かけて何度か解析するうちに、
DDRCからPixel FIFOへのリードデータ転送が間に合ってない事に
気付いた。Stream to Streamではなく、Memory to Stream転送だから
これが限界か?と疑うが、しかしこの遅さでは画像データが到底
間に合わないし、先人はフツーに成功してるようだから何か方法が
あるのかも。悩んでいるうちに以下を発見し、画面止める事に成功。
■リードデータ欠落対策
[1]以下資料page5には、
「異なるクロック間は、自動的にClock Crossing Adapter
が挿入されてレイテンシが増加する」
と書いてある。
SOPC Builder による高性能DDR、DDR2、DDR3、SDRAM の使用
http://www.altera.co.jp/literature/an/an517_j.pdf page5
これを防止するために、SGDMA含む、それ以降のVideo Pipeline
回路一式をDDRCと同じddrc_sysclkで駆動するように変更。
(変更前は、タイミング違反防止のためNiosIIや他ペリフェラルと
同様にPLL生成の25MHzクロックにしていた。)
[2]LCD用SGDMA(Memory to Stream)の設定を変更。
・Enable bursting on descriptor read masterにチェック。
・Enable burst transfersにチェック、更に
Read burstcount signal width=16に設定。
2つ設定したら画面が止まった。原因はどちらか一方かも
しれないが未解析。長らくここで止まってたので先に進む。
■画面下2/3へのアクセス不可対策
画面は止まったが、画面の下側2/3の画像が変わらない。
上側1/3は、DDRCへのライトで画像が順番に変わって行くのに
下側に該当するアドレスへのライトを実行しても固定色のまま。
なんとなく、以下設定を見直したら全画面の画素をいじる事が
出来た。
[3]alt_video_display.h内の以下変数設定を元に戻した。
#define ALT_VIDEO_DISPLAY_BYTES_PER_DESC 0x19000
↓
#define ALT_VIDEO_DISPLAY_BYTES_PER_DESC 0xFF00
これは、picture viewerサンプルプロジェクトを参考に、
元々0xFF00に設定していた。しかし、画像サイズを計算すると、
①800列 x 480行 x 32bit(RGB24bit+8bitの不要bit) = 1536000 bytes
であり、元々の「ディスクリプタ毎のバイト数」は
②0xFF00 = 65280
となる。
すると①/②=23.53となって、小数点のディスクリプタ数
になるから、ちょっとおかしいのでは?と思って、
割り切れて、かつ大きめの数値にすれば、ディスクリプタ用
メモリサイズが節約出来ると考え、0x19000にしていた。
なぜこの設定で問題が解決したか?は未解析。またまた先に進もう。
次はSDカードをリードして、そのデータをDDRCへ送れば画面表示出来るはず。
SDカードからのリードに成功した後は、動画像データの作成、そして
動画像のLCD画面表示・・・となるが、まだまだつまづきそう。
作成し、うまく行ってると思われたが、画面表示される画像は
砂嵐のような画像。
1Frame分のディスクリプタチェーンがちゃんと作成出来ていれば、
常にDDRメモリの同じアドレスからリードするから画面はズレないはず。
しかし、実際には砂嵐のように画面がズレル。
画面が動く原因を探るが、実機では手がかり掴めず、Simulationで
地道にやるが、DDR High Performance Controller(以下DDRC)や
PLLを追加してからやたら遅い。
100ms程度のSimulationを1日以上かけて何度か解析するうちに、
DDRCからPixel FIFOへのリードデータ転送が間に合ってない事に
気付いた。Stream to Streamではなく、Memory to Stream転送だから
これが限界か?と疑うが、しかしこの遅さでは画像データが到底
間に合わないし、先人はフツーに成功してるようだから何か方法が
あるのかも。悩んでいるうちに以下を発見し、画面止める事に成功。
■リードデータ欠落対策
[1]以下資料page5には、
「異なるクロック間は、自動的にClock Crossing Adapter
が挿入されてレイテンシが増加する」
と書いてある。
SOPC Builder による高性能DDR、DDR2、DDR3、SDRAM の使用
http://www.altera.co.jp/literature/an/an517_j.pdf page5
これを防止するために、SGDMA含む、それ以降のVideo Pipeline
回路一式をDDRCと同じddrc_sysclkで駆動するように変更。
(変更前は、タイミング違反防止のためNiosIIや他ペリフェラルと
同様にPLL生成の25MHzクロックにしていた。)
[2]LCD用SGDMA(Memory to Stream)の設定を変更。
・Enable bursting on descriptor read masterにチェック。
・Enable burst transfersにチェック、更に
Read burstcount signal width=16に設定。
2つ設定したら画面が止まった。原因はどちらか一方かも
しれないが未解析。長らくここで止まってたので先に進む。
■画面下2/3へのアクセス不可対策
画面は止まったが、画面の下側2/3の画像が変わらない。
上側1/3は、DDRCへのライトで画像が順番に変わって行くのに
下側に該当するアドレスへのライトを実行しても固定色のまま。
なんとなく、以下設定を見直したら全画面の画素をいじる事が
出来た。
[3]alt_video_display.h内の以下変数設定を元に戻した。
#define ALT_VIDEO_DISPLAY_BYTES_PER_DESC 0x19000
↓
#define ALT_VIDEO_DISPLAY_BYTES_PER_DESC 0xFF00
これは、picture viewerサンプルプロジェクトを参考に、
元々0xFF00に設定していた。しかし、画像サイズを計算すると、
①800列 x 480行 x 32bit(RGB24bit+8bitの不要bit) = 1536000 bytes
であり、元々の「ディスクリプタ毎のバイト数」は
②0xFF00 = 65280
となる。
すると①/②=23.53となって、小数点のディスクリプタ数
になるから、ちょっとおかしいのでは?と思って、
割り切れて、かつ大きめの数値にすれば、ディスクリプタ用
メモリサイズが節約出来ると考え、0x19000にしていた。
なぜこの設定で問題が解決したか?は未解析。またまた先に進もう。
次はSDカードをリードして、そのデータをDDRCへ送れば画面表示出来るはず。
SDカードからのリードに成功した後は、動画像データの作成、そして
動画像のLCD画面表示・・・となるが、まだまだつまづきそう。
スポンサーサイト