1 /***************************************************************************
2 ftdi.cpp - C++ wraper for libftdi
4 begin : Mon Oct 13 2008
5 copyright : (C) 2008 by Marek Vavruša
6 email : opensource@intra2net.com and marek@vavrusa.com
7 ***************************************************************************/
9 Copyright (C) 2008 by Marek Vavruša
11 The software in this package is distributed under the GNU General
12 Public License version 2 (with a special exception described below).
14 A copy of GNU General Public License (GPL) is included in this distribution,
15 in the file COPYING.GPL.
17 As a special exception, if other files instantiate templates or use macros
18 or inline functions from this file, or you compile this file and link it
19 with other works to produce a work based on this file, this file
20 does not by itself cause the resulting work to be covered
21 by the GNU General Public License.
23 However the source code for this file must still be made available
24 in accordance with section (3) of the GNU General Public License.
26 This exception does not invalidate any other reasons why a work based
27 on this file might be covered by the GNU General Public License.
35 class Context::Private
39 : ftdi(0), dev(0), open(false)
54 struct ftdi_context* ftdi;
55 struct usb_device* dev;
58 std::string description;
62 /*! \brief Constructor.
69 /*! \brief Destructor.
75 bool Context::is_open()
80 int Context::open(int vendor, int product, const std::string& description, const std::string& serial)
84 if (description.empty() && serial.empty())
85 ret = ftdi_usb_open(d->ftdi, vendor, product);
87 ret = ftdi_usb_open_desc(d->ftdi, vendor, product, description.c_str(), serial.c_str());
89 d->dev = usb_device(d->ftdi->usb_dev);
91 if ((ret = ftdi_usb_open_dev(d->ftdi, d->dev)) >= 0)
100 int Context::open(struct usb_device *dev)
110 if ((ret = ftdi_usb_open_dev(d->ftdi, d->dev)) >= 0)
122 return ftdi_usb_close(d->ftdi);
127 return ftdi_usb_reset(d->ftdi);
130 int Context::flush(int mask)
135 ret &= ftdi_usb_purge_rx_buffer(d->ftdi);
137 ret &= ftdi_usb_purge_tx_buffer(d->ftdi);
142 int Context::set_interface(enum ftdi_interface interface)
144 return ftdi_set_interface(d->ftdi, interface);
147 void Context::set_usb_device(struct usb_dev_handle *dev)
149 ftdi_set_usbdev(d->ftdi, dev);
150 d->dev = usb_device(dev);
153 int Context::set_baud_rate(int baudrate)
155 return ftdi_set_baudrate(d->ftdi, baudrate);
158 int Context::set_line_property(enum ftdi_bits_type bits, enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity)
160 return ftdi_set_line_property(d->ftdi, bits, sbit, parity);
163 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)
165 return ftdi_set_line_property2(d->ftdi, bits, sbit, parity, break_type);
168 int Context::read(unsigned char *buf, int size)
170 return ftdi_read_data(d->ftdi, buf, size);
173 int Context::set_read_chunk_size(unsigned int chunksize)
175 return ftdi_read_data_set_chunksize(d->ftdi, chunksize);
178 int Context::read_chunk_size()
181 if (ftdi_read_data_get_chunksize(d->ftdi, &chunk) < 0)
187 int Context::write(unsigned char *buf, int size)
189 return ftdi_write_data(d->ftdi, buf, size);
192 int Context::set_write_chunk_size(unsigned int chunksize)
194 return ftdi_write_data_set_chunksize(d->ftdi, chunksize);
197 int Context::write_chunk_size()
200 if (ftdi_write_data_get_chunksize(d->ftdi, &chunk) < 0)
206 int Context::set_flow_control(int flowctrl)
208 return ftdi_setflowctrl(d->ftdi, flowctrl);
211 int Context::set_modem_control(int mask)
213 int dtr = 0, rts = 0;
220 return ftdi_setdtr_rts(d->ftdi, dtr, rts);
223 int Context::set_dtr(bool state)
225 return ftdi_setdtr(d->ftdi, state);
228 int Context::set_rts(bool state)
230 return ftdi_setrts(d->ftdi, state);
233 int Context::set_latency(unsigned char latency)
235 return ftdi_set_latency_timer(d->ftdi, latency);
238 unsigned Context::latency()
240 unsigned char latency = 0;
241 ftdi_get_latency_timer(d->ftdi, &latency);
245 unsigned short Context::poll_modem_status()
247 unsigned short status = 0;
248 ftdi_poll_modem_status(d->ftdi, &status);
252 int Context::set_event_char(unsigned char eventch, unsigned char enable)
254 return ftdi_set_event_char(d->ftdi, eventch, enable);
257 int Context::set_error_char(unsigned char errorch, unsigned char enable)
259 return ftdi_set_error_char(d->ftdi, errorch, enable);
262 int Context::bitbang_enable(unsigned char bitmask)
264 return ftdi_enable_bitbang(d->ftdi, bitmask);
267 int Context::bitbang_disable()
269 return ftdi_disable_bitbang(d->ftdi);
272 int Context::set_bitmode(unsigned char bitmask, unsigned char mode)
274 return ftdi_set_bitmode(d->ftdi, bitmask, mode);
277 int Context::read_pins(unsigned char *pins)
279 return ftdi_read_pins(d->ftdi, pins);
282 char* Context::error_string()
284 return ftdi_get_error_string(d->ftdi);
287 int Context::get_strings()
290 char vendor[512], desc[512], serial[512];
292 int ret = ftdi_usb_get_strings(d->ftdi, d->dev, vendor, 512, desc, 512, serial, 512);
298 d->description = desc;
307 * \brief Device strings properties.
309 const std::string& Context::vendor()
314 const std::string& Context::description()
316 return d->description;
319 const std::string& Context::serial()
324 void Context::set_context(struct ftdi_context* context)
330 void Context::set_usb_device(struct usb_device *dev)
335 struct ftdi_context* Context::context()
340 class Eeprom::Private
347 struct ftdi_eeprom eeprom;
348 struct ftdi_context* context;
351 Eeprom::Eeprom(Context* parent)
352 : d ( new Private() )
354 d->context = parent->context();
361 void Eeprom::init_defaults()
363 return ftdi_eeprom_initdefaults(&d->eeprom);
366 void Eeprom::set_size(int size)
368 return ftdi_eeprom_setsize(d->context, &d->eeprom, size);
371 int Eeprom::size(unsigned char *eeprom, int maxsize)
373 return ftdi_read_eeprom_getsize(d->context, eeprom, maxsize);
376 int Eeprom::chip_id(unsigned int *chipid)
378 return ftdi_read_chipid(d->context, chipid);
381 int Eeprom::build(unsigned char *output)
383 return ftdi_eeprom_build(&d->eeprom, output);
386 int Eeprom::read(unsigned char *eeprom)
388 return ftdi_read_eeprom(d->context, eeprom);
391 int Eeprom::write(unsigned char *eeprom)
393 return ftdi_write_eeprom(d->context, eeprom);
398 return ftdi_erase_eeprom(d->context);
404 Private(struct ftdi_device_list* _devlist)
411 ftdi_list_free(&devlist);
414 std::list<Context> list;
415 struct ftdi_device_list* devlist;
418 List::List(struct ftdi_device_list* devlist)
419 : d( new Private(devlist) )
424 for (; devlist != 0; devlist = devlist->next)
427 c.set_usb_device(devlist->dev);
429 d->list.push_back(c);
439 * Return begin iterator for accessing the contained list elements
442 List::iterator List::begin()
444 return d->list.begin();
448 * Return end iterator for accessing the contained list elements
451 List::iterator List::end()
453 return d->list.end();
457 * Return begin iterator for accessing the contained list elements
458 * @return Const iterator
460 List::const_iterator List::begin() const
462 return d->list.begin();
466 * Return end iterator for accessing the contained list elements
467 * @return Const iterator
469 List::const_iterator List::end() const
471 return d->list.end();
475 * Return begin reverse iterator for accessing the contained list elements
476 * @return Reverse iterator
478 List::reverse_iterator List::rbegin()
480 return d->list.rbegin();
484 * Return end reverse iterator for accessing the contained list elements
485 * @return Reverse iterator
487 List::reverse_iterator List::rend()
489 return d->list.rend();
493 * Return begin reverse iterator for accessing the contained list elements
494 * @return Const reverse iterator
496 List::const_reverse_iterator List::rbegin() const
498 return d->list.rbegin();
502 * Return end reverse iterator for accessing the contained list elements
503 * @return Const reverse iterator
505 List::const_reverse_iterator List::rend() const
507 return d->list.rend();
512 * Get number of elements stored in the list
513 * @return Number of elements
515 List::ListType::size_type List::size() const
517 return d->list.size();
521 * Check if list is empty
522 * @return True if empty, false otherwise
524 bool List::empty() const
526 return d->list.empty();
530 * Removes all elements. Invalidates all iterators.
531 * Do it in a non-throwing way and also make
532 * sure we really free the allocated memory.
536 ListType().swap(d->list);
541 ftdi_list_free(&d->devlist);
547 * Appends a copy of the element as the new last element.
548 * @param element Value to copy and append
550 void List::push_back(const Context& element)
552 d->list.push_back(element);
556 * Adds a copy of the element as the new first element.
557 * @param element Value to copy and add
559 void List::push_front(const Context& element)
561 d->list.push_front(element);
565 * Erase one element pointed by iterator
566 * @param pos Element to erase
567 * @return Position of the following element (or end())
569 List::iterator List::erase(iterator pos)
571 return d->list.erase(pos);
575 * Erase a range of elements
576 * @param beg Begin of range
577 * @param end End of range
578 * @return Position of the element after the erased range (or end())
580 List::iterator List::erase(iterator beg, iterator end)
582 return d->list.erase(beg, end);
585 List* List::find_all(int vendor, int product)
587 struct ftdi_device_list* dlist = 0;
588 struct ftdi_context ftdi;
590 ftdi_usb_find_all(&ftdi, &dlist, vendor, product);
592 return new List(dlist);