From: Chris Johns
Closes #4708
---
cpukit/include/rtems/shellconfig.h | 7 +
cpukit/libmisc/shell/main_i2c.c| 653 +
spec/build/cpukit/objshell.yml | 1 +
3 files changed, 661 insertions(+)
create mode 100644 cpukit/libmisc/shell/main_i2c.c
diff --git a/cpukit/include/rtems/shellconfig.h
b/cpukit/include/rtems/shellconfig.h
index a013840ee7..bd44d9d310 100644
--- a/cpukit/include/rtems/shellconfig.h
+++ b/cpukit/include/rtems/shellconfig.h
@@ -98,6 +98,7 @@ extern rtems_shell_cmd_t rtems_shell_MD5_Command;
extern rtems_shell_cmd_t rtems_shell_RTC_Command;
extern rtems_shell_cmd_t rtems_shell_SPI_Command;
+extern rtems_shell_cmd_t rtems_shell_I2C_Command;
extern rtems_shell_cmd_t rtems_shell_I2CDETECT_Command;
extern rtems_shell_cmd_t rtems_shell_I2CGET_Command;
extern rtems_shell_cmd_t rtems_shell_I2CSET_Command;
@@ -556,6 +557,12 @@ extern rtems_shell_alias_t * const
rtems_shell_Initial_aliases[];
&rtems_shell_SPI_Command,
#endif
+#if (defined(CONFIGURE_SHELL_COMMANDS_ALL) \
+ && !defined(CONFIGURE_SHELL_NO_COMMAND_I2C)) \
+|| defined(CONFIGURE_SHELL_COMMAND_I2C)
+ &rtems_shell_I2C_Command,
+#endif
+
#if (defined(CONFIGURE_SHELL_COMMANDS_ALL) \
&& !defined(CONFIGURE_SHELL_NO_COMMAND_I2CDETECT)) \
|| defined(CONFIGURE_SHELL_COMMAND_I2CDETECT)
diff --git a/cpukit/libmisc/shell/main_i2c.c b/cpukit/libmisc/shell/main_i2c.c
new file mode 100644
index 00..bd43afbe38
--- /dev/null
+++ b/cpukit/libmisc/shell/main_i2c.c
@@ -0,0 +1,653 @@
+/* SPDX-License-Identifier: BSD-2-Clause */
+
+/**
+ * @file
+ *
+ * @ingroup
+ *
+ * @brief This source file contains the I2C command.
+ */
+
+/*
+ * Copyright (c) 2022 Chris Johns. All rights reserved.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+#include
+#include
+
+#include
+#include
+
+#define BUF_SIZE 2048
+#define MAX_BUSES 8
+#define MIN_ADDR 1
+#define MAX_ADDR 127 /* needs updating for 10bit addresses */
+
+static char bus_template[128] = "/dev/i2c-%d";
+
+typedef struct {
+ int argc;
+ char** argv;
+ int arg;
+ int bus[MAX_BUSES];
+ uint8_t buffer[BUF_SIZE];
+} i2c_data;
+
+static void dump_memory(const uint8_t* mem, size_t len) {
+ size_t i;
+ for (i = 0; i < len; ++i) {
+if ((i % 16) == 0) {
+ if (i > 0) {
+printf("\n");
+ }
+ printf("%04zu", i);
+}
+if ((i % 8) == 0) {
+ printf(" ");
+}
+printf(" %02x", (unsigned int) mem[i]);
+ }
+ printf("\n");
+}
+
+static int hex_to_bin(const char hex) {
+ int bin = -1;
+ if (hex >= '0' && hex <= '9') {
+bin = hex - '0';
+ } else if (hex >= 'a' && hex <= 'z') {
+bin = hex - 'a' + 10;
+ } else if (hex >= 'A' && hex <= 'A') {
+bin = hex - 'A' + 10;
+ }
+ return bin;
+}
+
+static bool check_args(const char* cmd, int count, i2c_data* i2c) {
+ bool ok = count + i2c->arg <= i2c->argc;
+ if (!ok) {
+printf("error: %s: not enough arguments\n", cmd);
+ }
+ return ok;
+}
+
+static bool check_flag(i2c_data* i2c) {
+ if (i2c->arg >= i2c->argc) {
+return false;
+ }
+return i2c->argv[i2c->arg][0] == '-';
+}
+
+static const char* get_arg_inc(i2c_data* i2c) {
+ if (i2c->arg < i2c->argc) {
+return i2c->argv[i2c->arg++];
+ }
+ return "";
+}
+
+static int get_value(
+ const char* cmd, const char* type, int min, int max, int* val, i2c_data*
i2c) {
+ const char* arg;
+ if (!check_args(cmd, 1, i2c)) {
+return -1;
+ }
+ arg = get_arg_inc(i2c);
+ *val = (int) strtol(arg, NULL, 0);
+ if (*val < min || *val > max) {
+printf("error: %s: invalid %s: %s\n", cmd, type, arg);