support gpio interrupt

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@1539 bbd45198-f89e-11dd-88c7-29a3b14d5316
This commit is contained in:
luohui2320@gmail.com 2011-06-26 15:09:26 +00:00
parent 7beb4cd4cf
commit 1586a43f6c
4 changed files with 262 additions and 7 deletions

View File

@ -0,0 +1,21 @@
#ifndef __AT91_PDC_H__
#define __AT91_PDC_H__
#define AT91_PDC_RPR 0x100 /* Receive Pointer Register */
#define AT91_PDC_RCR 0x104 /* Receive Counter Register */
#define AT91_PDC_TPR 0x108 /* Transmit Pointer Register */
#define AT91_PDC_TCR 0x10c /* Transmit Counter Register */
#define AT91_PDC_RNPR 0x110 /* Receive Next Pointer Register */
#define AT91_PDC_RNCR 0x114 /* Receive Next Counter Register */
#define AT91_PDC_TNPR 0x118 /* Transmit Next Pointer Register */
#define AT91_PDC_TNCR 0x11c /* Transmit Next Counter Register */
#define AT91_PDC_PTCR 0x120 /* Transfer Control Register */
#define AT91_PDC_RXTEN (1 << 0) /* Receiver Transfer Enable */
#define AT91_PDC_RXTDIS (1 << 1) /* Receiver Transfer Disable */
#define AT91_PDC_TXTEN (1 << 8) /* Transmitter Transfer Enable */
#define AT91_PDC_TXTDIS (1 << 9) /* Transmitter Transfer Disable */
#define AT91_PDC_PTSR 0x124 /* Transfer Status Register */
#endif

View File

@ -29,8 +29,10 @@ extern "C" {
#include "at91_pio.h"
#include "at91_serial.h"
#include "at91_tc.h"
#include "at91_pdc.h"
#include "io.h"
#include "irq.h"
#include "gpio.h"
/*
* Peripheral identifiers/interrupts.

View File

@ -0,0 +1,119 @@
#ifndef __GPIO_H__
#define __GPIO_H__
#include <at91_aic.h>
#define PIN_BASE AIC_IRQS
#define MAX_GPIO_BANKS 3
#define PIN_IRQS (MAX_GPIO_BANKS*32)
/* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */
#define AT91_PIN_PA0 (PIN_BASE + 0x00 + 0)
#define AT91_PIN_PA1 (PIN_BASE + 0x00 + 1)
#define AT91_PIN_PA2 (PIN_BASE + 0x00 + 2)
#define AT91_PIN_PA3 (PIN_BASE + 0x00 + 3)
#define AT91_PIN_PA4 (PIN_BASE + 0x00 + 4)
#define AT91_PIN_PA5 (PIN_BASE + 0x00 + 5)
#define AT91_PIN_PA6 (PIN_BASE + 0x00 + 6)
#define AT91_PIN_PA7 (PIN_BASE + 0x00 + 7)
#define AT91_PIN_PA8 (PIN_BASE + 0x00 + 8)
#define AT91_PIN_PA9 (PIN_BASE + 0x00 + 9)
#define AT91_PIN_PA10 (PIN_BASE + 0x00 + 10)
#define AT91_PIN_PA11 (PIN_BASE + 0x00 + 11)
#define AT91_PIN_PA12 (PIN_BASE + 0x00 + 12)
#define AT91_PIN_PA13 (PIN_BASE + 0x00 + 13)
#define AT91_PIN_PA14 (PIN_BASE + 0x00 + 14)
#define AT91_PIN_PA15 (PIN_BASE + 0x00 + 15)
#define AT91_PIN_PA16 (PIN_BASE + 0x00 + 16)
#define AT91_PIN_PA17 (PIN_BASE + 0x00 + 17)
#define AT91_PIN_PA18 (PIN_BASE + 0x00 + 18)
#define AT91_PIN_PA19 (PIN_BASE + 0x00 + 19)
#define AT91_PIN_PA20 (PIN_BASE + 0x00 + 20)
#define AT91_PIN_PA21 (PIN_BASE + 0x00 + 21)
#define AT91_PIN_PA22 (PIN_BASE + 0x00 + 22)
#define AT91_PIN_PA23 (PIN_BASE + 0x00 + 23)
#define AT91_PIN_PA24 (PIN_BASE + 0x00 + 24)
#define AT91_PIN_PA25 (PIN_BASE + 0x00 + 25)
#define AT91_PIN_PA26 (PIN_BASE + 0x00 + 26)
#define AT91_PIN_PA27 (PIN_BASE + 0x00 + 27)
#define AT91_PIN_PA28 (PIN_BASE + 0x00 + 28)
#define AT91_PIN_PA29 (PIN_BASE + 0x00 + 29)
#define AT91_PIN_PA30 (PIN_BASE + 0x00 + 30)
#define AT91_PIN_PA31 (PIN_BASE + 0x00 + 31)
#define AT91_PIN_PB0 (PIN_BASE + 0x20 + 0)
#define AT91_PIN_PB1 (PIN_BASE + 0x20 + 1)
#define AT91_PIN_PB2 (PIN_BASE + 0x20 + 2)
#define AT91_PIN_PB3 (PIN_BASE + 0x20 + 3)
#define AT91_PIN_PB4 (PIN_BASE + 0x20 + 4)
#define AT91_PIN_PB5 (PIN_BASE + 0x20 + 5)
#define AT91_PIN_PB6 (PIN_BASE + 0x20 + 6)
#define AT91_PIN_PB7 (PIN_BASE + 0x20 + 7)
#define AT91_PIN_PB8 (PIN_BASE + 0x20 + 8)
#define AT91_PIN_PB9 (PIN_BASE + 0x20 + 9)
#define AT91_PIN_PB10 (PIN_BASE + 0x20 + 10)
#define AT91_PIN_PB11 (PIN_BASE + 0x20 + 11)
#define AT91_PIN_PB12 (PIN_BASE + 0x20 + 12)
#define AT91_PIN_PB13 (PIN_BASE + 0x20 + 13)
#define AT91_PIN_PB14 (PIN_BASE + 0x20 + 14)
#define AT91_PIN_PB15 (PIN_BASE + 0x20 + 15)
#define AT91_PIN_PB16 (PIN_BASE + 0x20 + 16)
#define AT91_PIN_PB17 (PIN_BASE + 0x20 + 17)
#define AT91_PIN_PB18 (PIN_BASE + 0x20 + 18)
#define AT91_PIN_PB19 (PIN_BASE + 0x20 + 19)
#define AT91_PIN_PB20 (PIN_BASE + 0x20 + 20)
#define AT91_PIN_PB21 (PIN_BASE + 0x20 + 21)
#define AT91_PIN_PB22 (PIN_BASE + 0x20 + 22)
#define AT91_PIN_PB23 (PIN_BASE + 0x20 + 23)
#define AT91_PIN_PB24 (PIN_BASE + 0x20 + 24)
#define AT91_PIN_PB25 (PIN_BASE + 0x20 + 25)
#define AT91_PIN_PB26 (PIN_BASE + 0x20 + 26)
#define AT91_PIN_PB27 (PIN_BASE + 0x20 + 27)
#define AT91_PIN_PB28 (PIN_BASE + 0x20 + 28)
#define AT91_PIN_PB29 (PIN_BASE + 0x20 + 29)
#define AT91_PIN_PB30 (PIN_BASE + 0x20 + 30)
#define AT91_PIN_PB31 (PIN_BASE + 0x20 + 31)
#define AT91_PIN_PC0 (PIN_BASE + 0x40 + 0)
#define AT91_PIN_PC1 (PIN_BASE + 0x40 + 1)
#define AT91_PIN_PC2 (PIN_BASE + 0x40 + 2)
#define AT91_PIN_PC3 (PIN_BASE + 0x40 + 3)
#define AT91_PIN_PC4 (PIN_BASE + 0x40 + 4)
#define AT91_PIN_PC5 (PIN_BASE + 0x40 + 5)
#define AT91_PIN_PC6 (PIN_BASE + 0x40 + 6)
#define AT91_PIN_PC7 (PIN_BASE + 0x40 + 7)
#define AT91_PIN_PC8 (PIN_BASE + 0x40 + 8)
#define AT91_PIN_PC9 (PIN_BASE + 0x40 + 9)
#define AT91_PIN_PC10 (PIN_BASE + 0x40 + 10)
#define AT91_PIN_PC11 (PIN_BASE + 0x40 + 11)
#define AT91_PIN_PC12 (PIN_BASE + 0x40 + 12)
#define AT91_PIN_PC13 (PIN_BASE + 0x40 + 13)
#define AT91_PIN_PC14 (PIN_BASE + 0x40 + 14)
#define AT91_PIN_PC15 (PIN_BASE + 0x40 + 15)
#define AT91_PIN_PC16 (PIN_BASE + 0x40 + 16)
#define AT91_PIN_PC17 (PIN_BASE + 0x40 + 17)
#define AT91_PIN_PC18 (PIN_BASE + 0x40 + 18)
#define AT91_PIN_PC19 (PIN_BASE + 0x40 + 19)
#define AT91_PIN_PC20 (PIN_BASE + 0x40 + 20)
#define AT91_PIN_PC21 (PIN_BASE + 0x40 + 21)
#define AT91_PIN_PC22 (PIN_BASE + 0x40 + 22)
#define AT91_PIN_PC23 (PIN_BASE + 0x40 + 23)
#define AT91_PIN_PC24 (PIN_BASE + 0x40 + 24)
#define AT91_PIN_PC25 (PIN_BASE + 0x40 + 25)
#define AT91_PIN_PC26 (PIN_BASE + 0x40 + 26)
#define AT91_PIN_PC27 (PIN_BASE + 0x40 + 27)
#define AT91_PIN_PC28 (PIN_BASE + 0x40 + 28)
#define AT91_PIN_PC29 (PIN_BASE + 0x40 + 29)
#define AT91_PIN_PC30 (PIN_BASE + 0x40 + 30)
#define AT91_PIN_PC31 (PIN_BASE + 0x40 + 31)
static inline rt_uint32_t gpio_to_irq(rt_uint32_t gpio)
{
return gpio;
}
#endif

View File

@ -15,7 +15,7 @@
#include <rtthread.h>
#include "at91sam926x.h"
#define MAX_HANDLERS 32
#define MAX_HANDLERS (AIC_IRQS + PIN_IRQS)
extern rt_uint32_t rt_interrupt_nest;
@ -82,6 +82,39 @@ rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector)
return RT_NULL;
}
rt_isr_handler_t at91_gpio_irq_handle(rt_uint32_t vector)
{
rt_uint32_t isr, pio, irq_n;
if (vector == AT91SAM9260_ID_PIOA)
{
pio = AT91_PIOA;
irq_n = AIC_IRQS;
}
else if (vector == AT91SAM9260_ID_PIOB)
{
pio = AT91_PIOB;
irq_n = AIC_IRQS + 32;
}
else if (vector == AT91SAM9260_ID_PIOC)
{
pio = AT91_PIOC;
irq_n = AIC_IRQS + 32*2;
}
else
return;
isr = at91_sys_read(pio+PIO_ISR) & at91_sys_read(pio+PIO_IMR);
while (isr)
{
if (isr & 1)
{
isr_table[irq_n](irq_n);
}
isr >>= 1;
irq_n++;
}
}
/*
* Initialize the AIC interrupt controller.
*/
@ -93,7 +126,7 @@ void at91_aic_init(rt_uint32_t *priority)
* The IVR is used by macro get_irqnr_and_base to read and verify.
* The irq number is NR_AIC_IRQS when a spurious interrupt has occurred.
*/
for (i = 0; i < MAX_HANDLERS; i++) {
for (i = 0; i < AIC_IRQS; i++) {
/* Put irq number in Source Vector Register: */
at91_sys_write(AT91_AIC_SVR(i), i);
/* Active Low interrupt, with the specified priority */
@ -109,7 +142,7 @@ void at91_aic_init(rt_uint32_t *priority)
* Spurious Interrupt ID in Spurious Vector Register is NR_AIC_IRQS
* When there is no current interrupt, the IRQ Vector Register reads the value stored in AIC_SPU
*/
at91_sys_write(AT91_AIC_SPU, MAX_HANDLERS);
at91_sys_write(AT91_AIC_SPU, AIC_IRQS);
/* No debugging in AIC: Debug (Protect) Control Register */
at91_sys_write(AT91_AIC_DCR, 0);
@ -120,6 +153,22 @@ void at91_aic_init(rt_uint32_t *priority)
}
static void at91_gpio_irq_init()
{
at91_sys_write(AT91_PIOA+PIO_IDR, 0xffffffff);
at91_sys_write(AT91_PIOB+PIO_IDR, 0xffffffff);
at91_sys_write(AT91_PIOC+PIO_IDR, 0xffffffff);
isr_table[AT91SAM9260_ID_PIOA] = (rt_isr_handler_t)at91_gpio_irq_handle;
isr_table[AT91SAM9260_ID_PIOB] = (rt_isr_handler_t)at91_gpio_irq_handle;
isr_table[AT91SAM9260_ID_PIOC] = (rt_isr_handler_t)at91_gpio_irq_handle;
rt_hw_interrupt_umask(AT91SAM9260_ID_PIOA);
rt_hw_interrupt_umask(AT91SAM9260_ID_PIOB);
rt_hw_interrupt_umask(AT91SAM9260_ID_PIOC);
}
/**
* This function will initialize hardware interrupt
*/
@ -141,6 +190,8 @@ void rt_hw_interrupt_init(void)
isr_table[idx] = (rt_isr_handler_t)rt_hw_interrupt_handle;
}
at91_gpio_irq_init();
/* init interrupt nest, and context in thread sp */
rt_interrupt_nest = 0;
rt_interrupt_from_thread = 0;
@ -148,14 +199,69 @@ void rt_hw_interrupt_init(void)
rt_thread_switch_interrput_flag = 0;
}
static void at91_gpio_irq_mask(int irq)
{
rt_uint32_t pin, pio, bank;
bank = (irq - AIC_IRQS)>>5;
if (bank == 0)
{
pio = AT91_PIOA;
}
else if (bank == 1)
{
pio = AT91_PIOB;
}
else if (bank == 2)
{
pio = AT91_PIOC;
}
else
return;
pin = 1 << ((irq - AIC_IRQS) & 31);
at91_sys_write(pio+PIO_IDR, pin);
}
/**
* This function will mask a interrupt.
* @param vector the interrupt number
*/
void rt_hw_interrupt_mask(int irq)
{
/* Disable interrupt on AIC */
at91_sys_write(AT91_AIC_IDCR, 1 << irq);
if (irq >= AIC_IRQS)
{
at91_gpio_irq_mask(irq);
}
else
{
/* Disable interrupt on AIC */
at91_sys_write(AT91_AIC_IDCR, 1 << irq);
}
}
static void at91_gpio_irq_umask(int irq)
{
rt_uint32_t pin, pio, bank;
bank = (irq - AIC_IRQS)>>5;
if (bank == 0)
{
pio = AT91_PIOA;
}
else if (bank == 1)
{
pio = AT91_PIOB;
}
else if (bank == 2)
{
pio = AT91_PIOC;
}
else
return;
pin = 1 << ((irq - AIC_IRQS) & 31);
at91_sys_write(pio+PIO_IER, pin);
}
/**
@ -164,8 +270,15 @@ void rt_hw_interrupt_mask(int irq)
*/
void rt_hw_interrupt_umask(int irq)
{
/* Enable interrupt on AIC */
at91_sys_write(AT91_AIC_IECR, 1 << irq);
if (irq >= AIC_IRQS)
{
at91_gpio_irq_umask(irq);
}
else
{
/* Enable interrupt on AIC */
at91_sys_write(AT91_AIC_IECR, 1 << irq);
}
}
/**