Intra2net AG
  • Produkte
  • Support
  • Download
  • Partner
  • Unternehmen
  • Presse
  • Kontakt

  • Main Page
  • Modules
  • Namespaces
  • Classes
  • Files

ftdi.c

Go to the documentation of this file.
00001 /***************************************************************************
00002                           ftdi.c  -  description
00003                              -------------------
00004     begin                : Fri Apr 4 2003
00005     copyright            : (C) 2003-2008 by Intra2net AG
00006     email                : opensource@intra2net.com
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  *                                                                         *
00011  *   This program is free software; you can redistribute it and/or modify  *
00012  *   it under the terms of the GNU Lesser General Public License           *
00013  *   version 2.1 as published by the Free Software Foundation;             *
00014  *                                                                         *
00015  ***************************************************************************/
00016 
00029 /* @{ */
00030 
00031 #include <usb.h>
00032 #include <string.h>
00033 #include <errno.h>
00034 
00035 #include "ftdi.h"
00036 
00037 /* stuff needed for async write */
00038 #ifdef LIBFTDI_LINUX_ASYNC_MODE
00039     #include <sys/ioctl.h>
00040     #include <sys/time.h>
00041     #include <sys/select.h>
00042     #include <sys/types.h>
00043     #include <unistd.h>
00044     #include <linux/usbdevice_fs.h>
00045 #endif
00046 
00047 #define ftdi_error_return(code, str) do {  \
00048         ftdi->error_str = str;             \
00049         return code;                       \
00050    } while(0);
00051 
00052 
00063 int ftdi_init(struct ftdi_context *ftdi)
00064 {
00065     int i;
00066 
00067     ftdi->usb_dev = NULL;
00068     ftdi->usb_read_timeout = 5000;
00069     ftdi->usb_write_timeout = 5000;
00070 
00071     ftdi->type = TYPE_BM;    /* chip type */
00072     ftdi->baudrate = -1;
00073     ftdi->bitbang_enabled = 0;
00074 
00075     ftdi->readbuffer = NULL;
00076     ftdi->readbuffer_offset = 0;
00077     ftdi->readbuffer_remaining = 0;
00078     ftdi->writebuffer_chunksize = 4096;
00079 
00080     ftdi->interface = 0;
00081     ftdi->index = 0;
00082     ftdi->in_ep = 0x02;
00083     ftdi->out_ep = 0x81;
00084     ftdi->bitbang_mode = 1; /* 1: Normal bitbang mode, 2: SPI bitbang mode */
00085 
00086     ftdi->error_str = NULL;
00087 
00088 #ifdef LIBFTDI_LINUX_ASYNC_MODE
00089     ftdi->async_usb_buffer_size=10;
00090     if ((ftdi->async_usb_buffer=malloc(sizeof(struct usbdevfs_urb)*ftdi->async_usb_buffer_size)) == NULL)
00091         ftdi_error_return(-1, "out of memory for async usb buffer");
00092 
00093     /* initialize async usb buffer with unused-marker */
00094     for (i=0; i < ftdi->async_usb_buffer_size; i++)
00095         ((struct usbdevfs_urb*)ftdi->async_usb_buffer)[i].usercontext = FTDI_URB_USERCONTEXT_COOKIE;
00096 #else
00097     ftdi->async_usb_buffer_size=0;
00098     ftdi->async_usb_buffer = NULL;
00099 #endif
00100 
00101     ftdi->eeprom_size = FTDI_DEFAULT_EEPROM_SIZE;
00102 
00103     /* All fine. Now allocate the readbuffer */
00104     return ftdi_read_data_set_chunksize(ftdi, 4096);
00105 }
00106 
00112 struct ftdi_context *ftdi_new()
00113 {
00114     struct ftdi_context * ftdi = (struct ftdi_context *)malloc(sizeof(struct ftdi_context));
00115 
00116     if (ftdi == NULL) {
00117         return NULL;
00118     }
00119 
00120     if (ftdi_init(ftdi) != 0) {
00121         free(ftdi);
00122         return NULL;
00123     }
00124 
00125     return ftdi;
00126 }
00127 
00137 int ftdi_set_interface(struct ftdi_context *ftdi, enum ftdi_interface interface)
00138 {
00139     switch (interface) {
00140     case INTERFACE_ANY:
00141     case INTERFACE_A:
00142         /* ftdi_usb_open_desc cares to set the right index, depending on the found chip */
00143         break;
00144     case INTERFACE_B:
00145         ftdi->interface = 1;
00146         ftdi->index     = INTERFACE_B;
00147         ftdi->in_ep     = 0x04;
00148         ftdi->out_ep    = 0x83;
00149         break;
00150     default:
00151         ftdi_error_return(-1, "Unknown interface");
00152     }
00153     return 0;
00154 }
00155 
00161 void ftdi_deinit(struct ftdi_context *ftdi)
00162 {
00163     if (ftdi->async_usb_buffer != NULL) {
00164         free(ftdi->async_usb_buffer);
00165         ftdi->async_usb_buffer = NULL;
00166     }
00167 
00168     if (ftdi->readbuffer != NULL) {
00169         free(ftdi->readbuffer);
00170         ftdi->readbuffer = NULL;
00171     }
00172 }
00173 
00179 void ftdi_free(struct ftdi_context *ftdi)
00180 {
00181     ftdi_deinit(ftdi);
00182     free(ftdi);
00183 }
00184 
00191 void ftdi_set_usbdev (struct ftdi_context *ftdi, usb_dev_handle *usb)
00192 {
00193     ftdi->usb_dev = usb;
00194 }
00195 
00196 
00211 int ftdi_usb_find_all(struct ftdi_context *ftdi, struct ftdi_device_list **devlist, int vendor, int product)
00212 {
00213     struct ftdi_device_list **curdev;
00214     struct usb_bus *bus;
00215     struct usb_device *dev;
00216     int count = 0;
00217 
00218     usb_init();
00219     if (usb_find_busses() < 0)
00220         ftdi_error_return(-1, "usb_find_busses() failed");
00221     if (usb_find_devices() < 0)
00222         ftdi_error_return(-2, "usb_find_devices() failed");
00223 
00224     curdev = devlist;
00225     *curdev = NULL;
00226     for (bus = usb_get_busses(); bus; bus = bus->next) {
00227         for (dev = bus->devices; dev; dev = dev->next) {
00228             if (dev->descriptor.idVendor == vendor
00229                     && dev->descriptor.idProduct == product)
00230             {
00231                 *curdev = (struct ftdi_device_list*)malloc(sizeof(struct ftdi_device_list));
00232                 if (!*curdev)
00233                     ftdi_error_return(-3, "out of memory");
00234 
00235                 (*curdev)->next = NULL;
00236                 (*curdev)->dev = dev;
00237 
00238                 curdev = &(*curdev)->next;
00239                 count++;
00240             }
00241         }
00242     }
00243 
00244     return count;
00245 }
00246 
00252 void ftdi_list_free(struct ftdi_device_list **devlist)
00253 {
00254     struct ftdi_device_list *curdev, *next;
00255 
00256     for (curdev = *devlist; curdev != NULL;) {
00257         next = curdev->next;
00258         free(curdev);
00259         curdev = next;
00260     }
00261 
00262     *devlist = NULL;
00263 }
00264 
00270 void ftdi_list_free2(struct ftdi_device_list *devlist)
00271 {
00272     ftdi_list_free(&devlist);
00273 }
00274 
00301 int ftdi_usb_get_strings(struct ftdi_context * ftdi, struct usb_device * dev,
00302         char * manufacturer, int mnf_len, char * description, int desc_len, char * serial, int serial_len)
00303 {
00304     if ((ftdi==NULL) || (dev==NULL))
00305         return -1;
00306 
00307     if (!(ftdi->usb_dev = usb_open(dev)))
00308         ftdi_error_return(-4, usb_strerror());
00309 
00310     if (manufacturer != NULL) {
00311         if (usb_get_string_simple(ftdi->usb_dev, dev->descriptor.iManufacturer, manufacturer, mnf_len) <= 0) {
00312             usb_close (ftdi->usb_dev);
00313             ftdi_error_return(-7, usb_strerror());
00314         }
00315     }
00316 
00317     if (description != NULL) {
00318         if (usb_get_string_simple(ftdi->usb_dev, dev->descriptor.iProduct, description, desc_len) <= 0) {
00319             usb_close (ftdi->usb_dev);
00320             ftdi_error_return(-8, usb_strerror());
00321         }
00322     }
00323 
00324     if (serial != NULL) {
00325         if (usb_get_string_simple(ftdi->usb_dev, dev->descriptor.iSerialNumber, serial, serial_len) <= 0) {
00326             usb_close (ftdi->usb_dev);
00327             ftdi_error_return(-9, usb_strerror());
00328         }
00329     }
00330 
00331     if (usb_close (ftdi->usb_dev) != 0)
00332         ftdi_error_return(-10, usb_strerror());
00333 
00334     return 0;
00335 }
00336 
00350 int ftdi_usb_open_dev(struct ftdi_context *ftdi, struct usb_device *dev)
00351 {
00352     int detach_errno = 0;
00353     if (!(ftdi->usb_dev = usb_open(dev)))
00354         ftdi_error_return(-4, "usb_open() failed");
00355 
00356 #ifdef LIBUSB_HAS_GET_DRIVER_NP
00357     // Try to detach ftdi_sio kernel module.
00358     // Returns ENODATA if driver is not loaded.
00359     //
00360     // The return code is kept in a separate variable and only parsed
00361     // if usb_set_configuration() or usb_claim_interface() fails as the
00362     // detach operation might be denied and everything still works fine.
00363     // Likely scenario is a static ftdi_sio kernel module.
00364     if (usb_detach_kernel_driver_np(ftdi->usb_dev, ftdi->interface) != 0 && errno != ENODATA)
00365         detach_errno = errno;
00366 #endif
00367 
00368     // set configuration (needed especially for windows)
00369     // tolerate EBUSY: one device with one configuration, but two interfaces
00370     //    and libftdi sessions to both interfaces (e.g. FT2232)
00371     if (dev->descriptor.bNumConfigurations > 0 && 
00372         usb_set_configuration(ftdi->usb_dev, dev->config[0].bConfigurationValue) &&
00373         errno != EBUSY)
00374     {
00375         usb_close (ftdi->usb_dev);
00376         if (detach_errno == EPERM) {
00377             ftdi_error_return(-8, "inappropriate permissions on device!");
00378         } else {
00379             ftdi_error_return(-3, "unable to set usb configuration. Make sure ftdi_sio is unloaded!");
00380         }
00381     }
00382 
00383     if (usb_claim_interface(ftdi->usb_dev, ftdi->interface) != 0) {
00384         usb_close (ftdi->usb_dev);
00385         if (detach_errno == EPERM) {
00386             ftdi_error_return(-8, "inappropriate permissions on device!");
00387         } else {
00388             ftdi_error_return(-5, "unable to claim usb device. Make sure ftdi_sio is unloaded!");
00389         }
00390     }
00391 
00392     if (ftdi_usb_reset (ftdi) != 0) {
00393         usb_close (ftdi->usb_dev);
00394         ftdi_error_return(-6, "ftdi_usb_reset failed");
00395     }
00396 
00397     if (ftdi_set_baudrate (ftdi, 9600) != 0) {
00398         usb_close (ftdi->usb_dev);
00399         ftdi_error_return(-7, "set baudrate failed");
00400     }
00401 
00402     // Try to guess chip type
00403     // Bug in the BM type chips: bcdDevice is 0x200 for serial == 0
00404     if (dev->descriptor.bcdDevice == 0x400 || (dev->descriptor.bcdDevice == 0x200
00405             && dev->descriptor.iSerialNumber == 0))
00406         ftdi->type = TYPE_BM;
00407     else if (dev->descriptor.bcdDevice == 0x200)
00408         ftdi->type = TYPE_AM;
00409     else if (dev->descriptor.bcdDevice == 0x500) {
00410         ftdi->type = TYPE_2232C;
00411         if (!ftdi->index)
00412             ftdi->index = INTERFACE_A;
00413     } else if (dev->descriptor.bcdDevice == 0x600)
00414         ftdi->type = TYPE_R;
00415 
00416     ftdi_error_return(0, "all fine");
00417 }
00418 
00428 int ftdi_usb_open(struct ftdi_context *ftdi, int vendor, int product)
00429 {
00430     return ftdi_usb_open_desc(ftdi, vendor, product, NULL, NULL);
00431 }
00432 
00455 int ftdi_usb_open_desc(struct ftdi_context *ftdi, int vendor, int product,
00456                        const char* description, const char* serial)
00457 {
00458     struct usb_bus *bus;
00459     struct usb_device *dev;
00460     char string[256];
00461 
00462     usb_init();
00463 
00464     if (usb_find_busses() < 0)
00465         ftdi_error_return(-1, "usb_find_busses() failed");
00466     if (usb_find_devices() < 0)
00467         ftdi_error_return(-2, "usb_find_devices() failed");
00468 
00469     for (bus = usb_get_busses(); bus; bus = bus->next) {
00470         for (dev = bus->devices; dev; dev = dev->next) {
00471             if (dev->descriptor.idVendor == vendor
00472                     && dev->descriptor.idProduct == product) {
00473                 if (!(ftdi->usb_dev = usb_open(dev)))
00474                     ftdi_error_return(-4, "usb_open() failed");
00475 
00476                 if (description != NULL) {
00477                     if (usb_get_string_simple(ftdi->usb_dev, dev->descriptor.iProduct, string, sizeof(string)) <= 0) {
00478                         usb_close (ftdi->usb_dev);
00479                         ftdi_error_return(-8, "unable to fetch product description");
00480                     }
00481                     if (strncmp(string, description, sizeof(string)) != 0) {
00482                         if (usb_close (ftdi->usb_dev) != 0)
00483                             ftdi_error_return(-10, "unable to close device");
00484                         continue;
00485                     }
00486                 }
00487                 if (serial != NULL) {
00488                     if (usb_get_string_simple(ftdi->usb_dev, dev->descriptor.iSerialNumber, string, sizeof(string)) <= 0) {
00489                         usb_close (ftdi->usb_dev);
00490                         ftdi_error_return(-9, "unable to fetch serial number");
00491                     }
00492                     if (strncmp(string, serial, sizeof(string)) != 0) {
00493                         if (usb_close (ftdi->usb_dev) != 0)
00494                             ftdi_error_return(-10, "unable to close device");
00495                         continue;
00496                     }
00497                 }
00498 
00499                 if (usb_close (ftdi->usb_dev) != 0)
00500                     ftdi_error_return(-10, "unable to close device");
00501 
00502                 return ftdi_usb_open_dev(ftdi, dev);
00503             }
00504         }
00505     }
00506 
00507     // device not found
00508     ftdi_error_return(-3, "device not found");
00509 }
00510 
00519 int ftdi_usb_reset(struct ftdi_context *ftdi)
00520 {
00521    if (usb_control_msg(ftdi->usb_dev, SIO_RESET_REQUEST_TYPE,
00522                        SIO_RESET_REQUEST, SIO_RESET_SIO,
00523                        ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0)
00524         ftdi_error_return(-1,"FTDI reset failed");
00525 
00526     // Invalidate data in the readbuffer
00527     ftdi->readbuffer_offset = 0;
00528     ftdi->readbuffer_remaining = 0;
00529 
00530     return 0;
00531 }
00532 
00541 int ftdi_usb_purge_rx_buffer(struct ftdi_context *ftdi)
00542 {
00543    if (usb_control_msg(ftdi->usb_dev, SIO_RESET_REQUEST_TYPE,
00544                        SIO_RESET_REQUEST, SIO_RESET_PURGE_RX,
00545                        ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0)
00546         ftdi_error_return(-1, "FTDI purge of RX buffer failed");
00547 
00548     // Invalidate data in the readbuffer
00549     ftdi->readbuffer_offset = 0;
00550     ftdi->readbuffer_remaining = 0;
00551 
00552     return 0;
00553 }
00554 
00563 int ftdi_usb_purge_tx_buffer(struct ftdi_context *ftdi)
00564 {
00565    if (usb_control_msg(ftdi->usb_dev, SIO_RESET_REQUEST_TYPE,
00566                        SIO_RESET_REQUEST, SIO_RESET_PURGE_TX,
00567                        ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0)
00568         ftdi_error_return(-1, "FTDI purge of TX buffer failed");
00569 
00570     return 0;
00571 }
00572 
00582 int ftdi_usb_purge_buffers(struct ftdi_context *ftdi)
00583 {
00584     int result;
00585 
00586     result = ftdi_usb_purge_rx_buffer(ftdi);
00587     if (result < 0)
00588         return -1;
00589 
00590     result = ftdi_usb_purge_tx_buffer(ftdi);
00591     if (result < 0)
00592         return -2;
00593 
00594     return 0;
00595 }
00596 
00606 int ftdi_usb_close(struct ftdi_context *ftdi)
00607 {
00608     int rtn = 0;
00609 
00610 #ifdef LIBFTDI_LINUX_ASYNC_MODE
00611     /* try to release some kernel resources */
00612     ftdi_async_complete(ftdi,1);
00613 #endif
00614 
00615     if (usb_release_interface(ftdi->usb_dev, ftdi->interface) != 0)
00616         rtn = -1;
00617 
00618     if (usb_close (ftdi->usb_dev) != 0)
00619         rtn = -2;
00620 
00621     return rtn;
00622 }
00623 
00624 /*
00625     ftdi_convert_baudrate returns nearest supported baud rate to that requested.
00626     Function is only used internally
00627     \internal
00628 */
00629 static int ftdi_convert_baudrate(int baudrate, struct ftdi_context *ftdi,
00630                                  unsigned short *value, unsigned short *index)
00631 {
00632     static const char am_adjust_up[8] = {0, 0, 0, 1, 0, 3, 2, 1};
00633     static const char am_adjust_dn[8] = {0, 0, 0, 1, 0, 1, 2, 3};
00634     static const char frac_code[8] = {0, 3, 2, 4, 1, 5, 6, 7};
00635     int divisor, best_divisor, best_baud, best_baud_diff;
00636     unsigned long encoded_divisor;
00637     int i;
00638 
00639     if (baudrate <= 0) {
00640         // Return error
00641         return -1;
00642     }
00643 
00644     divisor = 24000000 / baudrate;
00645 
00646     if (ftdi->type == TYPE_AM) {
00647         // Round down to supported fraction (AM only)
00648         divisor -= am_adjust_dn[divisor & 7];
00649     }
00650 
00651     // Try this divisor and the one above it (because division rounds down)
00652     best_divisor = 0;
00653     best_baud = 0;
00654     best_baud_diff = 0;
00655     for (i = 0; i < 2; i++) {
00656         int try_divisor = divisor + i;
00657         int baud_estimate;
00658         int baud_diff;
00659 
00660         // Round up to supported divisor value
00661         if (try_divisor <= 8) {
00662             // Round up to minimum supported divisor
00663             try_divisor = 8;
00664         } else if (ftdi->type != TYPE_AM && try_divisor < 12) {
00665             // BM doesn't support divisors 9 through 11 inclusive
00666             try_divisor = 12;
00667         } else if (divisor < 16) {
00668             // AM doesn't support divisors 9 through 15 inclusive
00669             try_divisor = 16;
00670         } else {
00671             if (ftdi->type == TYPE_AM) {
00672                 // Round up to supported fraction (AM only)
00673                 try_divisor += am_adjust_up[try_divisor & 7];
00674                 if (try_divisor > 0x1FFF8) {
00675                     // Round down to maximum supported divisor value (for AM)
00676                     try_divisor = 0x1FFF8;
00677                 }
00678             } else {
00679                 if (try_divisor > 0x1FFFF) {
00680                     // Round down to maximum supported divisor value (for BM)
00681                     try_divisor = 0x1FFFF;
00682                 }
00683             }
00684         }
00685         // Get estimated baud rate (to nearest integer)
00686         baud_estimate = (24000000 + (try_divisor / 2)) / try_divisor;
00687         // Get absolute difference from requested baud rate
00688         if (baud_estimate < baudrate) {
00689             baud_diff = baudrate - baud_estimate;
00690         } else {
00691             baud_diff = baud_estimate - baudrate;
00692         }
00693         if (i == 0 || baud_diff < best_baud_diff) {
00694             // Closest to requested baud rate so far
00695             best_divisor = try_divisor;
00696             best_baud = baud_estimate;
00697             best_baud_diff = baud_diff;
00698             if (baud_diff == 0) {
00699                 // Spot on! No point trying
00700                 break;
00701             }
00702         }
00703     }
00704     // Encode the best divisor value
00705     encoded_divisor = (best_divisor >> 3) | (frac_code[best_divisor & 7] << 14);
00706     // Deal with special cases for encoded value
00707     if (encoded_divisor == 1) {
00708         encoded_divisor = 0;    // 3000000 baud
00709     } else if (encoded_divisor == 0x4001) {
00710         encoded_divisor = 1;    // 2000000 baud (BM only)
00711     }
00712     // Split into "value" and "index" values
00713     *value = (unsigned short)(encoded_divisor & 0xFFFF);
00714     if(ftdi->type == TYPE_2232C) {
00715         *index = (unsigned short)(encoded_divisor >> 8);
00716         *index &= 0xFF00;
00717         *index |= ftdi->index;
00718     }
00719     else
00720         *index = (unsigned short)(encoded_divisor >> 16);
00721 
00722     // Return the nearest baud rate
00723     return best_baud;
00724 }
00725 
00736 int ftdi_set_baudrate(struct ftdi_context *ftdi, int baudrate)
00737 {
00738     unsigned short value, index;
00739     int actual_baudrate;
00740 
00741     if (ftdi->bitbang_enabled) {
00742         baudrate = baudrate*4;
00743     }
00744 
00745     actual_baudrate = ftdi_convert_baudrate(baudrate, ftdi, &value, &index);
00746     if (actual_baudrate <= 0)
00747         ftdi_error_return (-1, "Silly baudrate <= 0.");
00748 
00749     // Check within tolerance (about 5%)
00750     if ((actual_baudrate * 2 < baudrate /* Catch overflows */ )
00751             || ((actual_baudrate < baudrate)
00752                 ? (actual_baudrate * 21 < baudrate * 20)
00753                 : (baudrate * 21 < actual_baudrate * 20)))
00754         ftdi_error_return (-1, "Unsupported baudrate. Note: bitbang baudrates are automatically multiplied by 4");
00755 
00756     if (usb_control_msg(ftdi->usb_dev, SIO_SET_BAUDRATE_REQUEST_TYPE,
00757                         SIO_SET_BAUDRATE_REQUEST, value,
00758                         index, NULL, 0, ftdi->usb_write_timeout) != 0)
00759         ftdi_error_return (-2, "Setting new baudrate failed");
00760 
00761     ftdi->baudrate = baudrate;
00762     return 0;
00763 }
00764 
00778 int ftdi_set_line_property(struct ftdi_context *ftdi, enum ftdi_bits_type bits,
00779                            enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity)
00780 {
00781     return ftdi_set_line_property2(ftdi, bits, sbit, parity, BREAK_OFF);
00782 }
00783 
00796 int ftdi_set_line_property2(struct ftdi_context *ftdi, enum ftdi_bits_type bits,
00797                            enum ftdi_stopbits_type sbit, enum ftdi_parity_type parity,
00798                            enum ftdi_break_type break_type)
00799 {
00800     unsigned short value = bits;
00801 
00802     switch(parity) {
00803     case NONE:
00804         value |= (0x00 << 8);
00805         break;
00806     case ODD:
00807         value |= (0x01 << 8);
00808         break;
00809     case EVEN:
00810         value |= (0x02 << 8);
00811         break;
00812     case MARK:
00813         value |= (0x03 << 8);
00814         break;
00815     case SPACE:
00816         value |= (0x04 << 8);
00817         break;
00818     }
00819 
00820     switch(sbit) {
00821     case STOP_BIT_1:
00822         value |= (0x00 << 11);
00823         break;
00824     case STOP_BIT_15:
00825         value |= (0x01 << 11);
00826         break;
00827     case STOP_BIT_2:
00828         value |= (0x02 << 11);
00829         break;
00830     }
00831 
00832     switch(break_type) {
00833     case BREAK_OFF:
00834         value |= (0x00 << 14);
00835         break;
00836     case BREAK_ON:
00837         value |= (0x01 << 14);
00838         break;
00839     }
00840 
00841     if (usb_control_msg(ftdi->usb_dev, SIO_SET_DATA_REQUEST_TYPE,
00842                         SIO_SET_DATA_REQUEST, value,
00843                         ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0)
00844         ftdi_error_return (-1, "Setting new line property failed");
00845 
00846     return 0;
00847 }
00848 
00859 int ftdi_write_data(struct ftdi_context *ftdi, unsigned char *buf, int size)
00860 {
00861     int ret;
00862     int offset = 0;
00863     int total_written = 0;
00864 
00865     while (offset < size) {
00866         int write_size = ftdi->writebuffer_chunksize;
00867 
00868         if (offset+write_size > size)
00869             write_size = size-offset;
00870 
00871         ret = usb_bulk_write(ftdi->usb_dev, ftdi->in_ep, buf+offset, write_size, ftdi->usb_write_timeout);
00872         if (ret < 0)
00873             ftdi_error_return(ret, "usb bulk write failed");
00874 
00875         total_written += ret;
00876         offset += write_size;
00877     }
00878 
00879     return total_written;
00880 }
00881 
00882 #ifdef LIBFTDI_LINUX_ASYNC_MODE
00883 /* this is strongly dependent on libusb using the same struct layout. If libusb
00884    changes in some later version this may break horribly (this is for libusb 0.1.12) */
00885 struct usb_dev_handle {
00886   int fd;
00887   // some other stuff coming here we don't need
00888 };
00889 
00894 static int _usb_get_async_urbs_pending(struct ftdi_context *ftdi)
00895 {
00896     struct usbdevfs_urb *urb;
00897     int pending=0;
00898     int i;
00899 
00900     for (i=0; i < ftdi->async_usb_buffer_size; i++) {
00901         urb=&((struct usbdevfs_urb *)(ftdi->async_usb_buffer))[i];
00902         if (urb->usercontext != FTDI_URB_USERCONTEXT_COOKIE)
00903             pending++;
00904     }
00905 
00906     return pending;
00907 }
00908 
00919 static void _usb_async_cleanup(struct ftdi_context *ftdi, int wait_for_more, int timeout_msec)
00920 {
00921   struct timeval tv;
00922   struct usbdevfs_urb *urb=NULL;
00923   int ret;
00924   fd_set writefds;
00925   int keep_going=0;
00926 
00927   FD_ZERO(&writefds);
00928   FD_SET(ftdi->usb_dev->fd, &writefds);
00929 
00930   /* init timeout only once, select writes time left after call */
00931   tv.tv_sec = timeout_msec / 1000;
00932   tv.tv_usec = (timeout_msec % 1000) * 1000;
00933 
00934   do {
00935     while (_usb_get_async_urbs_pending(ftdi)
00936            && (ret = ioctl(ftdi->usb_dev->fd, USBDEVFS_REAPURBNDELAY, &urb)) == -1
00937            && errno == EAGAIN)
00938     {
00939       if (keep_going && !wait_for_more) {
00940         /* don't wait if repeating only for keep_going */
00941         keep_going=0;
00942         break;
00943       }
00944 
00945       /* wait for timeout msec or something written ready */
00946       select(ftdi->usb_dev->fd+1, NULL, &writefds, NULL, &tv);
00947     }
00948 
00949     if (ret == 0 && urb != NULL) {
00950       /* got a free urb, mark it */
00951       urb->usercontext = FTDI_URB_USERCONTEXT_COOKIE;
00952 
00953       /* try to get more urbs that are ready now, but don't wait anymore */
00954       urb=NULL;
00955       keep_going=1;
00956     } else {
00957       /* no more urbs waiting */
00958       keep_going=0;
00959     }
00960   } while (keep_going);
00961 }
00962 
00970 void ftdi_async_complete(struct ftdi_context *ftdi, int wait_for_more)
00971 {
00972   _usb_async_cleanup(ftdi,wait_for_more,ftdi->usb_write_timeout);
00973 }
00974 
00980 static int _usb_bulk_write_async(struct ftdi_context *ftdi, int ep, char *bytes, int size)
00981 {
00982   struct usbdevfs_urb *urb;
00983   int bytesdone = 0, requested;
00984   int ret, i;
00985   int cleanup_count;
00986 
00987   do {
00988     /* find a free urb buffer we can use */
00989     urb=NULL;
00990     for (cleanup_count=0; urb==NULL && cleanup_count <= 1; cleanup_count++)
00991     {
00992         if (i==ftdi->async_usb_buffer_size) {
00993           /* wait until some buffers are free */
00994           _usb_async_cleanup(ftdi,0,ftdi->usb_write_timeout);
00995         }
00996 
00997         for (i=0; i < ftdi->async_usb_buffer_size; i++) {
00998           urb=&((struct usbdevfs_urb *)(ftdi->async_usb_buffer))[i];
00999           if (urb->usercontext == FTDI_URB_USERCONTEXT_COOKIE)
01000             break;  /* found a free urb position */
01001           urb=NULL;
01002         }
01003     }
01004 
01005     /* no free urb position found */
01006     if (urb==NULL)
01007         return -1;
01008 
01009     requested = size - bytesdone;
01010     if (requested > 4096)
01011       requested = 4096;
01012 
01013     memset(urb,0,sizeof(urb));
01014 
01015     urb->type = USBDEVFS_URB_TYPE_BULK;
01016     urb->endpoint = ep;
01017     urb->flags = 0;
01018     urb->buffer = bytes + bytesdone;
01019     urb->buffer_length = requested;
01020     urb->signr = 0;
01021     urb->actual_length = 0;
01022     urb->number_of_packets = 0;
01023     urb->usercontext = 0;
01024 
01025     do {
01026         ret = ioctl(ftdi->usb_dev->fd, USBDEVFS_SUBMITURB, urb);
01027     } while (ret < 0 && errno == EINTR);
01028     if (ret < 0)
01029       return ret;       /* the caller can read errno to get more info */
01030 
01031     bytesdone += requested;
01032   } while (bytesdone < size);
01033   return bytesdone;
01034 }
01035 
01054 int ftdi_write_data_async(struct ftdi_context *ftdi, unsigned char *buf, int size)
01055 {
01056     int ret;
01057     int offset = 0;
01058     int total_written = 0;
01059 
01060     while (offset < size) {
01061         int write_size = ftdi->writebuffer_chunksize;
01062 
01063         if (offset+write_size > size)
01064             write_size = size-offset;
01065 
01066         ret = _usb_bulk_write_async(ftdi, ftdi->in_ep, buf+offset, write_size);
01067         if (ret < 0)
01068             ftdi_error_return(ret, "usb bulk write async failed");
01069 
01070         total_written += ret;
01071         offset += write_size;
01072     }
01073 
01074     return total_written;
01075 }
01076 #endif // LIBFTDI_LINUX_ASYNC_MODE
01077 
01087 int ftdi_write_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize)
01088 {
01089     ftdi->writebuffer_chunksize = chunksize;
01090     return 0;
01091 }
01092 
01101 int ftdi_write_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize)
01102 {
01103     *chunksize = ftdi->writebuffer_chunksize;
01104     return 0;
01105 }
01106 
01123 int ftdi_read_data(struct ftdi_context *ftdi, unsigned char *buf, int size)
01124 {
01125     int offset = 0, ret = 1, i, num_of_chunks, chunk_remains;
01126 
01127     // everything we want is still in the readbuffer?
01128     if (size <= ftdi->readbuffer_remaining) {
01129         memcpy (buf, ftdi->readbuffer+ftdi->readbuffer_offset, size);
01130 
01131         // Fix offsets
01132         ftdi->readbuffer_remaining -= size;
01133         ftdi->readbuffer_offset += size;
01134 
01135         /* printf("Returning bytes from buffer: %d - remaining: %d\n", size, ftdi->readbuffer_remaining); */
01136 
01137         return size;
01138     }
01139     // something still in the readbuffer, but not enough to satisfy 'size'?
01140     if (ftdi->readbuffer_remaining != 0) {
01141         memcpy (buf, ftdi->readbuffer+ftdi->readbuffer_offset, ftdi->readbuffer_remaining);
01142 
01143         // Fix offset
01144         offset += ftdi->readbuffer_remaining;
01145     }
01146     // do the actual USB read
01147     while (offset < size && ret > 0) {
01148         ftdi->readbuffer_remaining = 0;
01149         ftdi->readbuffer_offset = 0;
01150         /* returns how much received */
01151         ret = usb_bulk_read (ftdi->usb_dev, ftdi->out_ep, ftdi->readbuffer, ftdi->readbuffer_chunksize, ftdi->usb_read_timeout);
01152         if (ret < 0)
01153             ftdi_error_return(ret, "usb bulk read failed");
01154 
01155         if (ret > 2) {
01156             // skip FTDI status bytes.
01157             // Maybe stored in the future to enable modem use
01158             num_of_chunks = ret / 64;
01159             chunk_remains = ret % 64;
01160             //printf("ret = %X, num_of_chunks = %X, chunk_remains = %X, readbuffer_offset = %X\n", ret, num_of_chunks, chunk_remains, ftdi->readbuffer_offset);
01161 
01162             ftdi->readbuffer_offset += 2;
01163             ret -= 2;
01164 
01165             if (ret > 62) {
01166                 for (i = 1; i < num_of_chunks; i++)
01167                     memmove (ftdi->readbuffer+ftdi->readbuffer_offset+62*i,
01168                              ftdi->readbuffer+ftdi->readbuffer_offset+64*i,
01169                              62);
01170                 if (chunk_remains > 2) {
01171                     memmove (ftdi->readbuffer+ftdi->readbuffer_offset+62*i,
01172                              ftdi->readbuffer+ftdi->readbuffer_offset+64*i,
01173                              chunk_remains-2);
01174                     ret -= 2*num_of_chunks;
01175                 } else
01176                     ret -= 2*(num_of_chunks-1)+chunk_remains;
01177             }
01178         } else if (ret <= 2) {
01179             // no more data to read?
01180             return offset;
01181         }
01182         if (ret > 0) {
01183             // data still fits in buf?
01184             if (offset+ret <= size) {
01185                 memcpy (buf+offset, ftdi->readbuffer+ftdi->readbuffer_offset, ret);
01186                 //printf("buf[0] = %X, buf[1] = %X\n", buf[0], buf[1]);
01187                 offset += ret;
01188 
01189                 /* Did we read exactly the right amount of bytes? */
01190                 if (offset == size)
01191                     //printf("read_data exact rem %d offset %d\n",
01192                     //ftdi->readbuffer_remaining, offset);
01193                     return offset;
01194             } else {
01195                 // only copy part of the data or size <= readbuffer_chunksize
01196                 int part_size = size-offset;
01197                 memcpy (buf+offset, ftdi->readbuffer+ftdi->readbuffer_offset, part_size);
01198 
01199                 ftdi->readbuffer_offset += part_size;
01200                 ftdi->readbuffer_remaining = ret-part_size;
01201                 offset += part_size;
01202 
01203                 /* printf("Returning part: %d - size: %d - offset: %d - ret: %d - remaining: %d\n",
01204                 part_size, size, offset, ret, ftdi->readbuffer_remaining); */
01205 
01206                 return offset;
01207             }
01208         }
01209     }
01210     // never reached
01211     return -127;
01212 }
01213 
01225 int ftdi_read_data_set_chunksize(struct ftdi_context *ftdi, unsigned int chunksize)
01226 {
01227     unsigned char *new_buf;
01228 
01229     // Invalidate all remaining data
01230     ftdi->readbuffer_offset = 0;
01231     ftdi->readbuffer_remaining = 0;
01232 
01233     if ((new_buf = (unsigned char *)realloc(ftdi->readbuffer, chunksize)) == NULL)
01234         ftdi_error_return(-1, "out of memory for readbuffer");
01235 
01236     ftdi->readbuffer = new_buf;
01237     ftdi->readbuffer_chunksize = chunksize;
01238 
01239     return 0;
01240 }
01241 
01250 int ftdi_read_data_get_chunksize(struct ftdi_context *ftdi, unsigned int *chunksize)
01251 {
01252     *chunksize = ftdi->readbuffer_chunksize;
01253     return 0;
01254 }
01255 
01256 
01269 int ftdi_enable_bitbang(struct ftdi_context *ftdi, unsigned char bitmask)
01270 {
01271     unsigned short usb_val;
01272 
01273     usb_val = bitmask; // low byte: bitmask
01274     /* FT2232C: Set bitbang_mode to 2 to enable SPI */
01275     usb_val |= (ftdi->bitbang_mode << 8);
01276 
01277     if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, usb_val, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0)
01278         ftdi_error_return(-1, "unable to enter bitbang mode. Perhaps not a BM type chip?");
01279 
01280     ftdi->bitbang_enabled = 1;
01281     return 0;
01282 }
01283 
01292 int ftdi_disable_bitbang(struct ftdi_context *ftdi)
01293 {
01294     if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, 0, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0)
01295         ftdi_error_return(-1, "unable to leave bitbang mode. Perhaps not a BM type chip?");
01296 
01297     ftdi->bitbang_enabled = 0;
01298     return 0;
01299 }
01300 
01312 int ftdi_set_bitmode(struct ftdi_context *ftdi, unsigned char bitmask, unsigned char mode)
01313 {
01314     unsigned short usb_val;
01315 
01316     usb_val = bitmask; // low byte: bitmask
01317     usb_val |= (mode << 8);
01318     if (usb_control_msg(ftdi->usb_dev, 0x40, 0x0B, usb_val, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0)
01319         ftdi_error_return(-1, "unable to configure bitbang mode. Perhaps not a 2232C type chip?");
01320 
01321     ftdi->bitbang_mode = mode;
01322     ftdi->bitbang_enabled = (mode == BITMODE_BITBANG || mode == BITMODE_SYNCBB)?1:0;
01323     return 0;
01324 }
01325 
01335 int ftdi_read_pins(struct ftdi_context *ftdi, unsigned char *pins)
01336 {
01337     if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x0C, 0, ftdi->index, (char *)pins, 1, ftdi->usb_read_timeout) != 1)
01338         ftdi_error_return(-1, "read pins failed");
01339 
01340     return 0;
01341 }
01342 
01357 int ftdi_set_latency_timer(struct ftdi_context *ftdi, unsigned char latency)
01358 {
01359     unsigned short usb_val;
01360 
01361     if (latency < 1)
01362         ftdi_error_return(-1, "latency out of range. Only valid for 1-255");
01363 
01364     usb_val = latency;
01365     if (usb_control_msg(ftdi->usb_dev, 0x40, 0x09, usb_val, ftdi->index, NULL, 0, ftdi->usb_write_timeout) != 0)
01366         ftdi_error_return(-2, "unable to set latency timer");
01367 
01368     return 0;
01369 }
01370 
01380 int ftdi_get_latency_timer(struct ftdi_context *ftdi, unsigned char *latency)
01381 {
01382     unsigned short usb_val;
01383     if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x0A, 0, ftdi->index, (char *)&usb_val, 1, ftdi->usb_read_timeout) != 1)
01384         ftdi_error_return(-1, "reading latency timer failed");
01385 
01386     *latency = (unsigned char)usb_val;
01387     return 0;
01388 }
01389 
01429 int ftdi_poll_modem_status(struct ftdi_context *ftdi, unsigned short *status)
01430 {
01431     char usb_val[2];
01432 
01433     if (usb_control_msg(ftdi->usb_dev, 0xC0, 0x05, 0, ftdi->index, usb_val, 2, ftdi->usb_read_timeout) != 2)
01434         ftdi_error_return(-1, "getting modem status failed");
01435 
01436     *status = (usb_val[1] << 8) | usb_val[0];
01437 
01438     return 0;
01439 }
01440 
01451 int ftdi_setflowctrl(struct ftdi_context *ftdi, int flowctrl)
01452 {
01453     if (usb_control_msg(ftdi->usb_dev, SIO_SET_FLOW_CTRL_REQUEST_TYPE,
01454                         SIO_SET_FLOW_CTRL_REQUEST, 0, (flowctrl | ftdi->index),
01455                         NULL, 0, ftdi->usb_write_timeout) != 0)
01456         ftdi_error_return(-1, "set flow control failed");
01457 
01458     return 0;
01459 }
01460 
01470 int ftdi_setdtr(struct ftdi_context *ftdi, int state)
01471 {
01472     unsigned short usb_val;
01473 
01474     if (state)
01475         usb_val = SIO_SET_DTR_HIGH;
01476     else
01477         usb_val = SIO_SET_DTR_LOW;
01478 
01479     if (usb_control_msg(ftdi->usb_dev, SIO_SET_MODEM_CTRL_REQUEST_TYPE,
01480                         SIO_SET_MODEM_CTRL_REQUEST, usb_val, ftdi->