几个GPXCON寄存器的物理地址。
GPACON 0X56000000
GPBCON 0X56000010
GPCCON 0X56000020
GPDCON 0X56000030
其他的以此类推,可以看出这个I/O口控制寄存器的规律,如果将ppvalue左移四位,加上GPIO虚拟基地址,就能得到GPXCON控制寄存器的虚拟地址了。顺便说下,这里的虚实地址的映射只是相差了一个偏移量。
分析:if (pin < S3C2410_GPIO_BANKB)
S3C2410_GPIO_BANKB的定义如下
#define S3C2410_GPIO_BANKA (32*0)
#define S3C2410_GPIO_BANKB (32*1)
#define S3C2410_GPIO_BANKC (32*2)
#define S3C2410_GPIO_BANKD (32*3)
#define S3C2410_GPIO_BANKE (32*4)
#define S3C2410_GPIO_BANKF (32*5)
#define S3C2410_GPIO_BANKG (32*6)
#define S3C2410_GPIO_BANKH (32*7)
用于判断此I/O口是否为GPA端口,这是为了区分开GPA与其他各组端口,因为GPA控制寄存器的操作和其他的有点区别,另外要注意,它是没有输入功能的。看datasheet能够更好的了解。
分析:S3C2410_GPIO_OFFSET(pin)
#define S3C2410_GPIO_OFFSET(pin) ((pin) & 31) //用此宏能得出偏移量
if (pin < S3C2410_GPIO_BANKB) { //判断I/O口是不是属于GPA, mask = 1 << S3C2410_GPIO_OFFSET(pin);//设置屏蔽码
} else {
mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;//设置屏蔽码
}
分析:local_irq_save(flags);
这个与下面出现的local_irq_restore(flags);成对使用,用于关闭、打开中断,同时将中断的标志存储在flags中。
分析:__raw_readl(base + 0x00); __raw_writel(con, base + 0x00);
con = __raw_readl(base + 0x00); //读取控制寄存器数据
con &= ~mask; //屏蔽掉相应的位
con |= function; //设置要设置的位
__raw_writel(con, base + 0x00);//把改变后的数据写回控制寄存器
上面的是两个函数宏,定义如下
#define __raw_writeb(v,a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a) = (v))
#define __raw_writew(v,a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a) = (v))
#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v))
PS(ZXX):先检查指针a是否合法,然后将数值v写入a所指向的空间。
三种类型分别对应char,short,int
#define __raw_readb(a) (__chk_io_ptr(a), *(volatile unsigned char __force *)(a))
#define __raw_readw(a) (__chk_io_ptr(a), *(volatile unsigned short __force *)(a))
#define __raw_readl(a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a))
PS(ZXX):先检查指针a是否合法,然后读取a所指向的空间的数值。
三种类型分别对应char,short,int
5.分析s3c2410_gpio_setpin(led_table[i], 0);
void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
{
void __iomem *base = S3C24XX_GPIO_BASE(pin);
unsigned long offs = S3C2410_GPIO_OFFSET(pin);
unsigned long flags;
unsigned long dat;
local_irq_save(flags);
dat = __raw_readl(base + 0x04);
dat &= ~(1 << offs);
dat |= to << offs;
__raw_writel(dat, base + 0x04);
local_irq_restore(flags);
}
有了上述的对s3c2410_gpio_cfgpin(led_table[i], led_cfg_table[i])的分析,上面的代码大同小异罢了,只是说一下__raw_readl(base + 0x04);这个,这是对数据寄存器进行操作,看datasheet就知道,每组的GPXDAT的地址值都比GPXCON的地址值大4。
总结:到此这个led驱动分析就结束了,程序虽小,里面涉及到的东西还是不少的,主要是刚入门者感觉很乱主要是对刚入门的同志有一定的帮助。关于这个驱动程序有几个版本,内核也在不断改变。我同时贴出另一个转载来的也是led驱动程序的文章,但里面涉及的结构数据比这个要复杂点,在我的博客里面可以找到,看懂的话还是能学到不少东西的。
上一篇:mini2440 Norflash驱动移植过程
下一篇:mini2440重新烧写supervivi方法
推荐阅读最新更新时间:2024-11-13 04:36
设计资源 培训 开发板 精华推荐
- BB-BONE-LCD3-01,BeagleBone LCD3 Cape,BeagleBone 的附加板
- ATMEGA16L最小系统
- 适用于低占空比应用的 LT3007ETS8-1.2 低压差线性稳压器的典型应用电路
- NCV8843DEMO/D、NCV8843 演示板为实施和评估完整实用的降压稳压器设计提供了便捷的方法
- QS-30 Nixie Clock_Mainboard
- LT1084CT-3.3、3.3V/5A 电池后备稳压电源的典型应用电路
- 5路隔离电源
- LT8330EDDB 4V 至 16V 输入、5V SEPIC 转换器的典型应用电路
- 华为hdmi 多USB版本
- 液晶电视电源用DC转DC单路输出电源
- 【唤新】微信寄语2018年STM32峰会,赢取ST精美板卡
- 助力EEWorld 19成长计划,赢取精美好礼!
- 【传感器,开玩啦】第一关:免费申请评测运动和环境传感器开发板
- 是德科技感恩月直播已结束|高速示波器基础与是德新品示波器解析
- TI携您共创未来乘驾新体验——深入学习: 点评明星产品,为它打榜
- TI首届低功耗设计大赛之玩转MSP430 FRAM MCU
- 【摸黑抢楼】赢大礼,关于示波器的狂想曲!正式开抢!!!
- TMS320F28377S LaunchPad俱乐部已成立,让我们一起见证它高性能的魅力!
- 玩儿转电源游戏,赢取800元TI手持POS机开发套件!
- 关注EE官方微信,大年初一抢新年红包