apps/system/spi: I needed a small test tool for spi in the style of the i2c tool, but I didn't see one so I've hacked one out of the i2c tool source.

This commit is contained in:
Dave Marples 2019-05-10 18:14:44 -06:00 committed by Gregory Nutt
parent dbb5211060
commit 80de28c865
12 changed files with 1694 additions and 0 deletions

View File

@ -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.

11
system/spi/.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
/Make.dep
/.depend
/.built
/*.asm
/*.rel
/*.lst
/*.sym
/*.adb
/*.lib
/*.src
/*.obj

72
system/spi/Kconfig Normal file
View File

@ -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

39
system/spi/Make.defs Normal file
View File

@ -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 <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.
#
############################################################################
ifneq ($(CONFIG_SYSTEM_SPITOOL),)
CONFIGURED_APPS += system/spi
endif

55
system/spi/Makefile Normal file
View File

@ -0,0 +1,55 @@
############################################################################
# apps/system/spi/Makefile
#
# Copyright (C) 2019 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.
#
############################################################################
-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

226
system/spi/README.txt Normal file
View File

@ -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 <cmd> [arguments]
Where <cmd> is one of:
Show help : ?
List busses : bus
SPI Exchange : exch [OPTIONS] [<hex senddata>]
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 <cmd> [arguments]
Where <cmd> 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 <cmd> [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] <Optional TX Data>
------------------------------------------------
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.

73
system/spi/spi_bus.c Normal file
View File

@ -0,0 +1,73 @@
/****************************************************************************
* apps/system/spi/spi_bus.c
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Dave Marples <dave@marples.net>
*
* 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 <nuttx/spi/spi_transfer.h>
#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;
}

220
system/spi/spi_common.c Normal file
View File

@ -0,0 +1,220 @@
/****************************************************************************
* apps/system/spi/spi_common.c
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Dave Marples <dave@marples.net>
*
* 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 <stdlib.h>
#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;
}

137
system/spi/spi_devif.c Normal file
View File

@ -0,0 +1,137 @@
/****************************************************************************
* apps/system/i2c/i2c_devif.c
*
* Copyright (C) 2019 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 <sys/stat.h>
#include <sys/ioctl.h>
#include <stdbool.h>
#include <fcntl.h>
#include <errno.h>
#include <nuttx/spi/spi_transfer.h>
#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));
}

185
system/spi/spi_exch.c Normal file
View File

@ -0,0 +1,185 @@
/****************************************************************************
* apps/system/spi/spi_exch.c
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Dave Marples <dave@marples.net>
*
* 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 <stdlib.h>
#include <ctype.h>
#include <nuttx/spi/spi_transfer.h>
#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;
}

459
system/spi/spi_main.c Normal file
View File

@ -0,0 +1,459 @@
/****************************************************************************
* apps/system/spi/spi_main.c
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Dave Marples <dave@marples.net>
*
* 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 <nuttx/config.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include <errno.h>
#include <debug.h>
#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] [<hex senddata>]" },
{ "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 <cmd> [arguments]\n");
spitool_printf(spitool, "Where <cmd> 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));
}

216
system/spi/spitool.h Normal file
View File

@ -0,0 +1,216 @@
/****************************************************************************
* apps/system/spi/spitool.h
*
* Copyright (C) 2019 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
* Dave Marples <dave@marples.net>
*
* 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 <nuttx/config.h>
#include <nuttx/compiler.h>
#include <sys/types.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <errno.h>
#include <nuttx/spi/spi_transfer.h>
/****************************************************************************
* 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 */