设为首页 加入收藏

TOP

AT9260 GPIO中断(一)
2014-11-24 14:37:03 来源: 作者: 【 】 浏览:4
Tags:AT9260 GPIO 中断

#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#i nclude




#i nclude
#i nclude
#i nclude
#i nclude
#i nclude
#define DEVICE_NAME "button"



#define KEY_TIMER_DELAY1 (HZ/50) //按键按下去抖延时20毫秒
#define KEY_TIMER_DELAY2 (HZ/10) //按键抬起去抖延时100毫秒



#define KEYSTATUS_DOWN 0 //按键按下
#define KEYSTATUS_UP 1 //按键抬起
#define KEYSTATUS_DOWNX 2 //按键不确定
#define KEY_NUM 4 // 4个按键



#define DP_MAJOR 0//主设备号
#define DP_MINOR 0 //次设备号
unsigned int button_major = DP_MAJOR;



// 按键驱动的设备结构体、定时器
#define MAX_KEY_BUF 16 // 按键缓存区大小
typedef unsigned char KEY_RET;
// 设备结构体
typedef struct
{
unsigned int keyStatus[KEY_NUM]; // 4个按键的按键状态
KEY_RET buf[MAX_KEY_BUF];
unsigned int head,tail; // 按键缓存区头和尾
wait_queue_head_t wq; // 等待队列
struct cdev cdev; // cdev 结构体
}KEY_DEV;
KEY_DEV key_dev,*key_devp;




#define BUF_HEAD (key_dev.buf[key_dev.head]) //缓冲头
#define BUF_TAIL (key_dev.buf[key_dev.tail]) //缓冲尾
#define INCBUF(x,mod) ((++(x))&((mod)-1))




static struct timer_list key_timer[KEY_NUM]; // 4个按键去抖定时器



// 按键硬件资源、键值信息结构体
static struct key_info
{
int irq_no; // 中断号
int irq_type; // 中断类型
unsigned int gpio_port; // GPIO端口
int key_no; // 键值


}key_info_tab[4]=
// 按键所使用的CPU资源
{

{
AT91_PIN_PB0,AT91_AIC_SRCTYPE_FALLING,AT91_PIN_PB0,1
},
{
AT91_PIN_PB1,AT91_AIC_SRCTYPE_FALLING,AT91_PIN_PB1,2
},
{
AT91_PIN_PB2,AT91_AIC_SRCTYPE_FALLING,AT91_PIN_PB2,3
},
{
AT91_PIN_PB3,AT91_AIC_SRCTYPE_FALLING,AT91_PIN_PB3,4
},
};



// 初始化
static void at91sam9260_key_io_init(void)
{
at91_set_gpio_input(AT91_PIN_PB0, 1);
at91_set_deglitch(AT91_PIN_PB0, 1);

at91_set_gpio_input(AT91_PIN_PB1, 1);
at91_set_deglitch(AT91_PIN_PB1, 1);



at91_set_gpio_input(AT91_PIN_PB2, 1);
at91_set_deglitch(AT91_PIN_PB2, 1);

at91_set_gpio_input(AT91_PIN_PB3, 1);
at91_set_deglitch(AT91_PIN_PB3, 1);
}



/* 记录键值并唤醒等待队列 */
static void keyEvent(unsigned int key)
{
BUF_HEAD = key_info_tab[key].key_no; // 记录键值
key_dev.head = INCBUF(key_dev.head, MAX_KEY_BUF); // 调整缓冲区头指针
wake_up_interruptible(&(key_dev.wq)); // 唤醒等待队列
}




// 按键设备的中断处理
// 键被按下后,将发生中断,在中断处理程序中,应该关闭中断进入查询模式,延迟20ms以实现去抖动
// 这个中断处理过程只包含顶半部,无底半部
static irqreturn_t at91sam9260_enit_key(int irq,void *dev_id,struct pt_regs *reg)
{
int key = (int)dev_id;
int found = 0;
int i;

for (i = 0; i < ARRAY_SIZE(key_info_tab); i++) // 查找产生中断的按键
{
if (key_info_tab[i].irq_no == irq)
{
found = 1;
break;
}
}
if (!found) // 没找到
{
printk(KERN_NOTICE"bad irq %d in button\n", irq);
return IRQ_NONE; //错误的中断
}

disable_irq(key_info_tab[key].irq_no); // 找到,关闭对应中断



key_dev.keyStatus[key] = KEYSTATUS_DOWNX; // 不确定是否为按下
key_timer[key].expires = j

首页 上一页 1 2 3 下一页 尾页 1/3/3
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇AT91SAM9261的LINUX2.6 GPIO与GPI.. 下一篇Android Matrix图片随意的放大缩..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: