Which of the two "hidraw" devices is my RawHID?

Status
Not open for further replies.

jwatte

Well-known member
When I use the RawHID USB type on a Teensy 3.2, and plug it into my Raspberry Pi, I see two rawhid devices show up:

Code:
pi@crunch:~/hidinfo $ ./hidinfo /dev/hidraw*
/dev/hidraw0: Permission denied
/dev/hidraw1: Permission denied
/dev/hidraw2: Permission denied
/dev/hidraw3: USB,16c0,0486 Teensyduino Teensyduino RawHID
/dev/hidraw4: USB,16c0,0486 Teensyduino Teensyduino RawHID

I presume one of these is the "programming" endpoint, and one of them is the endpoint I actually add.
How can I tell which is for programming, and which is for my sketch?

(It seems to be the one with INPUT endpoint number 0 -- is this always correct?)
 
One is RawHID and the other is the HID interface used for emulating Serial, so you can still use Serial.print() to send to the Arduino Serial Monitor.
 
One is RawHID and the other is the HID interface used for emulating Serial, so you can still use Serial.print() to send to the Arduino Serial Monitor.

But how do I tell, from the Linux machine, which one is which?
Should I attempt to talk to rawhid3 or rawhid4?
 
To tell them apart, you're probably going to need to open each and use the HIDIOCGRDESC ioctl to tell them apart. If you discover you've opened the wrong one, just close the file descriptor and move on.
 
You can use usage page / usage:

cat /sys/class/hidraw/hidraw0/device/report_descriptor | hidrd-convert -o spec
Usage Page (FFC9h), ; FFC9h, vendor-defined
Usage (04h),

Collection (92),
Report Size (8),
Logical Minimum (0),
Logical Maximum (255),
Report Count (64),
Usage (75h),
Input (Variable),
Report Count (32),
Usage (76h),
Output (Variable),
Report Count (4),
Usage (76h),
Feature (Variable),
End Collection

cat /sys/class/hidraw/hidraw1/device/report_descriptor | hidrd-convert -o spec
Usage Page (FFABh), ; FFABh, vendor-defined
Usage (0200h),

Collection (Application),
Report Size (8),
Logical Minimum (0),
Logical Maximum (255),
Report Count (64),
Usage (01h),
Input (Variable),
Report Count (64),
Usage (02h),
Output (Variable),
End Collection
 
Thanks! It's actually easier than that; I look for USB VID/PID of the Teensy, and then pick the endpoint that has a descriptor length of 28.
Some may call this a hack, but it works well enough for me :)

Code:
#include <linux/input.h>
#include <linux/hidraw.h>

#define TEENSY_VENDOR 0x16c0
#define TEENSY_PRODUCT 0x0486
#define TEENSY_RAWHID_ENDPOINT_DESC_SIZE 28

static int verify_open(char const *name) {
    int fd;
    int sz[2] = { 0 };
    hidraw_devinfo hrdi = { 0 };

    fd = open(name, O_RDWR | O_NONBLOCK);
    if (fd < 0) {
        return -1;
    }
    if (ioctl(fd, HIDIOCGRAWINFO, &hrdi) < 0) {
        goto bad_fd;
    }
    if (hrdi.vendor != TEENSY_VENDOR || hrdi.product != TEENSY_PRODUCT) {
        goto bad_fd;
    }
    if (ioctl(fd, HIDIOCGRDESCSIZE, sz) < 0) {
        goto bad_fd;
    }
    //  A magical size found by examination
    if (sz[0] != TEENSY_RAWHID_ENDPOINT_DESC_SIZE) {
        goto bad_fd;
    }
    fprintf(stderr, "serial/hidraw open %s returns fd %d\n", name, fd);
    return fd;

bad_fd:
    if (fd >= 0) {
        close(fd);
    }
    return -1;
}

And, using HidRAW, my application works well. The Linux USB serial driver has some kind of problem that makes it wedge more than work for anything that has a higher packet rate :-(
(I've seen this on more than one device, not just Teensys. Or maybe just all the devices have some kind of bug... but trying on Windows, it doesn't wedge.)
 
Status
Not open for further replies.
Back
Top