目录

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 视频通路硬件搭建相关推荐

  1. Zynq-PS-SDK(13) 之 VDMA+VTC+AXI4S-VideoOut 视频通路软件配置

    在<Zynq-PS-SDK(12) 之 VDMA+VTC+AXI4S-VideoOut 视频通路硬件搭建>我们已经生成了 bitStream,硬件环境已经准备 OK,接下来进行软件的配置: ...

  2. AXI总线技术简介——ZYNQ PS和PL的互联技术

    AXI总线技术简介--ZYNQ PS和PL的互联技术 1.AXI总线介绍 2.AXI协议通道介绍 3.ZYNQ芯片内部的AXI总线 4.常用AXI接口IP介绍 5. 多个AXI接口互联交互 1.AXI ...

  3. Zynq PS DMA控制器应用笔记

    Zynq PS DMA应用笔记 Hello,Panda Zynq-7000系列器件PS端的DMA控制器采用ARM的IP核DMA-330(PL-330)实现.有关DMA控制器的硬件细节及相关指令集.编程 ...

  4. linux zynq ps dma,Zynq PS侧DMA驱动

    Linux中,驱动必然会有驱动对应的设备类型.在linux4.4版本中,其设备是以设备树的形式展现的. PS端设备树的devicetree表示如下 324 dmac_s: dmac@f8003000 ...

  5. ZYNQ PS端模块读书笔记-中断

    作者:ShownSun 工作室:时沿科技 文章目录 ZYNQ PS端模块读书笔记-中断 0 引言 1 环境 1.1 私有.共享和软件中断 1.2 通用中断控制器 1.3 复位和时钟 1.4 模块框图 ...

  6. 从官方例程深度学习海思SDK及API-第2/11季视频课程-朱有鹏-专题视频课程

    从官方例程深度学习海思SDK及API-第2/11季视频课程-230人已学习 课程介绍         本季课程详细分析海思SDK中的sample程序的实现,讲解视频采集中的基本概念,视频sensor的 ...

  7. zynq PS侧DMA驱动

    linux中,驱动必然会有驱动对应的设备类型.在linux4.4版本中,其设备是以设备树的形式展现的. PS端设备树的devicetree表示如下 324 dmac_s: dmac@f8003000 ...

  8. FPGA USB FX2 ov5640摄像头视频采集 驱动CY7C68013A实现 提供2套工程源码和技术支持

    目录 1.前言 2.我这儿已有的 FPGA USB 通信方案 3.CY7C68013A芯片解读和硬件设计 FX2 简介 SlaveFIFO模式及其配置 4.工程详细设计方案 5.vivado工程 6. ...

  9. ZYNQ PS及MicroBlaze访问FPGA端BRAM实战

    目录 一.背景 二.BRAM是什么? 三.MicroBlaze连接BRAM外设 四.实战代码 一.背景 Xilinx  Zynq和带MicroBlaze的FPGA都存在处理器端和FPGA端的概念, 如 ...

  10. FPGA驱动FT601实现USB3.0相机HDMI视频采集 提供工程源码和QT上位机源码

    目录 1.前言 2.FT601芯片解读和时序分析 FT601功能和硬件电路 FT601读时序解读 FT601写时序解读 3.我这儿的 FT601 USB3.0通信方案 4.详细设计方案 5.vivad ...

最新文章

  1. 西南大学计算机英语统考时间,西南大学2018年9月全国计算机等级考试报名通知...
  2. Open Street Map维基世界地图初探--概念、开发
  3. 012_Comparable和Comparator实例
  4. CPU profiling
  5. 多元正态分布、多元t分布中的行列式求解 Java
  6. javascript实战pdf_web前端入门到实战:10分钟入门 CSS3 Animation
  7. PCL之计算点云质心---pcl::compute3DCentroid()
  8. 利用注册表修改桌面背景
  9. FAT32U盘挂载无法更改权限记录
  10. WinCE下Touch Panel驱动介绍
  11. 国内航线图 或城市之间连接图
  12. 使用web-play开发web应用
  13. SQL数据查询——单表查询(二)
  14. 整理的一些 Vue3 知识点
  15. 致铭主板好礼等着您拿
  16. 【GAT】如何理解Graph Attention Network(注意力机制)?
  17. 卡尔曼滤波+20201205
  18. 科技新品 | 大疆航拍小飞机重量不到249克;绘王数位屏薄至12毫米;追觅科技机器人吸尘器低至65分贝静音水平...
  19. 视频点播RTMP推流直播流媒体服务二次开发集成接口
  20. 【236期】ElasticSearch 进阶:一文全览各种 ES 查询在 Java 中的实现

热门文章

  1. linux定时器原理
  2. 娱乐视频直播背后的技术支持——DASH重构
  3. 三权鼎立形式的软件开发方式
  4. 数字签名的原理和应用
  5. U盘引导启动LINUX
  6. OpenCV实现监控移动侦测
  7. Linux内核学习路线 学习linux内核的建议
  8. 入门Struts1第一讲——Struts1入门就这么简单
  9. android判断极光推送是不是注册成功,android极光推送用户怎么注册sdk
  10. 如何使用 DiskGenius 合并分区