libftdi: (tomj) reformat according to I2n style, added copyright header and more...
[libftdi] / ftdipp / ftdi.cpp
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
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 "ftdi.hpp"
18 #include "ftdi.h"
19
20 namespace Ftdi
21 {
22
23 class Context::Private
24 {
25 public:
26     Private()
27         :  ftdi(0), dev(0), open(false)
28     {
29     }
30
31     bool open;
32
33     struct ftdi_context* ftdi;
34     struct usb_device*   dev;
35
36     std::string vendor;
37     std::string description;
38     std::string serial;
39 };
40
41 /*! \brief Constructor.
42  */
43 Context::Context()
44         : d( new Private() )
45 {
46     d->ftdi = ftdi_new();
47 }
48
49 /*! \brief Destructor.
50  */
51 Context::~Context()
52 {
53     if (d->open)
54         close();
55
56     ftdi_free(d->ftdi);
57     delete d;
58 }
59
60 bool Context::is_open()
61 {
62     return d->open;
63 }
64
65 int Context::open(int vendor, int product, const std::string& description, const std::string& serial)
66 {
67     int ret = 0;
68
69     if (description.empty() && serial.empty())
70         ret = ftdi_usb_open(d->ftdi, vendor, product);
71     else
72         ret = ftdi_usb_open_desc(d->ftdi, vendor, product, description.c_str(), serial.c_str());
73
74     d->dev = usb_device(d->ftdi->usb_dev);
75
76     if ((ret = ftdi_usb_open_dev(d->ftdi, d->dev)) >= 0)
77     {
78         d->open = true;
79         get_strings();
80     }
81
82     return ret;
83 }
84
85 int Context::open(struct usb_device *dev)
86 {
87     int ret = 0;
88
89     if (dev != 0)
90         d->dev = dev;
91
92     if (d->dev == 0)
93         return -1;
94
95     if ((ret = ftdi_usb_open_dev(d->ftdi, d->dev)) >= 0)
96     {
97         d->open = true;
98         get_strings();
99     }
100
101     return ret;
102 }
103
104 int Context::close()
105 {
106     d->open = false;
107     return ftdi_usb_close(d->ftdi);
108 }
109
110 int Context::reset()
111 {
112     return ftdi_usb_reset(d->ftdi);
113 }
114
115 int Context::flush(int mask)
116 {
117     int ret = 1;
118
119     if (mask & Input)
120         ret &= ftdi_usb_purge_rx_buffer(d->ftdi);
121     if (mask & Output)
122         ret &= ftdi_usb_purge_tx_buffer(d->ftdi);
123
124     return ret;
125 }
126
127 int Context::set_interface(enum ftdi_interface interface)
128 {
129     return ftdi_set_interface(d->ftdi, interface);
130 }
131
132 void Context::set_usb_device(struct usb_dev_handle *dev)
133 {
134     ftdi_set_usbdev(d->ftdi, dev);
135     d->dev = usb_device(dev);
136 }
137
138 int Context::set_baud_rate(int baudrate)
139 {
140     return ftdi_set_baudrate(d->ftdi, baudrate);
141 }
142
143 int Context::set_line_property(enum ftdi_bits_type bits, enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity)
144 {
145     return ftdi_set_line_property(d->ftdi, bits, sbit, parity);
146 }
147
148 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)
149 {
150     return ftdi_set_line_property2(d->ftdi, bits, sbit, parity, break_type);
151 }
152
153 int Context::read(unsigned char *buf, int size)
154 {
155     return ftdi_read_data(d->ftdi, buf, size);
156 }
157
158 int Context::set_read_chunk_size(unsigned int chunksize)
159 {
160     return ftdi_read_data_set_chunksize(d->ftdi, chunksize);
161 }
162
163 int Context::read_chunk_size()
164 {
165     unsigned chunk = -1;
166     if (ftdi_read_data_get_chunksize(d->ftdi, &chunk) < 0)
167         return -1;
168
169     return chunk;
170 }
171
172 int Context::write(unsigned char *buf, int size)
173 {
174     return ftdi_write_data(d->ftdi, buf, size);
175 }
176
177 int Context::set_write_chunk_size(unsigned int chunksize)
178 {
179     return ftdi_write_data_set_chunksize(d->ftdi, chunksize);
180 }
181
182 int Context::write_chunk_size()
183 {
184     unsigned chunk = -1;
185     if (ftdi_write_data_get_chunksize(d->ftdi, &chunk) < 0)
186         return -1;
187
188     return chunk;
189 }
190
191 int Context::set_flow_control(int flowctrl)
192 {
193     return ftdi_setflowctrl(d->ftdi, flowctrl);
194 }
195
196 int Context::set_modem_control(int mask)
197 {
198     int dtr = 0, rts = 0;
199
200     if (mask & Dtr)
201         dtr = 1;
202     if (mask & Rts)
203         rts = 1;
204
205     return ftdi_setdtr_rts(d->ftdi, dtr, rts);
206 }
207
208 int Context::set_dtr(bool state)
209 {
210     return ftdi_setdtr(d->ftdi, state);
211 }
212
213 int Context::set_rts(bool state)
214 {
215     return ftdi_setrts(d->ftdi, state);
216 }
217
218 int Context::set_latency(unsigned char latency)
219 {
220     return ftdi_set_latency_timer(d->ftdi, latency);
221 }
222
223 unsigned Context::latency()
224 {
225     unsigned char latency = 0;
226     ftdi_get_latency_timer(d->ftdi, &latency);
227     return latency;
228 }
229
230 unsigned short Context::poll_modem_status()
231 {
232     unsigned short status = 0;
233     ftdi_poll_modem_status(d->ftdi, &status);
234     return status;
235 }
236
237 int Context::set_event_char(unsigned char eventch, unsigned char enable)
238 {
239     return ftdi_set_event_char(d->ftdi, eventch, enable);
240 }
241
242 int Context::set_error_char(unsigned char errorch, unsigned char enable)
243 {
244     return ftdi_set_error_char(d->ftdi, errorch, enable);
245 }
246
247 int Context::bitbang_enable(unsigned char bitmask)
248 {
249     return ftdi_enable_bitbang(d->ftdi, bitmask);
250 }
251
252 int Context::bitbang_disable()
253 {
254     return ftdi_disable_bitbang(d->ftdi);
255 }
256
257 int Context::set_bitmode(unsigned char bitmask, unsigned char mode)
258 {
259     return ftdi_set_bitmode(d->ftdi, bitmask, mode);
260 }
261
262 int Context::read_pins(unsigned char *pins)
263 {
264     return ftdi_read_pins(d->ftdi, pins);
265 }
266
267 char* Context::error_string()
268 {
269     return ftdi_get_error_string(d->ftdi);
270 }
271
272 int Context::get_strings()
273 {
274     // Prepare buffers
275     char vendor[512], desc[512], serial[512];
276
277     int ret = ftdi_usb_get_strings(d->ftdi, d->dev, vendor, 512, desc, 512, serial, 512);
278
279     if (ret < 0)
280         return -1;
281
282     d->vendor = vendor;
283     d->description = desc;
284     d->serial = serial;
285
286     return 1;
287 }
288
289 /*! \fn vendor
290  * \fn description
291  * \fn serial
292  * \brief Device strings properties.
293  */
294 const std::string& Context::vendor()
295 {
296     return d->vendor;
297 }
298
299 const std::string& Context::description()
300 {
301     return d->description;
302 }
303
304 const std::string& Context::serial()
305 {
306     return d->serial;
307 }
308
309 void Context::set_context(struct ftdi_context* context)
310 {
311     ftdi_free(d->ftdi);
312     d->ftdi = context;
313 }
314
315 void Context::set_usb_device(struct usb_device *dev)
316 {
317     d->dev = dev;
318 }
319
320 struct ftdi_context* Context::context()
321 {
322     return d->ftdi;
323 }
324
325 class Eeprom::Private
326 {
327 public:
328     Private()
329             : context(0)
330     {}
331
332     struct ftdi_eeprom eeprom;
333     struct ftdi_context* context;
334 };
335
336 Eeprom::Eeprom(Context* parent)
337         : d ( new Private() )
338 {
339     d->context = parent->context();
340 }
341
342 Eeprom::~Eeprom()
343 {
344     delete d;
345 }
346
347 void Eeprom::init_defaults()
348 {
349     return ftdi_eeprom_initdefaults(&d->eeprom);
350 }
351
352 void Eeprom::set_size(int size)
353 {
354     return ftdi_eeprom_setsize(d->context, &d->eeprom, size);
355 }
356
357 int Eeprom::size(unsigned char *eeprom, int maxsize)
358 {
359     return ftdi_read_eeprom_getsize(d->context, eeprom, maxsize);
360 }
361
362 int Eeprom::chip_id(unsigned int *chipid)
363 {
364     return ftdi_read_chipid(d->context, chipid);
365 }
366
367 int Eeprom::build(unsigned char *output)
368 {
369     return ftdi_eeprom_build(&d->eeprom, output);
370 }
371
372 int Eeprom::read(unsigned char *eeprom)
373 {
374     return ftdi_read_eeprom(d->context, eeprom);
375 }
376
377 int Eeprom::write(unsigned char *eeprom)
378 {
379     return ftdi_write_eeprom(d->context, eeprom);
380 }
381
382 int Eeprom::erase()
383 {
384     return ftdi_erase_eeprom(d->context);
385 }
386
387 class List::Private
388 {
389 public:
390     Private()
391             : list(0)
392     {}
393
394     struct ftdi_device_list* list;
395 };
396
397 List::List(struct ftdi_device_list* devlist)
398         : ListBase(), d( new Private() )
399 {
400     if (devlist != 0)
401     {
402         // Iterate list
403         Context* c = 0;
404         for (d->list = devlist; d->list != 0; d->list = d->list->next)
405         {
406             c = new Context();
407             c->set_usb_device(d->list->dev);
408             push_back(c);
409         }
410
411         // Store pointer
412         d->list = devlist;
413     }
414 }
415
416 List::~List()
417 {
418     // Deallocate instances
419     for (iterator it = begin(); it != end(); it++)
420         delete *it;
421
422     // Clear list
423     clear();
424     ftdi_list_free(&d->list);
425
426     // Delete d-ptr
427     delete d;
428 }
429
430 List* List::find_all(int vendor, int product)
431 {
432     struct ftdi_device_list* dlist = 0;
433     struct ftdi_context ftdi;
434     ftdi_init(&ftdi);
435     ftdi_usb_find_all(&ftdi, &dlist, vendor, product);
436     ftdi_deinit(&ftdi);
437     return new List(dlist);
438 }
439
440 }