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