libftdi1  1.0
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 
38 {
39 public:
41  : open(false), ftdi(0), dev(0)
42  {
43  ftdi = ftdi_new();
44  }
45 
47  {
48  if (open)
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 
67  : d( new Private() )
68 {
69 }
70 
74 {
75 }
76 
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 
134 {
135  d->open = false;
136  d->dev = 0;
137  return ftdi_usb_close(d->ftdi);
138 }
139 
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 
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 
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 
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 
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 
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 
254 {
255  unsigned char latency = 0;
256  ftdi_get_latency_timer(d->ftdi, &latency);
257  return latency;
258 }
259 
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 
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 
298 {
299  return ftdi_get_error_string(d->ftdi);
300 }
301 
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 
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 
374 {
375  return d->ftdi;
376 }
377 
379 {
380 public:
382  : context(0)
383  {}
384 
387 };
388 
390  : d ( new Private() )
391 {
392  d->context = parent->context();
393 }
394 
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 
435 {
436  return ftdi_erase_eeprom(d->context);
437 }
438 
440 {
441 public:
442  Private(struct ftdi_device_list* _devlist)
443  : devlist(_devlist)
444  {}
445 
447  {
448  if(devlist)
450  }
451 
452  std::list<Context> list;
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 
473 {
474 }
475 
481 {
482  return d->list.begin();
483 }
484 
490 {
491  return d->list.end();
492 }
493 
499 {
500  return d->list.begin();
501 }
502 
508 {
509  return d->list.end();
510 }
511 
517 {
518  return d->list.rbegin();
519 }
520 
526 {
527  return d->list.rend();
528 }
529 
535 {
536  return d->list.rbegin();
537 }
538 
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 
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 
608 {
609  return d->list.erase(pos);
610 }
611 
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 }