diff --git a/graphics/twm4nx/README.txt b/graphics/twm4nx/README.txt index ac8fc775b..9f7246e89 100644 --- a/graphics/twm4nx/README.txt +++ b/graphics/twm4nx/README.txt @@ -70,3 +70,4 @@ STATUS 1. The is a small artifact in the upper lefthand corner. I am not sure exactly what that is. 2. The logic to move an icon on the desk top does not work. + 3. There is no calibration screen for touchscreen calibration. diff --git a/system/spi/.gitignore b/system/spi/.gitignore new file mode 100644 index 000000000..83bd7b811 --- /dev/null +++ b/system/spi/.gitignore @@ -0,0 +1,11 @@ +/Make.dep +/.depend +/.built +/*.asm +/*.rel +/*.lst +/*.sym +/*.adb +/*.lib +/*.src +/*.obj diff --git a/system/spi/Kconfig b/system/spi/Kconfig new file mode 100644 index 000000000..0f3a62ff0 --- /dev/null +++ b/system/spi/Kconfig @@ -0,0 +1,72 @@ +# +# For a description of the syntax of this configuration file, +# see the file kconfig-language.txt in the NuttX tools repository. +# + +menuconfig SYSTEM_SPITOOL + tristate "SPI tool" + default n + depends on SPI + select SPI_DRIVER + ---help--- + Enable support for the SPI tool. + +if SYSTEM_SPITOOL + +config SPITOOL_PROGNAME + string "Program name" + default "hello" + depends on BUILD_LOADABLE + ---help--- + This is the name of the program that will be use when the ELF + program is installed. + +config SPITOOL_PRIORITY + int "Task priority" + default 100 + +config SPITOOL_STACKSIZE + int "Stack size" + default 2048 + +config SPITOOL_MINBUS + int "Minimum bus number" + default 0 + ---help--- + Smallest bus index supported by the hardware (default 0). + +config SPITOOL_MAXBUS + int "Maximum bus number" + default 3 + ---help--- + Largest bus index supported by the hardware (default 3) + +config SPITOOL_DEFFREQ + int "SPI frequency" + default 4000000 + ---help--- + Default SPI frequency (default: 4000000) + +config SPITOOL_DEFMODE + int "SPI mode" + default 0 + ---help--- + Default SPI mode, where; + 0 = CPOL=0, CHPHA=0 + 1 = CPOL=0, CHPHA=1 + 2 = CPOL=1, CHPHA=0 + 3 = CPOL=1, CHPHA=1 + +config SPITOOL_DEFWIDTH + int "SPI Bit width" + default 8 + ---help--- + Number of bits per SPI transfer (default 8) + +config SPITOOL_DEFWORDS + int "Number of words to transfer" + default 1 + ---help--- + Number of words to be transferred (default 1) + +endif # SYSTEM_SPITOOL diff --git a/system/spi/Make.defs b/system/spi/Make.defs new file mode 100644 index 000000000..bb7cc58db --- /dev/null +++ b/system/spi/Make.defs @@ -0,0 +1,39 @@ +############################################################################ +# apps/system/spi/Make.defs +# Adds selected applications to apps/ build +# +# Copyright (C) 2019 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. +# +############################################################################ + +ifneq ($(CONFIG_SYSTEM_SPITOOL),) +CONFIGURED_APPS += system/spi +endif diff --git a/system/spi/Makefile b/system/spi/Makefile new file mode 100644 index 000000000..5c37756fe --- /dev/null +++ b/system/spi/Makefile @@ -0,0 +1,55 @@ +############################################################################ +# apps/system/spi/Makefile +# +# Copyright (C) 2019 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 + +# SPI tool + +CSRCS = spi_bus.c spi_devif.c spi_exch.c spi_common.c +MAINSRC = spi_main.c + +CONFIG_SPITOOL_PRIORITY ?= SCHED_PRIORITY_DEFAULT +CONFIG_SPITOOL_STACKSIZE ?= 2048 + +APPNAME = spi +PRIORITY = $(CONFIG_SPITOOL_PRIORITY) +STACKSIZE = $(CONFIG_SPITOOL_STACKSIZE) + +CONFIG_SPITOOL_PROGNAME ?= spi$(EXEEXT) +PROGNAME = $(CONFIG_SPITOOL_PROGNAME) + +MODULE = CONFIG_SYSTEM_SPITOOL + +include $(APPDIR)/Application.mk diff --git a/system/spi/README.txt b/system/spi/README.txt new file mode 100644 index 000000000..aae90b2ae --- /dev/null +++ b/system/spi/README.txt @@ -0,0 +1,226 @@ +README File for the SPI Tool +============================ + +The I2C tool provides a way to debug SPI related problems. This README file +will provide usage information for the SPI tools. + +CONTENTS +======== + + o System Requirements + - SPI Driver + - Configuration Options + o Help + o Common Line Form + o Common Command Options + - "Sticky" Options + - Environment variables + - Common Option Summary + o Command summary + - bus + - dev + - get + - set + - verf + o I2C Build Configuration + - NuttX Configuration Requirements + - I2C Tool Configuration Options + +System Requirements +=================== + +The SPI tool is designed to be implemented as a NuttShell (NSH) add-on. Read +the apps/nshlib/README.txt file for information about add-ons. + +Configuration Options +--------------------- +CONFIG_NSH_BUILTIN_APPS - Build the tools as an NSH built-in command +CONFIG_SPITOOL_MINBUS - Smallest bus index supported by the hardware (default 0). +CONFIG_SPITOOL_MAXBUS - Largest bus index supported by the hardware (default 3) +CONFIG_SPITOOL_DEFFREQ - Default frequency (default: 40000000) +CONFIG_SPITOOL_DEFMODE - Default mode, where; + 0 = CPOL=0, CHPHA=0 + 1 = CPOL=0, CHPHA=1 + 2 = CPOL=1, CHPHA=0 + 3 = CPOL=1, CHPHA=1 +CONFIG_SPITOOL_DEFWIDTH - Default bit width (default 8) +CONFIG_SPITOOL_DEFWORDS - Default number of words to exchange (default 1) + +HELP +==== + +he SPI tools supports some help output. That help output can be view +by entering either: + + nsh> spi help + +or + + nsh> spi ? + +Here is an example of the help output. I shows the general form of the +command line, the various SPI commands supported with their unique command +line options, and a more detailed summary of the command SPI command +options. + +nsh> Usage: spi [arguments] +Where is one of: + + Show help : ? + List busses : bus + SPI Exchange : exch [OPTIONS] [] + Show help : help + +Where common "sticky" OPTIONS include: + [-b bus] is the SPI bus number (decimal). Default: 0 Current: 2 + [-f freq] SPI frequency. Default: 4000000 Current: 4000000 + [-m mode] Mode for transfer. Default: 0 Current: 0 + [-u udelay] Delay after transfer in uS. Default: 0 Current: 0 + [-w width] Width of bus. Default: 8 Current: 8 + [-x count] Words to exchange Default: 1 Current: 4 + +NOTES: +o An environment variable like $PATH may be used for any argument. +o Arguments are "sticky". For example, once the SPI address is + specified, that address will be re-used until it is changed. + +WARNING: +o The SPI commands may have bad side effects on your SPI devices. + Use only at your own risk. + +COMMAND LINE FORM +================= + +The SPI is started from NSH by invoking the 'spi' command from the NSH +command line. The general form of the 'spi' command is: + + spi [arguments] + +Where is a "sub-command" and identifies one SPI operation supported +by the tool. [arguments] represents the list of arguments needed to perform +the SPI operation. Those arguments vary from command to command as +described below. However, there is also a core set of common OPTIONS +supported by all commands. So perhaps a better representation of the +general SPI command would be: + + i2c [OPTIONS] [arguments] + +Where [OPTIONS] represents the common options and and arguments represent +the operation-specific arguments. + +COMMON COMMAND OPTIONS +====================== + +"Sticky" Options +---------------- +In order to interact with SPI devices, there are a number of SPI parameters +that must be set correctly. One way to do this would be to provide to set +the value of each separate command for each SPI parameter. The SPI tool +takes a different approach, instead: The SPI configuration can be specified +as a (potentially long) sequence of command line arguments. + +These arguments, however, are "sticky." They are sticky in the sense that +once you set the SPI parameter, that value will remain until it is reset +with a new value (or until you reset the board). + +Environment Variables +--------------------- +NOTE also that if environment variables are not disabled (by +CONFIG_DISABLE_ENVIRON=y), then these options may also be environment +variables. Environment variables must be preceded with the special +character $. For example, PWD is the variable that holds the current +working directory and so $PWD could be used as a command line argument. The +use of environment variables on the I2C tools command is really only useful +if you wish to write NSH scripts to execute a longer, more complex series of +SPI commands. + +Common Option Summary +--------------------- + +[-b bus] is the SPI bus number (decimal). Default: 0 + Which SPI bus to commiuncate on. The bus must have been initialised + as a character device in the config in the form /dev/spiX (e.g. /dev/spi2). + + The valid range of bus numbers is controlled by the configuration settings + CONFIG_SPITOOL_MINBUS and CONFIG_SPITOOL_MAXBUS. + + The bus numbers are small, decimal numbers. + +[-m mode] SPI Mode for transfer. + Which of the available SPI modes is to be used. Options are; + 0 = CPOL=0, CHPHA=0 + 1 = CPOL=0, CHPHA=1 + 2 = CPOL=1, CHPHA=0 + 3 = CPOL=1, CHPHA=1 + + [-u udelay] Delay after transfer in uS. Default: 0 + Any extra delay to be provided after the transfer. Not normally needed + from the command line. + +[-x count] Words to exchange Default: 1 + The number of words to be transited over the bus. For sanitys sake this is + limited to a relatively small number (40 by default). Any data on the + command line is sent first, padded by 0xFF's while any remaining data + are received. + +[-w width] is the data width (varies according to target). Default: 8 + + Various SPI devices support different data widths. This option is untested. + +[-f freq] I2C frequency. Default: 4000000 Current: 4000000 + + The [-f freq] sets the frequency of the SPI device. The default is very conservative. + +COMMAND SUMMARY +=============== + +List buses: bus [OPTIONS] +-------------------------- + +This command will simply list all of the configured SPI buses and indicate +which are supported by the driver and which are not: + + BUS EXISTS? + Bus 1: YES + Bus 2: NO + +The valid range of bus numbers is controlled by the configuration settings +CONFIG_SPITOOL_MINBUS and CONFIG_SPITOOL_MAXBUS. + +Exchange data: exch [OPTIONS] +------------------------------------------------ + +This command triggers an SPI transfer, returning the data back from the far end. +As an example (with MOSI looped back to MISO); + +nsh>spi exch -b 2 -x 4 aabbccdd +Received: AA BB CC DD +nsh> + +Note that the TXData are always specified in hex, and are always two digits each, +case insensitive. + +I2C BUILD CONFIGURATION +======================= + +NuttX Configuration Requirements +-------------------------------- +The SPI tools requires the following in your NuttX configuration: + +1. Application configuration. + + Using 'make menuconfig', select the SPI tool. The following + definition should appear in your .config file: + + CONFIG_SYSTEM_SPI=y + +2. Device-specific SPI driver support must be enabled: + + CONFIG_SPI_DRIVER=y + + The SPI tool will then use the SPI character driver to access the SPI + bus. These devices will reside at /dev/spiN where N is the I2C bus + number. + + NOTE 1: The SPI driver ioctl interface is defined in + include/nuttx/spi/spi.h. diff --git a/system/spi/spi_bus.c b/system/spi/spi_bus.c new file mode 100644 index 000000000..f16efa4ca --- /dev/null +++ b/system/spi/spi_bus.c @@ -0,0 +1,73 @@ +/**************************************************************************** + * apps/system/spi/spi_bus.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Dave Marples + * + * 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 "spitool.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spicmd_bus + ****************************************************************************/ + +int spicmd_bus(FAR struct spitool_s *spitool, int argc, char **argv) +{ + int bus; + + spitool_printf(spitool, " BUS EXISTS?\n"); + for (bus = CONFIG_SPITOOL_MINBUS; bus <= CONFIG_SPITOOL_MAXBUS; bus++) + { + if (spidev_exists(bus)) + { + spitool_printf(spitool, "Bus %d: YES\n", bus); + } + else + { + spitool_printf(spitool, "Bus %d: NO\n", bus); + } + } + + return OK; +} diff --git a/system/spi/spi_common.c b/system/spi/spi_common.c new file mode 100644 index 000000000..d23692399 --- /dev/null +++ b/system/spi/spi_common.c @@ -0,0 +1,220 @@ +/**************************************************************************** + * apps/system/spi/spi_common.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Dave Marples + * + * 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 "spitool.h" + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: arg_string + ****************************************************************************/ + +static int arg_string(FAR char **arg, FAR char **value) +{ + FAR char *ptr = *arg; + + if (ptr[2] == '\0') + { + *value = arg[1]; + return 2; + } + else + { + *value = &ptr[2]; + return 1; + } +} + +/**************************************************************************** + * Name: arg_decimal + ****************************************************************************/ + +static int arg_decimal(FAR char **arg, FAR long *value) +{ + FAR char *string; + int ret; + + ret = arg_string(arg, &string); + *value = strtol(string, NULL, 10); + return ret; +} + +/**************************************************************************** + * Name: arg_hex + ****************************************************************************/ + +#if 0 /* Not used */ +static int arg_hex(FAR char **arg, FAR long *value) +{ + FAR char *string; + int ret; + + ret = arg_string(arg, &string); + *value = strtol(string, NULL, 16); + return ret; +} +#endif + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spitool_common_args + ****************************************************************************/ + +int spitool_common_args(FAR struct spitool_s *spitool, FAR char **arg) +{ + FAR char *ptr = *arg; + long value; + int ret; + + if (ptr[0] != '-') + { + goto invalid_argument; + } + + switch (ptr[1]) + { + case 'b': + ret = arg_decimal(arg, &value); + if (value < CONFIG_SPITOOL_MINBUS || value > CONFIG_SPITOOL_MAXBUS) + { + goto out_of_range; + } + + if (!spidev_exists((int)value)) + { + goto invalid_argument; + } + + spitool->bus = (uint8_t)value; + return ret; + +#ifdef CONFIG_SPI_CMDDATA + case 'c': + ret = arg_decimal(arg, &value); + if ((value < 0) || (value > 1)) + { + goto out_of_range; + } + + spitool->command = value; + return ret; +#endif + + case 'm': + ret = arg_decimal(arg, &value); + if ((value < 0) || (value > 3)) + { + goto out_of_range; + } + + spitool->mode = value; + return ret; + + case 'f': + ret = arg_decimal(arg, &value); + if (value == 0) + { + goto out_of_range; + } + + spitool->freq = value; + return ret; + + case 'r': + ret = arg_decimal(arg, &value); + if (value < 0) + { + goto out_of_range; + } + + spitool->count = (uint32_t)value; + return ret; + + case 'u': + ret = arg_decimal(arg, &value); + if ((value < 0) || (value > 65535)) + { + goto out_of_range; + } + + spitool->udelay = value; + return ret; + + case 'w': + ret = arg_decimal(arg, &value); + if (value != 8 && value != 16) + { + goto out_of_range; + } + + spitool->width = (uint8_t)value; + return ret; + + case 'x': + ret = arg_decimal(arg, &value); + if ((value < 0) || (value > MAX_XDATA)) + { + goto out_of_range; + } + + spitool->count = value; + return ret; + + default: + goto invalid_argument; + } + +invalid_argument: + spitool_printf(spitool, g_spiarginvalid, ptr); + return ERROR; + +out_of_range: + spitool_printf(spitool, g_spiargrange, ptr); + return ERROR; +} diff --git a/system/spi/spi_devif.c b/system/spi/spi_devif.c new file mode 100644 index 000000000..bc8a74509 --- /dev/null +++ b/system/spi/spi_devif.c @@ -0,0 +1,137 @@ +/**************************************************************************** + * apps/system/i2c/i2c_devif.c + * + * Copyright (C) 2019 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 "spitool.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Device naming */ + +#define DEVNAME_FMT "/dev/spi%d" +#define DEVNAME_FMTLEN (8 + 3 + 1) + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static char g_devname[DEVNAME_FMTLEN]; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spidev_path + ****************************************************************************/ + +FAR char *spidev_path(int bus) +{ + snprintf(g_devname, DEVNAME_FMTLEN, DEVNAME_FMT, bus); + return g_devname; +} + +/**************************************************************************** + * Name: spidev_exists + ****************************************************************************/ + +bool spidev_exists(int bus) +{ + struct stat buf; + FAR char *devpath; + int ret; + + /* Get the device path */ + + devpath = spidev_path(bus); + + /* Check if something exists at that path */ + + ret = stat(devpath, &buf); + if (ret >= 0) + { + /* Return TRUE only if it is a character driver */ + + if (S_ISCHR(buf.st_mode)) + { + return true; + } + } + + return false; +} + +/**************************************************************************** + * Name: spidev_open + ****************************************************************************/ + +int spidev_open(int bus) +{ + FAR char *devpath; + + /* Get the device path */ + + devpath = spidev_path(bus); + + /* Open the file for read-only access (we need only IOCTLs) */ + + return open(devpath, O_RDONLY); +} + +/**************************************************************************** + * Name: spidev_transfer + ****************************************************************************/ + +int spidev_transfer(int fd, FAR struct spi_sequence_s *seq) +{ + /* Perform the IOCTL */ + + return ioctl(fd, SPIIOC_TRANSFER, (unsigned long)((uintptr_t)seq)); +} diff --git a/system/spi/spi_exch.c b/system/spi/spi_exch.c new file mode 100644 index 000000000..ebfa3d3c0 --- /dev/null +++ b/system/spi/spi_exch.c @@ -0,0 +1,185 @@ +/**************************************************************************** + * apps/system/spi/spi_exch.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Dave Marples + * + * 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 "spitool.h" + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spicmd_exch + ****************************************************************************/ + +#define ISHEX(x) ((((x)>='0') && ((x)<='9')) || ((toupper(x)>='A') && (toupper(x)<='F'))) +#define HTOI(x) ( (((x)>='0') && ((x)<='9')) ? (x)-'0':toupper(x)-'A'+10 ) + +int spicmd_exch(FAR struct spitool_s *spitool, int argc, FAR char **argv) +{ + FAR char *ptr; + int nargs; + int argndx; + int ret; + int fd; + + uint8_t txdata[MAX_XDATA] = + { + 0 + }; + uint8_t rxdata[MAX_XDATA] = + { + 0 + }; + uint8_t *txdatap = txdata; + struct spi_trans_s trans; + struct spi_sequence_s seq; + uint32_t d; + + /* Parse any command line arguments */ + + for (argndx = 1; argndx < argc; ) + { + /* Break out of the loop when the last option has been parsed */ + + ptr = argv[argndx]; + if (*ptr != '-') + { + break; + } + + /* Otherwise, check for common options */ + + nargs = spitool_common_args(spitool, &argv[argndx]); + if (nargs < 0) + { + return ERROR; + } + + argndx += nargs; + } + + /* There may be transmit data on the command line */ + + if (argndx < argc) + { + FAR uint8_t *a = (uint8_t *)argv[argndx]; + while (*a) + { + if ((*(a + 1) == 0) || !ISHEX(*a) || !ISHEX(*(a + 1))) + { + /* Uneven number of characters or illegal char .... that's an error */ + + spitool_printf(spitool, g_spiincompleteparam, argv[0]); + return ERROR; + } + + *txdatap++ = (HTOI(*a) << 4) | HTOI(*(a + 1)); + a += 2; + } + + argndx += 1; + } + + if (argndx != argc) + { + spitool_printf(spitool, g_spitoomanyargs, argv[0]); + return ERROR; + } + + /* Get a handle to the SPI bus */ + + fd = spidev_open(spitool->bus); + if (fd < 0) + { + spitool_printf(spitool, "Failed to get bus %d\n", spitool->bus); + return ERROR; + } + + /* Set up the transfer profile */ + + seq.mode = spitool->mode; + seq.nbits = spitool->width; + seq.frequency = spitool->freq; + seq.ntrans = 1; + seq.trans = &trans; + + trans.deselect = false; +#ifdef CONFIG_SPI_CMDDATA + trans.cmd = spitool->command; +#endif + trans.delay = spitool->udelay; + trans.nwords = spitool->count; + trans.txbuffer = txdata; + trans.rxbuffer = rxdata; + + ret = spidev_transfer(fd, &seq); + + (void)close(fd); + + if (ret) + { + return ret; + } + + spitool_printf(spitool, "Received: "); + for (d = 0; d < spitool->count; d++) + { + if (spitool->width <= 8) + { + spitool_printf(spitool, "%02X ", rxdata[d]); + } + else + { + spitool_printf(spitool, "%04X ", ((uint16_t *)rxdata)[d]); + } + } + + spitool_printf(spitool, "\n"); + + return ret; +} diff --git a/system/spi/spi_main.c b/system/spi/spi_main.c new file mode 100644 index 000000000..8a905d346 --- /dev/null +++ b/system/spi/spi_main.c @@ -0,0 +1,459 @@ +/**************************************************************************** + * apps/system/spi/spi_main.c + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Dave Marples + * + * 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 Gregory Nutt 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 +#include + +#include "spitool.h" + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +static int spicmd_help(FAR struct spitool_s *spitool, int argc, char **argv); +static int spicmd_unrecognized(FAR struct spitool_s *spitool, int argc, + FAR char **argv); + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +static struct spitool_s g_spitool; + +static const struct cmdmap_s g_spicmds[] = +{ + { "?", spicmd_help, "Show help ", NULL }, + { "bus", spicmd_bus, "List busses ", NULL }, + { "exch", spicmd_exch, "SPI Exchange ", "[OPTIONS] []" }, + { "help", spicmd_help, "Show help ", NULL }, + { NULL, NULL, NULL, NULL } +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +/* Common, message formats */ + +const char g_spiargrequired[] = "spitool: %s: missing required argument(s)\n"; +const char g_spiarginvalid[] = "spitool: %s: argument invalid\n"; +const char g_spiargrange[] = "spitool: %s: value out of range\n"; +const char g_spicmdnotfound[] = "spitool: %s: command not found\n"; +const char g_spitoomanyargs[] = "spitool: %s: too many arguments\n"; +const char g_spicmdfailed[] = "spitool: %s: %s failed: %d\n"; +const char g_spixfrerror[] = "spitool: %s: Transfer failed: %d\n"; +const char g_spiincompleteparam[] = "spitool: %s: Odd number or illegal char in tx sequence\n"; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spicmd_help + ****************************************************************************/ + +static int spicmd_help(FAR struct spitool_s *spitool, int argc, + FAR char **argv) +{ + FAR const struct cmdmap_s *ptr; + + spitool_printf(spitool, "Usage: spi [arguments]\n"); + spitool_printf(spitool, "Where is one of:\n\n"); + + for (ptr = g_spicmds; ptr->cmd; ptr++) + { + if (ptr->usage) + { + spitool_printf(spitool, " %s: %s %s\n", + ptr->desc, ptr->cmd, ptr->usage); + } + else + { + spitool_printf(spitool, " %s: %s\n", ptr->desc, ptr->cmd); + } + } + + spitool_printf(spitool, "\nWhere common \"sticky\" OPTIONS include:\n"); + spitool_printf(spitool, " [-b bus] is the SPI bus number (decimal). " + "Default: %d Current: %d\n", + CONFIG_SPITOOL_MINBUS, spitool->bus); +#ifdef CONFIG_SPI_CMDDATA + spitool_printf(spitool, " [-c 0|1] Send in command mode. " + "Default: %d Current: %d\n", + CONFIG_SPITOOL_DEFCMD, spitool->command); +#endif + spitool_printf(spitool, " [-f freq] SPI frequency. " + "Default: %d Current: %d\n", + CONFIG_SPITOOL_DEFFREQ, spitool->freq); + + spitool_printf(spitool, " [-m mode] Mode for transfer. " + "Default: %d Current: %d\n", + CONFIG_SPITOOL_DEFMODE, spitool->mode); + + spitool_printf(spitool, " [-u udelay] Delay after transfer in uS. " + "Default: 0 Current: %d\n", spitool->udelay); + + spitool_printf(spitool, " [-w width] Width of bus. " + "Default: %d Current: %d\n", + CONFIG_SPITOOL_DEFWIDTH, spitool->width); + + spitool_printf(spitool, " [-x count] Words to exchange " + "Default: %d Current: %d Max: %d\n", + CONFIG_SPITOOL_DEFWORDS, spitool->count, MAX_XDATA); + + spitool_printf(spitool, "\nNOTES:\n"); +#ifndef CONFIG_DISABLE_ENVIRON + spitool_printf(spitool, "o An environment variable like $PATH may be used for any argument.\n"); +#endif + spitool_printf(spitool, "o Arguments are \"sticky\". For example, once the SPI address is\n"); + spitool_printf(spitool, " specified, that address will be re-used until it is changed.\n"); + spitool_printf(spitool, "\nWARNING:\n"); + spitool_printf(spitool, "o The SPI commands may have bad side effects on your SPI devices.\n"); + spitool_printf(spitool, " Use only at your own risk.\n"); + return OK; +} + +/**************************************************************************** + * Name: spicmd_unrecognized + ****************************************************************************/ + +static int spicmd_unrecognized(FAR struct spitool_s *spitool, int argc, + FAR char **argv) +{ + spitool_printf(spitool, g_spicmdnotfound, argv[0]); + return ERROR; +} + +/**************************************************************************** + * Name: spi_execute + ****************************************************************************/ + +static int spi_execute(FAR struct spitool_s *spitool, int argc, + FAR char *argv[]) +{ + FAR const struct cmdmap_s *cmdmap; + FAR const char *cmd; + cmd_t handler; + int ret; + + /* The form of argv is: + * + * argv[0]: The command name. This is argv[0] when the arguments + * are, finally, received by the command vtblr + * argv[1]: The beginning of argument (up to MAX_ARGUMENTS) + * argv[argc]: NULL terminating pointer + */ + + /* See if the command is one that we understand */ + + cmd = argv[0]; + handler = spicmd_unrecognized; + + for (cmdmap = g_spicmds; cmdmap->cmd; cmdmap++) + { + if (strcmp(cmdmap->cmd, cmd) == 0) + { + handler = cmdmap->handler; + break; + } + } + + ret = handler(spitool, argc, argv); + return ret; +} + +/**************************************************************************** + * Name: spi_argument + ****************************************************************************/ + +static FAR char *spi_argument(FAR struct spitool_s *spitool, int argc, + FAR char *argv[], FAR int *pindex) +{ + FAR char *arg; + int index = *pindex; + + /* If we are at the end of the arguments with nothing, then return NULL */ + + if (index >= argc) + { + return NULL; + } + + /* Get the return parameter */ + + arg = argv[index]; + *pindex = index + 1; + +#ifndef CONFIG_DISABLE_ENVIRON + /* Check for references to environment variables */ + + if (arg[0] == '$') + { + /* Return the value of the environment variable with this name */ + + FAR char *value = getenv(arg + 1); + if (value) + { + return value; + } + else + { + return (FAR char *)""; + } + } +#endif + + /* Return the next argument. */ + + return arg; +} + +/**************************************************************************** + * Name: spi_parse + ****************************************************************************/ + +static int spi_parse(FAR struct spitool_s *spitool, int argc, + FAR char *argv[]) +{ + FAR char *newargs[MAX_ARGUMENTS + 2]; + FAR char *cmd; + int nargs; + int index; + + /* Parse out the command, skipping the first argument (the program name) */ + + index = 1; + cmd = spi_argument(spitool, argc, argv, &index); + + /* Check if any command was provided */ + + if (!cmd) + { + /* An empty line is not an error and an unprocessed command cannot + * generate an error, but neither should they change the last + * command status. + */ + + return spicmd_help(spitool, 0, NULL); + } + + /* Parse all of the arguments following the command name. */ + + newargs[0] = cmd; + for (nargs = 1; nargs <= MAX_ARGUMENTS; nargs++) + { + newargs[nargs] = spi_argument(spitool, argc, argv, &index); + if (!newargs[nargs]) + { + break; + } + } + + newargs[nargs] = NULL; + + /* Then execute the command */ + + return spi_execute(spitool, nargs, newargs); +} + +/**************************************************************************** + * Name: spi_setup + ****************************************************************************/ + +static inline int spi_setup(FAR struct spitool_s *spitool) +{ + /* Initialize the output stream */ + +#ifdef CONFIG_SPITOOL_OUTDEV + spitool->ss_outfd = open(CONFIG_SPITOOL_OUTDEV, O_WRONLY); + if (spitool->ss_outfd < 0) + { + fprintf(stderr, g_spicmdfailed, "open", errno); + return ERROR; + } + + /* Create a standard C stream on the console device */ + + spitool->ss_outstream = fdopen(spitool->ss_outfd, "w"); + if (!spitool->ss_outstream) + { + fprintf(stderr, g_spicmdfailed, "fdopen", errno); + return ERROR; + } +#endif + + return OK; +} + +/**************************************************************************** + * Name: spi_teardown + * + * Description: + * Close the output stream if it is not the standard output stream. + * + ****************************************************************************/ + +static void spi_teardown(FAR struct spitool_s *spitool) +{ + fflush(OUTSTREAM(&g_spitool)); + +#ifdef CONFIG_SPITOOL_OUTDEV + fclose(spitool->ss_outstream); +#endif +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: spi_main + ****************************************************************************/ + +#ifdef BUILD_MODULE +int main(int argc, FAR char *argv[]) +#else +int spi_main(int argc, char *argv[]) +#endif +{ + /* Verify settings */ + + if (g_spitool.bus < CONFIG_SPITOOL_MINBUS || + g_spitool.bus > CONFIG_SPITOOL_MAXBUS) + { + g_spitool.bus = CONFIG_SPITOOL_MINBUS; + } + + if (g_spitool.freq == 0) + { + g_spitool.freq = CONFIG_SPITOOL_DEFFREQ; + } + + if (g_spitool.mode == 0) + { + g_spitool.mode = CONFIG_SPITOOL_DEFMODE; + } + + if (g_spitool.width == 0) + { + g_spitool.width = CONFIG_SPITOOL_DEFWIDTH; + } + + if (g_spitool.count == 0) + { + g_spitool.count = CONFIG_SPITOOL_DEFWORDS; + } + + /* Parse and process the command line */ + + spi_setup(&g_spitool); + (void)spi_parse(&g_spitool, argc, argv); + + spitool_flush(&g_spitool); + spi_teardown(&g_spitool); + return OK; +} + +/**************************************************************************** + * Name: spitool_printf + * + * Description: + * Print a string to the currently selected stream. + * + ****************************************************************************/ + +int spitool_printf(FAR struct spitool_s *spitool, FAR const char *fmt, ...) +{ + va_list ap; + int ret; + + va_start(ap, fmt); + ret = vfprintf(OUTSTREAM(spitool), fmt, ap); + va_end(ap); + + return ret; +} + +/**************************************************************************** + * Name: spitool_write + * + * Description: + * write a buffer to the currently selected stream. + * + ****************************************************************************/ + +ssize_t spitool_write(FAR struct spitool_s *spitool, FAR const void *buffer, + size_t nbytes) +{ + ssize_t ret; + + /* Write the data to the output stream */ + + ret = fwrite(buffer, 1, nbytes, OUTSTREAM(spitool)); + if (ret < 0) + { + _err("ERROR: [%d] Failed to send buffer: %d\n", OUTFD(spitool), errno); + } + + return ret; +} + +/**************************************************************************** + * Name: spitool_flush + * + * Description: + * Flush buffered I/O to the currently selected stream. + * + ****************************************************************************/ + +void spitool_flush(FAR struct spitool_s *spitool) +{ + fflush(OUTSTREAM(spitool)); +} diff --git a/system/spi/spitool.h b/system/spi/spitool.h new file mode 100644 index 000000000..890aed1ad --- /dev/null +++ b/system/spi/spitool.h @@ -0,0 +1,216 @@ +/**************************************************************************** + * apps/system/spi/spitool.h + * + * Copyright (C) 2019 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * Dave Marples + * + * 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. + * + ****************************************************************************/ + +#ifndef __APPS_SYSTEM_SPI_SPITOOLS_H +#define __APPS_SYSTEM_SPI_SPITOOLS_H + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include + +#include +#include +#include +#include +#include + +#include + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +/* Configuration ************************************************************/ + +/* CONFIG_NSH_BUILTIN_APPS - Build the tools as an NSH built-in command + * CONFIG_SPITOOL_MINBUS - Smallest bus index supported by the hardware + * (default 0). + * CONFIG_SPITOOL_MAXBUS - Largest bus index supported by the hardware + * (default 3) + * CONFIG_SPITOOL_DEFFREQ - Default frequency (default: 40000000) + * CONFIG_SPITOOL_DEFMODE - Default mode, where; + * 0 = CPOL=0, CHPHA=0 + * 1 = CPOL=0, CHPHA=1 + * 2 = CPOL=1, CHPHA=0 + * 3 = CPOL=1, CHPHA=1 + * CONFIG_SPITOOL_DEFWIDTH - Default bit width (default 8) + * CONFIG_SPITOOL_DEFWORDS - Default number of words to exchange + * (default 1) + */ + +#ifndef CONFIG_SPITOOL_MINBUS +# define CONFIG_SPITOOL_MINBUS 0 +#endif + +#ifndef CONFIG_SPITOOL_MAXBUS +# define CONFIG_SPITOOL_MAXBUS 3 +#endif + +#ifndef CONFIG_SPITOOL_DEFFREQ +# define CONFIG_SPITOOL_DEFFREQ 4000000 +#endif + +#ifndef CONFIG_SPITOOL_DEFMODE +#define CONFIG_SPITOOL_DEFMODE 0 /* CPOL=0, CHPHA=0 */ +#endif + +#ifndef CONFIG_SPITOOL_DEFWIDTH +#define CONFIG_SPITOOL_DEFWIDTH 8 +#endif + +#ifndef CONFIG_SPITOOL_DEFWORDS +#define CONFIG_SPITOOL_DEFWORDS 1 +#endif + +/* This is the maximum number of arguments that will be accepted for a + * command. This is only used for sizing a hardcoded array and is set + * to be sufficiently large to support all possible SPI tool arguments and + * then some. + */ + +#define MAX_ARGUMENTS 12 + +/* Maximum size of one command line */ + +#define MAX_LINELEN 80 +#define MAX_XDATA (MAX_LINELEN/2) + +/* Are we using the NuttX console for I/O? Or some other character device? */ + +#ifdef CONFIG_SPITOOL_INDEV +# define INFD(p) ((p)->ss_infd) +# define INSTREAM(p) ((p)->ss_instream) +#else +# define INFD(p) 0 +# define INSTREAM(p) stdin +#endif + +#ifdef CONFIG_SPITOOL_OUTDEV +# define OUTFD(p) ((p)->ss_outfd) +# define OUTSTREAM(p) ((p)->ss_outstream) +#else +# define OUTFD(p) 1 +# define OUTSTREAM(p) stdout +#endif + +/* Output is via printf but can be changed using this macro */ + +#ifdef CONFIG_CPP_HAVE_VARARGS +# define spi_output(v, ...) printf(v, ##__VA_ARGS__) +#else +# define spi_output printf +#endif + +/**************************************************************************** + * Public Types + ****************************************************************************/ + +struct spitool_s +{ + /* Sticky options */ + + uint8_t bus; /* [-b bus] is the SPI bus number */ + uint8_t width; /* [-w width] is the data width (8 or 16) */ + uint32_t freq; /* [-f freq] SPI frequency */ + uint32_t count; /* [-x count] No of words to exchange */ + bool command; /* [-c 0|1] Send as command or data? */ + useconds_t udelay; /* [-u udelay] Delay in uS after transfer */ + uint8_t mode; /* [-m mode] Mode to use for transfer */ + + /* Output streams */ + +#ifdef CONFIG_SPITOOL_OUTDEV + int ss_outfd; /* Output file descriptor */ + FILE *ss_outstream; /* Output stream */ +#endif +}; + +typedef int (*cmd_t)(FAR struct spitool_s *spitool, int argc, + FAR char **argv); + +struct cmdmap_s +{ + FAR const char *cmd; /* Name of the command */ + cmd_t handler; /* Function that handles the command */ + FAR const char *desc; /* Short description */ + FAR const char *usage; /* Usage instructions for 'help' command */ +}; + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +extern const char g_spiargrequired[]; +extern const char g_spiarginvalid[]; +extern const char g_spiargrange[]; +extern const char g_spiincompleteparam[]; +extern const char g_spicmdnotfound[]; +extern const char g_spitoomanyargs[]; +extern const char g_spicmdfailed[]; +extern const char g_spixfrerror[]; + +/**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +/* Message handler */ + +ssize_t spitool_exchange(FAR struct spitool_s *spitool, + FAR const void *outbuffer, size_t noutbytes, + FAR void *inbuffer, size_t ninbytes); +int spitool_printf(FAR struct spitool_s *spitool, const char *fmt, ...); +void spitool_flush(FAR struct spitool_s *spitool); + +/* Command handlers */ + +int spicmd_bus(FAR struct spitool_s *spitool, int argc, FAR char **argv); +int spicmd_exch(FAR struct spitool_s *spitool, int argc, FAR char **argv); + +/* Common logic */ + +int spitool_common_args(FAR struct spitool_s *spitool, FAR char **arg); + +/* Driver access utilities */ + +FAR char *spidev_path(int bus); +bool spidev_exists(int bus); +int spidev_open(int bus); +int spidev_transfer(int fd, FAR struct spi_sequence_s *seq); + +#endif /* __APPS_SYSTEM_SPI_SPITOOLS_H */