u-boot版本:2018.01版
作者:YFW
博客:https://blog.csdn.net/u012577474/article/details/102799363
当前分析基于cpu: F1C100S (全志)
下面代码位于: arch/arm/include/asm/arch-sunxi/gpio.h
#define SUNXI_GPIO_L 11
#define SUNXI_GPIO_M 12
#define SUNXI_GPIO_N 13
#define GPIO_BANK(pin) ((pin) >> 5) @F1C100S一共6组IO(GPA-GPF),每组IO bank sizes 设置等于32 ,所以右移5位是除以32得到当前操作哪一组寄存器
#define GPIO_NUM(pin) ((pin) & 0x1f) @得到具体操作哪个IO引脚
#define BANK_TO_GPIO(bank) (((bank) < SUNXI_GPIO_L) ? \ //GPIO组数小于11,执行下面这句。
&((struct sunxi_gpio_reg *)SUNXI_PIO_BASE)->gpio_bank[bank] : \ //根据当前bank号(gpio组号),获取当前这组gpio寄存器的首地址
&((struct sunxi_gpio_reg *)SUNXI_R_PIO_BASE)->gpio_bank[(bank) - SUNXI_GPIO_L])
//为了方便定义每个组的大小都为32
/* GPIO bank sizes */
#define SUNXI_GPIO_A_NR 32
#define SUNXI_GPIO_B_NR 32
#define SUNXI_GPIO_C_NR 32
#define SUNXI_GPIO_D_NR 32
#define SUNXI_GPIO_E_NR 32
#define SUNXI_GPIO_F_NR 32
#define SUNXI_GPIO_G_NR 32
#define SUNXI_GPIO_H_NR 32
#define SUNXI_GPIO_I_NR 32
#define SUNXI_GPIO_L_NR 32
#define SUNXI_GPIO_M_NR 32
//每一组gpio寄存器结构体
struct sunxi_gpio {
u32 cfg[4]; //f1c100s的每个gpio有5个配置寄存器
u32 dat; //f1c100s的每个gpio有1个数据寄存器
u32 drv[2]; //f1c100s的每个gpio有3个drv寄存器
u32 pull[2]; //f1c100s的每个gpio有3个上拉寄存器
};
//所有组GPIO寄存器结构体(创建一个sunxi_gpio结构体数组),寻址用
struct sunxi_gpio_reg {
struct sunxi_gpio gpio_bank[SUNXI_GPIO_BANKS];
u8 res[0xbc];
struct sunxi_gpio_int gpio_int;
};
下面代码位于:drivers/gpio/sunxi_gpio.c
//设置IO输出状态
// pin 表示gpio索引号,第x组的第y个gpio的索引为x*32+y
//
static int sunxi_gpio_output(u32 pin, u32 val)
{
u32 dat;
u32 bank = GPIO_BANK(pin);
u32 num = GPIO_NUM(pin);
struct sunxi_gpio *pio = BANK_TO_GPIO(bank); //通过组号索引得到该gpio的多个寄存器的首地址(并且创建了sunxi_gpio 结构体指向该组gipo的连续多个寄存器地址)
dat = readl(&pio->dat); //直接操作前面创建的sunxi_gpio 结构体,读取gpio_data寄存器的值
if (val) //设置该引脚的电平
dat |= 0x1 << num;
else
dat &= ~(0x1 << num);
writel(dat, &pio->dat); //写回到gpio_data寄存器,实现IO输出
return 0;
}