您的位置 首页 系统

Linux头文件中s3c2410 GPIO的宏

一、GPIO寄存器定义1.#defineGPCON(x)__REG2(0x56000000,(x)*0x10)这句是定义2410的GPIO的控制寄存器,注意:__REG2的参数是寄…

一、GPIO寄存器界说

1.#define GPCON(x) __REG2(0x56000000, (x) * 0x10)

这句是界说2410的GPIO的操控寄存器,留意:__REG2的参数是寄存器的物理地址,这个物理地址经_REG2转换为虚拟地址,对照2410的手册能够得到一下对应联系:

GPCON(1) ------ PORT A 0x56000000
GPCON(2) ------ PORT B 0x56000010
GPCON(3) ------ PORT C 0x56000020
……
GPCON(8) ------ PORT H 0x56000070

2.#define GPDAT(x) __REG2(0x56000004, (x) * 0x10)

这句是界说2410的GPIO的数据寄存器,界说办法同GPCON宏。

GPDAT(1) ------ PORT A 0x56000004
GPDAT(2) ------ PORT B 0x56000014
GPDAT(3) ------ PORT C 0x56000024
……
GPDAT(8) ------ PORT H 0x56000074

3.#define GPUP(x) __REG2(0x56000008, (x) * 0x10)

这句是界说2410的GPIO的上拉电阻屏蔽/激活寄存器,界说办法同GPCON宏。
GPUP(1) ------ PORT A 0x56000008
GPUP(2) ------ PORT B 0x56000018
GPUP(3) ------ PORT C 0x56000028
……
GPUP(8) ------ PORT H 0x56000078

二、GPIO端口号界说
以GPIO_G12来阐明在内核头文件$(KERNEL_INCLUDE)/asm-arm/arch/s3c2410.h中是如何来界说IO port的端口号的。界说GPIO端口首要涉及到以下几个宏:

#define MAKE_GPIO_NUM(p, o) ( (p << GPIO_PORT_SHIFTT) | (o << GPIO_OFS_SHIFT))
#define GPIO_G12 MAKE_GPIO_NUM(PORTG_OFS, 12)

GPIO_PORT_SHIFTT值为8,代表GPIO组号在整个GPIO端口号(如GPIO_G12)字段中的位移
GPIO_OFS_SHIFT值为0,代表GPIO组内偏移号在整个GPIO端口号(如GPIO_G12)字段中的位移

s3c2410有117个多功用input/output port pins。分为以下八组:

— Port A (GPA): 23-output port #define PORTA_OFS 0
— Port B (GPB): 11-input/output port #define PORTB_OFS 1
— Port C (GPC): 16-input/output port#define PORTC_OFS 2
— Port D (GPD): 16-input/output port#define PORTD_OFS 3
— Port E (GPE): 16-input/output port#define PORTE_OFS 4
— Port F (GPF): 8-input/output port#define PORTF_OFS 5
— Port G (GPG): 16-input/output port#define PORTG_OFS 6
— Port H (GPH): 11-input/output port#define PORTH_OFS 7

GPG12归于G组,组内偏移为12,从上述两个宏界说中,咱们能够很清楚地看出GPIO_G12结构:

图1 GPIO端口号结构图
端口一共有8组,从上面的宏界说能够看出,端口组号p的规模:0~7。而组内偏移各组不尽相同,Port A有23个输出口,因而它的组内偏移o为0~22,Port G有16个IO口,它的组内偏移o为0~15,其他组的GPIO以此类推。

三、write_gpio_bit(x,v)宏剖析
write_gpio_bit宏传入两个参数,第一个为GPIO端口号,如GPIO_G12;第二个参数为1或0,为相应IO口设置高电平或低电平输出。详细宏打开如下:

代码
  1. #definewrite_gpio_bit(x,v)
  2. ({
  3. GPDAT(GRAB_PORT((x)))&=~(0x1<
  4. GPDAT(GRAB_PORT((x)))|=((v)<
  5. })

GRAB_PORT宏的参数是GPIO端口号,功用是从GPIO端口号中解分出组号,详细界说如下:

#define GRAB_PORT(x) (((x) & GPIO_PORT_MASK) >> GPIO_PORT_SHIFTT)

其间GPIO_PORT_MASK是组号的掩码,值为0x0000ff00,从图1中也可看出。

GRAB_OFS宏和GRAB_PORT相似,它的功用是从GPIO端口号中解分出组内偏移:

#define GRAB_OFS(x) (((x) & GPIO_OFS_MASK) >> GPIO_OFS_SHIFT)

其间偏移值掩码GPIO_OFS_MASK=0x000000ff。

现在咱们结合上述阐明来剖析write_gpio_bit(GPIO_G12,1)这条句子:由GPIO_G12的宏界说可计算出其值为0x0000060C,GRAB_PORT(GPIO_G12)解析得到所操作的IO归于G组,组号为6;GRAB_OFS(GPIO_G12)解析得到此IO口为G组的第12个引脚(从0开端算起),为GPG12,表达式值为12。则write_gpio_bit(GPIO_G12,1)等价于下面两条句子:

GPDAT(6) &= ~(0x1<<12); //GPGDAT寄存器第12位清零
GPDAT(6) | = 1<<12; // 向GPGDAT寄存器第12位写入‘1’

到此,咱们知道了write_gpio_bit(GPIO_G12,1)这条句子是将GPG12这个引脚拉成高电平。

四、set_gpio_ctrl(x)宏剖析完成了对write_gpio_bit宏的剖析,现在来看set_gpio_ctrl就很简略了!在它的宏打开中只多了GRAB_MODE(x)和 GRAB_PULLUP(x)别离表明从参数x中解分出IO口的形式和使能/屏蔽此端口的上拉电阻。值得留意的是set_gpio_ctrl的参数x不仅仅表明GPIO端口号,其高16位还带有形式状况和上拉电阻操控信息,参数x的结构如下图:

图2 set_gpio_ctrl的参数字段结构图
低16位即为前面所述的GPIO的端口号,高16位中的R字段用来屏蔽/使能IO口的上拉电阻功用。R=0,上拉电阻使能;R=1,上拉电阻失效。M字段用来设置IO口的作业形式,M=0,IO口为输入端口;M=1,IO口为输出端口;M=2,可选功用1;M=3,可选功用2。

set_gpio_ctrl宏便是经过写相应GPIO地点组的GPXCON(X为A~H)的相应位来设置IO口形式(GPACON每一个位操控一个IO口,而GPBCON~GPHCON都是两个位操控一个IO口的形式),经过写GPXUP(X为A~H)来决议是否启用上拉电阻。典型的set_gpio_ctrl调用办法如下:

set_gpio_ctrl(GPIO_MODE_OUT | GPIO_PULLUP_DIS | GPIO_G12);

代码
  1. #defineset_gpio_ctrl(x)
  2. ({GPCON(GRAB_PORT((x)))&=~(0x3<<(GRAB_OFS((x))*2));
  3. GPCON(GRAB_PORT(x))|=(GRAB_MODE(x)<<(GRAB_OFS((x))*2));
  4. GPUP(GRAB_PORT((x)))&=~(1<
  5. GPUP(GRAB_PORT((x)))|=(GRAB_PULLUP((x))<

这条句子是将GPG12设置成输出形式,而且不运用端口的上拉电阻。

五、完毕
以上首要结合《S3C2410X 32-BIT RISC M%&&&&&%ROPROCESSOR USERS MANUAL》剖析了$(LINUX_KERNEL_INCLUDE)/asm-arm/arch/s3c2410.h中所界说的对2410GPIO进行操作的几个宏,除了文中提及的几个宏,除此还有read_gpio_bit(x)、read_gpio_reg(x) 、write_gpio_reg(x, v)等,完成办法和上述相似,在此不再逐个赘述!

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qianrushi/xitong/274798.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部