Zynq-PS-SDK(14) 之 OV5640-HDMI 视频通路硬件搭建
目录
1、OV5640
1.1、OV5640 Input Signals
1.2、OV5640 Output Signals
2、Video In to AXI4-Stream
在前面介绍了使用 VDMA + VTC + Video Out 搭建的显示通路,后端接转码 TMDS 差分信号输出到 HDMI 上;这里不再使用静态图片,使用 OV5640 摄像头作为 Video 输入,最终将视频信息输出到 HDMI 屏上;数据的输出部分,我们沿用之前的 VDMA + VTC + Dynamic Clock + rgb2dvi 那套通路;数据的输入部分需要研究一下 OV5640 的时序,以及如何将数据抓到我们内部并进行传输;
这里有几个点需要进行分析:
1、如何配置 OV5640 让其输出视频;
2、如何将 OV5640 的数据,怼到我们内部;
3、之前 VDMA 只有将数据从内存搬运出来,这里增加了数据源的输入通路,如何处理竞争;
1、OV5640
介绍 OV5640 的资料很多很多,这里简单的叙述一下即可,他是一颗 CMOS 摄像头,其感光阵列达到2592*1944(即500W像素),能实现最快15fps QSXVGA(2592*1944)或者90fps VGA(640*480)分辨率的图像采集。传感器采用OmniVision推出的OmniBSI(背面照度)技术,使传感器达到更高的性能,如高灵敏度、低串扰和低噪声。传感器内部集成了图像处理的功能,包括自动曝光控制(AEC)、自动白平衡(AWB)等。同时该传感器支持LED补光、MIPI(移动产业处理器接口)输出接口和 DVP(数字视频并行)输出接口选择、ISP(图像信号处理)以及AFC(自动聚焦控制)等功能;
它的内部框图如下所示:
由上图可知,时序发生器(timing generator)控制着感光阵列(image array)、放大器(AMP)、AD转换以及输出外部时序信号(VSYNC、HREF 和 PCLK),外部时钟XVCLK经过PLL锁相环后输出的时钟作为系统的控制时钟;感光阵列将光信号转化成模拟信号,经过增益放大器之后进入10位AD转换器;AD转换器将模拟信号转化成数字信号,并且经过ISP进行相关图像处理,最终输出所配置格式的10位视频数据流。增益放大器控制以及ISP等都可以通过寄存器(Registers)来配置,配置寄存器的接口就是SCCB接口,该接口协议兼容 IIC 协议;
1.1、OV5640 Input Signals
我们整理一个简单的 OV5640 的输入输出信号:
XVCLK 输入时钟,SCCB 用于对 OV5640 进行配置,配置的内容可以参考 OV5640 的datasheet 和《OV5640_自动对焦照相模组应用指南(DVP_接口)》;
SCCB 的协议具体描述,参考文档:《OmniVision Technologies Seril Camera Control Bus(SCCB) Specification》,网上很多介绍,这里我们不再多说;
SCCB 可以配置很多 OV5640 的关键特性,包括 XVCLK 输入后的 PLL,输出图像的格式(YUV/RGB),输出方式 MIPI/DVP,是否需要使用 ISP 进行处理,等等,有兴趣可以研究一下 datasheet 并进行尝试;
1.2、OV5640 Output Signals
通过 SCCB 配置完 OV5640 后,那么 OV5640 便开始输出图像数据了,它支持 1080p,720p 等等,以及不同分辨率,这些都囊括在 SCCB 配置中;同样分辨率下,不同帧率的输出,主要体现在 pclk 信号上,pclk 信号是输出的时钟,提频导致输出更多的数据,也就是帧率的含义了;
打个比如:
VSYNC:场同步信号,由摄像头输出,用于标志一帧数据的开始与结束。上图中VSYNC的高电平作为一帧的同步信号,在低电平时输出的数据有效。需要注意的是场同步信号是可以通过设置寄存器位进行取反的,即低电平同步高电平有效,这里和上图一致的默认设置;
HREF/HSYNC:行同步信号,由摄像头输出,用于标志一行数据的开始与结束。上图中的HREF和HSYNC是由同一引脚输出的,只是数据的同步方式不一样。本次实验使用的是HREF格式输出,当HREF为高电平时,图像输出有效,可以通过寄存器进行配置。这里使用的是HREF格式输出;
D[9:0]:数据信号,由摄像头输出,在RGB格式输出中,只有高8位D[9:2]是有效的;
tPCLK:一个像素时钟周期;
tp:单个数据周期,这里需要注意的是上图中左下角红框标注的部分,在RGB模式中,tp代表两个tPCLK(像素时钟)。以RGB565数据格式为例,RGB565采用16bit数据表示一个像素点,而OV5640在一个像素周期(tPCLK)内只能传输8bit数据,因此需要两个时钟周期才能输出一个RGB565数据;
这里使用 DVP + RGB565 方式进行输出,每两个 PCLK 传输一个像素,它的定义为:
2、Video In to AXI4-Stream
上面描述了如何配置和使用 OV5460 进行输出图像数据,它输出的数据是 8bit + 8bits 的图像数据,这里我们需要将这个数据怼到我们的系统中(内存中),为何要放到内存中呢,因为 VDMA 的输出是从 DDR framebuffer 去拿数据,所以呢,我们要想办法将视频数据仍到 DDR 中,让 VDMA 去拿;
VDMA 管理的到内存的写入是通过 S2MM 接口进行的,输入端是 AXI-Stream 的数据流,输出端是 AXI HP 到 memory controller,所以呢,这里,我们需要将图像数据转成为 AXI-Stream 数据,并接到 VDMA 的 S2MM 接口;
这里我们写一个 IP,来对 OV5640 的数据进行抓取,同时将数据怼到 Video In to AXI4-Stream IP ,利用 Video In to AXI4-Stream 进行输出 AXI-Stream 到 VDMA,在到 DDR;既然要用到 Video In to AXI4-Stream,那么我们大概分析一下他的输入,这样我们才能够去设计一个采集 OV5640 的 IP,将数据灌入到 DDR;
这里我们为了将数据输入到 Video In to AXI4-Stream,我们需要了解 Video In to AXI4-Stream 输入的数据和时序:
Video In to AXI4-Stream
为了简化设计,我们这里设计的 IP 包含以下几个信号,并且直接输入到 Video In to AXI4-Stream:
1、clk:时钟信号;
2、clk_en:时钟有效信号;
3、vsync:一帧的起始;
4、active:图像有效信号;
5、data[23:0]:RGB888 的数据信号;
这里需注意的一点:我们采集到数据是 2 个 pclk 产生一个像素,像素是 16bits 的 RGB565,我们需要将 RGB565 -> RGB888,并输入到 Video In to AXI4-Stream,我们的设计文件为:
`timescale 1ns / 1ps
//
// Company : Stephen Zhou Tech
// Engineer : StephenZhou
//
// Create Date : 2021/05/20 14:57:44
// Design Name :
// Module Name : Steph_OVSensorDVPCaptureV2
// Project Name :
// Target Devices : Zynq-7000
// Tool Versions :
// Description : Capture the OV5640 Image data
//
// Dependencies :
//
// Revision:
// Revision 0.02 - File Created
// Additional Comments:
//
//module Steph_OVSensorDVPCaptureV2(// enableinput ov_en_i ,// OV5640 Signalsinput ov_pclk_i ,input ov_vsync_i ,input ov_href_i ,input [9:0] ov_data_i ,// Output to Video In AXI Streamoutput vid_clk_o ,output vid_clk_en_o ,output vid_vsync_o ,output vid_active_o ,output [23:0] vid_data_o
);// Wair for video valid counterlocalparam VIDEO_STABLE_FRAME_CNT = 4'd15;reg vsync_d0 ;reg vsync_d1 ;wire vsync_pos ;reg [3:0] vsync_cnt ;reg wait_done ;reg ov_href_d0 ;reg ov_href_d1 ;reg [7:0] data_in_d0 ;reg [15:0] data_16bits ;reg data_merge ;reg data_merge_d0 ;assign vsync_pos = (~vsync_d1) & vsync_d0;assign vid_clk_o = ov_pclk_i;assign vid_vsync_o = wait_done ? (vsync_d1) : 1'b0;assign vid_active_o = wait_done ? (ov_href_d1) : 1'b0;assign vid_clk_en_o = wait_done ? ((data_merge_d0 & vid_active_o) || (!vid_active_o)) : 1'b0;assign vid_data_o = wait_done ? { data_16bits[15:11],3'd0 , data_16bits[10:5],2'd0 , data_16bits[4:0],3'd0 } : 24'd0;always @ (posedge ov_pclk_i) beginif(~ov_en_i) beginvsync_d0 <= 1'b0;vsync_d1 <= 1'b0;endelse beginvsync_d0 <= ov_vsync_i;vsync_d1 <= vsync_d0;endendalways @ (posedge ov_pclk_i) beginif(~ov_en_i) beginvsync_cnt <= 4'd0;endelse if (vsync_pos && (vsync_cnt < VIDEO_STABLE_FRAME_CNT)) beginvsync_cnt <= vsync_cnt + 1'b1;endelse beginvsync_cnt <= vsync_cnt;endend// Generate wait done signalalways @ (posedge ov_pclk_i) beginif(~ov_en_i) beginwait_done <= 4'd0;endelse if (vsync_pos && (vsync_cnt == VIDEO_STABLE_FRAME_CNT)) beginwait_done <= 1'b1;endelse beginwait_done <= wait_done;endendalways @ (posedge ov_pclk_i) beginif(~ov_en_i) beginov_href_d0 <= 4'd0;ov_href_d1 <= 4'd0;endelse beginov_href_d0 <= ov_href_i;ov_href_d1 <= ov_href_d0;endendalways @ (posedge ov_pclk_i) beginif(~ov_en_i) begindata_in_d0 <= 8'd0;endelse if (ov_href_i) begindata_in_d0 <= ov_data_i[9:2];endelse begindata_in_d0 <= 8'd0;endendalways @ (posedge ov_pclk_i) beginif(~ov_en_i) begindata_merge <= 1'b0;endelse if (ov_href_i) begindata_merge <= ~data_merge;endelse begindata_merge <= 1'b0;endendalways @ (posedge ov_pclk_i) beginif(~ov_en_i) begindata_16bits <= 1'b0;endelse if (ov_href_i && data_merge) begindata_16bits <= {data_in_d0, ov_data_i[9:2]};endelse begindata_16bits <= data_16bits;endendalways @ (posedge ov_pclk_i) beginif(~ov_en_i) begindata_merge_d0 <= 1'b0;endelse begindata_merge_d0 <= data_merge;endendendmodule
这部分设计完毕后,设计流程就成为如下:
在之前的 《Zynq-PS-SDK(12) 之 VDMA+VTC+AXI4S-VideoOut 视频通路硬件搭建》我们的 VDMA 只处理一帧数据,现在情况比较复杂了,又有输入,又有输出,如果不处理这种冲突的话,势必导致对同一帧数据,同时进行读写的情况,导致图像撕裂;我们这里整成 3 块 framebuffer,同时开启 VDMA 的 Dynamic GenLock,避免出现同时读写一帧的缓存;
配置完毕后,Generate Output Product,然后进行生成 Bitstream;
BD 的设计图中,抓取摄像头数据导入 Video In AXI-Stream 部分的连线如下所示:
整个 BD 的设计如下所示:
Zynq-PS-SDK(14) 之 OV5640-HDMI 视频通路硬件搭建相关推荐
- Zynq-PS-SDK(13) 之 VDMA+VTC+AXI4S-VideoOut 视频通路软件配置
在<Zynq-PS-SDK(12) 之 VDMA+VTC+AXI4S-VideoOut 视频通路硬件搭建>我们已经生成了 bitStream,硬件环境已经准备 OK,接下来进行软件的配置: ...
- AXI总线技术简介——ZYNQ PS和PL的互联技术
AXI总线技术简介--ZYNQ PS和PL的互联技术 1.AXI总线介绍 2.AXI协议通道介绍 3.ZYNQ芯片内部的AXI总线 4.常用AXI接口IP介绍 5. 多个AXI接口互联交互 1.AXI ...
- Zynq PS DMA控制器应用笔记
Zynq PS DMA应用笔记 Hello,Panda Zynq-7000系列器件PS端的DMA控制器采用ARM的IP核DMA-330(PL-330)实现.有关DMA控制器的硬件细节及相关指令集.编程 ...
- linux zynq ps dma,Zynq PS侧DMA驱动
Linux中,驱动必然会有驱动对应的设备类型.在linux4.4版本中,其设备是以设备树的形式展现的. PS端设备树的devicetree表示如下 324 dmac_s: dmac@f8003000 ...
- ZYNQ PS端模块读书笔记-中断
作者:ShownSun 工作室:时沿科技 文章目录 ZYNQ PS端模块读书笔记-中断 0 引言 1 环境 1.1 私有.共享和软件中断 1.2 通用中断控制器 1.3 复位和时钟 1.4 模块框图 ...
- 从官方例程深度学习海思SDK及API-第2/11季视频课程-朱有鹏-专题视频课程
从官方例程深度学习海思SDK及API-第2/11季视频课程-230人已学习 课程介绍 本季课程详细分析海思SDK中的sample程序的实现,讲解视频采集中的基本概念,视频sensor的 ...
- zynq PS侧DMA驱动
linux中,驱动必然会有驱动对应的设备类型.在linux4.4版本中,其设备是以设备树的形式展现的. PS端设备树的devicetree表示如下 324 dmac_s: dmac@f8003000 ...
- FPGA USB FX2 ov5640摄像头视频采集 驱动CY7C68013A实现 提供2套工程源码和技术支持
目录 1.前言 2.我这儿已有的 FPGA USB 通信方案 3.CY7C68013A芯片解读和硬件设计 FX2 简介 SlaveFIFO模式及其配置 4.工程详细设计方案 5.vivado工程 6. ...
- ZYNQ PS及MicroBlaze访问FPGA端BRAM实战
目录 一.背景 二.BRAM是什么? 三.MicroBlaze连接BRAM外设 四.实战代码 一.背景 Xilinx Zynq和带MicroBlaze的FPGA都存在处理器端和FPGA端的概念, 如 ...
- FPGA驱动FT601实现USB3.0相机HDMI视频采集 提供工程源码和QT上位机源码
目录 1.前言 2.FT601芯片解读和时序分析 FT601功能和硬件电路 FT601读时序解读 FT601写时序解读 3.我这儿的 FT601 USB3.0通信方案 4.详细设计方案 5.vivad ...
最新文章
- 西南大学计算机英语统考时间,西南大学2018年9月全国计算机等级考试报名通知...
- Open Street Map维基世界地图初探--概念、开发
- 012_Comparable和Comparator实例
- CPU profiling
- 多元正态分布、多元t分布中的行列式求解 Java
- javascript实战pdf_web前端入门到实战:10分钟入门 CSS3 Animation
- PCL之计算点云质心---pcl::compute3DCentroid()
- 利用注册表修改桌面背景
- FAT32U盘挂载无法更改权限记录
- WinCE下Touch Panel驱动介绍
- 国内航线图 或城市之间连接图
- 使用web-play开发web应用
- SQL数据查询——单表查询(二)
- 整理的一些 Vue3 知识点
- 致铭主板好礼等着您拿
- 【GAT】如何理解Graph Attention Network(注意力机制)?
- 卡尔曼滤波+20201205
- 科技新品 | 大疆航拍小飞机重量不到249克;绘王数位屏薄至12毫米;追觅科技机器人吸尘器低至65分贝静音水平...
- 视频点播RTMP推流直播流媒体服务二次开发集成接口
- 【236期】ElasticSearch 进阶:一文全览各种 ES 查询在 Java 中的实现