最近看驱动,不少地方涉及到GPIO,查找了很多资料,讲解的云里雾里的,剪来贴去的,丫的,不爽,于是决心想把它搞懂,看了不少资料,总算有点自己的认识,拿来跟大家分享一下。
S3C2410的GPIO有117pin:
--PortA(GPA):23--output port
--PortB(GPB):11--input/output port
--PortC(GPC):16--input/output port
--PortD(GPD):16--input/output port
--PortE(GPE):16--input/output port
--PortF(GPF):8--input/output port
--PortG(GPG):16--input/output port
--PortH(GPH):11--input/output port
( 其实我也不想把一些现成的直接拿来一大堆贴上,看着心烦,呵呵,有点古人掉书袋的感觉,没有办法呵,要不说来是在麻烦,大家就将就着吧)
注意:每一组端口最多只有23个,如果使用32位数据统计端口应该绰绰有余。
首先是pin的一些相关宏定义:
#define S3C2410_GPIONO(bank,offset) ((bank) + (offset))
#define S3C2410_GPIO_BANKA (32*0)
#define S3C2410_GPIO_BANKB (32*1)
#define S3C2410_GPIO_BANKC (32*2)
....
#define S3C2410_GPB0 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 0)
#define S3C2410_GPB1 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 1)
也就是说,可以从宏能直接推算出其端口值,比方S3C2410_GPF5,其端口值为(32*5+5)
#define S3C2410_GPB0_INP (0x00 << 0)
#define S3C2410_GPB0_OUTP (0x01 << 0)
#define S3C2410_GPB0_TOUT0 (0x02 << 0)
#define S3C2410_GPB1_INP (0x00 << 2)
#define S3C2410_GPB1_OUTP (0x01 << 2)
#define S3C2410_GPB1_TOUT1 (0x02 << 2)
....
从PORT B--PORT H 寄存器操作方面完全相同,即:GPxCON中每两位控制一根引脚:00表示输入、01表示输出、10表示特殊功能、11保留不用。上述六个宏即是定义GPB 的两个引脚。
GPIO寄存器物理地址:
在S3C2410中I/O端口的物理地址范围是0x56000000--0x560000B0,其中比较关键的是起始地址0x56000000,GPIO寄存器的物理地址便是基于这个起始地址。
在寄存器配置方面,每组寄存器包括四个。比如说GPA,其中包括GPACON、GPADAT、GPAUP、RESERVED四个寄存器。每一个寄存器占有32位(4字节),所以相邻GPA与GPB地址相差0x10,以此类推。
GPACON 0x56000000--0x56000003 GPBCON 0x56000010--0x56000013
GPADAT 0x56000004--0x56000007 GPBDAT 0x56000014--0x56000017
GPAUP 0x56000008--0x5600000B GPBUP 0x56000018--0x5600001B
RESERVED 0x5600000C--0x5600000F RESERVED 0x5600001C--0x5600001F
很显然, 由此便可以得到以下寄存器起始地址:
GPxCON 0x56000000+(x)*0x10
GPxDAT 0x56000004+(x)*0x10
GPxUP 0x56000008+(x)*0x10
RESERVED 0x5600000C+(x)*0x10
在Linux中会使用一下类似宏来定义寄存器地址:
#define S3C2410_GPBCON S3C2410_GPIOREG(0x10)
#define S3C2410_GPBDAT S3C2410_GPIOREG(0x14)
#define S3C2410_GPBUP S3C2410_GPIOREG(0x18)
原理还是一样的。
、