S3C6410 按键驱动(二) ---按键中断的基本流程

1.将引脚设置为中断模式

void init_dev(void)
{
	s3c_gpio_cfgpin(key_table[0],S3C_GPIO_SFN(2));
	s3c_gpio_cfgpin(key_table[1],S3C_GPIO_SFN(2));
	s3c_gpio_cfgpin(key_table[2],S3C_GPIO_SFN(2));
	s3c_gpio_cfgpin(key_table[3],S3C_GPIO_SFN(2));
	s3c_gpio_cfgpin(key_table[4],S3C_GPIO_SFN(2));
	s3c_gpio_cfgpin(key_table[5],S3C_GPIO_SFN(2));

	unsigned int tmp;
	tmp = readl(S3C64XX_GPNCON);
	printk("%x\n",tmp);
}


2.申请中断

ret = request_irq(key_irqs[num].irq,keys_interrupt,key_irqs[num].flags,key_irqs[num].name,(void*)&key_irqs[num]);


3.等待中断触发事件

wait_event_interruptible(key_waitq,ev_press);

当wake_up_interruptible()没有执行且ev_press没有改变时,将一直等待。


4.当中断发生时,调用中断处理函数

当外部中断发生时,request_irq()当中最后一个参数将提供给中断处理函数

中断处理函数

static irqreturn_t keys_interrupt(int irq,void *dev_id)
{
	struct key_irq *key_irqs = (struct key_irq *)dev_id;
	int down;
	int number;
	unsigned tmp;

	number = key_irqs->number;
	printk("number = %d\n",number);
	switch(number)
	{
		case 0:
		case 1:
		case 2:
		case 3:
		case 4:
		case 5:
			tmp = readl(S3C64XX_GPNDAT);
			down = !(tmp & (1 << number));
			break;

		default:
			down = 0;
	}

	if(down != (key_values[number] & 1))
	{
		key_values[number] = '0' + down;
		ev_press = 1;
		
		wake_up_interruptible(&key_waitq);
	}

	printk("interrupt\n");
	return IRQ_RETVAL(IRQ_HANDLED);
}


5. 释放中断

free_irq(key_irqs[i].irq,(void*)&key_irqs[i]);

你可能感兴趣的:(S3C6410 按键驱动(二) ---按键中断的基本流程)