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, const std::string& description, const std::string& serial)
00081 {
00082 int ret = 0;
00083
00084
00085 if (description.empty() && serial.empty())
00086 ret = ftdi_usb_open(d->ftdi, vendor, product);
00087 else
00088 ret = ftdi_usb_open_desc(d->ftdi, vendor, product, description.c_str(), serial.c_str());
00089
00090 if (ret < 0)
00091 return ret;
00092
00093
00094 get_strings();
00095
00096
00097 ret = ftdi_usb_open_dev(d->ftdi, d->dev);
00098 d->open = (ret >= 0);
00099
00100 return ret;
00101 }
00102
00103 int Context::open(struct usb_device *dev)
00104 {
00105 if (dev != 0)
00106 d->dev = dev;
00107
00108 if (d->dev == 0)
00109 return -1;
00110
00111
00112 get_strings();
00113
00114
00115 int ret = ftdi_usb_open_dev(d->ftdi, d->dev);
00116 d->open = (ret >= 0);
00117
00118 return ret;
00119 }
00120
00121 int Context::close()
00122 {
00123 d->open = false;
00124 return ftdi_usb_close(d->ftdi);
00125 }
00126
00127 int Context::reset()
00128 {
00129 return ftdi_usb_reset(d->ftdi);
00130 }
00131
00132 int Context::flush(int mask)
00133 {
00134 int ret = 1;
00135
00136 if (mask & Input)
00137 ret &= ftdi_usb_purge_rx_buffer(d->ftdi);
00138 if (mask & Output)
00139 ret &= ftdi_usb_purge_tx_buffer(d->ftdi);
00140
00141 return ret;
00142 }
00143
00144 int Context::set_interface(enum ftdi_interface interface)
00145 {
00146 return ftdi_set_interface(d->ftdi, interface);
00147 }
00148
00149 void Context::set_usb_device(struct usb_dev_handle *dev)
00150 {
00151 ftdi_set_usbdev(d->ftdi, dev);
00152 d->dev = usb_device(dev);
00153 }
00154
00155 int Context::set_baud_rate(int baudrate)
00156 {
00157 return ftdi_set_baudrate(d->ftdi, baudrate);
00158 }
00159
00160 int Context::set_line_property(enum ftdi_bits_type bits, enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity)
00161 {
00162 return ftdi_set_line_property(d->ftdi, bits, sbit, parity);
00163 }
00164
00165 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)
00166 {
00167 return ftdi_set_line_property2(d->ftdi, bits, sbit, parity, break_type);
00168 }
00169
00170 int Context::read(unsigned char *buf, int size)
00171 {
00172 return ftdi_read_data(d->ftdi, buf, size);
00173 }
00174
00175 int Context::set_read_chunk_size(unsigned int chunksize)
00176 {
00177 return ftdi_read_data_set_chunksize(d->ftdi, chunksize);
00178 }
00179
00180 int Context::read_chunk_size()
00181 {
00182 unsigned chunk = -1;
00183 if (ftdi_read_data_get_chunksize(d->ftdi, &chunk) < 0)
00184 return -1;
00185
00186 return chunk;
00187 }
00188
00189 int Context::write(unsigned char *buf, int size)
00190 {
00191 return ftdi_write_data(d->ftdi, buf, size);
00192 }
00193
00194 int Context::set_write_chunk_size(unsigned int chunksize)
00195 {
00196 return ftdi_write_data_set_chunksize(d->ftdi, chunksize);
00197 }
00198
00199 int Context::write_chunk_size()
00200 {
00201 unsigned chunk = -1;
00202 if (ftdi_write_data_get_chunksize(d->ftdi, &chunk) < 0)
00203 return -1;
00204
00205 return chunk;
00206 }
00207
00208 int Context::set_flow_control(int flowctrl)
00209 {
00210 return ftdi_setflowctrl(d->ftdi, flowctrl);
00211 }
00212
00213 int Context::set_modem_control(int mask)
00214 {
00215 int dtr = 0, rts = 0;
00216
00217 if (mask & Dtr)
00218 dtr = 1;
00219 if (mask & Rts)
00220 rts = 1;
00221
00222 return ftdi_setdtr_rts(d->ftdi, dtr, rts);
00223 }
00224
00225 int Context::set_dtr(bool state)
00226 {
00227 return ftdi_setdtr(d->ftdi, state);
00228 }
00229
00230 int Context::set_rts(bool state)
00231 {
00232 return ftdi_setrts(d->ftdi, state);
00233 }
00234
00235 int Context::set_latency(unsigned char latency)
00236 {
00237 return ftdi_set_latency_timer(d->ftdi, latency);
00238 }
00239
00240 unsigned Context::latency()
00241 {
00242 unsigned char latency = 0;
00243 ftdi_get_latency_timer(d->ftdi, &latency);
00244 return latency;
00245 }
00246
00247 unsigned short Context::poll_modem_status()
00248 {
00249 unsigned short status = 0;
00250 ftdi_poll_modem_status(d->ftdi, &status);
00251 return status;
00252 }
00253
00254 int Context::set_event_char(unsigned char eventch, unsigned char enable)
00255 {
00256 return ftdi_set_event_char(d->ftdi, eventch, enable);
00257 }
00258
00259 int Context::set_error_char(unsigned char errorch, unsigned char enable)
00260 {
00261 return ftdi_set_error_char(d->ftdi, errorch, enable);
00262 }
00263
00264 int Context::bitbang_enable(unsigned char bitmask)
00265 {
00266 return ftdi_enable_bitbang(d->ftdi, bitmask);
00267 }
00268
00269 int Context::bitbang_disable()
00270 {
00271 return ftdi_disable_bitbang(d->ftdi);
00272 }
00273
00274 int Context::set_bitmode(unsigned char bitmask, unsigned char mode)
00275 {
00276 return ftdi_set_bitmode(d->ftdi, bitmask, mode);
00277 }
00278
00279 int Context::read_pins(unsigned char *pins)
00280 {
00281 return ftdi_read_pins(d->ftdi, pins);
00282 }
00283
00284 char* Context::error_string()
00285 {
00286 return ftdi_get_error_string(d->ftdi);
00287 }
00288
00289 int Context::get_strings()
00290 {
00291
00292 char vendor[512], desc[512], serial[512];
00293
00294 int ret = ftdi_usb_get_strings(d->ftdi, d->dev, vendor, 512, desc, 512, serial, 512);
00295
00296 if (ret < 0)
00297 return -1;
00298
00299 d->vendor = vendor;
00300 d->description = desc;
00301 d->serial = serial;
00302
00303 return 1;
00304 }
00305
00311 const std::string& Context::vendor()
00312 {
00313 return d->vendor;
00314 }
00315
00316 const std::string& Context::description()
00317 {
00318 return d->description;
00319 }
00320
00321 const std::string& Context::serial()
00322 {
00323 return d->serial;
00324 }
00325
00326 void Context::set_context(struct ftdi_context* context)
00327 {
00328 ftdi_free(d->ftdi);
00329 d->ftdi = context;
00330 }
00331
00332 void Context::set_usb_device(struct usb_device *dev)
00333 {
00334 d->dev = dev;
00335 }
00336
00337 struct ftdi_context* Context::context()
00338 {
00339 return d->ftdi;
00340 }
00341
00342 class Eeprom::Private
00343 {
00344 public:
00345 Private()
00346 : context(0)
00347 {}
00348
00349 struct ftdi_eeprom eeprom;
00350 struct ftdi_context* context;
00351 };
00352
00353 Eeprom::Eeprom(Context* parent)
00354 : d ( new Private() )
00355 {
00356 d->context = parent->context();
00357 }
00358
00359 Eeprom::~Eeprom()
00360 {
00361 }
00362
00363 void Eeprom::init_defaults()
00364 {
00365 return ftdi_eeprom_initdefaults(&d->eeprom);
00366 }
00367
00368 void Eeprom::set_size(int size)
00369 {
00370 return ftdi_eeprom_setsize(d->context, &d->eeprom, size);
00371 }
00372
00373 int Eeprom::size(unsigned char *eeprom, int maxsize)
00374 {
00375 return ftdi_read_eeprom_getsize(d->context, eeprom, maxsize);
00376 }
00377
00378 int Eeprom::chip_id(unsigned int *chipid)
00379 {
00380 return ftdi_read_chipid(d->context, chipid);
00381 }
00382
00383 int Eeprom::build(unsigned char *output)
00384 {
00385 return ftdi_eeprom_build(&d->eeprom, output);
00386 }
00387
00388 int Eeprom::read(unsigned char *eeprom)
00389 {
00390 return ftdi_read_eeprom(d->context, eeprom);
00391 }
00392
00393 int Eeprom::write(unsigned char *eeprom)
00394 {
00395 return ftdi_write_eeprom(d->context, eeprom);
00396 }
00397
00398 int Eeprom::erase()
00399 {
00400 return ftdi_erase_eeprom(d->context);
00401 }
00402
00403 class List::Private
00404 {
00405 public:
00406 Private(struct ftdi_device_list* _devlist)
00407 : devlist(_devlist)
00408 {}
00409
00410 ~Private()
00411 {
00412 if(devlist)
00413 ftdi_list_free(&devlist);
00414 }
00415
00416 std::list<Context> list;
00417 struct ftdi_device_list* devlist;
00418 };
00419
00420 List::List(struct ftdi_device_list* devlist)
00421 : d( new Private(devlist) )
00422 {
00423 if (devlist != 0)
00424 {
00425
00426 for (; devlist != 0; devlist = devlist->next)
00427 {
00428 Context c;
00429 c.set_usb_device(devlist->dev);
00430 c.get_strings();
00431 d->list.push_back(c);
00432 }
00433 }
00434 }
00435
00436 List::~List()
00437 {
00438 }
00439
00444 List::iterator List::begin()
00445 {
00446 return d->list.begin();
00447 }
00448
00453 List::iterator List::end()
00454 {
00455 return d->list.end();
00456 }
00457
00462 List::const_iterator List::begin() const
00463 {
00464 return d->list.begin();
00465 }
00466
00471 List::const_iterator List::end() const
00472 {
00473 return d->list.end();
00474 }
00475
00480 List::reverse_iterator List::rbegin()
00481 {
00482 return d->list.rbegin();
00483 }
00484
00489 List::reverse_iterator List::rend()
00490 {
00491 return d->list.rend();
00492 }
00493
00498 List::const_reverse_iterator List::rbegin() const
00499 {
00500 return d->list.rbegin();
00501 }
00502
00507 List::const_reverse_iterator List::rend() const
00508 {
00509 return d->list.rend();
00510
00511 }
00512
00517 List::ListType::size_type List::size() const
00518 {
00519 return d->list.size();
00520 }
00521
00526 bool List::empty() const
00527 {
00528 return d->list.empty();
00529 }
00530
00536 void List::clear()
00537 {
00538 ListType().swap(d->list);
00539
00540
00541 if (d->devlist)
00542 {
00543 ftdi_list_free(&d->devlist);
00544 d->devlist = 0;
00545 }
00546 }
00547
00552 void List::push_back(const Context& element)
00553 {
00554 d->list.push_back(element);
00555 }
00556
00561 void List::push_front(const Context& element)
00562 {
00563 d->list.push_front(element);
00564 }
00565
00571 List::iterator List::erase(iterator pos)
00572 {
00573 return d->list.erase(pos);
00574 }
00575
00582 List::iterator List::erase(iterator beg, iterator end)
00583 {
00584 return d->list.erase(beg, end);
00585 }
00586
00587 List* List::find_all(int vendor, int product)
00588 {
00589 struct ftdi_device_list* dlist = 0;
00590 struct ftdi_context ftdi;
00591 ftdi_init(&ftdi);
00592 ftdi_usb_find_all(&ftdi, &dlist, vendor, product);
00593 ftdi_deinit(&ftdi);
00594 return new List(dlist);
00595 }
00596
00597 }