diff --git a/arch/arm/src/sam3u/sam3u_pio.c b/arch/arm/src/sam3u/sam3u_pio.c index 79e36c6dfe..833ff5e1fd 100644 --- a/arch/arm/src/sam3u/sam3u_pio.c +++ b/arch/arm/src/sam3u/sam3u_pio.c @@ -2,7 +2,7 @@ * arch/arm/src/sam3u/sam3u_pio.c * * Copyright (C) 2010 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt + * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/arch/mips/src/pic32mx/Make.defs b/arch/mips/src/pic32mx/Make.defs index 3a46c30782..f9d59cc729 100644 --- a/arch/mips/src/pic32mx/Make.defs +++ b/arch/mips/src/pic32mx/Make.defs @@ -2,7 +2,7 @@ # arch/mips/src/pic32mx/Make.defs # # Copyright (C) 2011 Gregory Nutt. All rights reserved. -# Author: Gregory Nutt +# Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without # modification, are permitted provided that the following conditions @@ -61,8 +61,11 @@ endif # Required PIC32MX files CHIP_ASRCS = -CHIP_CSRCS = pic32mx-irq.c pic32mx-decodeirq.c pic32mx-dobev.c pic32mx-lowconsole.c \ - pic32mx-lowinit.c pic32mx-serial.c pic32mx-timerisr.c +CHIP_CSRCS = pic32mx-irq.c pic32mx-decodeirq.c pic32mx-dobev.c pic32mx-gpio.c \ + pic32mx-lowconsole.c pic32mx-lowinit.c pic32mx-serial.c pic32mx-timerisr.c # Configuration-dependent PIC32MX files +ifeq ($(CONFIG_GPIO_IRQ),y) +CHIP_CSRCS += up_gpioirq.c +endif diff --git a/arch/mips/src/pic32mx/pic32mx-config.h b/arch/mips/src/pic32mx/pic32mx-config.h index 2eee06ae6d..689a6d2612 100644 --- a/arch/mips/src/pic32mx/pic32mx-config.h +++ b/arch/mips/src/pic32mx/pic32mx-config.h @@ -354,14 +354,14 @@ # error "CONFIG_PIC32MX_UART2PRIO is too large" #endif -#ifndef CONFIG_PIC32MX_CN /* Input Change Interrupt */ -# define CONFIG_PIC32MX_CN (INT_ICP_MID_PRIORITY << 2) +#ifndef CONFIG_PIC32MX_CNPRIO /* Input Change Interrupt */ +# define CONFIG_PIC32MX_CNPRIO (INT_ICP_MID_PRIORITY << 2) #endif -#if CONFIG_PIC32MX_CN < 4 -# error "CONFIG_PIC32MX_CN is too small" +#if CONFIG_PIC32MX_CNPRIO < 4 +# error "CONFIG_PIC32MX_CNPRIO is too small" #endif -#if CONFIG_PIC32MX_CN > 31 -# error "CONFIG_PIC32MX_CN is too large" +#if CONFIG_PIC32MX_CNPRIO > 31 +# error "CONFIG_PIC32MX_CNPRIO is too large" #endif #ifndef CONFIG_PIC32MX_ADCPRIO /* ADC1 Convert Done */ diff --git a/arch/mips/src/pic32mx/pic32mx-decodeirq.c b/arch/mips/src/pic32mx/pic32mx-decodeirq.c index f8a0a28bd0..400cc92b94 100644 --- a/arch/mips/src/pic32mx/pic32mx-decodeirq.c +++ b/arch/mips/src/pic32mx/pic32mx-decodeirq.c @@ -2,7 +2,7 @@ * arch/mips/src/pic32mx/pic32mx-decodeirq.c * * Copyright (C) 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt + * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/arch/mips/src/pic32mx/pic32mx-gpio.c b/arch/mips/src/pic32mx/pic32mx-gpio.c new file mode 100644 index 0000000000..380982010c --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-gpio.c @@ -0,0 +1,298 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/pic32mx-gpio.c + * + * Copyright (C) 2011 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_arch.h" +#include "pic32mx-ioport.h" +#include "pic32mx-internal.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define GPIO_NPORTS 7 + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const uintptr_t g_gpiobase[GPIO_NPORTS] = +{ + PIC32MX_IOPORTA_K1BASE, PIC32MX_IOPORTB_K1BASE, PIC32MX_IOPORTC_K1BASE, + PIC32MX_IOPORTD_K1BASE, PIC32MX_IOPORTE_K1BASE, PIC32MX_IOPORTF_K1BASE, + PIC32MX_IOPORTG_K1BASE +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: Inline PIN set field extractors + ****************************************************************************/ + +static inline bool pic32mx_output(uint16_t pinset) +{ + return ((pinset & GPIO_OUTPUT) != 0); +} + +static inline bool pic32mx_opendrain(uint16_t pinset) +{ + return ((pinset & GPIO_MODE_MASK) == GPIO_OPENDRAN); +} + +static inline bool pic32mx_outputhigh(uint16_t pinset) +{ + return ((pinset & GPIO_VALUE_MASK) != 0); +} + +static inline bool pic32mx_value(uint16_t pinset) +{ + return ((pinset & GPIO_VALUE_MASK) != GPIO_VALUE_ZERO); +} + +static inline unsigned int pic32mx_portno(uint16_t pinset) +{ + return ((pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT); +} + +static inline unsigned int pic32mx_pinno(uint16_t pinset) +{ + return ((pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mx_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin (the + * interrupt will be configured when pic32mx_attach() is called. + * + * Returned Value: + * OK on success; negated errno on failure. + * + ****************************************************************************/ + +int pic32mx_configgpio(uint16_t cfgset) +{ + unsigned int port = pic32mx_portno(cfgset); + unsigned int pin = pic32mx_pinno(cfgset); + uintptr_t base; + + /* Verify that the port number is within range */ + + if (port < GPIO_NPORTS) + { + /* Get the base address of the ports */ + + base = g_gpiobase[port]; + + /* Is this an input or an output? */ + + sched_lock(); + if (pic32mx_output(cfgset)) + { + /* It is an output; set the corresponding bit in the TRIS register */ + + putreg32(1 << pin, base + PIC32MX_IOPORT_TRISCLR_OFFSET); + + /* Is it an open drain output? */ + + if (pic32mx_opendrain(cfgset)) + { + /* It is an open drain output. Set the corresponding bit in + * the ODC register. + */ + + putreg32(1 << pin, base + PIC32MX_IOPORT_ODCSET_OFFSET); + } + else + { + /* Is is a normal output. Clear the corresponding bit in the + * ODC register. + */ + + putreg32(1 << pin, base + PIC32MX_IOPORT_ODCCLR_OFFSET); + } + + /* Set the initial output value */ + + pic32mx_gpiowrite(cfgset, pic32mx_outputhigh(cfgset)); + } + else + { + /* It is an input; clear the corresponding bit in the TRIS + * register. + */ + + putreg32(1 << pin, base + PIC32MX_IOPORT_TRISCLR_OFFSET); + putreg32(1 << pin, base + PIC32MX_IOPORT_ODCCLR_OFFSET); + } + + sched_unlock(); + return OK; + } + + return -EINVAL; +} + +/**************************************************************************** + * Name: pic32mx_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void pic32mx_gpiowrite(uint16_t pinset, bool value) +{ + unsigned int port = pic32mx_portno(pinset); + unsigned int pin = pic32mx_pinno(pinset); + uintptr_t base; + + /* Verify that the port number is within range */ + + if (port < GPIO_NPORTS) + { + /* Get the base address of the ports */ + + base = g_gpiobase[port]; + + /* Set or clear the output */ + + if (value) + { + putreg32(1 << pin, base + PIC32MX_IOPORT_PORTSET_OFFSET); + } + else + { + putreg32(1 << pin, base + PIC32MX_IOPORT_PORTCLR_OFFSET); + } + } +} + +/**************************************************************************** + * Name: pic32mx_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool pic32mx_gpioread(uint16_t pinset) +{ + unsigned int port = pic32mx_portno(pinset); + unsigned int pin = pic32mx_pinno(pinset); + uintptr_t base; + + /* Verify that the port number is within range */ + + if (port < GPIO_NPORTS) + { + /* Get the base address of the ports */ + + base = g_gpiobase[port]; + + /* Get ane return the input value */ + + return (getreg32(base + PIC32MX_IOPORT_PORT_OFFSET) & (1 << pin)) != 0; + } + + return false; +} + +/**************************************************************************** + * Function: pic32mx_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided base address + * + ****************************************************************************/ + +#if defined(CONFIG_DEBUG) && defined(CONFIG_DEBUG_VERBOSE) && defined(CONFIG_DEBUG_GPIO) +void pic32mx_dumpgpio(uint32_t pinset, const char *msg) +{ + unsigned int port = pic32mx_portno(pinset); + irqstate_t flags; + uintptr_t base; + + /* Verify that the port number is within range */ + + if (port < GPIO_NPORTS) + { + /* Get the base address of the ports */ + + base = g_gpiobase[port]; + + /* The following requires exclusive access to the GPIO registers */ + + sched_lock(); + lldbg("IOPORT%c pinset: %04x base: %08x -- %s\n", + 'A'+port, pinset, base, msg); + lldbg(" TRIS: %08x PORT: %08x LAT: %08x ODC: %08x\n", + getreg32(base + PIC32MX_IOPORT_TRIS_OFFSET), + getreg32(base + PIC32MX_IOPORT_PORT_OFFSET), + getreg32(base + PIC32MX_IOPORT_LAT_OFFSET), + getreg32(base + PIC32MX_IOPORT_ODC_OFFSET)); + lldbg(" CNCON: %08x CNEN: %08x CNPUE: %08x\n", + getreg32(PIC32MX_IOPORT_CNCON), + getreg32(PIC32MX_IOPORT_CNEN), + getreg32(PIC32MX_IOPORT_CNPUE)); + sched_unlock(); + } +} +#endif + diff --git a/arch/mips/src/pic32mx/pic32mx-gpioirq.c b/arch/mips/src/pic32mx/pic32mx-gpioirq.c new file mode 100644 index 0000000000..367412255c --- /dev/null +++ b/arch/mips/src/pic32mx/pic32mx-gpioirq.c @@ -0,0 +1,288 @@ +/**************************************************************************** + * arch/mips/src/pic32mx/pic32mx-gpio.c + * + * Copyright (C) 2011 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 "up_arch.h" +#include "pic32mx-gpio.h" +#include "pic32mx-internal.h" + +#ifdef CONFIG_GPIO_IRQ + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static xcpt_t g_cnisrs[IOPORT_NUMCN]; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: Inline PIN set field extractors + ****************************************************************************/ + +static inline bool pic32mx_input(uint16_t pinset) +{ + return ((pinset & GPIO_MODE_MASK) != GPIO_INPUT); +} + +static inline bool pic32mx_interrupt(uint16_t pinset) +{ + return ((pinset & GPIO_INTERRUPT) != 0); +} + +static inline bool pic32mx_pullup(uint16_t pinset) +{ + return ((pinset & GPIO_INT_MASK) == GPIO_PUINT); +} + +/**************************************************************************** + * Name: pic32mx_cninterrupt + * + * Description: + * Change notification interrupt handler. + * + ****************************************************************************/ + +static int pic32mx_cninterrupt(int irq, FAR void *context) +{ + int status; + int ret = OK; + int i; + + /* Call all attached handlers */ + + for (i = 0; i < IOPORT_NUMCN; i++) + { + /* Is this one attached */ + + if (g_cnisrs[i]) + { + /* Call the attached handler */ + + status = g_cnisrs[i](irq, context); + + /* Keep track of the status of the last handler that failed */ + + if (status < 0) + { + ret = status; + } + } + + /* Clear the pending interrupt */ + + up_clrpend_irq(PIC32MX_IRQ_CN); + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mx_gpioirqinitialize + * + * Description: + * Initialize logic to support a GPIO change notification interrupts. + * This function is called internally by the system on power up and should + * not be called again. + * + ****************************************************************************/ + +void pic32mx_gpioirqinitialize(void) +{ + int ret; + + /* Attach the change notice interrupt handler */ + + ret = irqattach(PIC32MX_IRQ_CN, pic32mx_cninterrupt); + DEBUGASSERT(ret == OK); + + /* Set the interrupt priority */ + +#ifdef CONFIG_ARCH_IRQPRIO + ret = up_prioritize_irq(PIC32MX_IRQ_CN, CONFIG_PIC32MX_CNPRIO); + DEBUGASSERT(ret == OK); +#endif + + /* Reset all registers and enable the CN module */ + + putreg32(IOPORT_CN_ALL, PIC32MX_IOPORT_CNENCLR); + putreg32(IOPORT_CN_ALL, PIC32MX_IOPORT_CNPUECLR); + putreg32(IOPORT_CNCON_ON, PIC32MX_IOPORT_CNCON); + + /* And enable the GPIO interrupt */ + + ret = up_enable_irq(PIC32MX_IRQSRC_CN); + DEBUGASSERT(ret == OK); +} + +/**************************************************************************** + * Name: pic32mx_gpioattach + * + * Description: + * Attach an interrupt service routine to a GPIO interrupt. This will + * also reconfigure the pin as an interrupting input. The change + * notification number is associated with all interrupt-capabile GPIO pins. + * The association could, however, differ from part to part and must be + * provided by the caller. + * + * When an interrupt occurs, it is due to a change on the GPIO input pin. + * In that case, all attached handlers will be called. Each handler must + * maintain state and determine if the unlying GPIO input value changed. + * + * Parameters: + * - pinset: GPIO pin configuration + * - cn: The change notification number associated with the pin. + * - handler: Interrupt handler (may be NULL to detach) + * + * Returns: + * The previous value of the interrupt handler function pointer. This + * value may, for example, be used to restore the previous handler when + * multiple handlers are used. + * + ****************************************************************************/ + +xcpt_t pic32mx_gpioattach(uint32_t pinset, unsigned int cn, xcpt_t handler) +{ + xcpt_t oldhandler = NULL; + irqstate_t flags; + + DEBUGASSERT(cn < IOPORT_NUMCN); + + /* First verify that the pinset is configured as an interrupting input */ + + if (pic32mx_input(pinset) && pic32mx_interrupt(pinset)) + { + /* Get the previously attached handler as the return value */ + + flags = irqsave(); + oldhandler = g_cnisrs[cn]; + + /* Are we attaching or detaching? */ + + if (handler != NULL) + { + /* Attaching... Make sure that the GPIO is properly configured as + * an input + */ + + pic32mx_configgpio(pinset); + + /* Pull-up requested? */ + + if (pic32mx_pullup(pinset)) + { + putreg32(1 << cn, PIC32MX_IOPORT_CNPUESET); + } + else + { + putreg32(1 << cn, PIC32MX_IOPORT_CNPUECLR); + } + } + else + { + /* Make sure that any further interrupts are disabled. + * (disable the pull-up as well). + */ + + putreg32(1 << cn, PIC32MX_IOPORT_CNENCLR); + putreg32(1 << cn, PIC32MX_IOPORT_CNPUECLR); + } + + /* Set the new handler (perhaps NULLifying the current handler) */ + + g_cnisrs[cn] = handler; + irqrestore(flags); + } + + return oldhandler; +} + +/**************************************************************************** + * Name: pic32mx_gpioirqenable + * + * Description: + * Enable the interrupt for specified GPIO IRQ + * + ****************************************************************************/ + +void pic32mx_gpioirqenable(unsigned int cn) +{ + DEBUGASSERT(cn < IOPORT_NUMCN); + putreg32(1 << cn, PIC32MX_IOPORT_CNENSET); +} + +/**************************************************************************** + * Name: pic32mx_gpioirqdisable + * + * Description: + * Disable the interrupt for specified GPIO IRQ + * + ****************************************************************************/ + +void pic32mx_gpioirqdisable(unsigned int cn) +{ + DEBUGASSERT(cn < IOPORT_NUMCN); + putreg32(1 << cn, PIC32MX_IOPORT_CNENCLR); +} + +#endif /* CONFIG_GPIO_IRQ */ diff --git a/arch/mips/src/pic32mx/pic32mx-internal.h b/arch/mips/src/pic32mx/pic32mx-internal.h index 1d42d006a5..8d9687ae4c 100644 --- a/arch/mips/src/pic32mx/pic32mx-internal.h +++ b/arch/mips/src/pic32mx/pic32mx-internal.h @@ -2,7 +2,7 @@ * arch/mips/src/pic32mx/pic32mx-internal.h * * Copyright (C) 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt + * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -54,6 +54,56 @@ /************************************************************************************ * Definitions ************************************************************************************/ +/* GPIO settings used in the configport, readport, writeport, etc. + * + * General encoding: + * MMxV Ixxx RRRx PPPP + */ + +#define GPIO_MODE_SHIFT (14) /* Bits 14-15: I/O mode */ +#define GPIO_MODE_MASK (3 << GPIO_MODE_SHIFT) +# define GPIO_INPUT (0 << GPIO_MODE_SHIFT) /* 00 Normal input */ +# define GPIO_OUTPUT (2 << GPIO_MODE_SHIFT) /* 10 Normal output */ +# define GPIO_OPENDRAN (3 << GPIO_MODE_SHIFT) /* 11 Open drain output */ + +#define GPIO_VALUE_MASK (1 << 12) /* Bit 12: Initial output value */ +# define GPIO_VALUE_ONE (1 << 12) +# define GPIO_VALUE_ZERO (0) + +#define GPIO_INT_SHIFT (14) /* Bits 10-11: Interrupt mode */ +#define GPIO_INT_MASK (3 << GPIO_INT_SHIFT) +# define GPIO_INT_NONE (0 << GPIO_INT_SHIFT) /* Bit 00: No interrupt */ +# define GPIO_INT (1 << GPIO_INT_SHIFT) /* Bit 01: Change notification enable */ +# define GPIO_PUINT (3 << GPIO_INT_SHIFT) /* Bit 11: Pulled-up interrupt input */ + +#define GPIO_PORT_SHIFT (5) /* Bits 5-7: Port number */ +#define GPIO_PORT_MASK (7 << GPIO_PORT_SHIFT) +# define GPIO_PORTA (0 << GPIO_PORT_SHIFT) +# define GPIO_PORTB (1 << GPIO_PORT_SHIFT) +# define GPIO_PORTC (2 << GPIO_PORT_SHIFT) +# define GPIO_PORTD (3 << GPIO_PORT_SHIFT) +# define GPIO_PORTE (4 << GPIO_PORT_SHIFT) +# define GPIO_PORTF (5 << GPIO_PORT_SHIFT) +# define GPIO_PORTG (6 << GPIO_PORT_SHIFT) + +#define GPIO_PIN_SHIFT 0 /* Bits 0-3: GPIO number: 0-15 */ +#define GPIO_PIN_MASK (15 << GPIO_PIN_SHIFT) +#define GPIO_PIN0 (0 << GPIO_PIN_SHIFT) +#define GPIO_PIN1 (1 << GPIO_PIN_SHIFT) +#define GPIO_PIN2 (2 << GPIO_PIN_SHIFT) +#define GPIO_PIN3 (3 << GPIO_PIN_SHIFT) +#define GPIO_PIN4 (4 << GPIO_PIN_SHIFT) +#define GPIO_PIN5 (5 << GPIO_PIN_SHIFT) +#define GPIO_PIN6 (6 << GPIO_PIN_SHIFT) +#define GPIO_PIN7 (7 << GPIO_PIN_SHIFT) +#define GPIO_PIN8 (8 << GPIO_PIN_SHIFT) +#define GPIO_PIN9 (9 << GPIO_PIN_SHIFT) +#define GPIO_PIN10 (10 << GPIO_PIN_SHIFT) +#define GPIO_PIN11 (11 << GPIO_PIN_SHIFT) +#define GPIO_PIN12 (12 << GPIO_PIN_SHIFT) +#define GPIO_PIN13 (13 << GPIO_PIN_SHIFT) +#define GPIO_PIN14 (14 << GPIO_PIN_SHIFT) +#define GPIO_PIN15 (15 << GPIO_PIN_SHIFT) /************************************************************************************ * Public Types @@ -191,6 +241,129 @@ EXTERN uint32_t *pic32mx_decodeirq(uint32_t *regs); EXTERN uint32_t *pic32mx_dobev(uint32_t *regs); +/************************************************************************************ + * Name: pic32mx_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin (the interrupt + * will be configured when pic32mx_attach() is called). + * + * Returned Value: + * OK on success; negated errno on failure. + * + ************************************************************************************/ + +EXTERN int pic32mx_configgpio(uint16_t cfgset); + +/************************************************************************************ + * Name: pic32mx_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ************************************************************************************/ + +EXTERN void pic32mx_gpiowrite(uint16_t pinset, bool value); + +/************************************************************************************ + * Name: pic32mx_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ************************************************************************************/ + +EXTERN bool pic32mx_gpioread(uint16_t pinset); + +/************************************************************************************ + * Name: pic32mx_gpioirqinitialize + * + * Description: + * Initialize logic to support a GPIO change notification interrupts. This + * function is called internally by the system on power up and should not be + * called again. + * + ************************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +EXTERN void pic32mx_gpioirqinitialize(void); +#else +# define pic32mx_gpioirqinitialize() +#endif + +/************************************************************************************ + * Name: pic32mx_gpioattach + * + * Description: + * Attach an interrupt service routine to a GPIO interrupt. This will also + * reconfigure the pin as an interrupting input. The change notification number is + * associated with all interrupt-capabile GPIO pins. The association could, + * however, differ from part to part and must be provided by the caller. + * + * When an interrupt occurs, it is due to a change on the GPIO input pin. In that + * case, all attached handlers will be called. Each handler must maintain state + * and determine if the unlying GPIO input value changed. + * + * Parameters: + * - pinset: GPIO pin configuration + * - cn: The change notification number associated with the pin + * - handler: Interrupt handler (may be NULL to detach) + * + * Returns: + * The previous value of the interrupt handler function pointer. This value may, + * for example, be used to restore the previous handler when multiple handlers are + * used. + * + ************************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +EXTERN xcpt_t pic32mx_gpioattach(uint32_t pinset, unsigned int cn, xcpt_t handler); +#else +# define pic32mx_gpioattach(p,f) (NULL) +#endif + +/************************************************************************************ + * Name: pic32mx_gpioirqenable + * + * Description: + * Enable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +EXTERN void pic32mx_gpioirqenable(unsigned int cn); +#else +# define pic32mx_gpioirqenable(irq) +#endif + +/************************************************************************************ + * Name: pic32mx_gpioirqdisable + * + * Description: + * Disable the interrupt for specified GPIO IRQ + * + ************************************************************************************/ + +#ifdef CONFIG_GPIO_IRQ +EXTERN void pic32mx_gpioirqdisable(unsigned int cn); +#else +# define pic32mx_gpioirqdisable(irq) +#endif + +/************************************************************************************ + * Function: pic32mx_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided base address + * + ************************************************************************************/ + +#ifdef CONFIG_DEBUG_GPIO +EXTERN void pic32mx_dumpgpio(uint32_t pinset, const char *msg); +#else +# define pic32mx_dumpgpio(p,m) +#endif + /************************************************************************************ * Name: pic32mx_spiNselect, pic32mx_spiNstatus, and pic32mx_spiNcmddata * diff --git a/arch/mips/src/pic32mx/pic32mx-ioport.h b/arch/mips/src/pic32mx/pic32mx-ioport.h index 186136345a..46b01db4b9 100644 --- a/arch/mips/src/pic32mx/pic32mx-ioport.h +++ b/arch/mips/src/pic32mx/pic32mx-ioport.h @@ -42,6 +42,7 @@ #include +#include "chip.h" #include "pic32mx-memorymap.h" /******************************************************************************************** @@ -265,6 +266,14 @@ #define IOPORT_CNPUE(n) (1 << (n)) /* Bits 0-18/21: Port pin pull-up enabled */ +#if defined(CHIP_PIC32MX3) || defined(CHIP_PIC32MX4) +# define IOPORT_CN_ALL 0x0007ffff /* Bits 0-18 */ +# define IOPORT_NUMCN 19 +#elif defined(CHIP_PIC32MX5) || defined(CHIP_PIC32MX6) || defined(CHIP_PIC32MX7) +# define IOPORT_CN_ALL 0x003fffff /* Bits 0-21 */ +# define IOPORT_NUMCN 22 +#endif + /******************************************************************************************** * Public Types ********************************************************************************************/ diff --git a/arch/mips/src/pic32mx/pic32mx-irq.c b/arch/mips/src/pic32mx/pic32mx-irq.c index 98c554c784..87e545853e 100644 --- a/arch/mips/src/pic32mx/pic32mx-irq.c +++ b/arch/mips/src/pic32mx/pic32mx-irq.c @@ -3,7 +3,7 @@ * arch/mips/src/chip/pic32mx-irq.c * * Copyright (C) 2011 Gregory Nutt. All rights reserved. - * Author: Gregory Nutt + * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -124,6 +124,12 @@ void up_irqinitialize(void) putreg32(INT_INTCON_MVEC, PIC32MX_INT_INTCONCLR); #endif + /* Initialize GPIO change notifiction handling */ + +#ifdef CONFIG_GPIO_IRQ + pic32mx_gpioirqinitialize(); +#endif + /* currents_regs is non-NULL only while processing an interrupt */ current_regs = NULL;