diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2015-02-25 11:09:04 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2015-02-25 11:09:04 -0600 |
commit | 3dab31e5fd3426d24a7ca33916fc829df564aac5 (patch) | |
tree | b2c1c91a314432fe4ac4c6b60c15a9cecf3babe4 /nuttx/arch/mips/src | |
parent | 1851c98ac7bd8a9d608167caa2f6226ca3c0c6fc (diff) | |
download | px4-nuttx-3dab31e5fd3426d24a7ca33916fc829df564aac5.tar.gz px4-nuttx-3dab31e5fd3426d24a7ca33916fc829df564aac5.tar.bz2 px4-nuttx-3dab31e5fd3426d24a7ca33916fc829df564aac5.zip |
PIC32MZ: Add file for GPIO interrupt support. There are issues so configuration is EXPERIMENTAL for now
Diffstat (limited to 'nuttx/arch/mips/src')
-rw-r--r-- | nuttx/arch/mips/src/pic32mx/Kconfig | 7 | ||||
-rw-r--r-- | nuttx/arch/mips/src/pic32mx/Make.defs | 2 | ||||
-rw-r--r-- | nuttx/arch/mips/src/pic32mx/pic32mx-gpioirq.c | 4 | ||||
-rw-r--r-- | nuttx/arch/mips/src/pic32mx/pic32mx-internal.h | 8 | ||||
-rw-r--r-- | nuttx/arch/mips/src/pic32mx/pic32mx-irq.c | 2 | ||||
-rw-r--r-- | nuttx/arch/mips/src/pic32mz/Kconfig | 13 | ||||
-rw-r--r-- | nuttx/arch/mips/src/pic32mz/Make.defs | 4 | ||||
-rw-r--r-- | nuttx/arch/mips/src/pic32mz/pic32mz-gpio.h | 8 | ||||
-rw-r--r-- | nuttx/arch/mips/src/pic32mz/pic32mz-gpioirq.c | 288 | ||||
-rw-r--r-- | nuttx/arch/mips/src/pic32mz/pic32mz-irq.c | 2 |
10 files changed, 322 insertions, 16 deletions
diff --git a/nuttx/arch/mips/src/pic32mx/Kconfig b/nuttx/arch/mips/src/pic32mx/Kconfig index a2f064687..a23b0cc80 100644 --- a/nuttx/arch/mips/src/pic32mx/Kconfig +++ b/nuttx/arch/mips/src/pic32mx/Kconfig @@ -1003,6 +1003,13 @@ config PIC32MX_USBPRIO endmenu +config PIC32MX_GPIOIRQ + bool "GPIO Interrupt" + default n + depends on EXPERIMENTAL + ---help--- + Build in support for interrupts based on GPIO inputs from IOPorts + menu "PIC32MX PHY/Ethernet device driver settings" depends on PIC32MX_ETHERNET diff --git a/nuttx/arch/mips/src/pic32mx/Make.defs b/nuttx/arch/mips/src/pic32mx/Make.defs index 6fbde1078..793e9ce06 100644 --- a/nuttx/arch/mips/src/pic32mx/Make.defs +++ b/nuttx/arch/mips/src/pic32mx/Make.defs @@ -74,7 +74,7 @@ ifneq ($(CONFIG_SCHED_TICKLESS),y) CHIP_CSRCS += pic32mx-timerisr.c endif -ifeq ($(CONFIG_GPIO_IRQ),y) +ifeq ($(CONFIG_PIC32MX_GPIOIRQ),y) CHIP_CSRCS += pic32mx_gpioirq.c endif diff --git a/nuttx/arch/mips/src/pic32mx/pic32mx-gpioirq.c b/nuttx/arch/mips/src/pic32mx/pic32mx-gpioirq.c index 8f4a6c751..8509d2d49 100644 --- a/nuttx/arch/mips/src/pic32mx/pic32mx-gpioirq.c +++ b/nuttx/arch/mips/src/pic32mx/pic32mx-gpioirq.c @@ -50,7 +50,7 @@ #include "pic32mx-gpio.h" #include "pic32mx-internal.h" -#ifdef CONFIG_GPIO_IRQ +#ifdef CONFIG_PIC32MX_GPIOIRQ /**************************************************************************** * Pre-processor Definitions @@ -285,4 +285,4 @@ void pic32mx_gpioirqdisable(unsigned int cn) putreg32(1 << cn, PIC32MX_IOPORT_CNENCLR); } -#endif /* CONFIG_GPIO_IRQ */ +#endif /* CONFIG_PIC32MX_GPIOIRQ */ diff --git a/nuttx/arch/mips/src/pic32mx/pic32mx-internal.h b/nuttx/arch/mips/src/pic32mx/pic32mx-internal.h index 91a3de396..d3cb65aa5 100644 --- a/nuttx/arch/mips/src/pic32mx/pic32mx-internal.h +++ b/nuttx/arch/mips/src/pic32mx/pic32mx-internal.h @@ -305,7 +305,7 @@ bool pic32mx_gpioread(uint16_t pinset); * ************************************************************************************/ -#ifdef CONFIG_GPIO_IRQ +#ifdef CONFIG_PIC32MX_GPIOIRQ void pic32mx_gpioirqinitialize(void); #else # define pic32mx_gpioirqinitialize() @@ -336,7 +336,7 @@ void pic32mx_gpioirqinitialize(void); * ************************************************************************************/ -#ifdef CONFIG_GPIO_IRQ +#ifdef CONFIG_PIC32MX_GPIOIRQ xcpt_t pic32mx_gpioattach(uint32_t pinset, unsigned int cn, xcpt_t handler); #else # define pic32mx_gpioattach(p,f) (NULL) @@ -350,7 +350,7 @@ xcpt_t pic32mx_gpioattach(uint32_t pinset, unsigned int cn, xcpt_t handler); * ************************************************************************************/ -#ifdef CONFIG_GPIO_IRQ +#ifdef CONFIG_PIC32MX_GPIOIRQ void pic32mx_gpioirqenable(unsigned int cn); #else # define pic32mx_gpioirqenable(irq) @@ -364,7 +364,7 @@ void pic32mx_gpioirqenable(unsigned int cn); * ************************************************************************************/ -#ifdef CONFIG_GPIO_IRQ +#ifdef CONFIG_PIC32MX_GPIOIRQ void pic32mx_gpioirqdisable(unsigned int cn); #else # define pic32mx_gpioirqdisable(irq) diff --git a/nuttx/arch/mips/src/pic32mx/pic32mx-irq.c b/nuttx/arch/mips/src/pic32mx/pic32mx-irq.c index 093d24d3d..b00335a02 100644 --- a/nuttx/arch/mips/src/pic32mx/pic32mx-irq.c +++ b/nuttx/arch/mips/src/pic32mx/pic32mx-irq.c @@ -149,7 +149,7 @@ void up_irqinitialize(void) /* Initialize GPIO change notification handling */ -#ifdef CONFIG_GPIO_IRQ +#ifdef CONFIG_PIC32MX_GPIOIRQ pic32mx_gpioirqinitialize(); #endif diff --git a/nuttx/arch/mips/src/pic32mz/Kconfig b/nuttx/arch/mips/src/pic32mz/Kconfig index 5c4dff9d7..a451d895c 100644 --- a/nuttx/arch/mips/src/pic32mz/Kconfig +++ b/nuttx/arch/mips/src/pic32mz/Kconfig @@ -248,6 +248,13 @@ config PIC32MZ_CTMU endmenu +config PIC32MZ_GPIOIRQ + bool "GPIO Interrupt" + default n + depends on EXPERIMENTAL + ---help--- + Build in support for interrupts based on GPIO inputs from IOPorts + config PIC32MZ_T1_SOSC bool default n @@ -257,14 +264,14 @@ menu "PIC32MZ PHY/Ethernet device driver settings" depends on PIC32MZ_ETHERNET config PHY_AUTONEG - bool "Auto-negotion" + bool "Auto-negotiation" default y depends on PIC32MZ_ETHERNET ---help--- - Enable auto-negotion + Enable auto-negotiation config PHY_SPEED100 - bool "100Mbps spped" + bool "100Mbps speed" default n depends on PIC32MZ_ETHERNET && !PHY_AUTONEG ---help--- diff --git a/nuttx/arch/mips/src/pic32mz/Make.defs b/nuttx/arch/mips/src/pic32mz/Make.defs index 1a47d7b43..8915bdd30 100644 --- a/nuttx/arch/mips/src/pic32mz/Make.defs +++ b/nuttx/arch/mips/src/pic32mz/Make.defs @@ -69,3 +69,7 @@ CHIP_CSRCS += pic32mz-irq.c pic32mz-timerisr.c pic32mz-gpio.c CHIP_CSRCS += pic32mz-lowconsole.c pic32mz-serial.c # Configuration-dependent PIC32MZ files + +ifeq ($(CONFIG_PIC32MZ_GPIOIRQ),y) +CHIP_CSRCS += pic32mz-gpioirq.c +endif diff --git a/nuttx/arch/mips/src/pic32mz/pic32mz-gpio.h b/nuttx/arch/mips/src/pic32mz/pic32mz-gpio.h index 98023d983..6162e31d9 100644 --- a/nuttx/arch/mips/src/pic32mz/pic32mz-gpio.h +++ b/nuttx/arch/mips/src/pic32mz/pic32mz-gpio.h @@ -175,7 +175,7 @@ bool pic32mz_gpioread(uint16_t pinset); * ************************************************************************************/ -#ifdef CONFIG_GPIO_IRQ +#ifdef CONFIG_PIC32MZ_GPIOIRQ void pic32mz_gpioirqinitialize(void); #else # define pic32mz_gpioirqinitialize() @@ -206,7 +206,7 @@ void pic32mz_gpioirqinitialize(void); * ************************************************************************************/ -#ifdef CONFIG_GPIO_IRQ +#ifdef CONFIG_PIC32MZ_GPIOIRQ xcpt_t pic32mz_gpioattach(uint32_t pinset, unsigned int cn, xcpt_t handler); #else # define pic32mz_gpioattach(p,f) (NULL) @@ -220,7 +220,7 @@ xcpt_t pic32mz_gpioattach(uint32_t pinset, unsigned int cn, xcpt_t handler); * ************************************************************************************/ -#ifdef CONFIG_GPIO_IRQ +#ifdef CONFIG_PIC32MZ_GPIOIRQ void pic32mz_gpioirqenable(unsigned int cn); #else # define pic32mz_gpioirqenable(irq) @@ -234,7 +234,7 @@ void pic32mz_gpioirqenable(unsigned int cn); * ************************************************************************************/ -#ifdef CONFIG_GPIO_IRQ +#ifdef CONFIG_PIC32MZ_GPIOIRQ void pic32mz_gpioirqdisable(unsigned int cn); #else # define pic32mz_gpioirqdisable(irq) diff --git a/nuttx/arch/mips/src/pic32mz/pic32mz-gpioirq.c b/nuttx/arch/mips/src/pic32mz/pic32mz-gpioirq.c new file mode 100644 index 000000000..be1363f60 --- /dev/null +++ b/nuttx/arch/mips/src/pic32mz/pic32mz-gpioirq.c @@ -0,0 +1,288 @@ +/**************************************************************************** + * arch/mips/src/pic32mz/pic32mz-gpio.c + * + * Copyright (C) 2015 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 "chip/pic32mz-ioport.h" +#include "pic32mz-gpio.h" + +#ifdef CONFIG_PIC32MZ_GPIOIRQ + +/**************************************************************************** + * 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 pic32mz_input(uint16_t pinset) +{ + return ((pinset & GPIO_MODE_MASK) != GPIO_INPUT); +} + +static inline bool pic32mz_interrupt(uint16_t pinset) +{ + return ((pinset & GPIO_INTERRUPT) != 0); +} + +static inline bool pic32mz_pullup(uint16_t pinset) +{ + return ((pinset & GPIO_INT_MASK) == GPIO_PUINT); +} + +/**************************************************************************** + * Name: pic32mz_cninterrupt + * + * Description: + * Change notification interrupt handler. + * + ****************************************************************************/ + +static int pic32mz_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(PIC32MZ_IRQ_CN); + return ret; +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mz_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 pic32mz_gpioirqinitialize(void) +{ + int ret; + + /* Attach the change notice interrupt handler */ + + ret = irqattach(PIC32MZ_IRQ_CN, pic32mz_cninterrupt); + DEBUGASSERT(ret == OK); + + /* Set the interrupt priority */ + +#ifdef CONFIG_ARCH_IRQPRIO + ret = up_prioritize_irq(PIC32MZ_IRQ_CN, CONFIG_PIC32MZ_CNPRIO); + DEBUGASSERT(ret == OK); +#endif + + /* Reset all registers and enable the CN module */ + + putreg32(IOPORT_CN_ALL, PIC32MZ_IOPORT_CNENCLR); + putreg32(IOPORT_CN_ALL, PIC32MZ_IOPORT_CNPUECLR); + putreg32(IOPORT_CNCON_ON, PIC32MZ_IOPORT_CNCON); + + /* And enable the GPIO interrupt */ + + ret = up_enable_irq(PIC32MZ_IRQSRC_CN); + DEBUGASSERT(ret == OK); +} + +/**************************************************************************** + * Name: pic32mz_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 pic32mz_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 (pic32mz_input(pinset) && pic32mz_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 + */ + + pic32mz_configgpio(pinset); + + /* Pull-up requested? */ + + if (pic32mz_pullup(pinset)) + { + putreg32(1 << cn, PIC32MZ_IOPORT_CNPUESET); + } + else + { + putreg32(1 << cn, PIC32MZ_IOPORT_CNPUECLR); + } + } + else + { + /* Make sure that any further interrupts are disabled. + * (disable the pull-up as well). + */ + + putreg32(1 << cn, PIC32MZ_IOPORT_CNENCLR); + putreg32(1 << cn, PIC32MZ_IOPORT_CNPUECLR); + } + + /* Set the new handler (perhaps NULLifying the current handler) */ + + g_cnisrs[cn] = handler; + irqrestore(flags); + } + + return oldhandler; +} + +/**************************************************************************** + * Name: pic32mz_gpioirqenable + * + * Description: + * Enable the interrupt for specified GPIO IRQ + * + ****************************************************************************/ + +void pic32mz_gpioirqenable(unsigned int cn) +{ + DEBUGASSERT(cn < IOPORT_NUMCN); + putreg32(1 << cn, PIC32MZ_IOPORT_CNENSET); +} + +/**************************************************************************** + * Name: pic32mz_gpioirqdisable + * + * Description: + * Disable the interrupt for specified GPIO IRQ + * + ****************************************************************************/ + +void pic32mz_gpioirqdisable(unsigned int cn) +{ + DEBUGASSERT(cn < IOPORT_NUMCN); + putreg32(1 << cn, PIC32MZ_IOPORT_CNENCLR); +} + +#endif /* CONFIG_PIC32MZ_GPIOIRQ */ diff --git a/nuttx/arch/mips/src/pic32mz/pic32mz-irq.c b/nuttx/arch/mips/src/pic32mz/pic32mz-irq.c index ef0b5e5d7..e03770ad1 100644 --- a/nuttx/arch/mips/src/pic32mz/pic32mz-irq.c +++ b/nuttx/arch/mips/src/pic32mz/pic32mz-irq.c @@ -229,7 +229,7 @@ void up_irqinitialize(void) /* Initialize GPIO change notification handling */ -#ifdef CONFIG_GPIO_IRQ +#ifdef CONFIG_PIC32MZ_GPIOIRQ pic32mz_gpioirqinitialize(); #endif |