i2c  1.4.2
RoadNarrows Robotics I2C Package
i2cread.c
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: RCB3
4 //
5 // File: i2cread.c
6 //
7 /*! \file
8  *
9  * $LastChangedDate: 2011-09-12 16:08:28 -0600 (Mon, 12 Sep 2011) $
10  * $Rev: 1279 $
11  *
12  * \brief Read an I2C device.
13  *
14  * \author Robin Knight (robin.knight@roadnarrows.com)
15  *
16  * \copyright
17  * \h_copy 2007-2017. RoadNarrows LLC.\n
18  * http://www.roadnarrows.com\n
19  * All Rights Reserved
20  */
21 // Permission is hereby granted, without written agreement and without
22 // license or royalty fees, to use, copy, modify, and distribute this
23 // software and its documentation for any purpose, provided that
24 // (1) The above copyright notice and the following two paragraphs
25 // appear in all copies of the source code and (2) redistributions
26 // including binaries reproduces these notices in the supporting
27 // documentation. Substantial modifications to this software may be
28 // copyrighted by their authors and need not follow the licensing terms
29 // described here, provided that the new terms are clearly indicated in
30 // all files where they apply.
31 //
32 // IN NO EVENT SHALL THE AUTHOR, ROADNARROWS LLC, OR ANY MEMBERS/EMPLOYEES
33 // OF ROADNARROW LLC OR DISTRIBUTORS OF THIS SOFTWARE BE LIABLE TO ANY
34 // PARTY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
35 // DAMAGES ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION,
36 // EVEN IF THE AUTHORS OR ANY OF THE ABOVE PARTIES HAVE BEEN ADVISED OF
37 // THE POSSIBILITY OF SUCH DAMAGE.
38 //
39 // THE AUTHOR AND ROADNARROWS LLC SPECIFICALLY DISCLAIM ANY WARRANTIES,
40 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
41 // FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN
42 // "AS IS" BASIS, AND THE AUTHORS AND DISTRIBUTORS HAVE NO OBLIGATION TO
43 // PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
44 //
45 ////////////////////////////////////////////////////////////////////////////////
46 
47 #include <stdio.h>
48 #include <stdlib.h>
49 #include <stdarg.h>
50 #include <string.h>
51 #include <errno.h>
52 #include <ctype.h>
53 #include <libgen.h>
54 #include <unistd.h>
55 
56 #include "rnr/rnrconfig.h"
57 #include "rnr/log.h"
58 #include "rnr/opts.h"
59 
60 #include "rnr/i2c-dev.h"
61 #include "rnr/i2c.h"
62 
63 #include "version.h"
64 
65 // ---------------------------------------------------------------------------
66 // Private Interface
67 // ---------------------------------------------------------------------------
68 
69 // The Command
70 static char *Argv0; ///< command namve
71 
72 //
73 // Command Option Values
74 //
75 static int OptVerbose = 0; ///< verbose option
76 static char *OptDevName = "/dev/i2c/0"; ///< i2c bus device option
77 static int OptDevFd = -1; ///< opened i2c bus dev option
78 static int OptI2CAddr = -1; ///< slave device address option
79 static int OptI2CReadCount = 1; ///< read byte count option
80 
81 /*!
82  * \brief Program Information
83  */
84 static OptsPgmInfo_T I2CReadPgmInfo =
85 {
86  .usage_args = "--address <addr>",
87 
88  .synopsis = "Read <count> bytes from an I2C device.",
89 
90  .long_desc =
91  "The %P command attempts to read <count> bytes from the specified I2C "
92  "device. All read bytes are printed to stdout in ASCII hex format.",
93 
94  .diagnostics =
95  "Exit status is 0 if <count> bytes are read, 1 otherwise. "
96  "Exit status is >=2 if error(s) are encountered."
97 };
98 
99 /*!
100  * \brief Command Line Options Information
101  */
102 static OptsInfo_T I2CReadOptsInfo[] =
103 {
104  // I2C device address
105  {
106  .long_opt = "address",
107  .short_opt = 'a',
108  .has_arg = required_argument,
109  .opt_addr = &OptI2CAddr,
110  .fn_cvt = OptsCvtArgInt,
111  .fn_fmt = OptsFmtInt,
112  .arg_name = "<addr>",
113  .opt_desc = "I2C device address. REQUIRED"
114  },
115 
116  // I2C device read count
117  {
118  .long_opt = "count",
119  .short_opt = 'c',
120  .has_arg = required_argument,
121  .has_default= true,
122  .opt_addr = &OptI2CReadCount,
123  .fn_cvt = OptsCvtArgInt,
124  .fn_fmt = OptsFmtInt,
125  .arg_name = "<count>",
126  .opt_desc = "I2C device read byte count"
127  },
128 
129  // I2C device name
130  {
131  .long_opt = "device",
132  .short_opt = 'd',
133  .has_arg = required_argument,
134  .has_default= true,
135  .opt_addr = &OptDevName,
136  .fn_cvt = OptsCvtArgStr,
137  .fn_fmt = OptsFmtStr,
138  .arg_name = "<device>",
139  .opt_desc = "I2C device."
140  },
141 
142  // opend I2C file descriptor
143  {
144  .long_opt = "fd",
145  .short_opt = OPTS_NO_SHORT,
146  .has_arg = required_argument,
147  .opt_addr = &OptDevFd,
148  .fn_cvt = OptsCvtArgInt,
149  .fn_fmt = OptsFmtInt,
150  .arg_name = "<n>",
151  .opt_desc = "Opened I2C device file descriptor."
152  },
153 
154  // verbose printing
155  {
156  .long_opt = "verbose",
157  .short_opt = 'v',
158  .has_arg = no_argument,
159  .has_default= true,
160  .opt_addr = &OptVerbose,
161  .fn_fmt = OptsFmtBool,
162  .opt_desc = "Set print verbosity."
163  },
164 
165  {NULL, }
166 };
167 
168 /*!
169  * \brief Execute \h_i2c slave device read.
170  *
171  * \param pI2C Pointer to \h_i2c handle.
172  * \param addr Slave device address.
173  * \param readlen Number of bytes to read.
174  *
175  * \return Returns number of bytes read \h_ge 0 on success, -1 on failure.
176  */
177 static int execRead(i2c_t *pI2C, int addr, int readlen)
178 {
179  int i;
180  byte_t readbuf[1024];
181 
182  if( readlen > sizeof(readbuf) )
183  {
184  readlen = sizeof(readbuf);
185  fprintf(stderr,
186  "%s: Warning: %d: I2C read length too long. Resetting to %u]\n",
187  Argv0, readlen, (uint_t)sizeof(readbuf));
188  }
189 
190  if( OptVerbose )
191  {
192  printf("%s Reading 0x%02x for %d bytes...\n", Argv0, (byte_t)addr, readlen);
193  }
194 
195  readlen = i2c_read(pI2C, (i2c_addr_t)addr, readbuf, (uint_t)readlen);
196 
197  if( readlen < 0 )
198  {
199  LOGSYSERROR("i2c_read()");
200  return RC_ERROR;
201  }
202 
203  if( OptVerbose )
204  {
205  printf("Read %d bytes: ", readlen);
206  }
207  for(i=0; i<readlen; ++i)
208  {
209  printf("0x%02x ", readbuf[i]);
210  }
211  if( (readlen > 0) || OptVerbose )
212  {
213  printf("\n");
214  }
215 
216  return readlen;
217 }
218 
219 /*!
220  * \brief Command initialization.
221  *
222  * \param argc Command-line argument count.
223  * \param argv Command-line arguments.
224  * \param pI2C Pointer to \h_i2c handle.
225  */
226 static void MainInit(int argc, char *argv[], i2c_t *pI2C)
227 {
228  // Name of this process
229  Argv0 = basename(argv[0]);
230 
231  // Get the environment
232  //EnvGet();
233 
234  // Parse input arguments
235  argv = OptsGet(Argv0, &PkgInfo, &I2CReadPgmInfo, I2CReadOptsInfo, true,
236  &argc, argv);
237 
238  // Final option checks
239  if( OptI2CAddr < 0x00 )
240  {
241  fprintf(stderr, "%s: Address option required\n", Argv0);
242  exit(EC_BAD_OPT);
243  }
245  {
246  fprintf(stderr, "%s: Address out of range: 0x%x\n", Argv0, OptI2CAddr);
247  exit(EC_BAD_OPT);
248  }
249 
250  // Opened device specified
251  if( OptDevFd >= 0 )
252  {
253  pI2C->fd = OptDevFd;
254  pI2C->addr = (ushort_t)(-1);
255  }
256 
257  // I2C Bus device specified
258  else
259  {
260  if( OptDevName == NULL || OptDevName[0] == 0 )
261  {
262  OptDevName = "/dev/i2c/0";
263  }
264 
265  if( OptVerbose )
266  {
267  printf("I2C device: %s\n\n", OptDevName);
268  }
269 
270  if( i2c_open(pI2C, OptDevName) < 0 )
271  {
272  LOGSYSERROR("%s: Failed to open.", OptDevName);
273  exit(EC_ERROR);
274  }
275  }
276 }
277 
278 /*!
279  * \brief i2cread main()
280  *
281  * \param argc Count of command-line options and arguments.
282  * \param argv Array of command-line options and arguments.
283  *
284  * \return Exit value.
285  */
286 int main(int argc, char *argv[])
287 {
288  i2c_t i2c;
289  int rc;
290 
291  MainInit(argc, argv, &i2c);
292 
293  rc = execRead(&i2c, OptI2CAddr, OptI2CReadCount);
294 
295  return rc > 0? 0: (rc == 0? 1: 2);
296 }
297 
298 /*!
299 \page i2cread I2CREAD(1)
300 
301 \section NAME
302 i2cread - Read bytes from an I<sup>2</sup>C Bus device
303 
304 \section SYNOPSIS
305 i2cread [OPTIONS] --address <addr>
306 
307 \section DESCRIPTION
308 The i2cread command attempts to read <count> bytes from the specified
309 I<sup>2</sup> device.
310 The bytes read are printed to \p stdout in ASCII hex format.
311 
312 \section OPTIONS RNR_OPTIONS
313 \verbatim
314  -a, --address=<addr> I2C device 7-bit address. REQUIRED.
315  -c, --count=<count> Read count bytes.
316  DEFAULT: 1
317  -d, --device=<device> I2C device.
318  DEFAULT: /dev/i2c/0
319  --fd=<n> Opened I2C device file descriptor.
320  -v, --verbose Set print verbosity.
321  DEFAULT: false
322  RNR_OPTIONS Standard set of options provided by librnr.
323 \endverbatim
324 
325 \section DIAGNOSTICS
326 Exit status is 0 if <count> bytes are read, 1 otherwise.
327 Exit status is >= 2 if error(s) are encountered.
328 
329 \section SEE_ALSO
330 \ref i2ccheck,
331 \ref i2cscan,
332 \ref i2ctrans,
333 \ref i2cwrite
334 
335 \section AUTHOR
336 Robin Knight (robin.knight@roadnarrows.com)
337 
338 \section COPYRIGHT
339 (C) 2007. RoadNarrows LLC.
340 (http://www.roadnarrows.com)
341 \n All Rights Reserved
342 */
i2c_addr_t addr
address of the currently selected attached I2C device
Definition: i2c.h:82
static OptsInfo_T I2CReadOptsInfo[]
Command Line Options Information.
Definition: i2cread.c:102
static char * OptDevName
i2c bus device option
Definition: i2cread.c:76
I2C python modules.
int fd
opened file descriptor of the I2C bus device
Definition: i2c.h:81
static int OptVerbose
verbose option
Definition: i2cread.c:75
ushort_t i2c_addr_t
I2C Device Address Type.
Definition: i2c.h:72
int main(int argc, char *argv[])
i2cread main()
Definition: i2cread.c:286
I2C Bus Handle Type.
Definition: i2c.h:79
#define I2C_ADDR_DEV_HIGH
last available device address
Definition: i2c-dev.h:103
static int OptI2CAddr
slave device address option
Definition: i2cread.c:78
static char * Argv0
command namve
Definition: i2cread.c:70
static int OptI2CReadCount
read byte count option
Definition: i2cread.c:79
static int execRead(i2c_t *pI2C, int addr, int readlen)
Execute I2C slave device read.
Definition: i2cread.c:177
I2C character device interface.
static const PkgInfo_T PkgInfo
Definition: version.h:45
static void MainInit(int argc, char *argv[], i2c_t *pI2C)
Command initialization.
Definition: i2cread.c:226
Package version information.
static int OptDevFd
opened i2c bus dev option
Definition: i2cread.c:77
static OptsPgmInfo_T I2CReadPgmInfo
Program Information.
Definition: i2cread.c:84
int i2c_open(i2c_t *i2c, const char *device)
Open the host I2C Bus device.
Definition: i2ccom.c:118
int i2c_read(i2c_t *i2c, i2c_addr_t addr, byte_t *buf, uint_t len)
Read from an I2C device.
Definition: i2ccom.c:147
#define I2C_ADDR_DEV_LOW
first available device address
Definition: i2c-dev.h:101
Low-level I2C communication level.