libftdi: (tomj) added libusb dependency to configure.in, removed "configure" from CVS
[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
105
106/* ftdi_usb_close return codes
107 0: all fine
108 -1: usb_release failed
109 -2: usb_close failed
110*/
111int 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*/
130int 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
192int 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
212int 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
224int 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
239int 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
250int 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
262int 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
278int 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
290int 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
304int 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
321int 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}