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 "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
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
00094
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 set_bitmode(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
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
00324 int ret=get_strings();
00325 if (ret < 0)
00326 {
00327 d->open = 0;
00328 return ret;
00329 }
00330
00331
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
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
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 }