Linux下s3c6410的GPIO操作(6)

发布者:cxx7848653最新更新时间:2022-06-09 来源: eefocus关键字:Linux  s3c6410  GPIO操作 手机看文章 扫描二维码
随时随地手机看文章

1、在  Linux下s3c6410的GPIO操作(3) 这篇博客中少分析了一个函数,当时列出了源码,但没分析,现在补上。


什么函数呢?如下所示:


#ifdef CONFIG_S3C_GPIO_CFG_S3C64XX


/**

 * s3c_gpio_setcfg_s3c64xx_4bit - S3C64XX 4bit single register GPIO config.

 * @chip: The gpio chip that is being configured.

 * @off: The offset for the GPIO being configured.

 * @cfg: The configuration value to set.

 *

 * This helper deal with the GPIO cases where the control register has 4 bits

 * of control per GPIO, generally in the form of:

 * 0000 = Input

 * 0001 = Output

 * others = Special functions (dependant on bank)

int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,

unsigned int off, unsigned int cfg)

{

void __iomem *reg = chip->base;


得到GPIO端口控制寄存器的基地址,不同的端口可能不同哦!如下所示:


(第一种)、


static struct s3c_gpio_chip gpio_4bit[] = {

{

.base =S3C64XX_GPA_BASE,

.config  = &gpio_4bit_cfg_eint0111,

.chip = {

.base = S3C64XX_GPA(0),

.ngpio  = S3C64XX_GPIO_A_NR,

.label  = "GPA",

}


(第二种)


static struct s3c_gpio_chip gpio_4bit2[] = {

{

.base =S3C64XX_GPH_BASE + 0x4,

.config  = &gpio_4bit_cfg_eint0111,

.chip = {

.base = S3C64XX_GPH(0),

.ngpio  = S3C64XX_GPIO_H_NR,

.label  = "GPH",

}


(第三种)、


static struct s3c_gpio_chip gpio_2bit[] = {

{

.base = S3C64XX_GPF_BASE,

.config  = &gpio_2bit_cfg_eint11,

.chip = {

.base = S3C64XX_GPF(0),

.ngpio  = S3C64XX_GPIO_F_NR,

.label  = "GPF",

}


既然端口分三种,那么对应的操作函数也应该分为三种,但实际上分成了两种,按控制寄存器的控制位数分为4和2.


这两种操作函数分别是s3c_gpio_setcfg_s3c64xx_4bit函数和s3c_gpio_setcfg_s3c24xx函数。



unsigned int shift = (off & 7) * 4;

u32 con;



if (off < 8 && chip->chip.ngpio > 8)

reg -= 4;


这个判断是为4-2这种情况准备的,因为上面的基地址是第二个控制寄存器的基地址,所以要减去4得到第一个控制寄存器的基地址。可以这样进行判断,一个很重要的原因就是下面这个表,观察一下,是否发现4Bit类型的都没有超过8个。所以我才说这个是针对4-2这种情况的。


/* GPIO bank summary:

 *

 * Bank GPIOs  Style SlpCon  ExtInt Group

 * A 8  4Bit Yes  1

 * B 7  4Bit Yes  1

 * C 8  4Bit Yes  2

 * D 5  4Bit Yes  3

 * E 5  4Bit Yes  None

 * F 16  2Bit Yes  4 [1]

 * G 7  4Bit Yes  5

 * H 10  4Bit[2] Yes  6

 * I 16  2Bit Yes  None

 * J 12  2Bit Yes  None

 * K 16  4Bit[2] No  None

 * L 15  4Bit[2] No None

 * M 6  4Bit No  IRQ_EINT

 * N 16  2Bit No  IRQ_EINT

 * O 16  2Bit Yes  7

 * P 15  2Bit Yes  8

 * Q 9  2Bit Yes  9

 *

 * [1] BANKF pins 14,15 do not form part of the external interrupt sources

 * [2] BANK has two control registers, GPxCON0 and GPxCON1

 */



if (s3c_gpio_is_cfg_special(cfg)) {

cfg &= 0xf;

cfg <<= shift;

}


#define s3c_gpio_is_cfg_special(_cfg)

(((_cfg) & S3C_GPIO_SPECIAL_MARK) == S3C_GPIO_SPECIAL_MARK)


#define S3C_GPIO_SPECIAL_MARK(0xfffffff0)


主要目的是为了判断传入的 unsigned int cfg这个参数,这个参数的之可以为0xfffffffx,其中x有下表所示:

当然,也可以传入的参数直接为上表中的数值,看开头的注释,就可以明白了。


con = __raw_readl(reg);

con &= ~(0xf << shift);

con |= cfg;

__raw_writel(con, reg);

这一部分很简单,无非就是读后,再写。


return 0;

}


注:如果大家对上面的shift的处理不是很明白,可以举个实际例子。如9的时候,unsigned int shift = (off & 7) * 4;的shift为1,别忘了现在是对第二个控制寄存器操作,0-7是第一个寄存器,8以后是第二个寄存器,那9就是第二个控制寄存器的第二个控制段,也就是第二个4位,这么说应该明白了吧。

#endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */


2、


上面说的是两个函数中的其中一个,现在来说第二个,s3c_gpio_setcfg_s3c24xx,源码如下:


/**

 * s3c_gpio_setcfg_s3c24xx - S3C24XX style GPIO configuration.

 * @chip: The gpio chip that is being configured.

 * @off: The offset for the GPIO being configured.

 * @cfg: The configuration value to set.

 *

 * This helper deal with the GPIO cases where the control register

 * has two bits of configuration per gpio, which have the following

 * functions:

 * 00 = input

 * 01 = output

 * 1x = special function

*/




int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,

   unsigned int off, unsigned int cfg)

{

void __iomem *reg = chip->base;

unsigned int shift = off * 2;

u32 con;



if (s3c_gpio_is_cfg_special(cfg)) {

cfg &= 0xf;

if (cfg > 3)

return -EINVAL;



cfg <<= shift;

}



con = __raw_readl(reg);

con &= ~(0x3 << shift);

con |= cfg;

__raw_writel(con, reg);



return 0;

}


和上面那个函数一样,而且还相对简单,就不分析了。

关键字:Linux  s3c6410  GPIO操作 引用地址:Linux下s3c6410的GPIO操作(6)

上一篇:Linux下s3c6410的GPIO操作(7)
下一篇:Linux下s3c6410的GPIO操作(5)

推荐阅读最新更新时间:2024-11-13 13:10

基于内核对象的Linux输入子系统触摸屏的驱动设计
随着人们对操控要求的不断提高,电容触摸屏因为能支持多点触摸而得到广泛使用。本文基于Nokia和Intel公司合作开发的开源操作系统MeeGo,采用基于内核对象的Linux输入子系统来设计触摸屏的驱动。该方案极大地方便了触摸屏的驱动开发,可应用在车载娱乐、上网本、智能手机等电子产品上。 随着人们对操控要求的不断提高,市场上出现了越来越多的高端手机、平板电脑,这些产品共同的特点就是给人们提供了非常便利的操控方式,尤其是电容触摸屏的使用,它能很好地实现多点触控功能。多点触控技术是当今炙手可热的技术,它让人们的生活方式得到了前所未有的改变。电容触摸屏已经成为高端手机的标配,如苹果的iPhone以及HTC Motorola的一些高端
[单片机]
基于内核对象的<font color='red'>Linux</font>输入子系统触摸屏的驱动设计
【ARM】移植linux kernel2.6.32注意事项
#三个文件 程老师(1209050967) 19:05:41 链接:http://pan.baidu.com/s/1pLg8V8J 密码:xu5r 程老师(1209050967) 19:06:03 程老师(1209050967) 19:06:31 各位到我网盘把这个三个文件下下来放到你们的ubuntu里面 (gcc4.4.3, linux-2.6.32, roots_rtm_2440) 加sudo 解压后才有/rootfs/dev/console这个文件 sudo tar –zxvf root… /rootfs/dev/console #arm-linux-gcc –v export PATH=$PATH:/home/wu
[单片机]
【ARM】移植<font color='red'>linux</font> kernel2.6.32注意事项
Linux之ARM(IMX6U)裸机主频和时钟配置
I.MX6U 系列标准的工作频率为 528MHz,有些型号甚至可以工作到 696MHz,但是默认的工作频率为396MHz,这就造成了浪费了,本次我们来配置主频时钟使其工作在528MHz,以及其他的外设时钟源都工作在NXP推荐的工作频率。 1、I.MX6U 时钟系统详解 I.MX6U 的系统主频为 528MHz,有些型号可以跑到 696MHz,但是默认情况下内部 boot rom 会将 I.MX6U 的主频设置为 396MHz。我们在使用 I.MX6U的时候肯定是要发挥它的最大性能,那么主频肯定要设置到 528MHz(其它型号可以设置更高,比如 696MHz),其它的外设时钟也要设置到 NXP 推荐的值。可参考NXP官方参考手册
[单片机]
<font color='red'>Linux</font>之ARM(IMX6U)裸机主频和时钟配置
linux 端口IO操作
linux对于端口IO使用遵循分配,映射与使用 struct resource *request_mem_region(unsigned long start,unsigned long len,char *name); 申请失败返回NULL,否则非零。 void release_mem_region(unsigned long start,unsigned long len); 释放。 void *ioremap(unsigned long phys_addr,unsigned long size); void iounmap(void *addr); 映射与反操作。 unsigned int ioread8(void *add
[单片机]
基于嵌入式Linux平台的指纹门禁系统
简介:本文基于嵌入式Linux平台的指纹门禁系统,该系统基于ARM9芯片Samsung S3C2440AL,以Veridicom公司指纹采集芯片FPS200作为硬件平台,以嵌入式Linux为软件平台。在该研究领域中,基于PC平台的识别系统一直是研究的重点,本文实现的基于ARM平台的系统具有轻便,易安装,成本低的优点,具有良好的发展前景。 指纹门禁系统是基于生物特征识别技术的一项高科技安全设施,近年来在国内外得到了广泛的应用,并已成为现代化建筑智能化的标志之一。对于一些核心机密部门,如重要机关、科研实验室、档案馆、民航机场等场所,指纹门禁系统可以提供高效、智能、便捷的授权控制。由于指纹具有携带方便、人人各异、终生不变的特点,因此
[单片机]
基于嵌入式<font color='red'>Linux</font>平台的指纹门禁系统
ARM11 S3C6410 的地址表
参考:1)《ARM1176 JZF-S Technical Reference Manual》: Chapter 3 System Control Coprocessor Chapter 6 Memory Management Unit 2)u-boot源码: u-boot-x.x.x/cpu/s3c64xx/start.S u-boot-x.x.x/board/samsung/smdk6410/lowlevel_init.S 1. ARMv6 MMU简述 1)MMU由协处理器CP15控制; 2)MMU功能:地址映射(VA- PA),内存访问权限控制; 3)虚拟地址到物理地址的转换过程:Micro TLB- Main TLB- P
[单片机]
基于S3C2440的Linux内核移植和yaffs2文件系统制作-- 配置Linux内核
1.3.3 配置Linux内核 1、 进入Linux-2.6.29.1内核主目录,通过以下命令将2410的默认配置文件写到当前目录下的.config。S3C2410的配置和S3C2440差不多,,在这基础上进行修改。 make s3c2410_defconfig 2、 配置内核模块的功能,有几种方式可以进行界面选择: make menuconfig(文本选单的配置方式,在有字符终端下才能使用) make xconfig(图形窗口模式的配置方式,图形窗口的配置比较直观,必须支持Xwindow下才能使用) make oldconfig(文本配置方式,在原内核配置的基础修改时使用) 这里使用make menuconfi
[单片机]
OK6410A 开发板 (八) 60 linux-5.11 OK6410A 异常相关初始化
arch/arm/kernel/head.S 77 ENTRY(stext) arch/arm/kernel/traps.c devicemaps_init void * vectors = early_alloc(PAGE_SIZE * 2); early_trap_init(vectors); vectors_base = vectors; vectors_page = vectors; // 填充 vectors - vectors+0x1000-1 vectors_base) = 0xe7fddef1; memcpy((void *)vectors, __vectors_star
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
更多往期活动
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved