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();
135 return ftdi_usb_close(d->ftdi);
140 return ftdi_usb_reset(d->ftdi);
143 int Context::flush(int mask)
148 ret &= ftdi_usb_purge_rx_buffer(d->ftdi);
150 ret &= ftdi_usb_purge_tx_buffer(d->ftdi);
155 int Context::set_interface(enum ftdi_interface interface)
157 return ftdi_set_interface(d->ftdi, interface);
160 void Context::set_usb_device(struct libusb_device_handle *dev)
162 ftdi_set_usbdev(d->ftdi, dev);
163 d->dev = libusb_get_device(dev);
166 int Context::set_baud_rate(int baudrate)
168 return ftdi_set_baudrate(d->ftdi, baudrate);
171 int Context::set_line_property(enum ftdi_bits_type bits, enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity)
173 return ftdi_set_line_property(d->ftdi, bits, sbit, parity);
176 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)
178 return ftdi_set_line_property2(d->ftdi, bits, sbit, parity, break_type);
181 int Context::read(unsigned char *buf, int size)
183 return ftdi_read_data(d->ftdi, buf, size);
186 int Context::set_read_chunk_size(unsigned int chunksize)
188 return ftdi_read_data_set_chunksize(d->ftdi, chunksize);
191 int Context::read_chunk_size()
194 if (ftdi_read_data_get_chunksize(d->ftdi, &chunk) < 0)
200 int Context::write(unsigned char *buf, int size)
202 return ftdi_write_data(d->ftdi, buf, size);
205 int Context::set_write_chunk_size(unsigned int chunksize)
207 return ftdi_write_data_set_chunksize(d->ftdi, chunksize);
210 int Context::write_chunk_size()
213 if (ftdi_write_data_get_chunksize(d->ftdi, &chunk) < 0)
219 int Context::set_flow_control(int flowctrl)
221 return ftdi_setflowctrl(d->ftdi, flowctrl);
224 int Context::set_modem_control(int mask)
226 int dtr = 0, rts = 0;
233 return ftdi_setdtr_rts(d->ftdi, dtr, rts);
236 int Context::set_dtr(bool state)
238 return ftdi_setdtr(d->ftdi, state);
241 int Context::set_rts(bool state)
243 return ftdi_setrts(d->ftdi, state);
246 int Context::set_latency(unsigned char latency)
248 return ftdi_set_latency_timer(d->ftdi, latency);
251 unsigned Context::latency()
253 unsigned char latency = 0;
254 ftdi_get_latency_timer(d->ftdi, &latency);
258 unsigned short Context::poll_modem_status()
260 unsigned short status = 0;
261 ftdi_poll_modem_status(d->ftdi, &status);
265 int Context::set_event_char(unsigned char eventch, unsigned char enable)
267 return ftdi_set_event_char(d->ftdi, eventch, enable);
270 int Context::set_error_char(unsigned char errorch, unsigned char enable)
272 return ftdi_set_error_char(d->ftdi, errorch, enable);
275 int Context::set_bitmode(unsigned char bitmask, unsigned char mode)
277 return ftdi_set_bitmode(d->ftdi, bitmask, mode);
280 int Context::set_bitmode(unsigned char bitmask, enum ftdi_mpsse_mode mode)
282 return ftdi_set_bitmode(d->ftdi, bitmask, mode);
285 int Context::bitbang_disable()
287 return ftdi_disable_bitbang(d->ftdi);
290 int Context::read_pins(unsigned char *pins)
292 return ftdi_read_pins(d->ftdi, pins);
295 char* Context::error_string()
297 return ftdi_get_error_string(d->ftdi);
300 int Context::get_strings()
303 char vendor[512], desc[512], serial[512];
305 int ret = ftdi_usb_get_strings(d->ftdi, d->dev, vendor, 512, desc, 512, serial, 512);
311 d->description = desc;
317 int Context::get_strings_and_reopen()
319 // Get device strings (closes device)
320 int ret=get_strings();
328 ret = ftdi_usb_open_dev(d->ftdi, d->dev);
329 d->open = (ret >= 0);
334 /*! \brief Device strings properties.
336 const std::string& Context::vendor()
341 /*! \brief Device strings properties.
343 const std::string& Context::description()
345 return d->description;
348 /*! \brief Device strings properties.
350 const std::string& Context::serial()
355 void Context::set_context(struct ftdi_context* context)
361 void Context::set_usb_device(struct libusb_device *dev)
366 struct ftdi_context* Context::context()
371 class Eeprom::Private
378 struct ftdi_eeprom eeprom;
379 struct ftdi_context* context;
382 Eeprom::Eeprom(Context* parent)
383 : d ( new Private() )
385 d->context = parent->context();
392 int Eeprom::init_defaults(char* manufacturer, char *product, char * serial)
394 return ftdi_eeprom_initdefaults(d->context, manufacturer, product, serial);
397 int Eeprom::chip_id(unsigned int *chipid)
399 return ftdi_read_chipid(d->context, chipid);
402 int Eeprom::build(unsigned char *output)
404 return ftdi_eeprom_build(d->context);
407 int Eeprom::read(unsigned char *eeprom)
409 return ftdi_read_eeprom(d->context);
412 int Eeprom::write(unsigned char *eeprom)
414 return ftdi_write_eeprom(d->context);
417 int Eeprom::read_location(int eeprom_addr, unsigned short *eeprom_val)
419 return ftdi_read_eeprom_location(d->context, eeprom_addr, eeprom_val);
422 int Eeprom::write_location(int eeprom_addr, unsigned short eeprom_val)
424 return ftdi_write_eeprom_location(d->context, eeprom_addr, eeprom_val);
429 return ftdi_erase_eeprom(d->context);
435 Private(struct ftdi_device_list* _devlist)
442 ftdi_list_free(&devlist);
445 std::list<Context> list;
446 struct ftdi_device_list* devlist;
449 List::List(struct ftdi_device_list* devlist)
450 : d( new Private(devlist) )
455 for (; devlist != 0; devlist = devlist->next)
458 c.set_usb_device(devlist->dev);
460 d->list.push_back(c);
470 * Return begin iterator for accessing the contained list elements
473 List::iterator List::begin()
475 return d->list.begin();
479 * Return end iterator for accessing the contained list elements
482 List::iterator List::end()
484 return d->list.end();
488 * Return begin iterator for accessing the contained list elements
489 * @return Const iterator
491 List::const_iterator List::begin() const
493 return d->list.begin();
497 * Return end iterator for accessing the contained list elements
498 * @return Const iterator
500 List::const_iterator List::end() const
502 return d->list.end();
506 * Return begin reverse iterator for accessing the contained list elements
507 * @return Reverse iterator
509 List::reverse_iterator List::rbegin()
511 return d->list.rbegin();
515 * Return end reverse iterator for accessing the contained list elements
516 * @return Reverse iterator
518 List::reverse_iterator List::rend()
520 return d->list.rend();
524 * Return begin reverse iterator for accessing the contained list elements
525 * @return Const reverse iterator
527 List::const_reverse_iterator List::rbegin() const
529 return d->list.rbegin();
533 * Return end reverse iterator for accessing the contained list elements
534 * @return Const reverse iterator
536 List::const_reverse_iterator List::rend() const
538 return d->list.rend();
543 * Get number of elements stored in the list
544 * @return Number of elements
546 List::ListType::size_type List::size() const
548 return d->list.size();
552 * Check if list is empty
553 * @return True if empty, false otherwise
555 bool List::empty() const
557 return d->list.empty();
561 * Removes all elements. Invalidates all iterators.
562 * Do it in a non-throwing way and also make
563 * sure we really free the allocated memory.
567 ListType().swap(d->list);
572 ftdi_list_free(&d->devlist);
578 * Appends a copy of the element as the new last element.
579 * @param element Value to copy and append
581 void List::push_back(const Context& element)
583 d->list.push_back(element);
587 * Adds a copy of the element as the new first element.
588 * @param element Value to copy and add
590 void List::push_front(const Context& element)
592 d->list.push_front(element);
596 * Erase one element pointed by iterator
597 * @param pos Element to erase
598 * @return Position of the following element (or end())
600 List::iterator List::erase(iterator pos)
602 return d->list.erase(pos);
606 * Erase a range of elements
607 * @param beg Begin of range
608 * @param end End of range
609 * @return Position of the element after the erased range (or end())
611 List::iterator List::erase(iterator beg, iterator end)
613 return d->list.erase(beg, end);
616 List* List::find_all(int vendor, int product)
618 struct ftdi_device_list* dlist = 0;
619 struct ftdi_context ftdi;
621 ftdi_usb_find_all(&ftdi, &dlist, vendor, product);
623 return new List(dlist);