原理图
PS_LED连接在MIO9上,ZYNQ的GPIO中,BANK0和BANK1通过MIO连接在PS端,BANK2和BANK3通过EMIO连接在PL端。
GPIO寄存器
由上图可知,ZYNQ GPIO寄存器的基地址是 0xE000A000。
上图中为GPIO的相关寄存器,为了控制PS_LED,只需关注上图中红色框里的几个特定寄存器即可。
DATA寄存器
DATA寄存器就是控制管脚输出高低电平的,所以在输出模式下,就可以通过对寄存器的相应 bit位写 0或 1来控制某个 GPIO输出电平为高还是低。
DIRM寄存器
方向控制寄存器控制GPIO的输入和输出。
OUTEN寄存器
GPIO时钟
APER_CLK_CTRL寄存器属于系统级别的控制寄存器。
该寄存器用于控制ZYNQ AMBA外设时钟,从图中可以知道该寄存器的 bit22位 GPIO时钟控制位,向该位写入 0禁止 GPIO时钟,写入 1则使能 GPIO时钟。
驱动编写
/** ===================================================== **
*Author : ALINX Electronic Technology (Shanghai) Co., Ltd.
*Website: http://www.alinx.com
*Address: Room 202, building 18,
No.518 xinbrick Road,
Songjiang District, Shanghai
*Created: 2020-3-2
*Version: 1.0
** ===================================================== **/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/fs.h>
#include <linux/init.h>
#include <linux/ide.h>
#include <linux/types.h>
/* 驱动名称 */
#define DEVICE_NAME "gpio_leds"
/* 驱动主设备号 */
#define GPIO_LED_MAJOR 200
/* gpio寄存器虚拟地址 */
static unsigned int gpio_add_minor;
/* gpio寄存器物理基地址 */
#define GPIO_BASE 0xE000A000
/* gpio寄存器所占空间大小 */
#define GPIO_SIZE 0x1000
/* gpio方向寄存器 */
#define GPIO_DIRM_0 (unsigned int *)(0xE000A204 - GPIO_BASE + gpio_add_minor)
/* gpio使能寄存器 */
#define GPIO_OEN_0 (unsigned int *)(0xE000A208 - GPIO_BASE + gpio_add_minor)
/* gpio控制寄存器 */
#