diff --git a/arch/arm/include/a1x/a10_irq.h b/arch/arm/include/a1x/a10_irq.h index 0963054652..23259db97d 100644 --- a/arch/arm/include/a1x/a10_irq.h +++ b/arch/arm/include/a1x/a10_irq.h @@ -144,9 +144,49 @@ #define A1X_IRQ_NINT 81 +/* Up to 32 external PIO interrupts */ + +#ifdef CONFIG_A1X_PIO_IRQ +# define A1X_PIO_EINT0 (A1X_IRQ_NINT+0) +# define A1X_PIO_EINT1 (A1X_IRQ_NINT+1) +# define A1X_PIO_EINT2 (A1X_IRQ_NINT+2) +# define A1X_PIO_EINT3 (A1X_IRQ_NINT+3) +# define A1X_PIO_EINT4 (A1X_IRQ_NINT+4) +# define A1X_PIO_EINT5 (A1X_IRQ_NINT+5) +# define A1X_PIO_EINT6 (A1X_IRQ_NINT+6) +# define A1X_PIO_EINT7 (A1X_IRQ_NINT+7) +# define A1X_PIO_EINT8 (A1X_IRQ_NINT+8) +# define A1X_PIO_EINT9 (A1X_IRQ_NINT+9) +# define A1X_PIO_EINT10 (A1X_IRQ_NINT+10) +# define A1X_PIO_EINT11 (A1X_IRQ_NINT+11) +# define A1X_PIO_EINT12 (A1X_IRQ_NINT+12) +# define A1X_PIO_EINT13 (A1X_IRQ_NINT+13) +# define A1X_PIO_EINT14 (A1X_IRQ_NINT+14) +# define A1X_PIO_EINT15 (A1X_IRQ_NINT+15) +# define A1X_PIO_EINT16 (A1X_IRQ_NINT+16) +# define A1X_PIO_EINT17 (A1X_IRQ_NINT+17) +# define A1X_PIO_EINT18 (A1X_IRQ_NINT+18) +# define A1X_PIO_EINT19 (A1X_IRQ_NINT+19) +# define A1X_PIO_EINT20 (A1X_IRQ_NINT+20) +# define A1X_PIO_EINT21 (A1X_IRQ_NINT+21) +# define A1X_PIO_EINT22 (A1X_IRQ_NINT+22) +# define A1X_PIO_EINT23 (A1X_IRQ_NINT+23) +# define A1X_PIO_EINT24 (A1X_IRQ_NINT+24) +# define A1X_PIO_EINT25 (A1X_IRQ_NINT+25) +# define A1X_PIO_EINT26 (A1X_IRQ_NINT+26) +# define A1X_PIO_EINT27 (A1X_IRQ_NINT+27) +# define A1X_PIO_EINT28 (A1X_IRQ_NINT+28) +# define A1X_PIO_EINT29 (A1X_IRQ_NINT+29) +# define A1X_PIO_EINT30 (A1X_IRQ_NINT+30) +# define A1X_PIO_EINT31 (A1X_IRQ_NINT+31) +# define A1X_PIO_NINT 32 +#else +# define A1X_PIO_NINT 0 +#endif + /* Total number of IRQ numbers */ -#define NR_IRQS 81 +#define NR_IRQS (A1X_IRQ_NINT + A1X_PIO_NINT) /**************************************************************************************** * Public Types diff --git a/arch/arm/src/a1x/Kconfig b/arch/arm/src/a1x/Kconfig index 111ce3b7a9..d50ba159c3 100644 --- a/arch/arm/src/a1x/Kconfig +++ b/arch/arm/src/a1x/Kconfig @@ -312,6 +312,14 @@ config A1X_GPU endmenu +config A1X_PIO_IRQ + bool "External PIO interrupts" + default n + ---help--- + Select to enable support for 32 external PIO interrupts. These will + be handled through a second level of interrupt decoding and will + otherwise appear as any other interrupt. + choice prompt "Boot device" default A1X_BOOT_SDCARD diff --git a/arch/arm/src/a1x/Make.defs b/arch/arm/src/a1x/Make.defs index 24f27a754c..ba487f209d 100644 --- a/arch/arm/src/a1x/Make.defs +++ b/arch/arm/src/a1x/Make.defs @@ -93,4 +93,4 @@ CHIP_ASRCS = # A1x-specific C source files -CHIP_CSRCS = a1x_boot.c a1x_irq.c +CHIP_CSRCS = a1x_boot.c a1x_irq.c a1x_pio.c diff --git a/arch/arm/src/a1x/a1x_irq.c b/arch/arm/src/a1x/a1x_irq.c index c281a95d18..037e469e80 100644 --- a/arch/arm/src/a1x/a1x_irq.c +++ b/arch/arm/src/a1x/a1x_irq.c @@ -51,6 +51,7 @@ #include "os_internal.h" #include "up_internal.h" +#include "a1x_pio.h" #include "a1x_irq.h" /**************************************************************************** @@ -174,6 +175,12 @@ void up_irqinitialize(void) current_regs = NULL; #ifndef CONFIG_SUPPRESS_INTERRUPTS +#ifdef CONFIG_A1X_PIO_IRQ + /* Initialize logic to support a second level of interrupt decoding for PIO pins. */ + + a1x_pio_irqinitialize(); +#endif + /* And finally, enable interrupts */ (void)irqenable(); @@ -339,6 +346,15 @@ void up_disable_irq(int irq) a1x_dumpintc("disable", irq); irqrestore(flags); } + +#ifdef CONFIG_A1X_PIO_IRQ + /* Perhaps this is a second level PIO interrupt */ + + else + { + a1x_pio_irqdisable(irq); + } +#endif } /**************************************************************************** @@ -378,6 +394,15 @@ void up_enable_irq(int irq) a1x_dumpintc("enable", irq); irqrestore(flags); } + +#ifdef CONFIG_A1X_PIO_IRQ + /* Perhaps this is a second level PIO interrupt */ + + else + { + a1x_pio_irqenable(irq); + } +#endif } /**************************************************************************** diff --git a/arch/arm/src/a1x/a1x_pio.c b/arch/arm/src/a1x/a1x_pio.c new file mode 100644 index 0000000000..32084dc336 --- /dev/null +++ b/arch/arm/src/a1x/a1x_pio.c @@ -0,0 +1,464 @@ +/**************************************************************************** + * arch/arm/src/a1x/a1x_pio.c + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include + +#include +#include +#include +#include + +#include +#include + +#include "up_internal.h" +#include "up_arch.h" + +#include "chip.h" +#include "a1x_pio.h" +#include "chip/a1x_pio.h" + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ +/**************************************************************************** + * Name: a1x_pio_pin + * + * Description: + * Return the port number + * + ****************************************************************************/ + +static inline int a1x_pio_port(pio_pinset_t cfgset) +{ + return ((cfgset & PIO_PORT_MASK) >> PIO_PORT_SHIFT); +} + +/**************************************************************************** + * Name: a1x_pio_pin + * + * Description: + * Return the pin bit position + * + ****************************************************************************/ + +static inline int a1x_pio_pin(pio_pinset_t cfgset) +{ + return 1 << ((cfgset & PIO_PIN_MASK) >> PIO_PIN_SHIFT); +} + +/**************************************************************************** + * Name: a1x_pio_interrupt + * + * Description: + * Initialize logic to support a second level of interrupt decoding for + * PIO pins. + * + ****************************************************************************/ + +#ifdef CONFIG_A1X_PIO_IRQ +static int a1x_pio_interrupt(int irq, void *context) +{ + uint32_t status; + uint32_t mask; + uint32_t pending; + int irq; + + /* Read the set of pending GPIO interrupts */ + + status = getreg32(A1X_PIO_INT_STA); + mask = getreg32(A1X_PIO_INT_CTL); + pending = status & mask; + + /* Re-dispatch all pending GPIO interrupts */ + + for (irq = A1X_PIO_EINT0; pending != 0 && irq <= A1X_PIO_EINT31; irq++) + { + /* Check for pending interrupts in any of the lower 16-bits */ + + if ((pending & 0x0000ffff) == 0) + { + irq += 16; + pending >>= 16; + } + + /* Check for pending interrupts in any of the lower 16-bits */ + + else if ((pending & 0x000000ff) == 0) + { + irq += 8; + pending >>= 8; + } + + /* Check for pending interrupts in any of the lower 4-bits */ + + else if ((pending & 0x0000000f) == 0) + { + irq += 4; + pending >>= 4; + } + + /* Check for pending interrupts in any of the lower 2-bits */ + + else if ((pending & 0x00000003) == 0) + { + irq += 2; + pending >>= 2; + } + + /* Check for pending interrupts in any of the last bits */ + + else + { + if ((pending & 0x00000001) == 0) + { + /* Yes.. dispatch the interrupt */ + + (void)arm_doirq(irq, regs); + } + + irq++; + pending >>= 1; + } + } +} +#endif + +/**************************************************************************** + * Global Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: a1x_pio_irqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for + * PIO pins. + * + ****************************************************************************/ + +#ifdef CONFIG_A1X_PIO_IRQ +void a1x_pio_irqinitialize(void) +{ + int ret; + + /* Disable all external PIO interrupts */ + + putreg32(0, A1X_PIO_INT_CTL); + + /* Attach the PIO interrupt handler */ + + ret = irq_attach(A1X_IRQ_PIO) + if (ret < 0) + { + return ret; + } + + /* And enable the PIO interrupt */ + + up_enable_irq(A1X_IRQ_PIO); +} +#endif + +/**************************************************************************** + * Name: a1x_configpio + * + * Description: + * Configure a PIO pin based on bit-encoded description of the pin. + * + ****************************************************************************/ + +int a1x_configpio(pio_pinset_t cfgset) +{ + unsigned int port = a1x_pioport(cfgset); + unsigned int pin = a1x_piopin(cfgset); + unsigned int shift; + unsigned int value; + uintptr_t cfgaddr; + uintptr_t puaddr; + uintptr_t drvaddr; + uintptr_t intaddr; + uintptr_t dataddr; + uint32_t regval; + irqstate_t flags; + + /* Disable interrupts to prohibit re-entrance. */ + + flags = irqsave(); + + /* Set the peripheral ID (0=input, 1=output) and interrupt mode */ + + switch (pin >> 3) + { + case 0: /* PIO 0-7 */ + cfgaddr = A1X_PIO_CFG0(port); + intaddr = A1X_PIO_INT_CFG0; + break; + + case 1: /* PIO 8-15 */ + cfgaddr = A1X_PIO_CFG1(port); + intaddr = A1X_PIO_INT_CFG1; + break; + + case 2: /* PIO 16-23 */ + cfgaddr = A1X_PIO_CFG2(port); + intaddr = A1X_PIO_INT_CFG2; + break; + + case 3: /* PIO 24-31 */ + cfgaddr = A1X_PIO_CFG3(port); + intaddr = A1X_PIO_INT_CFG3; + break; + + default: + return -EINVAL; + } + + value = (cfgset & PIO_MODE_MASK) >> PIO_MODE_SHIFT; + shift = (port & 7) << 4; + + regval = getreg32(cfgaddr); + regval &= ~(7 << shift); + regval |= (value << shift); + putreg32(regval, cfgaddr); + + /* Do not modify the INT MASK unless this pin is configured + * as an external PIO interrupt. + */ + + if ((cfgset & PIO_EINT_MASK) == PIO_EINT) + { + value = (cfgset & PIO_INT_MASK) >> PIO_INT_SHIFT; + + regval = getreg32(intaddr); + regval &= ~(7 << shift); + regval |= (value << shift); + putreg32(regval, intaddr); + } + + /* Set the pull-up/down and drive strength */ + + switch (pin >> 4) + { + case 0: /* PIO 0-15 */ + puaddr = A1X_PIO_PUL0(port); + drvaddr = A1X_PIO_DRV0(port); + break; + + case 1: /* PIO 16-31 */ + puaddr = A1X_PIO_PUL1(port); + drvaddr = A1X_PIO_DRV1(port); + break; + + default: + return -EINVAL; + } + + value = (cfgset & PIO_PULL_MASK) >> PIO_PULL_SHIFT; + shift = (port & 15) << 2; + + regval = getreg32(puaddr); + regval &= ~(3 << shift); + regval |= (value << shift); + putreg32(regval, puaddr); + + value = (cfgset & PIO_DRIVE_MASK) >> PIO_DRIVE_SHIFT; + + regval = getreg32(drvaddr); + regval &= ~(3 << shift); + regval |= (value << shift); + putreg32(regval, drvaddr); + + /* Set the output value (will have no effect on inputs) */ + + dataddr = A1X_PIO_DAT(port); + regval = getreg32(dataddr); + + if ((cfgset & PIO_OUTPUT_SET) != 0) + { + regval |= PIO_DAT(pin); + } + else + { + regval &= ~PIO_DAT(pin); + } + + putreg32(regval, dataddr); + + irqrestore(flags); + return OK; +} + +/**************************************************************************** + * Name: a1x_piowrite + * + * Description: + * Write one or zero to the selected PIO pin + * + ****************************************************************************/ + +void a1x_pio_write(pio_pinset_t pinset, bool value) +{ + unsigned int port = a1x_pio_port(pinset); + unsigned int pin = a1x_pio_pin(pinset); + irqstate_t flags; + uintptr_t regaddr; + uint32_t regval; + + /* Disable interrupts to prohibit re-entrance. */ + + flags = irqsave(); + + /* Set the output value (will have no effect on inputs */ + + regaddr = A1X_PIO_DAT(port); + regval = getreg32(regaddr); + + if (value) + { + regval |= PIO_DAT(pin); + } + else + { + regval &= ~PIO_DAT(pin); + } + + putreg32(regval, regaddr); + irqrestore(flags); +} + +/**************************************************************************** + * Name: a1x_pio_read + * + * Description: + * Read one or zero from the selected PIO pin + * + ****************************************************************************/ + +bool a1x_pio_read(pio_pinset_t pinset) +{ + unsigned int port = a1x_pio_port(pinset); + unsigned int pin = a1x_pio_pin(pinset); + uintptr_t regaddr; + uint32_t regval; + + /* Get the input value */ + + regaddr = A1X_PIO_DAT(port); + regval = getreg32(regaddr); + return ((regval & PIO_DAT(pin)) != 0); +} + +/************************************************************************************ + * Name: a1x_pio_irqenable + * + * Description: + * Enable the interrupt for specified PIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_A1X_PIO_IRQ +void a1x_pio_irqenable(int irq) +{ + irqstate_t flags; + uint32_t regval; + int pin; + + if (irq >= A1X_PIO_EINT0 && irq <= A1X_PIO_EINT31) + { + /* Convert the IRQ number to a bit position */ + + pin = irq - A1X_PIO_EINT0 + + /* Un-mask the interrupt be setting the corresponding bit in the PIO INT CTL + * register. + */ + + flags = irqsave(); + regval = getreg32(A1X_PIO_INT_CTL); + regval |= PIO_INT_CTL(irq); + irqrestore(flags); + } +} +#endif + +/************************************************************************************ + * Name: a1x_pio_irqdisable + * + * Description: + * Disable the interrupt for specified PIO IRQ + * + ************************************************************************************/ +#ifdef CONFIG_A1X_PIO_IRQ + +void a1x_pio_irqdisable(int irq) +{ + irqstate_t flags; + uint32_t regval; + int pin; + + if (irq >= A1X_PIO_EINT0 && irq <= A1X_PIO_EINT31) + { + /* Convert the IRQ number to a bit position */ + + pin = irq - A1X_PIO_EINT0 + + /* Mask the interrupt be clearning the corresponding bit in the PIO INT CTL + * register. + */ + + flags = irqsave(); + regval = getreg32(A1X_PIO_INT_CTL); + regval &= ~PIO_INT_CTL(irq); + irqrestore(flags); + } +} +#endif diff --git a/arch/arm/src/a1x/a1x_pio.h b/arch/arm/src/a1x/a1x_pio.h new file mode 100644 index 0000000000..be6636d3bf --- /dev/null +++ b/arch/arm/src/a1x/a1x_pio.h @@ -0,0 +1,324 @@ +/************************************************************************************ + * arch/arm/src/a1x/a1x_pio.h + * + * Copyright (C) 2013 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ************************************************************************************/ + +#ifndef __ARCH_ARM_SRC_A1X_A1X_PIO_H +#define __ARCH_ARM_SRC_A1X_A1X_PIO_H + +/************************************************************************************ + * Included Files + ************************************************************************************/ + +#include + +#include +#include + +#include "chip/a1x_pio.h" + +/************************************************************************************ + * Definitions + ************************************************************************************/ +/* Bit-encoded input to a1x_configpio() ********************************************/ + +/* 32-bit Encoding: + * + * 3322 2222 2222 1111 1111 11 + * 1098 7654 3210 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- ---- ---- ---- + * .... .... MMMM PPDD IIIV ...P PPPB BBBB + */ + +/* Input/Output mode: + * + * 3322 2222 2222 1111 1111 11 + * 1098 7654 3210 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- ---- ---- ---- + * .... .... MMMX .... .... .... .... .... + */ + +#define PIO_MODE_SHIFT (21) /* Bits 21-23: PIO mode */ +#define PIO_MODE_MASK (7 << PIO_MODE_SHIFT) +# define PIO_PERIPH0 (PIO_REG_CFG_INPUT << PIO_MODE_SHIFT) +# define PIO_PERIPH1 (PIO_REG_CFG_OUTPUT << PIO_MODE_SHIFT) +# define PIO_PERIPH2 (2 << PIO_MODE_SHIFT) +# define PIO_PERIPH3 (3 << PIO_MODE_SHIFT) +# define PIO_PERIPH4 (4 << PIO_MODE_SHIFT) +# define PIO_PERIPH5 (5 << PIO_MODE_SHIFT) +# define PIO_PERIPH6 (6 << PIO_MODE_SHIFT) +# define PIO_PERIPH7 (7 << PIO_MODE_SHIFT) + +# define PIO_INPUT PIO_PERIPH0 /* Input */ +# define PIO_OUTPUT PIO_PERIPH1 /* Output */ + +/* Bit 20 also specifies an external interrupt which must go with ID=6 */ + +#define PIO_EINT_BIT (1 << 20) /* Bit 20: External PIO interrupt */ +#define PIO_EINT_SHIFT (20) /* Bits 20-23: Extended PIO mode */ +#define PIO_EINT_MASK (15 << PIO_EINT_SHIFT) +# define PIO_EINT (PIO_EINT_BIT | PIO_PERIPH6) + +/* These bits set the pull-up/down configuration of the pin: + * + * 3322 2222 2222 1111 1111 11 + * 1098 7654 3210 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- ---- ---- ---- + * .... .... .... PP.. .... .... .... .... + */ + +#define PIO_PULL_SHIFT (18) /* Bits 18-19: PIO configuration bits */ +#define PIO_PULL_MASK (3 << PIO_PULL_SHIFT) +# define PIO_PULL_NONE (PIO_REG_PULL_NONE << PIO_PULL_SHIFT) +# define PIO_PULL_PULLUP (PIO_REG_PULL_UP << PIO_PULL_SHIFT) +# define PIO_PULL_PULLDOWN (PIO_REG_PULL_DOWN << PIO_PULL_SHIFT) + +/* Drive (outputs only): + * + * 3322 2222 2222 1111 1111 11 + * 1098 7654 3210 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- ---- ---- ---- + * .... .... .... ..DD .... .... .... .... + */ + +#define PIO_DRIVE_SHIFT (16) /* Bits 16-17: Drive strength */ +#define PIO_DRIVE_MASK (3 << PIO_DRIVE_SHIFT) +# define PIO_DRIVE_NONE (0 << PIO_DRIVE_SHIFT) +# define PIO_DRIVE_LOW (PIO_REG_DRV_LEVEL0 << PIO_DRIVE_SHIFT) +# define PIO_DRIVE_MEDLOW (PIO_REG_DRV_LEVEL1 << PIO_DRIVE_SHIFT) +# define PIO_DRIVE_MEDHIGH (PIO_REG_DRV_LEVEL2 << PIO_DRIVE_SHIFT) +# define PIO_DRIVE_HIGH (PIO_REG_DRV_LEVEL3 << PIO_DRIVE_SHIFT) + +/* Interrupt modes (inputs only): + * + * 3322 2222 2222 1111 1111 11 + * 1098 7654 3210 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- ---- ---- ---- + * .... .... ... .... III. .... .... .... + */ + +#define PIO_INT_SHIFT (13) /* Bits 13-15: PIO interrupt bits */ +#define PIO_INT_MASK (7 << PIO_INT_SHIFT) +# define PIO_INT_NONE (0 << PIO_INT_SHIFT) +# define PIO_INT_RISING (PIO_REG_INT_POSEDGE << PIO_INT_SHIFT) +# define PIO_INT_FALLING (PIO_REG_INT_NEGEDGE << PIO_INT_SHIFT) +# define PIO_INT_HIGHLEVEL (PIO_REG_INT_HILEVEL << PIO_INT_SHIFT) +# define PIO_INT_LOWLEVEL (PIO_REG_INT_LOWLEVEL << PIO_INT_SHIFT) +# define PIO_INT_BOTHEDGES (PIO_REG_INT_BOTHEDGES << PIO_INT_SHIFT) + +/* If the pin is an PIO output, then this identifies the initial output value: + * + * 3322 2222 2222 1111 1111 11 + * 1098 7654 3210 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- ---- ---- ---- + * .... .... .... .... ...V .... .... .... + * V + */ + +#define PIO_OUTPUT_SET (1 << 12) /* Bit 12: Initial value of output */ +#define PIO_OUTPUT_CLEAR (0) + +/* This identifies the PIO port: + * + * 3322 2222 2222 1111 1111 11 + * 1098 7654 3210 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- ---- ---- ---- + * .... .... .... .... .... ...P PPP. .... + * PPPP + */ + +#define PIO_PORT_SHIFT (5) /* Bit 5-8: Port number */ +#define PIO_PORT_MASK (15 << PIO_PORT_SHIFT) +# define PIO_PORT_PIOA (PIO_REG_PORTA << PIO_PORT_SHIFT) +# define PIO_PORT_PIOB (PIO_REG_PORTB << PIO_PORT_SHIFT) +# define PIO_PORT_PIOC (PIO_REG_PORTC << PIO_PORT_SHIFT) +# define PIO_PORT_PIOD (PIO_REG_PORTD << PIO_PORT_SHIFT) +# define PIO_PORT_PIOE (PIO_REG_PORTE << PIO_PORT_SHIFT) +# define PIO_PORT_PIOF (PIO_REG_PORTF << PIO_PORT_SHIFT) +# define PIO_PORT_PIOG (PIO_REG_PORTG << PIO_PORT_SHIFT) +# define PIO_PORT_PIOH (PIO_REG_PORTH << PIO_PORT_SHIFT) +# define PIO_PORT_PIOI (PIO_REG_PORTI << PIO_PORT_SHIFT) + +/* This identifies the bit in the port: + * + * 3322 2222 2222 1111 1111 11 + * 1098 7654 3210 9876 5432 1098 7654 3210 + * ---- ---- ---- ---- ---- ---- ---- ---- + * .... .... .... .... .... .... ...B BBBB + */ + +#define PIO_PIN_SHIFT (0) /* Bits 0-4: PIO number: 0-31 */ +#define PIO_PIN_MASK (31 << PIO_PIN_SHIFT) +#define PIO_PIN0 (0 << PIO_PIN_SHIFT) +#define PIO_PIN1 (1 << PIO_PIN_SHIFT) +#define PIO_PIN2 (2 << PIO_PIN_SHIFT) +#define PIO_PIN3 (3 << PIO_PIN_SHIFT) +#define PIO_PIN4 (4 << PIO_PIN_SHIFT) +#define PIO_PIN5 (5 << PIO_PIN_SHIFT) +#define PIO_PIN6 (6 << PIO_PIN_SHIFT) +#define PIO_PIN7 (7 << PIO_PIN_SHIFT) +#define PIO_PIN8 (8 << PIO_PIN_SHIFT) +#define PIO_PIN9 (9 << PIO_PIN_SHIFT) +#define PIO_PIN10 (10 << PIO_PIN_SHIFT) +#define PIO_PIN11 (11 << PIO_PIN_SHIFT) +#define PIO_PIN12 (12 << PIO_PIN_SHIFT) +#define PIO_PIN13 (13 << PIO_PIN_SHIFT) +#define PIO_PIN14 (14 << PIO_PIN_SHIFT) +#define PIO_PIN15 (15 << PIO_PIN_SHIFT) +#define PIO_PIN16 (16 << PIO_PIN_SHIFT) +#define PIO_PIN17 (17 << PIO_PIN_SHIFT) +#define PIO_PIN18 (18 << PIO_PIN_SHIFT) +#define PIO_PIN19 (19 << PIO_PIN_SHIFT) +#define PIO_PIN20 (20 << PIO_PIN_SHIFT) +#define PIO_PIN21 (21 << PIO_PIN_SHIFT) +#define PIO_PIN22 (22 << PIO_PIN_SHIFT) +#define PIO_PIN23 (23 << PIO_PIN_SHIFT) +#define PIO_PIN24 (24 << PIO_PIN_SHIFT) +#define PIO_PIN25 (25 << PIO_PIN_SHIFT) +#define PIO_PIN26 (26 << PIO_PIN_SHIFT) +#define PIO_PIN27 (27 << PIO_PIN_SHIFT) +#define PIO_PIN28 (28 << PIO_PIN_SHIFT) +#define PIO_PIN29 (29 << PIO_PIN_SHIFT) +#define PIO_PIN30 (30 << PIO_PIN_SHIFT) +#define PIO_PIN31 (31 << PIO_PIN_SHIFT) + +/************************************************************************************ + * Public Types + ************************************************************************************/ + +/* Must be big enough to hold the 32-bit encoding */ + +typedef uint32_t pio_pinset_t; + +/************************************************************************************ + * Inline Functions + ************************************************************************************/ + +#ifndef __ASSEMBLY__ + +/************************************************************************************ + * Public Data + ************************************************************************************/ + +#undef EXTERN +#if defined(__cplusplus) +#define EXTERN extern "C" +extern "C" +{ +#else +#define EXTERN extern +#endif + +/************************************************************************************ + * Public Function Prototypes + ************************************************************************************/ + +/************************************************************************************ + * Name: a1x_pio_irqinitialize + * + * Description: + * Initialize logic to support a second level of interrupt decoding for PIO pins. + * + ************************************************************************************/ + +#ifdef CONFIG_A1X_PIO_IRQ +void a1x_pio_irqinitialize(void); +#else +# define a1x_pio_irqinitialize() +#endif + +/************************************************************************************ + * Name: a1x_configpio + * + * Description: + * Configure a PIO pin based on bit-encoded description of the pin. + * + ************************************************************************************/ + +int a1x_configpio(pio_pinset_t cfgset); + +/************************************************************************************ + * Name: a1x_pio_write + * + * Description: + * Write one or zero to the selected PIO pin + * + ************************************************************************************/ + +void a1x_pio_write(pio_pinset_t pinset, bool value); + +/************************************************************************************ + * Name: a1x_pio_read + * + * Description: + * Read one or zero from the selected PIO pin + * + ************************************************************************************/ + +bool a1x_pio_read(pio_pinset_t pinset); + +/************************************************************************************ + * Name: a1x_pio_irqenable + * + * Description: + * Enable the interrupt for specified PIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_A1X_PIO_IRQ +void a1x_pio_irqenable(int irq); +#else +# define a1x_pio_irqenable(irq) +#endif + +/************************************************************************************ + * Name: a1x_pio_irqdisable + * + * Description: + * Disable the interrupt for specified PIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_A1X_PIO_IRQ +void a1x_pio_irqdisable(int irq); +#else +# define a1x_pio_irqdisable(irq) +#endif + +#undef EXTERN +#if defined(__cplusplus) +} +#endif + +#endif /* __ASSEMBLY__ */ +#endif /* __ARCH_ARM_SRC_A1X_A1X_PIO_H */ diff --git a/arch/arm/src/a1x/chip/a1x_pio.h b/arch/arm/src/a1x/chip/a1x_pio.h index e1c2f3640b..48cc2bd9d7 100644 --- a/arch/arm/src/a1x/chip/a1x_pio.h +++ b/arch/arm/src/a1x/chip/a1x_pio.h @@ -47,34 +47,34 @@ * Pre-processor Definitions ************************************************************************************/ -#define PIO_PORTA 0 -#define PIO_PORTB 1 -#define PIO_PORTC 2 -#define PIO_PORTD 3 -#define PIO_PORTE 4 -#define PIO_PORTF 5 -#define PIO_PORTG 6 -#define PIO_PORTH 7 -#define PIO_PORTI 8 -#define PIO_PORTS 9 +#define PIO_REG_PORTA 0 +#define PIO_REG_PORTB 1 +#define PIO_REG_PORTC 2 +#define PIO_REG_PORTD 3 +#define PIO_REG_PORTE 4 +#define PIO_REG_PORTF 5 +#define PIO_REG_PORTG 6 +#define PIO_REG_PORTH 7 +#define PIO_REG_PORTI 8 +#define PIO_REG_PORTS 9 -#define PIO_CFG_INPUT 0 -#define PIO_CFG_OUTPUT 1 +#define PIO_REG_CFG_INPUT 0 +#define PIO_REG_CFG_OUTPUT 1 -#define PIO_DRV_LEVEL0 0 -#define PIO_DRV_LEVEL1 1 -#define PIO_DRV_LEVEL2 2 -#define PIO_DRV_LEVEL3 3 +#define PIO_REG_DRV_LEVEL0 0 +#define PIO_REG_DRV_LEVEL1 1 +#define PIO_REG_DRV_LEVEL2 2 +#define PIO_REG_DRV_LEVEL3 3 -#define PIO_PULL_NONE 0 -#define PIO_PULL_UP 1 -#define PIO_PULL_DOWN 2 +#define PIO_REG_PULL_NONE 0 +#define PIO_REG_PULL_UP 1 +#define PIO_REG_PULL_DOWN 2 -#define PIO_INT_POSEDGE 0 -#define PIO_INT_NEGEDGE 1 -#define PIO_INT_HILEVEL 2 -#define PIO_INT_LOWLEVEL 3 -#define PIO_INT_BOTHEDGES 4 +#define PIO_REG_INT_POSEDGE 0 +#define PIO_REG_INT_NEGEDGE 1 +#define PIO_REG_INT_HILEVEL 2 +#define PIO_REG_INT_LOWLEVEL 3 +#define PIO_REG_INT_BOTHEDGES 4 /* Register offsets *****************************************************************/ @@ -144,14 +144,6 @@ #define PIO_CFG3_MASK(n)) (7 << PIO_CFG3_SHIFT(n)) # define PIO_CFG3(m,v) ((uint32_t)(v) << PIO_CFG3_SHIFT(n)) -/* Then bring-in CPU-specific PIO CFG register definitions */ - -#if defined(CONFIG_ARCH_CHIP_A10) -# include "chip/a10_piocfg.h" -#else -# error Unrecognized A1X architecture -#endif - /* Port n Data Register, n=0-9 */ #define PIO_DAT(n) (1 << (n)) /* PA data, n=0-31 */ @@ -160,25 +152,25 @@ #define PIO_DRV0_SHIFT(n) ((n) << 1) /* PA DRV0, n=0-15 */ #define PIO_DRV0_MASK(n) (3 << PIO_DRV0_SHIFT(n)) -# define PIO_DRV0_MASK(n,v) ((uint32_t)(v) << PIO_DRV0_SHIFT(n)) +# define PIO_DRV0(n,v) ((uint32_t)(v) << PIO_DRV0_SHIFT(n)) /* Port n Multi-Driving Register 1, n=0-9 */ #define PIO_DRV1_SHIFT(n) (((n) - 16) << 1) /* PA DRV1, n=16-31 */ #define PIO_DRV1_MASK(n) (3 << PIO_DRV1_SHIFT(n)) -# define PIO_DRV1_MASK(n,v) ((uint32_t)(v) << PIO_DRV1_SHIFT(n)) +# define PIO_DRV1(n,v) ((uint32_t)(v) << PIO_DRV1_SHIFT(n)) /* Port n Pull Register 0, n=0-9 */ #define PIO_PUL0_SHIFT(n) ((n) << 1) /* PA PUL0, n=0-15 */ #define PIO_PUL0_MASK(n) (3 << PIO_PUL0_SHIFT(n)) -# define PIO_PUL0_MASK(n,v) ((uint32_t)(v) << PIO_PUL0_SHIFT(n)) +# define PIO_PUL0(n,v) ((uint32_t)(v) << PIO_PUL0_SHIFT(n)) /* Port n Pull Register 1, n=0-9 */ #define PIO_PUL1_SHIFT(n) (((n) - 16) << 1) /* PA PUL1, n=16-31 */ #define PIO_PUL1_MASK(n) (3 << PIO_PUL1_SHIFT(n)) -# define PIO_PUL1_MASK(n,v) ((uint32_t)(v) << PIO_PUL1_SHIFT(n)) +# define PIO_PUL1(n,v) ((uint32_t)(v) << PIO_PUL1_SHIFT(n)) /* PIO Interrupt Configure Register 0 */ diff --git a/arch/arm/src/sama5/sam_pio.h b/arch/arm/src/sama5/sam_pio.h index e09f9a21ca..5e04e92a87 100644 --- a/arch/arm/src/sama5/sam_pio.h +++ b/arch/arm/src/sama5/sam_pio.h @@ -1,6 +1,6 @@ /************************************************************************************ * arch/arm/src/sama5/sam_pio.h - * Parallel Input/Output (PIO) definitions for the SAM4S + * Parallel Input/Output (PIO) definitions for the SAMA5 * * Copyright (C) 2013 Gregory Nutt. All rights reserved. * Author: Gregory Nutt @@ -330,10 +330,5 @@ int sam_dumppio(uint32_t pinset, const char *msg); } #endif -#undef EXTERN -#if defined(__cplusplus) -} -#endif - #endif /* __ASSEMBLY__ */ #endif /* __ARCH_ARM_SRC_SAMA5_SAM_PIO_H */