At91SAMXX系列设置GPIO口中断端口方法

本文介绍了如何在Linux 2.6.31环境下,针对AT91SAM9XE处理器设置GPIO中断和外部中断。详细阐述了外部中断(使用IRQ0和AT91_PIN_PC12触发)与GPIO中断(使用IRQ 108,触发类型为BOTH或NONE)的创建过程,并提到了中断处理函数和释放IRQ的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转自:http://rico-studio.com/linux/at91-gpio-interrupt/

Linux: 2.6.31
Processor: AT91SAM9XE

There are two types of interrupts you can create for an AT91.  An external interrupt or a GPIO interrupt.  An external interrupt does not have the additional overhead of going through the GPIO controller.  I will explain how to create an external and GPIO interrupt for an AT91.  I do these things for my own personal notes for the future.  The instructions for creating the interrupts are in arch/arm/mach-at91/gpio.c around line 338.  I will be using pin PC12.  This pin can be used as an external interrupt (IRQ0) or a GPIO interrupt.

External Interrupt
This will create an external interrupt with IRQ0 on pin AT91_PIN_PC12.  I will using a falling edge to trigger.  For an external interrupt, you can use any trigger.  On a GPIO interrupt you can only use BOTH (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING) or NONE.

/** Set pin as GPIO input, without internal pull up */
if (at91_set_gpio_input (AT91_PIN_PC12 , 0 ) ) {
    printk (KERN_DEBUG "Could not set pin %i for GPIO input.\n" , AT91_PIN_PC12 ) ;
}

/** Set deglitch for pin */
if (at91_set_deglitch (AT91_PIN_PC12 , 1 ) ) {
    printk (KERN_DEBUG "Could not set pin %i for GPIO deglitch.\n" , AT91_PIN_PC12 ) ;
}

/** Set the IRQ0 pin to Periph A */
at91_set_A_periph (AT91_PIN_PC12 , 0 ) ;

/** Request IRQ for pin */
if (request_irq (AT91SAM9260_ID_IRQ0 , interrupt_handler_function , IRQF_TRIGGER_FALLING , "my_interrupt" , NULL ) )   {
    printk (KERN_DEBUG "Can't register IRQ %d\n" , AT91_PIN_PC12 ) ;
    return -EIO ;
}

GPIO Interrupt
This will create an GPIO interrupt with IRQ 108.  The main difference between this way and the external interrupt and this can be used for any GPIO pin.  It must use BOTH (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING) or NONE for trigger and it does not have a defined IRQ value.  This also goes through the overhead of using the GPIO controller.

/** Set pin as GPIO periph, without internal pull up */
at91_set_GPIO_periph (AT91_PIN_PC12 , 0 ) ;

/** Set pin as GPIO input, without internal pull up */
if (at91_set_gpio_input (AT91_PIN_PC12 , 0 ) ) {
    printk (KERN_DEBUG "Could not set pin %i for GPIO input.\n" , AT91_PIN_PC12 ) ;
}

/** Set deglitch for pin */
if (at91_set_deglitch (AT91_PIN_PC12 , 1 ) ) {
    printk (KERN_DEBUG "Could not set pin %i for GPIO deglitch.\n" , AT91_PIN_PC12 ) ;
}

/** Request IRQ for pin */
if (request_irq (AT91_PIN_PC12 , interrupt_handler_function , IRQF_TRIGGER_FALLING |IRQF_TRIGGER_RISING , "my_interrupt" , NULL ) )   {
    printk (KERN_DEBUG "Can't register IRQ %d\n" , AT91_PIN_PC12 ) ;
    return -EIO ;
}

Interrupt handler function

/**
 * Called when an interrupt is triggered
 */
irqreturn_t interrupt_handler_function ( int irq , void *dev_id )
{
    /* Start tasklet */
    return IRQ_HANDLED ;
}

Kill IRQ
Use the free_irq for the type of interrupt you used.

free_irq (AT91SAM9260_ID_IRQ0 , 0 ) ;
free_irq (AT91_PIN_PC12 , 0 ) ;

Tasklet
Next post i will show how to make a tasklet to go with this interrupt.

转自:http://rico-studio.com/linux/at91-gpio-interrupt/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值