BCM2708: Fleshes out GPIO interrupt logic.
This commit is contained in:
parent
63b93a9fba
commit
25079a9c93
@ -193,7 +193,9 @@
|
||||
/* Second level GPIO interrupts */
|
||||
|
||||
#ifdef CONFIG_BCM2708_GPIO_IRQ
|
||||
# define BCM_IRQ_GPIO(n) (NR_INTERRUPTS + (n))
|
||||
# define BCM_IRQ_GPIO(n) (NR_INTERRUPTS + (n)) /* IRQ number of pin n */
|
||||
# define BCM_IRQ_GPIO0_FIRST (NR_INTERRUPTS) /* IRQ number of first GPIO0 interrupt */
|
||||
# define BCM_IRQ_GPIO1_FIRST (NR_INTERRUPTS + 32) /* IRQ number of first GPIO1 interrupt */
|
||||
# define NR_GPIOINTS (54)
|
||||
#else
|
||||
# define NR_GPIOINTS (0)
|
||||
|
@ -237,7 +237,7 @@ void bcm_gpio_write(gpio_pinset_t pinset, bool value)
|
||||
regaddr = BCM_GPIO_GPCLR(pin);
|
||||
}
|
||||
|
||||
putreg32(BCM_GPIO_GPSET0_SET(pin), regaddr);
|
||||
putreg32(BCM_GPIO_GPSET_SET(pin), regaddr);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
@ -252,7 +252,7 @@ bool bcm_gpio_read(gpio_pinset_t pinset)
|
||||
{
|
||||
unsigned int pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT;
|
||||
uintptr_t regaddr = BCM_GPIO_GPLEV(pin);
|
||||
uint32_t mask = BCM_GPIO_GPLEV0_LEV(pin);
|
||||
uint32_t mask = BCM_GPIO_GPLEV_LEV(pin);
|
||||
|
||||
return (getreg32(regaddr) & mask) != 0;
|
||||
}
|
||||
|
@ -261,46 +261,34 @@ void bcm_gpio_write(gpio_pinset_t pinset, bool value);
|
||||
|
||||
bool bcm_gpio_read(gpio_pinset_t pinset);
|
||||
|
||||
/************************************************************************************
|
||||
* Name: bcm_gpio_irqconfig
|
||||
*
|
||||
* Description:
|
||||
* Configure an interrupt for the specified GPIO pin.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef CONFIG_BCM2708_GPIO_IRQ
|
||||
void bcm_gpio_irqconfig(gpio_pinset_t pinset);
|
||||
#else
|
||||
# define bcm_gpio_irqconfig(pinset)
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: bcm_gpio_irqenable
|
||||
*
|
||||
* Description:
|
||||
* Enable the interrupt for specified GPIO IRQ
|
||||
* Configure interrupt event detection for the specified GPIO pin. This
|
||||
* effective enables the pin interrupts.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_BCM2708_GPIO_IRQ
|
||||
void bcm_gpio_irqenable(int irq);
|
||||
void bcm_gpio_irqenable(gpio_pinset_t pinset);
|
||||
#else
|
||||
# define bcm_gpio_irqenable(irq)
|
||||
# define bcm_gpio_irqenable(p)
|
||||
#endif
|
||||
|
||||
/************************************************************************************
|
||||
* Name: bcm_gpio_irqdisable
|
||||
*
|
||||
* Description:
|
||||
* Disable the interrupt for specified GPIO IRQ
|
||||
* Reset interrupt event detection for the specified GPIO pin. This
|
||||
* effective disables the pin interrupts.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
#ifdef CONFIG_BCM2708_GPIO_IRQ
|
||||
void bcm_gpio_irqdisable(int irq);
|
||||
void bcm_gpio_irqdisable(gpio_pinset_t pinset);
|
||||
#else
|
||||
# define bcm_gpio_irqdisable(irq)
|
||||
# define bcm_gpio_irqdisable(p)
|
||||
#endif
|
||||
|
||||
#undef EXTERN
|
||||
|
@ -44,60 +44,332 @@
|
||||
|
||||
#ifdef CONFIG_BCM2708_GPIO_IRQ
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm_gpio_risingedge
|
||||
*
|
||||
* Description:
|
||||
* Set/clear rising edge detection.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void bcm_gpio_risingedge(unsigned int pin, gpio_pinset_t pinset)
|
||||
{
|
||||
uintptr_t regaddr = BCM_GPIO_GPREN(pin);
|
||||
uint32_t mask = BCM_GPIO_GPREN_REN(pin;
|
||||
|
||||
if ((pinset & GPIO_INT_MASK) == GPIO_INT_RISING
|
||||
{
|
||||
modifiyreg32(regaddr, 0, mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
modifiyreg32(regaddr, mask, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm_gpio_fallingedge
|
||||
*
|
||||
* Description:
|
||||
* Set/clear falling edge detection.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void bcm_gpio_fallingedge(unsigned int pin, gpio_pinset_t pinset)
|
||||
{
|
||||
uintptr_t regaddr = BCM_GPIO_GPFEN(pin);
|
||||
uint32_t mask = BCM_GPIO_GPFEN_FEN(pin;
|
||||
|
||||
if ((pinset & GPIO_INT_MASK) == GPIO_INT_FALLING
|
||||
{
|
||||
modifiyreg32(regaddr, 0, mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
modifiyreg32(regaddr, mask, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm_gpio_highlevel
|
||||
*
|
||||
* Description:
|
||||
* Set/clear high level detection.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void bcm_gpio_highlevel(unsigned int pin, gpio_pinset_t pinset)
|
||||
{
|
||||
uintptr_t regaddr = BCM_GPIO_GPHEN(pin);
|
||||
uint32_t mask = BCM_GPIO_GPHEN_HEN(pin;
|
||||
|
||||
if ((pinset & GPIO_INT_MASK) == GPIO_INT_HIGHLEVEL
|
||||
{
|
||||
modifiyreg32(regaddr, 0, mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
modifiyreg32(regaddr, mask, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm_gpio_lowlevel
|
||||
*
|
||||
* Description:
|
||||
* Set/clear low level detection.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void bcm_gpio_lowlevel(unsigned int pin, gpio_pinset_t pinset)
|
||||
{
|
||||
uintptr_t regaddr = BCM_GPIO_GPLEN(pin);
|
||||
uint32_t mask = BCM_GPIO_GPHEN_HEN(pin;
|
||||
|
||||
if ((pinset & GPIO_INT_MASK) == GPIO_INT_LOWLEVEL
|
||||
{
|
||||
modifiyreg32(regaddr, 0, mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
modifiyreg32(regaddr, mask, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm_gpio_async_risingedge
|
||||
*
|
||||
* Description:
|
||||
* Set/clear asynchronous rising edge detection.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void bcm_gpio_async_risingedge(unsigned int pin, gpio_pinset_t pinset)
|
||||
{
|
||||
uintptr_t regaddr = BCM_GPIO_GPAREN(pin);
|
||||
uint32_t mask = BCM_GPIO_GPAREN_AREN(pin;
|
||||
|
||||
if ((pinset & GPIO_INT_MASK) == GPIO_INT_ASYNCHRISING
|
||||
{
|
||||
modifiyreg32(regaddr, 0, mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
modifiyreg32(regaddr, mask, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm_gpio_async_fallingedge
|
||||
*
|
||||
* Description:
|
||||
* Set/clear asynchronous falling edge detection.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void bcm_gpio_async_fallingedge(unsigned int pin, gpio_pinset_t pinset)
|
||||
{
|
||||
uintptr_t regaddr = BCM_GPIO_GPAFEN(pin);
|
||||
uint32_t mask = BCM_GPIO_GPAFEN_AFEN(pin;
|
||||
|
||||
if ((pinset & GPIO_INT_MASK) == GPIO_INT_ASYNCHFALLING
|
||||
{
|
||||
modifiyreg32(regaddr, 0, mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
modifiyreg32(regaddr, mask, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm_gpio_async_fallingedge
|
||||
*
|
||||
* Description:
|
||||
* Set/clear falling edge detection.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
static void bcm_gpio_async_fallingedge(unsigned int pin, gpio_pinset_t pinset)
|
||||
{
|
||||
uintptr_t regaddr = BCM_GPIO_GPAFEN(pin);
|
||||
uint32_t mask = BCM_GPIO_GPAFEN_AFEN(pin;
|
||||
|
||||
if ((pinset & GPIO_INT_MASK) == GPIO_INT_ASYNCHFALLING
|
||||
{
|
||||
modifiyreg32(regaddr, 0, mask);
|
||||
}
|
||||
else
|
||||
{
|
||||
modifiyreg32(regaddr, mask, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm_gpio0_interrupt
|
||||
*
|
||||
* Description:
|
||||
* GPIO0 interrupt handler
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int bcm_gpio0_interrupt(int irq, FAR void *context, FAR void *arg)
|
||||
{
|
||||
uint32_t eds;
|
||||
uint32_t mask;
|
||||
int i;
|
||||
|
||||
/* Clear all pending interrpts */
|
||||
|
||||
eds = getreg32(BCM_GPIO_GPEDS0);
|
||||
putreg32(eds, BCM_GPIO_GPEDS0);
|
||||
|
||||
/* Then process each pending GPIO interrupt */
|
||||
|
||||
for (i = 0; i < 32 && eds != NULL; i++)
|
||||
{
|
||||
mask = (uint32_t)1 << i;
|
||||
if ((eds & mask) != 0)
|
||||
{
|
||||
/* Remove the pending interrupt bit from the mask */
|
||||
|
||||
eds &= ~mask;
|
||||
|
||||
/* And disptach the GPIO interrupt to the register handler */
|
||||
|
||||
irq_dispatch(BCM_IRQ_GPIO0_FIRST + i, context);
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: bcm_gpio1_interrupt
|
||||
*
|
||||
* Description:
|
||||
* GPIO1 interrupt handler
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
int bcm_gpio1_interrupt(int irq, FAR void *context, FAR void *arg)
|
||||
{
|
||||
uint32_t eds;
|
||||
uint32_t mask;
|
||||
int i;
|
||||
|
||||
/* Clear all pending interrpts */
|
||||
|
||||
eds = getreg32(BCM_GPIO_GPEDS1);
|
||||
putreg32(eds, BCM_GPIO_GPEDS1);
|
||||
|
||||
/* Then process each pending GPIO interrupt */
|
||||
|
||||
for (i = 0; i < 32 && eds != NULL; i++)
|
||||
{
|
||||
mask = (uint32_t)1 << i;
|
||||
if ((eds & mask) != 0)
|
||||
{
|
||||
/* Remove the pending interrupt bit from the mask */
|
||||
|
||||
eds &= ~mask;
|
||||
|
||||
/* And disptach the GPIO interrupt to the register handler */
|
||||
|
||||
irq_dispatch(BCM_IRQ_GPIO1_FIRST + i, context);
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: bcm_gpio_irqinitialize
|
||||
*
|
||||
* Description:
|
||||
* Initialize logic to support a second level of interrupt decoding for GPIO pins.
|
||||
* Initialize logic to support a second level of interrupt decoding for
|
||||
* GPIO pins.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
void bcm_gpio_irqinitialize(void)
|
||||
{
|
||||
#warning Missing Logic
|
||||
/* Disabled all event detections */
|
||||
|
||||
putreg32(0, BCM_GPIO_GPREN0);
|
||||
putreg32(0, BCM_GPIO_GPREN1);
|
||||
putreg32(0, BCM_GPIO_GPFEN0);
|
||||
putreg32(0, BCM_GPIO_GPFEN1);
|
||||
putreg32(0, BCM_GPIO_GPHEN0);
|
||||
putreg32(0, BCM_GPIO_GPHEN1);
|
||||
putreg32(0, BCM_GPIO_GPLEN0);
|
||||
putreg32(0, BCM_GPIO_GPLEN1);
|
||||
putreg32(0, BCM_GPIO_GPAREN0);
|
||||
putreg32(0, BCM_GPIO_GPAREN1);
|
||||
putreg32(0, BCM_GPIO_GPAFEN0);
|
||||
putreg32(0, BCM_GPIO_GPAFEN1);
|
||||
|
||||
/* Attach and enable the GPIO interrupt handlers */
|
||||
|
||||
(void) irq_attach(BCM_IRQ_GPIO0, bcm_gpio0_interrupt);
|
||||
(void) irq_attach(BCM_IRQ_GPIO1, bcm_gpio1_interrupt);
|
||||
|
||||
up_enable_irq(BCM_IRQ_GPIO0);
|
||||
up_enable_irq(BCM_IRQ_GPIO1);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: bcm_gpio_irqconfig
|
||||
*
|
||||
* Description:
|
||||
* Configure an interrupt for the specified GPIO pin.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
void bcm_gpio_irqconfig(gpio_pinset_t pinset)
|
||||
{
|
||||
#warning Missing Logic
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
/****************************************************************************
|
||||
* Name: bcm_gpio_irqenable
|
||||
*
|
||||
* Description:
|
||||
* Enable the interrupt for specified GPIO IRQ
|
||||
* Configure interrupt event detection for the specified GPIO pin. This
|
||||
* effective enables the pin interrupts.
|
||||
*
|
||||
************************************************************************************/
|
||||
****************************************************************************/
|
||||
|
||||
void bcm_gpio_irqenable(int irq)
|
||||
void bcm_gpio_irqenable(gpio_pinset_t pinset)
|
||||
{
|
||||
#warning Missing Logic
|
||||
unsigned int pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT;
|
||||
|
||||
/* Configure pin detection settings */
|
||||
|
||||
bcm_gpio_risingedge(pin, pinset);
|
||||
bcm_gpio_fallingedge(pin, pinset);
|
||||
bcm_gpio_highlevel(pin, pinset);
|
||||
bcm_gpio_lowlevel(pin, pinset);
|
||||
bcm_gpio_async_risingedge(pin, pinset);
|
||||
bcm_gpio_async_fallingedge(pin, pinset);
|
||||
}
|
||||
|
||||
/************************************************************************************
|
||||
* Name: bcm_gpio_irqdisable
|
||||
*
|
||||
* Description:
|
||||
* Disable the interrupt for specified GPIO IRQ
|
||||
* Reset interrupt event detection for the specified GPIO pin. This
|
||||
* effective disables the pin interrupts.
|
||||
*
|
||||
************************************************************************************/
|
||||
|
||||
void bcm_gpio_irqdisable(int irq)
|
||||
void bcm_gpio_irqdisable(gpio_pinset_t pinset);
|
||||
{
|
||||
#warning Missing Logic
|
||||
unsigned int pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT;
|
||||
|
||||
/* Reset pin detection settings */
|
||||
|
||||
bcm_gpio_risingedge(pin, 0);
|
||||
bcm_gpio_fallingedge(pin, 0);
|
||||
bcm_gpio_highlevel(pin, 0);
|
||||
bcm_gpio_lowlevel(pin, 0);
|
||||
bcm_gpio_async_risingedge(pin, 0);
|
||||
bcm_gpio_async_fallingedge(pin, 0);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BCM2708_GPIO_IRQ */
|
||||
|
@ -254,16 +254,16 @@
|
||||
# define BCM_GPIO_GPFSEL_FSELx9_ALT4 (3 << BCM_GPIO_GPFSEL_FSELx9_SHIFT)
|
||||
# define BCM_GPIO_GPFSEL_FSELx9_ALT5 (2 << BCM_GPIO_GPFSEL_FSELx9_SHIFT)
|
||||
|
||||
#define BCM_GPIO_GPSET0_SET(n) (1 << ((n) & 0x1f))
|
||||
#define BCM_GPIO_GPCLR0_CLR(n) (1 << ((n) & 0x1f))
|
||||
#define BCM_GPIO_GPLEV0_LEV(n) (1 << ((n) & 0x1f))
|
||||
#define BCM_GPIO_GPEDS0_EDS(n) (1 << ((n) & 0x1f))
|
||||
#define BCM_GPIO_GPREN0_REN(n) (1 << ((n) & 0x1f))
|
||||
#define BCM_GPIO_GPFEN0_FEN(n) (1 << ((n) & 0x1f))
|
||||
#define BCM_GPIO_GPHEN0_HEN(n) (1 << ((n) & 0x1f))
|
||||
#define BCM_GPIO_GPLEN0_LEN(n) (1 << ((n) & 0x1f))
|
||||
#define BCM_GPIO_GPAREN0_AREN(n) (1 << ((n) & 0x1f))
|
||||
#define BCM_GPIO_GPAFEN0_AFEN(n) (1 << ((n) & 0x1f))
|
||||
#define BCM_GPIO_GPSET_SET(n) (1 << ((n) & 0x1f))
|
||||
#define BCM_GPIO_GPCLR_CLR(n) (1 << ((n) & 0x1f))
|
||||
#define BCM_GPIO_GPLEV_LEV(n) (1 << ((n) & 0x1f))
|
||||
#define BCM_GPIO_GPEDS_EDS(n) (1 << ((n) & 0x1f))
|
||||
#define BCM_GPIO_GPREN_REN(n) (1 << ((n) & 0x1f))
|
||||
#define BCM_GPIO_GPFEN_FEN(n) (1 << ((n) & 0x1f))
|
||||
#define BCM_GPIO_GPHEN_HEN(n) (1 << ((n) & 0x1f))
|
||||
#define BCM_GPIO_GPLEN_LEN(n) (1 << ((n) & 0x1f))
|
||||
#define BCM_GPIO_GPAREN_AREN(n) (1 << ((n) & 0x1f))
|
||||
#define BCM_GPIO_GPAFEN_AFEN(n) (1 << ((n) & 0x1f))
|
||||
|
||||
#define BCM_GPIO_GPPUD_PUD_SHIFT 0 /* bit 0-1: Pull-up/down register */
|
||||
#define BCM_GPIO_GPPUD_PUD_MASK (3 << BCM_GPIO_GPPUD_PUD_SHIFT)
|
||||
|
Loading…
Reference in New Issue
Block a user