Skip to content

Commit 8900543

Browse files
committed
i2c: add i2c shell with scan cmd
Add a shell to interact with I2C devices. Currently scanning for devices is supported. Example output: uart:~$ i2c scan I2C_1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- 18 -- -- -- -- -- -- -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: -- -- -- -- -- -- -- -- 2 devices found on I2C_1 uart:~$ i2c scan I2C_3 i2c - I2C commands Subcommands: I2C_1 :I2C_1 I2C_2 :I2C_2 uart:~$ i2c scan I2C_2 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- 10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- 1e -- 20: -- -- -- -- -- -- -- -- -- 29 -- -- -- 2d -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- 56 -- -- -- -- -- -- 5d -- 5f 60: -- -- -- -- -- -- -- -- -- -- 6a -- -- -- -- -- 70: -- -- -- -- -- -- -- -- 7 devices found on I2C_2 This shell is based on the a sample that did the same thing and was limited in support. The sample is now removed in favour of this generic shell module. Signed-off-by: Anas Nashif <[email protected]>
1 parent 7c9a87a commit 8900543

File tree

4 files changed

+113
-0
lines changed

4 files changed

+113
-0
lines changed

CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@
140140
/drivers/hwinfo/ @alexanderwachter
141141
/drivers/i2c/*litex* @mateusz-holenko @kgugala @pgielda
142142
/drivers/i2s/i2s_ll_stm32* @avisconti
143+
/drivers/i2c/i2c_shell.c @nashif
143144
/drivers/ieee802154/ @jukkar @tbursztyka
144145
/drivers/ieee802154/ieee802154_rf2xx* @jukkar @tbursztyka @nandojve
145146
/drivers/interrupt_controller/ @andrewboie

drivers/i2c/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
zephyr_library()
44

5+
zephyr_library_sources_ifdef(CONFIG_I2C_SHELL i2c_shell.c)
56
zephyr_library_sources_ifdef(CONFIG_I2C_BITBANG i2c_bitbang.c)
67
zephyr_library_sources_ifdef(CONFIG_I2C_CC13XX_CC26XX i2c_cc13xx_cc26xx.c)
78
zephyr_library_sources_ifdef(CONFIG_I2C_CC32XX i2c_cc32xx.c)

drivers/i2c/Kconfig

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,15 @@ menuconfig I2C
1414

1515
if I2C
1616

17+
config I2C_SHELL
18+
bool "Enable I2C Shell"
19+
default y
20+
depends on SHELL
21+
help
22+
Enable I2C Shell.
23+
24+
The I2C shell currently support scanning.
25+
1726
# Include these first so that any properties (e.g. defaults) below can be
1827
# overridden (by defining symbols in multiple locations)
1928
source "drivers/i2c/Kconfig.cc13xx_cc26xx"

drivers/i2c/i2c_shell.c

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
/*
2+
* Copyright (c) 2018 Prevas A/S
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <shell/shell.h>
8+
#include <stdlib.h>
9+
#include <i2c.h>
10+
#include <string.h>
11+
#include <sys/util.h>
12+
13+
#include <logging/log.h>
14+
LOG_MODULE_REGISTER(i2c_shell, CONFIG_LOG_DEFAULT_LEVEL);
15+
16+
#define I2C_DEVICE_PREFIX "I2C_"
17+
18+
extern struct device __device_init_start[];
19+
extern struct device __device_init_end[];
20+
21+
static int cmd_i2c_scan(const struct shell *shell,
22+
size_t argc, char **argv)
23+
{
24+
struct device *dev;
25+
u8_t cnt = 0, first = 0x04, last = 0x77;
26+
27+
dev = device_get_binding(argv[1]);
28+
29+
if (!dev) {
30+
shell_error(shell, "I2C: Device driver %s not found.",
31+
argv[1]);
32+
return -ENODEV;
33+
}
34+
35+
shell_print(shell,
36+
" 0 1 2 3 4 5 6 7 8 9 a b c d e f");
37+
for (u8_t i = 0; i <= last; i += 16) {
38+
shell_fprintf(shell, SHELL_NORMAL, "%02x: ", i);
39+
for (u8_t j = 0; j < 16; j++) {
40+
if (i + j < first || i + j > last) {
41+
shell_fprintf(shell, SHELL_NORMAL, " ");
42+
continue;
43+
}
44+
45+
struct i2c_msg msgs[1];
46+
u8_t dst;
47+
48+
/* Send the address to read from */
49+
msgs[0].buf = &dst;
50+
msgs[0].len = 0U;
51+
msgs[0].flags = I2C_MSG_WRITE | I2C_MSG_STOP;
52+
if (i2c_transfer(dev, &msgs[0], 1, i + j) == 0) {
53+
shell_fprintf(shell, SHELL_NORMAL,
54+
"%02x ", i + j);
55+
++cnt;
56+
} else {
57+
shell_fprintf(shell, SHELL_NORMAL, "-- ");
58+
}
59+
}
60+
shell_print(shell, "");
61+
}
62+
63+
shell_print(shell, "%u devices found on %s",
64+
cnt, argv[1]);
65+
66+
return 0;
67+
}
68+
69+
static void device_name_get(size_t idx, struct shell_static_entry *entry);
70+
71+
SHELL_DYNAMIC_CMD_CREATE(dsub_device_name, device_name_get);
72+
73+
static void device_name_get(size_t idx, struct shell_static_entry *entry)
74+
{
75+
int device_idx = 0;
76+
struct device *dev;
77+
78+
entry->syntax = NULL;
79+
entry->handler = NULL;
80+
entry->help = NULL;
81+
entry->subcmd = &dsub_device_name;
82+
83+
for (dev = __device_init_start; dev != __device_init_end; dev++) {
84+
if ((dev->driver_api != NULL) &&
85+
strstr(dev->config->name, I2C_DEVICE_PREFIX) != NULL &&
86+
strcmp(dev->config->name, "") && (dev->config->name != NULL)) {
87+
if (idx == device_idx) {
88+
entry->syntax = dev->config->name;
89+
break;
90+
}
91+
device_idx++;
92+
}
93+
}
94+
}
95+
96+
SHELL_STATIC_SUBCMD_SET_CREATE(sub_i2c_cmds,
97+
SHELL_CMD(scan, &dsub_device_name,
98+
"Scan I2C devices", cmd_i2c_scan),
99+
SHELL_SUBCMD_SET_END /* Array terminated. */
100+
);
101+
102+
SHELL_CMD_REGISTER(i2c, &sub_i2c_cmds, "I2C commands", NULL);

0 commit comments

Comments
 (0)