利用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摄像头采集笔记(二)的更多相关文章
- 利用AXI VDMA实现OV5640摄像头采集
利用AXI VDMA实现OV5640摄像头采集 导读:摄像头采样图像数据后经过VDMA进入DDR,通过PS部分控制,经过三级缓存,将DDR中保持的图形数据通过VDMA发送出去.在FPGA的接收端口产生 ...
- 利用ffmpeg一步一步编程实现摄像头采集编码推流直播系统
了解过ffmpeg的人都知道,利用ffmpeg命令即可实现将电脑中摄像头的画面发布出去,例如发布为UDP,RTP,RTMP等,甚至可以发布为HLS,将m3u8文件和视频ts片段保存至Web服务器,普通 ...
- 基于AXI VDMA的图像采集系统
基于AXI VDMA的图像采集系统 转载 2017年04月18日 17:26:43 标签: framebuffer / AXIS / AXI VDMA 2494 本课程将对Xilinx提供的一款IP核 ...
- 第46章 DCMI—OV5640摄像头—零死角玩转STM32-F429系列
第46章 DCMI—OV5640摄像头 全套200集视频教程和1000页PDF教程请到秉火论坛下载:www.firebbs.cn 野火视频教程优酷观看网址:http://i.youku.com ...
- ov5640摄像头设备驱动
http://www.cnblogs.com/firege/p/5806121.html (驱动大神) http://blog.csdn.net/yanbixing123/article/detai ...
- FPGA配置OV5640摄像头及RGB图像数据采集
本文设计思想采用明德扬至简设计法.在做摄像头数据采集处理之前,需要配置OV5640传感器内部寄存器使其按要求正常工作,详细内容请参见<OV5640自动对焦照相模组应用指南>.首先要关注OV ...
- 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 ...
- [转]GStreamer资料(摄像头采集,视频保存,远程监控)DVR
http://blog.csdn.net/wzwxiaozheng/archive/2010/12/26/6099397.aspx GStreamer资料整理(包括摄像头采集,视频保存,远程监控,流媒 ...
- 基于opencv和mfc的摄像头采集代码(GOMFCTemplate2)
编写带界面的图像处理程序,选择opencv+mfc是一种很好的选择:在读取摄像头数据方面,网上的方法很多,其中shiqiyu的camerads的方法是较好的. 基于现有资料 ...
随机推荐
- 手把手教你如何在Windows下allure与jenkins的集成生成让你一见钟情的测试报告 - 03(非常详细,非常实用)
简介 好了,国庆假期结束,开始搬砖.为什么要把allure和jenkins集成了?原因是集成以后,我们就可以直接查看allure的结果,不需要重复输入命令.重复使用浏览器打开文件来查看allure的结 ...
- for循环用腻了,试试列表生成式。
在编写程序或者查看别人的程序时,经常会遇到列表生成式,这个使用起来并不复杂,但是非常有用,使我们的代码更加简洁灵活.很多python使用者并不太会使用它.今天,就给大家详细讲解列表生成式和生成器表达式 ...
- 软件开发工具(第7章:Eclipse入门)
一.Eclipse简介 Eclipse [iˈklips],是一个开放源代 码的.基于Java的可扩展集成应 用程序开发环境. Eclipse最初主要用来进行Java语 言开发,但并非只有这个用途. ...
- hash长度扩展攻击
这里面就放一张百度百科的解释吧,emmm 反正我是看不懂还是做一下题来巩固一下吧 CTF中的hash长度攻击 进入网页你会发现页面显示  我这里没有看到什么可以利用的,抓了一下包也没有什么有可以利 ...
- 详述Python序列化
一.前言 1. 现实需求 每种编程语言都有各自的数据类型,其中面向对象的编程语言还允许开发者自定义数据类型(如:自定义类),Python也是一样.很多时候我们会有这样的需求: 把内存中的各种数据类型的 ...
- Paid Roads POJ - 3411
A network of m roads connects N cities (numbered from 1 to N). There may be more than one road conne ...
- Centos 7.2天兔(Lepus 3.8)数据库监控系统部署
天兔(Lepus 3.8)数据库监控系统部署 转载自:https://blog.csdn.net/m0_38039437/article/details/79613260 一.安装LAMP基础环境 首 ...
- Ubuntu安装exfat工具
sudo apt-get undate sudo apt-get install exfat-utils
- wait,notify,notifyAll详细介绍
https://www.cnblogs.com/pangyang/articles/5916349.html
- opencv::轮廓发现(find contour in your image)
轮廓发现(find contour) 轮廓发现是基于图像边缘提取的基础寻找对象轮廓的方法. 所以边缘提取的阈值选定会影响最终轮廓发现结果 //发现轮廓 cv::findContours( InputO ...