Clean up in error pathes
[libftdi] / examples / eeprom.c
1 /* LIBFTDI EEPROM access example
2
3    This program is distributed under the GPL, version 2
4 */
5
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <string.h>
9 #include <ctype.h>
10 #include <unistd.h>
11 #include <getopt.h>
12 #include <ftdi.h>
13
14 int main(int argc, char **argv)
15 {
16     struct ftdi_context *ftdi;
17     unsigned char buf[256];
18     int f, i, j;
19     int vid = 0x0403;
20     int pid = 0x6010;
21     char const *desc    = 0;
22     char const *serial  = 0;
23     int erase = 0;
24     int use_defaults = 0;
25     int large_chip = 0;
26     int do_write = 0;
27     int size;
28     int value;
29     int retval = 0;
30
31     if ((ftdi = ftdi_new()) == 0)
32     {
33         fprintf(stderr, "Failed to allocate ftdi structure :%s \n",
34                 ftdi_get_error_string(ftdi));
35         return EXIT_FAILURE;
36     }
37
38     while ((i = getopt(argc, argv, "d::ev:p:l:P:S:w")) != -1)
39     {
40         switch (i)
41         {
42             case 'd':
43                 use_defaults = 1;
44                 if (optarg)
45                     large_chip = 0x66;
46                 break;
47             case 'e':
48                 erase = 1;
49                 break;
50             case 'v':
51                 vid = strtoul(optarg, NULL, 0);
52                 break;
53             case 'p':
54                 pid = strtoul(optarg, NULL, 0);
55                 break;
56             case 'P':
57                 desc = optarg;
58                 break;
59             case 'S':
60                 serial = optarg;
61                 break;
62             case 'w':
63                 do_write  = 1;
64                 break;
65             default:
66                 fprintf(stderr, "usage: %s [options]\n", *argv);
67                 fprintf(stderr, "\t-d[num] Work with default valuesfor 128 Byte "
68                         "EEPROM or for 256 Byte EEPROM if some [num] is given\n");
69                 fprintf(stderr, "\t-w write\n");
70                 fprintf(stderr, "\t-e erase\n");
71                 fprintf(stderr, "\t-v verbose decoding\n");
72                 fprintf(stderr, "\t-p <number> Search for device with PID == number\n");
73                 fprintf(stderr, "\t-v <number> Search for device with VID == number\n");
74                 fprintf(stderr, "\t-P <string? Search for device with given "
75                         "product description\n");
76                 fprintf(stderr, "\t-S <string? Search for device with given "
77                         "serial number\n");
78                 retval = -1;
79                 goto done;
80         }
81     }
82
83     // Select first interface
84     ftdi_set_interface(ftdi, INTERFACE_ANY);
85
86     // Open device
87     f = ftdi_usb_open_desc(ftdi, vid, pid, desc, serial);
88     if (f < 0)
89     {
90         fprintf(stderr, "Device VID 0x%04x PID 0x%04x", vid, pid);
91         if (desc)
92             fprintf(stderr, " Desc %s", desc);
93         if (serial)
94             fprintf(stderr, " Serial %s", serial);
95         fprintf(stderr, "\n");
96         fprintf(stderr, "unable to open ftdi device: %d (%s)\n",
97                 f, ftdi_get_error_string(ftdi));
98
99         retval = -1;
100         goto done;
101     }
102
103     if (erase)
104     {
105         f = ftdi_erase_eeprom(ftdi); /* needed to determine EEPROM chip type */
106         if (f < 0)
107         {
108             fprintf(stderr, "Erase failed: %s",
109                     ftdi_get_error_string(ftdi));
110             retval =  -2;
111             goto done;
112         }
113         if (ftdi_get_eeprom_value(ftdi, CHIP_TYPE, & value) <0)
114         {
115             fprintf(stderr, "ftdi_get_eeprom_value: %d (%s)\n",
116                     f, ftdi_get_error_string(ftdi));
117         }
118         if (value == -1)
119             fprintf(stderr, "No EEPROM\n");
120         else if (value == 0)
121             fprintf(stderr, "Internal EEPROM\n");
122         else
123             fprintf(stderr, "Found 93x%02x\n", value);
124         retval = 0;
125         goto done;
126     }
127
128     if (use_defaults)
129     {
130         ftdi_eeprom_initdefaults(ftdi, NULL, NULL, NULL);
131         if (ftdi_set_eeprom_value(ftdi, MAX_POWER, 500) <0)
132         {
133             fprintf(stderr, "ftdi_set_eeprom_value: %d (%s)\n",
134                     f, ftdi_get_error_string(ftdi));
135         }
136         if (large_chip)
137             if (ftdi_set_eeprom_value(ftdi, CHIP_TYPE, 0x66) <0)
138             {
139                 fprintf(stderr, "ftdi_set_eeprom_value: %d (%s)\n",
140                         f, ftdi_get_error_string(ftdi));
141             }
142         f=(ftdi_eeprom_build(ftdi));
143         if (f < 0)
144         {
145             fprintf(stderr, "ftdi_eeprom_build: %d (%s)\n",
146                     f, ftdi_get_error_string(ftdi));
147             retval = -1;
148             goto done;
149         }
150     }
151     else if (do_write)
152     {
153         ftdi_eeprom_initdefaults(ftdi, NULL, NULL, NULL);
154         f = ftdi_erase_eeprom(ftdi);
155         if (ftdi_set_eeprom_value(ftdi, MAX_POWER, 500) <0)
156         {
157             fprintf(stderr, "ftdi_set_eeprom_value: %d (%s)\n",
158                     f, ftdi_get_error_string(ftdi));
159         }
160         f = ftdi_erase_eeprom(ftdi);/* needed to determine EEPROM chip type */
161         if (ftdi_get_eeprom_value(ftdi, CHIP_TYPE, & value) <0)
162         {
163             fprintf(stderr, "ftdi_get_eeprom_value: %d (%s)\n",
164                     f, ftdi_get_error_string(ftdi));
165         }
166         if (value == -1)
167             fprintf(stderr, "No EEPROM\n");
168         else if (value == 0)
169             fprintf(stderr, "Internal EEPROM\n");
170         else
171             fprintf(stderr, "Found 93x%02x\n", value);
172         f=(ftdi_eeprom_build(ftdi));
173         if (f < 0)
174         {
175             fprintf(stderr, "Erase failed: %s",
176                     ftdi_get_error_string(ftdi));
177             retval = -2;
178             goto done;
179         }
180         f = ftdi_write_eeprom(ftdi);
181         {
182             fprintf(stderr, "ftdi_eeprom_decode: %d (%s)\n",
183                     f, ftdi_get_error_string(ftdi));
184             retval = 1;
185             goto done;
186         }
187     }
188     f = ftdi_read_eeprom(ftdi);
189     if (f < 0)
190     {
191         fprintf(stderr, "ftdi_read_eeprom: %d (%s)\n",
192                 f, ftdi_get_error_string(ftdi));
193         retval = -1;
194         goto done;
195     }
196
197
198     ftdi_get_eeprom_value(ftdi, CHIP_SIZE, & value);
199     if (value <0)
200     {
201         fprintf(stderr, "No EEPROM found\n");
202         retval = -1;
203         goto done;
204
205     }
206     fprintf(stderr, "Chip type %d ftdi_eeprom_size: %d\n", ftdi->type, value);
207     if (ftdi->type == TYPE_R)
208         size = 0xa0;
209     else
210         size = value;
211     ftdi_get_eeprom_buf(ftdi, buf, size);
212     for (i=0; i < size; i += 16)
213     {
214         fprintf(stdout,"0x%03x:", i);
215
216         for (j = 0; j< 8; j++)
217             fprintf(stdout," %02x", buf[i+j]);
218         fprintf(stdout," ");
219         for (; j< 16; j++)
220             fprintf(stdout," %02x", buf[i+j]);
221         fprintf(stdout," ");
222         for (j = 0; j< 8; j++)
223             fprintf(stdout,"%c", isprint(buf[i+j])?buf[i+j]:'.');
224         fprintf(stdout," ");
225         for (; j< 16; j++)
226             fprintf(stdout,"%c", isprint(buf[i+j])?buf[i+j]:'.');
227         fprintf(stdout,"\n");
228     }
229
230     f = ftdi_eeprom_decode(ftdi, 1);
231     if (f < 0)
232     {
233         fprintf(stderr, "ftdi_eeprom_decode: %d (%s)\n",
234                 f, ftdi_get_error_string(ftdi));
235         retval = -1;
236     }
237
238 done:
239     ftdi_usb_close(ftdi);
240     ftdi_free(ftdi);
241     return retval;
242 }