AM3359 GPIO 驱动设计
开发板:英蓓特科技有限公司的Mini8600B
处理器:TI 公司的AM3359
操作系统:Linux 3.2.0
一、GPIO 资源简介
AM3359 包含四组GPIO 引脚,GPIO0~GPIO3,每组32 根线,共128 根GPIO 引脚。
GPIO0 寄存器基地址:0x44E0_7000
GPIO1 寄存器基地址:0x4804_C000
GPIO2 寄存器基地址:0x481A_C000
GPIO3 寄存器基地址:0x481A_E000
二、配置GPIO 引脚
在以下文件Linux-3.2.0-psp04.06.00.08.sdk/arch/arm/mach-omap2/board-am335xevm.c
中配置:
1、添加如下引脚配置代码
/*pin mux for FIFO writing*/
static struct pinmux_config fifo_pin_mux[] = {
{"gpmc_csn1.gpio1_30", OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT},
{"gpmc_csn2.gpio1_31", OMAP_MUX_MODE7 | AM33XX_PIN_INPUT},
{"gpmc_csn3.gpio2_0", OMAP_MUX_MODE7 | AM33XX_PIN_INPUT},
{"gpmc_clk.gpio2_1", OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT},
{"lcd_vsync.gpio2_22", OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT},
{"lcd_pclk.gpio2_24", OMAP_MUX_MODE7 | AM33XX_PIN_OUTPUT},
{NULL, 0},
};
2、添加初始化函数fifo_init(),调用setup_pin_mux()使引脚配置生效:
static void fifo_init(int evm_id, int profile)
{
setup_pin_mux(fifo_pin_mux);
return;
}
3、在结构体evm_dev_cfg sbc8600_dev_cfg[]中添加
{fifo_init, DEV_ON_BASEBOARD, PROFILE_ALL},
系统初始化的时候会调用下面的函数:
_configure_device(EVM_SK, sbc8600_dev_cfg, PROFILE_NONE);
4、注意事项
引脚配置不应有冲突,即不应有两个或以上的驱动配置相同的引脚,同一个引脚不应被
配置两次或多次不同的数值。
5、编译内核,生成uImage 文件,下载到开发板上。
三、驱动设计
1、除一般驱动所要的头文件外,还需包含的头文件
#include // gpio operation
#include
#include
#include
2、GPIO 引脚定义
#define GPIO_TO_PIN(bank, gpio) ((32 * (bank)) + (gpio))
#define GPMC_CSN1_RESET GPIO_TO_PIN(1, 30) /*FIFO reset*/
#define GPMC_CSN2_EF GPIO_TO_PIN(1, 31) /*FIFO empty flag*/
#define GPMC_CSN3_IRQ GPIO_TO_PIN(2, 0) /*中断信号*/
#define GPMC_CLK_IRQ GPIO_TO_PIN(2, 1) /*中断信号*/
#define LCD_VSYNC_TRMODE GPIO_TO_PIN(2, 22)/*传输状态位*/
#define LCD_PCLK_TRMODE GPIO_TO_PIN(2, 24)/*传输状态位*/
3、申请GPIO 引脚
在设备打开时申请,即在驱动的open()函数中调用gpio_request(gpio_pin,)申请GPIO 引
脚,第一个参数是GPIO 引脚号,第二个参数是引脚名字,由自己定。
4、设置GPIO 引脚的功能
在设备打开时设置,
gpio_direction_input(gpio_pin)设置引脚为输入模式,
gpio_direction_output(gpio_pin, value)设置引脚为输出模式,同时通过第二个参数可置引
脚的电平高低
5、设置/获得GPIO 引脚电平
gpio_set_value(gpio_pin, value)设置GPIO 引脚电平;
value = gpio_get_value(gpio_pin) 获取GPIO 引脚电平;
6、中断
GPIO 引脚号转换为中断号: irq_num = gpio_to_irq(gpio_pin);
设置中断出发方式为下降沿触发irq_set_irq_type(irq_num, IRQF_TRIGGER_FALLING);
申请中断:
request_irq(irq_num, irq_proc, IRQF_DISABLED, GPIO_DEVICE_NAME, NULL);
中断处理函数:
static irqreturn_t irq_proc(int irq, void *dev_id)
{
// your code
return IRQ_HANDLED;
}
中断类型IRQF_DISABLED 表示此中断处理函数调用时,屏蔽所有中断,更多信息可
在头文件 与中找到。
7、释放GPIO 资源
gpio_free(gpio_pin);
8、释放中断资源
free_irq(irq_num, NULL);
9、驱动源程序
见附件
四、Makefile
ARCH=arm
CROSS_COMPILE=/opt/arm-2009q1/bin/arm-none-linux-gnueabi-
KERNELDIR := /home/linfan/linux-3.2.0-psp04.06.00.08.sdk
obj-m := gpio_read.o
PWD := $(shell pwd)
default:
$(MAKE) -C $(KERNELDIR) M=$(PWD) ARCH=$(ARCH)
CROSS_COMPILE=$(CROSS_COMPILE) modules
app:
arm-none-linux-gnueabi-gcc test_read.c -o read
clean:
rm -rf *.o *.ko *.mod.c write *.symvers *.order
五、用户空间应用程序
见附件
六、总结
AM3359 的驱动设计要在board-am335xevm.c 中定义设备和配置引脚,然后再编译
内核,生成映像文件,颇有不便之处。我在编写这个GPIO 引脚的驱动时,大部分时间
花在修改内核源码及编译内核之上。曾试图将设备定义及引脚配置都转移出来,放到自
己的驱动中实现,但编译驱动时error 一大堆。引脚配置调用函数setup_pin_mux,而该
函数实际上调用omap_mux_init_signal 来实现,按照error 提示#include 了所需的头文件
后,编译又提示相关的函数undefined。最终还是没能实现在自己的驱动中定义设备和
配置引脚,这个问题留待以后有时间再研究。
后来看了AM3359 的datasheet,发现引脚模式的配置是通过control module 来实现
的,即配置CONTROL_MODULE Registers。一种可行的办法是,查到相关寄存器的物理
地址,用ioremap 函数转换为虚拟地址,然后往该地址中写配置data,就可以将引脚配置
为你想要的模式了。但这种操作是不安全的,因为你不知道你的Linux 系统中有没有驱动用
掉了你配置的那些引脚,一旦有引脚配置的冲突,结果是不可预知的。只有在确保你想配
置的引脚未被使用,未与其他驱动发生冲突时,才建议用这种方法。这样一来,还是要查
看board-am335xevm.c 的代码,如果有冲突,还是要修改里面的代码,重新编译内核。
阅读(757) | 评论(0) | 转发(0) |