1 /***************************************************************************
5 copyright : (C) 2003 by Intra2net AG
6 email : info@intra2net.com
7 ***************************************************************************/
9 /***************************************************************************
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; *
15 ***************************************************************************/
21 int ftdi_init(struct ftdi_context *ftdi) {
23 ftdi->usb_timeout = 5000;
26 ftdi->bitbang_enabled = 0;
28 ftdi->error_str = NULL;
34 void ftdi_set_usbdev (struct ftdi_context *ftdi, usb_dev_handle *usb) {
39 /* ftdi_usb_open return codes:
41 -1: usb_find_busses() failed
42 -2: usb_find_devices() failed
43 -3: usb device not found
44 -4: unable to open device
45 -5: unable to claim device
47 -7: set baudrate failed
49 int ftdi_usb_open(struct ftdi_context *ftdi, int vendor, int product) {
51 struct usb_device *dev;
55 if (usb_find_busses() < 0) {
56 ftdi->error_str = "usb_find_busses() failed";
60 if (usb_find_devices() < 0) {
61 ftdi->error_str = "usb_find_devices() failed";
65 for (bus = usb_busses; bus; bus = bus->next) {
66 for (dev = bus->devices; dev; dev = dev->next) {
67 if (dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product) {
68 ftdi->usb_dev = usb_open(dev);
70 if (usb_claim_interface(ftdi->usb_dev, 0) != 0) {
71 ftdi->error_str = "unable to claim usb device. You can still use it though...";
75 if (ftdi_usb_reset (ftdi) != 0)
78 if (ftdi_set_baudrate (ftdi, 9600) != 0)
83 ftdi->error_str = "usb_open() failed";
96 int ftdi_usb_reset(struct ftdi_context *ftdi) {
97 if (usb_control_msg(ftdi->usb_dev, 0x40, 0, 0, 0, NULL, 0, ftdi->usb_timeout) != 0) {
98 ftdi->error_str = "FTDI reset failed";
106 /* ftdi_usb_close return codes
108 -1: usb_release failed
111 int ftdi_usb_close(struct ftdi_context *ftdi) {
114 if (usb_release_interface(ftdi->usb_dev, 0) != 0)
117 if (usb_close (ftdi->usb_dev) != 0)
125 ftdi_set_baudrate return codes:
128 -2: setting baudrate failed
130 int ftdi_set_baudrate(struct ftdi_context *ftdi, int baudrate) {
131 unsigned short ftdi_baudrate;
133 if (ftdi->bitbang_enabled) {
134 baudrate = baudrate*4;
139 ftdi_baudrate = 0x2710;
142 ftdi_baudrate = 0x1388;
145 ftdi_baudrate = 0x09C4;
148 ftdi_baudrate = 0x04E2;
151 ftdi_baudrate = 0x0271;
154 ftdi_baudrate = 0x4138;
157 ftdi_baudrate = 0x809C;
160 ftdi_baudrate = 0xC04E;
163 ftdi_baudrate = 0x0034;
166 ftdi_baudrate = 0x001A;
169 ftdi_baudrate = 0x000D;
172 ftdi_baudrate = 0x4006;
175 ftdi_baudrate = 0x8003;
178 ftdi->error_str = "Unknown baudrate. Note: bitbang baudrates are automatically multiplied by 4";
182 if (usb_control_msg(ftdi->usb_dev, 0x40, 3, ftdi_baudrate, 0, NULL, 0, ftdi->usb_timeout) != 0) {
183 ftdi->error_str = "Setting new baudrate failed";
187 ftdi->baudrate = baudrate;
192 int ftdi_write_data(struct ftdi_context *ftdi, unsigned char *buf, int size) {
195 while (offset < size) {
198 if (offset+write_size > size)
199 write_size = size-offset;
201 ret=usb_bulk_write(ftdi->usb_dev, 2, buf+offset, write_size, ftdi->usb_timeout);
203 ftdi->error_str = "bulk write failed";
207 offset += write_size;
214 int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size) {
215 static unsigned char readbuf[64];
219 if (size != 0 && size % 64 != 0) {
220 ftdi->error_str = "Sorry, read buffer size must currently be a multiple (1x, 2x, 3x...) of 64";
224 while (offset < size && ret > 0) {
225 ret = usb_bulk_read (ftdi->usb_dev, 0x81, readbuf, 64, ftdi->usb_timeout);
226 // Skip FTDI status bytes
231 memcpy (buf+offset, readbuf+2, ret);
235 ftdi->error_str = "bulk read failed";
246 int ftdi_enable_bitbang(struct ftdi_context *ftdi, unsigned char bitmask) {
247 unsigned short usb_val;
249 usb_val = bitmask; // low byte: bitmask
250 usb_val += 1 << 8; // high byte: enable flag
251 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, usb_val, 0, NULL, 0, ftdi->usb_timeout) != 0) {
252 ftdi->error_str = "Unable to enter bitbang mode. Perhaps not a BM type chip?";
256 ftdi->bitbang_enabled = 1;
261 int ftdi_disable_bitbang(struct ftdi_context *ftdi) {
262 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, 0, 0, NULL, 0, ftdi->usb_timeout) != 0) {
263 ftdi->error_str = "Unable to leave bitbang mode. Perhaps not a BM type chip?";
267 ftdi->bitbang_enabled = 0;
272 int ftdi_read_pins(struct ftdi_context *ftdi, unsigned char *pins) {
273 unsigned short usb_val;
274 if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x0C, 0, 0, (char *)&usb_val, 1, ftdi->usb_timeout) != 1) {
275 ftdi->error_str = "Read pins failed";
279 *pins = (unsigned char)usb_val;
284 int ftdi_set_latency_timer(struct ftdi_context *ftdi, unsigned char latency) {
285 unsigned short usb_val;
288 ftdi->error_str = "Latency out of range. Only valid for 1-255";
292 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x09, usb_val, 0, NULL, 0, ftdi->usb_timeout) != 0) {
293 ftdi->error_str = "Unable to set latency timer";
300 int ftdi_get_latency_timer(struct ftdi_context *ftdi, unsigned char *latency) {
301 unsigned short usb_val;
302 if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x09, 0, 0, (char *)&usb_val, 1, ftdi->usb_timeout) != 1) {
303 ftdi->error_str = "Reading latency timer failed";
307 *latency = (unsigned char)usb_val;
312 void ftdi_eeprom_initdefaults(struct ftdi_eeprom *eeprom) {
313 eeprom->vendor_id = 0403;
314 eeprom->product_id = 6001;
316 eeprom->self_powered = 1;
317 eeprom->remote_wakeup = 1;
318 eeprom->BM_type_chip = 1;
320 eeprom->in_is_isochronous = 0;
321 eeprom->out_is_isochronous = 0;
322 eeprom->suspend_pull_downs = 0;
324 eeprom->use_serial = 0;
325 eeprom->change_usb_version = 0;
326 eeprom->usb_version = 200;
327 eeprom->max_power = 0;
329 eeprom->manufacturer = NULL;
330 eeprom->product = NULL;
331 eeprom->serial = NULL;
336 ftdi_eeprom_build return codes:
337 positive value: used eeprom size
338 -1: eeprom size (128 bytes) exceeded by custom strings
340 int ftdi_eeprom_build(struct ftdi_eeprom *eeprom, unsigned char *output) {
342 unsigned short checksum, value;
343 unsigned char manufacturer_size = 0, product_size = 0, serial_size = 0;
346 if (eeprom->manufacturer != NULL)
347 manufacturer_size = strlen(eeprom->manufacturer);
348 if (eeprom->product != NULL)
349 product_size = strlen(eeprom->product);
350 if (eeprom->serial != NULL)
351 serial_size = strlen(eeprom->serial);
353 size_check = 128; // eeprom is 128 bytes
354 size_check -= 28; // 28 are always in use (fixed)
355 size_check -= manufacturer_size*2;
356 size_check -= product_size*2;
357 size_check -= serial_size*2;
359 // eeprom size exceeded?
364 memset (output, 0, 128);
366 // Addr 00: Stay 00 00
367 // Addr 02: Vendor ID
368 output[0x02] = eeprom->vendor_id;
369 output[0x03] = eeprom->vendor_id >> 8;
371 // Addr 04: Product ID
372 output[0x04] = eeprom->product_id;
373 output[0x05] = eeprom->product_id >> 8;
375 // Addr 06: Device release number (0400h for BM features)
378 if (eeprom->BM_type_chip == 1)
383 // Addr 08: Config descriptor
384 // Bit 1: remote wakeup if 1
385 // Bit 0: self powered if 1
388 if (eeprom->self_powered == 1)
390 if (eeprom->remote_wakeup == 1)
394 // Addr 09: Max power consumption: max power = value * 2 mA
395 output[0x09] = eeprom->max_power;;
397 // Addr 0A: Chip configuration
398 // Bit 7: 0 - reserved
399 // Bit 6: 0 - reserved
400 // Bit 5: 0 - reserved
401 // Bit 4: 1 - Change USB version
402 // Bit 3: 1 - Use the serial number string
403 // Bit 2: 1 - Enable suspend pull downs for lower power
404 // Bit 1: 1 - Out EndPoint is Isochronous
405 // Bit 0: 1 - In EndPoint is Isochronous
408 if (eeprom->in_is_isochronous == 1)
410 if (eeprom->out_is_isochronous == 1)
412 if (eeprom->suspend_pull_downs == 1)
414 if (eeprom->use_serial == 1)
416 if (eeprom->change_usb_version == 1)
423 // Addr 0C: USB version low byte when 0x0A bit 4 is set
424 // Addr 0D: USB version high byte when 0x0A bit 4 is set
425 if (eeprom->change_usb_version == 1) {
426 output[0x0C] = eeprom->usb_version;
427 output[0x0D] = eeprom->usb_version >> 8;
431 // Addr 0E: Offset of the manufacturer string + 0x80
432 output[0x0E] = 0x14 + 0x80;
434 // Addr 0F: Length of manufacturer string
435 output[0x0F] = manufacturer_size*2 + 2;
437 // Addr 10: Offset of the product string + 0x80, calculated later
438 // Addr 11: Length of product string
439 output[0x11] = product_size*2 + 2;
441 // Addr 12: Offset of the serial string + 0x80, calculated later
442 // Addr 13: Length of serial string
443 output[0x13] = serial_size*2 + 2;
446 output[0x14] = manufacturer_size;
447 output[0x15] = 0x03; // type: string
451 // Output manufacturer
452 for (j = 0; j < manufacturer_size; j++) {
453 output[i] = eeprom->manufacturer[j], i++;
454 output[i] = 0x00, i++;
457 // Output product name
458 output[0x10] = i + 0x80; // calculate offset
459 output[i] = product_size*2 + 2, i++;
460 output[i] = 0x03, i++;
461 for (j = 0; j < product_size; j++) {
462 output[i] = eeprom->product[j], i++;
463 output[i] = 0x00, i++;
467 output[0x12] = i + 0x80; // calculate offset
468 output[i] = serial_size*2 + 2, i++;
469 output[i] = 0x03, i++;
470 for (j = 0; j < serial_size; j++) {
471 output[i] = eeprom->serial[j], i++;
472 output[i] = 0x00, i++;
475 // calculate checksum
478 for (i = 0; i < 63; i++) {
480 value += output[(i*2)+1] << 8;
482 checksum = value^checksum;
483 checksum = (checksum << 1) | (checksum >> 15);
486 output[0x7E] = checksum;
487 output[0x7F] = checksum >> 8;
493 int ftdi_read_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom) {
496 for (i = 0; i < 64; i++) {
497 if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x90, 0, i, eeprom+(i*2), 2, ftdi->usb_timeout) != 2) {
498 ftdi->error_str = "Reading eeprom failed";
507 int ftdi_write_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom) {
508 unsigned short usb_val;
511 for (i = 0; i < 64; i++) {
512 usb_val = eeprom[i*2];
513 usb_val += eeprom[(i*2)+1] << 8;
514 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x91, usb_val, i, NULL, 0, ftdi->usb_timeout) != 0) {
515 ftdi->error_str = "Unable to write eeprom";
524 int ftdi_erase_eeprom(struct ftdi_context *ftdi) {
525 if (usb_control_msg(ftdi->usb_dev, 0x40, 0x92, 0, 0, NULL, 0, ftdi->usb_timeout) != 0) {
526 ftdi->error_str = "Unable to erase eeprom";