diff options
author | Christian Mauderer <christian.mauderer@embedded-brains.de> | 2020-11-18 08:36:48 +0100 |
---|---|---|
committer | Jan Sommer <jan.sommer@dlr.de> | 2021-03-31 10:43:48 +0200 |
commit | a274b6fdcb7b39b3d67aad33dba0360a47f20204 (patch) | |
tree | 31d12ec76f4ac1efe77883074908e49b710393d1 /cpukit/libmisc/shell/main_i2cset.c | |
parent | bsps/xilinx_zynq: Add Xilinx AXI SPI driver to build (diff) | |
download | rtems-a274b6fdcb7b39b3d67aad33dba0360a47f20204.tar.bz2 |
shell: Add i2c and spi commands
This adds some commands that are usefull for debugging simple serial
interfaces.
Even if they are a complete re-implementation, the i2c* commands use a
simmilar call like the Linux i2c tools.
Closes #4371
Diffstat (limited to 'cpukit/libmisc/shell/main_i2cset.c')
-rw-r--r-- | cpukit/libmisc/shell/main_i2cset.c | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/cpukit/libmisc/shell/main_i2cset.c b/cpukit/libmisc/shell/main_i2cset.c new file mode 100644 index 0000000000..d9025b3b28 --- /dev/null +++ b/cpukit/libmisc/shell/main_i2cset.c @@ -0,0 +1,124 @@ +/* + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (C) 2020 embedded brains GmbH. + * + * 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. + */ + +/* + * The command implemented here has a similar interface like the one from Linux + * i2c tools. Think of it as a heavily simplified version of them. Instead of + * the bus number they expect a bus path. + * + * Additionally it is possible to write multiple values as a continuous write. + */ + +#include <dev/i2c/i2c.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> + +#include <rtems/shell.h> + +static const char rtems_i2cset_shell_usage [] = + "i2cset <I2C_BUS> <CHIP-ADDRESS> <DATA-ADDRESS> <VALUE> [<VALUE> [...]]\n" + "\tset one byte of an EEPROM like i2c device\n"; + +static int +rtems_i2cset_shell_main(int argc, char *argv[]) +{ + int fd; + int rv; + const char *bus; + uint16_t chip_address; + /* Necessary: data-address and values. This will be a bit more. */ + uint8_t writebuff[argc]; + size_t len; + size_t i; + i2c_msg msgs[] = {{ + .flags = 0, + .buf = writebuff, + .len = 0, + }}; + struct i2c_rdwr_ioctl_data payload = { + .msgs = msgs, + .nmsgs = sizeof(msgs)/sizeof(msgs[0]), + }; + + if (argc < 5) { + printf(rtems_i2cset_shell_usage); + return 1; + } + + errno = 0; + chip_address = (uint16_t) strtoul(argv[2], NULL, 0); + if (errno != 0) { + perror("Couldn't read CHIP_ADDRESS"); + return 1; + } + msgs[0].addr = chip_address; + + errno = 0; + writebuff[0] = (uint8_t) strtoul(argv[3], NULL, 0); + if (errno != 0) { + perror("Couldn't read DATA_ADDRESS"); + return 1; + } + + /* Read values starting from the fifth argument (index 4) */ + i = 4; + len = 0; + while (i < argc) { + errno = 0; + writebuff[len + 1] = (uint8_t) strtoul(argv[i], NULL, 0); + if (errno != 0) { + perror("Couldn't read VALUE"); + return 1; + } + ++i; + ++len; + } + msgs[0].len = len + 1; /* Don't forget address */ + + bus = argv[1]; + fd = open(bus, O_RDWR); + if (fd < 0) { + perror("Couldn't open bus"); + return 1; + } + + rv = ioctl(fd, I2C_RDWR, &payload); + if (rv < 0) { + perror("ioctl failed"); + } + close(fd); + + return rv; +} + +rtems_shell_cmd_t rtems_shell_I2CSET_Command = { + .name = "i2cset", + .usage = rtems_i2cset_shell_usage, + .topic = "misc", + .command = rtems_i2cset_shell_main, +}; |