From d7d541e2d97deb5aca7d58be18c93e7f3fcc97d6 Mon Sep 17 00:00:00 2001 From: akob Haufe Date: Thu, 30 Aug 2018 06:35:12 -0600 Subject: [PATCH] apps/system/i2c: Allow registers besides 0x00 in the dev command. --- system/i2c/README.txt | 16 +++++++++++---- system/i2c/i2c_dev.c | 47 +++++++++++++++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 15 deletions(-) diff --git a/system/i2c/README.txt b/system/i2c/README.txt index b51011b42..b6073ed12 100644 --- a/system/i2c/README.txt +++ b/system/i2c/README.txt @@ -221,11 +221,19 @@ The 'dev' command will attempt to identify all of the I2C devices on the selected bus. The and arguments are 7-bit, hexadecimal I2C addresses. This command will examine a range of addresses beginning with and continuing through . It will request the value -of register zero from each device. +of register address zero from each device. -If the device at an address responds, then this command will display the -address of the device. If the device does not respond, this command will -display "--". The resulting display is like: +The register address of zero is always used by default. The previous +"sticky" register address is ignored. Some devices may not respond to +ergister address zero, however. To work around this, you can provide a +new "sticky" register address on the command as an option to the 'dev' +command. Then that new "sticky" register address will be used instead +of the address zero. + +If the device at an I2C address responds to the read request, then the +'dev' command will display the I2C address of the device. If the device +does not respond, this command will display "--". The resulting display +looks like: nsh> i2c dev 03 77 0 1 2 3 4 5 6 7 8 9 a b c d e f diff --git a/system/i2c/i2c_dev.c b/system/i2c/i2c_dev.c index 38c4afd72..6c5dafd73 100644 --- a/system/i2c/i2c_dev.c +++ b/system/i2c/i2c_dev.c @@ -1,7 +1,7 @@ /**************************************************************************** * apps/system/i2c/i2c_dev.c * - * Copyright (C) 2011, 2016 Gregory Nutt. All rights reserved. + * Copyright (C) 2011, 2016, 2018 Gregory Nutt. All rights reserved. * Author: Gregory Nutt * * Redistribution and use in source and binary forms, with or without @@ -64,6 +64,7 @@ int i2ccmd_dev(FAR struct i2ctool_s *i2ctool, int argc, char **argv) } u; uint8_t regaddr; + uint8_t saveaddr; long first; long last; int addr; @@ -74,11 +75,20 @@ int i2ccmd_dev(FAR struct i2ctool_s *i2ctool, int argc, char **argv) int i; int j; + /* A register address other than zero may be provided on the command line. + * However, for backward compatibility, the address zero will be used + * unless the address is specifically included on the command line for + * this command. + */ + + saveaddr = i2ctool->regaddr; + i2ctool->regaddr = 0; + /* Parse any command line arguments */ for (argndx = 1; argndx < argc; ) { - /* Break out of the look when the last option has been parsed */ + /* Break out of the loop when the last option has been parsed */ ptr = argv[argndx]; if (*ptr != '-') @@ -91,8 +101,9 @@ int i2ccmd_dev(FAR struct i2ctool_s *i2ctool, int argc, char **argv) nargs = i2ctool_common_args(i2ctool, &argv[argndx]); if (nargs < 0) { - return ERROR; + goto errout; } + argndx += nargs; } @@ -100,14 +111,14 @@ int i2ccmd_dev(FAR struct i2ctool_s *i2ctool, int argc, char **argv) * last addresses to be probed. */ - if (argndx+1 < argc) + if (argndx + 1 < argc) { first = strtol(argv[argndx], NULL, 16); - last = strtol(argv[argndx+1], NULL, 16); + last = strtol(argv[argndx + 1], NULL, 16); if (first < 0 || first > 0x7f || last < 0 || last > 0x7f || first > last) { i2ctool_printf(i2ctool, g_i2cargrange, argv[0]); - return ERROR; + goto errout; } argndx += 2; @@ -115,13 +126,13 @@ int i2ccmd_dev(FAR struct i2ctool_s *i2ctool, int argc, char **argv) else { i2ctool_printf(i2ctool, g_i2cargrequired, argv[0]); - return ERROR; + goto errout; } if (argndx != argc) { i2ctool_printf(i2ctool, g_i2ctoomanyargs, argv[0]); - return ERROR; + goto errout; } /* Get a handle to the I2C bus */ @@ -130,7 +141,7 @@ int i2ccmd_dev(FAR struct i2ctool_s *i2ctool, int argc, char **argv) if (fd < 0) { i2ctool_printf(i2ctool, "Failed to get bus %d\n", i2ctool->bus); - return ERROR; + goto errout; } /* Probe each address */ @@ -143,7 +154,7 @@ int i2ccmd_dev(FAR struct i2ctool_s *i2ctool, int argc, char **argv) { /* Skip addresses that are out of the selected range */ - addr = i+j; + addr = i + j; if (addr < first || addr > last) { i2ctool_printf(i2ctool, " "); @@ -152,7 +163,7 @@ int i2ccmd_dev(FAR struct i2ctool_s *i2ctool, int argc, char **argv) /* Set up data structures */ - regaddr = 0; + regaddr = i2ctool->regaddr; msg[0].frequency = i2ctool->freq; msg[0].addr = addr; @@ -163,6 +174,7 @@ int i2ccmd_dev(FAR struct i2ctool_s *i2ctool, int argc, char **argv) msg[1].frequency = i2ctool->freq; msg[1].addr = addr; msg[1].flags = I2C_M_READ; + if (i2ctool->width == 8) { msg[1].buffer = &u.data8; @@ -202,5 +214,18 @@ int i2ccmd_dev(FAR struct i2ctool_s *i2ctool, int argc, char **argv) } (void)close(fd); + +errout: + + /* Restore the previous "sticky" register address unless a new register + * address was provided on the command line. In that case the new + * register address is retained. + */ + + if (i2ctool->regaddr == 0) + { + i2ctool->regaddr = saveaddr; + } + return OK; }