libftdi: (tomj) Improved error handling (Evgeny Sinelnikov)
[libftdi] / ftdi / ftdi.c
... / ...
CommitLineData
1/***************************************************************************
2 ftdi.c - description
3 -------------------
4 begin : Fri Apr 4 2003
5 copyright : (C) 2003 by Intra2net AG
6 email : opensource@intra2net.com
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 ***************************************************************************/
16
17#include <usb.h>
18
19#include "ftdi.h"
20
21/* ftdi_init return codes:
22 0: all fine
23 -1: couldn't allocate read buffer
24*/
25int ftdi_init(struct ftdi_context *ftdi) {
26 ftdi->usb_dev = NULL;
27 ftdi->usb_read_timeout = 5000;
28 ftdi->usb_write_timeout = 5000;
29
30 ftdi->type = TYPE_BM; /* chip type */
31 ftdi->baudrate = -1;
32 ftdi->bitbang_enabled = 0;
33
34 ftdi->readbuffer = NULL;
35 ftdi->readbuffer_offset = 0;
36 ftdi->readbuffer_remaining = 0;
37 ftdi->writebuffer_chunksize = 4096;
38
39 ftdi->interface = 0;
40 ftdi->index = 0;
41 ftdi->in_ep = 0x02;
42 ftdi->out_ep = 0x81;
43 ftdi->bitbang_mode = 1; /* 1: Normal bitbang mode, 2: SPI bitbang mode */
44
45 ftdi->error_str = NULL;
46
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);
52}
53
54
55void ftdi_deinit(struct ftdi_context *ftdi) {
56 if (ftdi->readbuffer != NULL) {
57 free(ftdi->readbuffer);
58 ftdi->readbuffer = NULL;
59 }
60}
61
62
63void ftdi_set_usbdev (struct ftdi_context *ftdi, usb_dev_handle *usb) {
64 ftdi->usb_dev = usb;
65}
66
67
68/* ftdi_usb_open return codes:
69 0: all fine
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
77*/
78int ftdi_usb_open(struct ftdi_context *ftdi, int vendor, int product) {
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";
91 return -2;
92 }
93
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 }
127
128 }
129
130 // device not found
131 return -3;
132}
133
134
135int ftdi_usb_reset(struct ftdi_context *ftdi) {
136 if (usb_control_msg(ftdi->usb_dev, 0x40, 0, 0, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) {
137 ftdi->error_str = "FTDI reset failed";
138 return -1;
139 }
140 // Invalidate data in the readbuffer
141 ftdi->readbuffer_offset = 0;
142 ftdi->readbuffer_remaining = 0;
143
144 return 0;
145}
146
147int ftdi_usb_purge_buffers(struct ftdi_context *ftdi) {
148 if (usb_control_msg(ftdi->usb_dev, 0x40, 0, 1, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) {
149 ftdi->error_str = "FTDI purge of RX buffer failed";
150 return -1;
151 }
152 // Invalidate data in the readbuffer
153 ftdi->readbuffer_offset = 0;
154 ftdi->readbuffer_remaining = 0;
155
156 if (usb_control_msg(ftdi->usb_dev, 0x40, 0, 2, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) {
157 ftdi->error_str = "FTDI purge of TX buffer failed";
158 return -1;
159 }
160
161
162 return 0;
163}
164
165/* ftdi_usb_close return codes
166 0: all fine
167 -1: usb_release failed
168 -2: usb_close failed
169*/
170int ftdi_usb_close(struct ftdi_context *ftdi) {
171 int rtn = 0;
172
173 if (usb_release_interface(ftdi->usb_dev, ftdi->interface) != 0)
174 rtn = -1;
175
176 if (usb_close (ftdi->usb_dev) != 0)
177 rtn = -2;
178
179 return rtn;
180}
181
182
183/*
184 ftdi_convert_baudrate returns nearest supported baud rate to that requested.
185 Function is only used internally
186*/
187static int ftdi_convert_baudrate(int baudrate, struct ftdi_context *ftdi,
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
203 if (ftdi->type == TYPE_AM) {
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;
221 } else if (ftdi->type != TYPE_AM && try_divisor < 12) {
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 {
228 if (ftdi->type == TYPE_AM) {
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);
271 if(ftdi->type == TYPE_2232C) {
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
279 // Return the nearest baud rate
280 return best_baud;
281}
282
283/*
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) {
290 unsigned short value, index;
291 int actual_baudrate;
292
293 if (ftdi->bitbang_enabled) {
294 baudrate = baudrate*4;
295 }
296
297 actual_baudrate = ftdi_convert_baudrate(baudrate, ftdi, &value, &index);
298 if (actual_baudrate <= 0) {
299 ftdi->error_str = "Silly baudrate <= 0.";
300 return -1;
301 }
302
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 }
311
312 if (usb_control_msg(ftdi->usb_dev, 0x40, 3, value, index, NULL, 0, ftdi->usb_write_timeout) != 0) {
313 ftdi->error_str = "Setting new baudrate failed";
314 return -2;
315 }
316
317 ftdi->baudrate = baudrate;
318 return 0;
319}
320
321
322int ftdi_write_data(struct ftdi_context *ftdi, unsigned char *buf, int size) {
323 int ret;
324 int offset = 0;
325 int total_written = 0;
326 while (offset < size) {
327 int write_size = ftdi->writebuffer_chunksize;
328
329 if (offset+write_size > size)
330 write_size = size-offset;
331
332 ret = usb_bulk_write(ftdi->usb_dev, ftdi->in_ep, buf+offset, write_size, ftdi->usb_write_timeout);
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;
339 }
340 total_written += ret;
341
342 offset += write_size;
343 }
344
345 return total_written;
346}
347
348
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}
359
360
361int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size) {
362 int offset = 0, ret = 1;
363
364 // everything we want is still in the readbuffer?
365 if (size <= ftdi->readbuffer_remaining) {
366 memcpy (buf, ftdi->readbuffer+ftdi->readbuffer_offset, size);
367
368 // Fix offsets
369 ftdi->readbuffer_remaining -= size;
370 ftdi->readbuffer_offset += size;
371
372 /* printf("Returning bytes from buffer: %d - remaining: %d\n", size, ftdi->readbuffer_remaining); */
373
374 return size;
375 }
376 // something still in the readbuffer, but not enough to satisfy 'size'?
377 if (ftdi->readbuffer_remaining != 0) {
378 memcpy (buf, ftdi->readbuffer+ftdi->readbuffer_offset, ftdi->readbuffer_remaining);
379
380 // Fix offset
381 offset += ftdi->readbuffer_remaining;
382 }
383 // do the actual USB read
384 while (offset < size && ret > 0) {
385 ftdi->readbuffer_remaining = 0;
386 ftdi->readbuffer_offset = 0;
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
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;
396 }
397
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 }
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);
411 //printf("buf[0] = %X, buf[1] = %X\n", buf[0], buf[1]);
412 offset += ret;
413
414 /* Did we read exactly the right amount of bytes? */
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);
421
422 ftdi->readbuffer_offset += part_size;
423 ftdi->readbuffer_remaining = ret-part_size;
424 offset += part_size;
425
426 /* printf("Returning part: %d - size: %d - offset: %d - ret: %d - remaining: %d\n",
427 part_size, size, offset, ret, ftdi->readbuffer_remaining); */
428
429 return offset;
430 }
431 }
432 }
433 // never reached
434 return -127;
435}
436
437
438int ftdi_read_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize) {
439 unsigned char *new_buf;
440
441 // Invalidate all remaining data
442 ftdi->readbuffer_offset = 0;
443 ftdi->readbuffer_remaining = 0;
444
445 if ((new_buf = (unsigned char *)realloc(ftdi->readbuffer, chunksize)) == NULL) {
446 ftdi->error_str = "out of memory for readbuffer";
447 return -1;
448 }
449
450 ftdi->readbuffer = new_buf;
451 ftdi->readbuffer_chunksize = chunksize;
452
453 return 0;
454}
455
456
457int ftdi_read_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize) {
458 *chunksize = ftdi->readbuffer_chunksize;
459 return 0;
460}
461
462
463
464int ftdi_enable_bitbang(struct ftdi_context *ftdi, unsigned char bitmask) {
465 unsigned short usb_val;
466
467 usb_val = bitmask; // low byte: bitmask
468 /* FT2232C: Set bitbang_mode to 2 to enable SPI */
469 usb_val |= (ftdi->bitbang_mode << 8);
470
471 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, usb_val, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) {
472 ftdi->error_str = "Unable to enter bitbang mode. Perhaps not a BM type chip?";
473 return -1;
474 }
475 ftdi->bitbang_enabled = 1;
476 return 0;
477}
478
479
480int ftdi_disable_bitbang(struct ftdi_context *ftdi) {
481 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, 0, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) {
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;
493 if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x0C, 0, ftdi->index, (char *)&usb_val, 1, ftdi->usb_read_timeout) != 1) {
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) {
507 ftdi->error_str = "Latency out of range. Only valid for 1-255";
508 return -1;
509 }
510
511 usb_val = latency;
512 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x09, usb_val, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) {
513 ftdi->error_str = "Unable to set latency timer";
514 return -2;
515 }
516 return 0;
517}
518
519
520int ftdi_get_latency_timer(struct ftdi_context *ftdi, unsigned char *latency) {
521 unsigned short usb_val;
522 if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x0A, 0, ftdi->index, (char *)&usb_val, 1, ftdi->usb_read_timeout) != 1) {
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
532void ftdi_eeprom_initdefaults(struct ftdi_eeprom *eeprom) {
533 eeprom->vendor_id = 0x0403;
534 eeprom->product_id = 0x6001;
535
536 eeprom->self_powered = 1;
537 eeprom->remote_wakeup = 1;
538 eeprom->BM_type_chip = 1;
539
540 eeprom->in_is_isochronous = 0;
541 eeprom->out_is_isochronous = 0;
542 eeprom->suspend_pull_downs = 0;
543
544 eeprom->use_serial = 0;
545 eeprom->change_usb_version = 0;
546 eeprom->usb_version = 0x0200;
547 eeprom->max_power = 0;
548
549 eeprom->manufacturer = NULL;
550 eeprom->product = NULL;
551 eeprom->serial = NULL;
552}
553
554
555/*
556 ftdi_eeprom_build return codes:
557 positive value: used eeprom size
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)
567 manufacturer_size = strlen(eeprom->manufacturer);
568 if (eeprom->product != NULL)
569 product_size = strlen(eeprom->product);
570 if (eeprom->serial != NULL)
571 serial_size = strlen(eeprom->serial);
572
573 size_check = 128; // eeprom is 128 bytes
574 size_check -= 28; // 28 are always in use (fixed)
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)
581 return (-1);
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;
597
598 if (eeprom->BM_type_chip == 1)
599 output[0x07] = 0x04;
600 else
601 output[0x07] = 0x02;
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)
609 j = j | 1;
610 if (eeprom->remote_wakeup == 1)
611 j = j | 2;
612 output[0x08] = j;
613
614 // Addr 09: Max power consumption: max power = value * 2 mA
615 output[0x09] = eeprom->max_power;
616 ;
617
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)
630 j = j | 1;
631 if (eeprom->out_is_isochronous == 1)
632 j = j | 2;
633 if (eeprom->suspend_pull_downs == 1)
634 j = j | 4;
635 if (eeprom->use_serial == 1)
636 j = j | 8;
637 if (eeprom->change_usb_version == 1)
638 j = j | 16;
639 output[0x0A] = j;
640
641 // Addr 0B: reserved
642 output[0x0B] = 0x00;
643
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;
648 output[0x0D] = eeprom->usb_version >> 8;
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
667 output[0x14] = manufacturer_size*2 + 2;
668 output[0x15] = 0x03; // type: string
669
670 i = 0x16, j = 0;
671
672 // Output manufacturer
673 for (j = 0; j < manufacturer_size; j++) {
674 output[i] = eeprom->manufacturer[j], i++;
675 output[i] = 0x00, i++;
676 }
677
678 // Output product name
679 output[0x10] = i + 0x80; // calculate offset
680 output[i] = product_size*2 + 2, i++;
681 output[i] = 0x03, i++;
682 for (j = 0; j < product_size; j++) {
683 output[i] = eeprom->product[j], i++;
684 output[i] = 0x00, i++;
685 }
686
687 // Output serial
688 output[0x12] = i + 0x80; // calculate offset
689 output[i] = serial_size*2 + 2, i++;
690 output[i] = 0x03, i++;
691 for (j = 0; j < serial_size; j++) {
692 output[i] = eeprom->serial[j], i++;
693 output[i] = 0x00, i++;
694 }
695
696 // calculate checksum
697 checksum = 0xAAAA;
698
699 for (i = 0; i < 63; i++) {
700 value = output[i*2];
701 value += output[(i*2)+1] << 8;
702
703 checksum = value^checksum;
704 checksum = (checksum << 1) | (checksum >> 15);
705 }
706
707 output[0x7E] = checksum;
708 output[0x7F] = checksum >> 8;
709
710 return size_check;
711}
712
713
714int ftdi_read_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom) {
715 int i;
716
717 for (i = 0; i < 64; i++) {
718 if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x90, 0, i, eeprom+(i*2), 2, ftdi->usb_read_timeout) != 2) {
719 ftdi->error_str = "Reading eeprom failed";
720 return -1;
721 }
722 }
723
724 return 0;
725}
726
727
728int ftdi_write_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom) {
729 unsigned short usb_val;
730 int i;
731
732 for (i = 0; i < 64; i++) {
733 usb_val = eeprom[i*2];
734 usb_val += eeprom[(i*2)+1] << 8;
735 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x91, usb_val, i, NULL, 0, ftdi->usb_write_timeout) != 0) {
736 ftdi->error_str = "Unable to write eeprom";
737 return -1;
738 }
739 }
740
741 return 0;
742}
743
744
745int ftdi_erase_eeprom(struct ftdi_context *ftdi) {
746 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x92, 0, 0, NULL, 0, ftdi->usb_write_timeout) != 0) {
747 ftdi->error_str = "Unable to erase eeprom";
748 return -1;
749 }
750
751 return 0;
752}