root/i2c-tools/trunk/eepromer/eeprog.c

Revision 5122, 7.2 kB (checked in by khali, 10 months ago)

According to Tobias Klauser:
"The placement of a storage-class specifier other than at the
beginning of the declaration specifiers in a declaration is an
obsolescent feature."

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 /***************************************************************************
2     copyright            : (C) by 2002-2003 Stefano Barbato
3     email                : stefano@codesink.org
4
5     $Id$
6  ***************************************************************************/
7
8 /***************************************************************************
9  *                                                                         *
10  *   This program is free software; you can redistribute it and/or modify  *
11  *   it under the terms of the GNU General Public License as published by  *
12  *   the Free Software Foundation; either version 2 of the License, or     *
13  *   (at your option) any later version.                                   *
14  *                                                                         *
15  ***************************************************************************/
16 #include <stdio.h>
17 #include <fcntl.h>
18 #include <getopt.h>
19 #include <unistd.h>
20 #include <stdlib.h>
21 #include <errno.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include <sys/stat.h>
25 #include "24cXX.h"
26
27 #define VERSION         "0.7.5"
28
29 #define ENV_DEV         "EEPROG_DEV"
30 #define ENV_I2C_ADDR    "EEPROG_I2C_ADDR"
31
32 int g_quiet;
33
34 #define usage_if(a) do { do_usage_if( a , __LINE__); } while(0);
35 void do_usage_if(int b, int line)
36 {
37         static const char *eeprog_usage =
38 "eeprog " VERSION ", a 24Cxx EEPROM reader/writer\n"
39 "Copyright (c) 2003 by Stefano Barbato - All rights reserved.\n"
40 "Usage: eeprog [-fqxdh] [-16|-8] [ -r addr[:count] | -w addr ] /dev/i2c-N i2c-address\n" 
41 "\n"
42 "  Address modes:\n"
43 "       -8              Use 8bit address mode for 24c0x...24C16 [default]\n"
44 "       -16             Use 16bit address mode for 24c32...24C256\n"
45 "  Actions:\n"
46 " -r addr[:count] Read [count] (1 if omitted) bytes from [addr]\n" 
47 " and print them to the standard output\n" 
48 "       -w addr         Write input (stdin) at address [addr] of the EEPROM\n"
49 "       -h              Print this help\n"
50 "  Options:\n"
51 " -x Set hex output mode\n" 
52 " -d Dummy mode, display what *would* have been done\n" 
53 "       -f              Disable warnings and don't ask confirmation\n"
54 "       -q              Quiet mode\n"
55 "\n"
56 "The following environment variables could be set instead of the command\n"
57 "line arguments:\n"
58 "       EEPROG_DEV              device name(/dev/i2c-N)\n"
59 "       EEPROG_I2C_ADDR         i2c-address\n"
60 "\n"
61 "       Examples\n"
62 "       1- read 64 bytes from the EEPROM at address 0x54 on bus 0 starting\n"
63 "          at address 123 (decimal)\n"
64 "               eeprog /dev/i2c-0 0x54 -r 123:64\n"
65 "       2- prints the hex codes of the first 32 bytes read from bus 1\n"
66 "          at address 0x22\n"
67 "               eeprog /dev/i2c-1 0x51 -x -r 0x22:0x20\n"
68 "       3- write the current timestamp at address 0x200 of the EEPROM on\n"
69 "          bus 0 at address 0x33\n"
70 "               date | eeprog /dev/i2c-0 0x33 -w 0x200\n";
71
72         if(!b)
73                 return;
74         fprintf(stderr, "%s\n[line %d]\n", eeprog_usage, line);
75         exit(1);
76 }
77
78
79 #define die_if(a, msg) do { do_die_if( a , msg, __LINE__); } while(0);
80 void do_die_if(int b, char* msg, int line)
81 {
82         if(!b)
83                 return;
84         fprintf(stderr, "Error at line %d: %s\n", line, msg);
85         //fprintf(stderr, "     sysmsg: %s\n", strerror(errno));
86         exit(1);
87 }
88
89 #define print_info(args...) do { if(!g_quiet) fprintf(stderr, args); } while(0);
90
91 void parse_arg(char *arg, int* paddr, int *psize)
92 {
93         char *end;
94         *paddr = strtoul(arg, &end, 0);
95         if(*end == ':')
96                 *psize = strtoul(++end, 0, 0);
97 }
98
99 int confirm_action()
100 {
101         fprintf(stderr,
102         "\n"
103         "____________________________WARNING____________________________\n"
104         "Erroneously writing to a system EEPROM (like DIMM SPD modules)\n"
105         "can break your system.  It will NOT boot anymore so you'll not\n"
106         "be able to fix it.\n"
107         "\n"
108         "Reading from 8bit EEPROMs (like that in your DIMM) without using\n"
109         "the -8 switch can also UNEXPECTEDLY write to them, so be sure to\n"
110         "use the -8 command param when required.\n"
111         "\n"
112         "Use -f to disable this warning message\n"
113         "\n"
114         "Press ENTER to continue or hit CTRL-C to exit\n"
115         "\n"
116         );
117         getchar();
118         return 1;
119 }
120
121
122 int read_from_eeprom(struct eeprom *e, int addr, int size, int hex)
123 {
124
125         int ch, i;
126         // hex print out
127         die_if((ch = eeprom_read_byte(e, addr)) < 0, "read error");
128         i = 1;
129         if(hex)
130                 printf("\n %.4x|  %.2x ", addr, ch);
131         else
132                 putchar(ch);
133         while(--size)
134         {
135                 die_if((ch = eeprom_read_current_byte(e)) < 0, "read error");
136                 if(hex)
137                 {
138                         addr++;
139                         if( (i % 16) == 0 )
140                                 printf("\n %.4x|  ", addr);
141                         else if( (i % 8) == 0 )
142                                 printf("  ");
143                         i++;
144                         printf("%.2x ", ch);
145                 } else {
146                         putchar(ch);
147                 }
148         }
149         if(hex)
150                 printf("\n\n");
151         fflush(stdout);
152         return 0;
153 }
154
155 int write_to_eeprom(struct eeprom *e, int addr)
156 {
157         int c;
158         while((c = getchar()) != EOF)
159         {
160                 print_info(".");
161                 fflush(stdout);
162                 die_if(eeprom_write_byte(e, addr++, c), "write error");
163         }
164         print_info("\n\n");
165         return 0;
166 }
167
168 int main(int argc, char** argv)
169 {
170         struct eeprom e;
171         int ret, op, i2c_addr, memaddr, size, want_hex, dummy, force, sixteen;
172         char *device, *arg = 0, *i2c_addr_s;
173         struct stat st;
174         int eeprom_type = 0;
175
176         op = want_hex = dummy = force = sixteen = 0;
177         g_quiet = 0;
178
179         while((ret = getopt(argc, argv, "1:8fr:qhw:xd")) != -1)
180         {
181                 switch(ret)
182                 {
183                 case '1':
184                         usage_if(*optarg != '6' || strlen(optarg) != 1);
185                         die_if(eeprom_type, "EEPROM type switch (-8 or -16) used twice");
186                         eeprom_type = EEPROM_TYPE_16BIT_ADDR;   
187                         break;
188                 case 'x':
189                         want_hex++;
190                         break;
191                 case 'd':
192                         dummy++;
193                         break;
194                 case '8':
195                         die_if(eeprom_type, "EEPROM type switch (-8 or -16) used twice");
196                         eeprom_type = EEPROM_TYPE_8BIT_ADDR;
197                         break;
198                 case 'f':
199                         force++;
200                         break;
201                 case 'q':
202                         g_quiet++;
203                         break;
204                 case 'h':
205                         usage_if(1);
206                         break;
207                 default:
208                         die_if(op != 0, "Both read and write requested");
209                         arg = optarg;
210                         op = ret;
211                 }
212         }
213         if(!eeprom_type)
214                 eeprom_type = EEPROM_TYPE_8BIT_ADDR; // default
215
216         usage_if(op == 0); // no switches
217         // set device and i2c_addr reading from cmdline or env
218         device = i2c_addr_s = 0;
219         switch(argc - optind)
220         {
221         case 0:
222                 device = getenv(ENV_DEV);
223                 i2c_addr_s = getenv(ENV_I2C_ADDR);
224                 break;
225         case 1:
226                 if(stat(argv[optind], &st) != -1)
227                 {
228                         device = argv[optind];
229                         i2c_addr_s = getenv(ENV_I2C_ADDR);
230                 } else {
231                         device = getenv(ENV_DEV);
232                         i2c_addr_s = argv[optind];
233                 }
234                 break;
235         case 2:
236                 device = argv[optind++];
237                 i2c_addr_s = argv[optind];
238                 break;
239         default:
240                 usage_if(1);
241         }
242         usage_if(!device || !i2c_addr_s);
243         i2c_addr = strtoul(i2c_addr_s, 0, 0);
244
245         print_info("eeprog %s, a 24Cxx EEPROM reader/writer\n", VERSION);
246         print_info("Copyright (c) 2003 by Stefano Barbato - All rights reserved.\n");
247         print_info("  Bus: %s, Address: 0x%x, Mode: %dbit\n",
248                         device, i2c_addr,
249                         (eeprom_type == EEPROM_TYPE_8BIT_ADDR ? 8 : 16) );
250         if(dummy)
251         {
252                 fprintf(stderr, "Dummy mode selected, nothing done.\n");
253                 return 0;
254         }
255         die_if(eeprom_open(device, i2c_addr, eeprom_type, &e) < 0,
256                         "unable to open eeprom device file (check that the file exists and that it's readable)");
257         switch(op)
258         {
259         case 'r':
260                 if(force == 0)
261                         confirm_action();
262                 size = 1; // default
263                 parse_arg(arg, &memaddr, &size);
264                 print_info("  Reading %d bytes from 0x%x\n", size, memaddr);
265                 read_from_eeprom(&e, memaddr, size, want_hex);
266                 break;
267         case 'w':
268                 if(force == 0)
269                         confirm_action();
270                 parse_arg(arg, &memaddr, &size);
271                 print_info("  Writing stdin starting at address 0x%x\n",
272                         memaddr);
273                 write_to_eeprom(&e, memaddr);
274                 break;
275         default:
276                 usage_if(1);
277                 exit(1);
278         }
279         eeprom_close(&e);
280
281         return 0;
282 }
283
Note: See TracBrowser for help on using the browser.