關於LINUX對926X中斷的實現(LINUX2.6.24中試用)
一,926X中斷的描述
對於926X有先進中斷控制器控制中斷具體對應的中斷有0~310為FIQ,1為系統,2~31對應設備.見DATASHEET
二,926X中斷的LINUX實現
1,PIO的輸入中斷問題,手冊描述了
PIOA 2
PIOB 3
PIOC 4
LINUX中AT91SAM926X.H定義了所有的中斷分配號:
*
* Peripheral identifiers/interrupts.
*/
#define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */
#define AT91_ID_SYS 1 /* System Peripherals */
#define AT91SAM9260_ID_PIOA 2 /* Parallel IO Controller A */
#define AT91SAM9260_ID_PIOB 3 /* Parallel IO Controller B */
#define AT91SAM9260_ID_PIOC 4 /* Parallel IO Controller C */
#define AT91SAM9260_ID_ADC 5 /* Analog-to-Digital Converter */
#define AT91SAM9260_ID_US0 6 /* USART 0 */
#define AT91SAM9260_ID_US1 7 /* USART 1 */
#define AT91SAM9260_ID_US2 8 /* USART 2 */
#define AT91SAM9260_ID_MCI 9 /* Multimedia Card Interface */
#define AT91SAM9260_ID_UDP 10 /* USB Device Port */
#define AT91SAM9260_ID_TWI 11 /* Two-Wire Interface */
#define AT91SAM9260_ID_SPI0 12 /* Serial Peripheral Interface 0 */
#define AT91SAM9260_ID_SPI1 13 /* Serial Peripheral Interface 1 */
#define AT91SAM9260_ID_SSC 14 /* Serial Synchronous Controller */
#define AT91SAM9260_ID_TC0 17 /* Timer Counter 0 */
#define AT91SAM9260_ID_TC1 18 /* Timer Counter 1 */
#define AT91SAM9260_ID_TC2 19 /* Timer Counter 2 */
#define AT91SAM9260_ID_UHP 20 /* USB Host port */
#define AT91SAM9260_ID_EMAC 21 /* Ethernet */
#define AT91SAM9260_ID_ISI 22 /* Image Sensor Interface */
#define AT91SAM9260_ID_US3 23 /* USART 3 */
#define AT91SAM9260_ID_US4 24 /* USART 4 */
#define AT91SAM9260_ID_US5 25 /* USART 5 */
#define AT91SAM9260_ID_TC3 26 /* Timer Counter 3 */
#define AT91SAM9260_ID_TC4 27 /* Timer Counter 4 */
#define AT91SAM9260_ID_TC5 28 /* Timer Counter 5 */
#define AT91SAM9260_ID_IRQ0 29 /* Advanced Interrupt Controller (IRQ0) */
#define AT91SAM9260_ID_IRQ1 30 /* Advanced Interrupt Controller (IRQ1) */
LINUX中AT91SAM926X.C分配中斷分配號到PIOA,PIOB,PIOC中:
static struct at91_gpio_bank at91sam9260_gpio[] = {
{
.id = AT91SAM9260_ID_PIOA,
.offset = AT91_PIOA,
.clock = &pioA_clk,
},
{
.id = AT91SAM9260_ID_PIOB,
.offset = AT91_PIOB,
.clock = &pioB_clk,
},
{
.id = AT91SAM9260_ID_PIOC,
.offset = AT91_PIOC,
.clock = &pioC_clk,
}
};
這裡調用允許中斷函數
At91_gpio_irq_setup();他的定義在gpio.c:
static struct at91_gpio_bank *gpio;
void __init at91_gpio_irq_setup(void)
{
unsigned pioc, pin;
for (pioc = 0, pin = PIN_BASE;
pioc < gpio_banks;
pioc++) {
void __iomem *controller;
unsigned id = gpio[pioc].id;
unsigned i;
clk_enable(gpio[pioc].clock);
//處理/* enable PIO controller's clock */
controller = (void __iomem *) AT91_VA_BASE_SYS + gpio[pioc].offset;
__raw_writel(~0, controller + PIO_IDR);
set_irq_data(id, (void *) pin);
set_irq_chip_data(id, controller);
for (i = 0; i < 32; i++, pin++) {
/*
* Can use the "simple" and not "edge" handler since it's
* shorter, and the AIC handles interupts sanely.
*/
set_irq_chip(pin, &gpio_irqchip);
set_irq_handler(pin, handle_simple_irq);
set_irq_flags(pin, IRQF_VALID);
}
set_irq_chained_handler(id, gpio_irq_handler);
}
如果使用PIO IO:
直接用int at91_get_gpio_value(unsigned pin)
int at91_set_gpio_value(unsigned pin, int value)
就可以實現讀寫啦
如果使用PIO的中斷呢?
一 設置為輸入.
二 設置毛刺(也可以不設置)
三 調用 REQUEST_IRQ()
at91_set_gpio_input(AT91_PIN_PB5,1);
result = request_irq(AT91_PIN_PB5, kirq_interrupt, SA_INTERRUPT, "kirq", &kirq_dev);
if (result < 0){
printk("register irq fail.%d\r\n",result);
return result;
}
/************************************************************************************/
實驗的結果(查看中斷是否產生)
/teset/irq # cat /proc/interrupts
CPU0
1: 72905 AIC at91_tick, atmel_serial
10: 0 AIC at91_udc
20: 0 AIC ohci_hcd:usb1
21: 4754 AIC eth0
69: 0 GPIO kirq
101: 1 GPIO at91_udc
at91_set_gpio_input(AT91_PIN_PA5,1);
result = request_irq(AT91_PIN_PA5, kirq_interrupt, SA_INTERRUPT, "kirq", &kirq_dev);
if (result < 0){
printk("register irq fail.%d\r\n",result);
return result;
}
實驗的結果(查看中斷是否產生)
/teset/irq # cat /proc/interrupts
CPU0
1: 3295 AIC at91_tick, atmel_serial
10: 0 AIC at91_udc
20: 0 AIC ohci_hcd:usb1
21: 1801 AIC eth0
37: 1 GPIO kirq
101: 1 GPIO at91_udc
Err: 0四 其他設備的調用就直接用request_irq(IRQ_NUMBER,…)