libftdi Archives

Subject: Re: usb bulk read failed

From: Eric Schott <eric@xxxxxxxxxxxxxx>
To: libftdi@xxxxxxxxxxxxxxxxxxxxxxx
Date: Sat, 11 Feb 2017 07:21:33 -0500
On Fri Feb 10, 2017, John Hein wrote:

Yep, the ftdio_sio driver was loaded.  'sudo rmmod ftdio_sio' before
running my program to bang the bits resolved the 'usb bulk write
failed' failure.

I have some follow on question(s) for the list in light of this:

I have a regular uart serial port that I do want to use (need
ftdio_sio / usbserial modules loaded).

What is the desired way to ...

(a) ... allow ftdi_sio and libftdi to coexist peacefully?  ... that
    is, without having to unload the driver to do libftdi stuff, and
    reload the driver to do usbserial (uart) stuff.

To the best of my understanding, this is not possible if the serial port
and the bitbang port are on the same FT4243H chip.

I have such a scenario and have developed a serial port C++ "wrapper"
class which emulates the serial UART functions not implement in libftdi1
(such as tcdrain(3)). I have found a bug in libftdi1 with the purge
(a.k.a., tcflush(3)) for which I am developing a patch.

If you require a Linux like serial driver for your serial port (for
instance to run minicom), you will need a userspace PTY program to
implement a TTY device. See the previous post on this list
http://developer.intra2net.com/mailarchive/html/libftdi/2009/msg00183.html

(b) ... allow bitbanging on one interface via libftdi as a regular user?

    I added a new 'ftdi' group and did 'sudo chgrp ftdi
    /dev/bus/usb/001/*' (there are 5 usb devices on this system -
    which happens to be centos 6) and made sure the users I want to
    have access are in group ftdi.  Then I can use my program as a
    regular user.  I changed the permissions of all the usb devices
    since ftdi_usb_open() tries them all looking for the device id.
    It fails if it can't open one of the usb devices before a positive
    match.

    There's probably a better way?  (yes, I could configure sudo
    for a specific command or make my program setuid-root, but
    those both seem less useful than my above hack - except
    for adding permissions to _all_ usb devices)

Use a udev rule.  In libftdi1's packages directory is the file
99-libftdi.rules which must be placed into the /etc/udev/rules.d
directory.  You will need to change the group.

If you are doing an embedded system, you can do much more with udev
rules such as starting a daemon to maintain the GPIO pins (they
float when the program terminates).

As I alluded to before, consider changing your chip's vendor and/or
product ids so your product would not interfere with standard FTDI
UARTs your user community may want to use.  If your product is
going to have a wide distribution, consider purchasing a vendor id.

As far as the -16... I'm guessing that is -1 * EBUSY.

The return value of ftdi_write_data is documented as:

       Return values:
           -666 USB device unavailable
           <0 error code from usb_bulk_write()
           >0 number of bytes written

Probably an EBUSY is getting returned somewhere if you drill into the
libusb code (possibly from poll(2) somewhere?).

Eric Schott wrote at 12:05 -0500 on Feb 10, 2017:
 > *On Fri, Feb 10, 2017, John Hein wrote:*
 > >
 > > I'm trying to use bit bang on the fourth interface of the FT4232H.
 > > See program below.
 > >
 > > I get an error I don't understand yet:
 > >
 > > write err: -16, usb bulk write failed
 > >
 > > What am I missing?
 >
 > I could not find -16 in my libusb.h.
 >
 > I have BITMODE_BITBANG working on FT4232H..  Things I have done
 >
 >    -  If using Linux, make sure the ftdi_sio driver is not loaded.
 >       You can blacklist the device (0x0403, 0x6011) or change the
 >       vendor/product values so Linux does not associate the
 >       chip with ftdio_sio kernel module.
 >
 >    -  I call ftdi_set_interface before calling ftdi_usb_open.
 >
 > > #include <ftdi.h>
 > > #include <stdio.h>
 > > int
 > > main()
 > > {
 > >     struct ftdi_context *ftdicx;
 > >     int rc;
 > >     unsigned char buf[1];
 > >
 > >     ftdicx = ftdi_new();
 > >     rc = ftdi_init(ftdicx);
 > >     if (rc != 0)
 > >         printf("err: %s\n", ftdi_get_error_string(ftdicx));
 > >     rc = ftdi_usb_open(ftdicx, 0x0403, 0x6011);
 > >     if (rc != 0)
 > >         printf("err: %s\n", ftdi_get_error_string(ftdicx));
 > >     rc = ftdi_set_interface(ftdicx, INTERFACE_D);
 > >     if (rc != 0)
 > >         printf("err: %s\n", ftdi_get_error_string(ftdicx));
 > >
 > >     /* 0xe => pin 0 is an input, pins 1-3 are outputs */
 > >     rc = ftdi_set_bitmode(ftdicx, 0xe, BITMODE_BITBANG);
 > >     if (rc != 0)
 > >         printf("err: %s\n", ftdi_get_error_string(ftdicx));
 > >
 > >     buf[0] = 0x6;                 /* pin 1 & 2 => 1 */
 > >     rc = ftdi_write_data(ftdicx, buf, 1);
 > >     if (rc < 0)
 > >         printf("write err: %d, %s\n", rc, ftdi_get_error_string(ftdicx));
 > >     return 0;
 > > }
 >
 > --
 > libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
 > To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx
 >

--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx


--
libftdi - see http://www.intra2net.com/en/developer/libftdi for details.
To unsubscribe send a mail to libftdi+unsubscribe@xxxxxxxxxxxxxxxxxxxxxxx
Current Thread