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