cornucopia: bump SRCREV
[openembedded.git] / recipes / i2c / files / i2c.c
blob9f0bafdba1042b4160ae5d3ec54271abb2a9ab0d
1 /****************************************************************************
3 * Copyright (c) 2006 Dave Hylands <dhylands@gmail.com>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
10 * license.
12 * See README and COPYING for more details.
14 ****************************************************************************/
15 /**
17 * @file i2c.c
19 * @brief This program allows basic i2c commands to be sent out the i2c
20 * bus,
22 ****************************************************************************/
24 // ---- Include Files -------------------------------------------------------
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <getopt.h>
29 #include <fcntl.h>
30 #include <errno.h>
31 #include <string.h>
32 #include <signal.h>
33 #include <unistd.h>
34 #include <sys/timeb.h>
36 #include "i2c-dev.h"
37 #include "i2c-api.h"
38 #include "i2c-io-api.h"
39 #include "Log.h"
41 // #include "svn-version.h"
43 // ---- Public Variables ----------------------------------------------------
44 // ---- Private Constants and Types -----------------------------------------
46 // ---- Private Variables ---------------------------------------------------
48 enum
50 OPT_MEM_DEFAULT = 0,
52 // Options assigned a single character code can use that charater code
53 // as a short option.
55 OPT_COUNT = 'c',
57 // Options from this point onwards don't have any short option equivalents
59 OPT_FIRST_LONG_OPT = 0x80,
61 OPT_HELP,
62 OPT_VERSION,
65 enum
67 CMD_DEFAULT,
69 CMD_READ_BYTE,
70 CMD_READ_BYTE_2,
71 CMD_READ_BYTE_4,
73 CMD_WRITE_BYTE,
74 CMD_WRITE_BYTE_2,
75 CMD_WRITE_BYTE_4,
77 CMD_RECV_BYTE,
78 CMD_RECV_BYTE_2,
79 CMD_RECV_BYTE_4,
81 CMD_SEND_BYTE,
82 CMD_SEND_BYTE_2,
83 CMD_SEND_BYTE_4,
86 struct
88 int cmd;
89 const char *cmdStr;
91 } gCmdMap[] =
93 { CMD_READ_BYTE, "ReadByte" },
94 { CMD_READ_BYTE, "rb" },
95 { CMD_READ_BYTE_2, "ReadByte2" },
96 { CMD_READ_BYTE_2, "rb2" },
97 { CMD_READ_BYTE_4, "ReadByte4" },
98 { CMD_READ_BYTE_4, "rb4" },
100 { CMD_WRITE_BYTE, "WriteByte" },
101 { CMD_WRITE_BYTE, "wb" },
102 { CMD_WRITE_BYTE_2, "WriteByte2" },
103 { CMD_WRITE_BYTE_2, "wb2" },
104 { CMD_WRITE_BYTE_4, "WriteByte4" },
105 { CMD_WRITE_BYTE_4, "wb4" },
107 { CMD_RECV_BYTE, "RecvByte" },
108 { CMD_RECV_BYTE, "vb" },
109 { CMD_RECV_BYTE_2, "RecvByte2" },
110 { CMD_RECV_BYTE_2, "vb2" },
111 { CMD_RECV_BYTE_4, "RecvByte4" },
112 { CMD_RECV_BYTE_4, "vb4" },
114 { CMD_SEND_BYTE, "SendByte" },
115 { CMD_SEND_BYTE, "sb" },
116 { CMD_SEND_BYTE_2, "SendByte2" },
117 { CMD_SEND_BYTE_2, "sb2" },
118 { CMD_SEND_BYTE_4, "SendByte4" },
119 { CMD_SEND_BYTE_4, "sb4" },
122 int gNumCmds = sizeof( gCmdMap ) / sizeof( gCmdMap[ 0 ]);
124 int gI2cAddr = -1;
125 int gByteCount = 1;
127 const char *gCmdStr;
128 int gCmd = CMD_DEFAULT;
129 const char *gAddrStr = NULL;
130 const char *gDataStr = NULL;
132 struct option gOption[] =
134 { "count", required_argument, NULL, OPT_COUNT },
135 { "version", no_argument, NULL, OPT_VERSION },
136 { "verbose", no_argument, &gVerbose, 1 },
137 { "debug", no_argument, &gDebug, 1 },
138 { "help", no_argument, NULL, OPT_HELP },
139 { NULL }
142 #define TRUE 1
143 #define FALSE 0
145 typedef enum
147 NoADC,
148 AllowADC,
150 } AllowADC_t;
152 #define ADC_PORT 8
154 // ---- Private Function Prototypes -----------------------------------------
156 static int ParseByte( const char *byteStr, uint8_t *byte );
157 static int ParseBytes( const char *byteStr, uint8_t *byte, uint8_t maxBytes, uint8_t *bytesParsed );
159 static void ProcessReadByteCommand( int i2cDev, const char *addrStr );
160 static void ProcessWriteByteCommand( int i2cDev, const char *addrStr, const char *dataStr );
161 static void ProcessRecvByteCommand( int i2cDev );
162 static void ProcessSendByteCommand( int i2cDev, const char *dataStr );
163 static void Usage( void );
165 // ---- Functions -----------------------------------------------------------
167 //***************************************************************************
169 * Main entry point
172 int main( int argc, char **argv )
174 char shortOptsStr[ sizeof( gOption ) / sizeof( gOption[ 0 ] ) + 1 ];
175 char *shortOpts = shortOptsStr;
176 struct option *scanOpt;
177 int opt;
178 const char *i2cDevName = "/dev/i2c-0";
179 int i2cDev;
180 int cmdIdx;
182 LogInit( stdout );
184 // Figure out the short options from our options structure
186 for ( scanOpt = gOption; scanOpt->name != NULL; scanOpt++ )
188 if (( scanOpt->flag == NULL ) && ( scanOpt->val < OPT_FIRST_LONG_OPT ))
190 *shortOpts++ = (char)scanOpt->val;
192 if ( scanOpt->has_arg != no_argument )
194 *shortOpts++ = ':';
198 *shortOpts++ = '\0';
200 // Parse the command line options
202 while (( opt = getopt_long( argc, argv, shortOptsStr, gOption, NULL )) != -1 )
204 switch ( opt )
206 case 0:
208 // getopt_long returns 0 for entries where flag is non-NULL
210 break;
213 case OPT_COUNT:
215 gByteCount = (int)strtol( optarg, NULL, 0 );
216 if ( gByteCount <= 0 )
218 LogError( "Expecting byte count >= 0, found: '%s'\n", optarg );
219 Usage();
220 exit( 1 );
222 if ( gByteCount > I2C_MAX_DATA_LEN )
224 LogError( "Max byte count supported: %d, found %d\n", I2C_MAX_DATA_LEN, gByteCount );
225 Usage();
226 exit( 1 );
228 break;
231 // case OPT_VERSION:
232 // {
233 // Log( "i2c SVN Revision: %d\n", SVN_REVISION );
234 // exit( 0 );
235 // break;
236 // }
238 case '?':
239 case OPT_HELP:
240 default:
242 LogError( "opt:%d\n", opt );
243 Usage();
244 exit( 1 );
248 argc -= optind;
249 argv += optind;
251 // Verify that an i2c-address was specified
253 if ( argc < 1 )
255 LogError( "Must specify an i2c address\n\n" );
256 Usage();
257 exit( 1 );
259 gI2cAddr = strtol( argv[ 0 ], NULL, 0 );
260 if (( gI2cAddr <= 0 ) || ( gI2cAddr > 127 ))
262 LogError( "Expecting i2c address in the range of 1-127, Found: %d\n", gI2cAddr );
263 Usage();
264 exit( 1 );
267 // Verify that a command has been specified
269 if ( argc < 2 )
271 LogError( "Must specify a command\n" );
272 Usage();
273 exit( 1 );
275 gCmdStr = argv[ 1 ];
276 for ( cmdIdx = 0; cmdIdx < gNumCmds; cmdIdx++ )
278 if ( strcasecmp( gCmdStr, gCmdMap[ cmdIdx ].cmdStr ) == 0 )
280 gCmd = gCmdMap[ cmdIdx ].cmd;
281 break;
284 if ( gCmd == CMD_DEFAULT )
286 LogError( "Unrecognized command '%s'\n", gCmdStr );
287 exit( 1 );
290 // Process command specific arguments
292 if (( gCmd == CMD_READ_BYTE_2 )
293 || ( gCmd == CMD_WRITE_BYTE_2 )
294 || ( gCmd == CMD_RECV_BYTE_2 )
295 || ( gCmd == CMD_SEND_BYTE_2 ))
297 gByteCount = 2;
299 else
300 if (( gCmd == CMD_READ_BYTE_4 )
301 || ( gCmd == CMD_WRITE_BYTE_4 )
302 || ( gCmd == CMD_RECV_BYTE_4 )
303 || ( gCmd == CMD_SEND_BYTE_4 ))
305 gByteCount = 4;
308 if (( gCmd == CMD_READ_BYTE )
309 || ( gCmd == CMD_READ_BYTE_2 )
310 || ( gCmd == CMD_READ_BYTE_4 ))
312 if ( argc < 3 )
314 LogError( "Expecting address\n" );
315 Usage();
316 exit( 1 );
318 if ( argc > 3 )
320 LogError( "Unexpected extra parameters\n" );
321 Usage();
322 exit( 1 );
325 gAddrStr = argv[ 2 ];
327 else
328 if (( gCmd == CMD_WRITE_BYTE )
329 || ( gCmd == CMD_WRITE_BYTE_2 )
330 || ( gCmd == CMD_WRITE_BYTE_4 ))
332 if ( argc < 4 )
334 LogError( "Expecting address and data\n" );
335 Usage();
336 exit( 1 );
338 if ( argc > 4 )
340 LogError( "Unexpected extra parameters\n" );
341 Usage();
342 exit( 1 );
345 gAddrStr = argv[ 2 ];
346 gDataStr = argv[ 3 ];
348 else
349 if (( gCmd == CMD_RECV_BYTE )
350 || ( gCmd == CMD_RECV_BYTE_2 )
351 || ( gCmd == CMD_RECV_BYTE_4 ))
353 if ( argc > 2 )
355 LogError( "Unexpected extra parameters\n" );
356 Usage();
357 exit( 1 );
360 else
361 if (( gCmd == CMD_SEND_BYTE )
362 || ( gCmd == CMD_SEND_BYTE_2 )
363 || ( gCmd == CMD_SEND_BYTE_4 ))
365 if ( argc < 3 )
367 LogError( "Expecting data\n" );
368 Usage();
369 exit( 1 );
371 if ( argc > 3 )
373 LogError( "Unexpected extra parameters\n" );
374 Usage();
375 exit( 1 );
377 gDataStr = argv[ 2 ];
380 if ( gDebug )
382 Log( "i2cAddr:0x%02x Cmd: %s (%d)", gI2cAddr, gCmdStr, gCmd );
383 if ( gAddrStr != NULL )
385 Log( " Addr: %s", gAddrStr );
387 if ( gDataStr != NULL )
389 Log( " Data: %s", gDataStr );
391 Log( "\n" );
394 // Try to open the i2c device
396 if (( i2cDev = open( i2cDevName, O_RDWR )) < 0 )
398 LogError( "Error opening '%s': %s\n", i2cDevName, strerror( errno ));
399 exit( 1 );
402 // Indicate which slave we wish to speak to
404 I2cSetSlaveAddress( i2cDev, gI2cAddr, I2C_NO_CRC );
406 switch ( gCmd )
408 case CMD_READ_BYTE:
409 case CMD_READ_BYTE_2:
410 case CMD_READ_BYTE_4:
412 ProcessReadByteCommand( i2cDev, gAddrStr );
413 break;
416 case CMD_WRITE_BYTE:
417 case CMD_WRITE_BYTE_2:
418 case CMD_WRITE_BYTE_4:
420 ProcessWriteByteCommand( i2cDev, gAddrStr, gDataStr );
421 break;
424 case CMD_RECV_BYTE:
425 case CMD_RECV_BYTE_2:
426 case CMD_RECV_BYTE_4:
428 ProcessRecvByteCommand( i2cDev );
429 break;
432 case CMD_SEND_BYTE:
433 case CMD_SEND_BYTE_2:
434 case CMD_SEND_BYTE_4:
436 ProcessSendByteCommand( i2cDev, gDataStr );
437 break;
441 close( i2cDev );
443 return 0;
445 } // main
447 //***************************************************************************
449 * Parse a string looking for a single byte.
452 int ParseByte( const char *byteStr, uint8_t *byte )
454 char *endPtr;
456 *byte = (uint8_t)strtol( byteStr, &endPtr, 0 );
458 if ( *endPtr != '\0' )
460 LogError( "Expecting numeric value, found '%s'\n", byteStr );
461 return FALSE;
464 return TRUE;
466 } // ParseByte
468 //***************************************************************************
470 * Parse a string looking for an array of bytes.
473 int ParseBytes( const char *byteStr, uint8_t *byte, uint8_t maxBytes, uint8_t *bytesParsed )
475 char *endPtr;
477 if (( byteStr[ 0 ] == '0' ) && ( byteStr[ 1 ] == 'x' ))
479 const char *s = &byteStr[ 2 ];
480 *bytesParsed = 0;
482 // Could be a multi-byte hex string
484 while ( *s != '\0' )
486 if ( *bytesParsed >= maxBytes )
488 LogError( "Too many bytes, max: %d\n", maxBytes );
489 return FALSE;
492 (*bytesParsed)++;
493 *byte = 0;
495 if (( *s >= 'A' ) && ( *s <= 'F' ))
497 *byte = *s - 'A' + 10;
499 else
500 if (( *s >= 'a' ) && ( *s <= 'f' ))
502 *byte = *s - 'a' + 10;
504 else
505 if (( *s >= '0' ) && ( *s <= '9' ))
507 *byte = *s - '0';
509 else
511 LogError( "Expecting hex digit, found '%c'\n", *s );
512 return FALSE;
514 s++;
516 if ( *s == '\0' )
518 break;
521 *byte <<= 4;
522 if (( *s >= 'A' ) && ( *s <= 'F' ))
524 *byte |= *s - 'A' + 10;
526 else
527 if (( *s >= 'a' ) && ( *s <= 'f' ))
529 *byte |= *s - 'a' + 10;
531 else
532 if (( *s >= '0' ) && ( *s <= '9' ))
534 *byte |= *s - '0';
536 else
538 LogError( "Expecting hex digit, found '%c'\n", *s );
539 return FALSE;
541 s++;
542 byte++;
545 else
547 // It's decimal or octal - only a single byte
549 *byte = (uint8_t)strtol( byteStr, &endPtr, 0 );
551 if ( *endPtr != '\0' )
553 LogError( "Expecting numeric value, found '%s'\n", byteStr );
554 return FALSE;
556 *bytesParsed = 1;
559 return TRUE;
561 } // ParseBytes
563 //***************************************************************************
565 * Issues a read byte command to read a byte from a particular address.
568 void ProcessReadByteCommand( int i2cDev, const char *addrStr )
570 uint8_t addr;
571 uint8_t dataByte[ I2C_MAX_DATA_LEN ];
572 int rc;
573 int i;
575 if ( !ParseByte( addrStr, &addr ))
577 return;
580 if (( rc = I2cReadBytes( i2cDev, addr, dataByte, gByteCount )) != 0 )
582 LogError( "I2cReadByte failed: %d\n", rc );
583 return;
586 Log( "0x", dataByte[0] );
588 for ( i = 0; i < gByteCount; i++ )
590 Log( "%02x", dataByte[i] );
592 Log( "\n" );
594 } // ProcessReadByteCommand
596 //***************************************************************************
598 * Issues a recv byte command to read bytes with no address.
601 void ProcessRecvByteCommand( int i2cDev )
603 uint8_t dataByte[ I2C_MAX_DATA_LEN ];
604 int rc;
605 int i;
607 if (( rc = I2cReceiveBytes( i2cDev, dataByte, gByteCount )) != 0 )
609 LogError( "I2cRecvBytes failed: %d\n", rc );
610 return;
613 Log( "0x", dataByte[0] );
615 for ( i = 0; i < gByteCount; i++ )
617 Log( "%02x", dataByte[i] );
619 Log( "\n" );
621 } // ProcessRecvByteCommand
623 //***************************************************************************
625 * Issues a write byte command to write a byte to a particular address.
628 void ProcessWriteByteCommand( int i2cDev, const char *addrStr, const char *dataStr )
630 uint8_t addr;
631 uint8_t dataByte[ I2C_MAX_DATA_LEN ];
632 uint8_t bytesParsed;
633 int rc;
635 if ( !ParseByte( addrStr, &addr ))
637 return;
640 if ( !ParseBytes( dataStr, dataByte, sizeof( dataByte ), &bytesParsed ))
642 return;
645 if (( rc = I2cWriteBytes( i2cDev, addr, dataByte, bytesParsed )) != 0 )
647 LogError( "I2cWriteBytes failed: %d\n", rc );
648 return;
651 } // ProcessWriteByteCommand
653 //***************************************************************************
655 * Issues a send byte command to write bytes with no address specified.
658 void ProcessSendByteCommand( int i2cDev, const char *dataStr )
660 uint8_t dataByte[ I2C_MAX_DATA_LEN ];
661 uint8_t bytesParsed;
662 int rc;
664 if ( !ParseBytes( dataStr, dataByte, sizeof( dataByte ), &bytesParsed ))
666 return;
669 if (( rc = I2cSendBytes( i2cDev, dataByte, bytesParsed )) != 0 )
671 LogError( "I2cSendBytes failed: %d\n", rc );
672 return;
675 } // ProcessSendByteCommand
677 //***************************************************************************
679 * Usage
682 void Usage( void )
684 fprintf( stderr, "Usage: i2c [options] i2c-addr cmd [cmd-arguments]\n" );
685 fprintf( stderr, "Send I2C commands\n" );
686 fprintf( stderr, "\n" );
687 fprintf( stderr, "The following commands are supported:\n" );
688 fprintf( stderr, "ReadByte addr Retrieves byte(s) starting at the indicated address\n" );
689 fprintf( stderr, "WriteByte addr data Write byte(s) starting at the indicated address\n" );
690 fprintf( stderr, "ReadByte2 addr Retrieves two bytes from the indicated address\n" );
691 fprintf( stderr, "WriteByte2 addr data Writes two bytes into the indicated address\n" );
692 fprintf( stderr, "ReadByte4 addr Retrieves four bytes from the indicated address\n" );
693 fprintf( stderr, "WriteByte4 addr data Writes four bytes into the indicated address\n" );
694 fprintf( stderr, "RecvByte Retrieves byte(s)(no address specified)\n" );
695 fprintf( stderr, "SendByte data Writes byte(s)(no address specified)\n" );
696 fprintf( stderr, "RecvByte2 Retrieves 2 bytes (no address specified)\n" );
697 fprintf( stderr, "SendByte2 data Writes 2 bytes(no address specified)\n" );
698 fprintf( stderr, "RecvByte4 Retrieves 4 bytes (no address specified)\n" );
699 fprintf( stderr, "SendByte4 data Writes 4 bytes(no address specified)\n" );
700 fprintf( stderr, "\n" );
701 fprintf( stderr, "The above commands can be shortened to rb, wb, rb2, wb2, rb4, wb4, vb, sd, vb2 sb2 vb4, and sb4 \n" );
702 fprintf( stderr, "respectively.\n" );
703 fprintf( stderr, "\n" );
704 fprintf( stderr, "The following options may be used:\n" );
705 fprintf( stderr, "--count=n Specifies how many bytes to read for ReadByte or RecvByte\n" );
706 fprintf( stderr, "--version Prints the SVN version of this program\n" );
707 fprintf( stderr, "--verbose Print additional information\n" );
708 fprintf( stderr, "--help Prints this information\n" );