zynq7000系列PS端GPIO初始化函数XGpioPs_LookupConfig()和XGpioPs_CfgInitialize()详解

前言
   xilinx公司在设计这款芯片时就同步编写了ps端的函数库,我们在对zynq这款芯片进行开发,直接调用库函数就可以了。不过比较难过的是,官方虽然编写了函数驱动库,但并没有出版相应的类似于函数指导之类的文档,需要开发者自己去理解这个函数用法,但官方还是有相应的历程,我们可以学历历程来基本掌握这些函数的用法,但并不是很详细,也没有说明文档,需要结合datasheet和其他的文档进行综合理解分析。
首先
gpio有两个重要的数据结构:XGpioPs 和 XGpioPs_Config

typedef struct {
	XGpioPs_Config GpioConfig;	/**< Device configuration */
	u32 IsReady;			/**< Device is initialized and ready */
	XGpioPs_Handler Handler;	/**< Status handlers for all banks */
	void *CallBackRef; 		/**< Callback ref for bank handlers */
	u32 Platform;			/**< Platform data */
	u32 MaxPinNum;			/**< Max pins in the GPIO device */
	u8 MaxBanks;			/**< Max banks in a GPIO device */
} XGpioPs;

typedef struct {
	u16 DeviceId;		/**< Unique ID of device */
	u32 BaseAddr;		/**< Register base address */
} XGpioPs_Config;

XGpioPs 结构体里面各个成员变量的大致作用:
  1:GpioConfig 是XGpioPs_Config结构体的指针,指向内部成员DeviceId和BaseAddr;这两个成员作用是保存gpio这个设备的Id和基地址,在zynq中任何外设都有一个相应的id和基地址用来识别。
  解析一下为什么我们在所有历程中或者别人的工程中看到的id都是0,它只是被用来初始化,表示这个设备在vivado搭建工程环境时我们勾选了这个设备,没有勾选的设备你是在#include "xparameters_ps.h"中找不到相应的id和地址的。
  2:IsReady,当设备初始化完成,设备已经准备好
  3:Handler ,中断句柄,用于中断读取和写入
  4:CallBackRef 中断回调函数,没有用到中断时可不做关心
  5:Platform 这个是跟你的开发板硬件平台相关,不做关心
  6:MaxPinNum ps端能使用的最大的pin数量,在zynq中为118
  7:MaxBanks 在zynq中的io bank数目为4

1:查询函数XGpioPs_LookupConfig()

XGpioPs_Config *XGpioPs_LookupConfig(u16 DeviceId)
{
	XGpioPs_Config *CfgPtr = NULL;
	u32 Index;
	for (Index = 0U; Index < (u32)XPAR_XGPIOPS_NUM_INSTANCES; Index++) {
		if (XGpioPs_ConfigTable[Index].DeviceId == DeviceId) {
			CfgPtr = &XGpioPs_ConfigTable[Index];
			break;
		}
	}
	return (XGpioPs_Config *)CfgPtr;
}

参数:设备id,我们可以在#include "xparameters_ps.h"找到id和地址

/* Definitions for peripheral PS7_GPIO_0 */
#define XPAR_PS7_GPIO_0_DEVICE_ID 0
#define XPAR_PS7_GPIO_0_BASEADDR 0xE000A000
#define XPAR_PS7_GPIO_0_HIGHADDR 0xE000AFFF

每一个设备都有一个唯一的配置表:

XGpioPs_Config XGpioPs_ConfigTable[XPAR_XGPIOPS_NUM_INSTANCES] =
{
	{
		XPAR_PS7_GPIO_0_DEVICE_ID,
		XPAR_PS7_GPIO_0_BASEADDR
	}
};

XGpioPs_LookupConfig这个函数就是根据设备id,查找配置表,然后将设备的地址等信息,通过XGpioPs_Config 指针返回。

2:初始化函数XGpioPs_CfgInitialize()

s32 XGpioPs_CfgInitialize(XGpioPs *InstancePtr, XGpioPs_Config *ConfigPtr,
				u32 EffectiveAddr)
{
	s32 Status = XST_SUCCESS;
	u8 i;
	Xil_AssertNonvoid(InstancePtr != NULL);
	Xil_AssertNonvoid(ConfigPtr != NULL);
	Xil_AssertNonvoid(EffectiveAddr != (u32)0);
	/*
	 * Set some default values for instance data, don't indicate the device
	 * is ready to use until everything has been initialized successfully.
	 */
	InstancePtr->IsReady = 0U;
	InstancePtr->GpioConfig.BaseAddr = EffectiveAddr;
	InstancePtr->GpioConfig.DeviceId = ConfigPtr->DeviceId;
	InstancePtr->Handler = StubHandler;
	InstancePtr->Platform = XGetPlatform_Info();

	/* Initialize the Bank data based on platform */
	if (InstancePtr->Platform == XPLAT_ZYNQ_ULTRA_MP) {
		/*
		 *	Max pins in the ZynqMP GPIO device
		 *	0 - 25,  Bank 0
		 *	26 - 51, Bank 1
		 *	52 - 77, Bank 2
		 *	78 - 109, Bank 3
		 *	110 - 141, Bank 4
		 *	142 - 173, Bank 5
		 */
		InstancePtr->MaxPinNum = (u32)174;
		InstancePtr->MaxBanks = (u8)6;
	} else {
		/*
		 *	Max pins in the GPIO device
		 *	0 - 31,  Bank 0
		 *	32 - 53, Bank 1
		 *	54 - 85, Bank 2
		 *	86 - 117, Bank 3
		 */
		InstancePtr->MaxPinNum = (u32)118;
		InstancePtr->MaxBanks = (u8)4;
	}

	/*
	 * By default, interrupts are not masked in GPIO. Disable
	 * interrupts for all pins in all the 4 banks.
	 */
	for (i=0;i<InstancePtr->MaxBanks;i++) {
		XGpioPs_WriteReg(InstancePtr->GpioConfig.BaseAddr,
					  ((u32)(i) * XGPIOPS_REG_MASK_OFFSET) +
					  XGPIOPS_INTDIS_OFFSET, 0xFFFFFFFFU);
	}

	/* Indicate the component is now ready to use. */
	InstancePtr->IsReady = XIL_COMPONENT_IS_READY;

	return Status;
}

  参数1:XGpioPs 结构体指针
  参数2:指向XGpioPs_Config 设备指针
  参数3:指向设备基地址
**函数功能:**设置一些初始默认值,如:设置io的最大值和bank数,默认关闭中断等等。

使用

	static XGpioPs   psGpioInstancePtr;
	XGpioPs_Config*  GpioConfigPtr;
	int xStatus;
	
    GpioConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);
	if(GpioConfigPtr == NULL)
		return XST_FAILURE;
		
	xStatus = XGpioPs_CfgInitialize(&psGpioInstancePtr,GpioConfigPtr, GpioConfigPtr->BaseAddr);
	if(XST_SUCCESS != xStatus)
		print(" PS GPIO INIT FAILED \n\r");
  • 4
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
Zynq7000 AP SoC 是一款由赛灵思(Xilinx)公司生产的可编程逻辑器件,集成了一个双核ARM Cortex-A9处理器和FPGA(现场可编程门阵列)芯片。IEEE 1588 PTP(精确时间协议)是一种网络通讯协议,主要用于将网络中的设备同步到全局的统一时间。 在 Zynq7000 AP SoC 上设计和实现 IEEE 1588 PTP 功能可以提供高精度和高稳定性的时间同步。这样的设计可以在工业自动化、电力系统、通信设备等领域中得到广泛的应用。 首先,需要在 Zynq7000 AP SoC 上配置和调试 PTP协议堆栈。这可以通过在芯片内嵌入适当的协议软件来实现。然后,需要配置网络接口以支持 IEEE 1588 PTP 协议的数据传输。这可以通过使用以太网接口,并调整其参数来实现。 随后,我们需要将 PTP 时钟模块与芯片的时钟系统集成在一起。PTP时钟模块是实现 IEEE 1588 PTP 功能的关键组件,它可以提供高精度的时钟信号。我们需要将该模块与芯片的时钟源相连,以确保时间同步的准确性。 最后,还需要进行软件编程以实现 IEEE 1588 PTP 的相关功能,例如时间戳的生成和比较、同步精度控制等。这可以通过编写适当的驱动程序和应用软件来实现。 总结来说,将 IEEE 1588 PTP 设计集成到 Zynq7000 AP SoC 中需要配置和调试协议堆栈、网络接口以及时钟模块,并进行软件编程以实现相关功能。这样的设计可以为各种应用场景提供高精度和可靠的时间同步。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值