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()
321 d->dev = libusb_get_device(d->ftdi->usb_dev);
324 // Get device strings (closes device)
325 int ret=get_strings();
333 ret = ftdi_usb_open_dev(d->ftdi, d->dev);
334 d->open = (ret >= 0);
339 /*! \brief Device strings properties.
341 const std::string& Context::vendor()
346 /*! \brief Device strings properties.
348 const std::string& Context::description()
350 return d->description;
353 /*! \brief Device strings properties.
355 const std::string& Context::serial()
360 void Context::set_context(struct ftdi_context* context)
366 void Context::set_usb_device(struct libusb_device *dev)
371 struct ftdi_context* Context::context()
376 class Eeprom::Private
383 struct ftdi_eeprom eeprom;
384 struct ftdi_context* context;
387 Eeprom::Eeprom(Context* parent)
388 : d ( new Private() )
390 d->context = parent->context();
397 int Eeprom::init_defaults(char* manufacturer, char *product, char * serial)
399 return ftdi_eeprom_initdefaults(d->context, manufacturer, product, serial);
402 int Eeprom::chip_id(unsigned int *chipid)
404 return ftdi_read_chipid(d->context, chipid);
407 int Eeprom::build(unsigned char *output)
409 return ftdi_eeprom_build(d->context);
412 int Eeprom::read(unsigned char *eeprom)
414 return ftdi_read_eeprom(d->context);
417 int Eeprom::write(unsigned char *eeprom)
419 return ftdi_write_eeprom(d->context);
422 int Eeprom::read_location(int eeprom_addr, unsigned short *eeprom_val)
424 return ftdi_read_eeprom_location(d->context, eeprom_addr, eeprom_val);
427 int Eeprom::write_location(int eeprom_addr, unsigned short eeprom_val)
429 return ftdi_write_eeprom_location(d->context, eeprom_addr, eeprom_val);
434 return ftdi_erase_eeprom(d->context);
440 Private(struct ftdi_device_list* _devlist)
447 ftdi_list_free(&devlist);
450 std::list<Context> list;
451 struct ftdi_device_list* devlist;
454 List::List(struct ftdi_device_list* devlist)
455 : d( new Private(devlist) )
460 for (; devlist != 0; devlist = devlist->next)
463 c.set_usb_device(devlist->dev);
465 d->list.push_back(c);
475 * Return begin iterator for accessing the contained list elements
478 List::iterator List::begin()
480 return d->list.begin();
484 * Return end iterator for accessing the contained list elements
487 List::iterator List::end()
489 return d->list.end();
493 * Return begin iterator for accessing the contained list elements
494 * @return Const iterator
496 List::const_iterator List::begin() const
498 return d->list.begin();
502 * Return end iterator for accessing the contained list elements
503 * @return Const iterator
505 List::const_iterator List::end() const
507 return d->list.end();
511 * Return begin reverse iterator for accessing the contained list elements
512 * @return Reverse iterator
514 List::reverse_iterator List::rbegin()
516 return d->list.rbegin();
520 * Return end reverse iterator for accessing the contained list elements
521 * @return Reverse iterator
523 List::reverse_iterator List::rend()
525 return d->list.rend();
529 * Return begin reverse iterator for accessing the contained list elements
530 * @return Const reverse iterator
532 List::const_reverse_iterator List::rbegin() const
534 return d->list.rbegin();
538 * Return end reverse iterator for accessing the contained list elements
539 * @return Const reverse iterator
541 List::const_reverse_iterator List::rend() const
543 return d->list.rend();
548 * Get number of elements stored in the list
549 * @return Number of elements
551 List::ListType::size_type List::size() const
553 return d->list.size();
557 * Check if list is empty
558 * @return True if empty, false otherwise
560 bool List::empty() const
562 return d->list.empty();
566 * Removes all elements. Invalidates all iterators.
567 * Do it in a non-throwing way and also make
568 * sure we really free the allocated memory.
572 ListType().swap(d->list);
577 ftdi_list_free(&d->devlist);
583 * Appends a copy of the element as the new last element.
584 * @param element Value to copy and append
586 void List::push_back(const Context& element)
588 d->list.push_back(element);
592 * Adds a copy of the element as the new first element.
593 * @param element Value to copy and add
595 void List::push_front(const Context& element)
597 d->list.push_front(element);
601 * Erase one element pointed by iterator
602 * @param pos Element to erase
603 * @return Position of the following element (or end())
605 List::iterator List::erase(iterator pos)
607 return d->list.erase(pos);
611 * Erase a range of elements
612 * @param beg Begin of range
613 * @param end End of range
614 * @return Position of the element after the erased range (or end())
616 List::iterator List::erase(iterator beg, iterator end)
618 return d->list.erase(beg, end);
621 List* List::find_all(int vendor, int product)
623 struct ftdi_device_list* dlist = 0;
624 struct ftdi_context ftdi;
626 ftdi_usb_find_all(&ftdi, &dlist, vendor, product);
628 return new List(dlist);