1 /***************************************************************************
2 ftdi.cpp - C++ wraper for libftdi
4 begin : Mon Oct 13 2008
5 copyright : (C) 2008-2013 by Marek Vavruša / libftdi developers
6 email : opensource@intra2net.com and marek@vavrusa.com
7 ***************************************************************************/
9 Copyright (C) 2008-2013 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::read(unsigned char *buf, int size)
185 return ftdi_read_data(d->ftdi, buf, size);
188 int Context::set_read_chunk_size(unsigned int chunksize)
190 return ftdi_read_data_set_chunksize(d->ftdi, chunksize);
193 int Context::read_chunk_size()
196 if (ftdi_read_data_get_chunksize(d->ftdi, &chunk) < 0)
202 int Context::write(unsigned char *buf, int size)
204 return ftdi_write_data(d->ftdi, buf, size);
207 int Context::set_write_chunk_size(unsigned int chunksize)
209 return ftdi_write_data_set_chunksize(d->ftdi, chunksize);
212 int Context::write_chunk_size()
215 if (ftdi_write_data_get_chunksize(d->ftdi, &chunk) < 0)
221 int Context::set_flow_control(int flowctrl)
223 return ftdi_setflowctrl(d->ftdi, flowctrl);
226 int Context::set_modem_control(int mask)
228 int dtr = 0, rts = 0;
235 return ftdi_setdtr_rts(d->ftdi, dtr, rts);
238 int Context::set_dtr(bool state)
240 return ftdi_setdtr(d->ftdi, state);
243 int Context::set_rts(bool state)
245 return ftdi_setrts(d->ftdi, state);
248 int Context::set_latency(unsigned char latency)
250 return ftdi_set_latency_timer(d->ftdi, latency);
253 unsigned Context::latency()
255 unsigned char latency = 0;
256 ftdi_get_latency_timer(d->ftdi, &latency);
260 unsigned short Context::poll_modem_status()
262 unsigned short status = 0;
263 ftdi_poll_modem_status(d->ftdi, &status);
267 int Context::set_event_char(unsigned char eventch, unsigned char enable)
269 return ftdi_set_event_char(d->ftdi, eventch, enable);
272 int Context::set_error_char(unsigned char errorch, unsigned char enable)
274 return ftdi_set_error_char(d->ftdi, errorch, enable);
277 int Context::set_bitmode(unsigned char bitmask, unsigned char mode)
279 return ftdi_set_bitmode(d->ftdi, bitmask, mode);
282 int Context::set_bitmode(unsigned char bitmask, enum ftdi_mpsse_mode mode)
284 return ftdi_set_bitmode(d->ftdi, bitmask, mode);
287 int Context::bitbang_disable()
289 return ftdi_disable_bitbang(d->ftdi);
292 int Context::read_pins(unsigned char *pins)
294 return ftdi_read_pins(d->ftdi, pins);
297 char* Context::error_string()
299 return ftdi_get_error_string(d->ftdi);
302 int Context::get_strings()
305 char vendor[512], desc[512], serial[512];
307 int ret = ftdi_usb_get_strings(d->ftdi, d->dev, vendor, 512, desc, 512, serial, 512);
313 d->description = desc;
319 int Context::get_strings_and_reopen()
323 d->dev = libusb_get_device(d->ftdi->usb_dev);
326 // Get device strings (closes device)
327 int ret=get_strings();
335 ret = ftdi_usb_open_dev(d->ftdi, d->dev);
336 d->open = (ret >= 0);
341 /*! \brief Device strings properties.
343 const std::string& Context::vendor()
348 /*! \brief Device strings properties.
350 const std::string& Context::description()
352 return d->description;
355 /*! \brief Device strings properties.
357 const std::string& Context::serial()
362 void Context::set_context(struct ftdi_context* context)
368 void Context::set_usb_device(struct libusb_device *dev)
373 struct ftdi_context* Context::context()
378 class Eeprom::Private
385 struct ftdi_eeprom eeprom;
386 struct ftdi_context* context;
389 Eeprom::Eeprom(Context* parent)
390 : d ( new Private() )
392 d->context = parent->context();
399 int Eeprom::init_defaults(char* manufacturer, char *product, char * serial)
401 return ftdi_eeprom_initdefaults(d->context, manufacturer, product, serial);
404 int Eeprom::chip_id(unsigned int *chipid)
406 return ftdi_read_chipid(d->context, chipid);
409 int Eeprom::build(unsigned char *output)
411 return ftdi_eeprom_build(d->context);
414 int Eeprom::read(unsigned char *eeprom)
416 return ftdi_read_eeprom(d->context);
419 int Eeprom::write(unsigned char *eeprom)
421 return ftdi_write_eeprom(d->context);
424 int Eeprom::read_location(int eeprom_addr, unsigned short *eeprom_val)
426 return ftdi_read_eeprom_location(d->context, eeprom_addr, eeprom_val);
429 int Eeprom::write_location(int eeprom_addr, unsigned short eeprom_val)
431 return ftdi_write_eeprom_location(d->context, eeprom_addr, eeprom_val);
436 return ftdi_erase_eeprom(d->context);
442 Private(struct ftdi_device_list* _devlist)
449 ftdi_list_free(&devlist);
452 std::list<Context> list;
453 struct ftdi_device_list* devlist;
456 List::List(struct ftdi_device_list* devlist)
457 : d( new Private(devlist) )
462 for (; devlist != 0; devlist = devlist->next)
465 c.set_usb_device(devlist->dev);
467 d->list.push_back(c);
477 * Return begin iterator for accessing the contained list elements
480 List::iterator List::begin()
482 return d->list.begin();
486 * Return end iterator for accessing the contained list elements
489 List::iterator List::end()
491 return d->list.end();
495 * Return begin iterator for accessing the contained list elements
496 * @return Const iterator
498 List::const_iterator List::begin() const
500 return d->list.begin();
504 * Return end iterator for accessing the contained list elements
505 * @return Const iterator
507 List::const_iterator List::end() const
509 return d->list.end();
513 * Return begin reverse iterator for accessing the contained list elements
514 * @return Reverse iterator
516 List::reverse_iterator List::rbegin()
518 return d->list.rbegin();
522 * Return end reverse iterator for accessing the contained list elements
523 * @return Reverse iterator
525 List::reverse_iterator List::rend()
527 return d->list.rend();
531 * Return begin reverse iterator for accessing the contained list elements
532 * @return Const reverse iterator
534 List::const_reverse_iterator List::rbegin() const
536 return d->list.rbegin();
540 * Return end reverse iterator for accessing the contained list elements
541 * @return Const reverse iterator
543 List::const_reverse_iterator List::rend() const
545 return d->list.rend();
550 * Get number of elements stored in the list
551 * @return Number of elements
553 List::ListType::size_type List::size() const
555 return d->list.size();
559 * Check if list is empty
560 * @return True if empty, false otherwise
562 bool List::empty() const
564 return d->list.empty();
568 * Removes all elements. Invalidates all iterators.
569 * Do it in a non-throwing way and also make
570 * sure we really free the allocated memory.
574 ListType().swap(d->list);
579 ftdi_list_free(&d->devlist);
585 * Appends a copy of the element as the new last element.
586 * @param element Value to copy and append
588 void List::push_back(const Context& element)
590 d->list.push_back(element);
594 * Adds a copy of the element as the new first element.
595 * @param element Value to copy and add
597 void List::push_front(const Context& element)
599 d->list.push_front(element);
603 * Erase one element pointed by iterator
604 * @param pos Element to erase
605 * @return Position of the following element (or end())
607 List::iterator List::erase(iterator pos)
609 return d->list.erase(pos);
613 * Erase a range of elements
614 * @param beg Begin of range
615 * @param end End of range
616 * @return Position of the element after the erased range (or end())
618 List::iterator List::erase(iterator beg, iterator end)
620 return d->list.erase(beg, end);
623 List* List::find_all(Context &context, int vendor, int product)
625 struct ftdi_device_list* dlist = 0;
626 ftdi_usb_find_all(context.context(), &dlist, vendor, product);
627 return new List(dlist);