|
libftdi1
1.0
|
00001 /*************************************************************************** 00002 ftdi.cpp - C++ wraper for libftdi 00003 ------------------- 00004 begin : Mon Oct 13 2008 00005 copyright : (C) 2008-2013 by Marek Vavruša / libftdi developers 00006 email : opensource@intra2net.com and marek@vavrusa.com 00007 ***************************************************************************/ 00008 /* 00009 Copyright (C) 2008-2013 by Marek Vavruša / libftdi developers 00010 00011 The software in this package is distributed under the GNU General 00012 Public License version 2 (with a special exception described below). 00013 00014 A copy of GNU General Public License (GPL) is included in this distribution, 00015 in the file COPYING.GPL. 00016 00017 As a special exception, if other files instantiate templates or use macros 00018 or inline functions from this file, or you compile this file and link it 00019 with other works to produce a work based on this file, this file 00020 does not by itself cause the resulting work to be covered 00021 by the GNU General Public License. 00022 00023 However the source code for this file must still be made available 00024 in accordance with section (3) of the GNU General Public License. 00025 00026 This exception does not invalidate any other reasons why a work based 00027 on this file might be covered by the GNU General Public License. 00028 */ 00029 #include <libusb.h> 00030 #include "ftdi.hpp" 00031 #include "ftdi_i.h" 00032 #include "ftdi.h" 00033 00034 namespace Ftdi 00035 { 00036 00037 class Context::Private 00038 { 00039 public: 00040 Private() 00041 : open(false), ftdi(0), dev(0) 00042 { 00043 ftdi = ftdi_new(); 00044 } 00045 00046 ~Private() 00047 { 00048 if (open) 00049 ftdi_usb_close(ftdi); 00050 00051 ftdi_free(ftdi); 00052 } 00053 00054 bool open; 00055 00056 struct ftdi_context* ftdi; 00057 struct libusb_device* dev; 00058 00059 std::string vendor; 00060 std::string description; 00061 std::string serial; 00062 }; 00063 00066 Context::Context() 00067 : d( new Private() ) 00068 { 00069 } 00070 00073 Context::~Context() 00074 { 00075 } 00076 00077 bool Context::is_open() 00078 { 00079 return d->open; 00080 } 00081 00082 int Context::open(int vendor, int product) 00083 { 00084 // Open device 00085 int ret = ftdi_usb_open(d->ftdi, vendor, product); 00086 00087 if (ret < 0) 00088 return ret; 00089 00090 return get_strings_and_reopen(); 00091 } 00092 00093 int Context::open(int vendor, int product, const std::string& description, const std::string& serial, unsigned int index) 00094 { 00095 // translate empty strings to NULL 00096 // -> do not use them to find the device (vs. require an empty string to be set in the EEPROM) 00097 const char* c_description=NULL; 00098 const char* c_serial=NULL; 00099 if (!description.empty()) 00100 c_description=description.c_str(); 00101 if (!serial.empty()) 00102 c_serial=serial.c_str(); 00103 00104 int ret = ftdi_usb_open_desc_index(d->ftdi, vendor, product, c_description, c_serial, index); 00105 00106 if (ret < 0) 00107 return ret; 00108 00109 return get_strings_and_reopen(); 00110 } 00111 00112 int Context::open(const std::string& description) 00113 { 00114 int ret = ftdi_usb_open_string(d->ftdi, description.c_str()); 00115 00116 if (ret < 0) 00117 return ret; 00118 00119 return get_strings_and_reopen(); 00120 } 00121 00122 int Context::open(struct libusb_device *dev) 00123 { 00124 if (dev != 0) 00125 d->dev = dev; 00126 00127 if (d->dev == 0) 00128 return -1; 00129 00130 return get_strings_and_reopen(); 00131 } 00132 00133 int Context::close() 00134 { 00135 d->open = false; 00136 d->dev = 0; 00137 return ftdi_usb_close(d->ftdi); 00138 } 00139 00140 int Context::reset() 00141 { 00142 return ftdi_usb_reset(d->ftdi); 00143 } 00144 00145 int Context::flush(int mask) 00146 { 00147 int ret = 1; 00148 00149 if (mask & Input) 00150 ret &= ftdi_usb_purge_rx_buffer(d->ftdi); 00151 if (mask & Output) 00152 ret &= ftdi_usb_purge_tx_buffer(d->ftdi); 00153 00154 return ret; 00155 } 00156 00157 int Context::set_interface(enum ftdi_interface interface) 00158 { 00159 return ftdi_set_interface(d->ftdi, interface); 00160 } 00161 00162 void Context::set_usb_device(struct libusb_device_handle *dev) 00163 { 00164 ftdi_set_usbdev(d->ftdi, dev); 00165 d->dev = libusb_get_device(dev); 00166 } 00167 00168 int Context::set_baud_rate(int baudrate) 00169 { 00170 return ftdi_set_baudrate(d->ftdi, baudrate); 00171 } 00172 00173 int Context::set_line_property(enum ftdi_bits_type bits, enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity) 00174 { 00175 return ftdi_set_line_property(d->ftdi, bits, sbit, parity); 00176 } 00177 00178 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) 00179 { 00180 return ftdi_set_line_property2(d->ftdi, bits, sbit, parity, break_type); 00181 } 00182 00183 int Context::read(unsigned char *buf, int size) 00184 { 00185 return ftdi_read_data(d->ftdi, buf, size); 00186 } 00187 00188 int Context::set_read_chunk_size(unsigned int chunksize) 00189 { 00190 return ftdi_read_data_set_chunksize(d->ftdi, chunksize); 00191 } 00192 00193 int Context::read_chunk_size() 00194 { 00195 unsigned chunk = -1; 00196 if (ftdi_read_data_get_chunksize(d->ftdi, &chunk) < 0) 00197 return -1; 00198 00199 return chunk; 00200 } 00201 00202 int Context::write(unsigned char *buf, int size) 00203 { 00204 return ftdi_write_data(d->ftdi, buf, size); 00205 } 00206 00207 int Context::set_write_chunk_size(unsigned int chunksize) 00208 { 00209 return ftdi_write_data_set_chunksize(d->ftdi, chunksize); 00210 } 00211 00212 int Context::write_chunk_size() 00213 { 00214 unsigned chunk = -1; 00215 if (ftdi_write_data_get_chunksize(d->ftdi, &chunk) < 0) 00216 return -1; 00217 00218 return chunk; 00219 } 00220 00221 int Context::set_flow_control(int flowctrl) 00222 { 00223 return ftdi_setflowctrl(d->ftdi, flowctrl); 00224 } 00225 00226 int Context::set_modem_control(int mask) 00227 { 00228 int dtr = 0, rts = 0; 00229 00230 if (mask & Dtr) 00231 dtr = 1; 00232 if (mask & Rts) 00233 rts = 1; 00234 00235 return ftdi_setdtr_rts(d->ftdi, dtr, rts); 00236 } 00237 00238 int Context::set_dtr(bool state) 00239 { 00240 return ftdi_setdtr(d->ftdi, state); 00241 } 00242 00243 int Context::set_rts(bool state) 00244 { 00245 return ftdi_setrts(d->ftdi, state); 00246 } 00247 00248 int Context::set_latency(unsigned char latency) 00249 { 00250 return ftdi_set_latency_timer(d->ftdi, latency); 00251 } 00252 00253 unsigned Context::latency() 00254 { 00255 unsigned char latency = 0; 00256 ftdi_get_latency_timer(d->ftdi, &latency); 00257 return latency; 00258 } 00259 00260 unsigned short Context::poll_modem_status() 00261 { 00262 unsigned short status = 0; 00263 ftdi_poll_modem_status(d->ftdi, &status); 00264 return status; 00265 } 00266 00267 int Context::set_event_char(unsigned char eventch, unsigned char enable) 00268 { 00269 return ftdi_set_event_char(d->ftdi, eventch, enable); 00270 } 00271 00272 int Context::set_error_char(unsigned char errorch, unsigned char enable) 00273 { 00274 return ftdi_set_error_char(d->ftdi, errorch, enable); 00275 } 00276 00277 int Context::set_bitmode(unsigned char bitmask, unsigned char mode) 00278 { 00279 return ftdi_set_bitmode(d->ftdi, bitmask, mode); 00280 } 00281 00282 int Context::set_bitmode(unsigned char bitmask, enum ftdi_mpsse_mode mode) 00283 { 00284 return ftdi_set_bitmode(d->ftdi, bitmask, mode); 00285 } 00286 00287 int Context::bitbang_disable() 00288 { 00289 return ftdi_disable_bitbang(d->ftdi); 00290 } 00291 00292 int Context::read_pins(unsigned char *pins) 00293 { 00294 return ftdi_read_pins(d->ftdi, pins); 00295 } 00296 00297 char* Context::error_string() 00298 { 00299 return ftdi_get_error_string(d->ftdi); 00300 } 00301 00302 int Context::get_strings() 00303 { 00304 // Prepare buffers 00305 char vendor[512], desc[512], serial[512]; 00306 00307 int ret = ftdi_usb_get_strings(d->ftdi, d->dev, vendor, 512, desc, 512, serial, 512); 00308 00309 if (ret < 0) 00310 return -1; 00311 00312 d->vendor = vendor; 00313 d->description = desc; 00314 d->serial = serial; 00315 00316 return 1; 00317 } 00318 00319 int Context::get_strings_and_reopen() 00320 { 00321 if ( d->dev == 0 ) 00322 { 00323 d->dev = libusb_get_device(d->ftdi->usb_dev); 00324 } 00325 00326 // Get device strings (closes device) 00327 int ret=get_strings(); 00328 if (ret < 0) 00329 { 00330 d->open = 0; 00331 return ret; 00332 } 00333 00334 // Reattach device 00335 ret = ftdi_usb_open_dev(d->ftdi, d->dev); 00336 d->open = (ret >= 0); 00337 00338 return ret; 00339 } 00340 00343 const std::string& Context::vendor() 00344 { 00345 return d->vendor; 00346 } 00347 00350 const std::string& Context::description() 00351 { 00352 return d->description; 00353 } 00354 00357 const std::string& Context::serial() 00358 { 00359 return d->serial; 00360 } 00361 00362 void Context::set_context(struct ftdi_context* context) 00363 { 00364 ftdi_free(d->ftdi); 00365 d->ftdi = context; 00366 } 00367 00368 void Context::set_usb_device(struct libusb_device *dev) 00369 { 00370 d->dev = dev; 00371 } 00372 00373 struct ftdi_context* Context::context() 00374 { 00375 return d->ftdi; 00376 } 00377 00378 class Eeprom::Private 00379 { 00380 public: 00381 Private() 00382 : context(0) 00383 {} 00384 00385 struct ftdi_eeprom eeprom; 00386 struct ftdi_context* context; 00387 }; 00388 00389 Eeprom::Eeprom(Context* parent) 00390 : d ( new Private() ) 00391 { 00392 d->context = parent->context(); 00393 } 00394 00395 Eeprom::~Eeprom() 00396 { 00397 } 00398 00399 int Eeprom::init_defaults(char* manufacturer, char *product, char * serial) 00400 { 00401 return ftdi_eeprom_initdefaults(d->context, manufacturer, product, serial); 00402 } 00403 00404 int Eeprom::chip_id(unsigned int *chipid) 00405 { 00406 return ftdi_read_chipid(d->context, chipid); 00407 } 00408 00409 int Eeprom::build(unsigned char *output) 00410 { 00411 return ftdi_eeprom_build(d->context); 00412 } 00413 00414 int Eeprom::read(unsigned char *eeprom) 00415 { 00416 return ftdi_read_eeprom(d->context); 00417 } 00418 00419 int Eeprom::write(unsigned char *eeprom) 00420 { 00421 return ftdi_write_eeprom(d->context); 00422 } 00423 00424 int Eeprom::read_location(int eeprom_addr, unsigned short *eeprom_val) 00425 { 00426 return ftdi_read_eeprom_location(d->context, eeprom_addr, eeprom_val); 00427 } 00428 00429 int Eeprom::write_location(int eeprom_addr, unsigned short eeprom_val) 00430 { 00431 return ftdi_write_eeprom_location(d->context, eeprom_addr, eeprom_val); 00432 } 00433 00434 int Eeprom::erase() 00435 { 00436 return ftdi_erase_eeprom(d->context); 00437 } 00438 00439 class List::Private 00440 { 00441 public: 00442 Private(struct ftdi_device_list* _devlist) 00443 : devlist(_devlist) 00444 {} 00445 00446 ~Private() 00447 { 00448 if(devlist) 00449 ftdi_list_free(&devlist); 00450 } 00451 00452 std::list<Context> list; 00453 struct ftdi_device_list* devlist; 00454 }; 00455 00456 List::List(struct ftdi_device_list* devlist) 00457 : d( new Private(devlist) ) 00458 { 00459 if (devlist != 0) 00460 { 00461 // Iterate list 00462 for (; devlist != 0; devlist = devlist->next) 00463 { 00464 Context c; 00465 c.set_usb_device(devlist->dev); 00466 c.get_strings(); 00467 d->list.push_back(c); 00468 } 00469 } 00470 } 00471 00472 List::~List() 00473 { 00474 } 00475 00480 List::iterator List::begin() 00481 { 00482 return d->list.begin(); 00483 } 00484 00489 List::iterator List::end() 00490 { 00491 return d->list.end(); 00492 } 00493 00498 List::const_iterator List::begin() const 00499 { 00500 return d->list.begin(); 00501 } 00502 00507 List::const_iterator List::end() const 00508 { 00509 return d->list.end(); 00510 } 00511 00516 List::reverse_iterator List::rbegin() 00517 { 00518 return d->list.rbegin(); 00519 } 00520 00525 List::reverse_iterator List::rend() 00526 { 00527 return d->list.rend(); 00528 } 00529 00534 List::const_reverse_iterator List::rbegin() const 00535 { 00536 return d->list.rbegin(); 00537 } 00538 00543 List::const_reverse_iterator List::rend() const 00544 { 00545 return d->list.rend(); 00546 00547 } 00548 00553 List::ListType::size_type List::size() const 00554 { 00555 return d->list.size(); 00556 } 00557 00562 bool List::empty() const 00563 { 00564 return d->list.empty(); 00565 } 00566 00572 void List::clear() 00573 { 00574 ListType().swap(d->list); 00575 00576 // Free device list 00577 if (d->devlist) 00578 { 00579 ftdi_list_free(&d->devlist); 00580 d->devlist = 0; 00581 } 00582 } 00583 00588 void List::push_back(const Context& element) 00589 { 00590 d->list.push_back(element); 00591 } 00592 00597 void List::push_front(const Context& element) 00598 { 00599 d->list.push_front(element); 00600 } 00601 00607 List::iterator List::erase(iterator pos) 00608 { 00609 return d->list.erase(pos); 00610 } 00611 00618 List::iterator List::erase(iterator beg, iterator end) 00619 { 00620 return d->list.erase(beg, end); 00621 } 00622 00623 List* List::find_all(Context &context, int vendor, int product) 00624 { 00625 struct ftdi_device_list* dlist = 0; 00626 ftdi_usb_find_all(context.context(), &dlist, vendor, product); 00627 return new List(dlist); 00628 } 00629 00630 }
1.7.6.1