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, const std::string& description, const std::string& serial)
85 if (description.empty() && serial.empty())
86 ret = ftdi_usb_open(d->ftdi, vendor, product);
88 ret = ftdi_usb_open_desc(d->ftdi, vendor, product, description.c_str(), serial.c_str());
93 // Get device strings (closes device)
97 ret = ftdi_usb_open_dev(d->ftdi, d->dev);
103 int Context::open(struct usb_device *dev)
111 // Get device strings (closes device)
115 int ret = ftdi_usb_open_dev(d->ftdi, d->dev);
116 d->open = (ret >= 0);
124 return ftdi_usb_close(d->ftdi);
129 return ftdi_usb_reset(d->ftdi);
132 int Context::flush(int mask)
137 ret &= ftdi_usb_purge_rx_buffer(d->ftdi);
139 ret &= ftdi_usb_purge_tx_buffer(d->ftdi);
144 int Context::set_interface(enum ftdi_interface interface)
146 return ftdi_set_interface(d->ftdi, interface);
149 void Context::set_usb_device(struct usb_dev_handle *dev)
151 ftdi_set_usbdev(d->ftdi, dev);
152 d->dev = usb_device(dev);
155 int Context::set_baud_rate(int baudrate)
157 return ftdi_set_baudrate(d->ftdi, baudrate);
160 int Context::set_line_property(enum ftdi_bits_type bits, enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity)
162 return ftdi_set_line_property(d->ftdi, bits, sbit, parity);
165 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)
167 return ftdi_set_line_property2(d->ftdi, bits, sbit, parity, break_type);
170 int Context::read(unsigned char *buf, int size)
172 return ftdi_read_data(d->ftdi, buf, size);
175 int Context::set_read_chunk_size(unsigned int chunksize)
177 return ftdi_read_data_set_chunksize(d->ftdi, chunksize);
180 int Context::read_chunk_size()
183 if (ftdi_read_data_get_chunksize(d->ftdi, &chunk) < 0)
189 int Context::write(unsigned char *buf, int size)
191 return ftdi_write_data(d->ftdi, buf, size);
194 int Context::set_write_chunk_size(unsigned int chunksize)
196 return ftdi_write_data_set_chunksize(d->ftdi, chunksize);
199 int Context::write_chunk_size()
202 if (ftdi_write_data_get_chunksize(d->ftdi, &chunk) < 0)
208 int Context::set_flow_control(int flowctrl)
210 return ftdi_setflowctrl(d->ftdi, flowctrl);
213 int Context::set_modem_control(int mask)
215 int dtr = 0, rts = 0;
222 return ftdi_setdtr_rts(d->ftdi, dtr, rts);
225 int Context::set_dtr(bool state)
227 return ftdi_setdtr(d->ftdi, state);
230 int Context::set_rts(bool state)
232 return ftdi_setrts(d->ftdi, state);
235 int Context::set_latency(unsigned char latency)
237 return ftdi_set_latency_timer(d->ftdi, latency);
240 unsigned Context::latency()
242 unsigned char latency = 0;
243 ftdi_get_latency_timer(d->ftdi, &latency);
247 unsigned short Context::poll_modem_status()
249 unsigned short status = 0;
250 ftdi_poll_modem_status(d->ftdi, &status);
254 int Context::set_event_char(unsigned char eventch, unsigned char enable)
256 return ftdi_set_event_char(d->ftdi, eventch, enable);
259 int Context::set_error_char(unsigned char errorch, unsigned char enable)
261 return ftdi_set_error_char(d->ftdi, errorch, enable);
264 int Context::bitbang_enable(unsigned char bitmask)
266 return ftdi_enable_bitbang(d->ftdi, bitmask);
269 int Context::bitbang_disable()
271 return ftdi_disable_bitbang(d->ftdi);
274 int Context::set_bitmode(unsigned char bitmask, unsigned char mode)
276 return ftdi_set_bitmode(d->ftdi, bitmask, mode);
279 int Context::read_pins(unsigned char *pins)
281 return ftdi_read_pins(d->ftdi, pins);
284 char* Context::error_string()
286 return ftdi_get_error_string(d->ftdi);
289 int Context::get_strings()
292 char vendor[512], desc[512], serial[512];
294 int ret = ftdi_usb_get_strings(d->ftdi, d->dev, vendor, 512, desc, 512, serial, 512);
300 d->description = desc;
306 /*! \brief Device strings properties.
308 const std::string& Context::vendor()
313 /*! \brief Device strings properties.
315 const std::string& Context::description()
317 return d->description;
320 /*! \brief Device strings properties.
322 const std::string& Context::serial()
327 void Context::set_context(struct ftdi_context* context)
333 void Context::set_usb_device(struct usb_device *dev)
338 struct ftdi_context* Context::context()
343 class Eeprom::Private
350 struct ftdi_eeprom eeprom;
351 struct ftdi_context* context;
354 Eeprom::Eeprom(Context* parent)
355 : d ( new Private() )
357 d->context = parent->context();
364 void Eeprom::init_defaults()
366 return ftdi_eeprom_initdefaults(&d->eeprom);
369 void Eeprom::set_size(int size)
371 return ftdi_eeprom_setsize(d->context, &d->eeprom, size);
374 int Eeprom::size(unsigned char *eeprom, int maxsize)
376 return ftdi_read_eeprom_getsize(d->context, eeprom, maxsize);
379 int Eeprom::chip_id(unsigned int *chipid)
381 return ftdi_read_chipid(d->context, chipid);
384 int Eeprom::build(unsigned char *output)
386 return ftdi_eeprom_build(&d->eeprom, output);
389 int Eeprom::read(unsigned char *eeprom)
391 return ftdi_read_eeprom(d->context, eeprom);
394 int Eeprom::write(unsigned char *eeprom)
396 return ftdi_write_eeprom(d->context, eeprom);
399 int Eeprom::read_location(int eeprom_addr, unsigned short *eeprom_val)
401 return ftdi_read_eeprom_location(d->context, eeprom_addr, eeprom_val);
404 int Eeprom::write_location(int eeprom_addr, unsigned short eeprom_val)
406 return ftdi_write_eeprom_location(d->context, eeprom_addr, eeprom_val);
411 return ftdi_erase_eeprom(d->context);
417 Private(struct ftdi_device_list* _devlist)
424 ftdi_list_free(&devlist);
427 std::list<Context> list;
428 struct ftdi_device_list* devlist;
431 List::List(struct ftdi_device_list* devlist)
432 : d( new Private(devlist) )
437 for (; devlist != 0; devlist = devlist->next)
440 c.set_usb_device(devlist->dev);
442 d->list.push_back(c);
452 * Return begin iterator for accessing the contained list elements
455 List::iterator List::begin()
457 return d->list.begin();
461 * Return end iterator for accessing the contained list elements
464 List::iterator List::end()
466 return d->list.end();
470 * Return begin iterator for accessing the contained list elements
471 * @return Const iterator
473 List::const_iterator List::begin() const
475 return d->list.begin();
479 * Return end iterator for accessing the contained list elements
480 * @return Const iterator
482 List::const_iterator List::end() const
484 return d->list.end();
488 * Return begin reverse iterator for accessing the contained list elements
489 * @return Reverse iterator
491 List::reverse_iterator List::rbegin()
493 return d->list.rbegin();
497 * Return end reverse iterator for accessing the contained list elements
498 * @return Reverse iterator
500 List::reverse_iterator List::rend()
502 return d->list.rend();
506 * Return begin reverse iterator for accessing the contained list elements
507 * @return Const reverse iterator
509 List::const_reverse_iterator List::rbegin() const
511 return d->list.rbegin();
515 * Return end reverse iterator for accessing the contained list elements
516 * @return Const reverse iterator
518 List::const_reverse_iterator List::rend() const
520 return d->list.rend();
525 * Get number of elements stored in the list
526 * @return Number of elements
528 List::ListType::size_type List::size() const
530 return d->list.size();
534 * Check if list is empty
535 * @return True if empty, false otherwise
537 bool List::empty() const
539 return d->list.empty();
543 * Removes all elements. Invalidates all iterators.
544 * Do it in a non-throwing way and also make
545 * sure we really free the allocated memory.
549 ListType().swap(d->list);
554 ftdi_list_free(&d->devlist);
560 * Appends a copy of the element as the new last element.
561 * @param element Value to copy and append
563 void List::push_back(const Context& element)
565 d->list.push_back(element);
569 * Adds a copy of the element as the new first element.
570 * @param element Value to copy and add
572 void List::push_front(const Context& element)
574 d->list.push_front(element);
578 * Erase one element pointed by iterator
579 * @param pos Element to erase
580 * @return Position of the following element (or end())
582 List::iterator List::erase(iterator pos)
584 return d->list.erase(pos);
588 * Erase a range of elements
589 * @param beg Begin of range
590 * @param end End of range
591 * @return Position of the element after the erased range (or end())
593 List::iterator List::erase(iterator beg, iterator end)
595 return d->list.erase(beg, end);
598 List* List::find_all(int vendor, int product)
600 struct ftdi_device_list* dlist = 0;
601 struct ftdi_context ftdi;
603 ftdi_usb_find_all(&ftdi, &dlist, vendor, product);
605 return new List(dlist);