summaryrefslogtreecommitdiffstats
path: root/apps/system
diff options
context:
space:
mode:
authorpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2011-09-18 17:52:00 +0000
committerpatacongo <patacongo@7fd9a85b-ad96-42d3-883c-3090e2eb8679>2011-09-18 17:52:00 +0000
commit78a589fd5583cfbdd47eac5671d18e945a4c2ea7 (patch)
tree1c324fbc0ad5b3bcbf28818660c322c026914789 /apps/system
parent24ef9fdbf63a1eb0beca472a437a20c5cc183773 (diff)
Add I2C trace capability; Fix another STM32 I2C/FSMC bug; add verify command to the I2C tool
git-svn-id: https://nuttx.svn.sourceforge.net/svnroot/nuttx/trunk@3961 7fd9a85b-ad96-42d3-883c-3090e2eb8679
Diffstat (limited to 'apps/system')
-rw-r--r--apps/system/i2c/Makefile2
-rwxr-xr-xapps/system/i2c/README.txt65
-rw-r--r--apps/system/i2c/i2c_bus.c4
-rw-r--r--apps/system/i2c/i2c_common.c8
-rw-r--r--apps/system/i2c/i2c_dev.c4
-rw-r--r--apps/system/i2c/i2c_get.c163
-rw-r--r--apps/system/i2c/i2c_main.c34
-rw-r--r--apps/system/i2c/i2c_set.c132
-rw-r--r--apps/system/i2c/i2c_verf.c249
-rw-r--r--apps/system/i2c/i2ctool.h21
10 files changed, 563 insertions, 119 deletions
diff --git a/apps/system/i2c/Makefile b/apps/system/i2c/Makefile
index 2755c93225..5ea974452f 100644
--- a/apps/system/i2c/Makefile
+++ b/apps/system/i2c/Makefile
@@ -40,7 +40,7 @@ include $(APPDIR)/Make.defs
# I2C tool
ASRCS =
-CSRCS = i2c_bus.c i2c_common.c i2c_dev.c i2c_get.c i2c_main.c i2c_set.c
+CSRCS = i2c_bus.c i2c_common.c i2c_dev.c i2c_get.c i2c_main.c i2c_set.c i2c_verf.c
AOBJS = $(ASRCS:.S=$(OBJEXT))
diff --git a/apps/system/i2c/README.txt b/apps/system/i2c/README.txt
index 0435be148c..97801bcaaa 100755
--- a/apps/system/i2c/README.txt
+++ b/apps/system/i2c/README.txt
@@ -21,6 +21,7 @@ CONTENTS
- dev
- get
- set
+ - verf
o I2C Build Configuration
- NuttX Configuration Requirements
- I2C Tool Configuration Options
@@ -74,12 +75,13 @@ options.
Usage: i2c <cmd> [arguments]
Where <cmd> is one of:
- Show help: ?
- List buses: bus
- List devices: dev [OPTIONS] <first> <last>
- Read register: get [OPTIONS]
- Show help: help
- Write register: set [OPTIONS] <value>
+ Show help : ?
+ List buses : bus
+ List devices : dev [OPTIONS] <first> <last>
+ Read register : get [OPTIONS] [<repititions>]
+ Show help : help
+ Write register: set [OPTIONS] <value> [<repititions>]
+ Verify access : verf [OPTIONS] <value> [<repititions>]
Where common "sticky" OPTIONS include:
[-a addr] is the I2C device address (hex). Default: 03 Current: 03
@@ -87,6 +89,7 @@ options.
[-r regaddr] is the I2C device register address (hex). Default: 00 Current: 00
[-w width] is the data width (8 or 16 decimal). Default: 8 Current: 8
[-s|n], send/don't send start between command and data. Default: -n Current: -n
+ [-i|j], Auto increment|don't increment regaddr on repititions. Default: NO Current: NO
[-f freq] I2C frequency. Default: 100000 Current: 100000
NOTES:
@@ -195,6 +198,11 @@ Common Option Summary
This determines whether or not there should be a new I2C START between
sending of the register address and sending/receiving of the register data.
+[-i|j], Auto increment|don't increment regaddr on repititions. Default: NO Current: NO
+
+ On commands that take a optional number of repetitions, the option can be
+ used to temporarily increment the regaddr value by one on each repitition.
+
[-f freq] I2C frequency. Default: 400000 Current: 400000
The [-f freq] sets the frequency of the I2C device.
@@ -257,6 +265,13 @@ Read register: get [OPTIONS]
data value from the device. Optionally, it may re-start the transfer
before obtaining the data.
+ An optional <repititions> argument can be supplied to repeat the
+ read operation an arbitrary number of times (up to 2 billion). If
+ auto-increment is select (-i), then the register address will be
+ temporarily incremented on each repitions. The increment is temporary
+ in the since that it will not alter the "sticky" value of the
+ register address.
+
On success, the output will look like the following (the data value
read will be shown as a 4-character hexadecimal number if the 16-bit
data width option is selected).
@@ -274,10 +289,17 @@ Write register: set [OPTIONS] <value>
range 00-ff) or a 16-bit value (in the range 0000-ffff), depending upon
the selected data width.
- This command with write the 8-bit address value then write the 8- or 16-bit
+ This command will write the 8-bit address value then write the 8- or 16-bit
data value to the device. Optionally, it may re-start the transfer
before writing the data.
+ An optional <repititions> argument can be supplied to repeat the
+ write operation an arbitrary number of times (up to 2 billion). If
+ auto-increment is select (-i), then the register address will be
+ temporarily incremented on each repitions. The increment is temporary
+ in the since that it will not alter the "sticky" value of the
+ register address.
+
On success, the output will look like the following (the data value
written will be shown as a 4-character hexadecimal number if the 16-bit
data width option is selected).
@@ -286,6 +308,35 @@ Write register: set [OPTIONS] <value>
All values (except the bus numbers) are hexadecimal.
+Verify access : verf [OPTIONS] <value> [<repititions>]
+------------------------------------------------------
+
+ This command combines writing and reading from an I2C device register.
+ It will write a value to an will write a value to an I2C register using
+ the selected I2C parameters in the common options just as described for
+ tie 'set' command. Then this command will read the value back just
+ as described with the 'get' command. Finally, this command will compare
+ the value read and against the value written and emit an error message
+ if they do not match.
+
+ If no value is provided, then this command will use the register address
+ itself as the data, providing for a address-in-address test.
+
+ An optional <repititions> argument can be supplied to repeat the
+ verify operation an arbitrary number of times (up to 2 billion). If
+ auto-increment is select (-i), then the register address will be
+ temporarily incremented on each repitions. The increment is temporary
+ in the since that it will not alter the "sticky" value of the
+ register address.
+
+ On success, the output will look like the following (the data value
+ written will be shown as a 4-character hexadecimal number if the 16-bit
+ data width option is selected).
+
+ VERIFY Bus: 1 Addr: 49 Subaddr: 04 Wrote: 96 Read: 92 FAILURE
+
+ All values (except the bus numbers) are hexadecimal.
+
I2C BUILD CONFIGURATION
=======================
diff --git a/apps/system/i2c/i2c_bus.c b/apps/system/i2c/i2c_bus.c
index 23bd83f58f..07e6d2da38 100644
--- a/apps/system/i2c/i2c_bus.c
+++ b/apps/system/i2c/i2c_bus.c
@@ -72,10 +72,10 @@
****************************************************************************/
/****************************************************************************
- * Name: cmd_bus
+ * Name: i2ccmd_bus
****************************************************************************/
-int cmd_bus(FAR struct i2ctool_s *i2ctool, int argc, char **argv)
+int i2ccmd_bus(FAR struct i2ctool_s *i2ctool, int argc, char **argv)
{
FAR struct i2c_dev_s *dev;
int i;
diff --git a/apps/system/i2c/i2c_common.c b/apps/system/i2c/i2c_common.c
index 6d53963464..e7b27693ad 100644
--- a/apps/system/i2c/i2c_common.c
+++ b/apps/system/i2c/i2c_common.c
@@ -118,6 +118,14 @@ int common_args(FAR struct i2ctool_s *i2ctool, FAR char **arg)
i2ctool->freq = value;
return ret;
+ case 'i':
+ i2ctool->autoincr = true;
+ return 1;
+
+ case 'j':
+ i2ctool->autoincr = false;
+ return 1;
+
case 'n':
i2ctool->start = false;
return 1;
diff --git a/apps/system/i2c/i2c_dev.c b/apps/system/i2c/i2c_dev.c
index d5c65f2365..f2b5a0e212 100644
--- a/apps/system/i2c/i2c_dev.c
+++ b/apps/system/i2c/i2c_dev.c
@@ -74,10 +74,10 @@
****************************************************************************/
/****************************************************************************
- * Name: cmd_dev
+ * Name: i2ccmd_dev
****************************************************************************/
-int cmd_dev(FAR struct i2ctool_s *i2ctool, int argc, char **argv)
+int i2ccmd_dev(FAR struct i2ctool_s *i2ctool, int argc, char **argv)
{
FAR struct i2c_dev_s *dev;
struct i2c_msg_s msg[2];
diff --git a/apps/system/i2c/i2c_get.c b/apps/system/i2c/i2c_get.c
index 6c2083dd53..773f2c9637 100644
--- a/apps/system/i2c/i2c_get.c
+++ b/apps/system/i2c/i2c_get.c
@@ -39,6 +39,8 @@
#include <nuttx/config.h>
+#include <stdlib.h>
+
#include <nuttx/i2c.h>
#include "i2ctool.h"
@@ -72,33 +74,64 @@
****************************************************************************/
/****************************************************************************
- * Name: cmd_get
+ * Name: i2ccmd_get
****************************************************************************/
-int cmd_get(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv)
+int i2ccmd_get(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv)
{
FAR struct i2c_dev_s *dev;
- struct i2c_msg_s msg[2];
- union
- {
- uint16_t data16;
- uint8_t data8;
- } u;
-
+ FAR char *ptr;
+ uint16_t result;
+ uint8_t regaddr;
+ long repititions;
int nargs;
+ int argndx;
int ret;
int i;
/* Parse any command line arguments */
- for (i = 1; i < argc; )
+ for (argndx = 1; argndx < argc; )
{
- nargs = common_args(i2ctool, &argv[i]);
+ /* Break out of the look when the last option has been parsed */
+
+ ptr = argv[argndx];
+ if (*ptr != '-')
+ {
+ break;
+ }
+
+ /* Otherwise, check for common options */
+
+ nargs = common_args(i2ctool, &argv[argndx]);
if (nargs < 0)
{
return ERROR;
}
- i += nargs;
+ argndx += nargs;
+ }
+
+ /* There may be one more thing on the command line: The repitition
+ * count.
+ */
+
+ repititions = 1;
+ if (argndx < argc)
+ {
+ repititions = strtol(argv[argndx], NULL, 16);
+ if (repititions < 1)
+ {
+ i2ctool_printf(i2ctool, g_i2cargrange, argv[0]);
+ return ERROR;
+ }
+
+ argndx++;
+ }
+
+ if (argndx != argc)
+ {
+ i2ctool_printf(i2ctool, g_i2ctoomanyargs, argv[0]);
+ return ERROR;
}
/* Get a handle to the I2C bus */
@@ -110,16 +143,75 @@ int cmd_get(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv)
return ERROR;
}
- /* Set the frequency and address (NOTE: Only 7-bit address supported now) */
+ /* Set the frequency and the address (NOTE: Only 7-bit address supported now) */
I2C_SETFREQUENCY(dev, i2ctool->freq);
I2C_SETADDRESS(dev, i2ctool->addr, 7);
+ /* Loop for the requested number of repititions */
+
+ regaddr = i2ctool->regaddr;
+ ret = OK;
+
+ for (i = 0; i < repititions; i++)
+ {
+ /* Read from the I2C bus */
+
+ ret = i2ctool_get(i2ctool, dev, regaddr, &result);
+
+ /* Display the result */
+
+ if (ret == OK)
+ {
+ i2ctool_printf(i2ctool, "READ Bus: %d Addr: %02x Subaddr: %02x Value: ",
+ i2ctool->bus, i2ctool->addr, i2ctool->regaddr);
+ if (i2ctool->width == 8)
+ {
+ i2ctool_printf(i2ctool, "%02x\n", result);
+ }
+ else
+ {
+ i2ctool_printf(i2ctool, "%04x\n", result);
+ }
+ }
+ else
+ {
+ i2ctool_printf(i2ctool, g_i2cxfrerror, argv[0], -ret);
+ break;
+ }
+
+ /* Auto-increment the address if so configured */
+
+ if (i2ctool->autoincr)
+ {
+ regaddr++;
+ }
+ }
+
+ (void)up_i2cuninitialize(dev);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: i2ctool_get
+ ****************************************************************************/
+
+int i2ctool_get(FAR struct i2ctool_s *i2ctool, FAR struct i2c_dev_s *dev,
+ uint8_t regaddr, uint16_t *result)
+{
+ struct i2c_msg_s msg[2];
+ union
+ {
+ uint16_t data16;
+ uint8_t data8;
+ } u;
+ int ret;
+
/* Set up data structures */
msg[0].addr = i2ctool->addr;
msg[0].flags = 0;
- msg[0].buffer = &i2ctool->regaddr;
+ msg[0].buffer = &regaddr;
msg[0].length = 1;
msg[1].addr = i2ctool->addr;
@@ -138,43 +230,28 @@ int cmd_get(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv)
if (i2ctool->start)
{
ret = I2C_TRANSFER(dev, &msg[0], 1);
- if (ret < 0)
+ if (ret== OK)
{
- i2ctool_printf(i2ctool, g_i2cxfrerror, argv[0], -ret);
- goto errout;
- }
- ret = I2C_TRANSFER(dev, &msg[1], 1);
- if (ret < 0)
- {
- i2ctool_printf(i2ctool, g_i2cxfrerror, argv[0], -ret);
- goto errout;
+ ret = I2C_TRANSFER(dev, &msg[1], 1);
}
}
else
{
ret = I2C_TRANSFER(dev, msg, 2);
- if (ret < 0)
- {
- goto errout;
- }
}
- i2ctool_printf(i2ctool, "READ Bus: %d Addr: %02x Subaddr: %02x Value: ",
- i2ctool->bus, i2ctool->addr, i2ctool->regaddr);
- if (i2ctool->width == 8)
- {
- i2ctool_printf(i2ctool, "%02x\n", u.data8);
- }
- else
+ /* Return the result of the read operation */
+
+ if (ret == OK)
{
- i2ctool_printf(i2ctool, "%04x\n", u.data16);
+ if (i2ctool->width == 8)
+ {
+ *result = (uint16_t)u.data8;
+ }
+ else
+ {
+ *result = u.data16;
+ }
}
-
- (void)up_i2cuninitialize(dev);
- return OK;
-
-errout:
- i2ctool_printf(i2ctool, g_i2cxfrerror, argv[0], -ret);
- (void)up_i2cuninitialize(dev);
- return ERROR;
+ return ret;
}
diff --git a/apps/system/i2c/i2c_main.c b/apps/system/i2c/i2c_main.c
index cb4889c545..2a0e5d626d 100644
--- a/apps/system/i2c/i2c_main.c
+++ b/apps/system/i2c/i2c_main.c
@@ -64,8 +64,8 @@
* Private Function Prototypes
****************************************************************************/
-static int cmd_help(FAR struct i2ctool_s *i2ctool, int argc, char **argv);
-static int cmd_unrecognized(FAR struct i2ctool_s *i2ctool, int argc, char **argv);
+static int i2ccmd_help(FAR struct i2ctool_s *i2ctool, int argc, char **argv);
+static int i2ccmd_unrecognized(FAR struct i2ctool_s *i2ctool, int argc, char **argv);
/****************************************************************************
* Private Data
@@ -75,13 +75,14 @@ struct i2ctool_s g_i2ctool;
static const struct cmdmap_s g_i2ccmds[] =
{
- { "?", cmd_help, "Show help", NULL },
- { "bus", cmd_bus, "List busses", NULL },
- { "dev", cmd_dev, "List devices", "[OPTIONS] <first> <last>" },
- { "get", cmd_get, "Read register", "[OPTIONS]" },
- { "help", cmd_help, "Show help", NULL },
- { "set", cmd_set, "Write register", "[OPTIONS] <value>" },
- { NULL, NULL, NULL, NULL }
+ { "?", i2ccmd_help, "Show help ", NULL },
+ { "bus", i2ccmd_bus, "List busses ", NULL },
+ { "dev", i2ccmd_dev, "List devices ", "[OPTIONS] <first> <last>" },
+ { "get", i2ccmd_get, "Read register ", "[OPTIONS] [<repititions>]" },
+ { "help", i2ccmd_help, "Show help ", NULL },
+ { "set", i2ccmd_set, "Write register", "[OPTIONS] <value> [<repititions>]" },
+ { "verf", i2ccmd_verf, "Verify access ", "[OPTIONS] [<value>] [<repititions>]" },
+ { NULL, NULL, NULL, NULL }
};
/****************************************************************************
@@ -103,10 +104,10 @@ const char g_i2cxfrerror[] = "i2ctool: %s: Transfer failed: %d\n";
****************************************************************************/
/****************************************************************************
- * Name: cmd_help
+ * Name: i2ccmd_help
****************************************************************************/
-static int cmd_help(FAR struct i2ctool_s *i2ctool, int argc, char **argv)
+static int i2ccmd_help(FAR struct i2ctool_s *i2ctool, int argc, char **argv)
{
const struct cmdmap_s *ptr;
@@ -140,6 +141,9 @@ static int cmd_help(FAR struct i2ctool_s *i2ctool, int argc, char **argv)
i2ctool_printf(i2ctool, " [-s|n], send/don't send start between command and data. "
"Default: -n Current: %s\n",
i2ctool->start ? "-s" : "-n");
+ i2ctool_printf(i2ctool, " [-i|j], Auto increment|don't increment regaddr on repititions. "
+ "Default: NO Current: %s\n",
+ i2ctool->autoincr ? "YES" : "NO");
i2ctool_printf(i2ctool, " [-f freq] I2C frequency. "
"Default: %d Current: %d\n",
CONFIG_I2CTOOL_DEFFREQ, i2ctool->freq);
@@ -156,10 +160,10 @@ static int cmd_help(FAR struct i2ctool_s *i2ctool, int argc, char **argv)
}
/****************************************************************************
- * Name: cmd_unrecognized
+ * Name: i2ccmd_unrecognized
****************************************************************************/
-static int cmd_unrecognized(FAR struct i2ctool_s *i2ctool, int argc, char **argv)
+static int i2ccmd_unrecognized(FAR struct i2ctool_s *i2ctool, int argc, char **argv)
{
i2ctool_printf(i2ctool, g_i2ccmdnotfound, argv[0]);
return ERROR;
@@ -187,7 +191,7 @@ static int i2c_execute(FAR struct i2ctool_s *i2ctool, int argc, char *argv[])
/* See if the command is one that we understand */
cmd = argv[0];
- handler = cmd_unrecognized;
+ handler = i2ccmd_unrecognized;
for (cmdmap = g_i2ccmds; cmdmap->cmd; cmdmap++)
{
@@ -272,7 +276,7 @@ int i2c_parse(FAR struct i2ctool_s *i2ctool, int argc, char *argv[])
* command status.
*/
- return cmd_help(i2ctool, 0, NULL);
+ return i2ccmd_help(i2ctool, 0, NULL);
}
/* Parse all of the arguments following the command name. */
diff --git a/apps/system/i2c/i2c_set.c b/apps/system/i2c/i2c_set.c
index 22706ff089..66fd8c85a0 100644
--- a/apps/system/i2c/i2c_set.c
+++ b/apps/system/i2c/i2c_set.c
@@ -74,24 +74,20 @@
****************************************************************************/
/****************************************************************************
- * Name: cmd_set
+ * Name: i2ccmd_set
****************************************************************************/
-int cmd_set(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv)
+int i2ccmd_set(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv)
{
FAR struct i2c_dev_s *dev;
- struct i2c_msg_s msg[2];
FAR char *ptr;
- union
- {
- uint16_t data16;
- uint8_t data8;
- } u;
-
+ uint8_t regaddr;
long value;
+ long repititions;
int nargs;
int argndx;
int ret;
+ int i;
/* Parse any command line arguments */
@@ -115,7 +111,7 @@ int cmd_set(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv)
argndx += nargs;
}
- /* There should be exactly one more thing on the command line: The value
+ /* There must be at least one more thing on the command line: The value
* to be written.
*/
@@ -144,6 +140,23 @@ int cmd_set(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv)
return ERROR;
}
+ /* There may be one more thing on the command line: The repitition
+ * count.
+ */
+
+ repititions = 1;
+ if (argndx < argc)
+ {
+ repititions = strtol(argv[argndx], NULL, 16);
+ if (repititions < 1)
+ {
+ i2ctool_printf(i2ctool, g_i2cargrange, argv[0]);
+ return ERROR;
+ }
+
+ argndx++;
+ }
+
if (argndx != argc)
{
i2ctool_printf(i2ctool, g_i2ctoomanyargs, argv[0]);
@@ -159,23 +172,82 @@ int cmd_set(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv)
return ERROR;
}
- /* Set the frequency and address (NOTE: Only 7-bit address supported now) */
+ /* Set the frequency and the address (NOTE: Only 7-bit address supported now) */
I2C_SETFREQUENCY(dev, i2ctool->freq);
I2C_SETADDRESS(dev, i2ctool->addr, 7);
+ /* Loop for the requested number of repititions */
+
+ regaddr = i2ctool->regaddr;
+ ret = OK;
+
+ for (i = 0; i < repititions; i++)
+ {
+ /* Write to the I2C bus */
+
+ ret = i2ctool_set(i2ctool, dev, regaddr, (uint16_t)value);
+
+ /* Display the result */
+
+ if (ret == OK)
+ {
+ i2ctool_printf(i2ctool, "WROTE Bus: %d Addr: %02x Subaddr: %02x Value: ",
+ i2ctool->bus, i2ctool->addr, i2ctool->regaddr);
+ if (i2ctool->width == 8)
+ {
+ i2ctool_printf(i2ctool, "%02x\n", (int)value);
+ }
+ else
+ {
+ i2ctool_printf(i2ctool, "%04x\n", (int)value);
+ }
+ }
+ else
+ {
+ i2ctool_printf(i2ctool, g_i2cxfrerror, argv[0], -ret);
+ break;
+ }
+
+ /* Auto-increment the address if so configured */
+
+ if (i2ctool->autoincr)
+ {
+ regaddr++;
+ }
+ }
+
+ (void)up_i2cuninitialize(dev);
+ return ret;
+}
+
+/****************************************************************************
+ * Name: i2ctool_set
+ ****************************************************************************/
+
+int i2ctool_set(FAR struct i2ctool_s *i2ctool, FAR struct i2c_dev_s *dev,
+ uint8_t regaddr, uint16_t value)
+{
+ struct i2c_msg_s msg[2];
+ union
+ {
+ uint16_t data16;
+ uint8_t data8;
+ } u;
+ int ret;
+
/* Set up data structures */
msg[0].addr = i2ctool->addr;
msg[0].flags = 0;
- msg[0].buffer = &i2ctool->regaddr;
+ msg[0].buffer = &regaddr;
msg[0].length = 1;
msg[1].addr = i2ctool->addr;
msg[1].flags = 0;
if (i2ctool->width == 8)
{
- u.data8 = value;
+ u.data8 = (uint8_t)value;
msg[1].buffer = &u.data8;
msg[1].length = 1;
}
@@ -189,43 +261,15 @@ int cmd_set(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv)
if (i2ctool->start)
{
ret = I2C_TRANSFER(dev, &msg[0], 1);
- if (ret < 0)
+ if (ret == OK)
{
- i2ctool_printf(i2ctool, g_i2cxfrerror, argv[0], -ret);
- goto errout;
- }
- ret = I2C_TRANSFER(dev, &msg[1], 1);
- if (ret < 0)
- {
- i2ctool_printf(i2ctool, g_i2cxfrerror, argv[0], -ret);
- goto errout;
+ ret = I2C_TRANSFER(dev, &msg[1], 1);
}
}
else
{
ret = I2C_TRANSFER(dev, msg, 2);
- if (ret < 0)
- {
- goto errout;
- }
- }
-
- i2ctool_printf(i2ctool, "WROTE Bus: %d Addr: %02x Subaddr: %02x Value: ",
- i2ctool->bus, i2ctool->addr, i2ctool->regaddr);
- if (i2ctool->width == 8)
- {
- i2ctool_printf(i2ctool, "%02x\n", u.data8);
}
- else
- {
- i2ctool_printf(i2ctool, "%04x\n", u.data16);
- }
-
- (void)up_i2cuninitialize(dev);
- return OK;
-errout:
- i2ctool_printf(i2ctool, g_i2cxfrerror, argv[0], -ret);
- (void)up_i2cuninitialize(dev);
- return ERROR;
+ return ret;
}
diff --git a/apps/system/i2c/i2c_verf.c b/apps/system/i2c/i2c_verf.c
new file mode 100644
index 0000000000..0fa34b96e1
--- /dev/null
+++ b/apps/system/i2c/i2c_verf.c
@@ -0,0 +1,249 @@
+/****************************************************************************
+ * apps/system/i2c/i2c_verf.c
+ *
+ * Copyright (C) 2011 Gregory Nutt. All rights reserved.
+ * Author: Gregory Nutt <spudmonkey@racsa.co.cr>
+ *
+ * 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 <nuttx/i2c.h>
+
+#include "i2ctool.h"
+
+/****************************************************************************
+ * Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Types
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: i2ccmd_verf
+ ****************************************************************************/
+
+int i2ccmd_verf(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv)
+{
+ FAR struct i2c_dev_s *dev;
+ FAR char *ptr;
+ uint16_t rdvalue;
+ uint8_t regaddr;
+ bool addrinaddr;
+ long wrvalue;
+ long repititions;
+ int nargs;
+ int argndx;
+ int ret;
+ int i;
+
+ /* Parse any command line arguments */
+
+ for (argndx = 1; argndx < argc; )
+ {
+ /* Break out of the look when the last option has been parsed */
+
+ ptr = argv[argndx];
+ if (*ptr != '-')
+ {
+ break;
+ }
+
+ /* Otherwise, check for common options */
+
+ nargs = common_args(i2ctool, &argv[argndx]);
+ if (nargs < 0)
+ {
+ return ERROR;
+ }
+ argndx += nargs;
+ }
+
+ /* The options may be followed by the optional wrvalue to be written. If omitted, then
+ * the register address will be used as the wrvalue, providing an address-in-address
+ * test.
+ */
+
+ addrinaddr = true;
+ wrvalue = 0;
+
+ if (argndx < argc)
+ {
+ wrvalue = strtol(argv[argndx], NULL, 16);
+ if (i2ctool->width == 8)
+ {
+ if (wrvalue < 0 || wrvalue > 255)
+ {
+ i2ctool_printf(i2ctool, g_i2cargrange, argv[0]);
+ return ERROR;
+ }
+ }
+ else if (wrvalue < 0 || wrvalue > 65535)
+ {
+ i2ctool_printf(i2ctool, g_i2cargrange, argv[0]);
+ return ERROR;
+ }
+
+ addrinaddr = false;
+ argndx++;
+ }
+
+ /* There may be one more thing on the command line: The repitition
+ * count.
+ */
+
+ repititions = 1;
+ if (argndx < argc)
+ {
+ repititions = strtol(argv[argndx], NULL, 16);
+ if (repititions < 1)
+ {
+ i2ctool_printf(i2ctool, g_i2cargrange, argv[0]);
+ return ERROR;
+ }
+
+ argndx++;
+ }
+
+ if (argndx != argc)
+ {
+ i2ctool_printf(i2ctool, g_i2ctoomanyargs, argv[0]);
+ return ERROR;
+ }
+
+ /* Get a handle to the I2C bus */
+
+ dev = up_i2cinitialize(i2ctool->bus);
+ if (!dev)
+ {
+ i2ctool_printf(i2ctool, "Failed to get bus %d\n", i2ctool->bus);
+ return ERROR;
+ }
+
+ /* Set the frequency and the address (NOTE: Only 7-bit address supported now) */
+
+ I2C_SETFREQUENCY(dev, i2ctool->freq);
+ I2C_SETADDRESS(dev, i2ctool->addr, 7);
+
+ /* Loop for the requested number of repititions */
+
+ regaddr = i2ctool->regaddr;
+ ret = OK;
+
+ for (i = 0; i < repititions; i++)
+ {
+ /* If we are performing an address-in-address test, then use the register
+ * address as the value to write.
+ */
+
+ if (addrinaddr)
+ {
+ wrvalue = regaddr;
+ }
+
+ /* Write to the I2C bus */
+
+ ret = i2ctool_set(i2ctool, dev, regaddr, (uint16_t)wrvalue);
+ if (ret == OK)
+ {
+ /* Read the value back from the I2C bus */
+
+ ret = i2ctool_get(i2ctool, dev, regaddr, &rdvalue);
+ }
+
+ /* Display the result */
+
+ if (ret == OK)
+ {
+ i2ctool_printf(i2ctool, "VERIFY Bus: %d Addr: %02x Subaddr: %02x Wrote: ",
+ i2ctool->bus, i2ctool->addr, i2ctool->regaddr);
+
+ if (i2ctool->width == 8)
+ {
+ i2ctool_printf(i2ctool, "%02x Read: %02x", (int)wrvalue, (int)rdvalue);
+ }
+ else
+ {
+ i2ctool_printf(i2ctool, "%04x Read: %04x", (int)wrvalue, (int)rdvalue);
+ }
+
+ if (wrvalue != rdvalue)
+ {
+ i2ctool_printf(i2ctool, " <<< FAILURE\n");
+ }
+ else
+ {
+ i2ctool_printf(i2ctool, "\n");
+ }
+ }
+ else
+ {
+ i2ctool_printf(i2ctool, g_i2cxfrerror, argv[0], -ret);
+ break;
+ }
+
+ /* Auto-increment the address if so configured */
+
+ if (i2ctool->autoincr)
+ {
+ regaddr++;
+ }
+ }
+
+ (void)up_i2cuninitialize(dev);
+ return ret;
+}
diff --git a/apps/system/i2c/i2ctool.h b/apps/system/i2c/i2ctool.h
index 56802ffb22..9726f0083f 100644
--- a/apps/system/i2c/i2ctool.h
+++ b/apps/system/i2c/i2ctool.h
@@ -49,6 +49,8 @@
#include <stdbool.h>
#include <errno.h>
+#include <nuttx/i2c.h>
+
/****************************************************************************
* Definitions
****************************************************************************/
@@ -139,7 +141,8 @@ struct i2ctool_s
uint8_t bus; /* [-b bus] is the I2C bus number */
uint8_t regaddr; /* [-r regaddr] is the I2C device register address */
uint8_t width; /* [-w width] is the data width (8 or 16) */
- bool start; /* [-s|n], send/don't send start between command and data */
+ bool start; /* [-s|n], send|don't send start between command and data */
+ bool autoincr; /* [-i|j], Auto increment|don't increment regaddr on repititions */
uint32_t freq; /* [-f freq] I2C frequency */
/* Output streams */
@@ -184,10 +187,18 @@ void i2ctool_flush(FAR struct i2ctool_s *i2ctool);
/* Command handlers */
-int cmd_bus(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv);
-int cmd_dev(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv);
-int cmd_get(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv);
-int cmd_set(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv);
+int i2ccmd_bus(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv);
+int i2ccmd_dev(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv);
+int i2ccmd_get(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv);
+int i2ccmd_set(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv);
+int i2ccmd_verf(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv);
+
+/* I2C access functions */
+
+int i2ctool_get(FAR struct i2ctool_s *i2ctool, FAR struct i2c_dev_s *dev,
+ uint8_t addr, uint16_t *result);
+int i2ctool_set(FAR struct i2ctool_s *i2ctool, FAR struct i2c_dev_s *dev,
+ uint8_t regaddr, uint16_t value);
/* Common logic */