build fixes
[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);
cbabb7d3 333 if (ret == -1) {
d9f0cce7 334 ftdi->error_str = "bulk write failed";
a3da1d95 335 return -1;
d9f0cce7 336 }
545820ce 337 total_written += ret;
a3da1d95
GE
338
339 offset += write_size;
340 }
341
545820ce 342 return total_written;
a3da1d95
GE
343}
344
345
948f9ada
TJ
346int ftdi_write_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize) {
347 ftdi->writebuffer_chunksize = chunksize;
348 return 0;
349}
350
351
352int ftdi_write_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize) {
353 *chunksize = ftdi->writebuffer_chunksize;
354 return 0;
355}
cbabb7d3 356
948f9ada
TJ
357
358int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size) {
98452d97 359 int offset = 0, ret = 1;
d9f0cce7 360
948f9ada
TJ
361 // everything we want is still in the readbuffer?
362 if (size <= ftdi->readbuffer_remaining) {
d9f0cce7
TJ
363 memcpy (buf, ftdi->readbuffer+ftdi->readbuffer_offset, size);
364
365 // Fix offsets
366 ftdi->readbuffer_remaining -= size;
367 ftdi->readbuffer_offset += size;
368
545820ce 369 /* printf("Returning bytes from buffer: %d - remaining: %d\n", size, ftdi->readbuffer_remaining); */
d9f0cce7
TJ
370
371 return size;
979a145c 372 }
948f9ada
TJ
373 // something still in the readbuffer, but not enough to satisfy 'size'?
374 if (ftdi->readbuffer_remaining != 0) {
d9f0cce7 375 memcpy (buf, ftdi->readbuffer+ftdi->readbuffer_offset, ftdi->readbuffer_remaining);
979a145c 376
d9f0cce7
TJ
377 // Fix offset
378 offset += ftdi->readbuffer_remaining;
948f9ada 379 }
948f9ada 380 // do the actual USB read
cbabb7d3 381 while (offset < size && ret > 0) {
d9f0cce7
TJ
382 ftdi->readbuffer_remaining = 0;
383 ftdi->readbuffer_offset = 0;
98452d97
TJ
384 /* returns how much received */
385 ret = usb_bulk_read (ftdi->usb_dev, ftdi->out_ep, ftdi->readbuffer, ftdi->readbuffer_chunksize, ftdi->usb_read_timeout);
386
387 if (ret == -1) {
388 ftdi->error_str = "bulk read failed";
0e302db6
TJ
389 return -1;
390 }
98452d97 391
d9f0cce7
TJ
392 if (ret > 2) {
393 // skip FTDI status bytes.
394 // Maybe stored in the future to enable modem use
395 ftdi->readbuffer_offset += 2;
396 ret -= 2;
397 } else if (ret <= 2) {
398 // no more data to read?
399 return offset;
400 }
d9f0cce7
TJ
401 if (ret > 0) {
402 // data still fits in buf?
403 if (offset+ret <= size) {
404 memcpy (buf+offset, ftdi->readbuffer+ftdi->readbuffer_offset, ret);
545820ce 405 //printf("buf[0] = %X, buf[1] = %X\n", buf[0], buf[1]);
d9f0cce7
TJ
406 offset += ret;
407
53ad271d 408 /* Did we read exactly the right amount of bytes? */
d9f0cce7
TJ
409 if (offset == size)
410 return offset;
411 } else {
412 // only copy part of the data or size <= readbuffer_chunksize
413 int part_size = size-offset;
414 memcpy (buf+offset, ftdi->readbuffer+ftdi->readbuffer_offset, part_size);
98452d97 415
d9f0cce7
TJ
416 ftdi->readbuffer_offset += part_size;
417 ftdi->readbuffer_remaining = ret-part_size;
418 offset += part_size;
419
53ad271d
TJ
420 /* printf("Returning part: %d - size: %d - offset: %d - ret: %d - remaining: %d\n",
421 part_size, size, offset, ret, ftdi->readbuffer_remaining); */
d9f0cce7
TJ
422
423 return offset;
424 }
425 }
cbabb7d3 426 }
948f9ada
TJ
427 // never reached
428 return -2;
a3da1d95
GE
429}
430
431
948f9ada
TJ
432int ftdi_read_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize) {
433 // Invalidate all remaining data
434 ftdi->readbuffer_offset = 0;
435 ftdi->readbuffer_remaining = 0;
436
437 unsigned char *new_buf;
438 if ((new_buf = (unsigned char *)realloc(ftdi->readbuffer, chunksize)) == NULL) {
d9f0cce7
TJ
439 ftdi->error_str = "out of memory for readbuffer";
440 return -1;
948f9ada 441 }
d9f0cce7 442
948f9ada
TJ
443 ftdi->readbuffer = new_buf;
444 ftdi->readbuffer_chunksize = chunksize;
445
446 return 0;
447}
448
449
25707904 450int ftdi_read_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize) {
948f9ada
TJ
451 *chunksize = ftdi->readbuffer_chunksize;
452 return 0;
453}
454
455
456
a3da1d95
GE
457int ftdi_enable_bitbang(struct ftdi_context *ftdi, unsigned char bitmask) {
458 unsigned short usb_val;
459
d9f0cce7 460 usb_val = bitmask; // low byte: bitmask
3119537f
TJ
461 /* FT2232C: Set bitbang_mode to 2 to enable SPI */
462 usb_val |= (ftdi->bitbang_mode << 8);
463
98452d97 464 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, usb_val, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) {
a3da1d95
GE
465 ftdi->error_str = "Unable to enter bitbang mode. Perhaps not a BM type chip?";
466 return -1;
467 }
a3da1d95
GE
468 ftdi->bitbang_enabled = 1;
469 return 0;
470}
471
472
473int ftdi_disable_bitbang(struct ftdi_context *ftdi) {
98452d97 474 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, 0, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) {
a3da1d95
GE
475 ftdi->error_str = "Unable to leave bitbang mode. Perhaps not a BM type chip?";
476 return -1;
477 }
478
479 ftdi->bitbang_enabled = 0;
480 return 0;
481}
482
483
484int ftdi_read_pins(struct ftdi_context *ftdi, unsigned char *pins) {
485 unsigned short usb_val;
98452d97 486 if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x0C, 0, ftdi->index, (char *)&usb_val, 1, ftdi->usb_read_timeout) != 1) {
a3da1d95
GE
487 ftdi->error_str = "Read pins failed";
488 return -1;
489 }
490
491 *pins = (unsigned char)usb_val;
492 return 0;
493}
494
495
496int ftdi_set_latency_timer(struct ftdi_context *ftdi, unsigned char latency) {
497 unsigned short usb_val;
498
499 if (latency < 1) {
d9f0cce7
TJ
500 ftdi->error_str = "Latency out of range. Only valid for 1-255";
501 return -1;
a3da1d95
GE
502 }
503
d79d2e68 504 usb_val = latency;
98452d97 505 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x09, usb_val, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0) {
d9f0cce7
TJ
506 ftdi->error_str = "Unable to set latency timer";
507 return -2;
a3da1d95
GE
508 }
509 return 0;
510}
511
512
513int ftdi_get_latency_timer(struct ftdi_context *ftdi, unsigned char *latency) {
514 unsigned short usb_val;
98452d97 515 if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x0A, 0, ftdi->index, (char *)&usb_val, 1, ftdi->usb_read_timeout) != 1) {
a3da1d95
GE
516 ftdi->error_str = "Reading latency timer failed";
517 return -1;
518 }
519
520 *latency = (unsigned char)usb_val;
521 return 0;
522}
523
524
b8aa7b35 525void ftdi_eeprom_initdefaults(struct ftdi_eeprom *eeprom) {
f396dbad
TJ
526 eeprom->vendor_id = 0x0403;
527 eeprom->product_id = 0x6001;
d9f0cce7 528
b8aa7b35
TJ
529 eeprom->self_powered = 1;
530 eeprom->remote_wakeup = 1;
531 eeprom->BM_type_chip = 1;
d9f0cce7 532
b8aa7b35
TJ
533 eeprom->in_is_isochronous = 0;
534 eeprom->out_is_isochronous = 0;
535 eeprom->suspend_pull_downs = 0;
d9f0cce7 536
b8aa7b35
TJ
537 eeprom->use_serial = 0;
538 eeprom->change_usb_version = 0;
f396dbad 539 eeprom->usb_version = 0x0200;
b8aa7b35 540 eeprom->max_power = 0;
d9f0cce7 541
b8aa7b35
TJ
542 eeprom->manufacturer = NULL;
543 eeprom->product = NULL;
544 eeprom->serial = NULL;
545}
546
547
548/*
549 ftdi_eeprom_build return codes:
8ed61121 550 positive value: used eeprom size
b8aa7b35
TJ
551 -1: eeprom size (128 bytes) exceeded by custom strings
552*/
553int ftdi_eeprom_build(struct ftdi_eeprom *eeprom, unsigned char *output) {
554 unsigned char i, j;
555 unsigned short checksum, value;
556 unsigned char manufacturer_size = 0, product_size = 0, serial_size = 0;
557 int size_check;
558
559 if (eeprom->manufacturer != NULL)
d9f0cce7 560 manufacturer_size = strlen(eeprom->manufacturer);
b8aa7b35 561 if (eeprom->product != NULL)
d9f0cce7 562 product_size = strlen(eeprom->product);
b8aa7b35 563 if (eeprom->serial != NULL)
d9f0cce7 564 serial_size = strlen(eeprom->serial);
b8aa7b35 565
d9f0cce7
TJ
566 size_check = 128; // eeprom is 128 bytes
567 size_check -= 28; // 28 are always in use (fixed)
b8aa7b35
TJ
568 size_check -= manufacturer_size*2;
569 size_check -= product_size*2;
570 size_check -= serial_size*2;
571
572 // eeprom size exceeded?
573 if (size_check < 0)
d9f0cce7 574 return (-1);
b8aa7b35
TJ
575
576 // empty eeprom
577 memset (output, 0, 128);
578
579 // Addr 00: Stay 00 00
580 // Addr 02: Vendor ID
581 output[0x02] = eeprom->vendor_id;
582 output[0x03] = eeprom->vendor_id >> 8;
583
584 // Addr 04: Product ID
585 output[0x04] = eeprom->product_id;
586 output[0x05] = eeprom->product_id >> 8;
587
588 // Addr 06: Device release number (0400h for BM features)
589 output[0x06] = 0x00;
d9f0cce7 590
b8aa7b35 591 if (eeprom->BM_type_chip == 1)
d9f0cce7 592 output[0x07] = 0x04;
b8aa7b35 593 else
d9f0cce7 594 output[0x07] = 0x02;
b8aa7b35
TJ
595
596 // Addr 08: Config descriptor
597 // Bit 1: remote wakeup if 1
598 // Bit 0: self powered if 1
599 //
600 j = 0;
601 if (eeprom->self_powered == 1)
d9f0cce7 602 j = j | 1;
b8aa7b35 603 if (eeprom->remote_wakeup == 1)
d9f0cce7 604 j = j | 2;
b8aa7b35
TJ
605 output[0x08] = j;
606
607 // Addr 09: Max power consumption: max power = value * 2 mA
d9f0cce7
TJ
608 output[0x09] = eeprom->max_power;
609 ;
610
b8aa7b35
TJ
611 // Addr 0A: Chip configuration
612 // Bit 7: 0 - reserved
613 // Bit 6: 0 - reserved
614 // Bit 5: 0 - reserved
615 // Bit 4: 1 - Change USB version
616 // Bit 3: 1 - Use the serial number string
617 // Bit 2: 1 - Enable suspend pull downs for lower power
618 // Bit 1: 1 - Out EndPoint is Isochronous
619 // Bit 0: 1 - In EndPoint is Isochronous
620 //
621 j = 0;
622 if (eeprom->in_is_isochronous == 1)
d9f0cce7 623 j = j | 1;
b8aa7b35 624 if (eeprom->out_is_isochronous == 1)
d9f0cce7 625 j = j | 2;
b8aa7b35 626 if (eeprom->suspend_pull_downs == 1)
d9f0cce7 627 j = j | 4;
b8aa7b35 628 if (eeprom->use_serial == 1)
d9f0cce7 629 j = j | 8;
b8aa7b35 630 if (eeprom->change_usb_version == 1)
d9f0cce7 631 j = j | 16;
b8aa7b35 632 output[0x0A] = j;
d9f0cce7 633
b8aa7b35
TJ
634 // Addr 0B: reserved
635 output[0x0B] = 0x00;
d9f0cce7 636
b8aa7b35
TJ
637 // Addr 0C: USB version low byte when 0x0A bit 4 is set
638 // Addr 0D: USB version high byte when 0x0A bit 4 is set
639 if (eeprom->change_usb_version == 1) {
640 output[0x0C] = eeprom->usb_version;
d9f0cce7 641 output[0x0D] = eeprom->usb_version >> 8;
b8aa7b35
TJ
642 }
643
644
645 // Addr 0E: Offset of the manufacturer string + 0x80
646 output[0x0E] = 0x14 + 0x80;
647
648 // Addr 0F: Length of manufacturer string
649 output[0x0F] = manufacturer_size*2 + 2;
650
651 // Addr 10: Offset of the product string + 0x80, calculated later
652 // Addr 11: Length of product string
653 output[0x11] = product_size*2 + 2;
654
655 // Addr 12: Offset of the serial string + 0x80, calculated later
656 // Addr 13: Length of serial string
657 output[0x13] = serial_size*2 + 2;
658
659 // Dynamic content
a862ddcf 660 output[0x14] = manufacturer_size*2 + 2;
d9f0cce7
TJ
661 output[0x15] = 0x03; // type: string
662
b8aa7b35 663 i = 0x16, j = 0;
d9f0cce7 664
b8aa7b35
TJ
665 // Output manufacturer
666 for (j = 0; j < manufacturer_size; j++) {
d9f0cce7
TJ
667 output[i] = eeprom->manufacturer[j], i++;
668 output[i] = 0x00, i++;
b8aa7b35
TJ
669 }
670
671 // Output product name
d9f0cce7 672 output[0x10] = i + 0x80; // calculate offset
b8aa7b35
TJ
673 output[i] = product_size*2 + 2, i++;
674 output[i] = 0x03, i++;
675 for (j = 0; j < product_size; j++) {
d9f0cce7
TJ
676 output[i] = eeprom->product[j], i++;
677 output[i] = 0x00, i++;
b8aa7b35 678 }
d9f0cce7 679
b8aa7b35 680 // Output serial
d9f0cce7 681 output[0x12] = i + 0x80; // calculate offset
b8aa7b35
TJ
682 output[i] = serial_size*2 + 2, i++;
683 output[i] = 0x03, i++;
684 for (j = 0; j < serial_size; j++) {
d9f0cce7
TJ
685 output[i] = eeprom->serial[j], i++;
686 output[i] = 0x00, i++;
b8aa7b35
TJ
687 }
688
689 // calculate checksum
690 checksum = 0xAAAA;
d9f0cce7 691
b8aa7b35 692 for (i = 0; i < 63; i++) {
d9f0cce7
TJ
693 value = output[i*2];
694 value += output[(i*2)+1] << 8;
b8aa7b35 695
d9f0cce7
TJ
696 checksum = value^checksum;
697 checksum = (checksum << 1) | (checksum >> 15);
b8aa7b35
TJ
698 }
699
700 output[0x7E] = checksum;
d9f0cce7 701 output[0x7F] = checksum >> 8;
b8aa7b35 702
8ed61121 703 return size_check;
b8aa7b35
TJ
704}
705
706
be5d7eec 707int ftdi_read_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom) {
a3da1d95
GE
708 int i;
709
710 for (i = 0; i < 64; i++) {
98452d97 711 if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x90, 0, i, eeprom+(i*2), 2, ftdi->usb_read_timeout) != 2) {
d9f0cce7
TJ
712 ftdi->error_str = "Reading eeprom failed";
713 return -1;
a3da1d95
GE
714 }
715 }
716
717 return 0;
718}
719
720
be5d7eec 721int ftdi_write_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom) {
a3da1d95
GE
722 unsigned short usb_val;
723 int i;
724
725 for (i = 0; i < 64; i++) {
d9f0cce7
TJ
726 usb_val = eeprom[i*2];
727 usb_val += eeprom[(i*2)+1] << 8;
98452d97 728 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x91, usb_val, i, NULL, 0, ftdi->usb_write_timeout) != 0) {
d9f0cce7
TJ
729 ftdi->error_str = "Unable to write eeprom";
730 return -1;
731 }
a3da1d95
GE
732 }
733
734 return 0;
735}
736
737
738int ftdi_erase_eeprom(struct ftdi_context *ftdi) {
98452d97 739 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x92, 0, 0, NULL, 0, ftdi->usb_write_timeout) != 0) {
a3da1d95
GE
740 ftdi->error_str = "Unable to erase eeprom";
741 return -1;
742 }
743
744 return 0;
745}