00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
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
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(false,false,false);
00091 }
00092
00093 int Context::open(int vendor, int product, const std::string& description, const std::string& serial, unsigned int index)
00094 {
00095
00096
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(false,!description.empty(),!serial.empty());
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(false,true,false);
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;
00148
00149 switch (mask & (Input | Output)) {
00150 case Input:
00151 ret = ftdi_usb_purge_rx_buffer(d->ftdi);
00152 break;
00153
00154 case Output:
00155 ret = ftdi_usb_purge_tx_buffer(d->ftdi);
00156 break;
00157
00158 case Input | Output:
00159 ret = ftdi_usb_purge_buffers(d->ftdi);
00160 break;
00161
00162 default:
00163
00164 ret = 1;
00165 break;
00166 }
00167
00168 return ret;
00169 }
00170
00171 int Context::set_interface(enum ftdi_interface interface)
00172 {
00173 return ftdi_set_interface(d->ftdi, interface);
00174 }
00175
00176 void Context::set_usb_device(struct libusb_device_handle *dev)
00177 {
00178 ftdi_set_usbdev(d->ftdi, dev);
00179 d->dev = libusb_get_device(dev);
00180 }
00181
00182 int Context::set_baud_rate(int baudrate)
00183 {
00184 return ftdi_set_baudrate(d->ftdi, baudrate);
00185 }
00186
00187 int Context::set_line_property(enum ftdi_bits_type bits, enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity)
00188 {
00189 return ftdi_set_line_property(d->ftdi, bits, sbit, parity);
00190 }
00191
00192 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)
00193 {
00194 return ftdi_set_line_property2(d->ftdi, bits, sbit, parity, break_type);
00195 }
00196
00197 int Context::get_usb_read_timeout() const
00198 {
00199 return d->ftdi->usb_read_timeout;
00200 }
00201
00202 void Context::set_usb_read_timeout(int usb_read_timeout)
00203 {
00204 d->ftdi->usb_read_timeout = usb_read_timeout;
00205 }
00206
00207 int Context::get_usb_write_timeout() const
00208 {
00209 return d->ftdi->usb_write_timeout;
00210 }
00211
00212 void Context::set_usb_write_timeout(int usb_write_timeout)
00213 {
00214 d->ftdi->usb_write_timeout = usb_write_timeout;
00215 }
00216
00217 int Context::read(unsigned char *buf, int size)
00218 {
00219 return ftdi_read_data(d->ftdi, buf, size);
00220 }
00221
00222 int Context::set_read_chunk_size(unsigned int chunksize)
00223 {
00224 return ftdi_read_data_set_chunksize(d->ftdi, chunksize);
00225 }
00226
00227 int Context::read_chunk_size()
00228 {
00229 unsigned chunk = -1;
00230 if (ftdi_read_data_get_chunksize(d->ftdi, &chunk) < 0)
00231 return -1;
00232
00233 return chunk;
00234 }
00235
00236 int Context::write(const unsigned char *buf, int size)
00237 {
00238 return ftdi_write_data(d->ftdi, buf, size);
00239 }
00240
00241 int Context::set_write_chunk_size(unsigned int chunksize)
00242 {
00243 return ftdi_write_data_set_chunksize(d->ftdi, chunksize);
00244 }
00245
00246 int Context::write_chunk_size()
00247 {
00248 unsigned chunk = -1;
00249 if (ftdi_write_data_get_chunksize(d->ftdi, &chunk) < 0)
00250 return -1;
00251
00252 return chunk;
00253 }
00254
00255 int Context::set_flow_control(int flowctrl)
00256 {
00257 return ftdi_setflowctrl(d->ftdi, flowctrl);
00258 }
00259
00260 int Context::set_modem_control(int mask)
00261 {
00262 int dtr = 0, rts = 0;
00263
00264 if (mask & Dtr)
00265 dtr = 1;
00266 if (mask & Rts)
00267 rts = 1;
00268
00269 return ftdi_setdtr_rts(d->ftdi, dtr, rts);
00270 }
00271
00272 int Context::set_dtr(bool state)
00273 {
00274 return ftdi_setdtr(d->ftdi, state);
00275 }
00276
00277 int Context::set_rts(bool state)
00278 {
00279 return ftdi_setrts(d->ftdi, state);
00280 }
00281
00282 int Context::set_latency(unsigned char latency)
00283 {
00284 return ftdi_set_latency_timer(d->ftdi, latency);
00285 }
00286
00287 unsigned Context::latency()
00288 {
00289 unsigned char latency = 0;
00290 ftdi_get_latency_timer(d->ftdi, &latency);
00291 return latency;
00292 }
00293
00294 unsigned short Context::poll_modem_status()
00295 {
00296 unsigned short status = 0;
00297 ftdi_poll_modem_status(d->ftdi, &status);
00298 return status;
00299 }
00300
00301 int Context::set_event_char(unsigned char eventch, unsigned char enable)
00302 {
00303 return ftdi_set_event_char(d->ftdi, eventch, enable);
00304 }
00305
00306 int Context::set_error_char(unsigned char errorch, unsigned char enable)
00307 {
00308 return ftdi_set_error_char(d->ftdi, errorch, enable);
00309 }
00310
00311 int Context::set_bitmode(unsigned char bitmask, unsigned char mode)
00312 {
00313 return ftdi_set_bitmode(d->ftdi, bitmask, mode);
00314 }
00315
00316 int Context::set_bitmode(unsigned char bitmask, enum ftdi_mpsse_mode mode)
00317 {
00318 return ftdi_set_bitmode(d->ftdi, bitmask, mode);
00319 }
00320
00321 int Context::bitbang_disable()
00322 {
00323 return ftdi_disable_bitbang(d->ftdi);
00324 }
00325
00326 int Context::read_pins(unsigned char *pins)
00327 {
00328 return ftdi_read_pins(d->ftdi, pins);
00329 }
00330
00331 const char* Context::error_string()
00332 {
00333 return ftdi_get_error_string(d->ftdi);
00334 }
00335
00336 int Context::get_strings(bool vendor, bool description, bool serial)
00337 {
00338
00339 char ivendor[512], idesc[512], iserial[512];
00340
00341 int ret = ftdi_usb_get_strings(d->ftdi, d->dev, vendor?ivendor:NULL, 512, description?idesc:NULL, 512, serial?iserial:NULL, 512);
00342
00343 if (ret < 0)
00344 return -1;
00345
00346 d->vendor = ivendor;
00347 d->description = idesc;
00348 d->serial = iserial;
00349
00350 return 1;
00351 }
00352
00353 int Context::get_strings_and_reopen(bool vendor, bool description, bool serial)
00354 {
00355 int ret = 0;
00356
00357 if(vendor || description || serial)
00358 {
00359 if (d->dev == 0)
00360 {
00361 d->dev = libusb_get_device(d->ftdi->usb_dev);
00362 }
00363
00364
00365 ret=get_strings(vendor, description, serial);
00366 if (ret < 0)
00367 {
00368 d->open = 0;
00369 return ret;
00370 }
00371
00372
00373 ret = ftdi_usb_open_dev(d->ftdi, d->dev);
00374 d->open = (ret >= 0);
00375 }
00376
00377 return ret;
00378 }
00379
00382 const std::string& Context::vendor()
00383 {
00384 if(d->vendor.empty())
00385 get_strings_and_reopen(true,false,false);
00386 return d->vendor;
00387 }
00388
00391 const std::string& Context::description()
00392 {
00393 if(d->description.empty())
00394 get_strings_and_reopen(false,true,false);
00395 return d->description;
00396 }
00397
00400 const std::string& Context::serial()
00401 {
00402 if(d->serial.empty())
00403 get_strings_and_reopen(false,false,true);
00404 return d->serial;
00405 }
00406
00407 void Context::set_context(struct ftdi_context* context)
00408 {
00409 ftdi_free(d->ftdi);
00410 d->ftdi = context;
00411 }
00412
00413 void Context::set_usb_device(struct libusb_device *dev)
00414 {
00415 d->dev = dev;
00416 }
00417
00418 struct ftdi_context* Context::context()
00419 {
00420 return d->ftdi;
00421 }
00422
00423 class Eeprom::Private
00424 {
00425 public:
00426 Private()
00427 : context(0)
00428 {}
00429
00430 struct ftdi_eeprom eeprom;
00431 struct ftdi_context* context;
00432 };
00433
00434 Eeprom::Eeprom(Context* parent)
00435 : d ( new Private() )
00436 {
00437 d->context = parent->context();
00438 }
00439
00440 Eeprom::~Eeprom()
00441 {
00442 }
00443
00444 int Eeprom::init_defaults(char* manufacturer, char *product, char * serial)
00445 {
00446 return ftdi_eeprom_initdefaults(d->context, manufacturer, product, serial);
00447 }
00448
00449 int Eeprom::chip_id(unsigned int *chipid)
00450 {
00451 return ftdi_read_chipid(d->context, chipid);
00452 }
00453
00454 int Eeprom::build(unsigned char *output)
00455 {
00456 return ftdi_eeprom_build(d->context);
00457 }
00458
00459 int Eeprom::read(unsigned char *eeprom)
00460 {
00461 return ftdi_read_eeprom(d->context);
00462 }
00463
00464 int Eeprom::write(unsigned char *eeprom)
00465 {
00466 return ftdi_write_eeprom(d->context);
00467 }
00468
00469 int Eeprom::read_location(int eeprom_addr, unsigned short *eeprom_val)
00470 {
00471 return ftdi_read_eeprom_location(d->context, eeprom_addr, eeprom_val);
00472 }
00473
00474 int Eeprom::write_location(int eeprom_addr, unsigned short eeprom_val)
00475 {
00476 return ftdi_write_eeprom_location(d->context, eeprom_addr, eeprom_val);
00477 }
00478
00479 int Eeprom::erase()
00480 {
00481 return ftdi_erase_eeprom(d->context);
00482 }
00483
00484 class List::Private
00485 {
00486 public:
00487 Private(struct ftdi_device_list* _devlist)
00488 : devlist(_devlist)
00489 {}
00490
00491 ~Private()
00492 {
00493 if(devlist)
00494 ftdi_list_free(&devlist);
00495 }
00496
00497 std::list<Context> list;
00498 struct ftdi_device_list* devlist;
00499 };
00500
00501 List::List(struct ftdi_device_list* devlist)
00502 : d( new Private(devlist) )
00503 {
00504 if (devlist != 0)
00505 {
00506
00507 for (; devlist != 0; devlist = devlist->next)
00508 {
00509 Context c;
00510 c.set_usb_device(devlist->dev);
00511 c.get_strings();
00512 d->list.push_back(c);
00513 }
00514 }
00515 }
00516
00517 List::~List()
00518 {
00519 }
00520
00525 List::iterator List::begin()
00526 {
00527 return d->list.begin();
00528 }
00529
00534 List::iterator List::end()
00535 {
00536 return d->list.end();
00537 }
00538
00543 List::const_iterator List::begin() const
00544 {
00545 return d->list.begin();
00546 }
00547
00552 List::const_iterator List::end() const
00553 {
00554 return d->list.end();
00555 }
00556
00561 List::reverse_iterator List::rbegin()
00562 {
00563 return d->list.rbegin();
00564 }
00565
00570 List::reverse_iterator List::rend()
00571 {
00572 return d->list.rend();
00573 }
00574
00579 List::const_reverse_iterator List::rbegin() const
00580 {
00581 return d->list.rbegin();
00582 }
00583
00588 List::const_reverse_iterator List::rend() const
00589 {
00590 return d->list.rend();
00591
00592 }
00593
00598 List::ListType::size_type List::size() const
00599 {
00600 return d->list.size();
00601 }
00602
00607 bool List::empty() const
00608 {
00609 return d->list.empty();
00610 }
00611
00617 void List::clear()
00618 {
00619 ListType().swap(d->list);
00620
00621
00622 if (d->devlist)
00623 {
00624 ftdi_list_free(&d->devlist);
00625 d->devlist = 0;
00626 }
00627 }
00628
00633 void List::push_back(const Context& element)
00634 {
00635 d->list.push_back(element);
00636 }
00637
00642 void List::push_front(const Context& element)
00643 {
00644 d->list.push_front(element);
00645 }
00646
00652 List::iterator List::erase(iterator pos)
00653 {
00654 return d->list.erase(pos);
00655 }
00656
00663 List::iterator List::erase(iterator beg, iterator end)
00664 {
00665 return d->list.erase(beg, end);
00666 }
00667
00668 List* List::find_all(Context &context, int vendor, int product)
00669 {
00670 struct ftdi_device_list* dlist = 0;
00671 ftdi_usb_find_all(context.context(), &dlist, vendor, product);
00672 return new List(dlist);
00673 }
00674
00675 }