diff options
Diffstat (limited to 'nuttx/arch/mips/src/pic32mz/pic32mz-gpio.c')
-rw-r--r-- | nuttx/arch/mips/src/pic32mz/pic32mz-gpio.c | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/nuttx/arch/mips/src/pic32mz/pic32mz-gpio.c b/nuttx/arch/mips/src/pic32mz/pic32mz-gpio.c new file mode 100644 index 000000000..c4008a952 --- /dev/null +++ b/nuttx/arch/mips/src/pic32mz/pic32mz-gpio.c @@ -0,0 +1,344 @@ +/**************************************************************************** + * 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 <errno.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" + +#if CHIP_NPORTS > 0 + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static const uintptr_t g_gpiobase[CHIP_NPORTS] = +{ + PIC32MZ_IOPORTA_K1BASE +#if CHIP_NPORTS > 1 + , PIC32MZ_IOPORTB_K1BASE +#endif +#if CHIP_NPORTS > 2 + , PIC32MZ_IOPORTC_K1BASE +#endif +#if CHIP_NPORTS > 3 + , PIC32MZ_IOPORTD_K1BASE +#endif +#if CHIP_NPORTS > 4 + , PIC32MZ_IOPORTE_K1BASE +#endif +#if CHIP_NPORTS > 5 + , PIC32MZ_IOPORTF_K1BASE +#endif +#if CHIP_NPORTS > 6 + , PIC32MZ_IOPORTG_K1BASE +#endif +#if CHIP_NPORTS > 7 + , PIC32MZ_IOPORTH_K1BASE +#endif +#if CHIP_NPORTS > 8 + , PIC32MZ_IOPORTJ_K1BASE +#endif +#if CHIP_NPORTS > 9 + , PIC32MZ_IOPORTK_K1BASE +#endif +}; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: Inline PIN set field extractors + ****************************************************************************/ + +static inline bool pic32mz_output(uint16_t pinset) +{ + return ((pinset & GPIO_OUTPUT) != 0); +} + +static inline bool pic32mz_opendrain(uint16_t pinset) +{ + return ((pinset & GPIO_MODE_MASK) == GPIO_OPENDRAN); +} + +static inline bool pic32mz_outputhigh(uint16_t pinset) +{ + return ((pinset & GPIO_VALUE_MASK) != 0); +} + +static inline bool pic32mz_value(uint16_t pinset) +{ + return ((pinset & GPIO_VALUE_MASK) != GPIO_VALUE_ZERO); +} + +static inline unsigned int pic32mz_portno(uint16_t pinset) +{ + return ((pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT); +} + +static inline unsigned int pic32mz_pinno(uint16_t pinset) +{ + return ((pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT); +} + +static inline unsigned int pic32mz_analog(uint16_t pinset) +{ + return ((pinset & GPIO_ANALOG_MASK) != 0); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: pic32mz_configgpio + * + * Description: + * Configure a GPIO pin based on bit-encoded description of the pin (the + * interrupt will be configured when pic32mz_attach() is called. + * + * Returned Value: + * OK on success; negated errno on failure. + * + ****************************************************************************/ + +int pic32mz_configgpio(uint16_t cfgset) +{ + unsigned int port = pic32mz_portno(cfgset); + unsigned int pin = pic32mz_pinno(cfgset); + uint32_t mask = (1 << pin); + uintptr_t base; + + /* Verify that the port number is within range */ + + if (port < CHIP_NPORTS) + { + /* Get the base address of the ports */ + + base = g_gpiobase[port]; + + /* Is this an input or an output? */ + + sched_lock(); + if (pic32mz_output(cfgset)) + { + /* Not analog */ + + putreg32(mask, base + PIC32MZ_IOPORT_ANSELCLR_OFFSET); + + /* It is an output; clear the corresponding bit in the TRIS register */ + + putreg32(mask, base + PIC32MZ_IOPORT_TRISCLR_OFFSET); + + /* Is it an open drain output? */ + + if (pic32mz_opendrain(cfgset)) + { + /* It is an open drain output. Set the corresponding bit in + * the ODC register. + */ + + putreg32(mask, base + PIC32MZ_IOPORT_ODCSET_OFFSET); + } + else + { + /* Is is a normal output. Clear the corresponding bit in the + * ODC register. + */ + + putreg32(mask, base + PIC32MZ_IOPORT_ODCCLR_OFFSET); + } + + /* Set the initial output value */ + + pic32mz_gpiowrite(cfgset, pic32mz_outputhigh(cfgset)); + } + else + { + /* It is an input; set the corresponding bit in the TRIS register. */ + + putreg32(mask, base + PIC32MZ_IOPORT_TRISSET_OFFSET); + putreg32(mask, base + PIC32MZ_IOPORT_ODCCLR_OFFSET); + + /* Is it an analog input? */ + + if (pic32mz_analog(cfgset)) + { + putreg32(mask, base + PIC32MZ_IOPORT_ANSELSET_OFFSET); + } + else + { + putreg32(mask, base + PIC32MZ_IOPORT_ANSELCLR_OFFSET); + } + } + + sched_unlock(); + return OK; + } + + return -EINVAL; +} + +/**************************************************************************** + * Name: pic32mz_gpiowrite + * + * Description: + * Write one or zero to the selected GPIO pin + * + ****************************************************************************/ + +void pic32mz_gpiowrite(uint16_t pinset, bool value) +{ + unsigned int port = pic32mz_portno(pinset); + unsigned int pin = pic32mz_pinno(pinset); + uintptr_t base; + + /* Verify that the port number is within range */ + + if (port < CHIP_NPORTS) + { + /* Get the base address of the ports */ + + base = g_gpiobase[port]; + + /* Set or clear the output */ + + if (value) + { + putreg32(1 << pin, base + PIC32MZ_IOPORT_PORTSET_OFFSET); + } + else + { + putreg32(1 << pin, base + PIC32MZ_IOPORT_PORTCLR_OFFSET); + } + } +} + +/**************************************************************************** + * Name: pic32mz_gpioread + * + * Description: + * Read one or zero from the selected GPIO pin + * + ****************************************************************************/ + +bool pic32mz_gpioread(uint16_t pinset) +{ + unsigned int port = pic32mz_portno(pinset); + unsigned int pin = pic32mz_pinno(pinset); + uintptr_t base; + + /* Verify that the port number is within range */ + + if (port < CHIP_NPORTS) + { + /* Get the base address of the ports */ + + base = g_gpiobase[port]; + + /* Get ane return the input value */ + + return (getreg32(base + PIC32MZ_IOPORT_PORT_OFFSET) & (1 << pin)) != 0; + } + + return false; +} + +/**************************************************************************** + * Function: pic32mz_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 pic32mz_dumpgpio(uint32_t pinset, const char *msg) +{ + unsigned int port = pic32mz_portno(pinset); + irqstate_t flags; + uintptr_t base; + + /* Verify that the port number is within range */ + + if (port < CHIP_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 + PIC32MZ_IOPORT_TRIS_OFFSET), + getreg32(base + PIC32MZ_IOPORT_PORT_OFFSET), + getreg32(base + PIC32MZ_IOPORT_LAT_OFFSET), + getreg32(base + PIC32MZ_IOPORT_ODC_OFFSET)); + lldbg(" CNCON: %08x CNEN: %08x CNPUE: %08x\n", + getreg32(PIC32MZ_IOPORT_CNCON), + getreg32(PIC32MZ_IOPORT_CNEN), + getreg32(PIC32MZ_IOPORT_CNPUE)); + sched_unlock(); + } +} +#endif + +#endif /* CHIP_NPORTS > 0 */ |