libftdi: (tomj) implemented read
[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                : info@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 int ftdi_init(struct ftdi_context *ftdi) {
22     ftdi->usb_dev = NULL;
23     ftdi->usb_timeout = 5000;
24
25     ftdi->baudrate = -1;
26     ftdi->bitbang_enabled = 0;
27
28     ftdi->error_str = NULL;
29
30     return 0;
31 }
32
33
34 void ftdi_set_usbdev (struct ftdi_context *ftdi, usb_dev_handle *usb) {
35     ftdi->usb_dev = usb;
36 }
37
38
39 /* ftdi_usb_open return codes:
40    0: all fine
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
46   -6: reset failed
47   -7: set baudrate failed
48 */
49 int ftdi_usb_open(struct ftdi_context *ftdi, int vendor, int product) {
50     struct usb_bus *bus;
51     struct usb_device *dev;
52
53     usb_init();
54
55     if (usb_find_busses() < 0) {
56         ftdi->error_str = "usb_find_busses() failed";
57         return -1;
58     }
59
60     if (usb_find_devices() < 0) {
61         ftdi->error_str = "usb_find_devices() failed";
62         return -2;
63     }
64
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);
69                 if (ftdi->usb_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...";
72                         return -5;
73                     }
74
75                     if (ftdi_usb_reset (ftdi) != 0)
76                        return -6;
77
78                     if (ftdi_set_baudrate (ftdi, 9600) != 0)
79                        return -7;
80
81                     return 0;
82                 } else {
83                     ftdi->error_str = "usb_open() failed";
84                     return -4;
85                 }
86             }
87         }
88
89     }
90
91     // device not found
92     return -3;
93 }
94
95
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";
99         return -1;
100     }
101
102     return 0;
103 }
104
105
106 /* ftdi_usb_close return codes
107     0: all fine
108    -1: usb_release failed
109    -2: usb_close failed
110 */
111 int ftdi_usb_close(struct ftdi_context *ftdi) {
112     int rtn = 0;
113
114     if (usb_release_interface(ftdi->usb_dev, 0) != 0)
115         rtn = -1;
116
117     if (usb_close (ftdi->usb_dev) != 0)
118         rtn = -2;
119
120     return rtn;
121 }
122
123
124 /*
125     ftdi_set_baudrate return codes:
126      0: all fine
127     -1: invalid baudrate
128     -2: setting baudrate failed
129 */
130 int ftdi_set_baudrate(struct ftdi_context *ftdi, int baudrate) {
131     unsigned short ftdi_baudrate;
132
133     if (ftdi->bitbang_enabled) {
134         baudrate = baudrate*4;
135     }
136
137     switch (baudrate) {
138     case 300:
139         ftdi_baudrate = 0x2710;
140         break;
141     case 600:
142         ftdi_baudrate = 0x1388;
143         break;
144     case 1200:
145         ftdi_baudrate = 0x09C4;
146         break;
147     case 2400:
148         ftdi_baudrate = 0x04E2;
149         break;
150     case 4800:
151         ftdi_baudrate = 0x0271;
152         break;
153     case 9600:
154         ftdi_baudrate = 0x4138;
155         break;
156     case 19200:
157         ftdi_baudrate = 0x809C;
158         break;
159     case 38400:
160         ftdi_baudrate = 0xC04E;
161         break;
162     case 57600:
163         ftdi_baudrate = 0x0034;
164         break;
165     case 115200:
166         ftdi_baudrate = 0x001A;
167         break;
168     case 230400:
169         ftdi_baudrate = 0x000D;
170         break;
171     case 460800:
172         ftdi_baudrate = 0x4006;
173         break;
174     case 921600:
175         ftdi_baudrate = 0x8003;
176         break;
177     default:
178         ftdi->error_str = "Unknown baudrate. Note: bitbang baudrates are automatically multiplied by 4";
179         return -1;
180     }
181
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";
184         return -2;
185     }
186
187     ftdi->baudrate = baudrate;
188     return 0;
189 }
190
191
192 int ftdi_write_data(struct ftdi_context *ftdi, unsigned char *buf, int size) {
193     int ret;
194     int offset = 0;
195     while (offset < size) {
196         int write_size = 64;
197
198         if (offset+write_size > size)
199             write_size = size-offset;
200
201         ret=usb_bulk_write(ftdi->usb_dev, 2, buf+offset, write_size, ftdi->usb_timeout);
202         if (ret == -1) {
203             ftdi->error_str = "bulk write failed";
204             return -1;
205         }
206
207         offset += write_size;
208     }
209
210     return 0;
211 }
212
213
214 int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size) {
215     static unsigned char readbuf[64];
216     int ret = 1;
217     int offset = 0;
218
219     while (offset < size && ret > 0) {
220         ret = usb_bulk_read (ftdi->usb_dev, 0x81, readbuf, 64, ftdi->usb_timeout);
221         // Skip FTDI status bytes
222         if (ret >= 2)
223             ret-=2;
224         
225         if (ret > 0) {
226             memcpy (buf+offset, readbuf+2, ret);
227         }
228
229         if (ret == -1) {
230             ftdi->error_str = "bulk read failed";
231             return -1;
232         }
233
234         offset += ret;
235     }
236
237     return offset;
238 }
239
240
241 int ftdi_enable_bitbang(struct ftdi_context *ftdi, unsigned char bitmask) {
242     unsigned short usb_val;
243
244     usb_val = bitmask;  // low byte: bitmask
245     usb_val += 1 << 8;  // high byte: enable flag
246     if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, usb_val, 0, NULL, 0, ftdi->usb_timeout) != 0) {
247         ftdi->error_str = "Unable to enter bitbang mode. Perhaps not a BM type chip?";
248         return -1;
249     }
250
251     ftdi->bitbang_enabled = 1;
252     return 0;
253 }
254
255
256 int ftdi_disable_bitbang(struct ftdi_context *ftdi) {
257     if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, 0, 0, NULL, 0, ftdi->usb_timeout) != 0) {
258         ftdi->error_str = "Unable to leave bitbang mode. Perhaps not a BM type chip?";
259         return -1;
260     }
261
262     ftdi->bitbang_enabled = 0;
263     return 0;
264 }
265
266
267 int ftdi_read_pins(struct ftdi_context *ftdi, unsigned char *pins) {
268     unsigned short usb_val;
269     if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x0C, 0, 0, (char *)&usb_val, 1, ftdi->usb_timeout) != 1) {
270         ftdi->error_str = "Read pins failed";
271         return -1;
272     }
273
274     *pins = (unsigned char)usb_val;
275     return 0;
276 }
277
278
279 int ftdi_set_latency_timer(struct ftdi_context *ftdi, unsigned char latency) {
280     unsigned short usb_val;
281
282     if (latency < 1) {
283        ftdi->error_str = "Latency out of range. Only valid for 1-255";
284        return -1;
285     }
286
287     if (usb_control_msg(ftdi->usb_dev, 0x40, 0x09, usb_val, 0, NULL, 0, ftdi->usb_timeout) != 0) {
288        ftdi->error_str = "Unable to set latency timer";
289        return -2;
290     }
291     return 0;
292 }
293
294
295 int ftdi_get_latency_timer(struct ftdi_context *ftdi, unsigned char *latency) {
296     unsigned short usb_val;
297     if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x09, 0, 0, (char *)&usb_val, 1, ftdi->usb_timeout) != 1) {
298         ftdi->error_str = "Reading latency timer failed";
299         return -1;
300     }
301
302     *latency = (unsigned char)usb_val;
303     return 0;
304 }
305
306
307 void ftdi_eeprom_initdefaults(struct ftdi_eeprom *eeprom) {
308     eeprom->vendor_id = 0403;
309     eeprom->product_id = 6001;
310     
311     eeprom->self_powered = 1;
312     eeprom->remote_wakeup = 1;
313     eeprom->BM_type_chip = 1;
314     
315     eeprom->in_is_isochronous = 0;
316     eeprom->out_is_isochronous = 0;
317     eeprom->suspend_pull_downs = 0;
318     
319     eeprom->use_serial = 0;
320     eeprom->change_usb_version = 0;
321     eeprom->usb_version = 200;
322     eeprom->max_power = 0;
323     
324     eeprom->manufacturer = NULL;
325     eeprom->product = NULL;
326     eeprom->serial = NULL;
327 }
328
329
330 /*
331     ftdi_eeprom_build return codes:
332     positive value: used eeprom size
333     -1: eeprom size (128 bytes) exceeded by custom strings
334 */
335 int ftdi_eeprom_build(struct ftdi_eeprom *eeprom, unsigned char *output) {
336     unsigned char i, j;
337     unsigned short checksum, value;
338     unsigned char manufacturer_size = 0, product_size = 0, serial_size = 0;
339     int size_check;
340
341     if (eeprom->manufacturer != NULL)
342         manufacturer_size = strlen(eeprom->manufacturer);
343     if (eeprom->product != NULL)
344         product_size = strlen(eeprom->product);
345     if (eeprom->serial != NULL)
346         serial_size = strlen(eeprom->serial);
347
348     size_check = 128;   // eeprom is 128 bytes
349     size_check -= 28;   // 28 are always in use (fixed)
350     size_check -= manufacturer_size*2;
351     size_check -= product_size*2;
352     size_check -= serial_size*2;
353
354     // eeprom size exceeded?
355     if (size_check < 0)
356         return (-1);
357
358     // empty eeprom
359     memset (output, 0, 128);
360
361     // Addr 00: Stay 00 00
362     // Addr 02: Vendor ID
363     output[0x02] = eeprom->vendor_id;
364     output[0x03] = eeprom->vendor_id >> 8;
365
366     // Addr 04: Product ID
367     output[0x04] = eeprom->product_id;
368     output[0x05] = eeprom->product_id >> 8;
369
370     // Addr 06: Device release number (0400h for BM features)
371     output[0x06] = 0x00;
372     
373     if (eeprom->BM_type_chip == 1)
374         output[0x07] = 0x04;
375     else
376         output[0x07] = 0x02;
377
378     // Addr 08: Config descriptor
379     // Bit 1: remote wakeup if 1
380     // Bit 0: self powered if 1
381     //
382     j = 0;
383     if (eeprom->self_powered == 1)
384         j = j | 1;
385     if (eeprom->remote_wakeup == 1)
386         j = j | 2;
387     output[0x08] = j;
388
389     // Addr 09: Max power consumption: max power = value * 2 mA
390     output[0x09] = eeprom->max_power;;
391     
392     // Addr 0A: Chip configuration
393     // Bit 7: 0 - reserved
394     // Bit 6: 0 - reserved
395     // Bit 5: 0 - reserved
396     // Bit 4: 1 - Change USB version
397     // Bit 3: 1 - Use the serial number string
398     // Bit 2: 1 - Enable suspend pull downs for lower power
399     // Bit 1: 1 - Out EndPoint is Isochronous
400     // Bit 0: 1 - In EndPoint is Isochronous
401     //
402     j = 0;
403     if (eeprom->in_is_isochronous == 1)
404         j = j | 1;
405     if (eeprom->out_is_isochronous == 1)
406         j = j | 2;
407     if (eeprom->suspend_pull_downs == 1)
408         j = j | 4;
409     if (eeprom->use_serial == 1)
410         j = j | 8;
411     if (eeprom->change_usb_version == 1)
412         j = j | 16;
413     output[0x0A] = j;
414     
415     // Addr 0B: reserved
416     output[0x0B] = 0x00;
417     
418     // Addr 0C: USB version low byte when 0x0A bit 4 is set
419     // Addr 0D: USB version high byte when 0x0A bit 4 is set
420     if (eeprom->change_usb_version == 1) {
421         output[0x0C] = eeprom->usb_version;
422         output[0x0D] = eeprom->usb_version >> 8;
423     }
424
425
426     // Addr 0E: Offset of the manufacturer string + 0x80
427     output[0x0E] = 0x14 + 0x80;
428
429     // Addr 0F: Length of manufacturer string
430     output[0x0F] = manufacturer_size*2 + 2;
431
432     // Addr 10: Offset of the product string + 0x80, calculated later
433     // Addr 11: Length of product string
434     output[0x11] = product_size*2 + 2;
435
436     // Addr 12: Offset of the serial string + 0x80, calculated later
437     // Addr 13: Length of serial string
438     output[0x13] = serial_size*2 + 2;
439
440     // Dynamic content
441     output[0x14] = manufacturer_size;
442     output[0x15] = 0x03;        // type: string
443     
444     i = 0x16, j = 0;
445     
446     // Output manufacturer
447     for (j = 0; j < manufacturer_size; j++) {
448         output[i] = eeprom->manufacturer[j], i++;
449         output[i] = 0x00, i++;
450     }
451
452     // Output product name
453     output[0x10] = i + 0x80;    // calculate offset
454     output[i] = product_size*2 + 2, i++;
455     output[i] = 0x03, i++;
456     for (j = 0; j < product_size; j++) {
457         output[i] = eeprom->product[j], i++;
458         output[i] = 0x00, i++;
459     }
460     
461     // Output serial
462     output[0x12] = i + 0x80;    // calculate offset
463     output[i] = serial_size*2 + 2, i++;
464     output[i] = 0x03, i++;
465     for (j = 0; j < serial_size; j++) {
466         output[i] = eeprom->serial[j], i++;
467         output[i] = 0x00, i++;
468     }
469
470     // calculate checksum
471     checksum = 0xAAAA;
472     
473     for (i = 0; i < 63; i++) {
474         value = output[i*2];
475         value += output[(i*2)+1] << 8;
476
477         checksum = value^checksum;
478         checksum = (checksum << 1) | (checksum >> 15);  
479     }
480
481     output[0x7E] = checksum;
482     output[0x7F] = checksum >> 8;    
483
484     return size_check;
485 }
486
487
488 int ftdi_read_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom) {
489     int i;
490
491     for (i = 0; i < 64; i++) {
492         if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x90, 0, i, eeprom+(i*2), 2, ftdi->usb_timeout) != 2) {
493            ftdi->error_str = "Reading eeprom failed";
494            return -1;
495         }
496     }
497
498     return 0;
499 }
500
501
502 int ftdi_write_eeprom(struct ftdi_context *ftdi, unsigned char *eeprom) {
503     unsigned short usb_val;
504     int i;
505
506     for (i = 0; i < 64; i++) {
507        usb_val = eeprom[i*2];
508        usb_val += eeprom[(i*2)+1] << 8;
509        if (usb_control_msg(ftdi->usb_dev, 0x40, 0x91, usb_val, i, NULL, 0, ftdi->usb_timeout) != 0) {
510           ftdi->error_str = "Unable to write eeprom";
511           return -1;
512        }
513     }
514
515     return 0;
516 }
517
518
519 int ftdi_erase_eeprom(struct ftdi_context *ftdi) {
520     if (usb_control_msg(ftdi->usb_dev, 0x40, 0x92, 0, 0, NULL, 0, ftdi->usb_timeout) != 0) {
521         ftdi->error_str = "Unable to erase eeprom";
522         return -1;
523     }
524
525     return 0;
526 }
527