List having non-virtual destructor fixed (thanks to Thomas Jarosch) Proposed subset...
[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 if (description.empty() && serial.empty())
85 ret = ftdi_usb_open(d->ftdi, vendor, product);
86 else
87 ret = ftdi_usb_open_desc(d->ftdi, vendor, product, description.c_str(), serial.c_str());
88
89 d->dev = usb_device(d->ftdi->usb_dev);
90
91 if ((ret = ftdi_usb_open_dev(d->ftdi, d->dev)) >= 0)
92 {
93 d->open = true;
94 get_strings();
95 }
96
97 return ret;
98}
99
100int Context::open(struct usb_device *dev)
101{
102 int ret = 0;
103
104 if (dev != 0)
105 d->dev = dev;
106
107 if (d->dev == 0)
108 return -1;
109
110 if ((ret = ftdi_usb_open_dev(d->ftdi, d->dev)) >= 0)
111 {
112 d->open = true;
113 get_strings();
114 }
115
116 return ret;
117}
118
119int Context::close()
120{
121 d->open = false;
122 return ftdi_usb_close(d->ftdi);
123}
124
125int Context::reset()
126{
127 return ftdi_usb_reset(d->ftdi);
128}
129
130int Context::flush(int mask)
131{
132 int ret = 1;
133
134 if (mask & Input)
135 ret &= ftdi_usb_purge_rx_buffer(d->ftdi);
136 if (mask & Output)
137 ret &= ftdi_usb_purge_tx_buffer(d->ftdi);
138
139 return ret;
140}
141
142int Context::set_interface(enum ftdi_interface interface)
143{
144 return ftdi_set_interface(d->ftdi, interface);
145}
146
147void Context::set_usb_device(struct usb_dev_handle *dev)
148{
149 ftdi_set_usbdev(d->ftdi, dev);
150 d->dev = usb_device(dev);
151}
152
153int Context::set_baud_rate(int baudrate)
154{
155 return ftdi_set_baudrate(d->ftdi, baudrate);
156}
157
158int Context::set_line_property(enum ftdi_bits_type bits, enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity)
159{
160 return ftdi_set_line_property(d->ftdi, bits, sbit, parity);
161}
162
163int 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)
164{
165 return ftdi_set_line_property2(d->ftdi, bits, sbit, parity, break_type);
166}
167
168int Context::read(unsigned char *buf, int size)
169{
170 return ftdi_read_data(d->ftdi, buf, size);
171}
172
173int Context::set_read_chunk_size(unsigned int chunksize)
174{
175 return ftdi_read_data_set_chunksize(d->ftdi, chunksize);
176}
177
178int Context::read_chunk_size()
179{
180 unsigned chunk = -1;
181 if (ftdi_read_data_get_chunksize(d->ftdi, &chunk) < 0)
182 return -1;
183
184 return chunk;
185}
186
187int Context::write(unsigned char *buf, int size)
188{
189 return ftdi_write_data(d->ftdi, buf, size);
190}
191
192int Context::set_write_chunk_size(unsigned int chunksize)
193{
194 return ftdi_write_data_set_chunksize(d->ftdi, chunksize);
195}
196
197int Context::write_chunk_size()
198{
199 unsigned chunk = -1;
200 if (ftdi_write_data_get_chunksize(d->ftdi, &chunk) < 0)
201 return -1;
202
203 return chunk;
204}
205
206int Context::set_flow_control(int flowctrl)
207{
208 return ftdi_setflowctrl(d->ftdi, flowctrl);
209}
210
211int Context::set_modem_control(int mask)
212{
213 int dtr = 0, rts = 0;
214
215 if (mask & Dtr)
216 dtr = 1;
217 if (mask & Rts)
218 rts = 1;
219
220 return ftdi_setdtr_rts(d->ftdi, dtr, rts);
221}
222
223int Context::set_dtr(bool state)
224{
225 return ftdi_setdtr(d->ftdi, state);
226}
227
228int Context::set_rts(bool state)
229{
230 return ftdi_setrts(d->ftdi, state);
231}
232
233int Context::set_latency(unsigned char latency)
234{
235 return ftdi_set_latency_timer(d->ftdi, latency);
236}
237
238unsigned Context::latency()
239{
240 unsigned char latency = 0;
241 ftdi_get_latency_timer(d->ftdi, &latency);
242 return latency;
243}
244
245unsigned short Context::poll_modem_status()
246{
247 unsigned short status = 0;
248 ftdi_poll_modem_status(d->ftdi, &status);
249 return status;
250}
251
252int Context::set_event_char(unsigned char eventch, unsigned char enable)
253{
254 return ftdi_set_event_char(d->ftdi, eventch, enable);
255}
256
257int Context::set_error_char(unsigned char errorch, unsigned char enable)
258{
259 return ftdi_set_error_char(d->ftdi, errorch, enable);
260}
261
262int Context::bitbang_enable(unsigned char bitmask)
263{
264 return ftdi_enable_bitbang(d->ftdi, bitmask);
265}
266
267int Context::bitbang_disable()
268{
269 return ftdi_disable_bitbang(d->ftdi);
270}
271
272int Context::set_bitmode(unsigned char bitmask, unsigned char mode)
273{
274 return ftdi_set_bitmode(d->ftdi, bitmask, mode);
275}
276
277int Context::read_pins(unsigned char *pins)
278{
279 return ftdi_read_pins(d->ftdi, pins);
280}
281
282char* Context::error_string()
283{
284 return ftdi_get_error_string(d->ftdi);
285}
286
287int Context::get_strings()
288{
289 // Prepare buffers
290 char vendor[512], desc[512], serial[512];
291
292 int ret = ftdi_usb_get_strings(d->ftdi, d->dev, vendor, 512, desc, 512, serial, 512);
293
294 if (ret < 0)
295 return -1;
296
297 d->vendor = vendor;
298 d->description = desc;
299 d->serial = serial;
300
301 return 1;
302}
303
304/*! \fn vendor
305 * \fn description
306 * \fn serial
307 * \brief Device strings properties.
308 */
309const std::string& Context::vendor()
310{
311 return d->vendor;
312}
313
314const std::string& Context::description()
315{
316 return d->description;
317}
318
319const std::string& Context::serial()
320{
321 return d->serial;
322}
323
324void Context::set_context(struct ftdi_context* context)
325{
326 ftdi_free(d->ftdi);
327 d->ftdi = context;
328}
329
330void Context::set_usb_device(struct usb_device *dev)
331{
332 d->dev = dev;
333}
334
335struct ftdi_context* Context::context()
336{
337 return d->ftdi;
338}
339
340class Eeprom::Private
341{
342public:
343 Private()
344 : context(0)
345 {}
346
347 struct ftdi_eeprom eeprom;
348 struct ftdi_context* context;
349};
350
351Eeprom::Eeprom(Context* parent)
352 : d ( new Private() )
353{
354 d->context = parent->context();
355}
356
357Eeprom::~Eeprom()
358{
359}
360
361void Eeprom::init_defaults()
362{
363 return ftdi_eeprom_initdefaults(&d->eeprom);
364}
365
366void Eeprom::set_size(int size)
367{
368 return ftdi_eeprom_setsize(d->context, &d->eeprom, size);
369}
370
371int Eeprom::size(unsigned char *eeprom, int maxsize)
372{
373 return ftdi_read_eeprom_getsize(d->context, eeprom, maxsize);
374}
375
376int Eeprom::chip_id(unsigned int *chipid)
377{
378 return ftdi_read_chipid(d->context, chipid);
379}
380
381int Eeprom::build(unsigned char *output)
382{
383 return ftdi_eeprom_build(&d->eeprom, output);
384}
385
386int Eeprom::read(unsigned char *eeprom)
387{
388 return ftdi_read_eeprom(d->context, eeprom);
389}
390
391int Eeprom::write(unsigned char *eeprom)
392{
393 return ftdi_write_eeprom(d->context, eeprom);
394}
395
396int Eeprom::erase()
397{
398 return ftdi_erase_eeprom(d->context);
399}
400
401class List::Private
402{
403public:
404 Private(struct ftdi_device_list* _devlist)
405 : devlist(_devlist)
406 {}
407
408 ~Private()
409 {
410 if(devlist)
411 ftdi_list_free(&devlist);
412 }
413
414 std::list<Context> list;
415 struct ftdi_device_list* devlist;
416};
417
418List::List(struct ftdi_device_list* devlist)
419 : d( new Private(devlist) )
420{
421 if (devlist != 0)
422 {
423 // Iterate list
424 for (; devlist != 0; devlist = devlist->next)
425 {
426 Context c;
427 c.set_usb_device(devlist->dev);
428 c.get_strings();
429 d->list.push_back(c);
430 }
431 }
432}
433
434List::~List()
435{
436}
437
438int List::size()
439{
440 return d->list.size();
441}
442
443void List::push_front(const Context& element)
444{
445 d->list.push_front(element);
446}
447
448
449void List::push_back(const Context& element)
450{
451 d->list.push_back(element);
452}
453
454void List::clear()
455{
456 d->list.clear();
457
458 // Free device list
459 ftdi_list_free(&d->devlist);
460 d->devlist = 0;
461}
462
463std::list<Context>::iterator List::begin()
464{
465 return d->list.begin();
466}
467
468std::list<Context>::iterator List::end()
469{
470 return d->list.end();
471}
472
473
474List* List::find_all(int vendor, int product)
475{
476 struct ftdi_device_list* dlist = 0;
477 struct ftdi_context ftdi;
478 ftdi_init(&ftdi);
479 ftdi_usb_find_all(&ftdi, &dlist, vendor, product);
480 ftdi_deinit(&ftdi);
481 return new List(dlist);
482}
483
484}