i2c  1.4.2
RoadNarrows Robotics I2C Package
i2csh.c
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////
2 //
3 // Package: RCB3
4 //
5 // File: i2csh.c
6 //
7 /*! \file
8  *
9  * $LastChangedDate: 2009-09-09 09:44:12 -0600 (Wed, 09 Sep 2009) $
10  * $Rev: 130 $
11  *
12  * \brief Simple I2C Bus Command-Line Shell.
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 
55 #ifdef HAVE_READLINE
56 #include <readline/readline.h>
57 #include <readline/history.h>
58 #endif // HAVE_READLINE
59 
60 #include "rnr/rnrconfig.h"
61 #include "rnr/log.h"
62 #include "rnr/opts.h"
63 
64 #include "rnr/i2c.h"
65 
66 #include "version.h"
67 
68 // ---------------------------------------------------------------------------
69 // Private Interface
70 // ---------------------------------------------------------------------------
71 
72 #define RC_QUIT (RC_ERROR-1) ///< quit shell return code
73 
74 //
75 // types
76 //
77 
78 /*!
79  * \brief Command execution function type.
80  */
81 typedef int (execfunc_t)(i2c_t *, int, const char *[]);
82 
83 /*!
84  * \brief Shell Command Info.
85  */
86 typedef struct
87 {
88  const char *m_sCmd; ///< input-line full command name
89  execfunc_t *m_fnExec; ///< assoc. exec. function
90  const char *m_sHelpBrief; ///< command help
91  const char *m_sHelpArgs; ///< command help argments
92 } shcmd_t;
93 
94 // The Command
95 static char *Argv0; ///< command name
96 
97 static int OptVerbose = 0; ///< verbose option
98 static char *OptDevName = "/dev/i2c/0"; ///< i2c bus device option
99 
100 /*!
101  * \brief Program Information
102  */
103 static OptsPgmInfo_T I2CShPgmInfo =
104 {
105  .synopsis = "I2C Simple Raw Shell",
106  .long_desc =
107  "The I2C Shell (%P) provides a simple interactive interface to devices "
108  "attached to an I2C Bus."
109 };
110 
111 /*!
112  * \brief Command Line Options Information
113  */
114 static OptsInfo_T I2CShOptsInfo[] =
115 {
116  // I2C device name
117  {
118  .long_opt = "device",
119  .short_opt = 'd',
120  .has_arg = required_argument,
121  .has_default= true,
122  .opt_addr = &OptDevName,
123  .fn_cvt = OptsCvtArgStr,
124  .fn_fmt = OptsFmtStr,
125  .arg_name = "<device>",
126  .opt_desc = "I2C device."
127  },
128 
129  // verbose printing
130  {
131  .long_opt = "verbose",
132  .short_opt = 'v',
133  .has_arg = no_argument,
134  .has_default= true,
135  .opt_addr = &OptVerbose,
136  .fn_fmt = OptsFmtBool,
137  .opt_desc = "Set print verbosity."
138  },
139 
140  {NULL, }
141 };
142 
143 
144 // ---------------------------------------------------------------------------
145 // Support
146 // ---------------------------------------------------------------------------
147 
148 /*!
149  * \brief Convert string to unsigned integer.
150  *
151  * \param s String.
152  * \param [out] pVal Pointer to converted value.
153  *
154  * \return Returns OK on success, RC_ERROR on error.
155  */
156 static int StrToUnsigned(const char *s, uint_t *pVal)
157 {
158  long lVal;
159  char *sEnd;
160 
161  if( (s == NULL) || (*s == 0) )
162  {
163  return RC_ERROR;
164  }
165 
166  lVal = strtol(s, &sEnd, 0);
167 
168  if( *sEnd != 0 )
169  {
170  return RC_ERROR;
171  }
172  else if( lVal < 0 )
173  {
174  return RC_ERROR;
175  }
176  else
177  {
178  *pVal = (uint_t)lVal;
179  return OK;
180  }
181 }
182 
183 /*!
184  * \brief Convert string to byte.
185  *
186  * \param s String.
187  * \param [out] pByte Pointer to converted value.
188  *
189  * \return Returns OK on success, RC_ERROR on error.
190  */
191 static int StrToByte(const char *s, byte_t *pByte)
192 {
193  uint_t uVal;
194 
195  if( StrToUnsigned(s, &uVal) != OK )
196  {
197  return RC_ERROR;
198  }
199  else if( uVal > 0xff )
200  {
201  return RC_ERROR;
202  }
203  else
204  {
205  *pByte = (byte_t)uVal;
206  return OK;
207  }
208 }
209 
210 /*!
211  * \brief Make array of arguments separated with white-space.
212  *
213  * \param sLine Input line.
214  * \param [out] pArgc Number of parsed arguments
215  *
216  * \return Returns pointer to array of strings.
217  */
218 static const char **makeargs(char *sLine, int *pArgc)
219 {
220  static const char *args[256];
221  char *s;
222  char *sDelim = " \t\n\r";
223  int i = 0;
224 
225  for(s=strtok(sLine, sDelim); s!=NULL && i<256; s=strtok(NULL, sDelim))
226  {
227  args[i++] = s;
228  }
229  *pArgc = i;
230  return args;
231 }
232 
233 #ifndef HAVE_READLINE
234 /*!
235  * \brief Read an input line from stdin.
236  *
237  * This function is used only if there is no readline functionality.
238  *
239  * \param prompt User prompt string.
240  *
241  * \return Returns read line buffer.
242  */
243 static char *readline(const char *prompt)
244 {
245  static char linebuf[512]; // real readline() uses malloc's so adjust
246  int bIsBlank;
247  char *s;
248 
249  if( prompt && *prompt )
250  {
251  printf("%s", prompt);
252  }
253 
254  if( fgets(linebuf, (int)sizeof(linebuf), stdin) == NULL )
255  {
256  return 0;
257  }
258 
259  linebuf[sizeof(linebuf)-1] = 0;
260 
261  bIsBlank = 1;
262  for(s=linebuf; *s && bIsBlank; ++s)
263  {
264  if( !isspace(*s) )
265  {
266  bIsBlank = 0;
267  }
268  }
269 
270  if( bIsBlank )
271  {
272  return NULL;
273  }
274  else
275  {
276  return linebuf;
277  }
278 }
279 #endif // HAVE_READLINE
280 
281 
282 // ---------------------------------------------------------------------------
283 // Commands
284 // ---------------------------------------------------------------------------
285 
286 /*!
287  * \brief Execute \h_i2c slave device read.
288  *
289  * read <addr> <readlength>
290  *
291  * \param pI2C Pointer to \h_i2c handle.
292  * \param nArgc Number of input arguments.
293  * \param sArgv Array of input argument strings.
294  *
295  * \return Returns OK on success, RC_ERROR on error.
296  */
297 static int execRead(i2c_t *pI2C, int nArgc, const char *sArgv[])
298 {
299  int i;
300  byte_t addr;
301  byte_t readbuf[256];
302  uint_t readlen;
303  int rc;
304 
305  if( nArgc != 3 )
306  {
307  printf("Error: %s requires 2 arguments\n", sArgv[0]);
308  return RC_ERROR;
309  }
310 
311  LOGDIAG1CALL(_TPTR(pI2C), _TINT(nArgc), _TSTR(sArgv[0]), _TSTR(sArgv[1]),
312  _TSTR(sArgv[2]));
313 
314  // address
315  if( StrToByte(sArgv[1], &addr) != OK )
316  {
317  printf("Error: %s: bad I2C address\n", sArgv[1]);
318  return RC_ERROR;
319  }
320  else if( addr > 0x7f )
321  {
322  printf("Error: 0x%02x: I2C address out of range [0,0x7f]\n", addr);
323  return RC_ERROR;
324  }
325 
326  // read length
327  if( StrToUnsigned(sArgv[2], &readlen) != OK )
328  {
329  printf("Error: %s: bad read length\n", sArgv[2]);
330  return RC_ERROR;
331  }
332  else if( readlen > sizeof(readbuf) )
333  {
334  printf("Error: %d: I2C read length out of range [0,%u]\n",
335  readlen, (uint_t)sizeof(readbuf));
336  return RC_ERROR;
337  }
338 
339  // echo out parsed command prior to execution
340  if( OptVerbose )
341  {
342  printf("command: %s\n", sArgv[0]);
343  printf(" address: 0x%02x\n", addr);
344  printf(" read length: %d\n", readlen);
345  }
346 
347  rc = i2c_read(pI2C, addr, readbuf, readlen);
348  if( rc < 0 )
349  {
350  LOGSYSERROR("i2c_read()");
351  return RC_ERROR;
352  }
353 
354  if( OptVerbose )
355  {
356  printf("response:\n");
357  printf(" read: ");
358  }
359 
360  readlen = (uint_t)rc;
361 
362  for(i=0; i<readlen; ++i)
363  {
364  printf("0x%02x ", readbuf[i]);
365  }
366  printf("\n");
367  if( OptVerbose )
368  {
369  printf(" bytes read: %u\n", readlen);
370  }
371 
372  return OK;
373 }
374 
375 /*!
376  * \brief Execute \h_i2c slave device write.
377  *
378  * write <addr> <wbyte0> [<wbyte1> ...]
379  *
380  * \param pI2C Pointer to \h_i2c handle.
381  * \param nArgc Number of input arguments.
382  * \param sArgv Array of input argument strings.
383  *
384  * \return Returns OK on success, RC_ERROR on error.
385  */
386 static int execWrite(i2c_t *pI2C, int nArgc, const char *sArgv[])
387 {
388  int i, j;
389  byte_t addr;
390  byte_t writebuf[256];
391  uint_t writelen;
392  int rc;
393 
394  if( nArgc < 3 )
395  {
396  printf("Error: %s requires at least 2 arguments\n", sArgv[0]);
397  return RC_ERROR;
398  }
399 
400  LOGDIAG1CALL(_TPTR(pI2C), _TINT(nArgc), _TSTR(sArgv[0]), _TSTR(sArgv[1]),
401  _TSTR(sArgv[2]));
402 
403  // address
404  if( StrToByte(sArgv[1], &addr) != OK )
405  {
406  printf("Error: %s: bad I2C address\n", sArgv[1]);
407  return RC_ERROR;
408  }
409  else if( addr > 0x7f )
410  {
411  printf("Error: 0x%02x: I2C address out of range [0,0x7f]\n", addr);
412  return RC_ERROR;
413  }
414 
415  // write bytes
416  for(i=2, j=0; i<nArgc && j<sizeof(writebuf); ++i, ++j)
417  {
418  if( StrToByte(sArgv[i], writebuf+j) != OK )
419  {
420  printf("Error: argv[%d]='%s': bad byte value\n", i, sArgv[i]);
421  return RC_ERROR;
422  }
423  }
424  writelen = (uint_t)j;
425 
426  // echo out parsed command prior to execution
427  if( OptVerbose )
428  {
429  printf("command: %s\n", sArgv[0]);
430  printf(" address: 0x%02x\n", addr);
431  printf(" write length: %d\n", writelen);
432  printf(" write: ");
433  for(i=0; i<writelen; ++i)
434  {
435  printf("0x%02x ", writebuf[i]);
436  }
437  printf("\n");
438  }
439 
440  rc = i2c_write(pI2C, addr, writebuf, writelen);
441 
442  if( rc < 0 )
443  {
444  LOGSYSERROR("i2c_write()");
445  return RC_ERROR;
446  }
447 
448  if( OptVerbose )
449  {
450  printf("response:\n");
451  printf(" bytes written: ");
452  }
453  printf("%d\n", writelen);
454 
455  return OK;
456 }
457 
458 /*!
459  * \brief Execute \h_i2c slave device write/read transaction.
460  *
461  * transaction <addr> <wbyte0> [<wbyte1> ...] <readlength>
462  *
463  * \param pI2C Pointer to \h_i2c handle.
464  * \param nArgc Number of input arguments.
465  * \param sArgv Array of input argument strings.
466  *
467  * \return Returns OK on success, RC_ERROR on error.
468  */
469 static int execTransaction(i2c_t *pI2C, int nArgc, const char *sArgv[])
470 {
471  int i, j;
472  byte_t addr;
473  byte_t writebuf[256];
474  uint_t writelen;
475  byte_t readbuf[256];
476  uint_t readlen;
477  int rc;
478 
479  if( nArgc < 4 )
480  {
481  printf("Error: %s requires at least 3 arguments\n", sArgv[0]);
482  return RC_ERROR;
483  }
484 
485  LOGDIAG1CALL(_TPTR(pI2C), _TINT(nArgc), _TSTR(sArgv[0]), _TSTR(sArgv[1]),
486  _TSTR(sArgv[2]), _TSTR(sArgv[3]));
487 
488  // address
489  if( StrToByte(sArgv[1], &addr) != OK )
490  {
491  printf("Error: %s: bad I2C address\n", sArgv[1]);
492  return RC_ERROR;
493  }
494  else if( addr > 0x7f )
495  {
496  printf("Error: 0x%02x: I2C address out of range [0,0x7f]\n", addr);
497  return RC_ERROR;
498  }
499 
500  // write bytes
501  for(i=2, j=0; i<nArgc-1 && j<sizeof(writebuf); ++i, ++j)
502  {
503  if( StrToByte(sArgv[i], writebuf+j) != OK )
504  {
505  printf("Error: argv[%d]='%s': bad byte value\n", i, sArgv[i]);
506  return RC_ERROR;
507  }
508  }
509  writelen = (uint_t)j;
510 
511  // read length
512  if( StrToUnsigned(sArgv[nArgc-1], &readlen) != OK )
513  {
514  printf("Error: %s: bad read length\n", sArgv[nArgc-1]);
515  return RC_ERROR;
516  }
517  else if( readlen > sizeof(readbuf) )
518  {
519  printf("Error: %d: I2C read length out of range [0,%u]\n",
520  readlen, (uint_t)sizeof(readbuf));
521  return RC_ERROR;
522  }
523 
524  // echo out parsed command prior to execution
525  if( OptVerbose )
526  {
527  printf("command: %s\n", sArgv[0]);
528  printf(" address: 0x%02x\n", addr);
529  printf(" write length: %d\n", writelen);
530  printf(" write: ");
531  for(i=0; i<writelen; ++i)
532  {
533  printf("0x%02x ", writebuf[i]);
534  }
535  printf("\n");
536  printf(" read length: %d\n", readlen);
537  }
538 
539  rc = i2c_transfer(pI2C, addr, writebuf, writelen, readbuf, readlen);
540 
541  if( rc < 0 )
542  {
543  LOGSYSERROR("i2c_transfer()");
544  return RC_ERROR;
545  }
546 
547  if( OptVerbose )
548  {
549  printf("response:\n");
550  printf(" read: ");
551  }
552  for(i=0; i<readlen; ++i)
553  {
554  printf("0x%02x ", readbuf[i]);
555  }
556  printf("\n");
557 
558  return OK;
559 }
560 
561 /*!
562  * \brief Found scanned device callback.
563  *
564  * \param pI2C Pointer to \h_i2c handle.
565  * \param addr Slave device address.
566  * \param context User provided context.
567  *
568  * \return Returns 1.
569  */
570 static int scanCallback(i2c_t *pI2C, i2c_addr_t addr, void *context)
571 {
572  printf("0x%02x ", addr);
573  return 1;
574 }
575 
576 /*!
577  * \brief Execute \h_i2c slave device scan.
578  *
579  * scan
580  *
581  * \param pI2C Pointer to \h_i2c handle.
582  * \param nArgc Number of input arguments.
583  * \param sArgv Array of input argument strings.
584  *
585  * \return Returns OK on success, RC_ERROR on error.
586  */
587 static int execScan(i2c_t *pI2C, int nArgc, const char *sArgv[])
588 {
589  int n;
590 
591  if( nArgc > 1 )
592  {
593  printf("Error: %s takes no arguments\n", sArgv[0]);
594  return RC_ERROR;
595  }
596 
597  LOGDIAG1CALL(_TPTR(pI2C), _TINT(nArgc), _TSTR(sArgv[0]));
598 
599  if( OptVerbose )
600  {
601  printf("command: %s\n", sArgv[0]);
602  printf("response:\n");
603  printf(" scanned devices: ");
604  }
605  n = i2c_scan(pI2C, scanCallback, NULL);
606  printf("\n");
607 
608  if( OptVerbose )
609  {
610  printf(" number found: %d\n", n);
611  }
612 
613  return OK;
614 }
615 
616 /*!
617  * \brief Execute \h_i2c slave device check.
618  *
619  * check <addr>
620  *
621  * \param pI2C Pointer to \h_i2c handle.
622  * \param nArgc Number of input arguments.
623  * \param sArgv Array of input argument strings.
624  *
625  * \return Returns OK on success, RC_ERROR on error.
626  */
627 static int execCheck(i2c_t *pI2C, int nArgc, const char *sArgv[])
628 {
629  byte_t addr;
630  int rc;
631 
632  if( nArgc != 2 )
633  {
634  printf("Error: %s requires 1 argument\n", sArgv[0]);
635  return RC_ERROR;
636  }
637 
638  LOGDIAG1CALL(_TPTR(pI2C), _TINT(nArgc), _TSTR(sArgv[0]), _TSTR(sArgv[1]));
639 
640  // address
641  if( StrToByte(sArgv[1], &addr) != OK )
642  {
643  printf("Error: %s: bad I2C address\n", sArgv[1]);
644  return RC_ERROR;
645  }
646  else if( addr > 0x7f )
647  {
648  printf("Error: 0x%02x: I2C address out of range [0,0x7f]\n", addr);
649  return RC_ERROR;
650  }
651 
652  if( OptVerbose )
653  {
654  printf("command: %s\n", sArgv[0]);
655  }
656  rc = i2c_exists(pI2C, addr);
657  if( rc < 0 )
658  {
659  LOGSYSERROR("i2c_exists()");
660  return RC_ERROR;
661  }
662 
663  if( OptVerbose )
664  {
665  printf("response:\n");
666  printf(" 0x%02X", addr);
667  }
668 
669  if( rc )
670  {
671  printf("device found\n");
672  }
673  else
674  {
675  printf("device not found\n");
676  }
677 
678  return OK;
679 }
680 
681 /*!
682  * \brief Execute enabling/disabling verbose printing.
683  *
684  * \param pI2C Pointer to \h_i2c handle.
685  * \param nArgc Number of input arguments.
686  * \param sArgv Array of input argument strings.
687  *
688  * \return Returns OK on success, RC_ERROR on error.
689  */
690 static int execVerbose(i2c_t *pI2C, int nArgc, const char *sArgv[])
691 {
692  //printf("execExists(%s, %d, ...)\n", sArgv[0], nArgc);
693 
694  if( nArgc != 2 )
695  {
696  printf("Error: %s requires 1 argument\n", sArgv[0]);
697  return RC_ERROR;
698  }
699 
700  if( !strcmp(sArgv[1], "on") )
701  {
702  OptVerbose = 1;
703  printf("on\n");
704  return OK;
705  }
706  else if( !strcmp(sArgv[1], "off") )
707  {
708  OptVerbose = 0;
709  printf("off\n");
710  return OK;
711  }
712  else
713  {
714  printf("Error: %s: unknown option\n", sArgv[1]);
715  return RC_ERROR;
716  }
717 }
718 
719 static shcmd_t I2CCmds[]; ///< forward declaration of shell commands
720 
721 /*!
722  * \brief Execute shell help.
723  *
724  * \param pI2C Pointer to \h_i2c handle.
725  * \param nArgc Number of input arguments.
726  * \param sArgv Array of input argument strings.
727  *
728  * \return Returns OK on success, RC_ERROR on error.
729  */
730 static int execHelp(i2c_t *pI2C, int nArgc, const char *sArgv[])
731 {
732  shcmd_t *pCmd;
733 
734  //printf("execHelp(%s, %d, ...)\n", sArgv[0], nArgc);
735 
736  for(pCmd=I2CCmds; pCmd->m_sCmd!=NULL; pCmd++)
737  {
738  if( pCmd->m_sHelpArgs != NULL )
739  {
740  printf("%s %s\n", pCmd->m_sCmd, pCmd->m_sHelpArgs);
741  }
742  printf(" %s\n", pCmd->m_sHelpBrief);
743  }
744  return OK;
745 }
746 
747 /*!
748  * \brief Execute quit shell.
749  *
750  * \param pI2C Pointer to \h_i2c handle.
751  * \param nArgc Number of input arguments.
752  * \param sArgv Array of input argument strings.
753  *
754  * \return Returns RC_QUIT.
755  */
756 static int execQuit(i2c_t *pI2C, int nArgc, const char *sArgv[])
757 {
758  //printf("execQuit(%s, %d, ...)\n", sArgv[0], nArgc);
759  i2c_close(pI2C);
760 
761  return RC_QUIT;
762 }
763 
764 /*!
765  * \brief Shell commands.
766  */
767 static shcmd_t I2CCmds[] =
768 {
769  { "read",
770  execRead,
771  "read I2C device",
772  "<addr> <readlength>"
773  },
774 
775  { "write",
776  execWrite,
777  "write I2C device",
778  "<addr> <wbyte0> [<wbyte1> ...]"
779  },
780 
781  { "transaction",
783  "I2C write/read transaction",
784  "<addr> <wbyte0> [<wbyte1> ...] <readlength>"
785  },
786 
787  { "check",
788  execCheck,
789  "check if device exists on I2C Bus",
790  "<addr>"
791  },
792 
793  { "scan",
794  execScan,
795  "scan I2C Bus for all connected devices",
796  ""
797  },
798 
799  { "verbose",
800  execVerbose,
801  "print verbosity",
802  "{on|off}"
803  },
804 
805  { "help",
806  execHelp,
807  "print help",
808  ""
809  },
810 
811  { "quit",
812  execQuit,
813  "quit shell",
814  ""
815  },
816 
817  {NULL, }
818 };
819 
820 
821 // ---------------------------------------------------------------------------
822 // Execution Control
823 // ---------------------------------------------------------------------------
824 
825 /*!
826  * \brief Command initialization.
827  *
828  * \param argc Command-line argument count.
829  * \param argv Command-line arguments.
830  * \param pI2C Pointer to \h_i2c handle.
831  */
832 static void MainInit(int argc, char *argv[], i2c_t *pI2C)
833 {
834  // Name of this process
835  Argv0 = basename(argv[0]);
836 
837  // Get the environment
838  //EnvGet();
839 
840  // Parse input arguments
841  argv = OptsGet(Argv0, &PkgInfo, &I2CShPgmInfo, I2CShOptsInfo, true,
842  &argc, argv);
843 
844  if( OptDevName == NULL || OptDevName[0] == 0 )
845  {
846  OptDevName = "/dev/i2c/0";
847  }
848 
849  if( OptVerbose )
850  {
851  printf("I2C device: %s\n\n", OptDevName);
852  }
853 
854  if( i2c_open(pI2C, OptDevName) < 0 )
855  {
856  LOGSYSERROR("%s: Failed to open.", OptDevName);
857  exit(EC_ERROR);
858  }
859 }
860 
861 /*!
862  * \brief Shell main loop.
863  *
864  * \param pI2C Pointer to \h_i2c handle.
865  */
866 static void MainLoop(i2c_t *pI2C)
867 {
868  int bDoQuit = 0;
869  char *sInput;
870  int nArgc;
871  const char **sArgv;
872  //int i;
873  int bDidCmd;
874  shcmd_t *pCmd;
875  int rc;
876 
877  while( !bDoQuit )
878  {
879  sInput = readline("i2csh> ");
880  if( sInput == NULL )
881  {
882  continue;
883  }
884  //printf("'%s'\n", sInput);
885 
886  sArgv = makeargs(sInput, &nArgc);
887  //for(i=0; i<nArgc; ++i)
888  //{
889  // printf("sArgv[%d]='%s'\n", i, sArgv[i]);
890  //}
891 
892  if( nArgc == 0 )
893  {
894  continue;
895  }
896 
897  for(pCmd=I2CCmds, bDidCmd=0; pCmd->m_sCmd!=NULL && !bDidCmd; pCmd++)
898  {
899  if( !strncmp(sArgv[0], pCmd->m_sCmd, strlen(sArgv[0])) )
900  {
901  sArgv[0] = pCmd->m_sCmd;
902  rc = pCmd->m_fnExec(pI2C, nArgc, sArgv);
903  bDidCmd = 1;
904  if( rc == RC_QUIT )
905  {
906  bDoQuit = 1;
907  }
908  }
909  }
910 
911  if( !bDidCmd )
912  {
913  printf("Error: Unknown command: %s\n", sArgv[0]);
914  }
915 #ifdef HAVE_READLINE
916  free(sInput);
917 #endif // HAVE_READLINE
918  }
919 }
920 
921 /*!
922  * \brief i2csh main()
923  *
924  * \param argc Count of command-line options and arguments.
925  * \param argv Array of command-line options and arguments.
926  *
927  * \return Exit value.
928  */
929 int main(int argc, char *argv[])
930 {
931  i2c_t i2c;
932 
933  MainInit(argc, argv, &i2c);
934 
935  printf("I2C Raw Shell\n");
936  printf("-------------\n");
937  printf("(partial command matching valid; enter 'help' for help)\n\n");
938 
939  MainLoop(&i2c);
940 
941  return 0;
942 }
943 
944 /*!
945 \page i2csh I2CSH(1)
946 
947 \section NAME
948 i2csh - Simple I<sup>2</sup>C Bus command-line shell
949 
950 \section SYNOPSIS
951 i2csh [OPTIONS]
952 
953 \section DESCRIPTION
954 The I2C Shell (i2csh) provides a simple interactive interface to devices
955 attached to an I<sup>2</sup>C Bus.
956 
957 \section OPTIONS RNR_OPTIONS
958 \verbatim
959  -d, --device=<device> I2C device.
960  DEFAULT: /dev/i2c/0
961  -v, --verbose Set print verbosity.
962  DEFAULT: false
963  RNR_OPTIONS Standard set of options provided by librnr.
964 \endverbatim
965 
966 \section AUTHOR
967 Robin Knight (robin.knight@roadnarrows.com)
968 
969 \section COPYRIGHT
970 (C) 2007. RoadNarrows LLC.
971 (http://www.roadnarrows.com)
972 \n All Rights Reserved
973 */
int i2c_write(i2c_t *i2c, i2c_addr_t addr, const byte_t *buf, uint_t len)
Write to an I2C device.
Definition: i2ccom.c:159
static int execCheck(i2c_t *pI2C, int nArgc, const char *sArgv[])
Execute I2C slave device check.
Definition: i2csh.c:627
static OptsPgmInfo_T I2CShPgmInfo
Program Information.
Definition: i2csh.c:103
I2C python modules.
static const char ** makeargs(char *sLine, int *pArgc)
Make array of arguments separated with white-space.
Definition: i2csh.c:218
ushort_t i2c_addr_t
I2C Device Address Type.
Definition: i2c.h:72
void i2c_close(i2c_t *i2c)
Closes an I2C Bus.
Definition: i2ccom.c:137
static char * OptDevName
i2c bus device option
Definition: i2csh.c:98
I2C Bus Handle Type.
Definition: i2c.h:79
static char * readline(const char *prompt)
Read an input line from stdin.
Definition: i2csh.c:243
static int StrToByte(const char *s, byte_t *pByte)
Convert string to byte.
Definition: i2csh.c:191
int( execfunc_t)(i2c_t *, int, const char *[])
Command execution function type.
Definition: i2csh.c:81
int i2c_scan(i2c_t *i2c, int(*callback)(i2c_t *i2c, i2c_addr_t addr, void *context), void *context)
Scans the given I2C Bus to find all connected devices.
Definition: i2ccom.c:219
static int execWrite(i2c_t *pI2C, int nArgc, const char *sArgv[])
Execute I2C slave device write.
Definition: i2csh.c:386
static int execVerbose(i2c_t *pI2C, int nArgc, const char *sArgv[])
Execute enabling/disabling verbose printing.
Definition: i2csh.c:690
static int OptVerbose
verbose option
Definition: i2csh.c:97
const char * m_sHelpArgs
command help argments
Definition: i2csh.c:91
Shell Command Info.
Definition: i2csh.c:86
static OptsInfo_T I2CShOptsInfo[]
Command Line Options Information.
Definition: i2csh.c:114
static void MainLoop(i2c_t *pI2C)
Shell main loop.
Definition: i2csh.c:866
int i2c_transfer(i2c_t *i2c, i2c_addr_t addr, const byte_t *write_buf, uint_t write_len, byte_t *read_buf, uint_t read_len)
Perform a transfer with an I2C device.
Definition: i2ccom.c:171
static const PkgInfo_T PkgInfo
Definition: version.h:45
static void MainInit(int argc, char *argv[], i2c_t *pI2C)
Command initialization.
Definition: i2csh.c:832
static int execRead(i2c_t *pI2C, int nArgc, const char *sArgv[])
Execute I2C slave device read.
Definition: i2csh.c:297
const char * m_sCmd
input-line full command name
Definition: i2csh.c:88
execfunc_t * m_fnExec
assoc. exec. function
Definition: i2csh.c:89
Package version information.
static int execTransaction(i2c_t *pI2C, int nArgc, const char *sArgv[])
Execute I2C slave device write/read transaction.
Definition: i2csh.c:469
static int execQuit(i2c_t *pI2C, int nArgc, const char *sArgv[])
Execute quit shell.
Definition: i2csh.c:756
int i2c_open(i2c_t *i2c, const char *device)
Open the host I2C Bus device.
Definition: i2ccom.c:118
int main(int argc, char *argv[])
i2csh main()
Definition: i2csh.c:929
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
static int execScan(i2c_t *pI2C, int nArgc, const char *sArgv[])
Execute I2C slave device scan.
Definition: i2csh.c:587
static shcmd_t I2CCmds[]
forward declaration of shell commands
Definition: i2csh.c:719
#define RC_QUIT
quit shell return code
Definition: i2csh.c:72
static int StrToUnsigned(const char *s, uint_t *pVal)
Convert string to unsigned integer.
Definition: i2csh.c:156
const char * m_sHelpBrief
command help
Definition: i2csh.c:90
int i2c_exists(i2c_t *i2c, i2c_addr_t addr)
Test the existance of a device at the given address on the given I2C Bus.
Definition: i2ccom.c:199
static int scanCallback(i2c_t *pI2C, i2c_addr_t addr, void *context)
Found scanned device callback.
Definition: i2csh.c:570
static char * Argv0
command name
Definition: i2csh.c:95
Low-level I2C communication level.
static int execHelp(i2c_t *pI2C, int nArgc, const char *sArgv[])
Execute shell help.
Definition: i2csh.c:730