source: rtems/cpukit/libmisc/shell/main_i2cget.c @ a274b6f

5
Last change on this file since a274b6f was a274b6f, checked in by Christian Mauderer <christian.mauderer@…>, on 11/18/20 at 07:36:48

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

  • Property mode set to 100644
File size: 3.8 KB
Line 
1/*
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (C) 2020 embedded brains GmbH.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 * POSSIBILITY OF SUCH DAMAGE.
26 */
27
28/*
29 * The command implemented here has a similar interface like the one from Linux
30 * i2c tools. Think of it as a heavily simplified version of them. Instead of
31 * the bus number they expect a bus path.
32 *
33 * Additionally the i2cget has a continuous read mode that isn't available on
34 * Linux but does something similar to i2cdump.
35 */
36
37#include <dev/i2c/i2c.h>
38#include <fcntl.h>
39#include <stdio.h>
40#include <stdlib.h>
41
42#include <rtems/shell.h>
43
44static const char rtems_i2cget_shell_usage [] =
45  "i2cget <I2C_BUS> <CHIP-ADDRESS> <DATA-ADDRESS> [<NR-BYTES>]\n"
46  "\tGet one or more bytes from an EEPROM like i2c device.\n"
47  "\tNote that multiple bytes will be read in continuous mode.\n";
48
49static int read_bytes(
50  int fd,
51  uint16_t i2c_address,
52  uint8_t data_address,
53  uint16_t nr_bytes
54)
55{
56  int rv;
57  uint8_t value[nr_bytes];
58  i2c_msg msgs[] = {{
59    .addr = i2c_address,
60    .flags = 0,
61    .buf = &data_address,
62    .len = 1,
63  }, {
64    .addr = i2c_address,
65    .flags = I2C_M_RD,
66    .buf = value,
67    .len = nr_bytes,
68  }};
69  struct i2c_rdwr_ioctl_data payload = {
70    .msgs = msgs,
71    .nmsgs = sizeof(msgs)/sizeof(msgs[0]),
72  };
73  uint16_t i;
74
75  rv = ioctl(fd, I2C_RDWR, &payload);
76  if (rv < 0) {
77    perror("ioctl failed");
78  } else {
79    for (i = 0; i < nr_bytes; ++i) {
80      printf("0x%02x ", value[i]);
81    }
82    printf("\n");
83  }
84
85  return rv;
86}
87
88static int rtems_i2cget_shell_main(int argc, char *argv[])
89{
90  int fd;
91  int rv;
92  const char *bus;
93  uint16_t chip_address;
94  uint8_t data_address;
95  uint16_t nr_bytes;
96
97  if (argc < 4 || argc > 5) {
98    printf(rtems_i2cget_shell_usage);
99    return 1;
100  }
101
102  errno = 0;
103  chip_address = (uint16_t) strtoul(argv[2], NULL, 0);
104  if (errno != 0) {
105    perror("Couldn't read chip address");
106    return 1;
107  }
108
109  errno = 0;
110  data_address = (uint8_t) strtoul(argv[3], NULL, 0);
111  if (errno != 0) {
112    perror("Couldn't read data address");
113    return 1;
114  }
115
116  nr_bytes = 1;
117  if (argc == 5) {
118    errno = 0;
119    nr_bytes = (uint16_t) strtoul(argv[4], NULL, 0);
120    if (errno != 0) {
121      perror("Couldn't read number of bytes");
122      return 1;
123    }
124  }
125
126  bus = argv[1];
127  fd = open(bus, O_RDWR);
128  if (fd < 0) {
129    perror("Couldn't open bus");
130    return 1;
131  }
132
133  rv = read_bytes(fd, chip_address, data_address, nr_bytes);
134
135  close(fd);
136
137  return rv;
138}
139
140rtems_shell_cmd_t rtems_shell_I2CGET_Command = {
141  .name = "i2cget",
142  .usage = rtems_i2cget_shell_usage,
143  .topic = "misc",
144  .command = rtems_i2cget_shell_main,
145};
Note: See TracBrowser for help on using the repository browser.