summaryrefslogtreecommitdiff
path: root/nuttx/arch
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-10-11 20:50:10 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2011-10-11 20:50:10 +0000
commitebebf7f4acbae1c917962c14d21e86a5cf0484c2 (patch)
tree9e719b791f2addbec3b4cab37c3ed166c4f2b952 /nuttx/arch
parent7155446ba1a312a61d55d0c6dab9cc621112d743 (diff)
downloadpx4-nuttx-ebebf7f4acbae1c917962c14d21e86a5cf0484c2.tar.gz
px4-nuttx-ebebf7f4acbae1c917962c14d21e86a5cf0484c2.tar.bz2
px4-nuttx-ebebf7f4acbae1c917962c14d21e86a5cf0484c2.zip
Add PIC32MX GPIO handling; add button/LED support for the Sure PIC32MX
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@4040 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch')
-rw-r--r--nuttx/arch/arm/src/sam3u/sam3u_pio.c2
-rw-r--r--nuttx/arch/mips/src/pic32mx/Make.defs9
-rw-r--r--nuttx/arch/mips/src/pic32mx/pic32mx-config.h12
-rw-r--r--nuttx/arch/mips/src/pic32mx/pic32mx-decodeirq.c2
-rw-r--r--nuttx/arch/mips/src/pic32mx/pic32mx-gpio.c298
-rw-r--r--nuttx/arch/mips/src/pic32mx/pic32mx-gpioirq.c288
-rw-r--r--nuttx/arch/mips/src/pic32mx/pic32mx-internal.h175
-rw-r--r--nuttx/arch/mips/src/pic32mx/pic32mx-ioport.h9
-rw-r--r--nuttx/arch/mips/src/pic32mx/pic32mx-irq.c8
9 files changed, 790 insertions, 13 deletions
diff --git a/nuttx/arch/arm/src/sam3u/sam3u_pio.c b/nuttx/arch/arm/src/sam3u/sam3u_pio.c
index 79e36c6df..833ff5e1f 100644
--- a/nuttx/arch/arm/src/sam3u/sam3u_pio.c
+++ b/nuttx/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 <spudmonkey@racsa.co.cr>
+ * Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/nuttx/arch/mips/src/pic32mx/Make.defs b/nuttx/arch/mips/src/pic32mx/Make.defs
index 3a46c3078..f9d59cc72 100644
--- a/nuttx/arch/mips/src/pic32mx/Make.defs
+++ b/nuttx/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 <spudmonkey@racsa.co.cr>
+# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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/nuttx/arch/mips/src/pic32mx/pic32mx-config.h b/nuttx/arch/mips/src/pic32mx/pic32mx-config.h
index 2eee06ae6..689a6d261 100644
--- a/nuttx/arch/mips/src/pic32mx/pic32mx-config.h
+++ b/nuttx/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/nuttx/arch/mips/src/pic32mx/pic32mx-decodeirq.c b/nuttx/arch/mips/src/pic32mx/pic32mx-decodeirq.c
index f8a0a28bd..400cc92b9 100644
--- a/nuttx/arch/mips/src/pic32mx/pic32mx-decodeirq.c
+++ b/nuttx/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 <spudmonkey@racsa.co.cr>
+ * Author: Gregory Nutt <gnutt@nuttx.org>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
diff --git a/nuttx/arch/mips/src/pic32mx/pic32mx-gpio.c b/nuttx/arch/mips/src/pic32mx/pic32mx-gpio.c
new file mode 100644
index 000000000..380982010
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * 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 <nuttx/config.h>
+
+#include <stdint.h>
+#include <assert.h>
+#include <errno.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#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/nuttx/arch/mips/src/pic32mx/pic32mx-gpioirq.c b/nuttx/arch/mips/src/pic32mx/pic32mx-gpioirq.c
new file mode 100644
index 000000000..367412255
--- /dev/null
+++ b/nuttx/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 <gnutt@nuttx.org>
+ *
+ * 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 <nuttx/config.h>
+
+#include <stdint.h>
+#include <assert.h>
+
+#include <nuttx/irq.h>
+#include <nuttx/arch.h>
+#include <arch/board/board.h>
+
+#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/nuttx/arch/mips/src/pic32mx/pic32mx-internal.h b/nuttx/arch/mips/src/pic32mx/pic32mx-internal.h
index 1d42d006a..8d9687ae4 100644
--- a/nuttx/arch/mips/src/pic32mx/pic32mx-internal.h
+++ b/nuttx/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 <spudmonkey@racsa.co.cr>
+ * Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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
@@ -192,6 +242,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
*
* Description:
diff --git a/nuttx/arch/mips/src/pic32mx/pic32mx-ioport.h b/nuttx/arch/mips/src/pic32mx/pic32mx-ioport.h
index 186136345..46b01db4b 100644
--- a/nuttx/arch/mips/src/pic32mx/pic32mx-ioport.h
+++ b/nuttx/arch/mips/src/pic32mx/pic32mx-ioport.h
@@ -42,6 +42,7 @@
#include <nuttx/config.h>
+#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/nuttx/arch/mips/src/pic32mx/pic32mx-irq.c b/nuttx/arch/mips/src/pic32mx/pic32mx-irq.c
index 98c554c78..87e545853 100644
--- a/nuttx/arch/mips/src/pic32mx/pic32mx-irq.c
+++ b/nuttx/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 <spudmonkey@racsa.co.cr>
+ * Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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;