微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > micro2440驱动分析1——LED驱动

micro2440驱动分析1——LED驱动

时间:11-20 来源:互联网 点击:
micro2440采用S3C2440处理器(和S3C2410区别不大),在其Linux源码中,和这个平台相关的代码主要在arch/arm/mach-s3c2410和include/asm-arm/arch-s3c2410中,相关驱动在drivers目录中。

(1)DM9000 网卡驱动
kernel-2.6.13/drivers/net/dm9000x.c
(2)串口(包括三个串口驱动0,1,2,对应设备名/dev/tts/0,1,2)
kernel-2.6.13/drivers/serial/s3c2410.c
(3)实时时钟RTC 驱动
kernel-2.6.13/drivers/char/s3c2410-rtc.c
(4)LED 驱动
kernel-2.6.13/drivers/char/qq2440_leds.c
(5)按键驱动
kernel-2.6.13/drivers/char/qq2440_buttons.c
(6)触摸屏驱动
kernel-2.6.13/drivers/input/touchscreen/s3c2410_ts.c
(7)yaffs 文件系统源代码目录
kernel-2.6.13/fs/yaffs2
(8)USB 鼠标、键盘源代码
kernel-2.6.13/drivers/ usb/input/hid-input.c
(9)SD/MMC 卡驱动源代码目录(在2.6.13 内核中仅支持2G 容量以内的SD 卡)
kernel-2.6.13/drivers/mmc
(10)Nand Flash 驱动
kernel-2.6.13/drivers/mtd/nand
(11)UDA1341 音频驱动目录
kernel-2.6.13/ sound/oss/uda1341.c
kernel-2.6.13/ drivers/l3
(12)LCD 驱动(包含3.5", 7", 8.4", 10.4", 12.4", 15"等大小的驱动)
kernel-2.6.13/drivers/video/s3c2410fb.c
(13)优盘支持驱动
kernel-2.6.13/drivers/usb/storage
(14)中星微USB 摄像头驱动
kernel-2.6.13/drivers/usb/media/gspca

1.S3C2410_GPB5是端口编号,定义在regs-gpio.h中,

#define S3C2410_GPIO_BANKB (32*1)
#define S3C2410_GPIONO(bank,offset) ((bank) + (offset))
#define S3C2410_GPB5 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 5)

S3C2410共有130个GPIO,分为9组(GPA~GPJ),每组最多可以有32个,每个GPIO有2~4个可选功能,每组的控制寄存器空间有4个,例如对于GPB,有GPBCON、GPBDAT、GPBUP和Reserved,分别是功能配置、数据缓存、上拉使能和保留。

上面的S3C2410_GPB5就是GPIO的编号,也就是在号码空间(0~32*9-1)中的位置,bank是分组的基号码,offset是组内偏移量。

2.S3C2410_GPB5_OUTP是端口功能,定义在regs-gpio.h中,

#define S3C2410_GPB5_INP (0x00 < 10)
#define S3C2410_GPB5_OUTP (0x01 < 10)

GPBCON的第10、11两位用于配置GPB5的功能,00 = Input ,01 = Output

3.S3C2410 GPIO的操作函数

在hardware.h文件中有:

s3c2410_gpio_cfgpin //配置端口的GPIO的功能
s3c2410_gpio_getcfg //读取功能配置
s3c2410_gpio_pullup //配置上拉电阻
s3c2410_modify_misccr //杂项配置

s3c2410_gpio_getirq //给定端口,转换出IRQ号
s3c2410_gpio_irqfilter //配置IRQ过滤使能与否

s3c2410_gpio_setpin //写数据到端口
s3c2410_gpio_getpin //从端口读数据

这些函数的实现在gpio.h中

void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
{
void __iomem *base = S3C2410_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);
}

4.S3C2410_GPIO_BASE和S3C2410_GPIO_OFFSET也是在regs-gpio.h文件中定义,

#define S3C2410_GPIO_BASE(pin) ((((pin) & ~31) >> 1) + S3C24XX_VA_GPIO)
#define S3C2410_GPIO_OFFSET(pin) ((pin) & 31)

而在map.h中有:

#define S3C24XX_VA_GPIO S3C2410_ADDR(0x00E00000) //虚拟地址S3C24XX_VA_GPIO= 0xF0E00000
#define S3C2400_PA_GPIO (0x15600000)
#define S3C2410_PA_GPIO (0x56000000) //GPACON 物理地址
#define S3C24XX_SZ_GPIO SZ_1M //0x100000 = 1024 *1024

S3C2410_GPIO_BASE作用是:根据端口编号pin,算出端口所在组的虚拟基址。((pin) & ~31)是去掉pin当中小于等于31的零头(清0低5位),>>1的原因是每组GPIO中最多可以有32个端口,控制这些端口需要4个寄存器空间,4个寄存器空间就需要4*4=16个字节进行编址,32/16=2,左移一位刚好满足。也就是说,上一组端口和下一组端口的编号相差32,而控制寄存器的地址相差16。

S3C2410_GPIO_OFFSET作用是:根据端口编号pin,算出端口所在组的偏移量。((pin) & 31)即去掉比31大的数(清0第6位以上的位)。

5. __raw_readl和__raw_writel

Linux对I/O的操作都定义在asm/io.h中,相应的在arm平台下,就在asm-arm/io.h中。

#define __raw_readl(a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a))
#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v))

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top