GPIO

        Zynq GPIO 被称为 MIO,是 Multiplexed I/O 的缩写,译为多路复用 I/O。一般 MIO 指Zynq PS 端的用户管脚,而 PL 端的用户管脚属于扩展的 MIO,因此也被称为 EMIO(Extendable Multiplexed I/O)。

        从下图可以看到,Zynq PS 端的 MIO 管脚由 MIO Multiplexer 模块控制,PL 端的用户管脚需要通过 EMIO 接口访问。

【ZYNQ】GPIO 与 AXI GPIO-LMLPHP

        Zynq GPIO 以 Bank 的形式组织,其中 MIO 位于 Bank 0 和 Bank1,共有 54 个;EMIO 则位于 Bank2 和 Bank3,共有 64 个。

【ZYNQ】GPIO 与 AXI GPIO-LMLPHP

        Zynq 每个 GPIO 的功能都可以单个或以 Bank 为单位进行动态编程,并由软件通过一系列内存映射寄存器进行控制。GPIO 可以通过读写相关寄存器进行访问,也可以使用高层次的方式,即使用结构体与函数读写 GPIO。

        下图是 xgpiops.h 头文件关于 XGpioPs_Config 和 XGpioPs 结构体的定义。

【ZYNQ】GPIO 与 AXI GPIO-LMLPHP

XGpioPs API

【ZYNQ】GPIO 与 AXI GPIO-LMLPHP

#include "xparameters.h"
#include "xgpiops.h"

#define  GPIO_0          0
#define  GPIO_DEVICE_ID  XPAR_XGPIOPS_0_DEVICE_ID

void XGpioPs_Init(XGpioPs *GpioInstance, u32 deviceID) {
	// XGpioPs_Config object definition
	XGpioPs_Config *ConfigPtr;
	ConfigPtr = XGpioPs_LookupConfig(deviceID);
	XGpioPs_CfgInitialize(GpioInstance, ConfigPtr, ConfigPtr->BaseAddr);

	// Gpio initialization
	XGpioPs_SetDirectionPin(GpioInstance, GPIO_0, 1);
	XGpioPs_SetOutputEnablePin(GpioInstance, GPIO_0, 1);
	XGpioPs_WritePin(GpioInstance, GPIO_0, 0);
}

int main(void) {
    XGpioPs Gpio;
    XGpioPs_Init(&Gpio, GPIO_DEVICE_ID);

    // Todo
    return -1;
}

AXI GPIO

        AXI GPIO 是 Xilinx 提供的 GPIO IP,使用 AXI 接口通信,需要消耗一部分 PL 逻辑资源。

【ZYNQ】GPIO 与 AXI GPIO-LMLPHP

从下图可以看到,AXI GPIO 包含两个 GPIO 通道,每个通道最多 32 个 GPIO。

【ZYNQ】GPIO 与 AXI GPIO-LMLPHP

使用 AXI GPIO 时,需要 include 对应的头文件 xgpio.h,下图是 xgpio.h 中关于 XGpio_Config 和 XGpio 结构体的定义。

【ZYNQ】GPIO 与 AXI GPIO-LMLPHP

XGpio API

【ZYNQ】GPIO 与 AXI GPIO-LMLPHP

        XGpio_Initialize() 函数调用了 XGpio_LookupConfig() 和 XGpio_CfgInitialize() 这两个函数实现 GPIO 初始化,因此用户初始化只需要调用 XGpio_Initialize() 函数即可。

#include "xparameters.h"
#include "xgpio.h"

#define  GPIO_0          0x01
#define  GPIO_CHANNEL    1
#define  GPIO_DEVICE_ID  XPAR_GPIO_0_DEVICE_ID

int XGpio_Init(XGpio *GpioInstance, u16 DeviceId) {
	int Status;

	/* Initialize the GPIO driver */
	Status = XGpio_Initialize(GpioInstance, DeviceId);
	if (Status != XST_SUCCESS) {
		return XST_FAILURE;
	}

	/* Set the direction for all signals as inputs except the GPIO_0 output */
	XGpio_SetDataDirection(GpioInstance, GPIO_CHANNEL, ~GPIO_0);

	return XST_SUCCESS;
}
05-24 23:19