/**************************************************************************** * 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