一、官方介绍adv7511参考设计
vivado 为2016.4 相对应 官方 HDL 与 no-OS Software 链接如下
2017_r1 ZC706 HDL Reference Design for Vivado
2017_r1 no-OS Software
Building HDL 可使用Cygwin自动make构建项目所需库,然后构建项目
使用Cygwin make项目可参考裸机工程搭建
之后参照adv7511参考设计中Software Setup for Vivado 部分添加 inc头文件 与 HDMI_ZynqLib 库
注意
1)如果遇到如下 VFP register 错误
可将 1) gcc compiler 2) gcc linker 中的 Miscellaneous 中 -mfloat-abi=hard 替换为 -mfloat-abi=softfp
及 bsp 中drivers 也要替换成 -mfloat-abi=softfp
问题解决参考xilinx及Zedboard:HDMI核的构建和输出显示测试
2)遇到下面报错
参考Zedboard:HDMI核的构建和输出显示测试中解决方法直接将函数复制到了cf_hdmi.c文件
成功编译后下载到zc706中显示如下
二、官方例子HDL添加 IP核 TPG
设置如下 color bar solid color 设置为1 可显示纯色 彩条等 像素 1280*720
位宽选择
参考ADV7511 ON ZC706 HDMI IP核数据输入为64位,zc706 有效数据位 0:23和 33:56 , 可将位宽设为10位,TPG 一次输出32位,不需额外组合tpg输出数据。
打开官方例程中VDMA 写通道使能
tpg输出连接VDMA的S2MM,时钟连接系统时钟,tpg VDMA模块的复位都要连接
validate design(F6) 生成bit流
打开SDK,cf_hdmi.c 函数 void InitHdmiVideoPcore 修改如下
void InitHdmiVideoPcore(unsigned short horizontalActiveTime,
unsigned short horizontalBlankingTime,
unsigned short horizontalSyncOffset,
unsigned short horizontalSyncPulseWidth,
unsigned short verticalActiveTime,
unsigned short verticalBlankingTime,
unsigned short verticalSyncOffset,
unsigned short verticalSyncPulseWidth)
{
unsigned short horizontalCount = 0;
unsigned short verticalCount = 0;
unsigned short horizontalBackPorch = 0;
unsigned short verticalBackPorch = 0;
unsigned short horizontalDeMin = 0;
unsigned short horizontalDeMax = 0;
unsigned short verticalDeMin = 0;
unsigned short verticalDeMax = 0;
// DDRVideoWr(horizontalActiveTime, verticalActiveTime);
horizontalCount = horizontalActiveTime +
horizontalBlankingTime;
verticalCount = verticalActiveTime +
verticalBlankingTime;
horizontalBackPorch = horizontalBlankingTime -
horizontalSyncOffset -
horizontalSyncPulseWidth;
verticalBackPorch = verticalBlankingTime -
verticalSyncOffset -
verticalSyncPulseWidth;
horizontalDeMin = horizontalSyncPulseWidth +
horizontalBackPorch;
horizontalDeMax = horizontalDeMin +
horizontalActiveTime;
verticalDeMin = verticalSyncPulseWidth +
verticalBackPorch;
verticalDeMax = verticalDeMin +
verticalActiveTime;
Xil_Out32((CFV_BASEADDR + AXI_HDMI_REG_HTIMING1),
((horizontalActiveTime << 16) | horizontalCount));
Xil_Out32((CFV_BASEADDR + AXI_HDMI_REG_HTIMING2),
horizontalSyncPulseWidth);
Xil_Out32((CFV_BASEADDR + AXI_HDMI_REG_HTIMING3),
((horizontalDeMax << 16) | horizontalDeMin));
Xil_Out32((CFV_BASEADDR + AXI_HDMI_REG_VTIMING1),
((verticalActiveTime << 16) | verticalCount));
Xil_Out32((CFV_BASEADDR + AXI_HDMI_REG_VTIMING2),
verticalSyncPulseWidth);
Xil_Out32((CFV_BASEADDR + AXI_HDMI_REG_VTIMING3),
((verticalDeMax << 16) | verticalDeMin));
Xil_Out32((CFV_BASEADDR + AXI_HDMI_REG_RESET), 0x1);
Xil_Out32((CFV_BASEADDR + AXI_HDMI_REG_SOURCE_SEL), 0x0);
Xil_Out32((CFV_BASEADDR + AXI_HDMI_REG_SOURCE_SEL), 0x1);
///
Xil_Out32(VDMA_BASEADDR + 0x30, 0x4); //reset S2MM VDMA Control Register
Xil_Out32(VDMA_BASEADDR + 0x30, 0x8); //genlock
// VDMA设置 三帧缓存,采用了VIDEO_BASEADDR0、VIDEO_BASEADDR1、VIDEO_BASEADDR2三个地址,三个基地址的分配取决于输入和输出的位宽,DDR3的地址是0x0000_0000,
// 使用1280*720*4=3,686,400,转换成16进制为384,000,0x0138_4000,小于基地址之间间隔0x0200_0000
Xil_Out32(VDMA_BASEADDR + 0xAC, 0x08000000);//S2MM Start Addresses
Xil_Out32(VDMA_BASEADDR + 0xAC+4, 0x0A000000);
Xil_Out32(VDMA_BASEADDR + 0xAC+8, 0x0C000000);
Xil_Out32(VDMA_BASEADDR + 0xA4, horizontalActiveTime*4);//S2MM Horizontal Size 该寄存器的低16bit用于指定每一行有多少个字节的数据要传输,例如显示分辨率为1280*720,每个像素4个字节(RGB+Alpha),其值应该设置为1280*4
Xil_Out32(VDMA_BASEADDR + 0xA8, horizontalActiveTime*4);//S2MM Frame Delay and Stride 低16位指定水平方向的跨度,同样以字节为单位。跨度指的是每两行第一个像素之间间隔的数据个数,可参见VDMA帧存格式。
Xil_Out32(VDMA_BASEADDR + 0x30, 0x3);//S2MM VDMA Control Register
Xil_Out32(VDMA_BASEADDR + 0xA0, verticalActiveTime);//S2MM Vertical Size start an S2M 该寄存器的低13bit用于指定总共有多少行。
Xil_DCacheFlush();
Xil_Out32((VDMA_BASEADDR + AXI_VDMA_REG_DMA_CTRL),
0x4); //reset MM2S VDMA Control Register
Xil_Out32((VDMA_BASEADDR + AXI_VDMA_REG_DMA_CTRL),
0x8); //genlock
Xil_Out32((VDMA_BASEADDR + AXI_VDMA_REG_START_1),
0x08000000); // start address
Xil_Out32((VDMA_BASEADDR + AXI_VDMA_REG_START_2),
0x0A000000); // start address
Xil_Out32((VDMA_BASEADDR + AXI_VDMA_REG_START_3),
0x0C000000); // start address
Xil_Out32((VDMA_BASEADDR + AXI_VDMA_REG_FRMDLY_STRIDE),
(horizontalActiveTime*4)); // h offset 低16位指定水平方向上的跨度,以字节为单位。
Xil_Out32((VDMA_BASEADDR + AXI_VDMA_REG_H_SIZE),
(horizontalActiveTime*4)); // h size 低16bit指定每一行有多少字节的数据要进行传输。
Xil_Out32((VDMA_BASEADDR + AXI_VDMA_REG_DMA_CTRL),
0x00000003); // enable circular mode
Xil_Out32((VDMA_BASEADDR + AXI_VDMA_REG_V_SIZE),
verticalActiveTime); // v size 该寄存器的低13位指定总共有多少行要进行显示
Xil_DCacheFlush();
TPG
// tpg 基地址 0x43C00000
Xil_Out32(0x43C00000 + 0x0010, 720); // 一帧 720行
Xil_Out32(0x43C00000 + 0x0018, 1280); // 一帧 1280列
Xil_Out32(0x43C00000 + 0x0020, 0x9); // color bar
Xil_Out32(0x43C00000 + 0x0040, 0x0); //RGB格式
Xil_Out32(0x43C00000, 0x81); // 启动
Xil_DCacheFlush();
}