软件版本:Anlogic -TD5.9.1-DR1_ES1.1 操作系统:WIN10 64bit 硬件平台:适用安路(Anlogic)FPGA 实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板 1 概述本课对FPSoC芯片GPIO进行介绍,通过点亮PS LED和PL LED以及读取PL按键输入值,来控制LED灯闪烁,演示GPIO PS和GPIO PL的使用方法。 本文实验目的: 1:熟悉FPSoC PS部分PSIO的内部结构、相关寄存器 2:掌握FPSoC IP核中如何分配GPIO 3:掌握FD中如何使用PSIO 2系统框图PSIO一般会分配到固定的外设,包括FLASH、EMMC、TFCARD、UART、USB2.0、ETH以太网。GPIO也可以单独配置成普通的PSIO,如果IO不够用也可以通过PLIO扩展更多IO。 3 GPIO介绍3.1功能描述GPIO(General Purpose I/O Ports),通用输入/输出端口。 DR1 器件含有通用I/O(GPI0)外设通过PS IO 模块为软件提供多达54个设备引脚的观察和控制。它还通过PL IO 接口提供对来自可编程逻辑(PL)的64 个输入和PL 的128 个输出的访问。GPI0 被组织成四组寄存器,对相关接口信号进行分组。每个GPI0 作为输入、输出或中断传感是独立和动态编程。软件可以使用单个加载指令读取bank 内的所有GPI0 值,或者使用单个存储指令将数据写入一个或多个GPIO(在GPIO 的范围内)。 软件将 GPIO配置为输出或输入。无论 GPIO设置为输入(OE 信号 false)还是输出(OE 信号true),数据寄存器始终返回GPIO引脚的状态。为了生成输出波形,软件会重复写入一个或多个 GPIO。 3.2 GPIO特性1、设备引脚的 54 GPI0 信号(通过PS 10 多路复用器布线) 2、PS 和PL 之间通过PL 10 接口的192 个GPIO 信号(64 输入+64输出+64输出使能) - 64 个输入,128 个输出(64 个真实输出和64 个输出使能)
3、每个GPIO的功能可单独或成组动态编程 4、支持位或列数据方式对 GP10 进行写入、输出使能和方向控制 5、基于单个 GPIO 的可编程中断 - 支持初始和屏蔽中断的状态读取
- 支持中断可选灵敏度:电平敏感(高或低)或边缘敏感(正或负)
6、配置为 GPIO 的时候,默认状态是输入上拉 3.3 关键寄存器名称 | | | | GPIO SWPORTA DR BLK0-3 GPIO SWPORTA DDR BLK0-3 GPIO SWPORTA DR CLR BLK0-3 GPIO SWPORTA DDR CLR BLK0-3 | 控制 GPIO 的输入/输出,清除输入/输出的数据。 | | GPIO INTEN CLR BLK0-3 GPIO INTMASK CLR BLK0-3 GPIO INTTYPE LEVEL CLR BLK0-3 GPIO INT POLARITY_CLR_BLK0-3 GPIO INT BOTHEDGE CLR BLKO-3 | 中断使能、中断 mask、中断清除,中断响应极性设置。 | | GPIO DEBOUNCE CLR BLK0-3 GPIO DEBOUNCE BLK0-3 | |
4硬件电路分析硬件接口和子卡模块请阅读"附录1" 配套工程的FPGA PIN脚定义路径为soc_prj/uisrc/04_pin/ fpga_pin.adc 5搭建SOC系统工程详细的搭建过程这里不再重复,对于初学读者如果还不清楚如何创建SOC工程的,请学习"01Vitis Soc开发入门"这篇文章。 本文中的PS设置内容是新增加的GPIO PS以及GPIO PL部分,关于DDR、PSIO、CPU时钟等设置请参考"01Vitis Soc开发入门"这篇文章。 5.1GPIO配置01Vitis Soc开发入门"这篇文章中已经对特定功能的PSIO做了设置,只有剩余的PSIO可以用于其他的自定义功能。以下设置未分配功能的PSIO,以及需要扩展的GPIO PL IO的数量。 5.2GPIO PL定义设置好后,右击选择Create Design Port 设置IO名称、IO类型、IO位宽 最终GPIO PL需要定义到FPGA的IO中,所以我们需要引出GPIO PL信号到system_top顶层文件 - module system_top (
- output PL_LED,
- input PL_KEY
- );
- wire [1:0] pl_gpio_in;
- wire [1:0] pl_gpio_out;
- assign PL_LED = pl_gpio_out[0];
- assign pl_gpio_in[1] = PL_KEY;
- system I_system (
- .pl_gpio_in (pl_gpio_in),
- .pl_gpio_out(pl_gpio_out)
- );
- endmodule
复制代码 5.3编译并导出平台文件以下步骤简写,有不清楚的看第1篇《01 Soc开发入门》文章。 导出完成后,对应工程路径的soc_hw路径下有硬件平台文件:fpga_prj.hpf的文件。根据硬件平台文件fpga_prj.hpf来创建需要Platform平台。 6 搭建SDK工程创建soc_base sdk platform和APP工程的过程不再重复,如果不清楚请参考本章节第一个demo。 6.1创建Platform工程创建soc_base sdk platform和APP工程的过程不再重复,如果不清楚请参考本章节第一个demo《01 Soc开发入门》文章。
6.2创建gpio_ctl_led APP工程 7程序分析Gpio_ctl_led.c - #include "al_gpio_hal.h"
- #define PS_LED 51 //PS GPIO 51
- #define PL_LED 54 //PL GPIO 01
- #define PS_KEY 50 //PS GPIO 50
- #define PL_KEY 55 //PL GPIO 02
- #define LED_IN_BANK0 0x80000
- #define LED_IN_BANK2 0x1
- #define AL_GPIO_DEVICE_ID 0
- #define AL_GPIO_DELAY_20MS 20
- #define AL_GPIO_DELAY_2000MS 2000
- AL_S32 AlGpio_Hal_Ctl_LED_Example()
- {
- AL_GPIO_HalStruct *GPIO;
- AL_S32 PS_LedValue = 0;
- AL_S32 PL_LedValue = 0;
- AL_S32 PS_KeyValue = 0;
- AL_S32 PL_KeyValue = 0;
- /* 1、Test AlGpio_Hal_Init */
- AL_S32 ret = AlGpio_Hal_Init(&GPIO, AL_GPIO_DEVICE_ID, AL_NULL);
- if (ret == AL_OK) {
- AL_LOG(AL_LOG_LEVEL_INFO, "[TEST] APU AlGpio_Hal_Init success");
- }
- else {
- AL_LOG(AL_LOG_LEVEL_INFO, "[TEST] APU AlGpio_Hal_Init failed");
- }
- /* 2、Test Gpio function through Bank. */
- AlGpio_Hal_WriteBank(GPIO, AL_GPIO_BANK1, LED_IN_BANK0);
- AlGpio_Hal_WriteBank(GPIO, AL_GPIO_BANK2, LED_IN_BANK2);
- AlSys_MDelay(AL_GPIO_DELAY_2000MS);
- AlGpio_Hal_WriteBank(GPIO, AL_GPIO_BANK1, 0x0);
- AlGpio_Hal_WriteBank(GPIO, AL_GPIO_BANK2, 0x0);
- AlSys_MDelay(AL_GPIO_DELAY_2000MS);
- /* 3、Test Gpio polling */
- PS_LedValue = AlGpio_Hal_ReadPinOutput(GPIO, PS_LED);
- AL_LOG(AL_LOG_LEVEL_INFO, "GPIO PS led value is 0x%x", PS_LedValue);
- PL_LedValue = AlGpio_Hal_ReadPinOutput(GPIO, PL_LED);
- AL_LOG(AL_LOG_LEVEL_INFO, "GPIO PL led value is 0x%x", PL_LedValue);
- while(1)
- {
- PS_KeyValue = AlGpio_Hal_ReadPinInput(GPIO, PS_KEY);
- PL_KeyValue = AlGpio_Hal_ReadPinInput(GPIO, PL_KEY);
- if(PS_KeyValue == 0|PL_KeyValue == 0){
- AlSys_MDelay(AL_GPIO_DELAY_20MS);
- if (PS_KeyValue == 0|PL_KeyValue == 0) {
- AlGpio_Hal_WritePin(GPIO, PS_LED, ~PS_LedValue);
- AlGpio_Hal_WritePin(GPIO, PL_LED, ~PL_LedValue);
- AlSys_MDelay(AL_GPIO_DELAY_20MS);
- AlGpio_Hal_WritePin(GPIO, PS_LED, PS_LedValue);
- AlGpio_Hal_WritePin(GPIO, PL_LED, PL_LedValue);
- AlSys_MDelay(AL_GPIO_DELAY_20MS);
- }
- }
- }
- return AL_OK;
- }
- AL_S32 main(void) {
- AL_LOG(AL_LOG_LEVEL_INFO, "[TEST]AlGpio_Hal_CTL_LED_Test start");
- AlGpio_Hal_Ctl_LED_Example();
- return AL_OK;
- }
复制代码接下来对程序进行分析。 7.1GPIO位号定义
- #define PS_LED 51 //PS GPIO 51
- #define PL_LED 54 //PL GPIO 01
- #define PS_KEY 50 //PS GPIO 50
- #define PL_KEY 55 //PL GPIO 02
复制代码
PS GPIO比较好确认,主要是根据原理图确认好PSIO编号即可。GPIO PL扩展的GPIO需要根据绑定的FPGA PIN来划分,GPIO PL [0]位对应的位号为54,是Bank 2中的第1位。其他的以此类推。 7.2GPIO操控方法程序中使用了2种方式演示操控GPIO,依次分析: 方法1:直接操控对应Bank寄存器,下列程序分别对Bank1以及Bank2直接进行写数据。由原理图可知PS LED为PSIO51,Bank0的最大位号为31,所以Bank1的第1个位号为32。以此类推,PSIO51对应的是在对应的地址为0x80000,正好对应第20位。PL IO由此推断为Bank2的第1位,对应的地址为0x1。该程序完成了点亮PS_LED、PL_LED持续2000MS之后再熄灭功能。 反应到开发板上状态为,PL_LED以及PS_LED先点亮200MS后熄灭。 - /* 2、Test Gpio function through Bank. */
- AlGpio_Hal_WriteBank(GPIO, AL_GPIO_BANK1, LED_IN_BANK0);
- AlGpio_Hal_WriteBank(GPIO, AL_GPIO_BANK2, LED_IN_BANK2);
- AlSys_MDelay(AL_GPIO_DELAY_2000MS);
- AlGpio_Hal_WriteBank(GPIO, AL_GPIO_BANK1, 0x0);
- AlGpio_Hal_WriteBank(GPIO, AL_GPIO_BANK2, 0x0);
- AlSys_MDelay(AL_GPIO_DELAY_2000MS);
复制代码方法2:通过位号控制,先通过AlGpio_Hal_ReadPinOutput函数通过位号读取了PL_LED以及PS_LED的状态。然后持续读取PS_KEY、PL_KEY的状态,当发现PS_KeyValue == 0|PL_KeyValue == 0时,也就是PL KEY或者PS KEY任意哪个按键按下时,将PL_LED以及PS_LED以20MS为周期持续取反。 反应到开发板上状态为,当任意对应按键KEY按下时,PL_LED以及PS_LED持续闪烁。 - /* 3、Test Gpio polling */
- PS_LedValue = AlGpio_Hal_ReadPinOutput(GPIO, PS_LED);
- AL_LOG(AL_LOG_LEVEL_INFO, "GPIO PS led value is 0x%x", PS_LedValue);
- PL_LedValue = AlGpio_Hal_ReadPinOutput(GPIO, PL_LED);
- AL_LOG(AL_LOG_LEVEL_INFO, "GPIO PL led value is 0x%x", PL_LedValue);
- while(1)
- {
- PS_KeyValue = AlGpio_Hal_ReadPinInput(GPIO, PS_KEY);
- PL_KeyValue = AlGpio_Hal_ReadPinInput(GPIO, PL_KEY);
- if(PS_KeyValue == 0|PL_KeyValue == 0){
- AlSys_MDelay(AL_GPIO_DELAY_20MS);
- if (PS_KeyValue == 0|PL_KeyValue == 0) {
- AlGpio_Hal_WritePin(GPIO, PS_LED, ~PS_LedValue);
- AlGpio_Hal_WritePin(GPIO, PL_LED, ~PL_LedValue);
- AlSys_MDelay(AL_GPIO_DELAY_20MS);
- AlGpio_Hal_WritePin(GPIO, PS_LED, PS_LedValue);
- AlGpio_Hal_WritePin(GPIO, PL_LED, PL_LedValue);
- AlSys_MDelay(AL_GPIO_DELAY_20MS);
- }
- }
- }
复制代码 8方案演示
8.1硬件准备本实验需要用到JTAG下载器、USB转串口外设,另外需要把SW1模式开关设置到JTAG模式 8.2实验结果由于添加了PL端按键资源,所以Debug时需要将TD生成的soc_prj/soc_prj_Runs/best_result/soc_prj.bit文件同时添加进来,在debug前会先下载PL端资源后启动SOC部分。 IO输出功能,可看到底板上的PS LED以及PL LED先亮起,后熄灭。 IO输入功能,可以通过按动KEY2或KEY4,观察到PS LED以及PL LED以20MS周期闪烁。 串口观察到读取的PS LED以及PL LED的状态。
|