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.
36 class Context::Private
40 : open(false), ftdi(0), dev(0)
55 struct ftdi_context* ftdi;
56 struct libusb_device* dev;
59 std::string description;
63 /*! \brief Constructor.
70 /*! \brief Destructor.
76 bool Context::is_open()
81 int Context::open(int vendor, int product)
84 int ret = ftdi_usb_open(d->ftdi, vendor, product);
89 return get_strings_and_reopen();
92 int Context::open(int vendor, int product, const std::string& description, const std::string& serial, unsigned int index)
94 // translate empty strings to NULL
95 // -> do not use them to find the device (vs. require an empty string to be set in the EEPROM)
96 const char* c_description=NULL;
97 const char* c_serial=NULL;
98 if (!description.empty())
99 c_description=description.c_str();
101 c_serial=serial.c_str();
103 int ret = ftdi_usb_open_desc_index(d->ftdi, vendor, product, c_description, c_serial, index);
108 return get_strings_and_reopen();
111 int Context::open(const std::string& description)
113 int ret = ftdi_usb_open_string(d->ftdi, description.c_str());
118 return get_strings_and_reopen();
121 int Context::open(struct libusb_device *dev)
129 return get_strings_and_reopen();
136 return ftdi_usb_close(d->ftdi);
141 return ftdi_usb_reset(d->ftdi);
144 int Context::flush(int mask)
149 ret &= ftdi_usb_purge_rx_buffer(d->ftdi);
151 ret &= ftdi_usb_purge_tx_buffer(d->ftdi);
156 int Context::set_interface(enum ftdi_interface interface)
158 return ftdi_set_interface(d->ftdi, interface);
161 void Context::set_usb_device(struct libusb_device_handle *dev)
163 ftdi_set_usbdev(d->ftdi, dev);
164 d->dev = libusb_get_device(dev);
167 int Context::set_baud_rate(int baudrate)
169 return ftdi_set_baudrate(d->ftdi, baudrate);
172 int Context::set_line_property(enum ftdi_bits_type bits, enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity)
174 return ftdi_set_line_property(d->ftdi, bits, sbit, parity);
177 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)
179 return ftdi_set_line_property2(d->ftdi, bits, sbit, parity, break_type);
182 int Context::read(unsigned char *buf, int size)
184 return ftdi_read_data(d->ftdi, buf, size);
187 int Context::set_read_chunk_size(unsigned int chunksize)
189 return ftdi_read_data_set_chunksize(d->ftdi, chunksize);
192 int Context::read_chunk_size()
195 if (ftdi_read_data_get_chunksize(d->ftdi, &chunk) < 0)
201 int Context::write(unsigned char *buf, int size)
203 return ftdi_write_data(d->ftdi, buf, size);
206 int Context::set_write_chunk_size(unsigned int chunksize)
208 return ftdi_write_data_set_chunksize(d->ftdi, chunksize);
211 int Context::write_chunk_size()
214 if (ftdi_write_data_get_chunksize(d->ftdi, &chunk) < 0)
220 int Context::set_flow_control(int flowctrl)
222 return ftdi_setflowctrl(d->ftdi, flowctrl);
225 int Context::set_modem_control(int mask)
227 int dtr = 0, rts = 0;
234 return ftdi_setdtr_rts(d->ftdi, dtr, rts);
237 int Context::set_dtr(bool state)
239 return ftdi_setdtr(d->ftdi, state);
242 int Context::set_rts(bool state)
244 return ftdi_setrts(d->ftdi, state);
247 int Context::set_latency(unsigned char latency)
249 return ftdi_set_latency_timer(d->ftdi, latency);
252 unsigned Context::latency()
254 unsigned char latency = 0;
255 ftdi_get_latency_timer(d->ftdi, &latency);
259 unsigned short Context::poll_modem_status()
261 unsigned short status = 0;
262 ftdi_poll_modem_status(d->ftdi, &status);
266 int Context::set_event_char(unsigned char eventch, unsigned char enable)
268 return ftdi_set_event_char(d->ftdi, eventch, enable);
271 int Context::set_error_char(unsigned char errorch, unsigned char enable)
273 return ftdi_set_error_char(d->ftdi, errorch, enable);
276 int Context::set_bitmode(unsigned char bitmask, unsigned char mode)
278 return ftdi_set_bitmode(d->ftdi, bitmask, mode);
281 int Context::set_bitmode(unsigned char bitmask, enum ftdi_mpsse_mode mode)
283 return ftdi_set_bitmode(d->ftdi, bitmask, mode);
286 int Context::bitbang_disable()
288 return ftdi_disable_bitbang(d->ftdi);
291 int Context::read_pins(unsigned char *pins)
293 return ftdi_read_pins(d->ftdi, pins);
296 char* Context::error_string()
298 return ftdi_get_error_string(d->ftdi);
301 int Context::get_strings()
304 char vendor[512], desc[512], serial[512];
306 int ret = ftdi_usb_get_strings(d->ftdi, d->dev, vendor, 512, desc, 512, serial, 512);
312 d->description = desc;
318 int Context::get_strings_and_reopen()
322 d->dev = libusb_get_device(d->ftdi->usb_dev);
325 // Get device strings (closes device)
326 int ret=get_strings();
334 ret = ftdi_usb_open_dev(d->ftdi, d->dev);
335 d->open = (ret >= 0);
340 /*! \brief Device strings properties.
342 const std::string& Context::vendor()
347 /*! \brief Device strings properties.
349 const std::string& Context::description()
351 return d->description;
354 /*! \brief Device strings properties.
356 const std::string& Context::serial()
361 void Context::set_context(struct ftdi_context* context)
367 void Context::set_usb_device(struct libusb_device *dev)
372 struct ftdi_context* Context::context()
377 class Eeprom::Private
384 struct ftdi_eeprom eeprom;
385 struct ftdi_context* context;
388 Eeprom::Eeprom(Context* parent)
389 : d ( new Private() )
391 d->context = parent->context();
398 int Eeprom::init_defaults(char* manufacturer, char *product, char * serial)
400 return ftdi_eeprom_initdefaults(d->context, manufacturer, product, serial);
403 int Eeprom::chip_id(unsigned int *chipid)
405 return ftdi_read_chipid(d->context, chipid);
408 int Eeprom::build(unsigned char *output)
410 return ftdi_eeprom_build(d->context);
413 int Eeprom::read(unsigned char *eeprom)
415 return ftdi_read_eeprom(d->context);
418 int Eeprom::write(unsigned char *eeprom)
420 return ftdi_write_eeprom(d->context);
423 int Eeprom::read_location(int eeprom_addr, unsigned short *eeprom_val)
425 return ftdi_read_eeprom_location(d->context, eeprom_addr, eeprom_val);
428 int Eeprom::write_location(int eeprom_addr, unsigned short eeprom_val)
430 return ftdi_write_eeprom_location(d->context, eeprom_addr, eeprom_val);
435 return ftdi_erase_eeprom(d->context);
441 Private(struct ftdi_device_list* _devlist)
448 ftdi_list_free(&devlist);
451 std::list<Context> list;
452 struct ftdi_device_list* devlist;
455 List::List(struct ftdi_device_list* devlist)
456 : d( new Private(devlist) )
461 for (; devlist != 0; devlist = devlist->next)
464 c.set_usb_device(devlist->dev);
466 d->list.push_back(c);
476 * Return begin iterator for accessing the contained list elements
479 List::iterator List::begin()
481 return d->list.begin();
485 * Return end iterator for accessing the contained list elements
488 List::iterator List::end()
490 return d->list.end();
494 * Return begin iterator for accessing the contained list elements
495 * @return Const iterator
497 List::const_iterator List::begin() const
499 return d->list.begin();
503 * Return end iterator for accessing the contained list elements
504 * @return Const iterator
506 List::const_iterator List::end() const
508 return d->list.end();
512 * Return begin reverse iterator for accessing the contained list elements
513 * @return Reverse iterator
515 List::reverse_iterator List::rbegin()
517 return d->list.rbegin();
521 * Return end reverse iterator for accessing the contained list elements
522 * @return Reverse iterator
524 List::reverse_iterator List::rend()
526 return d->list.rend();
530 * Return begin reverse iterator for accessing the contained list elements
531 * @return Const reverse iterator
533 List::const_reverse_iterator List::rbegin() const
535 return d->list.rbegin();
539 * Return end reverse iterator for accessing the contained list elements
540 * @return Const reverse iterator
542 List::const_reverse_iterator List::rend() const
544 return d->list.rend();
549 * Get number of elements stored in the list
550 * @return Number of elements
552 List::ListType::size_type List::size() const
554 return d->list.size();
558 * Check if list is empty
559 * @return True if empty, false otherwise
561 bool List::empty() const
563 return d->list.empty();
567 * Removes all elements. Invalidates all iterators.
568 * Do it in a non-throwing way and also make
569 * sure we really free the allocated memory.
573 ListType().swap(d->list);
578 ftdi_list_free(&d->devlist);
584 * Appends a copy of the element as the new last element.
585 * @param element Value to copy and append
587 void List::push_back(const Context& element)
589 d->list.push_back(element);
593 * Adds a copy of the element as the new first element.
594 * @param element Value to copy and add
596 void List::push_front(const Context& element)
598 d->list.push_front(element);
602 * Erase one element pointed by iterator
603 * @param pos Element to erase
604 * @return Position of the following element (or end())
606 List::iterator List::erase(iterator pos)
608 return d->list.erase(pos);
612 * Erase a range of elements
613 * @param beg Begin of range
614 * @param end End of range
615 * @return Position of the element after the erased range (or end())
617 List::iterator List::erase(iterator beg, iterator end)
619 return d->list.erase(beg, end);
622 List* List::find_all(int vendor, int product)
624 struct ftdi_device_list* dlist = 0;
625 struct ftdi_context ftdi;
627 ftdi_usb_find_all(&ftdi, &dlist, vendor, product);
629 return new List(dlist);