libftdi: (tomj) Improved error handling (Evgeny Sinelnikov)
[libftdi] / ftdi / ftdi.c
CommitLineData
a3da1d95
GE
1/***************************************************************************
2 ftdi.c - description
3 -------------------
4 begin : Fri Apr 4 2003
5 copyright : (C) 2003 by Intra2net AG
5fdb1cb1 6 email : opensource@intra2net.com
a3da1d95
GE
7 ***************************************************************************/
8
9/***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU Lesser General Public License *
13 * version 2.1 as published by the Free Software Foundation; *
14 * *
15 ***************************************************************************/
d9f0cce7 16
98452d97 17#include <usb.h>
0e302db6 18
98452d97 19#include "ftdi.h"
a3da1d95 20
948f9ada
TJ
21/* ftdi_init return codes:
22 0: all fine
6d9aa99f 23 -1: couldn't allocate read buffer
948f9ada 24*/
98452d97
TJ
25int ftdi_init(struct ftdi_context *ftdi) {
26 ftdi->usb_dev = NULL;
545820ce
TJ
27 ftdi->usb_read_timeout = 5000;
28 ftdi->usb_write_timeout = 5000;
a3da1d95 29
53ad271d 30 ftdi->type = TYPE_BM; /* chip type */
a3da1d95
GE
31 ftdi->baudrate = -1;
32 ftdi->bitbang_enabled = 0;
33
948f9ada
TJ
34 ftdi->readbuffer = NULL;
35 ftdi->readbuffer_offset = 0;
36 ftdi->readbuffer_remaining = 0;
37 ftdi->writebuffer_chunksize = 4096;
38
545820ce
TJ
39 ftdi->interface = 0;
40 ftdi->index = 0;
41 ftdi->in_ep = 0x02;
42 ftdi->out_ep = 0x81;
3119537f 43 ftdi->bitbang_mode = 1; /* 1: Normal bitbang mode, 2: SPI bitbang mode */
53ad271d 44
a3da1d95
GE
45 ftdi->error_str = NULL;
46
41b8ae57
TJ
47 /* All fine. Now allocate the readbuffer
48 Note: A readbuffer size above 64 bytes results in buggy input.
49 This seems to be a hardware limitation as noted
50 in the ftdi_sio driver */
51 return ftdi_read_data_set_chunksize(ftdi, 64);
948f9ada
TJ
52}
53
54
98452d97 55void ftdi_deinit(struct ftdi_context *ftdi) {
948f9ada 56 if (ftdi->readbuffer != NULL) {
d9f0cce7
TJ
57 free(ftdi->readbuffer);
58 ftdi->readbuffer = NULL;
948f9ada 59 }
a3da1d95
GE
60}
61
98452d97
TJ
62
63void ftdi_set_usbdev (struct ftdi_context *ftdi, usb_dev_handle *usb) {
64 ftdi->usb_dev = usb;
65}
66
67
a3da1d95
GE
68/* ftdi_usb_open return codes:
69 0: all fine
98452d97
TJ
70 -1: usb_find_busses() failed
71 -2: usb_find_devices() failed
72 -3: usb device not found
73 -4: unable to open device
74 -5: unable to claim device
75 -6: reset failed
76 -7: set baudrate failed
a3da1d95
GE
77*/
78int ftdi_usb_open(struct ftdi_context *ftdi, int vendor, int product) {
98452d97
TJ
79 struct usb_bus *bus;
80 struct usb_device *dev;
81
82 usb_init();
83
84 if (usb_find_busses() < 0) {
85 ftdi->error_str = "usb_find_busses() failed";
86 return -1;
87 }
88
89 if (usb_find_devices() < 0) {
90 ftdi->error_str = "usb_find_devices() failed";
a3da1d95
GE
91 return -2;
92 }
93
98452d97
TJ
94 for (bus = usb_busses; bus; bus = bus->next) {
95 for (dev = bus->devices; dev; dev = dev->next) {
96 if (dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product) {
97 ftdi->usb_dev = usb_open(dev);
98 if (ftdi->usb_dev) {
99 if (usb_claim_interface(ftdi->usb_dev, ftdi->interface) != 0) {
100 ftdi->error_str = "unable to claim usb device. Make sure ftdi_sio is unloaded!";
101 return -5;
102 }
103
104 if (ftdi_usb_reset (ftdi) != 0)
105 return -6;
106
107 if (ftdi_set_baudrate (ftdi, 9600) != 0)
108 return -7;
109
110 // Try to guess chip type
111 // Bug in the BM type chips: bcdDevice is 0x200 for serial == 0
112 if (dev->descriptor.bcdDevice == 0x400 || (dev->descriptor.bcdDevice == 0x200
113 && dev->descriptor.iSerialNumber == 0))
114 ftdi->type = TYPE_BM;
115 else if (dev->descriptor.bcdDevice == 0x200)
116 ftdi->type = TYPE_AM;
117 else if (dev->descriptor.bcdDevice == 0x500)
118 ftdi->type = TYPE_2232C;
119
120 return 0;
121 } else {
122 ftdi->error_str = "usb_open() failed";
123 return -4;
124 }
125 }
126 }
a3da1d95 127
98452d97 128 }
a3da1d95 129
98452d97
TJ
130 // device not found
131 return -3;
a3da1d95
GE
132}
133
134
135int ftdi_usb_reset(struct ftdi_context *ftdi) {
98452d97 136 if (usb_control_msg(ftdi->usb_dev, 0x40, 0, 0, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) {
a3da1d95
GE
137 ftdi->error_str = "FTDI reset failed";
138 return -1;
139 }
545820ce 140 // Invalidate data in the readbuffer
bfcee05b
TJ
141 ftdi->readbuffer_offset = 0;
142 ftdi->readbuffer_remaining = 0;
143
a3da1d95
GE
144 return 0;
145}
146
a60be878 147int ftdi_usb_purge_buffers(struct ftdi_context *ftdi) {
98452d97 148 if (usb_control_msg(ftdi->usb_dev, 0x40, 0, 1, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) {
a60be878
TJ
149 ftdi->error_str = "FTDI purge of RX buffer failed";
150 return -1;
151 }
545820ce 152 // Invalidate data in the readbuffer
bfcee05b
TJ
153 ftdi->readbuffer_offset = 0;
154 ftdi->readbuffer_remaining = 0;
a60be878 155
98452d97 156 if (usb_control_msg(ftdi->usb_dev, 0x40, 0, 2, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) {
a60be878
TJ
157 ftdi->error_str = "FTDI purge of TX buffer failed";
158 return -1;
159 }
160
545820ce 161
a60be878
TJ
162 return 0;
163}
a3da1d95
GE
164
165/* ftdi_usb_close return codes
166 0: all fine
98452d97
TJ
167 -1: usb_release failed
168 -2: usb_close failed
a3da1d95
GE
169*/
170int ftdi_usb_close(struct ftdi_context *ftdi) {
171 int rtn = 0;
172
98452d97 173 if (usb_release_interface(ftdi->usb_dev, ftdi->interface) != 0)
a3da1d95 174 rtn = -1;
98452d97
TJ
175
176 if (usb_close (ftdi->usb_dev) != 0)
a3da1d95 177 rtn = -2;
98452d97 178
a3da1d95
GE
179 return rtn;
180}
181
182
183/*
53ad271d
TJ
184 ftdi_convert_baudrate returns nearest supported baud rate to that requested.
185 Function is only used internally
186*/
0126d22e 187static int ftdi_convert_baudrate(int baudrate, struct ftdi_context *ftdi,
53ad271d
TJ
188 unsigned short *value, unsigned short *index) {
189 static const char am_adjust_up[8] = {0, 0, 0, 1, 0, 3, 2, 1};
190 static const char am_adjust_dn[8] = {0, 0, 0, 1, 0, 1, 2, 3};
191 static const char frac_code[8] = {0, 3, 2, 4, 1, 5, 6, 7};
192 int divisor, best_divisor, best_baud, best_baud_diff;
193 unsigned long encoded_divisor;
194 int i;
195
196 if (baudrate <= 0) {
197 // Return error
198 return -1;
199 }
200
201 divisor = 24000000 / baudrate;
202
0126d22e 203 if (ftdi->type == TYPE_AM) {
53ad271d
TJ
204 // Round down to supported fraction (AM only)
205 divisor -= am_adjust_dn[divisor & 7];
206 }
207
208 // Try this divisor and the one above it (because division rounds down)
209 best_divisor = 0;
210 best_baud = 0;
211 best_baud_diff = 0;
212 for (i = 0; i < 2; i++) {
213 int try_divisor = divisor + i;
214 int baud_estimate;
215 int baud_diff;
216
217 // Round up to supported divisor value
218 if (try_divisor < 8) {
219 // Round up to minimum supported divisor
220 try_divisor = 8;
0126d22e 221 } else if (ftdi->type != TYPE_AM && try_divisor < 12) {
53ad271d
TJ
222 // BM doesn't support divisors 9 through 11 inclusive
223 try_divisor = 12;
224 } else if (divisor < 16) {
225 // AM doesn't support divisors 9 through 15 inclusive
226 try_divisor = 16;
227 } else {
0126d22e 228 if (ftdi->type == TYPE_AM) {
53ad271d
TJ
229 // Round up to supported fraction (AM only)
230 try_divisor += am_adjust_up[try_divisor & 7];
231 if (try_divisor > 0x1FFF8) {
232 // Round down to maximum supported divisor value (for AM)
233 try_divisor = 0x1FFF8;
234 }
235 } else {
236 if (try_divisor > 0x1FFFF) {
237 // Round down to maximum supported divisor value (for BM)
238 try_divisor = 0x1FFFF;
239 }
240 }
241 }
242 // Get estimated baud rate (to nearest integer)
243 baud_estimate = (24000000 + (try_divisor / 2)) / try_divisor;
244 // Get absolute difference from requested baud rate
245 if (baud_estimate < baudrate) {
246 baud_diff = baudrate - baud_estimate;
247 } else {
248 baud_diff = baud_estimate - baudrate;
249 }
250 if (i == 0 || baud_diff < best_baud_diff) {
251 // Closest to requested baud rate so far
252 best_divisor = try_divisor;
253 best_baud = baud_estimate;
254 best_baud_diff = baud_diff;
255 if (baud_diff == 0) {
256 // Spot on! No point trying
257 break;
258 }
259 }
260 }
261 // Encode the best divisor value
262 encoded_divisor = (best_divisor >> 3) | (frac_code[best_divisor & 7] << 14);
263 // Deal with special cases for encoded value
264 if (encoded_divisor == 1) {
265 encoded_divisor = 0; // 3000000 baud
266 } else if (encoded_divisor == 0x4001) {
267 encoded_divisor = 1; // 2000000 baud (BM only)
268 }
269 // Split into "value" and "index" values
270 *value = (unsigned short)(encoded_divisor & 0xFFFF);
de22df10 271 if(ftdi->type == TYPE_2232C) {
0126d22e
TJ
272 *index = (unsigned short)(encoded_divisor >> 8);
273 *index &= 0xFF00;
274 *index |= ftdi->interface;
275 }
276 else
277 *index = (unsigned short)(encoded_divisor >> 16);
278
53ad271d
TJ
279 // Return the nearest baud rate
280 return best_baud;
281}
282
283/*
a3da1d95
GE
284 ftdi_set_baudrate return codes:
285 0: all fine
286 -1: invalid baudrate
287 -2: setting baudrate failed
288*/
289int ftdi_set_baudrate(struct ftdi_context *ftdi, int baudrate) {
53ad271d
TJ
290 unsigned short value, index;
291 int actual_baudrate;
a3da1d95
GE
292
293 if (ftdi->bitbang_enabled) {
294 baudrate = baudrate*4;
295 }
296
25707904 297 actual_baudrate = ftdi_convert_baudrate(baudrate, ftdi, &value, &index);
53ad271d
TJ
298 if (actual_baudrate <= 0) {
299 ftdi->error_str = "Silly baudrate <= 0.";
a3da1d95
GE
300 return -1;
301 }
302
53ad271d
TJ
303 // Check within tolerance (about 5%)
304 if ((actual_baudrate * 2 < baudrate /* Catch overflows */ )
305 || ((actual_baudrate < baudrate)
306 ? (actual_baudrate * 21 < baudrate * 20)
307 : (baudrate * 21 < actual_baudrate * 20))) {
308 ftdi->error_str = "Unsupported baudrate. Note: bitbang baudrates are automatically multiplied by 4";
309 return -1;
310 }
545820ce 311
98452d97 312 if (usb_control_msg(ftdi->usb_dev, 0x40, 3, value, index, NULL, 0, ftdi->usb_write_timeout) != 0) {
a3da1d95
GE
313 ftdi->error_str = "Setting new baudrate failed";
314 return -2;
315 }
316
317 ftdi->baudrate = baudrate;
318 return 0;
319}
320
321
be5d7eec 322int ftdi_write_data(struct ftdi_context *ftdi, unsigned char *buf, int size) {
a3da1d95
GE
323 int ret;
324 int offset = 0;
545820ce 325 int total_written = 0;
a3da1d95 326 while (offset < size) {
948f9ada 327 int write_size = ftdi->writebuffer_chunksize;
a3da1d95
GE
328
329 if (offset+write_size > size)
330 write_size = size-offset;
331
98452d97 332 ret = usb_bulk_write(ftdi->usb_dev, ftdi->in_ep, buf+offset, write_size, ftdi->usb_write_timeout);
29c4af7f
TJ
333 if (ret < 0) {
334 if (ret == -1)
335 ftdi->error_str = "bulk write failed";
336 else
337 ftdi->error_str = "usb failed";
338 return ret;
d9f0cce7 339 }
545820ce 340 total_written += ret;
a3da1d95
GE
341
342 offset += write_size;
343 }
344
545820ce 345 return total_written;
a3da1d95
GE
346}
347
348
948f9ada
TJ
349int ftdi_write_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize) {
350 ftdi->writebuffer_chunksize = chunksize;
351 return 0;
352}
353
354
355int ftdi_write_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize) {
356 *chunksize = ftdi->writebuffer_chunksize;
357 return 0;
358}
cbabb7d3 359
948f9ada
TJ
360
361int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size) {
98452d97 362 int offset = 0, ret = 1;
d9f0cce7 363
948f9ada
TJ
364 // everything we want is still in the readbuffer?
365 if (size <= ftdi->readbuffer_remaining) {
d9f0cce7
TJ
366 memcpy (buf, ftdi->readbuffer+ftdi->readbuffer_offset, size);
367
368 // Fix offsets
369 ftdi->readbuffer_remaining -= size;
370 ftdi->readbuffer_offset += size;
371
545820ce 372 /* printf("Returning bytes from buffer: %d - remaining: %d\n", size, ftdi->readbuffer_remaining); */
d9f0cce7
TJ
373
374 return size;
979a145c 375 }
948f9ada
TJ
376 // something still in the readbuffer, but not enough to satisfy 'size'?
377 if (ftdi->readbuffer_remaining != 0) {
d9f0cce7 378 memcpy (buf, ftdi->readbuffer+ftdi->readbuffer_offset, ftdi->readbuffer_remaining);
979a145c 379
d9f0cce7
TJ
380 // Fix offset
381 offset += ftdi->readbuffer_remaining;
948f9ada 382 }
948f9ada 383 // do the actual USB read
cbabb7d3 384 while (offset < size && ret > 0) {
d9f0cce7
TJ
385 ftdi->readbuffer_remaining = 0;
386 ftdi->readbuffer_offset = 0;
98452d97
TJ
387 /* returns how much received */
388 ret = usb_bulk_read (ftdi->usb_dev, ftdi->out_ep, ftdi->readbuffer, ftdi->readbuffer_chunksize, ftdi->usb_read_timeout);
389
29c4af7f
TJ
390 if (ret < 0) {
391 if (ret == -1)
392 ftdi->error_str = "bulk read failed";
393 else
394 ftdi->error_str = "usb failed";
395 return ret;
0e302db6 396 }
98452d97 397
d9f0cce7
TJ
398 if (ret > 2) {
399 // skip FTDI status bytes.
400 // Maybe stored in the future to enable modem use
401 ftdi->readbuffer_offset += 2;
402 ret -= 2;
403 } else if (ret <= 2) {
404 // no more data to read?
405 return offset;
406 }
d9f0cce7
TJ
407 if (ret > 0) {
408 // data still fits in buf?
409 if (offset+ret <= size) {
410 memcpy (buf+offset, ftdi->readbuffer+ftdi->readbuffer_offset, ret);
545820ce 411 //printf("buf[0] = %X, buf[1] = %X\n", buf[0], buf[1]);
d9f0cce7
TJ
412 offset += ret;
413
53ad271d 414 /* Did we read exactly the right amount of bytes? */
d9f0cce7
TJ
415 if (offset == size)
416 return offset;
417 } else {
418 // only copy part of the data or size <= readbuffer_chunksize
419 int part_size = size-offset;
420 memcpy (buf+offset, ftdi->readbuffer+ftdi->readbuffer_offset, part_size);
98452d97 421
d9f0cce7
TJ
422 ftdi->readbuffer_offset += part_size;
423 ftdi->readbuffer_remaining = ret-part_size;
424 offset += part_size;
425
53ad271d
TJ
426 /* printf("Returning part: %d - size: %d - offset: %d - ret: %d - remaining: %d\n",
427 part_size, size, offset, ret, ftdi->readbuffer_remaining); */
d9f0cce7
TJ
428
429 return offset;
430 }
431 }
cbabb7d3 432 }
948f9ada 433 // never reached
29c4af7f 434 return -127;
a3da1d95
GE
435}
436
437
948f9ada 438int ftdi_read_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize) {
29c4af7f
TJ
439 unsigned char *new_buf;
440
948f9ada
TJ
441 // Invalidate all remaining data
442 ftdi->readbuffer_offset = 0;
443 ftdi->readbuffer_remaining = 0;
444
948f9ada 445 if ((new_buf = (unsigned char *)realloc(ftdi->readbuffer, chunksize)) == NULL) {
d9f0cce7
TJ
446 ftdi->error_str = "out of memory for readbuffer";
447 return -1;
948f9ada 448 }
d9f0cce7 449
948f9ada
TJ
450 ftdi->readbuffer = new_buf;
451 ftdi->readbuffer_chunksize = chunksize;
452
453 return 0;
454}
455
456
25707904 457int ftdi_read_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize) {
948f9ada
TJ
458 *chunksize = ftdi->readbuffer_chunksize;
459 return 0;
460}
461
462
463
a3da1d95
GE
464int ftdi_enable_bitbang(struct ftdi_context *ftdi, unsigned char bitmask) {
465 unsigned short usb_val;
466
d9f0cce7 467 usb_val = bitmask; // low byte: bitmask
3119537f
TJ
468 /* FT2232C: Set bitbang_mode to 2 to enable SPI */
469 usb_val |= (ftdi->bitbang_mode << 8);
470
98452d97 471 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, usb_val, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) {
a3da1d95
GE
472 ftdi->error_str = "Unable to enter bitbang mode. Perhaps not a BM type chip?";
473 return -1;
474 }
a3da1d95
GE
475 ftdi->bitbang_enabled = 1;
476 return 0;
477}
478
479
480int ftdi_disable_bitbang(struct ftdi_context *ftdi) {
98452d97 481 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, 0, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) {
a3da1d95
GE
482 ftdi->error_str = "Unable to leave bitbang mode. Perhaps not a BM type chip?";
483 return -1;
484 }
485
486 ftdi->bitbang_enabled = 0;
487 return 0;
488}
489
490
491int ftdi_read_pins(struct ftdi_context *ftdi, unsigned char *pins) {
492 unsigned short usb_val;
98452d97 493 if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x0C, 0, ftdi->index, (char *)&usb_val, 1, ftdi->usb_read_timeout) != 1) {
a3da1d95
GE
494 ftdi->error_str = "Read pins failed";
495 return -1;
496 }
497
498 *pins = (unsigned char)usb_val;
499 return 0;
500}
501
502
503int ftdi_set_latency_timer(struct ftdi_context *ftdi, unsigned char latency) {
504 unsigned short usb_val;
505
506 if (latency < 1) {
d9f0cce7
TJ
507 ftdi->error_str = "Latency out of range. Only valid for 1-255";
508 return -1;
a3da1d95
GE
509 }
510
d79d2e68 511 usb_val = latency;
98452d97 512 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x09, usb_val, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) {
d9f0cce7
TJ
513 ftdi->error_str = "Unable to set latency timer";
514 return -2;
a3da1d95
GE
515 }
516 return 0;
517}
518
519
520int ftdi_get_latency_timer(struct ftdi_context *ftdi, unsigned char *latency) {
521 unsigned short usb_val;
98452d97 522 if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x0A, 0, ftdi->index, (char *)&usb_val, 1, ftdi->usb_read_timeout) != 1) {
a3da1d95
GE
523 ftdi->error_str = "Reading latency timer failed";
524 return -1;
525 }
526
527 *latency = (unsigned char)usb_val;
528 return 0;
529}
530
531
b8aa7b35 532void ftdi_eeprom_initdefaults(struct ftdi_eeprom *eeprom) {
f396dbad
TJ
533 eeprom->vendor_id = 0x0403;
534 eeprom->product_id = 0x6001;
d9f0cce7 535
b8aa7b35
TJ
536 eeprom->self_powered = 1;
537 eeprom->remote_wakeup = 1;
538 eeprom->BM_type_chip = 1;
d9f0cce7 539
b8aa7b35
TJ
540 eeprom->in_is_isochronous = 0;
541 eeprom->out_is_isochronous = 0;
542 eeprom->suspend_pull_downs = 0;
d9f0cce7 543
b8aa7b35
TJ
544 eeprom->use_serial = 0;
545 eeprom->change_usb_version = 0;
f396dbad 546 eeprom->usb_version = 0x0200;
b8aa7b35 547 eeprom->max_power = 0;
d9f0cce7 548
b8aa7b35
TJ
549 eeprom->manufacturer = NULL;
550 eeprom->product = NULL;
551 eeprom->serial = NULL;
552}
553
554
555/*
556 ftdi_eeprom_build return codes:
8ed61121 557 positive value: used eeprom size
b8aa7b35
TJ
558 -1: eeprom size (128 bytes) exceeded by custom strings
559*/
560int ftdi_eeprom_build(struct ftdi_eeprom *eeprom, unsigned char *output) {
561 unsigned char i, j;
562 unsigned short checksum, value;
563 unsigned char manufacturer_size = 0, product_size = 0, serial_size = 0;
564 int size_check;
565
566 if (eeprom->manufacturer != NULL)
d9f0cce7 567 manufacturer_size = strlen(eeprom->manufacturer);
b8aa7b35 568 if (eeprom->product != NULL)
d9f0cce7 569 product_size = strlen(eeprom->product);
b8aa7b35 570 if (eeprom->serial != NULL)
d9f0cce7 571 serial_size = strlen(eeprom->serial);
b8aa7b35 572
d9f0cce7
TJ
573 size_check = 128; // eeprom is 128 bytes
574 size_check -= 28; // 28 are always in use (fixed)
b8aa7b35
TJ
575 size_check -= manufacturer_size*2;
576 size_check -= product_size*2;
577 size_check -= serial_size*2;
578
579 // eeprom size exceeded?
580 if (size_check < 0)
d9f0cce7 581 return (-1);
b8aa7b35
TJ
582
583 // empty eeprom
584 memset (output, 0, 128);
585
586 // Addr 00: Stay 00 00
587 // Addr 02: Vendor ID
588 output[0x02] = eeprom->vendor_id;
589 output[0x03] = eeprom->vendor_id >> 8;
590
591 // Addr 04: Product ID
592 output[0x04] = eeprom->product_id;
593 output[0x05] = eeprom->product_id >> 8;
594
595 // Addr 06: Device release number (0400h for BM features)
596 output[0x06] = 0x00;
d9f0cce7 597
b8aa7b35 598 if (eeprom->BM_type_chip == 1)
d9f0cce7 599 output[0x07] = 0x04;
b8aa7b35 600 else
d9f0cce7 601 output[0x07] = 0x02;
b8aa7b35
TJ
602
603 // Addr 08: Config descriptor
604 // Bit 1: remote wakeup if 1
605 // Bit 0: self powered if 1
606 //
607 j = 0;
608 if (eeprom->self_powered == 1)
d9f0cce7 609 j = j | 1;
b8aa7b35 610 if (eeprom->remote_wakeup == 1)
d9f0cce7 611 j = j | 2;
b8aa7b35
TJ
612 output[0x08] = j;
613
614 // Addr 09: Max power consumption: max power = value * 2 mA
d9f0cce7
TJ
615 output[0x09] = eeprom->max_power;
616 ;
617
b8aa7b35
TJ
618 // Addr 0A: Chip configuration
619 // Bit 7: 0 - reserved
620 // Bit 6: 0 - reserved
621 // Bit 5: 0 - reserved
622 // Bit 4: 1 - Change USB version
623 // Bit 3: 1 - Use the serial number string
624 // Bit 2: 1 - Enable suspend pull downs for lower power
625 // Bit 1: 1 - Out EndPoint is Isochronous
626 // Bit 0: 1 - In EndPoint is Isochronous
627 //
628 j = 0;
629 if (eeprom->in_is_isochronous == 1)
d9f0cce7 630 j = j | 1;
b8aa7b35 631 if (eeprom->out_is_isochronous == 1)
d9f0cce7 632 j = j | 2;
b8aa7b35 633 if (eeprom->suspend_pull_downs == 1)
d9f0cce7 634 j = j | 4;
b8aa7b35 635 if (eeprom->use_serial == 1)
d9f0cce7 636 j = j | 8;
b8aa7b35 637 if (eeprom->change_usb_version == 1)
d9f0cce7 638 j = j | 16;
b8aa7b35 639 output[0x0A] = j;
d9f0cce7 640
b8aa7b35
TJ
641 // Addr 0B: reserved
642 output[0x0B] = 0x00;
d9f0cce7 643
b8aa7b35
TJ
644 // Addr 0C: USB version low byte when 0x0A bit 4 is set
645 // Addr 0D: USB version high byte when 0x0A bit 4 is set
646 if (eeprom->change_usb_version == 1) {
647 output[0x0C] = eeprom->usb_version;
d9f0cce7 648 output[0x0D] = eeprom->usb_version >> 8;
b8aa7b35
TJ
649 }
650
651
652 // Addr 0E: Offset of the manufacturer string + 0x80
653 output[0x0E] = 0x14 + 0x80;
654
655 // Addr 0F: Length of manufacturer string
656 output[0x0F] = manufacturer_size*2 + 2;
657
658 // Addr 10: Offset of the product string + 0x80, calculated later
659 // Addr 11: Length of product string
660 output[0x11] = product_size*2 + 2;
661
662 // Addr 12: Offset of the serial string + 0x80, calculated later
663 // Addr 13: Length of serial string
664 output[0x13] = serial_size*2 + 2;
665
666 // Dynamic content
a862ddcf 667 output[0x14] = manufacturer_size*2 + 2;
d9f0cce7
TJ
668 output[0x15] = 0x03; // type: string
669
b8aa7b35 670 i = 0x16, j = 0;
d9f0cce7 671
b8aa7b35
TJ
672 // Output manufacturer
673 for (j = 0; j < manufacturer_size; j++) {
d9f0cce7
TJ
674 output[i] = eeprom->manufacturer[j], i++;
675 output[i] = 0x00, i++;
b8aa7b35
TJ
676 }
677
678 // Output product name
d9f0cce7 679 output[0x10] = i + 0x80; // calculate offset
b8aa7b35
TJ
680 output[i] = product_size*2 + 2, i++;
681 output[i] = 0x03, i++;
682 for (j = 0; j < product_size; j++) {
d9f0cce7
TJ
683 output[i] = eeprom->product[j], i++;
684 output[i] = 0x00, i++;
b8aa7b35 685 }
d9f0cce7 686
b8aa7b35 687 // Output serial
d9f0cce7 688 output[0x12] = i + 0x80; // calculate offset
b8aa7b35
TJ
689 output[i] = serial_size*2 + 2, i++;
690 output[i] = 0x03, i++;
691 for (j = 0; j < serial_size; j++) {
d9f0cce7
TJ
692 output[i] = eeprom->serial[j], i++;
693 output[i] = 0x00, i++;
b8aa7b35
TJ
694 }
695
696 // calculate checksum
697 checksum = 0xAAAA;
d9f0cce7 698
b8aa7b35 699 for (i = 0; i < 63; i++) {
d9f0cce7
TJ
700 value = output[i*2];
701 value += output[(i*2)+1] << 8;
b8aa7b35 702
d9f0cce7
TJ
703 checksum = value^checksum;
704 checksum = (checksum << 1) | (checksum >> 15);
b8aa7b35
TJ
705 }
706
707 output[0x7E] = checksum;
d9f0cce7 708 output[0x7F] = checksum >> 8;
b8aa7b35 709
8ed61121 710 return size_check;
b8aa7b35
TJ
711}
712
713
be5d7eec 714int ftdi_read_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom) {
a3da1d95
GE
715 int i;
716
717 for (i = 0; i < 64; i++) {
98452d97 718 if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x90, 0, i, eeprom+(i*2), 2, ftdi->usb_read_timeout) != 2) {
d9f0cce7
TJ
719 ftdi->error_str = "Reading eeprom failed";
720 return -1;
a3da1d95
GE
721 }
722 }
723
724 return 0;
725}
726
727
be5d7eec 728int ftdi_write_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom) {
a3da1d95
GE
729 unsigned short usb_val;
730 int i;
731
732 for (i = 0; i < 64; i++) {
d9f0cce7
TJ
733 usb_val = eeprom[i*2];
734 usb_val += eeprom[(i*2)+1] << 8;
98452d97 735 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x91, usb_val, i, NULL, 0, ftdi->usb_write_timeout) != 0) {
d9f0cce7
TJ
736 ftdi->error_str = "Unable to write eeprom";
737 return -1;
738 }
a3da1d95
GE
739 }
740
741 return 0;
742}
743
744
745int ftdi_erase_eeprom(struct ftdi_context *ftdi) {
98452d97 746 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x92, 0, 0, NULL, 0, ftdi->usb_write_timeout) != 0) {
a3da1d95
GE
747 ftdi->error_str = "Unable to erase eeprom";
748 return -1;
749 }
750
751 return 0;
752}