diff --git a/arch/arm/src/nuc1xx/Make.defs b/arch/arm/src/nuc1xx/Make.defs index 7ccae77fa0..0d20f8135f 100644 --- a/arch/arm/src/nuc1xx/Make.defs +++ b/arch/arm/src/nuc1xx/Make.defs @@ -58,3 +58,7 @@ endif CHIP_ASRCS = CHIP_CSRCS = nuc_clockconfig.c nuc_gpio.c nuc_idle.c nuc_irq.c nuc_lowputc.c CHIP_CSRCS += nuc_serial.c nuc_start.c nuc_timerisr.c + +ifeq ($(CONFIG_DEBUG),y) +CHIP_CSRCS += nuc_dumpgpio.c +endif diff --git a/arch/arm/src/nuc1xx/chip/nuc_gpio.h b/arch/arm/src/nuc1xx/chip/nuc_gpio.h index 4e2f2d7f74..aea16ab0c6 100644 --- a/arch/arm/src/nuc1xx/chip/nuc_gpio.h +++ b/arch/arm/src/nuc1xx/chip/nuc_gpio.h @@ -55,6 +55,8 @@ #define NUC_GPIO_PORTD 3 #define NUC_GPIO_PORTE 4 +#define NUC_GPIO_NPORTS 5 + /* GPIO control registers */ #define NUC_GPIO_CTRL_OFFSET(n) (0x0000 + ((n) << 6)) diff --git a/arch/arm/src/nuc1xx/nuc_dumpgpio.c b/arch/arm/src/nuc1xx/nuc_dumpgpio.c new file mode 100644 index 0000000000..aee9fa2198 --- /dev/null +++ b/arch/arm/src/nuc1xx/nuc_dumpgpio.c @@ -0,0 +1,144 @@ +/**************************************************************************** + * arch/arm/src/nuc/nuc_gpio.c + * + * Copyright (C) 2013 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 "up_arch.h" + +#include "chip.h" +#include "nuc_gpio.h" + +#ifdef CONFIG_DEBUG + +/**************************************************************************** + * Private Data + ****************************************************************************/ +/* Port letters for prettier debug output */ + +#ifdef CONFIG_DEBUG +static const char g_portchar[NUC_GPIO_NPORTS] = +{ +#if NUC_GPIO_NPORTS > 9 +# error "Additional support required for this number of GPIOs" +#elif NUC_GPIO_NPORTS > 8 + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I' +#elif NUC_GPIO_NPORTS > 7 + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H' +#elif NUC_GPIO_NPORTS > 6 + 'A', 'B', 'C', 'D', 'E', 'F', 'G' +#elif NUC_GPIO_NPORTS > 5 + 'A', 'B', 'C', 'D', 'E', 'F' +#elif NUC_GPIO_NPORTS > 4 + 'A', 'B', 'C', 'D', 'E' +#elif NUC_GPIO_NPORTS > 3 + 'A', 'B', 'C', 'D' +#elif NUC_GPIO_NPORTS > 2 + 'A', 'B', 'C' +#elif NUC_GPIO_NPORTS > 1 + 'A', 'B' +#elif NUC_GPIO_NPORTS > 0 + 'A' +#else +# error "Bad number of GPIOs" +#endif +}; +#endif + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Function: nuc_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided pin description + * along with a descriptive messasge. + * + ****************************************************************************/ + +int nuc_dumpgpio(gpio_cfgset_t pinset, const char *msg) +{ + irqstate_t flags; + uintptr_t base; + int port; + + /* Decode the port and pin. Use the port number to get the GPIO base + * address. + */ + + port = (pinset & GPIO_PORT_MASK) >> GPIO_PORT_SHIFT; + DEBUGASSERT((unsigned)port <= NUC_GPIO_PORTE); + base = NUC_GPIO_CTRL_BASE(port); + + /* The following requires exclusive access to the GPIO registers */ + + flags = irqsave(); + + lldbg("GPIO%c pinset: %08x base: %08x -- %s\n", + g_portchar[port], pinset, base, msg); + lldbg(" PMD: %08x OFFD: %08x DOUT: %08x DMASK: %08x\n", + getreg32(base + NUC_GPIO_PMD_OFFSET), + getreg32(base + NUC_GPIO_OFFD_OFFSET), + getreg32(base + NUC_GPIO_DOUT_OFFSET), + getreg32(base + NUC_GPIO_DMASK_OFFSET)); + lldbg(" PIN: %08x DBEN: %08x IMD: %08x IEN: %08x\n", + getreg32(base + NUC_GPIO_PIN_OFFSET), + getreg32(base + NUC_GPIO_DBEN_OFFSET), + getreg32(base + NUC_GPIO_IMD_OFFSET), + getreg32(base + NUC_GPIO_IEN_OFFSET)); + lldbg(" ISRC: %08x\n", + getreg32(base + NUC_GPIO_ISRC_OFFSET)); + + irqrestore(flags); + return OK; +} + +#endif /* CONFIG_DEBUG */ diff --git a/arch/arm/src/nuc1xx/nuc_gpio.c b/arch/arm/src/nuc1xx/nuc_gpio.c index 1ba92a801f..366226a8cf 100644 --- a/arch/arm/src/nuc1xx/nuc_gpio.c +++ b/arch/arm/src/nuc1xx/nuc_gpio.c @@ -43,6 +43,8 @@ #include #include +#include + #include "up_arch.h" #include "chip.h" @@ -222,6 +224,10 @@ int nuc_configgpio(gpio_cfgset_t cfgset) void nuc_gpiowrite(gpio_cfgset_t pinset, bool value) { +#ifndef NUC_LOW + irqstate_t flags; + uintptr_t base; +#endif int port; int pin; @@ -233,7 +239,31 @@ void nuc_gpiowrite(gpio_cfgset_t pinset, bool value) pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; DEBUGASSERT((unsigned)port <= NUC_GPIO_PORTE); + + /* Only the low density NUC100/120 chips support bit-band access to GPIO + * pins. + */ + +#ifdef NUC_LOW putreg32((uint32_t)value, NUC_PORT_PDIO(port, pin)); +#else + /* Get the base address of the GPIO port registers */ + + base = NUC_GPIO_CTRL_BASE(port); + + /* Disable interrupts -- the following operations must be atomic */ + + flags = irqsave(); + + /* Allow writing only to the selected pin in the DOUT register */ + + putreg32(~(1 << pin), base + NUC_GPIO_DMASK_OFFSET); + + /* Set the pin to the selected value and re-enable interrupts */ + + putreg32(((uint32_t)value << pin), base + NUC_GPIO_DOUT_OFFSET); + irqrestore(flags); +#endif } /**************************************************************************** @@ -246,6 +276,9 @@ void nuc_gpiowrite(gpio_cfgset_t pinset, bool value) bool nuc_gpioread(gpio_cfgset_t pinset) { +#ifndef NUC_LOW + uintptr_t base; +#endif int port; int pin; @@ -257,5 +290,20 @@ bool nuc_gpioread(gpio_cfgset_t pinset) pin = (pinset & GPIO_PIN_MASK) >> GPIO_PIN_SHIFT; DEBUGASSERT((unsigned)port <= NUC_GPIO_PORTE); + + /* Only the low density NUC100/120 chips support bit-band access to GPIO + * pins. + */ + +#ifdef NUC_LOW return (getreg32(NUC_PORT_PDIO(port, pin)) & PORT_MASK) != 0; +#else + /* Get the base address of the GPIO port registers */ + + base = NUC_GPIO_CTRL_BASE(port); + + /* Return the state of the selected pin */ + + return (getreg32(base + NUC_GPIO_PIN_OFFSET) & (1 << pin)) != 0; +#endif } diff --git a/arch/arm/src/nuc1xx/nuc_gpio.h b/arch/arm/src/nuc1xx/nuc_gpio.h index 7da42af8f9..807080475e 100644 --- a/arch/arm/src/nuc1xx/nuc_gpio.h +++ b/arch/arm/src/nuc1xx/nuc_gpio.h @@ -74,7 +74,7 @@ * MM.. .... .... .... */ -#define GPIO_MODE_SHIFT (14) /* Bits 145_15: GPIO mode */ +#define GPIO_MODE_SHIFT (14) /* Bits 14-15: GPIO mode */ #define GPIO_MODE_MASK (3 << GPIO_MODE_SHIFT) # define GPIO_INPUT (0 << GPIO_MODE_SHIFT) /* Input */ # define GPIO_OUTPUT (1 << GPIO_MODE_SHIFT) /* Push-pull output */ @@ -146,6 +146,7 @@ # define GPIO_PORTD (3 << GPIO_PORT_SHIFT) /* GPIOD */ # define GPIO_PORTE (4 << GPIO_PORT_SHIFT) /* GPIOE */ # + /* This identifies the bit in the port: * * 1111 1100 0000 0000 @@ -234,6 +235,21 @@ void nuc_gpiowrite(gpio_cfgset_t pinset, bool value); bool nuc_gpioread(gpio_cfgset_t pinset); +/**************************************************************************** + * Function: nuc_dumpgpio + * + * Description: + * Dump all GPIO registers associated with the provided pin description + * along with a descriptive messasge. + * + ****************************************************************************/ + +#ifdef CONFIG_DEBUG +int nuc_dumpgpio(gpio_cfgset_t pinset, const char *msg); +#else +# define nuc_dumpgpio(p,m) +#endif + #undef EXTERN #if defined(__cplusplus) }