目录
一、创建 Vivado 工程
二、创建 Processing System


三、配置ZYNQ7 Processing System
(1)配置 PS 的 UART


(2)配置 PS 的 GPIO MIO

(3)配置 PS 的 IIC
要勾选上Quad SPI Flash
配置I2C 0 为14 15
(4)配置 PS 的 DDR3 控制器

(5)配置 PS 的时钟
(6)取消勾选没有用到的接口


配置 ZYNQ7 Processing System 完成,点击“OK”。
点击上图中箭头所指示的位置“Run Block Automation”,会弹出如下图所示的对话框:

四、导出到SDK

五、SDK设计
(1)SDK 打开后,主页面会显示硬件描述文件 system.hdf 的内容。如下图所示:
system.hdf 标签页显示了整个 PS 系统的地址映射信息。大家应该还记得,在启动 SDK 之前,我们将硬件以一个 ZIP 压缩文件(system_wrapper.hdf)的形式导出到软件的工作空间。在 SDK 启动时,该文件会自动解压,大家可以在图 1.4.1 的左侧看到解压后的所有文件。其中,前四个文件(ps7_init_gpl.c、ps7_init_gpl.h、ps7_init.c 和 ps7_init.h)包含了 Zynq SOC 处理系统的初始化代码,以及 DDR、时钟、pll 和 MIO 的初始化设置信息。在初始化过程中,SDK 使用这些信息去配置相应的模块,使得应用程序能够在 PS 上运行。
(2)在菜单栏选择 File > New > Application Project, 新建一个 SDK 应用工程。
(4)可以看到 SDK 创建了一个 gpio_mio 目录和 gpio_mio_bsp 目录。我们打开 gpio_mio_bsp 目录下的system.mss 文件,找到 ps7_gpio_0,如下图 所示:
xgpiops_intr_example.c 包含有关如何直接使用 XGpiops 驱动程序的示例。此示例显示了中断模式下驱动程序的用法,并使用 GPIO 的中断功能检测按钮事件,根据输入控制 LED 输出。xgpiops_polled_example.c 同样包含有关如何直接使用 XGpiops 驱动程序的示例。此示例提供了用于读取/写入各个引脚的 API 的用法。从上面的介绍中,我们因为本实验暂未使用到中断,所以应该选择 xgpiops_polled_example 示例。选择好示例后,点击“OK”按钮。
六、IIC设计
下面为LT8619C IIC的读写测试代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "xil_types.h"
#include "xil_cache.h"
#include "xparameters.h"
//#include "xgpio.h"
#include "xaxivdma.h"
#include "xaxivdma_i.h"
//#include "display_ctrl/display_ctrl.h"
#include "vdma_api/vdma_api.h"
//#include "xv_tpg.h"
#include "xcsi2txss.h"
//#include "xcsiss.h"
#include "xgpiops.h"
#include "xtime_l.h"
//#include "xvtc.h"
//#include "xvidc.h"
//#include "xvprocss.h"
//#include "xrgb2ycrcb.h"
//#include "xiicps.h"
#include "LT8619C.h"
#include "xiicps.h"
//宏定义
#define IIC_SLAVE_ADDR 0x55
//#define IIC_SCLK_RATE 400000
#define TEST_BUFFER_SIZE 132
#define FRAME_BUFFER_NUM 3 //帧缓存个数
#define BYTES_PIXEL 3 //像素字节数,RGB888占3个字节
//#define DYNCLK_BASEADDR XPAR_AXI_DYNCLK_0_BASEADDR //动态时钟基地址
#define VDMA_ID XPAR_AXIVDMA_0_DEVICE_ID //VDMA器件ID
//#define DISP_VTC_ID XPAR_VTC_0_DEVICE_ID //VTC器件ID
//#define AXI_GPIO_0_ID XPAR_AXI_GPIO_0_DEVICE_ID //PL端 AXI GPIO 0(lcd_id)器件ID
//#define AXI_GPIO_0_CHANEL 1 //PL按键使用AXI GPIO(lcd_id)通道1
#define GPIO_DEVICE_ID XPAR_XGPIOPS_0_DEVICE_ID
#define XRGB_DEVICE_ID XPAR_RGB2YCRCB_0_DEVICE_ID
//XGpioPs InstancePtr;
//XGpioPs* XGInstancePtr = &InstancePtr;
//函数声明
//void colorbar(u8 *frame, u32 width, u32 height, u32 stride);
//全局变量
XAxiVdma vdma;
//XGpio Gpio; /* The Instance of the GPIO Driver */
//DisplayCtrl dispCtrl;
//XGpio axi_gpio_inst; //PL端 AXI GPIO 驱动实例
//VideoMode vd_mode;
//frame buffer的起始地址
unsigned int const frame_buffer_addr = (XPAR_PS7_DDR_0_S_AXI_BASEADDR+0x1000000);
unsigned int lcd_id=0; //LCD ID
XCsi2TxSs csitx_inst;
XIicPs Iic; /**< Instance of the IIC Device */
//XCsiSs csirx_inst;
int Status;
u32 volatile *gpio_hlsIpReset;
u32 volatile *gpio_videoLockMonitor;
XGpioPs_Config * XGpio_Cif;
char * FUNCTION = "[XGpiops_Init]";
XCsi2TxSs_Config *mipiTxConfigPtr;
//XCsiSs_Config *mipiRxConfigPtr;
int driverInit();
int Rgb2YCrCb_Update_Example(u16 DeviceId);
int IicPsMasterPolledExample(u16 DeviceId);
/*
* The following buffers are used in this example to send and receive data
* with the IIC.
*/
u8 SendBuffer[TEST_BUFFER_SIZE]; /**< Buffer for Transmitting Data */
u8 RecvBuffer[TEST_BUFFER_SIZE]; /**< Buffer for Receiving Data */
int main(void)
{
driverInit();
int Status=0;
XIicPs_Config *Config;
//***********************************************************************************
//mipi tx
XCsi2TxSs_ReportCoreInfo(&csitx_inst);
XCsi2TxSs_Reset(&csitx_inst);
XCsi2TxSs_SetClkMode(&csitx_inst, 1); //non-continuous clock mode
usleep(300000);
XCsi2TxSs_Activate(&csitx_inst, XCSI2TX_ENABLE);
//***********************************************************************************
//配置VDMA
run_vdma_frame_buffer(&vdma, VDMA_ID, 1280, 1024,frame_buffer_addr,0, 0,BOTH);
// usleep(300000);
//*********************************************************************************
LT8619C_intial();
//*********************************************************************************
Config = XIicPs_LookupConfig(IIC_DEVICE_ID);
if (NULL == Config) {
return XST_FAILURE;
}
Status = XIicPs_CfgInitialize(&Iic, Config, Config->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Perform a self-test to ensure that the hardware was built correctly.
*/
Status = XIicPs_SelfTest(&Iic);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
Status = XIicPs_SetSClk(&Iic, IIC_SCLK_RATE);
while(1)
{
SendBuffer[0]=0x60;
SendBuffer[1]=0x00;
Status = XIicPs_MasterSendPolled(&Iic, SendBuffer,2, 0x64>>1);
Status = XIicPs_MasterRecvPolled(&Iic, RecvBuffer,1, 0x64>>1);
SendBuffer[0]=0x60;
SendBuffer[1]=0x01;
Status = XIicPs_MasterSendPolled(&Iic, SendBuffer,2, 0x64>>1);
Status = XIicPs_MasterRecvPolled(&Iic, RecvBuffer+1,1, 0x64>>1);
SendBuffer[0]=0x60;
SendBuffer[1]=0x02;
Status = XIicPs_MasterSendPolled(&Iic, SendBuffer,2, 0x64>>1);
Status = XIicPs_MasterRecvPolled(&Iic, RecvBuffer+2,1, 0x64>>1);
SendBuffer[0]=0x60;
SendBuffer[1]=0x05;
SendBuffer[2]=0x65;
Status = XIicPs_MasterSendPolled(&Iic, SendBuffer,3, 0x64>>1);
usleep(1);
Status = XIicPs_MasterSendPolled(&Iic, SendBuffer,2, 0x64>>1);
Status = XIicPs_MasterRecvPolled(&Iic, RecvBuffer+3,1, 0x64>>1);
SendBuffer[0]=0x60;
SendBuffer[1]=0x07;
SendBuffer[2]=0x84;
Status = XIicPs_MasterSendPolled(&Iic, SendBuffer,3, 0x64>>1);
usleep(1);
Status = XIicPs_MasterSendPolled(&Iic, SendBuffer,2, 0x64>>1);
Status = XIicPs_MasterRecvPolled(&Iic, RecvBuffer+4,1, 0x64>>1);
}
/*
while(1)
{
usleep(300000);
XGpioPs_WritePin(&InstancePtr,7,1);
usleep(300000);
XGpioPs_WritePin(&InstancePtr,7,0);
}
*/
return 0;
}
int driverInit()
{
int status;
//***********************************************************************************
//GPIO
XGpio_Cif = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
status = XGpioPs_CfgInitialize(&InstancePtr,XGpio_Cif,XGpio_Cif->BaseAddr);
if(status != 0) {
xil_printf("%s XGpioPs_CfgInitialize error status:%d \n\r",FUNCTION,status);
return -1;
}
//set MIO 0 as output & set MIO 13 as output
XGpioPs_SetDirectionPin(&InstancePtr,7,1);
XGpioPs_SetDirectionPin(&InstancePtr,10,1);
//Enable
XGpioPs_SetOutputEnablePin(&InstancePtr,7,1);
XGpioPs_SetOutputEnablePin(&InstancePtr,10,1);
//***********************************************************************************
//mipi tx
mipiTxConfigPtr = XCsi2TxSs_LookupConfig(XPAR_CSI2TXSS_0_DEVICE_ID);
if (!mipiTxConfigPtr) {
return XST_FAILURE;
}
status=XCsi2TxSs_CfgInitialize(&csitx_inst, mipiTxConfigPtr,mipiTxConfigPtr->BaseAddr);
if (status != XST_SUCCESS) {
xil_printf("MIPI CSI TX SS config initialization failed.\n\r");
return XST_FAILURE;
}
//***********************************************************************************
//lt8619C
LT8619_Config = XIicPs_LookupConfig(IIC_DEVICE_ID);
if (NULL == LT8619_Config) {
return XST_FAILURE;
}
status = XIicPs_CfgInitialize(&Iic, LT8619_Config, LT8619_Config->BaseAddress);
if (status != XST_SUCCESS) {
return XST_FAILURE;
}
status = XIicPs_SelfTest(&Iic);
if (status != XST_SUCCESS) {
return XST_FAILURE;
}
XIicPs_SetSClk(&Iic, IIC_SCLK_RATE);
}
int IicPsMasterPolledExample(u16 DeviceId)
{
int Status;
XIicPs_Config *Config;
int Index;
/*
* Initialize the IIC driver so that it's ready to use
* Look up the configuration in the config table,
* then initialize it.
*/
Config = XIicPs_LookupConfig(DeviceId);
if (NULL == Config) {
return XST_FAILURE;
}
Status = XIicPs_CfgInitialize(&Iic, Config, Config->BaseAddress);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Perform a self-test to ensure that the hardware was built correctly.
*/
Status = XIicPs_SelfTest(&Iic);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Set the IIC serial clock rate.
*/
XIicPs_SetSClk(&Iic, IIC_SCLK_RATE);
/*
* Initialize the send buffer bytes with a pattern to send and the
* the receive buffer bytes to zero to allow the receive data to be
* verified.
*/
for (Index = 0; Index < TEST_BUFFER_SIZE; Index++) {
SendBuffer[Index] = (Index % TEST_BUFFER_SIZE);
RecvBuffer[Index] = 0;
}
/*
* Send the buffer using the IIC and ignore the number of bytes sent
* as the return value since we are using it in interrupt mode.
*/
Status = XIicPs_MasterSendPolled(&Iic, SendBuffer,
TEST_BUFFER_SIZE, IIC_SLAVE_ADDR);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Wait until bus is idle to start another transfer.
*/
while (XIicPs_BusIsBusy(&Iic)) {
/* NOP */
}
Status = XIicPs_MasterRecvPolled(&Iic, RecvBuffer,
TEST_BUFFER_SIZE, IIC_SLAVE_ADDR);
if (Status != XST_SUCCESS) {
return XST_FAILURE;
}
/*
* Verify received data is correct.
*/
for(Index = 0; Index < TEST_BUFFER_SIZE; Index ++) {
/* Aardvark as slave can only set 64 bytes for output */
if (RecvBuffer[Index] != Index % 64) {
return XST_FAILURE;
}
}
return XST_SUCCESS;
}
用逻辑分析仪观测信号:
SendBuffer[0]=0x60;
SendBuffer[1]=0x05;
SendBuffer[2]=0x35;
Status = XIicPs_MasterSendPolled(&Iic, SendBuffer,3, 0x64>>1);//写操作
Status = XIicPs_MasterSendPolled(&Iic, SendBuffer,2, 0x64>>1); //读操作
Status = XIicPs_MasterRecvPolled(&Iic, RecvBuffer+3,1, 0x64>>1); //读操作