libftdi: (tomj) added libusb dependency to configure.in, removed "configure" from CVS
[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, 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             return -1;
204
205         offset += write_size;
206     }
207
208     return 0;
209 }
210
211
212 int ftdi_read_data(struct ftdi_context *ftdi, char *buf, int size) {
213     /*
214       unsigned char buf[64];
215       int read_bytes;
216
217       read_bytes = usb_bulk_read (udev, 0x81, (char *)&buf, 64, USB_TIMEOUT);
218     */
219     ftdi->error_str = "Not implemented yet";
220     return -1;
221 }
222
223
224 int ftdi_enable_bitbang(struct ftdi_context *ftdi, unsigned char bitmask) {
225     unsigned short usb_val;
226
227     usb_val = bitmask;  // low byte: bitmask
228     usb_val += 1 << 8;  // high byte: enable flag
229     if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, usb_val, 0, NULL, 0, ftdi->usb_timeout) != 0) {
230         ftdi->error_str = "Unable to enter bitbang mode. Perhaps not a BM type chip?";
231         return -1;
232     }
233
234     ftdi->bitbang_enabled = 1;
235     return 0;
236 }
237
238
239 int ftdi_disable_bitbang(struct ftdi_context *ftdi) {
240     if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, 0, 0, NULL, 0, ftdi->usb_timeout) != 0) {
241         ftdi->error_str = "Unable to leave bitbang mode. Perhaps not a BM type chip?";
242         return -1;
243     }
244
245     ftdi->bitbang_enabled = 0;
246     return 0;
247 }
248
249
250 int ftdi_read_pins(struct ftdi_context *ftdi, unsigned char *pins) {
251     unsigned short usb_val;
252     if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x0C, 0, 0, (char *)&usb_val, 1, ftdi->usb_timeout) != 1) {
253         ftdi->error_str = "Read pins failed";
254         return -1;
255     }
256
257     *pins = (unsigned char)usb_val;
258     return 0;
259 }
260
261
262 int ftdi_set_latency_timer(struct ftdi_context *ftdi, unsigned char latency) {
263     unsigned short usb_val;
264
265     if (latency < 1) {
266        ftdi->error_str = "Latency out of range. Only valid for 1-255";
267        return -1;
268     }
269
270     if (usb_control_msg(ftdi->usb_dev, 0x40, 0x09, usb_val, 0, NULL, 0, ftdi->usb_timeout) != 0) {
271        ftdi->error_str = "Unable to set latency timer";
272        return -2;
273     }
274     return 0;
275 }
276
277
278 int ftdi_get_latency_timer(struct ftdi_context *ftdi, unsigned char *latency) {
279     unsigned short usb_val;
280     if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x09, 0, 0, (char *)&usb_val, 1, ftdi->usb_timeout) != 1) {
281         ftdi->error_str = "Reading latency timer failed";
282         return -1;
283     }
284
285     *latency = (unsigned char)usb_val;
286     return 0;
287 }
288
289
290 int ftdi_read_eeprom(struct ftdi_context *ftdi, char *eeprom) {
291     int i;
292
293     for (i = 0; i < 64; i++) {
294         if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x90, 0, i, eeprom+(i*2), 2, ftdi->usb_timeout) != 2) {
295            ftdi->error_str = "Reading eeprom failed";
296            return -1;
297         }
298     }
299
300     return 0;
301 }
302
303
304 int ftdi_write_eeprom(struct ftdi_context *ftdi, char *eeprom) {
305     unsigned short usb_val;
306     int i;
307
308     for (i = 0; i < 64; i++) {
309        usb_val = eeprom[i*2];
310        usb_val += eeprom[(i*2)+1] << 8;
311        if (usb_control_msg(ftdi->usb_dev, 0x40, 0x91, usb_val, i, NULL, 0, ftdi->usb_timeout) != 0) {
312           ftdi->error_str = "Unable to write eeprom";
313           return -1;
314        }
315     }
316
317     return 0;
318 }
319
320
321 int ftdi_erase_eeprom(struct ftdi_context *ftdi) {
322     if (usb_control_msg(ftdi->usb_dev, 0x40, 0x92, 0, 0, NULL, 0, ftdi->usb_timeout) != 0) {
323         ftdi->error_str = "Unable to erase eeprom";
324         return -1;
325     }
326
327     return 0;
328 }