Skip to content

Commit a3660d1

Browse files
erang20nashif
authored andcommitted
drivers: i2c_shell: Add direct_read sub command
Adds a direct_read subcommand to the I2C command. Usage: I2C direct_read <device> <addr> [<nbytes>]. This command reads directly from the I2C device without first writing a register address. Signed-off-by: Eran Gal <[email protected]>
1 parent e4ea597 commit a3660d1

File tree

1 file changed

+44
-10
lines changed

1 file changed

+44
-10
lines changed

drivers/i2c/i2c_shell.c

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -195,9 +195,6 @@ static int i2c_read_to_buffer(const struct shell *shell_ctx,
195195
uint8_t *buf, uint8_t buf_length)
196196
{
197197
const struct device *dev;
198-
uint8_t reg_addr_buf[MAX_BYTES_FOR_REGISTER_INDEX];
199-
int reg_addr_bytes;
200-
int reg_addr;
201198
int dev_addr;
202199
int ret;
203200

@@ -209,15 +206,23 @@ static int i2c_read_to_buffer(const struct shell *shell_ctx,
209206
}
210207

211208
dev_addr = strtol(s_dev_addr, NULL, 16);
212-
reg_addr = strtol(s_reg_addr, NULL, 16);
213209

214-
reg_addr_bytes = get_bytes_count_for_hex(s_reg_addr);
215-
sys_put_be32(reg_addr, reg_addr_buf);
210+
if (s_reg_addr != NULL) {
211+
uint8_t reg_addr_buf[MAX_BYTES_FOR_REGISTER_INDEX];
212+
int reg_addr_bytes;
213+
int reg_addr;
214+
215+
reg_addr = strtol(s_reg_addr, NULL, 16);
216+
reg_addr_bytes = get_bytes_count_for_hex(s_reg_addr);
217+
sys_put_be32(reg_addr, reg_addr_buf);
218+
219+
ret = i2c_write_read(dev, dev_addr,
220+
reg_addr_buf + MAX_BYTES_FOR_REGISTER_INDEX - reg_addr_bytes,
221+
reg_addr_bytes, buf, buf_length);
222+
} else {
223+
ret = i2c_read(dev, buf, buf_length, dev_addr);
224+
}
216225

217-
ret = i2c_write_read(dev, dev_addr,
218-
reg_addr_buf +
219-
MAX_BYTES_FOR_REGISTER_INDEX - reg_addr_bytes,
220-
reg_addr_bytes, buf, buf_length);
221226
if (ret < 0) {
222227
shell_error(shell_ctx, "Failed to read from device: %s",
223228
s_dev_addr);
@@ -270,6 +275,30 @@ static int cmd_i2c_read(const struct shell *shell_ctx, size_t argc, char **argv)
270275
return ret;
271276
}
272277

278+
/* i2c direct_read <device> <dev_addr> [<numbytes>] */
279+
static int cmd_i2c_direct_read(const struct shell *shell_ctx, size_t argc, char **argv)
280+
{
281+
uint8_t buf[MAX_I2C_BYTES];
282+
int num_bytes;
283+
int ret;
284+
285+
if (argc > 3) {
286+
num_bytes = strtol(argv[3], NULL, 16);
287+
if (num_bytes > MAX_I2C_BYTES) {
288+
num_bytes = MAX_I2C_BYTES;
289+
}
290+
} else {
291+
num_bytes = MAX_I2C_BYTES;
292+
}
293+
294+
ret = i2c_read_to_buffer(shell_ctx, argv[ARGV_DEV], argv[ARGV_ADDR], NULL, buf, num_bytes);
295+
if (ret == 0) {
296+
shell_hexdump(shell_ctx, buf, num_bytes);
297+
}
298+
299+
return ret;
300+
}
301+
273302
/* i2c speed <device> <speed>
274303
* For: speed see constants like I2C_SPEED_STANDARD
275304
*/
@@ -336,6 +365,11 @@ SHELL_STATIC_SUBCMD_SET_CREATE(sub_i2c_cmds,
336365
"Read a byte from an I2C device\n"
337366
"Usage: read_byte <device> <addr> <reg>",
338367
cmd_i2c_read_byte, 4, 0),
368+
SHELL_CMD_ARG(direct_read, &dsub_device_name,
369+
"Read byte stream directly from an I2C device without "
370+
"writing a register address first\n"
371+
"Usage: direct_read <device> <addr> [<bytes>]",
372+
cmd_i2c_direct_read, 3, 1),
339373
SHELL_CMD_ARG(write, &dsub_device_name,
340374
"Write bytes to an I2C device\n"
341375
"Usage: write <device> <addr> <reg> [<byte1>, ...]",

0 commit comments

Comments
 (0)