方案
开发板:ebaz4205
摄像头:ov5640
显示器:vga接口,1080p
vivado设计
VTC
输出:视频显示同步信号
根据显示器的分辨率输出同步信号
clk:74.25Mhz(1024*720 60hz) (用一个clock wizard生成)
vga接口
输入:使能信号、视频数据
输出:vga数据
根据有效信号使能,向vga输出16位显示数据。
`timescale 1ns / 1ps
module video_active(
input active_video,
input [15:0] rgb_data_i,
output wire [15:0] rgb_data_out
);
assign rgb_data_out = (active_video == 1'b1) ? {rgb_data_i[7:0], rgb_data_i[15:8]}: 16'h0;
endmodule
AXI4-Stream to Video Out
输入:video_data 、 VTC输出的视频同步信号
输出:vga同步信号、视频数据
作用:将DDR取出的视频数据进行同步
输入输出位宽都为16bit
in_clk:200M
out_clk:74.25Mhz(1024*720 60hz)
VDMA
通过高速接口连接至zynq,通过zynq读写内存中的视频数据,输出至stream to video_out
clk:200M
OV5640模块
verilog驱动(配置)ov5640摄像头(摄像头自带驱动晶振)
摄像头输入:视频数据1024*720(可配置)、同步信号、像素时钟
RTL输出:iic配置信号、复位、上电
50Mhz时钟用于输出配置信息
三个模块:iic通信模块、ov5640寄存器配置模块、sccb通信启动模块
代码托管:wrjxx/ov5640-驱动程序-verilog- (github.com)
modelsim仿真(debug)
寄存器配置到100被复位,检测发现计数溢出导致。修改为时序逻辑后解决,成功输出304个寄存器配置。
AXI4-Stream to Video In
接收摄像头采集的数据,传到VDMA
输入:同步信号、像素时钟(pclk)、视频数据
输出:视频数据 (clk=200M)
PS
时钟需求:74.25Mhz、50Mhz、200Mhz
74.25Mhz从PL晶振分频
50和200从PS得到
高速总线需求
报错
外部输入时钟
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets ov5640_pclk_IBUF]
xdc文件添加,降级该错误
vitis寄存器配置
xsa导入vitis,platform设备树工程,在main.c中配置vdma,编译。
一个像素占两个字节(所以要x2)
#include "xil_io.h"
#include "xil_types.h"
#include <stdio.h>
#include <sleep.h>
int main(){
Xil_Out32(0x43000000,0x1);
Xil_Out32(0x43000000+0x5C,0x01000000);
Xil_Out32(0x43000000+0x58,1024*2);
Xil_Out32(0x43000000+0x54,1024*2);
Xil_Out32(0x43000000+0x50,720);
Xil_Out32(0x43000000+0x30,0x1);
Xil_Out32(0x43000000+0xAC,0x01000000);
Xil_Out32(0x43000000+0xA8,1024*2);
Xil_Out32(0x43000000+0xA4,1024*2);
Xil_Out32(0x43000000+0xA0,720);
return 0;
}
1080p输出
改VTC ip核的参数为1080p
改VTC的输入时钟,1080p 60hz 时钟为148.5Mhz
改ov5640驱动中的寄存器配置,配置输出1080p的参数。(可参考github 1080p_cfg)
乒乓操作
使用外置的 DDR3 存储器作为帧缓存(显存),来避免视频割裂。
VDMA提供四种模式的 Genlock 同步。其中GenLock 同步锁相机制(保证读写同一块帧缓冲的顺序)。
①vivado中
VDMA设置 3帧缓存
②vitis中配置寄存器
指定三帧在ddr中的起始地址
#include "xil_io.h"
#include "xil_types.h"
#include <stdio.h>
#include <sleep.h>
int main(){
// read
Xil_Out32(0x43000000,0x8B);
Xil_Out32(0x43000000+0x5C,0x01000000);
Xil_Out32(0x43000000+0x60,0x02000000);
Xil_Out32(0x43000000+0x64,0x03000000);
Xil_Out32(0x43000000+0x58,1920*2);
Xil_Out32(0x43000000+0x54,1920*2);
Xil_Out32(0x43000000+0x50,1080);
//write
Xil_Out32(0x43000000+0x30,0x8B);
Xil_Out32(0x43000000+0xAC,0x01000000);
Xil_Out32(0x43000000+0xB0,0x02000000);
Xil_Out32(0x43000000+0xB4,0x03000000);
Xil_Out32(0x43000000+0xA8,1920*2);
Xil_Out32(0x43000000+0xA4,1920*2);
Xil_Out32(0x43000000+0xA0,1080);
return 0;
}
对0x8b的解释:10001011 ???
MM2S_VDMACR[3]=1,使能主、从通道之间的Genlock同步。
MM2S_VDMACR[7]=1,使能内部Genlock模式。
问题记录
一
vga和摄像头一直驱动不起来,给使能恒定高电平不行?
把使能和复位接在一起后就行了。why?
二
视频显示偏蓝绿色,寄存器错误配置为了YUV。修改后解决。