libftdi: (tomj) wrote Changelog, library version increase
[libftdi] / ftdi / ftdi.c
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 */
25 int ftdi_init(struct ftdi_context *ftdi) {
26     ftdi->usb_dev = NULL;
27     ftdi->usb_timeout = 5000;
28
29     ftdi->baudrate = -1;
30     ftdi->bitbang_enabled = 0;
31
32     ftdi->readbuffer = NULL;
33     ftdi->readbuffer_offset = 0;
34     ftdi->readbuffer_remaining = 0;
35     ftdi->writebuffer_chunksize = 4096;
36
37     ftdi->error_str = NULL;
38
39     // all fine. Now allocate the readbuffer
40     return ftdi_read_data_set_chunksize(ftdi, 4096);
41 }
42
43
44 void ftdi_deinit(struct ftdi_context *ftdi) {
45     if (ftdi->readbuffer != NULL) {
46         free(ftdi->readbuffer);
47         ftdi->readbuffer = NULL;
48     }
49 }
50
51
52 void ftdi_set_usbdev (struct ftdi_context *ftdi, usb_dev_handle *usb) {
53     ftdi->usb_dev = usb;
54 }
55
56
57 /* ftdi_usb_open return codes:
58    0: all fine
59   -1: usb_find_busses() failed
60   -2: usb_find_devices() failed
61   -3: usb device not found
62   -4: unable to open device
63   -5: unable to claim device
64   -6: reset failed
65   -7: set baudrate failed
66 */
67 int ftdi_usb_open(struct ftdi_context *ftdi, int vendor, int product) {
68     struct usb_bus *bus;
69     struct usb_device *dev;
70
71     usb_init();
72
73     if (usb_find_busses() < 0) {
74         ftdi->error_str = "usb_find_busses() failed";
75         return -1;
76     }
77
78     if (usb_find_devices() < 0) {
79         ftdi->error_str = "usb_find_devices() failed";
80         return -2;
81     }
82
83     for (bus = usb_busses; bus; bus = bus->next) {
84         for (dev = bus->devices; dev; dev = dev->next) {
85             if (dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product) {
86                 ftdi->usb_dev = usb_open(dev);
87                 if (ftdi->usb_dev) {
88                     if (usb_claim_interface(ftdi->usb_dev, 0) != 0) {
89                         ftdi->error_str = "unable to claim usb device. You can still use it though...";
90                         return -5;
91                     }
92
93                     if (ftdi_usb_reset (ftdi) != 0)
94                        return -6;
95
96                     if (ftdi_set_baudrate (ftdi, 9600) != 0)
97                        return -7;
98
99                     return 0;
100                 } else {
101                     ftdi->error_str = "usb_open() failed";
102                     return -4;
103                 }
104             }
105         }
106
107     }
108
109     // device not found
110     return -3;
111 }
112
113
114 int ftdi_usb_reset(struct ftdi_context *ftdi) {
115     if (usb_control_msg(ftdi->usb_dev, 0x40, 0, 0, 0, NULL, 0, ftdi->usb_timeout) != 0) {
116         ftdi->error_str = "FTDI reset failed";
117         return -1;
118     }
119
120     return 0;
121 }
122
123 int ftdi_usb_purge_buffers(struct ftdi_context *ftdi) {
124     if (usb_control_msg(ftdi->usb_dev, 0x40, 0, 1, 0, NULL, 0, ftdi->usb_timeout) != 0) {
125         ftdi->error_str = "FTDI purge of RX buffer failed";
126         return -1;
127     }
128
129     if (usb_control_msg(ftdi->usb_dev, 0x40, 0, 2, 0, NULL, 0, ftdi->usb_timeout) != 0) {
130         ftdi->error_str = "FTDI purge of TX buffer failed";
131         return -1;
132     }
133
134     return 0;
135 }
136
137 /* ftdi_usb_close return codes
138     0: all fine
139    -1: usb_release failed
140    -2: usb_close failed
141 */
142 int ftdi_usb_close(struct ftdi_context *ftdi) {
143     int rtn = 0;
144
145     if (usb_release_interface(ftdi->usb_dev, 0) != 0)
146         rtn = -1;
147
148     if (usb_close (ftdi->usb_dev) != 0)
149         rtn = -2;
150
151     return rtn;
152 }
153
154
155 /*
156     ftdi_set_baudrate return codes:
157      0: all fine
158     -1: invalid baudrate
159     -2: setting baudrate failed
160 */
161 int ftdi_set_baudrate(struct ftdi_context *ftdi, int baudrate) {
162     unsigned short ftdi_baudrate;
163
164     if (ftdi->bitbang_enabled) {
165         baudrate = baudrate*4;
166     }
167
168     switch (baudrate) {
169     case 300:
170         ftdi_baudrate = 0x2710;
171         break;
172     case 600:
173         ftdi_baudrate = 0x1388;
174         break;
175     case 1200:
176         ftdi_baudrate = 0x09C4;
177         break;
178     case 2400:
179         ftdi_baudrate = 0x04E2;
180         break;
181     case 4800:
182         ftdi_baudrate = 0x0271;
183         break;
184     case 9600:
185         ftdi_baudrate = 0x4138;
186         break;
187     case 19200:
188         ftdi_baudrate = 0x809C;
189         break;
190     case 38400:
191         ftdi_baudrate = 0xC04E;
192         break;
193     case 57600:
194         ftdi_baudrate = 0x0034;
195         break;
196     case 115200:
197         ftdi_baudrate = 0x001A;
198         break;
199     case 230400:
200         ftdi_baudrate = 0x000D;
201         break;
202     case 460800:
203         ftdi_baudrate = 0x4006;
204         break;
205     case 921600:
206         ftdi_baudrate = 0x8003;
207         break;
208     default:
209         ftdi->error_str = "Unknown baudrate. Note: bitbang baudrates are automatically multiplied by 4";
210         return -1;
211     }
212
213     if (usb_control_msg(ftdi->usb_dev, 0x40, 3, ftdi_baudrate, 0, NULL, 0, ftdi->usb_timeout) != 0) {
214         ftdi->error_str = "Setting new baudrate failed";
215         return -2;
216     }
217
218     ftdi->baudrate = baudrate;
219     return 0;
220 }
221
222
223 int ftdi_write_data(struct ftdi_context *ftdi, unsigned char *buf, int size) {
224     int ret;
225     int offset = 0;
226     while (offset < size) {
227         int write_size = ftdi->writebuffer_chunksize;
228
229         if (offset+write_size > size)
230             write_size = size-offset;
231
232         ret=usb_bulk_write(ftdi->usb_dev, 2, buf+offset, write_size, ftdi->usb_timeout);
233         if (ret == -1) {
234             ftdi->error_str = "bulk write failed";
235             return -1;
236         }
237
238         offset += write_size;
239     }
240
241     return 0;
242 }
243
244
245 int ftdi_write_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize) {
246     ftdi->writebuffer_chunksize = chunksize;
247     return 0;
248 }
249
250
251 int ftdi_write_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize) {
252     *chunksize = ftdi->writebuffer_chunksize;
253     return 0;
254 }
255
256
257 int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size) {
258     int offset = 0, ret = 1;
259     
260     // everything we want is still in the readbuffer?
261     if (size <= ftdi->readbuffer_remaining) {
262         memcpy (buf, ftdi->readbuffer+ftdi->readbuffer_offset, size);
263         
264         // Fix offsets
265         ftdi->readbuffer_remaining -= size;
266         ftdi->readbuffer_offset += size;
267         
268         // printf("Returning bytes from buffer: %d - remaining: %d\n", size, ftdi->readbuffer_remaining);
269         
270         return size;
271     }
272     
273     // something still in the readbuffer, but not enough to satisfy 'size'?
274     if (ftdi->readbuffer_remaining != 0) {
275         memcpy (buf, ftdi->readbuffer+ftdi->readbuffer_offset, ftdi->readbuffer_remaining);
276
277         // printf("Got bytes from buffer: %d\n", ftdi->readbuffer_remaining);
278
279         // Fix offsets
280         offset += ftdi->readbuffer_remaining;
281         ftdi->readbuffer_remaining = 0;
282         ftdi->readbuffer_offset = 0;
283     }
284     
285     // do the actual USB read
286     while (offset < size && ret > 0) {
287         ftdi->readbuffer_remaining = 0;
288         ftdi->readbuffer_offset = 0;
289         ret = usb_bulk_read (ftdi->usb_dev, 0x81, ftdi->readbuffer, ftdi->readbuffer_chunksize, ftdi->usb_timeout);
290
291         if (ret == -1) {
292             ftdi->error_str = "bulk read failed";
293             return -1;
294         }
295
296         if (ret > 2) {
297             // skip FTDI status bytes.
298             // Maybe stored in the future to enable modem use
299             ftdi->readbuffer_offset += 2;
300             ret -= 2;
301         } else if (ret <= 2) {
302             // no more data to read?
303             return offset;
304         }
305
306         if (ret > 0) {
307             // data still fits in buf?
308             if (offset+ret <= size) {
309                 memcpy (buf+offset, ftdi->readbuffer+ftdi->readbuffer_offset, ret);
310                 offset += ret;
311                 
312                 if (offset == size)
313                     return offset;
314             } else {
315                 // only copy part of the data or size <= readbuffer_chunksize
316                 int part_size = size-offset;
317                 memcpy (buf+offset, ftdi->readbuffer+ftdi->readbuffer_offset, part_size);
318
319                 ftdi->readbuffer_offset += part_size;
320                 ftdi->readbuffer_remaining = ret-part_size;
321                 
322                 // printf("Returning part: %d - size: %d - offset: %d - ret: %d - remaining: %d\n", part_size, size, offset, ret, ftdi->readbuffer_remaining);
323
324                 return part_size;
325             }
326         }
327     }
328
329     // never reached
330     return -2;
331 }
332
333
334 int ftdi_read_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize) {
335     // Invalidate all remaining data
336     ftdi->readbuffer_offset = 0;
337     ftdi->readbuffer_remaining = 0;
338
339     unsigned char *new_buf;
340     if ((new_buf = (unsigned char *)realloc(ftdi->readbuffer, chunksize)) == NULL) {
341         ftdi->error_str = "out of memory for readbuffer";
342         return -1;
343     }
344     
345     ftdi->readbuffer = new_buf;
346     ftdi->readbuffer_chunksize = chunksize;
347
348     return 0;
349 }
350
351
352 int ftdi_readt_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize) {
353     *chunksize = ftdi->readbuffer_chunksize;
354     return 0;
355 }
356
357
358
359 int ftdi_enable_bitbang(struct ftdi_context *ftdi, unsigned char bitmask) {
360     unsigned short usb_val;
361
362     usb_val = bitmask;  // low byte: bitmask
363     usb_val += 1 << 8;  // high byte: enable flag
364     if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, usb_val, 0, NULL, 0, ftdi->usb_timeout) != 0) {
365         ftdi->error_str = "Unable to enter bitbang mode. Perhaps not a BM type chip?";
366         return -1;
367     }
368
369     ftdi->bitbang_enabled = 1;
370     return 0;
371 }
372
373
374 int ftdi_disable_bitbang(struct ftdi_context *ftdi) {
375     if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, 0, 0, NULL, 0, ftdi->usb_timeout) != 0) {
376         ftdi->error_str = "Unable to leave bitbang mode. Perhaps not a BM type chip?";
377         return -1;
378     }
379
380     ftdi->bitbang_enabled = 0;
381     return 0;
382 }
383
384
385 int ftdi_read_pins(struct ftdi_context *ftdi, unsigned char *pins) {
386     unsigned short usb_val;
387     if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x0C, 0, 0, (char *)&usb_val, 1, ftdi->usb_timeout) != 1) {
388         ftdi->error_str = "Read pins failed";
389         return -1;
390     }
391
392     *pins = (unsigned char)usb_val;
393     return 0;
394 }
395
396
397 int ftdi_set_latency_timer(struct ftdi_context *ftdi, unsigned char latency) {
398     unsigned short usb_val;
399
400     if (latency < 1) {
401        ftdi->error_str = "Latency out of range. Only valid for 1-255";
402        return -1;
403     }
404
405     usb_val = latency;
406     if (usb_control_msg(ftdi->usb_dev, 0x40, 0x09, usb_val, 0, NULL, 0, ftdi->usb_timeout) != 0) {
407        ftdi->error_str = "Unable to set latency timer";
408        return -2;
409     }
410     return 0;
411 }
412
413
414 int ftdi_get_latency_timer(struct ftdi_context *ftdi, unsigned char *latency) {
415     unsigned short usb_val;
416     if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x0A, 0, 0, (char *)&usb_val, 1, ftdi->usb_timeout) != 1) {
417         ftdi->error_str = "Reading latency timer failed";
418         return -1;
419     }
420
421     *latency = (unsigned char)usb_val;
422     return 0;
423 }
424
425
426 void ftdi_eeprom_initdefaults(struct ftdi_eeprom *eeprom) {
427     eeprom->vendor_id = 0403;
428     eeprom->product_id = 6001;
429     
430     eeprom->self_powered = 1;
431     eeprom->remote_wakeup = 1;
432     eeprom->BM_type_chip = 1;
433     
434     eeprom->in_is_isochronous = 0;
435     eeprom->out_is_isochronous = 0;
436     eeprom->suspend_pull_downs = 0;
437     
438     eeprom->use_serial = 0;
439     eeprom->change_usb_version = 0;
440     eeprom->usb_version = 200;
441     eeprom->max_power = 0;
442     
443     eeprom->manufacturer = NULL;
444     eeprom->product = NULL;
445     eeprom->serial = NULL;
446 }
447
448
449 /*
450     ftdi_eeprom_build return codes:
451     positive value: used eeprom size
452     -1: eeprom size (128 bytes) exceeded by custom strings
453 */
454 int ftdi_eeprom_build(struct ftdi_eeprom *eeprom, unsigned char *output) {
455     unsigned char i, j;
456     unsigned short checksum, value;
457     unsigned char manufacturer_size = 0, product_size = 0, serial_size = 0;
458     int size_check;
459
460     if (eeprom->manufacturer != NULL)
461         manufacturer_size = strlen(eeprom->manufacturer);
462     if (eeprom->product != NULL)
463         product_size = strlen(eeprom->product);
464     if (eeprom->serial != NULL)
465         serial_size = strlen(eeprom->serial);
466
467     size_check = 128;   // eeprom is 128 bytes
468     size_check -= 28;   // 28 are always in use (fixed)
469     size_check -= manufacturer_size*2;
470     size_check -= product_size*2;
471     size_check -= serial_size*2;
472
473     // eeprom size exceeded?
474     if (size_check < 0)
475         return (-1);
476
477     // empty eeprom
478     memset (output, 0, 128);
479
480     // Addr 00: Stay 00 00
481     // Addr 02: Vendor ID
482     output[0x02] = eeprom->vendor_id;
483     output[0x03] = eeprom->vendor_id >> 8;
484
485     // Addr 04: Product ID
486     output[0x04] = eeprom->product_id;
487     output[0x05] = eeprom->product_id >> 8;
488
489     // Addr 06: Device release number (0400h for BM features)
490     output[0x06] = 0x00;
491     
492     if (eeprom->BM_type_chip == 1)
493         output[0x07] = 0x04;
494     else
495         output[0x07] = 0x02;
496
497     // Addr 08: Config descriptor
498     // Bit 1: remote wakeup if 1
499     // Bit 0: self powered if 1
500     //
501     j = 0;
502     if (eeprom->self_powered == 1)
503         j = j | 1;
504     if (eeprom->remote_wakeup == 1)
505         j = j | 2;
506     output[0x08] = j;
507
508     // Addr 09: Max power consumption: max power = value * 2 mA
509     output[0x09] = eeprom->max_power;;
510     
511     // Addr 0A: Chip configuration
512     // Bit 7: 0 - reserved
513     // Bit 6: 0 - reserved
514     // Bit 5: 0 - reserved
515     // Bit 4: 1 - Change USB version
516     // Bit 3: 1 - Use the serial number string
517     // Bit 2: 1 - Enable suspend pull downs for lower power
518     // Bit 1: 1 - Out EndPoint is Isochronous
519     // Bit 0: 1 - In EndPoint is Isochronous
520     //
521     j = 0;
522     if (eeprom->in_is_isochronous == 1)
523         j = j | 1;
524     if (eeprom->out_is_isochronous == 1)
525         j = j | 2;
526     if (eeprom->suspend_pull_downs == 1)
527         j = j | 4;
528     if (eeprom->use_serial == 1)
529         j = j | 8;
530     if (eeprom->change_usb_version == 1)
531         j = j | 16;
532     output[0x0A] = j;
533     
534     // Addr 0B: reserved
535     output[0x0B] = 0x00;
536     
537     // Addr 0C: USB version low byte when 0x0A bit 4 is set
538     // Addr 0D: USB version high byte when 0x0A bit 4 is set
539     if (eeprom->change_usb_version == 1) {
540         output[0x0C] = eeprom->usb_version;
541         output[0x0D] = eeprom->usb_version >> 8;
542     }
543
544
545     // Addr 0E: Offset of the manufacturer string + 0x80
546     output[0x0E] = 0x14 + 0x80;
547
548     // Addr 0F: Length of manufacturer string
549     output[0x0F] = manufacturer_size*2 + 2;
550
551     // Addr 10: Offset of the product string + 0x80, calculated later
552     // Addr 11: Length of product string
553     output[0x11] = product_size*2 + 2;
554
555     // Addr 12: Offset of the serial string + 0x80, calculated later
556     // Addr 13: Length of serial string
557     output[0x13] = serial_size*2 + 2;
558
559     // Dynamic content
560     output[0x14] = manufacturer_size*2 + 2;
561     output[0x15] = 0x03;        // type: string
562     
563     i = 0x16, j = 0;
564     
565     // Output manufacturer
566     for (j = 0; j < manufacturer_size; j++) {
567         output[i] = eeprom->manufacturer[j], i++;
568         output[i] = 0x00, i++;
569     }
570
571     // Output product name
572     output[0x10] = i + 0x80;    // calculate offset
573     output[i] = product_size*2 + 2, i++;
574     output[i] = 0x03, i++;
575     for (j = 0; j < product_size; j++) {
576         output[i] = eeprom->product[j], i++;
577         output[i] = 0x00, i++;
578     }
579     
580     // Output serial
581     output[0x12] = i + 0x80;    // calculate offset
582     output[i] = serial_size*2 + 2, i++;
583     output[i] = 0x03, i++;
584     for (j = 0; j < serial_size; j++) {
585         output[i] = eeprom->serial[j], i++;
586         output[i] = 0x00, i++;
587     }
588
589     // calculate checksum
590     checksum = 0xAAAA;
591     
592     for (i = 0; i < 63; i++) {
593         value = output[i*2];
594         value += output[(i*2)+1] << 8;
595
596         checksum = value^checksum;
597         checksum = (checksum << 1) | (checksum >> 15);  
598     }
599
600     output[0x7E] = checksum;
601     output[0x7F] = checksum >> 8;    
602
603     return size_check;
604 }
605
606
607 int ftdi_read_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom) {
608     int i;
609
610     for (i = 0; i < 64; i++) {
611         if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x90, 0, i, eeprom+(i*2), 2, ftdi->usb_timeout) != 2) {
612            ftdi->error_str = "Reading eeprom failed";
613            return -1;
614         }
615     }
616
617     return 0;
618 }
619
620
621 int ftdi_write_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom) {
622     unsigned short usb_val;
623     int i;
624
625     for (i = 0; i < 64; i++) {
626        usb_val = eeprom[i*2];
627        usb_val += eeprom[(i*2)+1] << 8;
628        if (usb_control_msg(ftdi->usb_dev, 0x40, 0x91, usb_val, i, NULL, 0, ftdi->usb_timeout) != 0) {
629           ftdi->error_str = "Unable to write eeprom";
630           return -1;
631        }
632     }
633
634     return 0;
635 }
636
637
638 int ftdi_erase_eeprom(struct ftdi_context *ftdi) {
639     if (usb_control_msg(ftdi->usb_dev, 0x40, 0x92, 0, 0, NULL, 0, ftdi->usb_timeout) != 0) {
640         ftdi->error_str = "Unable to erase eeprom";
641         return -1;
642     }
643
644     return 0;
645 }