您的位置:首页 > 其它

详解内核驱动操作GPIO引脚API函数(1)

2012-08-01 13:11 411 查看
函数原型:

void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function);

unsigned int s3c2410_gpio_getcfg(unsigned int pin);

void s3c2410_gpio_pullup(unsigned int pin, unsigned int to);

void s3c2410_gpio_setpin(unsigned int pin, unsigned int to);

unsigned int s3c2410_gpio_getpin(unsigned int pin);

unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change);

int s3c2410_gpio_getirq(unsigned int pin);

关于函数中用到的虚拟地址到物理地址转换的变量及算法可以参考

http://blog.163.com/hefeng330467115@126/blog/static/782058422010620511659/

http://blog.chinaunix.net/u3/102836/showart_2065945.html

看简单led驱动程序是用到的文件及头文件可能有:

linux/include/asm-arm/arch-s3c2410/map.h

linux/include/asm-arm/arch-s3c2410/regs-gpio.h

linux/arch/arm/plat-s3c24xx/gpio.c

linux/include/asm-arm/io.h

用Source Insight 打开这些文件,然后再看驱动程序,可以随意跳转到定义处,很是方便

pin参数:

gpio引脚及特殊功能寄存器助记符都在linux/include/asm-arm/arch-s3c2410/regs-gpio.h中定义:

eg:

S3C2410_GPACON

S3C2410_GPADAT

S3C2410_GPA0 - S3C2410_GPA22 //引脚

S3C2410_GPA0_OUT - S3C2410_GPA22_OUT //设置引脚为输出

用到哪个不清楚的可以直接到这个文件去查找

还有中断和GSTATUS:

S3C2410_EXTINT0 -> irq sense control for EINT0..EINT7

S3C2410_EXTINT1 -> irq sense control for EINT8..EINT15

S3C2410_EXTINT2 -> irq sense control for EINT16..EINT23

……

function参数:

指定引脚功能:输出、输入还是特殊功能,也在linux/include/asm-arm/arch-s3c2410/regs-gpio.h中定义。

函数功能:

1 原型:void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function);

作用:配置GPIO引脚功能,即是配置相应的CON位

eg:

s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPB0_OUTP);//设置B5脚为输出功能

函数原代码及注释:

(这个函数注释的比较详细,后面类似的不再重复注释)

void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)

{

void __iomem *base = S3C24XX_GPIO_BASE(pin);

//取引脚基地址即是:GPA0、GPB0 …… 的虚拟基地址

unsigned long mask;

unsigned long con;

unsigned long flags;

if (pin < S3C2410_GPIO_BANKB) {

mask = 1 << S3C2410_GPIO_OFFSET(pin);

//用于查找对应的引脚位(端口A一位控制一个引脚)

} else {

mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;

//除端口A外其他端口都是两位控制一个引脚

}

//根据function值具体确定怎么来调整function

switch (function) {

case S3C2410_GPIO_LEAVE:

mask = 0;

function = 0;

break;

case S3C2410_GPIO_INPUT:

case S3C2410_GPIO_OUTPUT:

case S3C2410_GPIO_SFN2:

case S3C2410_GPIO_SFN3:

if (pin < S3C2410_GPIO_BANKB)

{ // 当某位被设为0时,相应引脚为输出,此时可

function -= 1; //以在GPADAT中相应位写入1或0;当某位被

function &= 1; //设为1时,相应引脚为地址线或用于地址控制。

function <<= S3C2410_GPIO_OFFSET(pin); //偏移量即是相应的引脚位

} else {

function &= 3;

function <<= S3C2410_GPIO_OFFSET(pin)*2; //除A端口以外的其他端口都是

} //两位控制一个引脚

}

/* modify the specified register wwith IRQs off */

local_irq_save(flags); //调用该宏函数来保存IRQ 中断使能状态,并禁止IRQ 中断

con = __raw_readl(base + 0x00);

// 基地址加偏移量得到相应端口的控制寄存器(GPxCON)地址,然后读取该寄存器的值

con &= ~mask; // 找到需要修改的引脚的控制位

con |= function; // 使对应的引脚的功能为function

__raw_writel(con, base + 0x00); // 重写控制寄存器的值,实现引脚功能修改

local_irq_restore(flags); //恢复IRQ 和FIQ 的中断使能状态

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  GPIO