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