利用AXI VDMA实现OV5640摄像头采集

导读:摄像头采样图像数据后经过VDMA进入DDR,通过PS部分控制,经过三级缓存,将DDR中保持的图形数据通过VDMA发送出去。在FPGA的接收端口产生VID OUT时序驱动HDMI显示器显示图形。

一、          基础知识点

1、OV5640和VDMA之间同步信号的配置,输入端采样视频流协议中的tuser作为同步信号。

2、VDMA主要端口:

(1)、S_AXI_Lite:寄存器配置接口,用于软件配置VDMA,并读取状态信息。

(2)、S_AXI_S2MM:视频流入端,接收外来的视屏数据。

(3)、M_AXI_MM2S:AXI4全协议主端,从DDR中读取数据给M_AXI_MM2S。

(4)、M_AXI_S2MM:AXI4全协议主端,从DDR中读取的数据给M_AXI_S2MM

(5)、M_AXIS_MM2S:视频流接口,向外发送数据。

3、PL中的DMA IP对于DDR和PL存储资源来说是主机(Master),DMA对于PS来说是从机(Slave),PS通过AXI_Lite配置DMA的寄存器从原地址向目的地址转移多少数据,DMA通过AHP读写DDR,通过AXI读写PL资源。

4、在ZYNQ芯片内部,PS和PL是共享DDR控制器的,PS访问DDR只要操作DDR虚拟地址的应设计可,对于PL,要接入DDR,必须通过AXI_HP端口。

二、          框架分析

1、PS配置

(1)、processing_system7_0

PS模块处理单元,选择的是端口M_AXI_GP0,用于通过AXI-Lite总线配置外设,引出IIC总线,硬件中已经将其搭到IIC总线,同时引出两个时钟FCLK_CLK0(100Mhz)作为系统时钟,FCLK_CLK1(25Mhz)作为OV640摄像头驱动时钟,同时引出FCLK_RESET_N复位信号,用于系统中断时对系统进行复位。引出PS侧的DDR管脚,由此可以通过DMA读写DDR,同时PL侧DMA可以通过AXI-HP总线读取DDR的数据。对于两个AXI总线(S_AXI_HP0和M_AXI_GP0),两个时钟工作在相同的时钟下,都连接到FCLK_CLK0(100Mhz)。

此外,PS侧开启中断输入,检测中断。

(2)VDMA

输出部分:

VDMA数据接口可以分为读写通过,通过M_AXI_S2MM端口将数据流写入DDR3。通过M_AXI_MM2S端口可以从DDR3读取数据,并通过M_AXI_MM2S端口将DDR3中读取出的数据以AXIS_Stream类型输出。

VDMA与Zynq processor通过AXI_Interconnect进行连接。

输入部分:

在VDMA的IP配合部分,通过ZYNQ processor的M_AXI_GP接口进行配置。

视频数据输入是OV5640的数据经过video to Stream核实现的数据输入。对于这些AXI协议类型的总线,需要同步于ZYNQ自带的GP时钟,也就是ACLK,S00_ACLK,M00_ACLK,S01_ACLK都要用FCLK_CLK0时钟。

(3)Processor System Reset

输入信号:

系统复位处理器,slowest_sync_clk最小同步时钟,复位信号与时钟进行同步。复位输入信号是ZYNQ processor的FCLK_RESET_N。

输出信号

interconnect_aresetn:互联复位信号,连接到各个AXI connect连接模块的复位信号输入。

peripheral_aresetn:外围模块复位信号,作为其他各个外设模块的AXI总线复位信号输入。

三、          代码分析

1、 关于XiixPs_MasterSendPolled()函数

该函数在主模式下启动轮循(Polled)模式发送,讲数据发送到Fifo,并等待从机接收数据,如果设备无法送fifo中读取数据,导致发送超时而失败。

1.1     传入参数:

s32 XIicPs_MasterSendPolled(XIicPs *InstancePtr, u8 *MsgPtr, s32 ByteCount, u16 SlaveAddr)

@ 指向XiicPs实例结构的指针

@指向发送缓存区的指针

@要发送的字节数

@从设备的地址

1.2 语句1

if (((InstancePtr->IsRepeatedStart) != 0) ||

((ByteCount > XIICPS_FIFO_DEPTH) != 0U)) {

XIicPs_WriteReg(BaseAddr, XIICPS_CR_OFFSET,

XIicPs_ReadReg(BaseAddr, (u32)XIICPS_CR_OFFSET) |

(u32)XIICPS_CR_HOLD_MASK);

}

作用:

判断实例结构中时都设置为重复启动或者要放的数据的长度大于FIFO的深度。

由于条件1、2不成立,所以不会执行将IIC控制寄存器的bit4置一,该位的作用是:

0:在接收、发送完毕后,允许主机终止发送

1:在没有数据接收与发送时,保持时钟线为低直到主机操作

1.2     语句2 建立主机模式

(void)XIicPs_SetupMaster(InstancePtr, SENDING_ROLE);

SENDING_ROLE=1;

1.3     将所有的错误中断进行关联

Intrs = (u32)XIICPS_IXR_ARB_LOST_MASK | (u32)XIICPS_IXR_TX_OVR_MASK |      (u32)XIICPS_IXR_NACK_MASK;

1.4     启用中断前将所有中断标志位清除

IntrStatusReg = XIicPs_ReadReg(BaseAddr, XIICPS_ISR_OFFSET);

XIicPs_WriteReg(BaseAddr, XIICPS_ISR_OFFSET, IntrStatusReg);

采用的方式为先读取中断标志寄存器,然后将读出的数据再进行写入,寄存器类型为wtc,即write true clear,由此清除标志位。

1.5     清空发送fifo

(void)TransmitFifoFill(InstancePtr);

然后写入0V5640的地址,再将要发送的数据经过fifo发送出去。

1.6     等待发送完毕

while (XIicPs_BusIsBusy(InstancePtr));

查询IIC状态寄存器的发送标志位,0x04,改为为1的话表示发送完毕,结束该部分。

2、 对于VDMA的配置

(1)、Xil_Out32((VDMA_BASEADDR + 0x030), 0x108B);// enable circular mode

该地址对应的是S2MM VDMA控制寄存器,写入0x108B,即0x1000_1000_1010。该寄存器用于控制VDMA S2MM,可以实现复位、使能锁相同步、设定帧存切换模式、启动VDMA读写通道等操作。

bit3使能锁相同步或者动态锁相同步模式

0:关闭Genlocken和动态Genlock同步。

1:开启Genlock或Genlock同步

该位仅在通道配置为锁相同步从接口或者动态锁相从接口时才起作用。配置成锁相同步主接口时,该位为保留位,恒为0.

bit2:先将通道进行复位

0:正常操作

1:复位S2MM通道。

bit1:制定帧存为循环模式还是停留模式。

0:停留模式,显示用缓存也将停留在指定的帧存

1:循环模式,循环切换显示用缓存页。

bit0:控制VDMA的运行和停止,开始任何VDMA操作前,该位必须置一。

0:停止

1:运行

(2)、设置帧存的起始地址

Xil_Out32((VDMA_BASEADDR + 0x0AC), VIDEO_BASEADDR0);  // start address

Xil_Out32((VDMA_BASEADDR + 0x0B0), VIDEO_BASEADDR1);  // start address

Xil_Out32((VDMA_BASEADDR + 0x0B4), VIDEO_BASEADDR2);  // start address

S2MM_START_ADDRESS(1-16):Ach~E8h

以上几位用于设置S2MM的帧存地址。有最多32个寄存器用于存放帧存的起始地址,其分布在两个bank上:bank0和bank1,每个bank上有16个寄存器。

存储地址如何配置:

本次例程中用到了三帧缓存,采用了VIDEO_BASEADDR0、VIDEO_BASEADDR1、VIDEO_BASEADDR2三个地址,三个基地址的分配取决于输入和输出的位宽,DDR3的地址是0x0000_0000,实际使用时最好偏移0x0100_00000的地址来存储应用的数据,因为程序在运行过程中需要一些内存来运行,为了保证不冲突,对其加一个偏移量。设置的空间还要保证可以存储一帧数据,例如使用1280*720*4=3,686,400,转换成16进制为384,000,0x0100_0000+0x0138_4000,小于VIDEO_BASEADDR1的基地址0x0200_0000,因此分配是合理的。

(3)、设置帧延迟和跨度寄存器

Xil_Out32((VDMA_BASEADDR + 0x0A8), (H_STRIDE*3)); //h offset (H_STRIDE* 3) bytes

S2MM帧延迟和跨度寄存器,该寄存器有两个作用,

bit24~bit28:

仅用于Genlock从模式,bit24~bit28指定从接口要比主接口延迟多少个帧。

bit15~bit0:

低16位指定水平方向的跨度,同样以字节为单位。跨度指的是每两行第一个像素之间间隔的数据个数,可参见VDMA帧存格式。

(4)、设置S2MM_HSIZE S2MM水平方向尺寸

该寄存器的低16bit用于指定每一行有多少个字节的数据要传输,例如显示分辨率为640*480,每个像素4个字节(RGB+Alpha),其值应该设置为640*4

Xil_Out32((VDMA_BASEADDR + 0x0A4), (H_ACTIVE*3));     // h size (H_ACTIVE * 3) bytes

对于纯24bit的RGB数据,每一行有1280x3个字节,所以向寄存器写入行有效数x3。

(5)、设置S2MM_VSIZE垂直方向尺寸

Xil_Out32((VDMA_BASEADDR + 0x0A0), V_ACTIVE);         // v size (V_ACTIVE)

该寄存器的低13bit用于指定总共有多少行。

3、 对于DDR3读取数据的配置

3.1 MM2S VDMA控制寄存器配置

Xil_Out32((VDMA_BASEADDR + 0x000), 0x8B);     // enable circular mode

0x8B:  0x1000_1010

bit3:使能锁相同步或者动态锁相同步模式。

0:关闭锁相同步或者动态锁相同。

1:开启锁相同步或者动态锁相同。

bit2:复位控制

0:正常操作

1:复位MM2S通道

bit1:指定帧存为循环模式还是停留模式

0:停留模式,显示用的缓存页将停留在指定的帧存。

1:循环模式,循环切换显示用缓存页。

bit0:运行/停止控制,控制VDMA通道的停止和运行。

0:停止。

1:运行。

3.2 设置MM2S帧存起始地址

Xil_Out32((VDMA_BASEADDR + 0x05c), VIDEO_BASEADDR0); // start address

Xil_Out32((VDMA_BASEADDR + 0x060), VIDEO_BASEADDR1); // start address

Xil_Out32((VDMA_BASEADDR + 0x064), VIDEO_BASEADDR2); // start address

3.3 设置MM2S帧延迟和跨度寄存器

该寄存器仅适用于Genlock从模式,指定从接口要比主接口至少延迟多少个帧。低16位指定水平方向上的跨度,以字节为单位。

Xil_Out32((VDMA_BASEADDR + 0x058), (H_STRIDE*3));         // h offset (H_STRIDE * 3) bytes

3.4 MM2S水平方向显示大小寄存器设置

低16bit指定每一行有多少字节的数据要进行传输。

Xil_Out32((VDMA_BASEADDR + 0x054), (H_ACTIVE*3));         // h size (H_ACTIVE * 3) bytes

3.5 MM2S垂直方向显示大小寄存器配置

该寄存器的低13位指定总共有多少行要进行显示

Xil_Out32((VDMA_BASEADDR + 0x050), V_ACTIVE);         // v size (V_ACTIVE)

利用AXI VDMA实现OV5640摄像头采集的更多相关文章

  1. 利用AXI VDMA实现OV5640摄像头采集笔记(二)

    导读:摄像头采样图像数据后经过VDMA进入DDR,通过PS部分控制,经过三级缓存,将DDR中保持的图形数据通过VDMA发送出去.在FPGA的接收端口产生VID OUT时序驱动HDMI显示器显示图形. ...

  2. 利用ffmpeg一步一步编程实现摄像头采集编码推流直播系统

    了解过ffmpeg的人都知道,利用ffmpeg命令即可实现将电脑中摄像头的画面发布出去,例如发布为UDP,RTP,RTMP等,甚至可以发布为HLS,将m3u8文件和视频ts片段保存至Web服务器,普通 ...

  3. 基于AXI VDMA的图像采集系统

    基于AXI VDMA的图像采集系统 转载 2017年04月18日 17:26:43 标签: framebuffer / AXIS / AXI VDMA 2494 本课程将对Xilinx提供的一款IP核 ...

  4. 第46章 DCMI—OV5640摄像头—零死角玩转STM32-F429系列

    第46章     DCMI—OV5640摄像头 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com ...

  5. ov5640摄像头设备驱动

    http://www.cnblogs.com/firege/p/5806121.html  (驱动大神) http://blog.csdn.net/yanbixing123/article/detai ...

  6. FPGA配置OV5640摄像头及RGB图像数据采集

    本文设计思想采用明德扬至简设计法.在做摄像头数据采集处理之前,需要配置OV5640传感器内部寄存器使其按要求正常工作,详细内容请参见<OV5640自动对焦照相模组应用指南>.首先要关注OV ...

  7. Linux 下V4l2摄像头采集图片,实现yuyv转RGB,RGB转BMP,RGB伸缩,jpeglib 库实现压缩RGB到内存中,JPEG经UDP发送功(转)

    ./configure CC=arm-linux-gnueabihf-gcc LD=arm-linux-gnueabihf-ld --host=arm-linux --prefix=/usr/loca ...

  8. [转]GStreamer资料(摄像头采集,视频保存,远程监控)DVR

    http://blog.csdn.net/wzwxiaozheng/archive/2010/12/26/6099397.aspx GStreamer资料整理(包括摄像头采集,视频保存,远程监控,流媒 ...

  9. 基于opencv和mfc的摄像头采集代码(GOMFCTemplate2)

            编写带界面的图像处理程序,选择opencv+mfc是一种很好的选择:在读取摄像头数据方面,网上的方法很多,其中shiqiyu的camerads的方法是较好的.       基于现有资料 ...

随机推荐

  1. HDU2196computer

    就是求每个点为起始点的最长链的长度. 写一下各个数组的意思吧. f[i][0]为点i向下走最长的距离:f[i][1]为点i向下走第二长的距离: xia[i][0]为点i向下走最长距离所要走的儿子节点: ...

  2. EcShop开发手册

    Ecshop文件结构 ecshop文件架构说明 ECShop 结构图及各文件相应功能介绍 ECShop upload 的目录 ┣ activity.php 活动列表 ┣ affiche.php 广告处 ...

  3. Android中播放声音

    在Android系统中,有两种播放声音的方式,一种是通过MediaPlayer,另外一种是通过SoundPool.前者主要用于播放长时间的音乐,而后者用于播放小段小段的音效,像按键音这种,其优点是资源 ...

  4. Spring Boot教程(十一) springboot程序构建一个docker镜像

    准备工作 环境: linux环境或mac,不要用windows jdk 8 maven 3.0 docker 对docker一无所知的看docker教程. 创建一个springboot工程 引入web ...

  5. 组件内导航之beforeRouteUpdate的使用

    使用场景: 组件复用:路由跳转: beforeRouteUpdate (to, from, next) { // 在当前路由改变,但是该组件被复用时调用 // 举例来说,对于一个带有动态参数的路径 / ...

  6. druid监控每个服务数据库连接数和SQL执行效率

    1.下载druid 2.将刚刚下载的druid放入tomcat下的lib目录 3.配置要监控的服务启动文件,添加: -Dcom.sun.management.jmxremote.port=4090 - ...

  7. JAVA单例模式的实现伪代码

    什么是单例?:其定义是单例对象的类只能允许一个实例存在 单例的实现基本原理:1.将该类的构造方法定义为私有访问,不对外暴露从而使其他类不能实例化该类对象,只能通过该类的静态方法得到该类的唯一实例 2. ...

  8. 关于option标签的selected属性

    当item的dict_id和custSource一样,那么当前的item的name就被选中并显示在页面 如果直接写selected="selected",就等于直接回显这个集合中最 ...

  9. PTA编程总结三

    7-1 抓老鼠啊~亏了还是赚了? (20 分) 某地老鼠成灾,现悬赏抓老鼠,每抓到一只奖励10元,于是开始跟老鼠斗智斗勇:每天在墙角可选择以下三个操作:放置一个带有一块奶酪的捕鼠夹(T),或者放置一块 ...

  10. LeetCode_1114.按顺序打印(多线程)

    LeetCode_1114 LeetCode-1114.按顺序打印 我们提供了一个类: public class Foo { public void one() { print("one&q ...