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