我准备在PYNQ中创建一个MIPI成像平台,我们可以借此使用它来探索Vitis视觉库。介绍PYNQ的优势之一是它能够非常轻松地生成高性能应用程序。除了Ultra96V2之外,我们看到的大多数PYNQ板都与Zynq7000相关(PYNQZ1、Z2)。新的PYNQZU板为我们提供了MPSOC类设备和从FMC到SYZYGY、Pmod和RPI的一系列接口。对于图像处理,它具有HDMI输入和输出、MiniDP以及最令我兴奋的MIPI接口,可与DigilentPCAM5C配合使用。对于连接,该板为我们提供了4个USB主机和1个USB复合接口。在这个项目中,我们将创建一个使用MIPI接口的设计,这将用于捕获帧。这将创建一个平台,使我能够探索AMD-XilinxVitisVision库。首先,我们需要下载PYNQZU的PYNQSD卡映像并将其写入SD卡。这将为我们提供一个PYNQ映像,我们可以在板上启动并开始使用。PYNQ2.7版本是在AMD-Xilinx工具链的2020.2版本中开发的。为了保持兼容性,我们还将在同一工具链中开发应用程序。设置Vivado要开始开发PYNQ覆盖,我们首先需要下载并安装PYNQZU板定义。我们可以从XilinxBoardStore获取电路板定义。从https://github.com/Xilinx/XilinxBoardStore克隆存储库克隆后,将PYNQZU板文件从克隆位置复制到Vivado安装。将文件PYNZU文件夹复制到/Vivado/2020.2/data/boards/board_files包含板文件后,下一阶段是从https://github.com/Xilinx/PYNQ/tree/image_v2.7克隆PYNQ存储库克隆PYNQ存储库后,在PYNQ\boards\ip\hls目录下运行build_ip.bt或sh,具体取决于开发机器。这将构建HSLIP内核,以便我们可以在Vivado中使用它们最后阶段是克隆下面的存储库——其中包含几个TCL脚本,可用于使用MIPI构建图像处理链。https://github.com/ATaylorCEngFIET/Vivado_Blocks创建叠加层克隆所有存储库后,下一步是在Vivado中创建一个项目:选择新建项目输入项目名称和位置选择RTL项目并将源留待以后选择选择PYNQZU板作为目标单击完成以创建项目打开项目后,下一步是创建一个新的框图,从左侧菜单中选择创建框图保持框图名称不变在TCL控制台中,将目录更改为克隆的ADIUVOVivadoBlocks存储库的位置使用命令获取脚本mipi_pcam.tcl:sourcemipi_pcam.tcl使用命令创建PCamMIPI块:create_hier_cell_mipi_pcam5.mipi_pcam这将创建一个具有所有必要时钟和元素的MIPI接口块展开块以检查内容打开IP目录并选择添加存储库导航并选择克隆的PYNQ目录中的IP文件夹您将看到几个IP被检测到并添加到项目中在IP目录中选择PixelPackIP,注意它没有打包用于MPSOC设备。右键单击IP块并选择在IP打包器中编辑:这将打开一个带有要编辑的IP的新Vivado项目,选择兼容性并确保可以为所有设备生成IP重新打包IP核并关闭项目回到主Vivado项目,我们现在可以添加PixelPackIP块添加像素包IP添加以下IP以创建最终系统MPSOC-处理器内核子集转换器-重新映射像素VDMA-配置为写入AXI中断控制器连接块添加MPSOC模块后,运行模块自动化以针对PYNQZU设置配置处理器最终设计应如下所示:在MIPI模块中,我们需要将MIPIIP连接到设备上的引脚,如下表所示:我添加了一个恒定输出设置为1以始终启用相机。完成后,我们可以创建HDL包装器并构建位文件。由于我们将把它用于PYNQ覆盖,我们只需要HWH文件和位文件。创建笔记本在Jupyter环境中(通过WIFI或USB-以太网连接时,在浏览器中转到PYNQ:9090)我创建了一个名为Adiuvo的新文件夹,并将bit和HWH移交文件上传到该文件夹。请注意,我将两个文件重命名为相同的名称。我们还将创建一个笔记本以添加python命令。我们通过I2C配置相机,PYNQZU使用PSI2C0并使用I2C多路复用器连接到多个不同的I2C总线。检查我们的相机已通电并以正确的方式连接到连接器中。我们可以在PYNQ中打开一个终端并运行i2cdetect-l命令来确定I2C通道。相机连接到I2CMux通道3。这使其成为I2C-6,运行命令i2cdetect-r-y6将列出网络上的所有I2C设备。如果存在,相机应响应地址0x3C。主要应用如下:frompynqimportOverlayfrompynq.lib.videoimport*importPIL.Imageimportcv2importmatplotlib.pyplotaspltimportscipy.ndimageimportmatplotlib.imageasmpimgimportsmbus2fromsmbus2importSMBus,i2c_msgol=Overlay("/home/xilinx/jupyter_notebooks/adiuvo/mipi_ol.bit")ol?vdma=ol.axi_vdma_0videomode=VideoMode(1280,720,24)i2c_bus=smbus2.SMBus(6)Sensor_addr=0x3cmsg=i2c_msg.write(Sensor_addr,[0x31,0x00])i2c_bus.i2c_rdwr(msg)msg=i2c_msg.read(Sensor_addr,0x1)i2c_bus.i2c_rdwr(msg)data=list(msg)print("CameraIDis=",hex(data[0]))demo=ol.mipi_pcam.v_demosaic_0mipi=ol.mipi_pcam.mipi_csi2_rx_subsyst_0cfg=[[0x3008,0x42],[0x3103,0x03],[0x3017,0x00],[0x3018,0x00],[0x3034,0x18],[0x3035,0x11],[0x3036,0x38],[0x3037,0x11],[0x3108,0x01],[0x303D,0x10],[0x303B,0x19],[0x3630,0x2e],[0x3631,0x0e],[0x3632,0xe2],[0x3633,0x23],[0x3621,0xe0],[0x3704,0xa0],[0x3703,0x5a],[0x3715,0x78],[0x3717,0x01],[0x370b,0x60],[0x3705,0x1a],[0x3905,0x02],[0x3906,0x10],[0x3901,0x0a],[0x3731,0x02],[0x3600,0x37],[0x3601,0x33],[0x302d,0x60],[0x3620,0x52],[0x371b,0x20],[0x471c,0x50],[0x3a13,0x43],[0x3a18,0x00],[0x3a19,0xf8],[0x3635,0x13],[0x3636,0x06],[0x3634,0x44],[0x3622,0x01],[0x3c01,0x34],[0x3c04,0x28],[0x3c05,0x98],[0x3c06,0x00],[0x3c07,0x08],[0x3c08,0x00],[0x3c09,0x1c],[0x3c0a,0x9c],[0x3c0b,0x40],[0x503d,0x00],[0x3820,0x46],[0x300e,0x45],[0x4800,0x14],[0x302e,0x08],[0x4300,0x6f],[0x501f,0x01],[0x4713,0x03],[0x4407,0x04],[0x440e,0x00],[0x460b,0x35],[0x460c,0x20],[0x3824,0x01],[0x5000,0x07],[0x5001,0x03]]forcmdincfg:#print(hex(cmd[0]))#print(hex(cmd[1]))first=cmd[0].to_bytes(2,'big')#print(hex(first[0]),hex(first[1]),hex(cmd[1]))msg=i2c_msg.write(Sensor_addr,[first[0],first[1],cmd[1]])i2c_bus.i2c_rdwr(msg)awb=[[0x518d,0x00],[0x518f,0x20],[0x518e,0x00],[0x5190,0x20],[0x518b,0x00],[0x518c,0x00],[0x5187,0x10],[0x5188,0x10],[0x5189,0x40],[0x518a,0x40],[0x5186,0x10],[0x5181,0x58],[0x5184,0x25],[0x5182,0x11],[0x3406,0x00],[0x5183,0x80],[0x5191,0xff],[0x5192,0x00],[0x5001,0x03]]forcmdinawb:#print(hex(cmd[0]))#print(hex(cmd[1]))first=cmd[0].to_bytes(2,'big')#print(hex(first[0]),hex(first[1]),hex(cmd[1]))msg=i2c_msg.write(Sensor_addr,[first[0],first[1],cmd[1]])i2c_bus.i2c_rdwr(msg)res_720p=[[0x3008,0x42],[0x3035,0x21],[0x3036,0x46],[0x3037,0x05],[0x3108,0x11],[0x3034,0x1A],[0x3800,(0>>8)&0x0F],[0x3801,0&0xFF],[0x3802,(8>>8)&0x07],[0x3803,8&0xFF],[0x3804,(2619>>8)&0x0F],[0x3805,2619&0xFF],[0x3806,(1947>>8)&0x07],[0x3807,1947&0xFF],[0x3810,(0>>8)&0x0F],[0x3811,0&0xFF],[0x3812,(0>>8)&0x07],[0x3813,0&0xFF],[0x3808,(1280>>8)&0x0F],[0x3809,1280&0xFF],[0x380a,(720>>8)&0x7F],[0x380b,720&0xFF],[0x380c,(1896>>8)&0x1F],[0x380d,1896&0xFF],[0x380e,(984>>8)&0xFF],[0x380f,984&0xFF],[0x3814,0x31],[0x3815,0x31],[0x3821,0x01],[0x4837,36],[0x3618,0x00],[0x3612,0x59],[0x3708,0x64],[0x3709,0x52],[0x370c,0x03],[0x4300,0x00],[0x501f,0x03],[0x3008,0x02]]forcmdinres_720p:#print(hex(cmd[0]))#print(hex(cmd[1]))first=cmd[0].to_bytes(2,'big')#print(hex(first[0]),hex(first[1]),hex(cmd[1]))msg=i2c_msg.write(Sensor_addr,[first[0],first[1],cmd[1]])i2c_bus.i2c_rdwr(msg)demo.write(0x10,1280)demo.write(0x18,720)demo.write(0x28,0x03)demo.write(0x00,0x81)pixel_in=ol.pixel_pack_0pixel_in.bits_per_pixel=24mipi=ol.mipi_pcam.mipi_csi2_rx_subsyst_0op=mipi.read(0x60)print("virtualchannel0status=",hex(op))cam_vdma=ol.axi_vdma_0lines=720framemode=VideoMode(1280,lines,24)cam_vdma.readchannel.mode=framemodecam_vdma.readchannel.start()cam_vdma.readchannel.runningcam_vdma.readchannel.modeframe_camera=cam_vdma.readchannel.readframe()frame_color=cv2.cvtColor(frame_camera,cv2.COLOR_BGR2RGB)pixels=np.array(frame_color)plt.imshow(pixels)plt.show()运行后,它将向我们展示Jupyter笔记本中的图像:最后现在,我们有了一个可以运行的图像平台,我们可以有办法来探索Vitis视觉库了。如果您对此项目有任何想法、意见或问题,请在下方留言。以上内容翻译自网络,原作者:AdamTaylor,如涉及侵权,可联系删除。