From acbbd690f93374a7f15fe42bc10b2b3ddc176191 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 1 Aug 2016 13:53:20 -0600 Subject: [PATCH] apps/examples/gpio: Add a simple test of the GPIO driver --- examples/README.txt | 11 +- examples/gpio/.gitignore | 11 ++ examples/gpio/Kconfig | 31 ++++ examples/gpio/Make.defs | 39 +++++ examples/gpio/Makefile | 56 +++++++ examples/gpio/gpio_main.c | 330 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 475 insertions(+), 3 deletions(-) create mode 100644 examples/gpio/.gitignore create mode 100644 examples/gpio/Kconfig create mode 100644 examples/gpio/Make.defs create mode 100644 examples/gpio/Makefile create mode 100644 examples/gpio/gpio_main.c diff --git a/examples/README.txt b/examples/README.txt index 3331fe2e9..ca46fdce9 100644 --- a/examples/README.txt +++ b/examples/README.txt @@ -553,6 +553,11 @@ examples/ftpd CONFIG_NETUTILS_NETLIB=y CONFIG_NETUTILS_TELNED=y +examples/gpio +^^^^^^^^^^^^ + + A simple test/example of the NuttX GPIO driver. + examples/hello ^^^^^^^^^^^^^^ @@ -648,8 +653,8 @@ examples/igmp * CONFIG_EXAMPLES_NETLIB The networking library is needed -examples/adc -^^^^^^^^^^^^ +examples/i2cchar +^^^^^^^^^^^^^^^^ A mindlessly simple test of an I2C driver. It reads an write garbage data to the I2C transmitter and/or received as fast possible. @@ -741,7 +746,7 @@ examples/lcdrw NuttX is built as a protected, supervisor kernel (CONFIG_BUILD_PROTECTED or CONFIG_BUILD_KERNEL). -examples/adc +examples/leds ^^^^^^^^^^^^ This is a simple test of the board LED driver at nuttx/drivers/leds/userled_*.c. diff --git a/examples/gpio/.gitignore b/examples/gpio/.gitignore new file mode 100644 index 000000000..fa1ec7579 --- /dev/null +++ b/examples/gpio/.gitignore @@ -0,0 +1,11 @@ +/Make.dep +/.depend +/.built +/*.asm +/*.obj +/*.rel +/*.lst +/*.sym +/*.adb +/*.lib +/*.src diff --git a/examples/gpio/Kconfig b/examples/gpio/Kconfig new file mode 100644 index 000000000..1e0d8b5f1 --- /dev/null +++ b/examples/gpio/Kconfig @@ -0,0 +1,31 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +config EXAMPLES_GPIO + bool "GPIO driver example" + default n + depends on DEV_GPIO + ---help--- + Enable the GPIO driver example + +if EXAMPLES_GPIO + +config EXAMPLES_GPIO_PROGNAME + string "Program name" + default "gpio" + depends on BUILD_KERNEL + ---help--- + This is the name of the program that will be use when the NSH ELF + program is installed. + +config EXAMPLES_GPIO_PRIORITY + int "GPIO task priority" + default 100 + +config EXAMPLES_GPIO_STACKSIZE + int "GPIO stack size" + default 2048 + +endif diff --git a/examples/gpio/Make.defs b/examples/gpio/Make.defs new file mode 100644 index 000000000..78c636d9e --- /dev/null +++ b/examples/gpio/Make.defs @@ -0,0 +1,39 @@ +############################################################################ +# apps/examples/gpio/Make.defs +# Adds selected applications to apps/ build +# +# Copyright (C) 2015 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. +# +############################################################################ + +ifeq ($(CONFIG_EXAMPLES_GPIO),y) +CONFIGURED_APPS += examples/gpio +endif diff --git a/examples/gpio/Makefile b/examples/gpio/Makefile new file mode 100644 index 000000000..ba5696100 --- /dev/null +++ b/examples/gpio/Makefile @@ -0,0 +1,56 @@ +############################################################################ +# apps/examples/gpio/Makefile +# +# Copyright (C) 2008, 2010-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. +# +############################################################################ + +-include $(TOPDIR)/Make.defs + +# GPIO, World! built-in application info + +CONFIG_EXAMPLES_GPIO_PRIORITY ?= SCHED_PRIORITY_DEFAULT +CONFIG_EXAMPLES_GPIO_STACKSIZE ?= 2048 + +APPNAME = gpio +PRIORITY = $(CONFIG_EXAMPLES_GPIO_PRIORITY) +STACKSIZE = $(CONFIG_EXAMPLES_GPIO_STACKSIZE) + +# GPIO, World! Example + +ASRCS = +CSRCS = +MAINSRC = gpio_main.c + +CONFIG_EXAMPLES_GPIO_PROGNAME ?= gpio$(EXEEXT) +PROGNAME = $(CONFIG_EXAMPLES_GPIO_PROGNAME) + +include $(APPDIR)/Application.mk diff --git a/examples/gpio/gpio_main.c b/examples/gpio/gpio_main.c new file mode 100644 index 000000000..af0881bd0 --- /dev/null +++ b/examples/gpio/gpio_main.c @@ -0,0 +1,330 @@ +/**************************************************************************** + * examples/gpio/gpio_main.c + * + * Copyright (C) 2016 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 +#include + +#include + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void show_usage(FAR const char *progname) +{ + fprintf(stderr, "USAGE: %s [-w ] [-o ] \n"); + fprintf(stderr, " %s -h\n"); + fprintf(stderr, "Where:\n"); + fprintf(stderr, "\t: The full path to the GPIO pin driver.\n"); + fprintf(stderr, "\t-w : Wait for an signal if this is an interrupt pin.\n"); + fprintf(stderr, "\t-o : Write this value (0 or 1) if this is an output pin.\n"); + fprintf(stderr, "\t-h: Print this usage information and exit.\n"); +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * gpio_main + ****************************************************************************/ + +#ifdef CONFIG_BUILD_KERNEL +int main(int argc, FAR char *argv[]) +#else +int gpio_main(int argc, char *argv[]) +#endif +{ + FAR char *devpath = NULL; + enum gpio_pintype_e pintype; + bool havesigno = false; + bool invalue; + bool outvalue = false; + bool haveout = false; + int signo = 0; + int ndx; + int ret; + int fd; + + /* Parse command line */ + + if (argc < 2) + { + fprintf(stderr, "ERROR: Missing required arguments\n"); + show_usage(argv[0]); + return EXIT_FAILURE; + } + + ndx = 1; + if (strcmp(argv[ndx], "-h") == 0) + { + show_usage(argv[0]); + return EXIT_FAILURE; + } + + if (strcmp(argv[ndx], "-w") == 0) + { + havesigno = true; + + if (++ndx >= argc) + { + fprintf(stderr, "ERROR: Missing argument to -o\n"); + show_usage(argv[0]); + return EXIT_FAILURE; + } + + signo = atoi(argv[ndx]); + + if (++ndx >= argc) + { + fprintf(stderr, "ERROR: Missing required \n"); + show_usage(argv[0]); + return EXIT_FAILURE; + } + } + + if (ndx < argc && strcmp(argv[ndx], "-o")) + { + if (++ndx >= argc) + { + fprintf(stderr, "ERROR: Missing argument to -o\n"); + show_usage(argv[0]); + return EXIT_FAILURE; + } + + if (strcmp(argv[ndx], "0")) + { + outvalue = false; + haveout = true; + } + else if (strcmp(argv[ndx], "1")) + { + outvalue = true; + haveout = true; + } + else + { + fprintf(stderr, "ERROR: Invalid argument to -o\n"); + show_usage(argv[0]); + return EXIT_FAILURE; + } + + if (++ndx >= argc) + { + fprintf(stderr, "ERROR: Missing required \n"); + show_usage(argv[0]); + return EXIT_FAILURE; + } + + } + + devpath = argv[ndx]; + printf("Driver: %s\n", devpath); + + /* Open the pin driver */ + + fd = open(devpath, O_RDWR); + if (fd < 0) + { + int errcode = errno; + fprintf(stderr, "ERROR: Failed to open %s: %d\n", devpath, errcode); + return EXIT_FAILURE; + } + + /* Get the pin type */ + + ret = ioctl(fd, GPIOC_PINTYPE, (unsigned long)((uintptr_t)&pintype)); + if (ret < 0) + { + int errcode = errno; + fprintf(stderr, "ERROR: Failed to read pintype from %s: %d\n", devpath, errcode); + close(fd); + return EXIT_FAILURE; + } + + /* Read the pin value */ + + ret = ioctl(fd, GPIOC_READ, (unsigned long)((uintptr_t)&invalue)); + if (ret < 0) + { + int errcode = errno; + fprintf(stderr, "ERROR: Failed to read value from %s: %d\n", devpath, errcode); + close(fd); + return EXIT_FAILURE; + } + + /* Perform the test based on the pintype and on command line options */ + + switch (pintype) + { + case GPIO_INPUT_PIN: + { + printf(" Input pin: Value=%u\n", (unsigned int)invalue); + } + break; + + case GPIO_OUTPUT_PIN: + { + printf(" Output pin: Value=%u\n", (unsigned int)invalue); + + if (haveout) + { + printf(" Writing: Value=%u\n", (unsigned int)outvalue); + + /* Write the pin value */ + + ret = ioctl(fd, GPIOC_WRITE, (unsigned long)outvalue); + if (ret < 0) + { + int errcode = errno; + fprintf(stderr, "ERROR: Failed to write value %u from %s: %d\n", + devpath, (unsigned int)outvalue, errcode); + close(fd); + return EXIT_FAILURE; + } + + /* Re-read the pin value */ + + ret = ioctl(fd, GPIOC_READ, (unsigned long)((uintptr_t)&invalue)); + if (ret < 0) + { + int errcode = errno; + fprintf(stderr, "ERROR: Failed to re-read value from %s: %d\n", + devpath, errcode); + close(fd); + return EXIT_FAILURE; + } + + printf(" Verify: Value=%u\n", (unsigned int)invalue); + } + else + { + fprintf(stderr, "ERROR: Missing value to write\n"); + show_usage(argv[0]); + close(fd); + return EXIT_FAILURE; + } + } + break; + + case GPIO_INTERRUPT_PIN: + { + printf(" Interrupt pin: Value=%u\n", invalue); + + if (havesigno) + { + struct timespec ts; + struct siginfo info; + sigset_t set; + + /* Set up to receive signal */ + + ret = ioctl(fd, GPIOC_REGISTER, (unsigned long)signo); + if (ret < 0) + { + int errcode = errno; + fprintf(stderr, "ERROR: Failed to setup for signal from %s: %d\n", + devpath, errcode); + close(fd); + return EXIT_FAILURE; + } + + /* Wait up to 5 seconds for the signal */ + + (void)sigemptyset(&set); + (void)sigaddset(&set, signo); + + ts.tv_sec = 5; + ts.tv_nsec = 0; + + ret = sigtimedwait(&set, &info, &ts); + (void)ioctl(fd, GPIOC_UNREGISTER, 0); + + if (ret < 0) + { + int errcode = errno; + if (errcode == EAGAIN) + { + printf(" [Five second timeout with no signal]\n"); + close(fd); + return EXIT_SUCCESS; + } + else + { + fprintf(stderr, "ERROR: Failed to wait signal %d from %s: %d\n", + signo, devpath, errcode); + close(fd); + return EXIT_FAILURE; + } + } + + /* Re-read the pin value */ + + ret = ioctl(fd, GPIOC_READ, (unsigned long)((uintptr_t)&invalue)); + if (ret < 0) + { + int errcode = errno; + fprintf(stderr, "ERROR: Failed to re-read value from %s: %d\n", + devpath, errcode); + close(fd); + return EXIT_FAILURE; + } + + printf(" Verify: Value=%u\n", (unsigned int)invalue); + } + } + break; + + default: + fprintf(stderr, "ERROR: Unrecognized pintype: %d\n", (int)pintype); + close(fd); + return EXIT_FAILURE; + } + + close(fd); + return EXIT_SUCCESS; +}