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)
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 const char* Context::error_string()
319 return ftdi_get_error_string(d->ftdi);
322 int Context::get_strings(bool vendor, bool description, bool serial)
325 char ivendor[512], idesc[512], iserial[512];
327 int ret = ftdi_usb_get_strings(d->ftdi, d->dev, vendor?ivendor:NULL, 512, description?idesc:NULL, 512, serial?iserial:NULL, 512);
333 d->description = idesc;
339 int Context::get_strings_and_reopen(bool vendor, bool description, bool serial)
343 if(vendor || description || serial)
347 d->dev = libusb_get_device(d->ftdi->usb_dev);
350 // Get device strings (closes device)
351 ret=get_strings(vendor, description, serial);
359 ret = ftdi_usb_open_dev(d->ftdi, d->dev);
360 d->open = (ret >= 0);
366 /*! \brief Device strings properties.
368 const std::string& Context::vendor()
370 if(d->vendor.empty())
371 get_strings_and_reopen(true,false,false);
375 /*! \brief Device strings properties.
377 const std::string& Context::description()
379 if(d->description.empty())
380 get_strings_and_reopen(false,true,false);
381 return d->description;
384 /*! \brief Device strings properties.
386 const std::string& Context::serial()
388 if(d->serial.empty())
389 get_strings_and_reopen(false,false,true);
393 void Context::set_context(struct ftdi_context* context)
399 void Context::set_usb_device(struct libusb_device *dev)
404 struct ftdi_context* Context::context()
409 class Eeprom::Private
416 struct ftdi_eeprom eeprom;
417 struct ftdi_context* context;
420 Eeprom::Eeprom(Context* parent)
421 : d ( new Private() )
423 d->context = parent->context();
430 int Eeprom::init_defaults(char* manufacturer, char *product, char * serial)
432 return ftdi_eeprom_initdefaults(d->context, manufacturer, product, serial);
435 int Eeprom::chip_id(unsigned int *chipid)
437 return ftdi_read_chipid(d->context, chipid);
440 int Eeprom::build(unsigned char *output)
442 return ftdi_eeprom_build(d->context);
445 int Eeprom::read(unsigned char *eeprom)
447 return ftdi_read_eeprom(d->context);
450 int Eeprom::write(unsigned char *eeprom)
452 return ftdi_write_eeprom(d->context);
455 int Eeprom::read_location(int eeprom_addr, unsigned short *eeprom_val)
457 return ftdi_read_eeprom_location(d->context, eeprom_addr, eeprom_val);
460 int Eeprom::write_location(int eeprom_addr, unsigned short eeprom_val)
462 return ftdi_write_eeprom_location(d->context, eeprom_addr, eeprom_val);
467 return ftdi_erase_eeprom(d->context);
473 Private(struct ftdi_device_list* _devlist)
480 ftdi_list_free(&devlist);
483 std::list<Context> list;
484 struct ftdi_device_list* devlist;
487 List::List(struct ftdi_device_list* devlist)
488 : d( new Private(devlist) )
493 for (; devlist != 0; devlist = devlist->next)
496 c.set_usb_device(devlist->dev);
498 d->list.push_back(c);
508 * Return begin iterator for accessing the contained list elements
511 List::iterator List::begin()
513 return d->list.begin();
517 * Return end iterator for accessing the contained list elements
520 List::iterator List::end()
522 return d->list.end();
526 * Return begin iterator for accessing the contained list elements
527 * @return Const iterator
529 List::const_iterator List::begin() const
531 return d->list.begin();
535 * Return end iterator for accessing the contained list elements
536 * @return Const iterator
538 List::const_iterator List::end() const
540 return d->list.end();
544 * Return begin reverse iterator for accessing the contained list elements
545 * @return Reverse iterator
547 List::reverse_iterator List::rbegin()
549 return d->list.rbegin();
553 * Return end reverse iterator for accessing the contained list elements
554 * @return Reverse iterator
556 List::reverse_iterator List::rend()
558 return d->list.rend();
562 * Return begin reverse iterator for accessing the contained list elements
563 * @return Const reverse iterator
565 List::const_reverse_iterator List::rbegin() const
567 return d->list.rbegin();
571 * Return end reverse iterator for accessing the contained list elements
572 * @return Const reverse iterator
574 List::const_reverse_iterator List::rend() const
576 return d->list.rend();
581 * Get number of elements stored in the list
582 * @return Number of elements
584 List::ListType::size_type List::size() const
586 return d->list.size();
590 * Check if list is empty
591 * @return True if empty, false otherwise
593 bool List::empty() const
595 return d->list.empty();
599 * Removes all elements. Invalidates all iterators.
600 * Do it in a non-throwing way and also make
601 * sure we really free the allocated memory.
605 ListType().swap(d->list);
610 ftdi_list_free(&d->devlist);
616 * Appends a copy of the element as the new last element.
617 * @param element Value to copy and append
619 void List::push_back(const Context& element)
621 d->list.push_back(element);
625 * Adds a copy of the element as the new first element.
626 * @param element Value to copy and add
628 void List::push_front(const Context& element)
630 d->list.push_front(element);
634 * Erase one element pointed by iterator
635 * @param pos Element to erase
636 * @return Position of the following element (or end())
638 List::iterator List::erase(iterator pos)
640 return d->list.erase(pos);
644 * Erase a range of elements
645 * @param beg Begin of range
646 * @param end End of range
647 * @return Position of the element after the erased range (or end())
649 List::iterator List::erase(iterator beg, iterator end)
651 return d->list.erase(beg, end);
654 List* List::find_all(Context &context, int vendor, int product)
656 struct ftdi_device_list* dlist = 0;
657 ftdi_usb_find_all(context.context(), &dlist, vendor, product);
658 return new List(dlist);