Recent Posts

Pages: [1] 2 3 ... 10
1
USB / Re: linux dies after sending a control transfer.
« Last post by bpaddock on October 19, 2020, 08:49:59 am »
yigityuce / HidApi

That is a five year old fork of HIDAPI.

The libusb people took over HIDAPI and
is keeping it up to date.  Updated three days ago.

They have fixed long standing bugs and addressed issues that
the original author refused to fix, that needed fixed.

Find it here:

https://github.com/libusb/hidapi


While multiple 'things' may be able to access a device at the same time, it is not always a good idea.
I run a HIDAPI based program and my colleague developed for the same device in Delphi.
Running my HIDAPI based program causes his Delphi program to crash if I forget to shut it down.
The device itself doesn't care.



2
USB / Re: linux dies after sending a control transfer.
« Last post by ulao on October 18, 2020, 07:47:24 pm »
Sure, and this is what I figured. My entire point is that Linux seems rather "picky" in this case.

In windows I can run 2 DirectX application at the same time. Do that in Linux (two LibUSB apps) and you fail.  Also LibUSB should have some type of a read only mode or something.  I mean If you want to use a device with something like jstest, there really is no need to take full control of it.  Its just a test app, why take exclusive control.

Though ok, lets settle to agree that you can only run one instance of LibUSB. The what else can I use to communicate with the driver simultaneously? See with linux there is only one option, LibUSB.


Linux should be thinking more open about its devices and one app (maybe SDL) should expose an API. So that many application can use it, or maybe libusb should do this. As it is, its useless accept for 1 case. Expose the device, don't own it.... And I mean that from the OS level. Seems Linux has no way to use a USB  gamepad other then libUSB . So it only seems reasonable that libUSB should allow some type of API once it takes exclusive writes of a device.


I just learned that libusb is not the only option.
 yigityuce / HidApi
seem to show a way to access a device without libusb. I may give that a try.
3
USB / Re: linux dies after sending a control transfer.
« Last post by Jan Axelson on October 18, 2020, 12:50:33 pm »
The host uses information retrieved during enumeration to assign a low-level driver to a device or interface. Unless an application has exclusive access, multiple applications can access the same device. But they all need to communicate with the driver assigned to the device, for example HID or libusb. Yes, a HID can perform periodic interrupt transfers and HID-class control transfers. 
4
USB / Re: linux dies after sending a control transfer.
« Last post by ulao on October 16, 2020, 10:38:39 pm »
Here is a screen shot of 3 application using the same driver.

1 Native windows, polling the game  controller interrupt transfer.
2 My own app using Control transfers and interrupt transfers via HIDAPI.
3 Dolphin using Direct X using control transfers to set up the PID force feedback engine and polling interrupt transfers for inputs.

When you press buttons or move the stick, all of these windows show movement.
5
USB / Re: linux dies after sending a control transfer.
« Last post by ulao on October 16, 2020, 10:24:15 pm »
Quote
OK, just wanted to be sure you understood that the host assigns one driver to the HID interface, typically the HID driver, and you can't use two drivers/APIs to access the same device at the same time.

Well that is not true depending on how you read it. In windows I can use HIDAPI to talk to a device that is also in use by the OS. On top of that I can use HIDAPI to poll interrupts transfers + control transfers + let a another DirectX application game poll for data all at the same time. So if you mean, that you can not have too application usb HIDAPI at the sometime I'd agree. Although one can use HIDAPI and another (HIDUSB?). I can provide proof.



I think I'm learning that in the case of linux its all done with one driver. Sort of a poor design but still not %100 sure I understand this.

Linux has a gamepad 'object' that can use the linux event system. Although to use it with any software you need to use sdl. sdl apparently uses linusb. So using a usb device in any way on linux at all, you are going to need to use libusb and there are no other ways. So you can never use two methods to talk to a device like you can in windows.

Second, I though a USB device was designed to have multiple end points. So you should be able to communicate with ENP0 with libusb and ENP1 with libusb in another instance, no? Or is the limitation the fact only one application can use libusb at a time.

further I was pretty sure you can also talk to a USB device via control transfers at the same time its polling bulk or interrupt date? This comment in the libusb interface I have suggest just that.

/* Continue anyway, even if we could not claim the interface. Control transfers
 * should still work.
 */

6
USB / Re: linux dies after sending a control transfer.
« Last post by Jan Axelson on October 16, 2020, 11:39:05 am »
OK, just wanted to be sure you understood that the host assigns one driver to the HID interface, typically the HID driver, and you can't use two drivers/APIs to access the same device at the same time.
7
USB / Re: linux dies after sending a control transfer.
« Last post by ulao on October 15, 2020, 07:54:37 pm »
No, I'm not necessarily using libusb to communicate. I'm not sure what to OS does to do that? If you connect a HID USB gamepad to a linux  box, you will see the event system mount it to js0. You then can use 'Jstest js0' to see the buttons and what the states are. I'm not really sure what jstest uses. Possibly SDL and if so I'm not sure what SDL uses.

SDL's page says these are the dependencies.
sudo apt-get install git cmake build-essential sqlite3 libsqlite3-dev libssl1.0-dev libssl1.0.0 libusb-1.0-0-dev libudev-dev libgtest-dev libbluetooth3 libbluetooth-dev bluez-tools libpulse-dev python3-pip python3-setuptools

So maybe it is using libusb. If so maybe linux is just not capable of sending controller transfers to a controller, as it is useless unless you are polling from it. I mean, that is its only intention...

The same thing is done in windows.  but when the USB drive is attached, it start polling (no need to run anything). In the case of windows I use  control transfers with HIDAPI, I'm not sure what the OS uses to poll the controller I'm guessing HIDUSB or WINUSB depending.
8
USB / Re: linux dies after sending a control transfer.
« Last post by Jan Axelson on October 15, 2020, 10:28:29 am »
You are using libusb to communicate and at the same time sending HID-class control transfers?
9
USB / Re: linux dies after sending a control transfer.
« Last post by ulao on October 10, 2020, 07:37:47 pm »
Ok turns out to be the call to libusb.The second I get a good retrun from usbOpenDevice Linux cuts off all USB traffic but for the application that called this.  This is what that function does.

Code: [Select]
int usbOpenDevice(usbDevice_t **device, int vendor, char *vendorName, int product, char *productName, int _usesReportIDs)
{
struct usb_bus      *bus;
struct usb_device   *dev;
usb_dev_handle      *handle = NULL;
int                 errorCode = USB_ERROR_NOTFOUND;
static int          didUsbInit = 0;

    if(!didUsbInit){
        usb_init();
        didUsbInit = 1;
    }
    usb_find_busses();
    usb_find_devices();
    for(bus=usb_get_busses(); bus; bus=bus->next){
        for(dev=bus->devices; dev; dev=dev->next){
            if(dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product){
                char    string[256];
                int     len;
                handle = usb_open(dev); /* we need to open the device in order to query strings */
                if(!handle){
                    errorCode = USB_ERROR_ACCESS;
                    fprintf(stderr, "Warning: cannot open USB device: %s\n", usb_strerror());
                    continue;
                }
                if(vendorName == NULL && productName == NULL){  /* name does not matter */
                    break;
                }
                /* now check whether the names match: */
                len = usbGetStringAscii(handle, dev->descriptor.iManufacturer, 0x0409, string, sizeof(string));
                if(len < 0){
                    errorCode = USB_ERROR_IO;
                    fprintf(stderr, "Warning: cannot query manufacturer for device: %s\n", usb_strerror());
                }else{
                    errorCode = USB_ERROR_NOTFOUND;
                    /* fprintf(stderr, "seen device from vendor ->%s<-\n", string); */
                    if(strcmp(string, vendorName) == 0){
                        len = usbGetStringAscii(handle, dev->descriptor.iProduct, 0x0409, string, sizeof(string));
                        if(len < 0){
                            errorCode = USB_ERROR_IO;
                            fprintf(stderr, "Warning: cannot query product for device: %s\n", usb_strerror());
                        }else{
                            errorCode = USB_ERROR_NOTFOUND;
                            /* fprintf(stderr, "seen product ->%s<-\n", string); */
                            if(strcmp(string, productName) == 0)
                                break;
                        }
                    }
                }
                usb_close(handle);
                handle = NULL;
            }
        }
        if(handle)
            break;
    }
    if(handle != NULL){
        int rval, retries = 3;
        //if(usb_set_configuration(handle, 1)){
            //fprintf(stderr, "Warning: could not set configuration: %s\n", usb_strerror());
        //}
        /* now try to claim the interface and detach the kernel HID driver on
         * linux and other operating systems which support the call.
         */
        while((rval = usb_claim_interface(handle, 0)) != 0 && retries-- > 0){
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
            if(usb_detach_kernel_driver_np(handle, 0) < 0){
                fprintf(stderr, "Warning: could not detach kernel HID driver: %s\n", usb_strerror());
            }
#endif
        }
#ifndef __APPLE__
        if(rval != 0)
            fprintf(stderr, "Warning: could not claim interface\n");
#endif
/* Continue anyway, even if we could not claim the interface. Control transfers
 * should still work.
 */
        errorCode = 0;
        *device = handle;
        usesReportIDs = _usesReportIDs;
    }
    return errorCode;
}
Calling usbCloseDevice does not release the device either. I must reset it.
I did notice this bit here
Continue anyway, even if we could not claim the interface. Control transfers should still work.
but commenting any of that make the CT's report error device is busy. Makes me yet again wonder if linux is just not as capable as windows.

EDIT: hmm, I'm not alone.
https://libusb-devel.narkive.com/gOkpkDrQ/re-attaching-device-to-kernel-driver-after-usb-detach-kernel-driver-np

and

https://stackoverflow.com/questions/53196265/libusb-send-control-transfer-without-interrupting-stream
10
USB / program stops receiving USB input data
« Last post by yindengxie on October 10, 2020, 02:03:49 pm »
Hello Jan!

I have four HID USB ports to input data, and the program is attached as follows.

If I do not slide the potentiometer or do not turn the switches on and off often,
after a while, my program stops receiving USB input data. If I continuously slide
the potentiometer or turn the switches on and off, my program can normally receives
the input data from USB port.

Please help me, what is my program problem?

Thank you very much for your support

Pages: [1] 2 3 ... 10