libftdi
0.19
|
00001 /*************************************************************************** 00002 ftdi.cpp - C++ wraper for libftdi 00003 ------------------- 00004 begin : Mon Oct 13 2008 00005 copyright : (C) 2008 by Marek Vavruša 00006 email : opensource@intra2net.com and marek@vavrusa.com 00007 ***************************************************************************/ 00008 /* 00009 Copyright (C) 2008 by Marek Vavruša 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 "ftdi.hpp" 00030 #include "ftdi.h" 00031 00032 namespace Ftdi 00033 { 00034 00035 class Context::Private 00036 { 00037 public: 00038 Private() 00039 : ftdi(0), dev(0), open(false) 00040 { 00041 ftdi = ftdi_new(); 00042 } 00043 00044 ~Private() 00045 { 00046 if (open) 00047 ftdi_usb_close(ftdi); 00048 00049 ftdi_free(ftdi); 00050 } 00051 00052 bool open; 00053 00054 struct ftdi_context* ftdi; 00055 struct usb_device* dev; 00056 00057 std::string vendor; 00058 std::string description; 00059 std::string serial; 00060 }; 00061 00064 Context::Context() 00065 : d( new Private() ) 00066 { 00067 } 00068 00071 Context::~Context() 00072 { 00073 } 00074 00075 bool Context::is_open() 00076 { 00077 return d->open; 00078 } 00079 00080 int Context::open(int vendor, int product) 00081 { 00082 // Open device 00083 int ret = ftdi_usb_open(d->ftdi, vendor, product); 00084 00085 if (ret < 0) 00086 return ret; 00087 00088 return get_strings_and_reopen(); 00089 } 00090 00091 int Context::open(int vendor, int product, const std::string& description, const std::string& serial, unsigned int index) 00092 { 00093 // translate empty strings to NULL 00094 // -> do not use them to find the device (vs. require an empty string to be set in the EEPROM) 00095 const char* c_description=NULL; 00096 const char* c_serial=NULL; 00097 if (!description.empty()) 00098 c_description=description.c_str(); 00099 if (!serial.empty()) 00100 c_serial=serial.c_str(); 00101 00102 int ret = ftdi_usb_open_desc_index(d->ftdi, vendor, product, c_description, c_serial, index); 00103 00104 if (ret < 0) 00105 return ret; 00106 00107 return get_strings_and_reopen(); 00108 } 00109 00110 int Context::open(const std::string& description) 00111 { 00112 int ret = ftdi_usb_open_string(d->ftdi, description.c_str()); 00113 00114 if (ret < 0) 00115 return ret; 00116 00117 return get_strings_and_reopen(); 00118 } 00119 00120 int Context::open(struct usb_device *dev) 00121 { 00122 if (dev != 0) 00123 d->dev = dev; 00124 00125 if (d->dev == 0) 00126 return -1; 00127 00128 return get_strings_and_reopen(); 00129 } 00130 00131 int Context::close() 00132 { 00133 d->open = false; 00134 return ftdi_usb_close(d->ftdi); 00135 } 00136 00137 int Context::reset() 00138 { 00139 return ftdi_usb_reset(d->ftdi); 00140 } 00141 00142 int Context::flush(int mask) 00143 { 00144 int ret = 1; 00145 00146 if (mask & Input) 00147 ret &= ftdi_usb_purge_rx_buffer(d->ftdi); 00148 if (mask & Output) 00149 ret &= ftdi_usb_purge_tx_buffer(d->ftdi); 00150 00151 return ret; 00152 } 00153 00154 int Context::set_interface(enum ftdi_interface interface) 00155 { 00156 return ftdi_set_interface(d->ftdi, interface); 00157 } 00158 00159 void Context::set_usb_device(struct usb_dev_handle *dev) 00160 { 00161 ftdi_set_usbdev(d->ftdi, dev); 00162 d->dev = usb_device(dev); 00163 } 00164 00165 int Context::set_baud_rate(int baudrate) 00166 { 00167 return ftdi_set_baudrate(d->ftdi, baudrate); 00168 } 00169 00170 int Context::set_line_property(enum ftdi_bits_type bits, enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity) 00171 { 00172 return ftdi_set_line_property(d->ftdi, bits, sbit, parity); 00173 } 00174 00175 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) 00176 { 00177 return ftdi_set_line_property2(d->ftdi, bits, sbit, parity, break_type); 00178 } 00179 00180 int Context::read(unsigned char *buf, int size) 00181 { 00182 return ftdi_read_data(d->ftdi, buf, size); 00183 } 00184 00185 int Context::set_read_chunk_size(unsigned int chunksize) 00186 { 00187 return ftdi_read_data_set_chunksize(d->ftdi, chunksize); 00188 } 00189 00190 int Context::read_chunk_size() 00191 { 00192 unsigned chunk = -1; 00193 if (ftdi_read_data_get_chunksize(d->ftdi, &chunk) < 0) 00194 return -1; 00195 00196 return chunk; 00197 } 00198 00199 int Context::write(unsigned char *buf, int size) 00200 { 00201 return ftdi_write_data(d->ftdi, buf, size); 00202 } 00203 00204 int Context::set_write_chunk_size(unsigned int chunksize) 00205 { 00206 return ftdi_write_data_set_chunksize(d->ftdi, chunksize); 00207 } 00208 00209 int Context::write_chunk_size() 00210 { 00211 unsigned chunk = -1; 00212 if (ftdi_write_data_get_chunksize(d->ftdi, &chunk) < 0) 00213 return -1; 00214 00215 return chunk; 00216 } 00217 00218 int Context::set_flow_control(int flowctrl) 00219 { 00220 return ftdi_setflowctrl(d->ftdi, flowctrl); 00221 } 00222 00223 int Context::set_modem_control(int mask) 00224 { 00225 int dtr = 0, rts = 0; 00226 00227 if (mask & Dtr) 00228 dtr = 1; 00229 if (mask & Rts) 00230 rts = 1; 00231 00232 return ftdi_setdtr_rts(d->ftdi, dtr, rts); 00233 } 00234 00235 int Context::set_dtr(bool state) 00236 { 00237 return ftdi_setdtr(d->ftdi, state); 00238 } 00239 00240 int Context::set_rts(bool state) 00241 { 00242 return ftdi_setrts(d->ftdi, state); 00243 } 00244 00245 int Context::set_latency(unsigned char latency) 00246 { 00247 return ftdi_set_latency_timer(d->ftdi, latency); 00248 } 00249 00250 unsigned Context::latency() 00251 { 00252 unsigned char latency = 0; 00253 ftdi_get_latency_timer(d->ftdi, &latency); 00254 return latency; 00255 } 00256 00257 unsigned short Context::poll_modem_status() 00258 { 00259 unsigned short status = 0; 00260 ftdi_poll_modem_status(d->ftdi, &status); 00261 return status; 00262 } 00263 00264 int Context::set_event_char(unsigned char eventch, unsigned char enable) 00265 { 00266 return ftdi_set_event_char(d->ftdi, eventch, enable); 00267 } 00268 00269 int Context::set_error_char(unsigned char errorch, unsigned char enable) 00270 { 00271 return ftdi_set_error_char(d->ftdi, errorch, enable); 00272 } 00273 00274 int Context::bitbang_enable(unsigned char bitmask) 00275 { 00276 return ftdi_set_bitmode(d->ftdi, bitmask, BITMODE_BITBANG); 00277 } 00278 00279 int Context::bitbang_disable() 00280 { 00281 return ftdi_disable_bitbang(d->ftdi); 00282 } 00283 00284 int Context::set_bitmode(unsigned char bitmask, unsigned char mode) 00285 { 00286 return ftdi_set_bitmode(d->ftdi, bitmask, mode); 00287 } 00288 00289 int Context::set_bitmode(unsigned char bitmask, enum ftdi_mpsse_mode mode) 00290 { 00291 return ftdi_set_bitmode(d->ftdi, bitmask, mode); 00292 } 00293 00294 int Context::read_pins(unsigned char *pins) 00295 { 00296 return ftdi_read_pins(d->ftdi, pins); 00297 } 00298 00299 char* Context::error_string() 00300 { 00301 return ftdi_get_error_string(d->ftdi); 00302 } 00303 00304 int Context::get_strings() 00305 { 00306 // Prepare buffers 00307 char vendor[512], desc[512], serial[512]; 00308 00309 int ret = ftdi_usb_get_strings(d->ftdi, d->dev, vendor, 512, desc, 512, serial, 512); 00310 00311 if (ret < 0) 00312 return -1; 00313 00314 d->vendor = vendor; 00315 d->description = desc; 00316 d->serial = serial; 00317 00318 return 1; 00319 } 00320 00321 int Context::get_strings_and_reopen() 00322 { 00323 // Get device strings (closes device) 00324 int ret=get_strings(); 00325 if (ret < 0) 00326 { 00327 d->open = 0; 00328 return ret; 00329 } 00330 00331 // Reattach device 00332 ret = ftdi_usb_open_dev(d->ftdi, d->dev); 00333 d->open = (ret >= 0); 00334 00335 return ret; 00336 } 00337 00340 const std::string& Context::vendor() 00341 { 00342 return d->vendor; 00343 } 00344 00347 const std::string& Context::description() 00348 { 00349 return d->description; 00350 } 00351 00354 const std::string& Context::serial() 00355 { 00356 return d->serial; 00357 } 00358 00359 void Context::set_context(struct ftdi_context* context) 00360 { 00361 ftdi_free(d->ftdi); 00362 d->ftdi = context; 00363 } 00364 00365 void Context::set_usb_device(struct usb_device *dev) 00366 { 00367 d->dev = dev; 00368 } 00369 00370 struct ftdi_context* Context::context() 00371 { 00372 return d->ftdi; 00373 } 00374 00375 class Eeprom::Private 00376 { 00377 public: 00378 Private() 00379 : context(0) 00380 {} 00381 00382 struct ftdi_eeprom eeprom; 00383 struct ftdi_context* context; 00384 }; 00385 00386 Eeprom::Eeprom(Context* parent) 00387 : d ( new Private() ) 00388 { 00389 d->context = parent->context(); 00390 } 00391 00392 Eeprom::~Eeprom() 00393 { 00394 } 00395 00396 void Eeprom::init_defaults() 00397 { 00398 return ftdi_eeprom_initdefaults(&d->eeprom); 00399 } 00400 00401 void Eeprom::set_size(int size) 00402 { 00403 return ftdi_eeprom_setsize(d->context, &d->eeprom, size); 00404 } 00405 00406 int Eeprom::size(unsigned char *eeprom, int maxsize) 00407 { 00408 return ftdi_read_eeprom_getsize(d->context, eeprom, maxsize); 00409 } 00410 00411 int Eeprom::chip_id(unsigned int *chipid) 00412 { 00413 return ftdi_read_chipid(d->context, chipid); 00414 } 00415 00416 int Eeprom::build(unsigned char *output) 00417 { 00418 return ftdi_eeprom_build(&d->eeprom, output); 00419 } 00420 00421 int Eeprom::read(unsigned char *eeprom) 00422 { 00423 return ftdi_read_eeprom(d->context, eeprom); 00424 } 00425 00426 int Eeprom::write(unsigned char *eeprom) 00427 { 00428 return ftdi_write_eeprom(d->context, eeprom); 00429 } 00430 00431 int Eeprom::read_location(int eeprom_addr, unsigned short *eeprom_val) 00432 { 00433 return ftdi_read_eeprom_location(d->context, eeprom_addr, eeprom_val); 00434 } 00435 00436 int Eeprom::write_location(int eeprom_addr, unsigned short eeprom_val) 00437 { 00438 return ftdi_write_eeprom_location(d->context, eeprom_addr, eeprom_val); 00439 } 00440 00441 int Eeprom::erase() 00442 { 00443 return ftdi_erase_eeprom(d->context); 00444 } 00445 00446 class List::Private 00447 { 00448 public: 00449 Private(struct ftdi_device_list* _devlist) 00450 : devlist(_devlist) 00451 {} 00452 00453 ~Private() 00454 { 00455 if(devlist) 00456 ftdi_list_free(&devlist); 00457 } 00458 00459 std::list<Context> list; 00460 struct ftdi_device_list* devlist; 00461 }; 00462 00463 List::List(struct ftdi_device_list* devlist) 00464 : d( new Private(devlist) ) 00465 { 00466 if (devlist != 0) 00467 { 00468 // Iterate list 00469 for (; devlist != 0; devlist = devlist->next) 00470 { 00471 Context c; 00472 c.set_usb_device(devlist->dev); 00473 c.get_strings(); 00474 d->list.push_back(c); 00475 } 00476 } 00477 } 00478 00479 List::~List() 00480 { 00481 } 00482 00487 List::iterator List::begin() 00488 { 00489 return d->list.begin(); 00490 } 00491 00496 List::iterator List::end() 00497 { 00498 return d->list.end(); 00499 } 00500 00505 List::const_iterator List::begin() const 00506 { 00507 return d->list.begin(); 00508 } 00509 00514 List::const_iterator List::end() const 00515 { 00516 return d->list.end(); 00517 } 00518 00523 List::reverse_iterator List::rbegin() 00524 { 00525 return d->list.rbegin(); 00526 } 00527 00532 List::reverse_iterator List::rend() 00533 { 00534 return d->list.rend(); 00535 } 00536 00541 List::const_reverse_iterator List::rbegin() const 00542 { 00543 return d->list.rbegin(); 00544 } 00545 00550 List::const_reverse_iterator List::rend() const 00551 { 00552 return d->list.rend(); 00553 00554 } 00555 00560 List::ListType::size_type List::size() const 00561 { 00562 return d->list.size(); 00563 } 00564 00569 bool List::empty() const 00570 { 00571 return d->list.empty(); 00572 } 00573 00579 void List::clear() 00580 { 00581 ListType().swap(d->list); 00582 00583 // Free device list 00584 if (d->devlist) 00585 { 00586 ftdi_list_free(&d->devlist); 00587 d->devlist = 0; 00588 } 00589 } 00590 00595 void List::push_back(const Context& element) 00596 { 00597 d->list.push_back(element); 00598 } 00599 00604 void List::push_front(const Context& element) 00605 { 00606 d->list.push_front(element); 00607 } 00608 00614 List::iterator List::erase(iterator pos) 00615 { 00616 return d->list.erase(pos); 00617 } 00618 00625 List::iterator List::erase(iterator beg, iterator end) 00626 { 00627 return d->list.erase(beg, end); 00628 } 00629 00630 List* List::find_all(int vendor, int product) 00631 { 00632 struct ftdi_device_list* dlist = 0; 00633 struct ftdi_context ftdi; 00634 ftdi_init(&ftdi); 00635 ftdi_usb_find_all(&ftdi, &dlist, vendor, product); 00636 ftdi_deinit(&ftdi); 00637 return new List(dlist); 00638 } 00639 00640 }