1 /***************************************************************************
2 ftdi.cpp - C++ wraper for libftdi
4 begin : Mon Oct 13 2008
5 copyright : (C) 2008-2014 by Marek Vavruša / libftdi developers
6 email : opensource@intra2net.com and marek@vavrusa.com
7 ***************************************************************************/
9 Copyright (C) 2008-2014 by Marek Vavruša / libftdi developers
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.
37 class Context::Private
41 : open(false), ftdi(0), dev(0)
56 struct ftdi_context* ftdi;
57 struct libusb_device* dev;
60 std::string description;
64 /*! \brief Constructor.
71 /*! \brief Destructor.
77 bool Context::is_open()
82 int Context::open(int vendor, int product)
85 int ret = ftdi_usb_open(d->ftdi, vendor, product);
90 return get_strings_and_reopen();
93 int Context::open(int vendor, int product, const std::string& description, const std::string& serial, unsigned int index)
95 // translate empty strings to NULL
96 // -> do not use them to find the device (vs. require an empty string to be set in the EEPROM)
97 const char* c_description=NULL;
98 const char* c_serial=NULL;
99 if (!description.empty())
100 c_description=description.c_str();
102 c_serial=serial.c_str();
104 int ret = ftdi_usb_open_desc_index(d->ftdi, vendor, product, c_description, c_serial, index);
109 return get_strings_and_reopen();
112 int Context::open(const std::string& description)
114 int ret = ftdi_usb_open_string(d->ftdi, description.c_str());
119 return get_strings_and_reopen();
122 int Context::open(struct libusb_device *dev)
130 return get_strings_and_reopen();
137 return ftdi_usb_close(d->ftdi);
142 return ftdi_usb_reset(d->ftdi);
145 int Context::flush(int mask)
150 ret &= ftdi_usb_purge_rx_buffer(d->ftdi);
152 ret &= ftdi_usb_purge_tx_buffer(d->ftdi);
157 int Context::set_interface(enum ftdi_interface interface)
159 return ftdi_set_interface(d->ftdi, interface);
162 void Context::set_usb_device(struct libusb_device_handle *dev)
164 ftdi_set_usbdev(d->ftdi, dev);
165 d->dev = libusb_get_device(dev);
168 int Context::set_baud_rate(int baudrate)
170 return ftdi_set_baudrate(d->ftdi, baudrate);
173 int Context::set_line_property(enum ftdi_bits_type bits, enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity)
175 return ftdi_set_line_property(d->ftdi, bits, sbit, parity);
178 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)
180 return ftdi_set_line_property2(d->ftdi, bits, sbit, parity, break_type);
183 int Context::get_usb_read_timeout() const
185 return d->ftdi->usb_read_timeout;
188 void Context::set_usb_read_timeout(int usb_read_timeout)
190 d->ftdi->usb_read_timeout = usb_read_timeout;
193 int Context::get_usb_write_timeout() const
195 return d->ftdi->usb_write_timeout;
198 void Context::set_usb_write_timeout(int usb_write_timeout)
200 d->ftdi->usb_write_timeout = usb_write_timeout;
203 int Context::read(unsigned char *buf, int size)
205 return ftdi_read_data(d->ftdi, buf, size);
208 int Context::set_read_chunk_size(unsigned int chunksize)
210 return ftdi_read_data_set_chunksize(d->ftdi, chunksize);
213 int Context::read_chunk_size()
216 if (ftdi_read_data_get_chunksize(d->ftdi, &chunk) < 0)
222 int Context::write(unsigned char *buf, int size)
224 return ftdi_write_data(d->ftdi, buf, size);
227 int Context::set_write_chunk_size(unsigned int chunksize)
229 return ftdi_write_data_set_chunksize(d->ftdi, chunksize);
232 int Context::write_chunk_size()
235 if (ftdi_write_data_get_chunksize(d->ftdi, &chunk) < 0)
241 int Context::set_flow_control(int flowctrl)
243 return ftdi_setflowctrl(d->ftdi, flowctrl);
246 int Context::set_modem_control(int mask)
248 int dtr = 0, rts = 0;
255 return ftdi_setdtr_rts(d->ftdi, dtr, rts);
258 int Context::set_dtr(bool state)
260 return ftdi_setdtr(d->ftdi, state);
263 int Context::set_rts(bool state)
265 return ftdi_setrts(d->ftdi, state);
268 int Context::set_latency(unsigned char latency)
270 return ftdi_set_latency_timer(d->ftdi, latency);
273 unsigned Context::latency()
275 unsigned char latency = 0;
276 ftdi_get_latency_timer(d->ftdi, &latency);
280 unsigned short Context::poll_modem_status()
282 unsigned short status = 0;
283 ftdi_poll_modem_status(d->ftdi, &status);
287 int Context::set_event_char(unsigned char eventch, unsigned char enable)
289 return ftdi_set_event_char(d->ftdi, eventch, enable);
292 int Context::set_error_char(unsigned char errorch, unsigned char enable)
294 return ftdi_set_error_char(d->ftdi, errorch, enable);
297 int Context::set_bitmode(unsigned char bitmask, unsigned char mode)
299 return ftdi_set_bitmode(d->ftdi, bitmask, mode);
302 int Context::set_bitmode(unsigned char bitmask, enum ftdi_mpsse_mode mode)
304 return ftdi_set_bitmode(d->ftdi, bitmask, mode);
307 int Context::bitbang_disable()
309 return ftdi_disable_bitbang(d->ftdi);
312 int Context::read_pins(unsigned char *pins)
314 return ftdi_read_pins(d->ftdi, pins);
317 char* Context::error_string()
319 return ftdi_get_error_string(d->ftdi);
322 int Context::get_strings()
325 char vendor[512], desc[512], serial[512];
327 int ret = ftdi_usb_get_strings(d->ftdi, d->dev, vendor, 512, desc, 512, serial, 512);
333 d->description = desc;
339 int Context::get_strings_and_reopen()
343 d->dev = libusb_get_device(d->ftdi->usb_dev);
346 // Get device strings (closes device)
347 int ret=get_strings();
355 ret = ftdi_usb_open_dev(d->ftdi, d->dev);
356 d->open = (ret >= 0);
361 /*! \brief Device strings properties.
363 const std::string& Context::vendor()
368 /*! \brief Device strings properties.
370 const std::string& Context::description()
372 return d->description;
375 /*! \brief Device strings properties.
377 const std::string& Context::serial()
382 void Context::set_context(struct ftdi_context* context)
388 void Context::set_usb_device(struct libusb_device *dev)
393 struct ftdi_context* Context::context()
398 class Eeprom::Private
405 struct ftdi_eeprom eeprom;
406 struct ftdi_context* context;
409 Eeprom::Eeprom(Context* parent)
410 : d ( new Private() )
412 d->context = parent->context();
419 int Eeprom::init_defaults(char* manufacturer, char *product, char * serial)
421 return ftdi_eeprom_initdefaults(d->context, manufacturer, product, serial);
424 int Eeprom::chip_id(unsigned int *chipid)
426 return ftdi_read_chipid(d->context, chipid);
429 int Eeprom::build(unsigned char *output)
431 return ftdi_eeprom_build(d->context);
434 int Eeprom::read(unsigned char *eeprom)
436 return ftdi_read_eeprom(d->context);
439 int Eeprom::write(unsigned char *eeprom)
441 return ftdi_write_eeprom(d->context);
444 int Eeprom::read_location(int eeprom_addr, unsigned short *eeprom_val)
446 return ftdi_read_eeprom_location(d->context, eeprom_addr, eeprom_val);
449 int Eeprom::write_location(int eeprom_addr, unsigned short eeprom_val)
451 return ftdi_write_eeprom_location(d->context, eeprom_addr, eeprom_val);
456 return ftdi_erase_eeprom(d->context);
462 Private(struct ftdi_device_list* _devlist)
469 ftdi_list_free(&devlist);
472 std::list<Context> list;
473 struct ftdi_device_list* devlist;
476 List::List(struct ftdi_device_list* devlist)
477 : d( new Private(devlist) )
482 for (; devlist != 0; devlist = devlist->next)
485 c.set_usb_device(devlist->dev);
487 d->list.push_back(c);
497 * Return begin iterator for accessing the contained list elements
500 List::iterator List::begin()
502 return d->list.begin();
506 * Return end iterator for accessing the contained list elements
509 List::iterator List::end()
511 return d->list.end();
515 * Return begin iterator for accessing the contained list elements
516 * @return Const iterator
518 List::const_iterator List::begin() const
520 return d->list.begin();
524 * Return end iterator for accessing the contained list elements
525 * @return Const iterator
527 List::const_iterator List::end() const
529 return d->list.end();
533 * Return begin reverse iterator for accessing the contained list elements
534 * @return Reverse iterator
536 List::reverse_iterator List::rbegin()
538 return d->list.rbegin();
542 * Return end reverse iterator for accessing the contained list elements
543 * @return Reverse iterator
545 List::reverse_iterator List::rend()
547 return d->list.rend();
551 * Return begin reverse iterator for accessing the contained list elements
552 * @return Const reverse iterator
554 List::const_reverse_iterator List::rbegin() const
556 return d->list.rbegin();
560 * Return end reverse iterator for accessing the contained list elements
561 * @return Const reverse iterator
563 List::const_reverse_iterator List::rend() const
565 return d->list.rend();
570 * Get number of elements stored in the list
571 * @return Number of elements
573 List::ListType::size_type List::size() const
575 return d->list.size();
579 * Check if list is empty
580 * @return True if empty, false otherwise
582 bool List::empty() const
584 return d->list.empty();
588 * Removes all elements. Invalidates all iterators.
589 * Do it in a non-throwing way and also make
590 * sure we really free the allocated memory.
594 ListType().swap(d->list);
599 ftdi_list_free(&d->devlist);
605 * Appends a copy of the element as the new last element.
606 * @param element Value to copy and append
608 void List::push_back(const Context& element)
610 d->list.push_back(element);
614 * Adds a copy of the element as the new first element.
615 * @param element Value to copy and add
617 void List::push_front(const Context& element)
619 d->list.push_front(element);
623 * Erase one element pointed by iterator
624 * @param pos Element to erase
625 * @return Position of the following element (or end())
627 List::iterator List::erase(iterator pos)
629 return d->list.erase(pos);
633 * Erase a range of elements
634 * @param beg Begin of range
635 * @param end End of range
636 * @return Position of the element after the erased range (or end())
638 List::iterator List::erase(iterator beg, iterator end)
640 return d->list.erase(beg, end);
643 List* List::find_all(Context &context, int vendor, int product)
645 struct ftdi_device_list* dlist = 0;
646 ftdi_usb_find_all(context.context(), &dlist, vendor, product);
647 return new List(dlist);