曲径通幽论坛

标题: S3C2410 write_gpio_bit(x,v) 宏在 linux 中的解析 [打印本页]

作者: beyes    时间: 2009-11-1 22:32
标题: S3C2410 write_gpio_bit(x,v) 宏在 linux 中的解析
write_gpio_bit(x,v)宏的作用是为相应的 IO口设置高电平或者低电平输出。它有两个参数,一个是 x ,另一个是 v 。x 表示 GPIO 端口号(包含端口所在寄存器组和组内偏移信息,具体分析见:http://www.groad.net/bbs/read.php?tid-1324.html) ;v的值为 1或为 0 。

write_gpio_bit(x, y) 具体定义为
#define write_gpio_bit(x, v)
   ({
           GPDAT(GRAB_PORT((x))) &= ~(0x1 << GRAB_OFS((x)));
           GPDAT(GRAB_PORT((x))) |= ((v) << GRAB_OFS((x)));
   })

其中,GRAB_PORT(x) 的参数是 GPIO 端口号,它的功能是从端口号中解析出组号,宏的具体定义如下:
#define GRAB_PORT(x)            (((x) & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT)
上面,GPIO_PORT_MASK 的定义为
#define GPIO_PORT_MASK          0x0000ff00

GPIO_PORT_SHIFT 的定义为
#define GPIO_PORT_SHIFTT        8

以端口号 GPIO_C8 为例来展开这个宏,GPIO_C8 最后会形成这么一个形式-->  (2 << 8 | 8 << 0) :
((x) & GPIO_PORT_MASK) --->   ( (2<<8 | 8 << 0) & 0x0000ff00)   --->   0x00000200
然后,
0x00000200 >>  GPIO_PORT_SHIFT ---> 0x00000200 >> 8  ---> 0x2
由上可见,组号 2 被解析了出来。

GRAB_OFS(x) 的作用是从端口号中解析出组内偏移量,宏的具体定义如下
#define GRAB_OFS(x)             (((x) & GPIO_OFS_MASK) >> GPIO_OFS_SHIFT)
其中, GPIO_OFS_MASK 和 GPIO_OFS_SHIFT 的定义分别为
#define GPIO_OFS_MASK           0x000000ff
#define GPIO_OFS_SHIFT          0
以端口号 GPIO_C8 为例展开这个宏:
((x) & GPIO_OFS_MASK  --->  ( ( 2<<8 | 8 << 0) & 0x000000ff ) --->  0x8
然后,
0x8 >> GPIO_OFS_SHIFT  --->  0x8 >> 0  ---> 0x8
所以,组内偏移量 8 也被解析了出来。

所以,GPDAT(GRAB_PORT((x))) &= ~(0x1 << GRAB_OFS((x))); 就相当于:
GPDAT(2) &= ~(0x01 << 8)
其意是,将 GPCDAT 数据寄存器里的第 8 位清 0 。

那么同样分析 GPDAT(GRAB_PORT((x))) |= ((v) << GRAB_OFS((x)));  这个宏,最后将 GPCDAT 寄存器的第 8 位置 1 。所以,到此 GPC8 这根引脚拉成高电平。




欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) Powered by Discuz! X3.2