FC2カウンター FPGAの部屋 HDMI入力XGA表示回路4(実機で確認)

FPGAやCPLDの話題やFPGA用のツールの話題などです。 マニアックです。 日記も書きます。

FPGAの部屋

FPGAの部屋の有用と思われるコンテンツのまとめサイトを作りました。Xilinx ISEの初心者の方には、FPGAリテラシーおよびチュートリアルのページをお勧めいたします。

HDMI入力XGA表示回路4(実機で確認)

HDMI入力XGA表示回路3(インプリメント)”の続き。

前回は、HDMI 端子から入力したXGAの画像をDDR3 SDRAM のフレームバッファにバッファして、SVGAで表示する回路のビットストリームを生成する事ができた。今回は、SDKでソフトウェアを作製して、実機でテストを行う。

ハードウェアをエクスポートして、SDKを立ち上る。

Vivado の File メニューから Exprot -> Export Hardware... を選択した。

Export Hardware ダイアログが表示される。Include bitstream にチェックを入れて、OKボタンをクリックした。

File メニューから Launch SDKを選択した。

SDKが立ち上がった。
ZYBO_1_XGA_test_15_151214.png

Project name に hdmi_in_disp と入力した。Next > ボタンをクリックした。OS Platform は取りあえず、ベアメタル・アプリケーションとするので、デフォルトの standalone に設定した。
Board Support Package は Create New のラジオボタンをチェックして、BSPを新しく生成する。

hdmi_in_disp.c を新しく生成して、Cソースコードを書いて、オート・ビルドした。
ZYBO_1_XGA_test_16_151214.png

ZYBO を2台用意して、1台には、”並列ステレオカメラによる距離の測定9(Ubuntuで動作するアプリケーションを作る2)”を入れた。これをZYBO_0 とする。ZYBO_0 からのHDMI ケーブルを現在作製中のプロジェクトを入れるZYBO (これをZYBO_1 とする)のHDMI 端子に接続する。
ZYBO_0 は電源をONして、HDMI 端子にXGA 画面を出力するアプリケーションを起動した。
ZYBO_1 も電源をON した。下に、2つのZYBO を接続した写真を示す。HDMI ケーブルで2つのZYBO を接続しているが、現在はデバックのために、ZYBO_0 のHDMI 出力をディスプレイに接続している。
ZYBO_1_XGA_test_18_151216.jpg

ZYBO_0 の Xilinx Tools メニューからProgram FPGA を選択して、ZYBO のコンフィギュレーションを行った。
ZYBO_1_XGA_test_17_151216.png

hdmi_in_disp.c を右クリックし、右クリックメニューから Run AS -> Launch on Hardware (GDB) を選択して、ソフトウェアを起動した。
すぐに砂嵐状の画面がディスプレイに表示されたが、すぐに下の写真の様に変化した。それ以外は変化がなかった。
たぶん、1度はHDMI から入力された画像を表示しようとしたのだと思う。
ZYBO_1_XGA_test_19_151216.jpg

ZYBO_0 のHDMI 出力は信用出来ない可能性があるので、ノートパソコンのHDMI 出力でテストしてみようと思う。

最後に、hdmi_in_disp.c を貼っておく。

/*
 * hdmi_in_disp.c
 *
 *  Created on: 2015/12/15
 *      Author: marsee
 */

#include <stdio.h>
#include <stdlib.h>
#include "xaxivdma.h"
#include "xil_io.h"
#include "xparameters.h"
#include "sleep.h"

#define NUMBER_OF_WRITE_FRAMES    3 // Note: If not at least 3 or more, the image is not displayed in succession.

#define HORIZONTAL_PIXELS    1024
#define VERTICAL_LINES        768
#define PIXEL_NUM_OF_BYTES    4

#define FRAME_BUFFER_ADDRESS 0x10000000

static XAxiVdma_DmaSetup Vdma0_WriteCfg;

int main(){
    // malloc frame buffer
    // unsigned int *frame_buffer = (unsigned int *)malloc(HORIZONTAL_PIXELS * VERTICAL_LINES * PIXEL_NUM_OF_BYTES * NUMBER_OF_WRITE_FRAMES);

    // AXI VDMA Initialization sequence
    XAxiVdma_Config *XAxiVdma0_Config;
    XAxiVdma XAxiVdma0;
    int XAxiVdma0_Status;

    XAxiVdma0_Config = XAxiVdma_LookupConfig(XPAR_AXI_VDMA_0_DEVICE_ID); // Look up the hardware configuration for a device instance
    if (XAxiVdma0_Config == NULL){
        fprintf(stderr, "No AXI VDMA found\n");
        return(-1);
    }

    XAxiVdma0_Status = XAxiVdma_CfgInitialize(&XAxiVdma0, XAxiVdma0_Config, XAxiVdma0_Config->BaseAddress); // Initialize the driver with hardware configuration
    if (XAxiVdma0_Status != XST_SUCCESS){
        fprintf(stderr, "XAxiVdma_CfgInitialize() failed\n");
        return(-1);
    }

    XAxiVdma_Reset(&XAxiVdma0, XAXIVDMA_WRITE);
    while(XAxiVdma_ResetNotDone(&XAxiVdma0, XAXIVDMA_WRITE)) ;

    XAxiVdma0_Status = XAxiVdma_SetFrmStore(&XAxiVdma0, NUMBER_OF_WRITE_FRAMES, XAXIVDMA_WRITE); // Set the number of frame store buffers to use.

    Vdma0_WriteCfg.VertSizeInput = VERTICAL_LINES;
    Vdma0_WriteCfg.HoriSizeInput = HORIZONTAL_PIXELS * PIXEL_NUM_OF_BYTES;
    Vdma0_WriteCfg.Stride = HORIZONTAL_PIXELS * PIXEL_NUM_OF_BYTES; // Indicates the number of address bytes between the first pixels of each video line.
    Vdma0_WriteCfg.FrameDelay = 0; // Indicates the minimum number of frame buffers the Genlock slave is to be behind the locked master. This field is only used if the channel is enabled for Genlock Slave operations. This field has no meaning in other Genlock modes.
    Vdma0_WriteCfg.EnableCircularBuf = 1; // Indicates frame buffer Circular mode or frame buffer Park mode.  1 = Circular Mode Engine continuously circles through frame buffers.
    Vdma0_WriteCfg.EnableSync = 0; // Enables Genlock or Dynamic Genlock Synchronization. 0 = Genlock or Dynamic Genlock Synchronization disabled.
    Vdma0_WriteCfg.PointNum = 0; // No Gen-Lock
    Vdma0_WriteCfg.EnableFrameCounter = 0; // Endless transfers
    Vdma0_WriteCfg.FixedFrameStoreAddr = 0; // We are not doing parking

    XAxiVdma0_Status = XAxiVdma_DmaConfig(&XAxiVdma0, XAXIVDMA_WRITE, &Vdma0_WriteCfg);
    if (XAxiVdma0_Status != XST_SUCCESS){
        fprintf(stderr, "XAxiVdma_DmaConfig() failed\n");
        return(-1);
    }

    // Frame buffer address set
    unsigned int frame_addr = (unsigned int)FRAME_BUFFER_ADDRESS;
    int i;
    for (i=0; i<NUMBER_OF_WRITE_FRAMES; i++){
        Vdma0_WriteCfg.FrameStoreStartAddr[i] = frame_addr;
        frame_addr += HORIZONTAL_PIXELS * PIXEL_NUM_OF_BYTES * VERTICAL_LINES;
    }

    XAxiVdma0_Status = XAxiVdma_DmaSetBufferAddr(&XAxiVdma0, XAXIVDMA_WRITE, Vdma0_WriteCfg.FrameStoreStartAddr);
    if (XAxiVdma0_Status != XST_SUCCESS){
        fprintf(stderr, "XAxiVdma_DmaSetBufferAddr() failed\n");
        return(-1);
    }

    // VDMA start
    XAxiVdma0_Status = XAxiVdma_DmaStart(&XAxiVdma0, XAXIVDMA_WRITE);
    if (XAxiVdma0_Status != XST_SUCCESS){
        fprintf(stderr, "XAxiVdma_DmaStart() failed\n");
        return(-1);
    }

    // mt9d111_inf_axis_0, axi_iic_0, bitmap_disp_cntrler_axi_master_0
    volatile unsigned int *bmdc_axi_lites;

    bmdc_axi_lites = (volatile unsigned *)XPAR_BITMAP_DISP_CNTRLER_AXI_MASTER_0_BASEADDR;
    bmdc_axi_lites[0] = (volatile unsigned int)FRAME_BUFFER_ADDRESS; // Bitmap Display Controller 0 start

    return(0);
}

  1. 2015年12月16日 04:50 |
  2. ZYBO
  3. | トラックバック:0
  4. | コメント:0

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック URL
http://marsee101.blog19.fc2.com/tb.php/3334-f40714c6
この記事にトラックバックする(FC2ブログユーザー)