1 /***************************************************************************
2 ftdi.cpp - C++ wraper for libftdi
4 begin : Mon Oct 13 2008
5 copyright : (C) 2008-2017 by Marek Vavruša / libftdi developers
6 email : opensource@intra2net.com and marek@vavrusa.com
7 ***************************************************************************/
9 Copyright (C) 2008-2017 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(false,false,false);
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(false,description.empty(),serial.empty());
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(false,true,false);
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)
149 switch (mask & (Input | Output)) {
151 ret = ftdi_usb_purge_rx_buffer(d->ftdi);
155 ret = ftdi_usb_purge_tx_buffer(d->ftdi);
159 ret = ftdi_usb_purge_buffers(d->ftdi);
163 // Emulate behavior of previous version.
171 int Context::set_interface(enum ftdi_interface interface)
173 return ftdi_set_interface(d->ftdi, interface);
176 void Context::set_usb_device(struct libusb_device_handle *dev)
178 ftdi_set_usbdev(d->ftdi, dev);
179 d->dev = libusb_get_device(dev);
182 int Context::set_baud_rate(int baudrate)
184 return ftdi_set_baudrate(d->ftdi, baudrate);
187 int Context::set_line_property(enum ftdi_bits_type bits, enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity)
189 return ftdi_set_line_property(d->ftdi, bits, sbit, parity);
192 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)
194 return ftdi_set_line_property2(d->ftdi, bits, sbit, parity, break_type);
197 int Context::get_usb_read_timeout() const
199 return d->ftdi->usb_read_timeout;
202 void Context::set_usb_read_timeout(int usb_read_timeout)
204 d->ftdi->usb_read_timeout = usb_read_timeout;
207 int Context::get_usb_write_timeout() const
209 return d->ftdi->usb_write_timeout;
212 void Context::set_usb_write_timeout(int usb_write_timeout)
214 d->ftdi->usb_write_timeout = usb_write_timeout;
217 int Context::read(unsigned char *buf, int size)
219 return ftdi_read_data(d->ftdi, buf, size);
222 int Context::set_read_chunk_size(unsigned int chunksize)
224 return ftdi_read_data_set_chunksize(d->ftdi, chunksize);
227 int Context::read_chunk_size()
230 if (ftdi_read_data_get_chunksize(d->ftdi, &chunk) < 0)
236 int Context::write(const unsigned char *buf, int size)
238 return ftdi_write_data(d->ftdi, buf, size);
241 int Context::set_write_chunk_size(unsigned int chunksize)
243 return ftdi_write_data_set_chunksize(d->ftdi, chunksize);
246 int Context::write_chunk_size()
249 if (ftdi_write_data_get_chunksize(d->ftdi, &chunk) < 0)
255 int Context::set_flow_control(int flowctrl)
257 return ftdi_setflowctrl(d->ftdi, flowctrl);
260 int Context::set_modem_control(int mask)
262 int dtr = 0, rts = 0;
269 return ftdi_setdtr_rts(d->ftdi, dtr, rts);
272 int Context::set_dtr(bool state)
274 return ftdi_setdtr(d->ftdi, state);
277 int Context::set_rts(bool state)
279 return ftdi_setrts(d->ftdi, state);
282 int Context::set_latency(unsigned char latency)
284 return ftdi_set_latency_timer(d->ftdi, latency);
287 unsigned Context::latency()
289 unsigned char latency = 0;
290 ftdi_get_latency_timer(d->ftdi, &latency);
294 unsigned short Context::poll_modem_status()
296 unsigned short status = 0;
297 ftdi_poll_modem_status(d->ftdi, &status);
301 int Context::set_event_char(unsigned char eventch, unsigned char enable)
303 return ftdi_set_event_char(d->ftdi, eventch, enable);
306 int Context::set_error_char(unsigned char errorch, unsigned char enable)
308 return ftdi_set_error_char(d->ftdi, errorch, enable);
311 int Context::set_bitmode(unsigned char bitmask, unsigned char mode)
313 return ftdi_set_bitmode(d->ftdi, bitmask, mode);
316 int Context::set_bitmode(unsigned char bitmask, enum ftdi_mpsse_mode mode)
318 return ftdi_set_bitmode(d->ftdi, bitmask, mode);
321 int Context::bitbang_disable()
323 return ftdi_disable_bitbang(d->ftdi);
326 int Context::read_pins(unsigned char *pins)
328 return ftdi_read_pins(d->ftdi, pins);
331 const char* Context::error_string()
333 return ftdi_get_error_string(d->ftdi);
336 int Context::get_strings(bool vendor, bool description, bool serial)
339 char ivendor[512], idesc[512], iserial[512];
341 int ret = ftdi_usb_get_strings(d->ftdi, d->dev, vendor?ivendor:NULL, 512, description?idesc:NULL, 512, serial?iserial:NULL, 512);
347 d->description = idesc;
353 int Context::get_strings_and_reopen(bool vendor, bool description, bool serial)
357 if(vendor || description || serial)
361 d->dev = libusb_get_device(d->ftdi->usb_dev);
364 // Get device strings (closes device)
365 ret=get_strings(vendor, description, serial);
373 ret = ftdi_usb_open_dev(d->ftdi, d->dev);
374 d->open = (ret >= 0);
380 /*! \brief Device strings properties.
382 const std::string& Context::vendor()
384 if(d->vendor.empty())
385 get_strings_and_reopen(true,false,false);
389 /*! \brief Device strings properties.
391 const std::string& Context::description()
393 if(d->description.empty())
394 get_strings_and_reopen(false,true,false);
395 return d->description;
398 /*! \brief Device strings properties.
400 const std::string& Context::serial()
402 if(d->serial.empty())
403 get_strings_and_reopen(false,false,true);
407 void Context::set_context(struct ftdi_context* context)
413 void Context::set_usb_device(struct libusb_device *dev)
418 struct ftdi_context* Context::context()
423 class Eeprom::Private
430 struct ftdi_eeprom eeprom;
431 struct ftdi_context* context;
434 Eeprom::Eeprom(Context* parent)
435 : d ( new Private() )
437 d->context = parent->context();
444 int Eeprom::init_defaults(char* manufacturer, char *product, char * serial)
446 return ftdi_eeprom_initdefaults(d->context, manufacturer, product, serial);
449 int Eeprom::chip_id(unsigned int *chipid)
451 return ftdi_read_chipid(d->context, chipid);
454 int Eeprom::build(unsigned char *output)
456 return ftdi_eeprom_build(d->context);
459 int Eeprom::read(unsigned char *eeprom)
461 return ftdi_read_eeprom(d->context);
464 int Eeprom::write(unsigned char *eeprom)
466 return ftdi_write_eeprom(d->context);
469 int Eeprom::read_location(int eeprom_addr, unsigned short *eeprom_val)
471 return ftdi_read_eeprom_location(d->context, eeprom_addr, eeprom_val);
474 int Eeprom::write_location(int eeprom_addr, unsigned short eeprom_val)
476 return ftdi_write_eeprom_location(d->context, eeprom_addr, eeprom_val);
481 return ftdi_erase_eeprom(d->context);
487 Private(struct ftdi_device_list* _devlist)
494 ftdi_list_free(&devlist);
497 std::list<Context> list;
498 struct ftdi_device_list* devlist;
501 List::List(struct ftdi_device_list* devlist)
502 : d( new Private(devlist) )
507 for (; devlist != 0; devlist = devlist->next)
510 c.set_usb_device(devlist->dev);
512 d->list.push_back(c);
522 * Return begin iterator for accessing the contained list elements
525 List::iterator List::begin()
527 return d->list.begin();
531 * Return end iterator for accessing the contained list elements
534 List::iterator List::end()
536 return d->list.end();
540 * Return begin iterator for accessing the contained list elements
541 * @return Const iterator
543 List::const_iterator List::begin() const
545 return d->list.begin();
549 * Return end iterator for accessing the contained list elements
550 * @return Const iterator
552 List::const_iterator List::end() const
554 return d->list.end();
558 * Return begin reverse iterator for accessing the contained list elements
559 * @return Reverse iterator
561 List::reverse_iterator List::rbegin()
563 return d->list.rbegin();
567 * Return end reverse iterator for accessing the contained list elements
568 * @return Reverse iterator
570 List::reverse_iterator List::rend()
572 return d->list.rend();
576 * Return begin reverse iterator for accessing the contained list elements
577 * @return Const reverse iterator
579 List::const_reverse_iterator List::rbegin() const
581 return d->list.rbegin();
585 * Return end reverse iterator for accessing the contained list elements
586 * @return Const reverse iterator
588 List::const_reverse_iterator List::rend() const
590 return d->list.rend();
595 * Get number of elements stored in the list
596 * @return Number of elements
598 List::ListType::size_type List::size() const
600 return d->list.size();
604 * Check if list is empty
605 * @return True if empty, false otherwise
607 bool List::empty() const
609 return d->list.empty();
613 * Removes all elements. Invalidates all iterators.
614 * Do it in a non-throwing way and also make
615 * sure we really free the allocated memory.
619 ListType().swap(d->list);
624 ftdi_list_free(&d->devlist);
630 * Appends a copy of the element as the new last element.
631 * @param element Value to copy and append
633 void List::push_back(const Context& element)
635 d->list.push_back(element);
639 * Adds a copy of the element as the new first element.
640 * @param element Value to copy and add
642 void List::push_front(const Context& element)
644 d->list.push_front(element);
648 * Erase one element pointed by iterator
649 * @param pos Element to erase
650 * @return Position of the following element (or end())
652 List::iterator List::erase(iterator pos)
654 return d->list.erase(pos);
658 * Erase a range of elements
659 * @param beg Begin of range
660 * @param end End of range
661 * @return Position of the element after the erased range (or end())
663 List::iterator List::erase(iterator beg, iterator end)
665 return d->list.erase(beg, end);
668 List* List::find_all(Context &context, int vendor, int product)
670 struct ftdi_device_list* dlist = 0;
671 ftdi_usb_find_all(context.context(), &dlist, vendor, product);
672 return new List(dlist);