libftdi1 1.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

ftdi.cpp
Go to the documentation of this file.
1 /***************************************************************************
2 ftdi.cpp - C++ wraper for libftdi
3 -------------------
4 begin : Mon Oct 13 2008
5 copyright : (C) 2008-2013 by Marek Vavruša / libftdi developers
6 email : opensource@intra2net.com and marek@vavrusa.com
7 ***************************************************************************/
8 /*
9 Copyright (C) 2008-2013 by Marek Vavruša / libftdi developers
10
11 The software in this package is distributed under the GNU General
12 Public License version 2 (with a special exception described below).
13
14 A copy of GNU General Public License (GPL) is included in this distribution,
15 in the file COPYING.GPL.
16
17 As a special exception, if other files instantiate templates or use macros
18 or inline functions from this file, or you compile this file and link it
19 with other works to produce a work based on this file, this file
20 does not by itself cause the resulting work to be covered
21 by the GNU General Public License.
22
23 However the source code for this file must still be made available
24 in accordance with section (3) of the GNU General Public License.
25
26 This exception does not invalidate any other reasons why a work based
27 on this file might be covered by the GNU General Public License.
28 */
29 #include <libusb.h>
30 #include "ftdi.hpp"
31 #include "ftdi_i.h"
32 #include "ftdi.h"
33
34 namespace Ftdi
35 {
36
37 class Context::Private
38 {
39 public:
40 Private()
41 : open(false), ftdi(0), dev(0)
42 {
43 ftdi = ftdi_new();
44 }
45
46 ~Private()
47 {
48 if (open)
49 ftdi_usb_close(ftdi);
50
51 ftdi_free(ftdi);
52 }
53
54 bool open;
55
56 struct ftdi_context* ftdi;
57 struct libusb_device* dev;
58
59 std::string vendor;
60 std::string description;
61 std::string serial;
62 };
63
66 Context::Context()
67 : d( new Private() )
68 {
69 }
70
73 Context::~Context()
74 {
75 }
76
77 bool Context::is_open()
78 {
79 return d->open;
80 }
81
82 int Context::open(int vendor, int product)
83 {
84 // Open device
85 int ret = ftdi_usb_open(d->ftdi, vendor, product);
86
87 if (ret < 0)
88 return ret;
89
90 return get_strings_and_reopen();
91 }
92
93 int Context::open(int vendor, int product, const std::string& description, const std::string& serial, unsigned int index)
94 {
95 // translate empty strings to NULL
96 // -> do not use them to find the device (vs. require an empty string to be set in the EEPROM)
97 const char* c_description=NULL;
98 const char* c_serial=NULL;
99 if (!description.empty())
100 c_description=description.c_str();
101 if (!serial.empty())
102 c_serial=serial.c_str();
103
104 int ret = ftdi_usb_open_desc_index(d->ftdi, vendor, product, c_description, c_serial, index);
105
106 if (ret < 0)
107 return ret;
108
109 return get_strings_and_reopen();
110 }
111
112 int Context::open(const std::string& description)
113 {
114 int ret = ftdi_usb_open_string(d->ftdi, description.c_str());
115
116 if (ret < 0)
117 return ret;
118
119 return get_strings_and_reopen();
120 }
121
122 int Context::open(struct libusb_device *dev)
123 {
124 if (dev != 0)
125 d->dev = dev;
126
127 if (d->dev == 0)
128 return -1;
129
130 return get_strings_and_reopen();
131 }
132
133 int Context::close()
134 {
135 d->open = false;
136 d->dev = 0;
137 return ftdi_usb_close(d->ftdi);
138 }
139
140 int Context::reset()
141 {
142 return ftdi_usb_reset(d->ftdi);
143 }
144
145 int Context::flush(int mask)
146 {
147 int ret = 1;
148
149 if (mask & Input)
150 ret &= ftdi_usb_purge_rx_buffer(d->ftdi);
151 if (mask & Output)
152 ret &= ftdi_usb_purge_tx_buffer(d->ftdi);
153
154 return ret;
155 }
156
157 int Context::set_interface(enum ftdi_interface interface)
158 {
159 return ftdi_set_interface(d->ftdi, interface);
160 }
161
162 void Context::set_usb_device(struct libusb_device_handle *dev)
163 {
164 ftdi_set_usbdev(d->ftdi, dev);
165 d->dev = libusb_get_device(dev);
166 }
167
168 int Context::set_baud_rate(int baudrate)
169 {
170 return ftdi_set_baudrate(d->ftdi, baudrate);
171 }
172
173 int Context::set_line_property(enum ftdi_bits_type bits, enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity)
174 {
175 return ftdi_set_line_property(d->ftdi, bits, sbit, parity);
176 }
177
178 int Context::set_line_property(enum ftdi_bits_type bits, enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity, enum ftdi_break_type break_type)
179 {
180 return ftdi_set_line_property2(d->ftdi, bits, sbit, parity, break_type);
181 }
182
183 int Context::read(unsigned char *buf, int size)
184 {
185 return ftdi_read_data(d->ftdi, buf, size);
186 }
187
188 int Context::set_read_chunk_size(unsigned int chunksize)
189 {
190 return ftdi_read_data_set_chunksize(d->ftdi, chunksize);
191 }
192
193 int Context::read_chunk_size()
194 {
195 unsigned chunk = -1;
196 if (ftdi_read_data_get_chunksize(d->ftdi, &chunk) < 0)
197 return -1;
198
199 return chunk;
200 }
201
202 int Context::write(unsigned char *buf, int size)
203 {
204 return ftdi_write_data(d->ftdi, buf, size);
205 }
206
207 int Context::set_write_chunk_size(unsigned int chunksize)
208 {
209 return ftdi_write_data_set_chunksize(d->ftdi, chunksize);
210 }
211
212 int Context::write_chunk_size()
213 {
214 unsigned chunk = -1;
215 if (ftdi_write_data_get_chunksize(d->ftdi, &chunk) < 0)
216 return -1;
217
218 return chunk;
219 }
220
221 int Context::set_flow_control(int flowctrl)
222 {
223 return ftdi_setflowctrl(d->ftdi, flowctrl);
224 }
225
226 int Context::set_modem_control(int mask)
227 {
228 int dtr = 0, rts = 0;
229
230 if (mask & Dtr)
231 dtr = 1;
232 if (mask & Rts)
233 rts = 1;
234
235 return ftdi_setdtr_rts(d->ftdi, dtr, rts);
236 }
237
238 int Context::set_dtr(bool state)
239 {
240 return ftdi_setdtr(d->ftdi, state);
241 }
242
243 int Context::set_rts(bool state)
244 {
245 return ftdi_setrts(d->ftdi, state);
246 }
247
248 int Context::set_latency(unsigned char latency)
249 {
250 return ftdi_set_latency_timer(d->ftdi, latency);
251 }
252
253 unsigned Context::latency()
254 {
255 unsigned char latency = 0;
256 ftdi_get_latency_timer(d->ftdi, &latency);
257 return latency;
258 }
259
260 unsigned short Context::poll_modem_status()
261 {
262 unsigned short status = 0;
263 ftdi_poll_modem_status(d->ftdi, &status);
264 return status;
265 }
266
267 int Context::set_event_char(unsigned char eventch, unsigned char enable)
268 {
269 return ftdi_set_event_char(d->ftdi, eventch, enable);
270 }
271
272 int Context::set_error_char(unsigned char errorch, unsigned char enable)
273 {
274 return ftdi_set_error_char(d->ftdi, errorch, enable);
275 }
276
277 int Context::set_bitmode(unsigned char bitmask, unsigned char mode)
278 {
279 return ftdi_set_bitmode(d->ftdi, bitmask, mode);
280 }
281
282 int Context::set_bitmode(unsigned char bitmask, enum ftdi_mpsse_mode mode)
283 {
284 return ftdi_set_bitmode(d->ftdi, bitmask, mode);
285 }
286
287 int Context::bitbang_disable()
288 {
289 return ftdi_disable_bitbang(d->ftdi);
290 }
291
292 int Context::read_pins(unsigned char *pins)
293 {
294 return ftdi_read_pins(d->ftdi, pins);
295 }
296
297 char* Context::error_string()
298 {
299 return ftdi_get_error_string(d->ftdi);
300 }
301
302 int Context::get_strings()
303 {
304 // Prepare buffers
305 char vendor[512], desc[512], serial[512];
306
307 int ret = ftdi_usb_get_strings(d->ftdi, d->dev, vendor, 512, desc, 512, serial, 512);
308
309 if (ret < 0)
310 return -1;
311
312 d->vendor = vendor;
313 d->description = desc;
314 d->serial = serial;
315
316 return 1;
317 }
318
319 int Context::get_strings_and_reopen()
320 {
321 if ( d->dev == 0 )
322 {
323 d->dev = libusb_get_device(d->ftdi->usb_dev);
324 }
325
326 // Get device strings (closes device)
327 int ret=get_strings();
328 if (ret < 0)
329 {
330 d->open = 0;
331 return ret;
332 }
333
334 // Reattach device
335 ret = ftdi_usb_open_dev(d->ftdi, d->dev);
336 d->open = (ret >= 0);
337
338 return ret;
339 }
340
343 const std::string& Context::vendor()
344 {
345 return d->vendor;
346 }
347
350 const std::string& Context::description()
351 {
352 return d->description;
353 }
354
357 const std::string& Context::serial()
358 {
359 return d->serial;
360 }
361
362 void Context::set_context(struct ftdi_context* context)
363 {
364 ftdi_free(d->ftdi);
365 d->ftdi = context;
366 }
367
368 void Context::set_usb_device(struct libusb_device *dev)
369 {
370 d->dev = dev;
371 }
372
373 struct ftdi_context* Context::context()
374 {
375 return d->ftdi;
376 }
377
378 class Eeprom::Private
379 {
380 public:
381 Private()
382 : context(0)
383 {}
384
385 struct ftdi_eeprom eeprom;
386 struct ftdi_context* context;
387 };
388
389 Eeprom::Eeprom(Context* parent)
390 : d ( new Private() )
391 {
392 d->context = parent->context();
393 }
394
395 Eeprom::~Eeprom()
396 {
397 }
398
399 int Eeprom::init_defaults(char* manufacturer, char *product, char * serial)
400 {
401 return ftdi_eeprom_initdefaults(d->context, manufacturer, product, serial);
402 }
403
404 int Eeprom::chip_id(unsigned int *chipid)
405 {
406 return ftdi_read_chipid(d->context, chipid);
407 }
408
409 int Eeprom::build(unsigned char *output)
410 {
411 return ftdi_eeprom_build(d->context);
412 }
413
414 int Eeprom::read(unsigned char *eeprom)
415 {
416 return ftdi_read_eeprom(d->context);
417 }
418
419 int Eeprom::write(unsigned char *eeprom)
420 {
421 return ftdi_write_eeprom(d->context);
422 }
423
424 int Eeprom::read_location(int eeprom_addr, unsigned short *eeprom_val)
425 {
426 return ftdi_read_eeprom_location(d->context, eeprom_addr, eeprom_val);
427 }
428
429 int Eeprom::write_location(int eeprom_addr, unsigned short eeprom_val)
430 {
431 return ftdi_write_eeprom_location(d->context, eeprom_addr, eeprom_val);
432 }
433
434 int Eeprom::erase()
435 {
436 return ftdi_erase_eeprom(d->context);
437 }
438
439 class List::Private
440 {
441 public:
442 Private(struct ftdi_device_list* _devlist)
443 : devlist(_devlist)
444 {}
445
446 ~Private()
447 {
448 if(devlist)
449 ftdi_list_free(&devlist);
450 }
451
452 std::list<Context> list;
453 struct ftdi_device_list* devlist;
454 };
455
456 List::List(struct ftdi_device_list* devlist)
457 : d( new Private(devlist) )
458 {
459 if (devlist != 0)
460 {
461 // Iterate list
462 for (; devlist != 0; devlist = devlist->next)
463 {
464 Context c;
465 c.set_usb_device(devlist->dev);
466 c.get_strings();
467 d->list.push_back(c);
468 }
469 }
470 }
471
472 List::~List()
473 {
474 }
475
480 List::iterator List::begin()
481 {
482 return d->list.begin();
483 }
484
489 List::iterator List::end()
490 {
491 return d->list.end();
492 }
493
498 List::const_iterator List::begin() const
499 {
500 return d->list.begin();
501 }
502
507 List::const_iterator List::end() const
508 {
509 return d->list.end();
510 }
511
516 List::reverse_iterator List::rbegin()
517 {
518 return d->list.rbegin();
519 }
520
525 List::reverse_iterator List::rend()
526 {
527 return d->list.rend();
528 }
529
534 List::const_reverse_iterator List::rbegin() const
535 {
536 return d->list.rbegin();
537 }
538
543 List::const_reverse_iterator List::rend() const
544 {
545 return d->list.rend();
546
547 }
548
553 List::ListType::size_type List::size() const
554 {
555 return d->list.size();
556 }
557
562 bool List::empty() const
563 {
564 return d->list.empty();
565 }
566
572 void List::clear()
573 {
574 ListType().swap(d->list);
575
576 // Free device list
577 if (d->devlist)
578 {
579 ftdi_list_free(&d->devlist);
580 d->devlist = 0;
581 }
582 }
583
588 void List::push_back(const Context& element)
589 {
590 d->list.push_back(element);
591 }
592
597 void List::push_front(const Context& element)
598 {
599 d->list.push_front(element);
600 }
601
607 List::iterator List::erase(iterator pos)
608 {
609 return d->list.erase(pos);
610 }
611
618 List::iterator List::erase(iterator beg, iterator end)
619 {
620 return d->list.erase(beg, end);
621 }
622
623 List* List::find_all(Context &context, int vendor, int product)
624 {
625 struct ftdi_device_list* dlist = 0;
626 ftdi_usb_find_all(context.context(), &dlist, vendor, product);
627 return new List(dlist);
628 }
629
630 }