Zynq-PS-SDK(1) 之 MIO 使用

目录

1、MIO 配置以及寄存器

2、工程中的配置

3、使用 MIO-GPIO

3.1、GPIO 硬件描述

3.2、GPIO 寄存器描述

3.2.1、MASK_0_LSW、MASK_0_MSW

3.2.2、Data_0

3.2.3、Data_0_RO

3.2.4、DIRECTION_0

3.2.5、OP_ENABLE_0

3.2.6、INT_

3.3、代码


 

1、MIO 配置以及寄存器

Zynq 7020 的 PS 端(ARM 端)的外设 IO(也叫 IOP)分为 MIO 和 EMIO,他们有什么区别呢?

首先他们都是 PS 端的 IO 资源,MIO 有 54 个 Pin 脚,分为两个 Bank(Bank0、Bank1)是 PS 直接的管脚连接,可以接诸如 UART、SPI、IIC、GPIO 等具体的外设引脚;

EMIO 也是 PS 的资源,它接到了 PL 端,由 PL 端输出信号;

这里,我们可以简单的理解为,MIO 是可以通过 Pinmux 配置而直接连接到 PS 端外设的管脚,而 EMIO 是连接到 PL 端用于扩展的引脚;

外设的 MIO/EMIO 的链接如下所示:

这里,我们暂时只关心 MIO(后续看 EMIO),MIO 分为了两个 Bank(Bank0、Bank1),这两个 Bank 分别叫做 Bank 500 和 Bank 501,他们可以配置为不同的电压等级

注意,这个是电压等级的 Bank,与后面的 GPIO bank 作区分;

Bank 500:MIO[15:0]

Bank 501:MIO[16:53]

提供 54 个 MIO 资源;

根据管脚复用的配置以及外设相关的资源,整个可实现的配置如下所示

MIO 的管脚复用配置逻辑如下所示:

每一路的 MIO(从 MIO[0] ~ MIO[53])都有一个这样的逐级配置,L3 的 MUX 结果可以作为 L2 MUX 的输入......最后配置出来成为最后的管脚;

举个例子,直接看寄存器;

MIO 配置的寄存器位于系统控制寄存器 slcr

在 slcr 中:

很多类似这样的寄存器:slcr.MIO_PIN_[PIN_MUN] 其中的 PIN_MUN 就是每个 MIO 的编号,从 0 到 53,一共 54 个;

每一个的寄存器内容大致一样,我们随便抓一个看:MIO_PIN_00:

可以看到,每个 MIO 都可以配置是否上拉,电平标准(同一个 Bank 500 或者 Bank 501 电平标准必须一致),还有就是 Level 0 ~ Level 3 的 MUX,这个就是对应的上面那个 4 级 MUX 图的;

DisableRcvr:HSTL 的配置,是 High Speed Transceiver Logic 的简写,这个域是配置 MIO 的 HSTL 的;

PULLUP:配置 Piin 脚是否带上拉;

IO TYPE:配置 IO 的电平标准;

Speed:配置速度;

L3_SEL:配置管脚复用 L3 逻辑,参考管脚复用的 MIO Signal Routing 那个图;

L2_SEL:配置管脚复用 L2 逻辑,参考管脚复用的 MIO Signal Routing 那个图;

L1_SEL:配置管脚复用 L1 逻辑,参考管脚复用的 MIO Signal Routing 那个图;

L0_SEL:配置管脚复用 L0 逻辑,参考管脚复用的 MIO Signal Routing 那个图;

TRI_ENABLE:用于配置 MIO 是否三态;

注意:这个是 slcr 寄存器的配置,关于所有 slcr 寄存器的配置,都需要往 slcr.SLCR_UNLOCK 寄存器(0xF8000008)写入 0xDF0D,来解锁 slcr 寄存器的写权限;

2、工程中的配置

具体工程中,我们使用 Vivado 进行配置,首先创建 Block Design 来生成一个 PS:

双击这个大的 ZYNQ 图标,进入配置界面:

选择红色部分,并配置每个 IO 的管脚复用,并选择好他的电平标准(绿色);

配置时钟,板载 33.333333 MHZ,使用 6:2:1 时钟比例(参考  ZYNQ 时钟子系统

配置完毕,并导出硬件,Launch SDK;

 

3、使用 MIO-GPIO

硬件原理图中 PS 端的 LED 连接如下:

分别使用了 MIO0_LED 和 MIO13_LED,都属于 Bank 500(V3.3),此刻,我们如果想点个灯,那么需要将其配置为输出,并置 0 即可导通;

3.1、GPIO 硬件描述

UG585 的 Chapter 14 就是 PS 的 GPIO 的使用说明(这里包含了 MIO 和 EMIO,这一章,我们看 MIO)

它支持 MIO 和 EMIO 的配置,MIO 分为 2 个 IO Bank (0~1),EMIO 也分为 2 个 IO Bank(2~3):

GPIO 支持中断输入和正常的写和读:INT 开头的,是中断配置:

针对每一个pin,它都有如下寄存器:

注意:如果 MIO 的 TRI_ENABLE 这个被设置为 1,那么输出就为 3 态了;

3.2、GPIO 寄存器描述

每个 GPIO Bank 提供了一组寄存器用来描述他的行为,一共 4组,我们以 GPIO Bank 0 为例:

GPIO Bank 0 一共有 32bits 根信号;

3.2.1、MASK_0_LSW、MASK_0_MSW

Zynq 针对 GPIO 的操作,增加了一组方式,以避免对 32bit 寄存器进行读改写的操作,它的方式是将(以 GPIO Bank0 为例)的 32bit 的信号(对应 32 个 IO)分为两组,每组代表 16 bits 的 IO 信号,用两个寄存器描述:

高 16 位使用叫 MASK_0_MSW 的寄存器描述:低位 16 位使用叫 MASK_0_LSW 的寄存器描述:

他们分别有两个域,一个 Mask 域,一个 Data 域,Zynq 使用 MASK + DATA 的方式,来避免对 GPIO 寄存器的读改写;用法是:

往 Mask 中写入 1 的位置,不会被对应的 Data 中的写入改变;换句话来说,16 bit 信号中,可以选择哪些信号被 Mask,Mask 中被写入了 1 的信号,即便是 在 Data 域写入任何值, GPIO 的电平状态都不会被改变;举个栗子:

往 MIO[0] 写 1,那么就可以配置寄存器 MASK_0_LSW 寄存器的值为:0xFFF70001;

意思是,除了 MIO GPIO0 以外的其他的 1~15 都被 Mask,你往里面写什么,都无效;

 

3.2.2、Data_0

当然,你也可以使用读改写的方式来对 IO 进行配置,直接配置 Data_0 寄存器就可以(以 GPIO Bank0 为例):

 

3.2.3、Data_0_RO

当然,也可以读 GPIO 的电平值,通过直接读取 Data_0_RO 寄存器(以 GPIO Bank0 为例):

 

3.2.4、DIRECTION_0

GPIO 呢,当然要配置它的方向,即,输入还是输出(以 GPIO Bank0 为例):

 

3.2.5、OP_ENABLE_0

如果 GPIO 配置为输出了后,要真的输出信号,要配置这个输出使能寄存器(以 GPIO Bank0 为例):

 

3.2.6、INT_

这个是 IO 输入中断相关的配置以后用到中断在仔细介绍;

 

3.3、代码

Xilinx SDK 关于 GPIO 的操作,有专门的 API 接口(其实就是按照前面的寄存器配置逻辑来配置),按照具体的硬件原理图的 LED(MIO_0 和 MIO_13),代码如下:

XGpioPs Gpio;
#define STEPH_MIO_0			0
#define STEPH_MIO_1			13

#define MIO_OUTPUT			1
#define MIO_INPUT			0

#define MIO_OUTPUT_EN		1
#define MIO_OUTPUT_DIS		0

uint32_t Steph_LEDInit(void)
{
	XGpioPs_Config *ConfigPtr = NULL;
	int Status = XST_SUCCESS;

	ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
	if(!ConfigPtr)
	{
		xil_printf("XGpioPs_LookupConfig Error.\r\n");
		return XST_FAILURE;
	}

	Status = XGpioPs_CfgInitialize(&Gpio, ConfigPtr,
						ConfigPtr->BaseAddr);

	if (Status != XST_SUCCESS) {
		xil_printf("XGpioPs_CfgInitialize Error.\r\n");
		return XST_FAILURE;
	}

	XGpioPs_SetDirectionPin(&Gpio, STEPH_MIO_0, MIO_OUTPUT);
	XGpioPs_SetDirectionPin(&Gpio, STEPH_MIO_1, MIO_OUTPUT);
	XGpioPs_SetOutputEnablePin(&Gpio, STEPH_MIO_0, MIO_OUTPUT_EN);
	XGpioPs_SetOutputEnablePin(&Gpio, STEPH_MIO_1, MIO_OUTPUT_EN);
	xil_printf("Steph_LED Initialize Finished...\r\n");

	return Status;
}

void LED_ON(uint32_t led_pin)
{
	XGpioPs_WritePin(&Gpio, led_pin, 0x0);
}

void LED_OFF(uint32_t led_pin)
{
	XGpioPs_WritePin(&Gpio, led_pin, 0x1);
}

相关代码和工程在 gitee 持续更新:

https://gitee.com/stephenzhou-tech/Zynq7020_PS

  • 10
    点赞
  • 55
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Zynq-7000是由Xilinx公司生产的一款集成了ARM处理器和可编程逻辑(PL)的片上系统(SoC)。它的可编程逻辑部分可以通过重新配置(Reconfigure)来进行定制和优化。 Zynq-7000的可编程逻辑部分由一系列可编程逻辑单元(PLU)组成,可以通过Vivado开发环境进行配置和定制。重配置PL意味着可以改变PL中的逻辑电路,以满足不同的需求。 重配置PL的过程大致分为三个步骤。首先,需要使用Vivado开发环境创建和配置逻辑电路。这可以通过使用硬件描述语言(如Verilog或VHDL)来实现,也可以通过使用硬件抽象层次语言(如C、C++或OpenCL)来实现。 其次,需要将配置好的逻辑电路编译成比特流(Bitstream)。比特流是一种描述逻辑电路的中间文件,可以被FPGA芯片理解和加载。 最后,将生成的比特流加载到Zynq-7000的可编程逻辑部分。这可以通过JTAG接口或SD卡等方式实现。一旦比特流被加载,Zynq-7000的可编程逻辑部分就被重新配置为新的逻辑电路。 通过重配置PL,可以实现许多应用场景,例如加速计算、优化算法、嵌入式系统的定制等。它提供了一种便捷的方式来优化和个性化Zynq-7000的使用。 总的来说,Zynq-7000的可编程逻辑部分可以通过Vivado开发环境进行重新配置,以满足不同的需求。这种重配置的过程包括创建和配置逻辑电路、生成比特流、加载比特流到Zynq-7000,并可以应用于各种应用场景。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值