diff --git a/ChangeLog b/ChangeLog index f7ee10dddc8..cad0f962c3e 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2162,3 +2162,6 @@ returned. * arch/sim/src/Makefile: Correct build issue for sim/nsh2 target. Old libboard.a was not being cleaned. + * arch/mips/src/pic32mx/pic32mx-gpio*.c: Add GPIO support for the PIC32MX. + * configs/sure-pic32mx/src/up_leds.c and up_buttons.c: Add button and LED + support for the Sure Electronics PIC32MX board. diff --git a/arch/arm/src/sam3u/sam3u_pio.c b/arch/arm/src/sam3u/sam3u_pio.c index 79e36c6dfe7..833ff5e1fd3 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 3a46c30782e..f9d59cc7298 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 2eee06ae6d5..689a6d26122 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 f8a0a28bd03..400cc92b942 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 00000000000..380982010c4 --- /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 00000000000..367412255cf --- /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 1d42d006a5f..8d9687ae4c3 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 186136345a7..46b01db4b9a 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 98c554c7842..87e545853e5 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; diff --git a/configs/stm3210e-eval/include/board.h b/configs/stm3210e-eval/include/board.h index d8e506e6ddb..02db848fed9 100755 --- a/configs/stm3210e-eval/include/board.h +++ b/configs/stm3210e-eval/include/board.h @@ -3,7 +3,7 @@ * include/arch/board/board.h * * Copyright (C) 2009 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/configs/sure-pic32mx/include/board.h b/configs/sure-pic32mx/include/board.h index ae850de46d7..37cb265ebf1 100644 --- a/configs/sure-pic32mx/include/board.h +++ b/configs/sure-pic32mx/include/board.h @@ -102,6 +102,24 @@ #define LED_SIGNAL 4 /* N/C N/C ON N/C N/C N/C OFF N/C */ #define LED_ASSERTION 4 /* N/C N/C ON N/C N/C N/C OFF N/C */ #define LED_PANIC 5 /* N/C N/C N/C ON N/C N/C N/C OFF */ +#define LED_NVALUES 6 + +/* Button Definitions *******************************************************/ +/* The Sure PIC32MX board has three buttons. + * + * SW1 (SW_UP, left arrow) RB3 Pulled high, Grounded/low when depressed + * SW2 (SW_DOWN, down/right arrow) RB2 Pulled high, Grounded/low when depressed + * SW3 (SW_OK, right arrow) RB4 Pulled high, Grounded/low when depressed + */ + +#define BUTTON_SW1 0 +#define BUTTON_SW2 1 +#define BUTTON_SW3 2 +#define NUM_BUTTONS 3 + +#define BUTTON_SW1_BIT (1 << BUTTON_SW1) +#define BUTTON_SW2_BIT (1 << BUTTON_SW2) +#define BUTTON_SW3_BIT (1 << BUTTON_SW3) /**************************************************************************** * Public Types @@ -124,6 +142,42 @@ extern "C" { #define EXTERN extern #endif +/**************************************************************************** + * Button support. + * + * Description: + * up_buttoninit() must be called to initialize button resources. After + * that, up_buttons() may be called to collect the current state of all + * buttons or up_irqbutton() may be called to register button interrupt + * handlers. + * + * After up_buttoninit() has been called, up_buttons() may be called to + * collect the state of all buttons. up_buttons() returns an 8-bit bit set + * with each bit associated with a button. See the BUTTON_*_BIT + * definitions in board.h for the meaning of each bit. + * + * up_irqbutton() may be called to register an interrupt handler that will + * be called when a button is depressed or released. The ID value is a + * button enumeration value that uniquely identifies a button resource. + * See the BUTTON_* definitions in board.h for the meaning of enumeration + * value. The previous interrupt handler address is returned (so that it + * may restored, if so desired). + * + * When an interrupt occurs, it is due to a change on the GPIO input pin + * associated with the button. In that case, all attached change + * notification handlers will be called. Each handler must maintain state + * and determine if the unlying GPIO button input value changed. + * + ****************************************************************************/ + +#ifdef CONFIG_ARCH_BUTTONS +EXTERN void up_buttoninit(void); +EXTERN uint8_t up_buttons(void); +#ifdef CONFIG_ARCH_IRQBUTTONS +EXTERN xcpt_t up_irqbutton(int id, xcpt_t irqhandler); +#endif +#endif + #undef EXTERN #ifdef __cplusplus } diff --git a/configs/sure-pic32mx/src/Makefile b/configs/sure-pic32mx/src/Makefile index 9b647eb1bf2..0a5849d9701 100644 --- a/configs/sure-pic32mx/src/Makefile +++ b/configs/sure-pic32mx/src/Makefile @@ -2,7 +2,7 @@ # configs/sure-pic32mx/src/Makefile # # 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 @@ -44,6 +44,10 @@ ifeq ($(CONFIG_ARCH_LEDS),y) CSRCS += up_leds.c endif +ifeq ($(CONFIG_ARCH_BUTTONS),y) +CSRCS += up_buttons.c +endif + ifeq ($(CONFIG_NSH_ARCHINIT),y) CSRCS += up_nsh.c endif diff --git a/configs/sure-pic32mx/src/up_buttons.c b/configs/sure-pic32mx/src/up_buttons.c new file mode 100644 index 00000000000..6a33309b103 --- /dev/null +++ b/configs/sure-pic32mx/src/up_buttons.c @@ -0,0 +1,210 @@ +/**************************************************************************** + * configs/sure-pic32mx/src/up_buttons.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 "chip.h" +#include "up_arch.h" + +#include "pic32mx-internal.h" +#include "pic32mx-ioport.h" +#include "pic32mx-adc.h" +#include "sure-internal.h" + +#ifdef CONFIG_ARCH_BUTTONS + +/**************************************************************************** + * Definitions + ****************************************************************************/ +/* The Sure PIC32MX board has three buttons. + * + * SW1 (SW_UP, left arrow) RB3 Pulled high, Grounded/low when depressed + * SW2 (SW_DOWN, down/right arrow) RB2 Pulled high, Grounded/low when depressed + * SW3 (SW_OK, right arrow) RB4 Pulled high, Grounded/low when depressed + * + * Internal pull-ups are not required since the LEDs are pull-up externally. + * Change notification interrupts are not *automatically* enabled. Change + * notification will be enabled when pic32mx_gpioattach() is called. + */ + +#define GPIO_SW1 (GPIO_INPUT|GPIO_INT|GPIO_PORTB|GPIO_PIN_3) +#define GPIO_SW2 (GPIO_INPUT|GPIO_INT|GPIO_PORTB|GPIO_PIN_2) +#define GPIO_SW3 (GPIO_INPUT|GPIO_INT|GPIO_PORTB|GPIO_PIN_4) + +/* Change notification numbers: + * RB3 -> CN5 + * RB2 -> CN2 + * RB4 -> CN6 + */ + +#define CN_SW1 5 +#define CN_SW2 2 +#define CN_SW3 6 + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +/* Pin configuration for each button */ + +static const uint16_t g_buttonset[NUM_BUTTONS] = +{ + BUTTON_SW1 BUTTON_SW2, BUTTON_SW3 +} + +/* Change notification number for each button */ + +#ifdef CONFIG_ARCH_IRQBUTTONS +static const uint8_t g_buttoncn[NUM_BUTTONS] = +{ + CN_SW1, CN_SW2, CN_SW3 +} +#endif + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_buttoninit + * + * Description: + * up_buttoninit() must be called to initialize button resources. After + * that, up_buttons() may be called to collect the current state of all + * buttons or up_irqbutton() may be called to register button interrupt + * handlers. + * + ****************************************************************************/ + +void up_buttoninit(void) +{ + int i; + + /* Configure input pins */ + + for (i = 0; i < NUM_BUTTONS; i++) + { + pic32mx_configgpio(g_buttonset[i]); + } + + /* Change AN2/AN3/AN4 to digital */ + + putreg32(0xffff, PIC32MX_ADC_CFG); +} + +/**************************************************************************** + * Name: up_buttons + ****************************************************************************/ + +uint8_t up_buttons(void) +{ + uint8_t ret = 0; + int id; + + /* Configure input pins */ + + for (id = 0; id < NUM_BUTTONS; id++) + { + if (pic32mx_gpioread(g_buttonset[id])) + { + ret |= (1 << id); + } + } + + return ret; +} + +/************************************************************************************ + * Button support. + * + * Description: + * up_buttoninit() must be called to initialize button resources. After + * that, up_buttons() may be called to collect the current state of all + * buttons or up_irqbutton() may be called to register button interrupt + * handlers. + * + * After up_buttoninit() has been called, up_buttons() may be called to + * collect the state of all buttons. up_buttons() returns an 8-bit bit set + * with each bit associated with a button. See the BUTTON_*_BIT and JOYSTICK_*_BIT + * definitions in board.h for the meaning of each bit. + * + * up_irqbutton() may be called to register an interrupt handler that will + * be called when a button is depressed or released. The ID value is a + * button enumeration value that uniquely identifies a button resource. See the + * BUTTON_* and JOYSTICK_* definitions in board.h for the meaning of enumeration + * value. The previous interrupt handler address is returned (so that it may + * restored, if so desired). + * + * Interrupts are automatically enabled when the button handler is attached and + * automatically disabled when the button handler is detached. + * + * When an interrupt occurs, it is due to a change on the GPIO input pin + * associated with the button. In that case, all attached change + * notification handlers will be called. Each handler must maintain state + * and determine if the unlying GPIO button input value changed. + * + ************************************************************************************/ + +#ifdef CONFIG_ARCH_IRQBUTTONS +xcpt_t up_irqbutton(int id, xcpt_t irqhandler) +{ + xcpt_t oldhandler = NULL; + + if (id < NUM_BUTTONS) + { + oldhandler = pic32mx_gpioattach(g_buttonset[id], g_buttoncn[id], irqhandler); + if (irqbuttron) + { + pic32mx_gpioirqenable(g_buttoncn[id]); + } + } + return oldhandler; +} +#endif +#endif /* CONFIG_ARCH_BUTTONS */ diff --git a/configs/sure-pic32mx/src/up_leds.c b/configs/sure-pic32mx/src/up_leds.c index 5177eef6a8c..a277ca00867 100644 --- a/configs/sure-pic32mx/src/up_leds.c +++ b/configs/sure-pic32mx/src/up_leds.c @@ -3,7 +3,7 @@ * arch/arm/src/board/up_leds.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 @@ -51,6 +51,7 @@ #include "up_internal.h" #include "pic32mx-internal.h" +#include "pic32mx-ioport.h" #include "sure-internal.h" #ifdef CONFIG_ARCH_LEDS @@ -58,6 +59,7 @@ /**************************************************************************** * Definitions ****************************************************************************/ +/* LED Configuration ********************************************************/ /* The Sure PIC32MX board has five LEDs. One (D4, lablel "Power") is not * controllable by software. Four are controllable by software: * @@ -78,6 +80,18 @@ * LED_PANIC 5 N/C N/C N/C ON N/C N/C N/C OFF */ +#define GPIO_USB_LED (GPIO_OUTPUT|GPIO_VALUE_ONE|GPIO_PORTD|GPIO_PIN7) +#define GPIO_SD_LED (GPIO_OUTPUT|GPIO_VALUE_ONE|GPIO_PORTD|GPIO_PIN8) +#define GPIO_FLASH_LED (GPIO_OUTPUT|GPIO_VALUE_ONE|GPIO_PORTD|GPIO_PIN9) +#define GPIO_ERROR_LED (GPIO_OUTPUT|GPIO_VALUE_ONE|GPIO_PORTD|GPIO_PIN10) + +/* LED Management Definitions ***********************************************/ + +#define LED_OFF 0 +#define LED_ON 1 +#define LED_NC 2 + +/* Debug ********************************************************************/ /* Enables debug output from this file (needs CONFIG_DEBUG with * CONFIG_DEBUG_VERBOSE too) */ @@ -99,13 +113,72 @@ #endif /**************************************************************************** + * Private types + ****************************************************************************/ + +struct led_setting_s +{ + uint8_t usb : 2; + uint8_t sd : 2; + uint8_t flash : 2; + uint8_t error : 2; +}; + + /**************************************************************************** * Private Data ****************************************************************************/ +static const g_ledonvalues[LED_NVALUES] = +{ + {LED_OFF, LED_OFF, LED_OFF, LED_OFF}, + {LED_ON, LED_OFF, LED_NC, LED_NC}, + {LED_OFF, LED_ON, LED_NC, LED_NC}, + {LED_ON, LED_ON, LED_NC, LED_NC}, + {LED_NC, LED_NC, LED_ON, LED_NC}, + {LED_NC, LED_NC, LED_NC, LED_ON}, +}; + +static const g_ledoffvalues[LED_NVALUES] = +{ + {LED_NC, LED_NC, LED_NC, LED_NC}, + {LED_NC, LED_NC, LED_NC, LED_NC}, + {LED_NC, LED_NC, LED_NC, LED_NC}, + {LED_NC, LED_NC, LED_NC, LED_NC}, + {LED_NC, LED_NC, LED_OFF, LED_NC}, + {LED_NC, LED_NC, LED_NC, LED_OFF} +}; + /**************************************************************************** * Private Functions ****************************************************************************/ +/**************************************************************************** + * Name: up_ledinit + ****************************************************************************/ + +void up_setleds(struct led_setting_s *setting) +{ + if (setting->usb != LED_NC) + { + pic32mx_gpiowrite(GPIO_USB_LED, setting->usb != LED_ON); + } + + if (setting->sd != LED_NC) + { + pic32mx_gpiowrite(GPIO_SD_LED, setting->sd != LED_ON); + } + + if (setting->flash != LED_NC) + { + pic32mx_gpiowrite(GPIO_FLASH_LED, setting->flash != LED_ON); + } + + if (setting->error != LED_NC) + { + pic32mx_gpiowrite(GPIO_ERROR_LED, setting->error != LED_ON); + } +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -116,7 +189,12 @@ void up_ledinit(void) { -#warning "Missing logic" + /* Configure output pins */ + + pic32mx_configgpio(GPIO_USB_LED); + pic32mx_configgpio(GPIO_SD_LED); + pic32mx_configgpio(GPIO_FLASH_LED); + pic32mx_configgpio(GPIO_ERROR_LED); } /**************************************************************************** @@ -125,7 +203,10 @@ void up_ledinit(void) void up_ledon(int led) { -#warning "Missing logic" + if (led < LED_NVALUES) + { + up_setleds(&g_ledonvalues[led]); + } } /**************************************************************************** @@ -134,6 +215,9 @@ void up_ledon(int led) void up_ledoff(int led) { -#warning "Missing logic" + if (led < LED_NVALUES) + { + up_setleds(&g_ledoffvalues[led]); + } } #endif /* CONFIG_ARCH_LEDS */