软件版本:Anlogic -TD5.9.1-DR1_ES1.1
操作系统:WIN10 64bit
硬件平台:适用安路(Anlogic)FPGA
实验平台:米联客-MLK-L1-CZ06-DR1M90G开发板
板卡获取平台:https://milianke.tmall.com/
登录“米联客”FPGA社区 http://www.uisrc.com 视频课程、答疑解惑!
目录
1 概述
2 系统框图
3 AXI-GPIO IP概述
3.1 特性
3.2 寄存器空间
4 硬件电路分析
5 搭建SOC系统工程
5.1 SOC系统工程
1:中断设置
2:设置GP Master接口
3:设置复位输出
4:AXI-GPIO
5.2设置AXI外设地址分配
5.3 编译并导出平台文件
6 搭建SDK工程
6.1 创建Platform工程
6.2 创建APP工程
7 程序分析
7.1 axi_gpio_test.c测试程序
8 方案演示
8.1 硬件准备
8.2 实验结果
8.3 实验结果
1 概述
本文介绍TD自带IP AXI-GPIO扩展PS IO的使用。我们在前面的文章中通过GPIO PL实现过扩展PS的IO,通过GPIO PL的方式实际上IO控制器还是用PS的。那么AXI-GPIO更多是使用FPGA资源实现的IO的扩展。并且很多应用中,我们会把AXI-GPIO的控制信号用于FPGA内部逻辑和PS之间的数据交互,比如通过AXI-GPIO输出复位信号,或者通过AXI-GPIO的输入中断,扩展出更多中断。
在本文的demo中,我们将实现通过AXI-GPIO扩展2个IO实现按键输入,并且通过按键输入产生2个GPIO中断。
本文实验目的:
1:熟悉AXI-GPIO的硬件资源
2:通过TD搭建AXI-GPIO的SOC工程,通过按键模拟输入
3:使用FD编写AXI-GPIO测试程序,完成GPIO输入、输入中断
2 系统框图
3 AXI-GPIO IP概述
AXI GPIO IP 旨在为 AXI-Lite 接口提供通用输入/输出接口(GPIO),并且可以将设备配置为单通道或双通道,每个通道的宽度是可以独立配置。AXI GPIO IP 的整体原理架构图如图所示
- AX14-Lite 接口模块
该模块实现了一个 32 位的 AXI4-Lite slave接口,用于访问 GPIO 通道寄存器
- 中断控制模块
该模块从 GPIO 通道获取中断状态,并对主机产生中断。当定制IP 时选择“Enable Interrupt”时,该模块将被启用。
- GPIO控制模块
该模块由寄存器和多路复用器组成,用于读写 AXI GPIO通道寄存器。它还包括必要的逻辑,以便在通道输入发生变化时监测并识别。
- 三态缓冲
本IP已在顶层加入了三态缓冲逻辑,当 IP 选择 GPIO既有输入端口,又有输出端口时,将根据 GPIO的三态选择信号自行对 GPIO的端口进行输入或输出的选择。
3.1 特性
- 支持 AXI4-Lite 接口规范
- 支持可配置的单或双 GPIO 通道
- 支持从1到 32 位的 GPIO 引脚的可配置通道宽度
- 支持每个 GPIO 位作为输入或输出的动态编程支持每个通道的单独配置
- 支持所有寄存器的每个位的独立复位值
- 支持可选的中断请求生成
3.2 寄存器空间
AXI GPIO IP 的寄存器配置包括 GPIO 数据寄存器、GPIO 三态寄存器和中断寄存器组成。下表列出了 AXI GPIO寄存器及其地址信息。
Address Space | Register Name | Access Type | DefaultValue | Description |
0x0000 | GPIO DATA | R/W | 0x0 | GPIO 数据寄存器 |
0x0004 | GPIO TRI | R/W | 0x0 | GPIO 三态控制寄存器 |
0x0008 | GPIO2 DATA | R/W | 0x0 | GPIO2 数据寄存器 |
0x000C | GPIO2 TRI | R/W | 0x0 | GPIO2 三态控制寄存器 |
0x0100 | IP IER | R/W | 0x0 | IP 通道中断使能寄存器 |
0x0104 | IP ISR | R/TOW | 0x0 | IP 中断状态寄存器 |
- 中断寄存器只有在启用中断参数时才可用。
- TOW(Toggle-On-Write)访问是指当一个值为1的数据被写入相应的位时,该位的状态被转换。
- 地址空间偏移量是相对于 BASEADDR 赋值。
- 写访问寄存器由 32 位的 AXI 写数据(* wdata)信号更新,且不受字节使能(* wstrb)信号的影响。
4 硬件电路分析
硬件接口和子卡模块请阅读“附录1”
配套工程的FPGA PIN脚定义路径为/soc_prj/uisrc/04_pin
5 搭建SOC系统工程
详细的搭建过程这里不再重复,对于初学读者如果还不清楚如何创建SOC工程的,请学习“01Vitis Soc开发入门”这篇文章。
5.1 SOC系统工程
1:中断设置
2:设置GP Master接口
3:设置复位输出
4:AXI-GPIO
位宽设置为1bit,使能中断
5.2设置AXI外设地址分配
从本节课开始,只要添加的AXI总线外设都要正确分配地址
5.3 编译并导出平台文件
以下步骤简写,有不清楚的看第1篇《01 Soc开发入门》文章。
导出完成后,对应工程路径的soc_hw路径下有硬件平台文件:fpga_prj.hpf的文件。根据硬件平台文件fpga_prj.hpf来创建需要Platform平台。
6 搭建SDK工程
创建soc_base platform和APP工程的过程不再重复,如果不清楚请参考本章节第1个demo。
6.1 创建Platform工程
6.2 创建APP工程
7 程序分析
7.1 axi_gpio_test.c测试程序
/*
* Copyright (c) 2023, Anlogic Inc. and Contributors. All rights reserved.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include <math.h>
#include <time.h>
#include "al_core.h"
#include <stdlib.h>
#include "ui_io.h"
#include "ui_type.h"
#define AXI_GPIO0_DATA_REG (0X80000000 + 0)
#define AXI_GPIO0_TRI_REG (0X80000000 + 4)
#define AXI_GPIO0_IER_REG (0X80000000 + 0x100)
#define AXI_GPIO0_SER_REG (0X80000000 + 0x104)
#define AXI_GPIO1_DATA_REG (0X80100000 + 0)
#define AXI_GPIO1_TRI_REG (0X80100000 + 4)
#define AXI_GPIO1_IER_REG (0X80100000 + 0x100)
#define AXI_GPIO1_SER_REG (0X80100000 + 0x104)
#define PL_IRQ_NUM0 114
#define PL_IRQ_NUM1 115
//pl interrupt call_back function
int gpio0_intr_func_handle(void) {
printf("btn0 intr_func_handle\r\n");
UI_Out32(AXI_GPIO0_SER_REG,0x01);//set gpio input
return 0;
}
int gpio1_intr_func_handle(void) {
printf("btn1 intr_func_handle\r\n");
UI_Out32(AXI_GPIO1_SER_REG,0x01);//set gpio input
return 0;
}
int main()
{
u32 btn_val;
printf("AXI GPIO TEST!\r\n");
printf("PL interrupt TEST!\r\n");
UI_Out32(AXI_GPIO0_TRI_REG,0x01);//set gpio input
UI_Out32(AXI_GPIO0_IER_REG,0x01);//set gpio channel1 interrupt enable
UI_Out32(AXI_GPIO1_TRI_REG,0x01);//set gpio input
UI_Out32(AXI_GPIO1_IER_REG,0x01);//set gpio channel1 interrupt enable
AL_INTR_AttrStrct *IntrAttr_PL_INTER0 = malloc(sizeof(AL_INTR_AttrStrct));
IntrAttr_PL_INTER0->TrigMode = POSTIVE_EDGE_TRIGGER;// set interrupt as edge trigger
IntrAttr_PL_INTER0->Priority = 137,
AlIntr_RegHandler(PL_IRQ_NUM0, IntrAttr_PL_INTER0, gpio0_intr_func_handle, NULL);
AL_INTR_AttrStrct *IntrAttr_PL_INTER1 = malloc(sizeof(AL_INTR_AttrStrct));
IntrAttr_PL_INTER1->TrigMode = POSTIVE_EDGE_TRIGGER;// set interrupt as edge trigger
IntrAttr_PL_INTER1->Priority = 137,
AlIntr_RegHandler(PL_IRQ_NUM1, IntrAttr_PL_INTER1, gpio1_intr_func_handle, NULL);
AlIntr_SetLocalInterrupt(1); // enable local interrupt
while(1)
{
}
return 0;
}
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部分。
8.3 实验结果
每次按下按键产生一个中断,每次松开按键也会产生一个中断。总之,只要按键的状态发生改变就会产生中断。