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:
parent
dbb5211060
commit
80de28c865
@ -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
11
system/spi/.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/Make.dep
|
||||
/.depend
|
||||
/.built
|
||||
/*.asm
|
||||
/*.rel
|
||||
/*.lst
|
||||
/*.sym
|
||||
/*.adb
|
||||
/*.lib
|
||||
/*.src
|
||||
/*.obj
|
72
system/spi/Kconfig
Normal file
72
system/spi/Kconfig
Normal 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
39
system/spi/Make.defs
Normal 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
55
system/spi/Makefile
Normal 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
226
system/spi/README.txt
Normal 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
73
system/spi/spi_bus.c
Normal 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
220
system/spi/spi_common.c
Normal 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
137
system/spi/spi_devif.c
Normal 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
185
system/spi/spi_exch.c
Normal 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
459
system/spi/spi_main.c
Normal 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
216
system/spi/spitool.h
Normal 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 */
|
Loading…
Reference in New Issue
Block a user