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.
35 class Context::Private
39 : ftdi(0), dev(0), open(false)
54 struct ftdi_context* ftdi;
55 struct usb_device* dev;
58 std::string description;
62 /*! \brief Constructor.
69 /*! \brief Destructor.
75 bool Context::is_open()
80 int Context::open(int vendor, int product)
83 int ret = ftdi_usb_open(d->ftdi, vendor, product);
88 d->dev = usb_device(d->ftdi->usb_dev);
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 d->dev = usb_device(d->ftdi->usb_dev);
111 return get_strings_and_reopen();
114 int Context::open(const std::string& description)
116 int ret = ftdi_usb_open_string(d->ftdi, description.c_str());
121 d->dev = usb_device(d->ftdi->usb_dev);
123 return get_strings_and_reopen();
126 int Context::open(struct usb_device *dev)
134 return get_strings_and_reopen();
140 return ftdi_usb_close(d->ftdi);
145 return ftdi_usb_reset(d->ftdi);
148 int Context::flush(int mask)
153 ret &= ftdi_usb_purge_rx_buffer(d->ftdi);
155 ret &= ftdi_usb_purge_tx_buffer(d->ftdi);
160 int Context::set_interface(enum ftdi_interface interface)
162 return ftdi_set_interface(d->ftdi, interface);
165 void Context::set_usb_device(struct usb_dev_handle *dev)
167 ftdi_set_usbdev(d->ftdi, dev);
168 d->dev = usb_device(dev);
171 int Context::set_baud_rate(int baudrate)
173 return ftdi_set_baudrate(d->ftdi, baudrate);
176 int Context::set_line_property(enum ftdi_bits_type bits, enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity)
178 return ftdi_set_line_property(d->ftdi, bits, sbit, parity);
181 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)
183 return ftdi_set_line_property2(d->ftdi, bits, sbit, parity, break_type);
186 int Context::read(unsigned char *buf, int size)
188 return ftdi_read_data(d->ftdi, buf, size);
191 int Context::set_read_chunk_size(unsigned int chunksize)
193 return ftdi_read_data_set_chunksize(d->ftdi, chunksize);
196 int Context::read_chunk_size()
199 if (ftdi_read_data_get_chunksize(d->ftdi, &chunk) < 0)
205 int Context::write(unsigned char *buf, int size)
207 return ftdi_write_data(d->ftdi, buf, size);
210 int Context::set_write_chunk_size(unsigned int chunksize)
212 return ftdi_write_data_set_chunksize(d->ftdi, chunksize);
215 int Context::write_chunk_size()
218 if (ftdi_write_data_get_chunksize(d->ftdi, &chunk) < 0)
224 int Context::set_flow_control(int flowctrl)
226 return ftdi_setflowctrl(d->ftdi, flowctrl);
229 int Context::set_modem_control(int mask)
231 int dtr = 0, rts = 0;
238 return ftdi_setdtr_rts(d->ftdi, dtr, rts);
241 int Context::set_dtr(bool state)
243 return ftdi_setdtr(d->ftdi, state);
246 int Context::set_rts(bool state)
248 return ftdi_setrts(d->ftdi, state);
251 int Context::set_latency(unsigned char latency)
253 return ftdi_set_latency_timer(d->ftdi, latency);
256 unsigned Context::latency()
258 unsigned char latency = 0;
259 ftdi_get_latency_timer(d->ftdi, &latency);
263 unsigned short Context::poll_modem_status()
265 unsigned short status = 0;
266 ftdi_poll_modem_status(d->ftdi, &status);
270 int Context::set_event_char(unsigned char eventch, unsigned char enable)
272 return ftdi_set_event_char(d->ftdi, eventch, enable);
275 int Context::set_error_char(unsigned char errorch, unsigned char enable)
277 return ftdi_set_error_char(d->ftdi, errorch, enable);
280 int Context::bitbang_enable(unsigned char bitmask)
282 return ftdi_set_bitmode(d->ftdi, bitmask, BITMODE_BITBANG);
285 int Context::bitbang_disable()
287 return ftdi_disable_bitbang(d->ftdi);
290 int Context::set_bitmode(unsigned char bitmask, unsigned char mode)
292 return ftdi_set_bitmode(d->ftdi, bitmask, mode);
295 int Context::set_bitmode(unsigned char bitmask, enum ftdi_mpsse_mode mode)
297 return ftdi_set_bitmode(d->ftdi, bitmask, mode);
300 int Context::read_pins(unsigned char *pins)
302 return ftdi_read_pins(d->ftdi, pins);
305 char* Context::error_string()
307 return ftdi_get_error_string(d->ftdi);
310 int Context::get_strings()
313 char vendor[512], desc[512], serial[512];
315 int ret = ftdi_usb_get_strings(d->ftdi, d->dev, vendor, 512, desc, 512, serial, 512);
321 d->description = desc;
327 int Context::get_strings_and_reopen()
329 // Get device strings (closes device)
330 int ret=get_strings();
338 ret = ftdi_usb_open_dev(d->ftdi, d->dev);
339 d->open = (ret >= 0);
344 /*! \brief Device strings properties.
346 const std::string& Context::vendor()
351 /*! \brief Device strings properties.
353 const std::string& Context::description()
355 return d->description;
358 /*! \brief Device strings properties.
360 const std::string& Context::serial()
365 void Context::set_context(struct ftdi_context* context)
371 void Context::set_usb_device(struct usb_device *dev)
376 struct ftdi_context* Context::context()
381 class Eeprom::Private
388 struct ftdi_eeprom eeprom;
389 struct ftdi_context* context;
392 Eeprom::Eeprom(Context* parent)
393 : d ( new Private() )
395 d->context = parent->context();
402 void Eeprom::init_defaults()
404 return ftdi_eeprom_initdefaults(&d->eeprom);
407 void Eeprom::set_size(int size)
409 return ftdi_eeprom_setsize(d->context, &d->eeprom, size);
412 int Eeprom::size(unsigned char *eeprom, int maxsize)
414 return ftdi_read_eeprom_getsize(d->context, eeprom, maxsize);
417 int Eeprom::chip_id(unsigned int *chipid)
419 return ftdi_read_chipid(d->context, chipid);
422 int Eeprom::build(unsigned char *output)
424 return ftdi_eeprom_build(&d->eeprom, output);
427 int Eeprom::read(unsigned char *eeprom)
429 return ftdi_read_eeprom(d->context, eeprom);
432 int Eeprom::write(unsigned char *eeprom)
434 return ftdi_write_eeprom(d->context, eeprom);
437 int Eeprom::read_location(int eeprom_addr, unsigned short *eeprom_val)
439 return ftdi_read_eeprom_location(d->context, eeprom_addr, eeprom_val);
442 int Eeprom::write_location(int eeprom_addr, unsigned short eeprom_val)
444 return ftdi_write_eeprom_location(d->context, eeprom_addr, eeprom_val);
449 return ftdi_erase_eeprom(d->context);
455 Private(struct ftdi_device_list* _devlist)
462 ftdi_list_free(&devlist);
465 std::list<Context> list;
466 struct ftdi_device_list* devlist;
469 List::List(struct ftdi_device_list* devlist)
470 : d( new Private(devlist) )
475 for (; devlist != 0; devlist = devlist->next)
478 c.set_usb_device(devlist->dev);
480 d->list.push_back(c);
490 * Return begin iterator for accessing the contained list elements
493 List::iterator List::begin()
495 return d->list.begin();
499 * Return end iterator for accessing the contained list elements
502 List::iterator List::end()
504 return d->list.end();
508 * Return begin iterator for accessing the contained list elements
509 * @return Const iterator
511 List::const_iterator List::begin() const
513 return d->list.begin();
517 * Return end iterator for accessing the contained list elements
518 * @return Const iterator
520 List::const_iterator List::end() const
522 return d->list.end();
526 * Return begin reverse iterator for accessing the contained list elements
527 * @return Reverse iterator
529 List::reverse_iterator List::rbegin()
531 return d->list.rbegin();
535 * Return end reverse iterator for accessing the contained list elements
536 * @return Reverse iterator
538 List::reverse_iterator List::rend()
540 return d->list.rend();
544 * Return begin reverse iterator for accessing the contained list elements
545 * @return Const reverse iterator
547 List::const_reverse_iterator List::rbegin() const
549 return d->list.rbegin();
553 * Return end reverse iterator for accessing the contained list elements
554 * @return Const reverse iterator
556 List::const_reverse_iterator List::rend() const
558 return d->list.rend();
563 * Get number of elements stored in the list
564 * @return Number of elements
566 List::ListType::size_type List::size() const
568 return d->list.size();
572 * Check if list is empty
573 * @return True if empty, false otherwise
575 bool List::empty() const
577 return d->list.empty();
581 * Removes all elements. Invalidates all iterators.
582 * Do it in a non-throwing way and also make
583 * sure we really free the allocated memory.
587 ListType().swap(d->list);
592 ftdi_list_free(&d->devlist);
598 * Appends a copy of the element as the new last element.
599 * @param element Value to copy and append
601 void List::push_back(const Context& element)
603 d->list.push_back(element);
607 * Adds a copy of the element as the new first element.
608 * @param element Value to copy and add
610 void List::push_front(const Context& element)
612 d->list.push_front(element);
616 * Erase one element pointed by iterator
617 * @param pos Element to erase
618 * @return Position of the following element (or end())
620 List::iterator List::erase(iterator pos)
622 return d->list.erase(pos);
626 * Erase a range of elements
627 * @param beg Begin of range
628 * @param end End of range
629 * @return Position of the element after the erased range (or end())
631 List::iterator List::erase(iterator beg, iterator end)
633 return d->list.erase(beg, end);
636 List* List::find_all(int vendor, int product)
638 struct ftdi_device_list* dlist = 0;
639 struct ftdi_context ftdi;
641 ftdi_usb_find_all(&ftdi, &dlist, vendor, product);
643 return new List(dlist);