From 2fce155def57d3416bec6b7741adf2770d4ad2b6 Mon Sep 17 00:00:00 2001 From: Matteo Golin Date: Wed, 17 Jul 2024 20:00:43 -0400 Subject: [PATCH] i2ctool dev has a `-z` option to use a zero-byte write request for scanning the bus, which allows detection of more sensors such as the MS5611 and SHT41 to be detected. --- system/i2c/i2c_common.c | 4 ++++ system/i2c/i2c_dev.c | 42 +++++++++++++++++++++++++++++++++++------ system/i2c/i2c_main.c | 5 +++++ system/i2c/i2ctool.h | 1 + 4 files changed, 46 insertions(+), 6 deletions(-) diff --git a/system/i2c/i2c_common.c b/system/i2c/i2c_common.c index 0c96a8557..2ede53232 100644 --- a/system/i2c/i2c_common.c +++ b/system/i2c/i2c_common.c @@ -173,6 +173,10 @@ int i2ctool_common_args(FAR struct i2ctool_s *i2ctool, FAR char **arg) i2ctool->width = (uint8_t)value; return ret; + case 'z': + i2ctool->zerowrite = true; + return 1; + default: goto invalid_argument; } diff --git a/system/i2c/i2c_dev.c b/system/i2c/i2c_dev.c index 3fb29c9dd..a06742feb 100644 --- a/system/i2c/i2c_dev.c +++ b/system/i2c/i2c_dev.c @@ -64,6 +64,14 @@ int i2ccmd_dev(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv) saveaddr = i2ctool->regaddr; i2ctool->regaddr = 0; + /* For backwards compatibility, the default behaviour while scanning will + * be to send a read request on the I2C bus. It is also possible to specify + * the use of a zero-byte write request instead, but this option will not + * be sticky. + */ + + i2ctool->zerowrite = false; + /* Parse any command line arguments */ for (argndx = 1; argndx < argc; ) @@ -126,6 +134,19 @@ int i2ccmd_dev(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv) goto errout; } + /* Display message warning user about some devices which don't appear + * unless using zero-byte write header. + */ + + if (!i2ctool->zerowrite) + { + i2ctool_printf( + i2ctool, + "NOTE: Some devices may not appear with this " + "scan.\nYou may also try a scan with the -z flag to " + "discover more devices using a zero-byte write request.\n"); + } + /* Probe each address */ i2ctool_printf(i2ctool, @@ -146,13 +167,22 @@ int i2ccmd_dev(FAR struct i2ctool_s *i2ctool, int argc, FAR char **argv) /* Set up data structures */ - regaddr = i2ctool->regaddr; - msg.frequency = i2ctool->freq; - msg.addr = addr; - msg.flags = I2C_M_READ; - msg.buffer = ®addr; - msg.length = 1; + msg.addr = addr; + + if (i2ctool->zerowrite) + { + msg.flags = 0; + msg.buffer = NULL; + msg.length = 0; + } + else + { + regaddr = i2ctool->regaddr; + msg.flags = I2C_M_READ; + msg.buffer = ®addr; + msg.length = 1; + } ret = i2cdev_transfer(fd, &msg, 1); diff --git a/system/i2c/i2c_main.c b/system/i2c/i2c_main.c index a73245058..2ad9e3a35 100644 --- a/system/i2c/i2c_main.c +++ b/system/i2c/i2c_main.c @@ -149,6 +149,10 @@ static int i2ccmd_help(FAR struct i2ctool_s *i2ctool, int argc, i2ctool_printf(i2ctool, " [-r regaddr] is the I2C device register index (hex)." " Default: not used/sent\n"); + i2ctool_printf( + i2ctool, + " [-z] instructs the 'dev' command to scan the I2C bus by sending " + "zero-byte write headers (if the architecture supports it)\n"); i2ctool_printf(i2ctool, "\nNOTES:\n"); #ifndef CONFIG_DISABLE_ENVIRON @@ -398,6 +402,7 @@ int main(int argc, FAR char *argv[]) } g_i2ctool.hasregindx = false; + g_i2ctool.zerowrite = false; /* Parse and process the command line */ diff --git a/system/i2c/i2ctool.h b/system/i2c/i2ctool.h index 70c728f4e..27553866d 100644 --- a/system/i2c/i2ctool.h +++ b/system/i2c/i2ctool.h @@ -127,6 +127,7 @@ struct i2ctool_s 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 zerowrite; /* [-z] uses a zero byte write request to scan the I2C bus */ bool autoincr; /* [-i|j], Auto increment|don't increment regaddr on repetitions */ bool hasregindx; /* true with the use of -r */ uint32_t freq; /* [-f freq] I2C frequency */