USB Host Mouse Driver

Status
Not open for further replies.
Thanks I will continue to take a stab at it... May have some other things I need to do as well, but hopefully.

Quick question, some of the code appears to be hard coded to buffer sizes of 64(0x40)... I noticed that the USB2AX(ATmege32u2), which uses LUFU has it's buffers set in the descriptors to 16(0x10). Should I use the 16s in both the creating of pipes and buffers in this case? I assume so.
 
Making headway!

I now have a Teensy 3.6 talking to a Teensy 3.2 using the USB Host code. I have it setup with both Whole device (Serial only) and I had the T3.2 setup with Serial+Mouse+joystick+.. and the two were able to talk.

I programmed the T3.2 with a version of my AX12 servo controller code and had the test case program on T3.6 try to query the 3.2 for it's local logical registers and it appears like it is returning valid data.

I am not having as much luck with the USB2AX, although will continue to try it. Maybe that it's buffer sizes are 16 instead of 64?

The code is up in a new branch: https://github.com/KurtE/USBHost_t36/tree/Serial-CDCACM

Still testing... May also play with adding rawhid? My guess is that should be pretty easy...
 
Quick update: Started to take a look at RAWHID...

Right Now I have it setup by constructor to only look for a specific top level report, that is: FFAB0200 which is the one that Teensyduino creates...
The constructor defaults to that one...

Looking on Linux at the HID created:
Code:
kurt@kurt-UP-CHT01:~$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 005: ID 0424:2530 Standard Microsystems Corp.
Bus 001 Device 004: ID 0bda:8178 Realtek Semiconductor Corp. RTL8192CU 802.11n WLAN Adapter
Bus 001 Device 003: ID 0424:4603 Standard Microsystems Corp.
Bus 001 Device 008: ID 16c0:0486 Van Ooijen Technische Informatica Teensyduino RawHID
Bus 001 Device 002: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode)
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
kurt@kurt-UP-CHT01:~$ sudo usbhid-dump  -i0 | grep -v : | xxd -r -p | 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
kurt@kurt-UP-CHT01:~$ sudo usbhid-dump  -i1 | grep -v : | xxd -r -p | hidrd-convert -o spec
[sudo] password for kurt:
No matching HID interfaces
kurt@kurt-UP-CHT01:~$

So far I am not doing anything with the data.... But I am getting callbacks for each item...
Code:
*** HID Device RawHID1 16c0:486 - connected ***
  manufacturer: Teensyduino
  product: Teensyduino RawHID
  Serial: 1797940
*** Device HID2 16c0:486 - connected ***
  manufacturer: Teensyduino
  product: Teensyduino RawHID
  Serial: 1797940
*** Device HID3 16c0:486 - connected ***
  manufacturer: Teensyduino
  product: Teensyduino RawHID
  Serial: 1797940
HID: AB CD 00 97 00 B0 00 8F 00 8C 00 DC 00 B7 00 CF 00 C1 00 AD 01 09 01 21 00 FC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 06 8D 
begin, usage=FFAB0200
       type= 2
       min=  0
       max=  255
       reportcount=64
       usage count=0
Raw Begin: usage=FFAB0200, type=2, min=0 Max=255
Input, total bits=512
  usage = FFAB0000  data = 171
Raw: usage=FFAB0000, value=171
  usage = FFAB0000  data = 205
Raw: usage=FFAB0000, value=205
  usage = FFAB0000  data = 0
Raw: usage=FFAB0000, value=0
  usage = FFAB0000  data = 151
Raw: usage=FFAB0000, value=151
  usage = FFAB0000  data = 0
Raw: usage=FFAB0000, value=0
  usage = FFAB0000  data = 176
Raw: usage=FFAB0000, value=176
  usage = FFAB0000  data = 0
Raw: usage=FFAB0000, value=0
  usage = FFAB0000  data = 143
Raw: usage=FFAB0000, value=143
  usage = FFAB0000  data = 0
Raw: usage=FFAB0000, value=0
...
This comes from a T3.2 programmed with Example Raw HID...
Question is what best to do with data. My first pass will probably keep a buffer in the RAWHID class, which will save away the data from each of these callbacks and when I receive the END callback, it will set the I have data (like the mouse) and then have a member the user passes in an array/count which then I would copy the data into... Also need to add a member to do a write...

But wonder if this will be pretty slow for those wanting to use RAWHID... Wondering if there should be some form of short cut that says we have data... Here it is...

Edit: also not sure yet how to do the Writes, That is the USBHIDInput class does not have the stuff setup for the derived class have access to the data needed to be able to queue up writes... May need to detect this and do it all as it's own driver like keyboard...
 
Last edited:
I just pushed a branch up: https://github.com/KurtE/USBHost_t36/tree/CDCACM-Serial

That appears to be working with the CDCACM Serial boards... At least I am able to talk to T3.x boards that are configured with USB=Serial as well as USB=Serial+Joystick...
Also now finally able to talk to USB2AX board which is Atmega32U2 board that uses LUFA library to control Dynamixel Servos (AX-12....)

There is still some code #ifdefed out setup for Prolific boards which was not working... Will try them again soon... Now that I am getting a little more used to use the Saleae logic analyzer to look at USB data...

Also may have a few other vendor boards arriving in the next couple of days from Sparkfun.

In the new branch I pulled the beginnings of RAWHID out of it for now... Need to decide if this somehow ties in with HIDInput class, if so need hooks from the handling class back to the actual device. Need to setup the output Pipe...

Alternatively need to setup as top level object like Keyboard, where it looks to see that it is a HID class like the other HID classes, then asks for HID file... Then does it's own parsing to find the TOP level report index and the like to decide it is a RAWHID.. Then the input class needs to bail on these top reports... Also with the USBHidParser class, may want to have these classes Bail if they have report id's and there are no top level Hid parsers that accept any of the Hid reports...
 
A quick question:

a) For my application, I'd need a faster polling interval. I'd like to add a patch like
Code:
#if defined(USBHS_PERIODIC_LIST_SIZE)
#define PERIODIC_LIST_SIZE (USBHS_PERIODIC_LIST_SIZE)
#else
#define PERIODIC_LIST_SIZE  32
#endif
to ehci.cpp. Paul, what do you think?

I guess, the keyboard code needs a change, too? (right???)
Code:
    println("polling interval = ", interval);
    datapipe = new_Pipe(dev, 3, endpoint, 1, 8, [COLOR=#ff0000]8[/COLOR]); //<---EDIT F.B.
This is a bit..hm, it would be great if it was selectable by the user, too. Can we do this with a #define, too ?
I'd really like to use the "official" library, not my very outdated fork...
 
Hi Frank,

For the fun of it I pushed your PERIODIC_LIST_SIZE change into my CDCACM- Branch listed in #154.
As for the Keyboard one, not sure what to do here as we are setting it to what the Device stated...
Could maybe add #ifdef USBHS_KEYBOARD_INTERVAL
And if set use it else use the one the device stated...

Edit: Added keyboard interval override as I mentioned

My fork is up to date with official but with some Serial support for CDCACM serial drivers (like Teensy) and now working on Prolific again. I have seen the different packets using Logic analyzer on Linux machine so now figuring out what I am missing. So far it looks like it is closely working like CDCACM with setting the baud stuff but there are some other settings as well.

@Paul -

Some of the decoded messages (I looked for ones who setup bmRequest...)
Time Analyzer Name Decoded Protocol Result
Code:
1.60268085	USB LS and FS	bmRequestType=0x80 Data direction=Device to host	 Type=Standard	 Recipient=Device
1.71459314	USB LS and FS	bmRequestType=0x00 Data direction=No data	 Type=Standard	 Recipient=Device
1.73054544	USB LS and FS	bmRequestType=0x80 Data direction=Device to host	 Type=Standard	 Recipient=Device
1.73067565	USB LS and FS	bmRequestType=0x80 Data direction=Device to host	 Type=Standard	 Recipient=Device
1.73077566	USB LS and FS	bmRequestType=0x80 Data direction=Device to host	 Type=Standard	 Recipient=Device
1.7308752	USB LS and FS	bmRequestType=0x80 Data direction=Device to host	 Type=Standard	 Recipient=Device
1.73097948	USB LS and FS	bmRequestType=0x80 Data direction=Device to host	 Type=Standard	 Recipient=Device
1.73110056	USB LS and FS	bmRequestType=0x80 Data direction=Device to host	 Type=Standard	 Recipient=Device
1.73242304	USB LS and FS	bmRequestType=0x00 Data direction=No data	 Type=Standard	 Recipient=Device
1.73268044	USB LS and FS	bmRequestType=0xC0 Data direction=Device to host	 Type=Vendor	 Recipient=Device
1.73276607	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
1.73281992	USB LS and FS	bmRequestType=0xC0 Data direction=Device to host	 Type=Vendor	 Recipient=Device
1.73379908	USB LS and FS	bmRequestType=0xC0 Data direction=Device to host	 Type=Vendor	 Recipient=Device
1.73386294	USB LS and FS	bmRequestType=0xC0 Data direction=Device to host	 Type=Vendor	 Recipient=Device
1.73392415	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
1.733975	USB LS and FS	bmRequestType=0xC0 Data direction=Device to host	 Type=Vendor	 Recipient=Device
1.735023	USB LS and FS	bmRequestType=0xC0 Data direction=Device to host	 Type=Vendor	 Recipient=Device
1.7351103	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
1.73518874	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
1.73526327	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
1.76318705	USB LS and FS	bmRequestType=0x80 Data direction=Device to host	 Type=Standard	 Recipient=Device
4.33803172	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
4.33809436	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
4.33815634	USB LS and FS	bmRequestType=0xA1 Data direction=Device to host	 Type=Class	 Recipient=Interface
4.33823654	USB LS and FS	bmRequestType=0x21 Data direction=Host to device	 Type=Class	 Recipient=Interface
4.33833013	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
4.33842266	USB LS and FS	bmRequestType=0x21 Data direction=No data	 Type=Class	 Recipient=Interface
 
Last edited:
@Paul - I have updated the PL2303 stuff to be pretty close to what I observed on Linux... Will rerecord the Linux one again. On first plugging in, to make sure I did not miss any reprogram of the chip...

The setup is a little more complex... Also I needed to add code to the TXTimer to say don't output the TX until setup is done.

Edit: Here is the decoded information from when I plug the PL2303 board into Linux board(up running Ubuntu), With Arduino Serial monitor configured to talk to it at 115200..
Start logic analyzer capture, plug in board, Hit terminal monitor button, type: Ver<cr> as I have a Lynxmotion SSC-32 plugged into other side...
I edited the output from Logic Analyzer decoded protocol to put in the 5 parameters needed to make a USB call...
Code:
		Time [s]	 Decoded Protocol Result					
Get Descriptor, 0, 0		4.14765112	bmRequestType=0x80 Data direction=Device to host	 Type=Standard	 Recipient=Device			
0, 5, 8, 0, 0		4.25958711	bmRequestType=0x00 Data direction=No data	 Type=Standard	 Recipient=Device			
80, 6, 0x100, 0, 12		4.27554749	bmRequestType=0x80 Data direction=Device to host	 Type=Standard	 Recipient=Device			
80, 6, 0x200, 0, 9		4.27567455	bmRequestType=0x80 Data direction=Device to host	 Type=Standard	 Recipient=Device			
80, 6, 0x200, 0, 27		4.2757782	bmRequestType=0x80 Data direction=Device to host	 Type=Standard	 Recipient=Device			
80, 6, 0x300, 0, 255		4.27590404	bmRequestType=0x80 Data direction=Device to host	 Type=Standard	 Recipient=Device			
80, 6, 0x302, 0x409, 255 (Get US String)		4.27600223	bmRequestType=0x80 Data direction=Device to host	 Type=Standard	 Recipient=Device			
80, 6, 0x301, 0x409, 255 (Get US String)		4.27612821	bmRequestType=0x80 Data direction=Device to host	 Type=Standard	 Recipient=Device			
0, 9, 1, 0, 0		4.27720326	bmRequestType=0x00 Data direction=No data	 Type=Standard	 Recipient=Device			
c0, 1, 0x8484, 0, 1	2	4.27746649	bmRequestType=0xC0 Data direction=Device to host	 Type=Vendor	 Recipient=Device			
40, 1, 0x404, 0, 0		4.27787095	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device			
c0,1,  0x8484, 0, 1 	?	4.27792723	bmRequestType=0xC0 Data direction=Device to host	 Type=Vendor	 Recipient=Device			
c0, 1, 0x8383, 0, 1	0xff	4.27893025	bmRequestType=0xC0 Data direction=Device to host	 Type=Vendor	 Recipient=Device			
c0, 1, 0x8484, 0, 1	2	4.27899998	bmRequestType=0xC0 Data direction=Device to host	 Type=Vendor	 Recipient=Device			
40, 1, 0x404, 1, 0		4.27906298	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device			
c0, 1, 0x8484, 0, 1	?	4.27911296	bmRequestType=0xC0 Data direction=Device to host	 Type=Vendor	 Recipient=Device			
c0, 1, 0x8383, 0, 1	0xff	4.28011553	bmRequestType=0xC0 Data direction=Device to host	 Type=Vendor	 Recipient=Device			
40, 1, 0, 1, 0		4.28017713	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device			
40, 1, 1, 0, 0		4.28022666	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device			
40, 1, 2, 0x44, 0		4.28027612	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device			
80, 6, 0x3ee, 0, 0x400 (get string)		4.30769737	bmRequestType=0x80 Data direction=Device to host	 Type=Standard	 Recipient=Device			
40, 1, 8,0,0		6.79469151	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device			
40, 1, 9, 0, 0		6.79502308	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device			
A1, 21, 0, 0, 7	80,250,0,0,0,0	6.79510902	bmRequestType=0xA1 Data direction=Device to host	 Type=Class	 Recipient=Interface			
21,20,0,0,7	0,c2,1,0,0,0,8	6.79517158	bmRequestType=0x21 Data direction=Host to device	 Type=Class	 Recipient=Interface			
40, 1, 0,0,0		6.7952483	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device			
21, 22, 3, 0,0		6.79531466	bmRequestType=0x21 Data direction=No data	 Type=Class	 Recipient=Interface			
21,22, 3,0,0		6.79543615	bmRequestType=0x21 Data direction=No data	 Type=Class	 Recipient=Interface
Edited again, to put the mk_setup parameters first


FYI - I purchased another USB to serial board from Sparkfun: https://www.sparkfun.com/products/14050, uses CH340G IC from WCH.

Needless to say code does not recognize it.
Code:
USBSerial claim this=1FFF3200
vid=1A86, pid=7523, bDeviceClass = 255, bDeviceSubClass = 0, bDeviceProtocol = 0
09 04 00 00 03 FF 01 02 00 07 05 82 02 20 00 00 07 05 02 02 20 00 00 07 05 81 03 08 00 01 
USBHub memory usage = 960


On Linux:
Code:
kurt@kurt-UP-CHT01:~$ ls /dev/tty*
/dev/tty    /dev/tty18  /dev/tty28  /dev/tty38  /dev/tty48  /dev/tty58      /dev/ttyS0
/dev/tty0   /dev/tty19  /dev/tty29  /dev/tty39  /dev/tty49  /dev/tty59      /dev/ttyS1
/dev/tty1   /dev/tty2   /dev/tty3   /dev/tty4   /dev/tty5   /dev/tty6       /dev/ttyS2
/dev/tty10  /dev/tty20  /dev/tty30  /dev/tty40  /dev/tty50  /dev/tty60      /dev/ttyS3
/dev/tty11  /dev/tty21  /dev/tty31  /dev/tty41  /dev/tty51  /dev/tty61      /dev/ttyUSB0
/dev/tty12  /dev/tty22  /dev/tty32  /dev/tty42  /dev/tty52  /dev/tty62
/dev/tty13  /dev/tty23  /dev/tty33  /dev/tty43  /dev/tty53  /dev/tty63
/dev/tty14  /dev/tty24  /dev/tty34  /dev/tty44  /dev/tty54  /dev/tty7
/dev/tty15  /dev/tty25  /dev/tty35  /dev/tty45  /dev/tty55  /dev/tty8
/dev/tty16  /dev/tty26  /dev/tty36  /dev/tty46  /dev/tty56  /dev/tty9
/dev/tty17  /dev/tty27  /dev/tty37  /dev/tty47  /dev/tty57  /dev/ttyprintk
kurt@kurt-UP-CHT01:~$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 004: ID 0424:2530 Standard Microsystems Corp.
Bus 001 Device 003: ID 0bda:8178 Realtek Semiconductor Corp. RTL8192CU 802.11n WLAN Adapter
Bus 001 Device 002: ID 0424:4603 Standard Microsystems Corp.
Bus 001 Device 006: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
kurt@kurt-UP-CHT01:~$ lsusb -v -d 1a86:7523

Bus 001 Device 006: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass          255 Vendor Specific Class
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0         8
  idVendor           0x1a86 QinHeng Electronics
  idProduct          0x7523 HL-340 USB-Serial adapter
  bcdDevice            2.54
  iManufacturer           0
  iProduct                2
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           39
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x80
      (Bus Powered)
    MaxPower               96mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           3
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      1
      bInterfaceProtocol      2
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0020  1x 32 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval               1
kurt@kurt-UP-CHT01:~$
 
Last edited:
I think, there might be some users who want to flash a Teensy 3.x with a T3.6 .... - from SD-Card :)
...or use a 3.6 with display as Terminal ...
 
Two things:

a) the Keyboard LEDS do not work anymore for me (last tested some weeks ago)

b) A user reported a not-working keyboard. He debugged the code and found that adding size 64 to the keyboard code :

if (size != 8 && size != 64) {
return false; // must be 8 bytes for Keyboard Boot Protocol
}

helped. (I have no idea what that means - I'm a usb-noob...)
 
Last edited:
a) the Keyboard LEDS do not work anymore for me (last tested some weeks ago)

b) A user reported a not-working keyboard. He debugged the code and found that adding size 64 to the keyboard code :

I will take a look at these... Make sure I did not bust anything...

As for the 64, sounds like a strange keyboard... I can obviously merge that into my branch, which hopefully will figure some more stuff out and have more serial ports working.

helped. (I have no idea what that means - I'm a usb-noob...)
I know the feeling! But I am thinking I have started to learn a few things.

For example with some of these Serial ports. I learn some by, doing lots of googling, plus also looking at what things that Linux can tell me about the device. PLus look at an old copy of Linux sources I had earlier downloaded... And now trying to copare the different packets that I see using the Saleae logic anlyzer with for example the startup sequence on Linux and the start up sequence that I am doing...
 
@Paul - One interesting thing I have noticed with the PL2303 and maybe others, is probably needing something to indicate (or wait for) to say that the Serial port has completed it's initialization.

That is for the PL2303... All of the drivers or explanations, plus observed data show their init code doing something like:
Code:
	pl2303_vendor_read(0x8484, 0, serial, buf);
	pl2303_vendor_write(0x0404, 0, serial);
	pl2303_vendor_read(0x8484, 0, serial, buf);
	pl2303_vendor_read(0x8383, 0, serial, buf);
	pl2303_vendor_read(0x8484, 0, serial, buf);
	pl2303_vendor_write(0x0404, 1, serial);
	pl2303_vendor_read(0x8484, 0, serial, buf);
	pl2303_vendor_read(0x8383, 0, serial, buf);
	pl2303_vendor_write(0, 1, serial);
	pl2303_vendor_write(1, 0, serial);
	if (type == HX)
		pl2303_vendor_write(2, 0x44, serial);
	else
		pl2303_vendor_write(2, 0x24, serial);
This is only some of the beginnings as then they continue on to do some of the stuff to set the baud rate...
Note vendor_read(C0, 1, ....) and vendor_write(40, 1)

Currently in the Serial code I have, the end of claim issue the first one:
Code:
			println("PL2303: readRegister(0x04)");
			// Need to setup  the data the line coding data
			mk_setup(setup, 0xC0, 0x1, 0x8484, 0, 1);  
			queue_Control_Transfer(dev, &setup, setupdata, this); 
			control_queued = true;
			setup_state = 1; 	// We are at step one of setup... 
			pending_control = 0x1f;	// Maybe don't need to do...
I then have the control method use both a state variable and your earlier pending_control... With the pending control, I use the first bit to say use the state variable... This way your setting the 2nd bit with the begin(baud) method, will allow me to do most of the initial stuff...
Like:
Code:
	if (sertype == PL2303) {
		if (pending_control & 1) {
			// Still in larger setup state mode
			switch (setup_state) {
				case 1:
					println("PL2303: writeRegister(0x04, 0x00)");
					mk_setup(setup, 0x40, 1, 0x0404, 0, 0); // 
					queue_Control_Transfer(device, &setup, NULL, this);
					setup_state = 2; 
					control_queued = true;
					return;
				case 2:
					println("PL2303: readRegister(0x04)");
					mk_setup(setup, 0xC0, 0x1, 0x8484, 0, 1);  
					queue_Control_Transfer(device, &setup, setupdata, this); 
					control_queued = true;
					setup_state = 3; 
					return;
				case 3:
					println("PL2303: v1 = readRegister(0x03)");
					mk_setup(setup, 0xC0, 0x1, 0x8383, 0, 1);  
					queue_Control_Transfer(device, &setup, setupdata, this); 
					control_queued = true;
					setup_state = 4; 
					return;
				case 4:
...

One issue is: When the claim completes, the code returns to the user code:
So if you have a serial object, like userial and you do something like:

Code:
bool userial_active = false;
void loop() {
    if (userial  && !userial_active) {
        userial_active = true;
        // We have a new active serial device. 
        userial.begin(115200); 

        userial.println("Hello World");
        ...
}

With this the userial.begin will be called right after the claim with only the first device initialization output. In this case the begin is not bad as I simply save the baud rate away, set the pending_control |=2; like you had so then the initial output is completed, before I try to output the Baud configuration (same as the CDCACM message)
Code:
			setupdata[0] = (baudrate) & 0xff;  // Setup baud rate 115200 - 0x1C200
			setupdata[1] = (baudrate >> 8) & 0xff;
			setupdata[2] = (baudrate >> 16) & 0xff;
			setupdata[3] = (baudrate >> 24) & 0xff;
	        setupdata[4] = 0; // 0 - 1 stop bit, 1 - 1.5 stop bits, 2 - 2 stop bits
	        setupdata[5] = 0; // 0 - None, 1 - Odd, 2 - Even, 3 - Mark, 4 - Space
	        setupdata[6] = 8; // Data bits (5, 6, 7, 8 or 16)
	        print("PL2303: Set baud/control: ");
	        print_hexbytes(&setupdata, 7);
			mk_setup(setup, 0x21, 0x20, 0, 0, 7);
			queue_Control_Transfer(device, &setup, setupdata, this);
			control_queued = true;

But then there is the println command. It will instantly put this on the TX output queue and as it is not > size of the output size (64), it starts the tx timer... Which will go off before we complete all of the init messages and probably screw things up...

Currently I have a hack in the txtimer code that detects if pending_control != 0 and then postpones the write, like if it did not have any buffers available... This is only a partial fix as did not handle case if the user had done something like: userial.write(buffer, 100);
Which would queue the first one and not rely on timer to do it.

Not sure best approach here...

Side note on PL2303, the interface defines 3 pipes:
Code:
kurt@kurt-UP-CHT01:~$ lsusb -v -d 067b:2303

Bus 001 Device 006: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0        64
  idVendor           0x067b Prolific Technology, Inc.
  idProduct          0x2303 PL2303 Serial Port
  bcdDevice            3.00
  iManufacturer           1
  iProduct                2
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           39
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           3
      bInterfaceClass       255 Vendor Specific Class
      bInterfaceSubClass      0
      bInterfaceProtocol      0
      iInterface              0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x000a  1x 10 bytes
        bInterval               1
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x83  EP 3 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0040  1x 64 bytes
        bInterval               0
kurt@kurt-UP-CHT01:~$
Wondering if I need to do something with EP1 (In interrupt) So far ignored it... May try creating the pipe and setup a callback to see if it gets called and with what?

Suggestions?
 
@Paul (and others) :D
I have the PL2303 now talking. Found bug in my code.

I issued a Pull Request so you can take a look at the FTDI and Prolific... Will probably before or after merge, do a cleanup pass. Maybe split out some of the things having to do with different Serial devices.

Kurt
 
Two things:

a) the Keyboard LEDS do not work anymore for me (last tested some weeks ago)

b) A user reported a not-working keyboard. He debugged the code and found that adding size 64 to the keyboard code :

if (size != 8 && size != 64) {
return false; // must be 8 bytes for Keyboard Boot Protocol
}

helped. (I have no idea what that means - I'm a usb-noob...)

a) I did a quick test run of my current stuff and it still appears to work at least for me with one keyboard...
At least with the default code that for key_release.

b) Put in a similar test like you, but simply allowed the range 8-64... This value is the maximum report size that the device can return to you. So maybe there are some other reports that this device can create with larger packet of data?

Note: I did not change the actual size of data the pipe can handle from the device:
datapipe = new_Pipe(dev, 3, endpoint, 1, 8, interval);

Nor did I change the size of data that we read or ask for: queue_Data_Transfer(datapipe, report, 8, this);
Or in class definition: uint8_t report[8];

I added this to my fork/branch that I have a Pull Request on. so assuming Pull takes it...
 
a) I did a quick test run of my current stuff and it still appears to work at least for me with one keyboard...
At least with the default code that for key_release.

b) Put in a similar test like you, but simply allowed the range 8-64... This value is the maximum report size that the device can return to you. So maybe there are some other reports that this device can create with larger packet of data?

Note: I did not change the actual size of data the pipe can handle from the device:
datapipe = new_Pipe(dev, 3, endpoint, 1, 8, interval);

Nor did I change the size of data that we read or ask for: queue_Data_Transfer(datapipe, report, 8, this);
Or in class definition: uint8_t report[8];

I added this to my fork/branch that I have a Pull Request on. so assuming Pull takes it...

LEDs: Hm, in this case, I have to check if I have everything right.. I tested with the keyboard example and the Lib that came with TD 1.40. Is it re:LEDs different from your version ? I try tomorrow.
 
@Paul - And others...

Today started adding support for CH341 based USB to serial adapters.
The one I am playing with: https://www.sparkfun.com/products/14050

I have a few more cheap USB to serial adapters arriving tomorrow maybe Friday...
PL2303: https://smile.amazon.com/gp/product/B00QT7LQ88
PL2303: https://smile.amazon.com/gp/product/B009GXEF8A
(3 adapters: PL2302, CP2102, CH340): https://smile.amazon.com/gp/product/B06Y3V9BPL

I will need to retest the different boards again as some code has changed. Like the FTDI and CDCACM.

Put code up in new branch: https://github.com/KurtE/USBHost_t36/tree/Serial-CH341-Plus
 
@Paul + others:

Wondering about Some of the other features for USB Host Serial drivers. Both what is needed and later how to implement...

Start with maybe some of the more obvious: Assume that userial is my object.

userial.flush() - Would expect it to send now and not wait for the txtimer to trigger. Not sure if I can simply call the txtimer function then, or should set the timer to 0 or... Currently this is a NOP (like I believe Serial.flush() is a NOP...

userial.format() - like userial.begin(baud, format) - Need to process that data and figure out how to encode the data for Parity, Number of bits, stop bits, ... into the appropriate messages. Also can be interesting as this may require different numbers of messages to be sent depending on which adapter.

Now some of the more interesting things: like how to handle DTR, RTS, CTS signals And when. Will try to test some of these with the FTDI breakout cables that have 6 pins (GND, -CTS, VCC, TXD, RXD, -DTR). This same pin out appears to be used on some of the others I have or will have...

9 pin RS232 cables have these signals as well:
Code:
Pin 	SIG. 	Signal Name 	DTE (PC)
1 	DCD 	Data Carrier Detect 	in
2 	RXD 	Receive Data 	in
3 	TXD 	Transmit Data 	out
4 	DTR 	Data Terminal Ready 	out
5 	GND 	Signal Ground 	-
6 	DSR 	Data Set Ready 	in
7 	RTS 	Request to Send 	out
8 	CTS 	Clear to Send 	in
9 	RI 	Ring Indicator 	in

DTR - Should the userial.begin() always try to assert this one then have userial.end() deassert it? I am guessing yes. Or should we have some way to set them? Or is this something for the device at the other side to control? so would need: userial.dtr() (like you sort of have in Serial.dtr which always returns 1...

Now for CTS - I believe that is something controlled at the connector end... i.e. the device telling the driver that it is clear to send... Should we enable this by default? Or should we add method like the other Serial objects, like:

userial.attachCts(myCTSPin) - Which configures the USB code to handle it, plus probably sets the pin into input mode...

BUT - I don't think this is correct. That is the CTS pin is more likely going to different processor to handle. So I assume this is some configuration setup to enable it (Should it be done by default?) Also wonder if the other side then the CTS pin is pulled HIGH (and low), how the Serial chips communicate this information. Does it send data back on the Control pipe, or is this were the Interrupt Input pipe is used (which we have not configured...

So I think maybe: need some way to configure... And maybe a query function so Teensy app can query?
Maybe something like: userial.cts().

Then there is RTS...

Probably missing some other information as well.

Edit: DTR/RTS appear to be asserted during Begin:
On FTDI: DTR is asserted with the message: mk_setup(setup, 0x40, 1, 0x0101, 0, 0);
On PL2303: DTR and asserted with: mk_setup(setup, 0x21, 0x22, 3, 0, 0); // 1 bit DTR, 2 bit: CTS...
On CH341: mk_setup(setup, 0x40, 0xa4, 0xff9f, 0, 0) (~(DTR=0x4S | RTX=0x20)

So will add step to END to output the appropriate values.

Again wondering: Should begin(...) and end(...) Wait until their packets are sent... Maybe something like:
Code:
void USBSerial::begin(uint32_t baud, uint32_t format)
{
	NVIC_DISABLE_IRQ(IRQ_USBHS);
	baudrate = baud;
	pending_control |= 2;
	if (!control_queued) control(NULL);
	NVIC_ENABLE_IRQ(IRQ_USBHS);
	while (pending_control) {
		yield(); // not sure if should be hard hang or yield...
	}
}
As some way to make sure the user code does not try to use it before it is ready. Alternatively could add a method like: busy() which returns true if there is still pending control.
 
Last edited:
Update: I believe I have the begin(9600)... end() ... begin(115200) working. At least reasonably.

When I was testing, I tried it on the different types of converters I have and it worked. One exception is I am not sure if the raising/lowering of DTR on the FTDI is working like it should yet, or simply that is not the DTR line that is going out on my FTDI cable... May need to get a breakout board, or someone else can test.

I am now putting the code in place that hopefully should allow you to specify: number of bits, Parity, Stop bits on the format parameter of the userial.begin.

I have the code in place (I think) for the currently implemented chip sets, except the CH341 as I am trying to figure out the USB packets differences for this on these chips. Did not find anything on network that describes it.

From my usage of the Saleae logic analyzer with the protocol analyzer (USB LS FS) I was able to locate the configuration message (filter on bmRequest). I then saved the found information to .csv file, which I opened in excel and then in the logic analyzer, I walked through each of these messages, extracting the data... As mentioned, I don't think the Linux driver supports this configuration stuff. So hacked up a Visual Basic (2015) app, that opened serial port and had drop downs with Baud/Num bits/Parity/Num stop bits... I then captured this data. Found the Windows driver may have some smarts in that it knows some configuration stuff from previous run. So to get consistent comparisons, I unplug and replug in board, before each test... Again not sure if anyone is interested in this, but for example found:

Code:
	Time [s]	 Analyzer Name	 Decoded Protocol Result		
40, a1, C29c, B2B9, 0	1.15750167	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
40, a4, df, 0, 0	1.15759889	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
40, a4, 9f, 0, 0	1.15768322	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
c0, 95, 0706, 0, 2 = 9f ee	1.15776571	USB LS and FS	bmRequestType=0xC0 Data direction=Device to host	 Type=Vendor	 Recipient=Device
40, 9a, 2727, 0, 0	1.15788994	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
c0, 95, 0706, 0, 2 = 9f ee	1.15804209	USB LS and FS	bmRequestType=0xC0 Data direction=Device to host	 Type=Vendor	 Recipient=Device
40, 9a, 2727, 0, 0	1.15816569	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
40, 9a, 1312, cc83,  0	1.15828494	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
40, 9a, f2c, 7, 0	1.15836139	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
40, a4, bf, 0, 0	1.15845769	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
40, 9a, 2518, c3, 0	1.15851495	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
c0, 95, 0706, 0, 2 = bf ee	1.15858652	USB LS and FS	bmRequestType=0xC0 Data direction=Device to host	 Type=Vendor	 Recipient=Device
40, 9a, 2727, 0, 0	1.15869347	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
c0, 95, 0706, 0, 2 = bf ee	1.15875924	USB LS and FS	bmRequestType=0xC0 Data direction=Device to host	 Type=Vendor	 Recipient=Device
40, 9a, 2727, 0, 0	1.15885762	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
40, a4, ff, 0, 0	1.1589389	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
c0, 95, 0706, 0, 2 = ff ee	1.15899345	USB LS and FS	bmRequestType=0xC0 Data direction=Device to host	 Type=Vendor	 Recipient=Device
40, 9a, 2727, 0, 0	1.15908112	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
c0, 95, 0706, 0, 2 = ff de	1.15964805	USB LS and FS	bmRequestType=0xC0 Data direction=Device to host	 Type=Vendor	 Recipient=Device
40, 9a, 2727, 0, 0	1.15974015	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
c0, 95, 0706, 0, 2 = ff ee	1.81255971	USB LS and FS	bmRequestType=0xC0 Data direction=Device to host	 Type=Vendor	 Recipient=Device
40, a4, ff, 0, 0	1.81267182	USB LS and FS	bmRequestType=0x40 Data direction=No data	 Type=Vendor	 Recipient=Device
The first column is the data, I hand typed in for (Request type, request, wValue, wIndex, length) the ones whose request type has the 0x80 bit set are query, the = values
where the returned values...

Some things interesting that I found was:
The linux code and Windows code output different stuff (not too unexpected), but for example baud rate ones: Two windows packets (40, 9a, 1312, cc83, 0) (40, 9a, f2c, 7, 0)
The linux version is almost the same: except on the first packet wIndex is: cc03 instead of cc83... Not sure what that bit does different...

As now trying to figure out: data bits, parity, I so far have found the packet (40, a4, bf, 0, 0) appears to probably control this, only packet different from
8N1 - wValue=c3, 7e1 = da, 7o1 = ca, and 7n1 - Packet missing...

I can probably try some additional configurations, but first will see if I can get this part to work...
 
@ Frank - Fixed and simplified keyboard LED updates. It appeared to work earlier but had to be deferred... Stupid mistake. I had the setup structure on the stack thinking it would be copied when it was put onto the queue... So now just uses the setup one part of the object. This also allowed me to remove the defer code and variables associated with it. Also the data buffer used is also part of class.

@Paul - And others - Update on USBSerial. I thought I posted an update two days ago, but looks like it was lost... Probably forgot to hit the post button...

I think the serial code is working reasonably well and went ahead and issued a Pull Request: https://github.com/PaulStoffregen/USBHost_t36/pull/11

Some of the updates in here included:

The code now allows you to call userial.begin(9600);
Then later call: userial.end();
And open again with different parameters: userial.begin(38400).

The code now is setup that the calls to begin and end will not return until the last setup packets have been at least queued.

As part of the begin/end stuff added some support for the Format parameter of the begin. So far I have only tested some with: 8N1, 8N2, 7E1, 7O1.

I have the format parameter set as a set of bits (5 bits for bits) as some of these adapters mention support for 16 bit writes. There are 3 bits for Parity. and 1 or 2 bits for stop bits...

Added support for CH341 based serial adapters. Note: I may not fully handle all combinations of these especially as it has to do with Format. But I think I have more support for the format parameters than some Linux drivers.

I also added support for some CP210x serial drivers as well. I only entered the one VID:pID that I have...
Other than the CDCACM driver, which looks at the USB type... All of the others are driven by the Vendor ID : Product ID.
Note: I used a really simple startup configuration code for this one, very similar to the FTDI startup (except the messages and data is different). The Linux and Windows startup appear to be a lot more complicated.
I traced some of them using the logic analyzer. The nice thing about these adapters is the vendor actually documents the USB protocol for them: https://www.silabs.com/documents/public/application-notes/AN571.pdf


The code has a table at the start which maps the VID:pID pairs to which type of Serial adapter it is.
Code:
USBSerial::product_vendor_mapping_t USBSerial::pid_vid_mapping[] = {
	// FTDI mappings. 
	{0x0403, 0x6001, USBSerial::FTDI},

	// PL2303
	{0x67B,0x2303, USBSerial::PL2303}, 

	// CH341
	{0x4348, 0x5523, USBSerial::CH341 },
	{0x1a86, 0x7523, USBSerial::CH341 },
	{0x1a86, 0x5523, USBSerial::CH341 },

	// Silex CP210...
	{0x10c4, 0xea60, USBSerial::CP210X }
So as others find different combinations that they would like to work, we can simply update this table...

Note: I also put the Keyboard LEDs fix into this branch as well. So it is also covered by this Pull Request. But could also be separated if desired.

I may give looking at these Serial adapters a break... But may do one little cleanup. The claim code, has a reasonable amount of duplicate code for each type.
That is they all look for the Input endpoint, output endpoint, ... Which should probably be combined.
 
I didn't want to make a new topic since all the people discussing this were in here anyway.

I'm trying to use an RFID reader with the Teensy 3.6 USB Host port. The reader appears to a computer as a keyboard and sends the UID of a tag in its field as key presses. The reader works fine.

I tried the USBHost_t36 library and got it working with my apple keyboard, but for some reason the Teensy does not recognise the reader as a keyboard. This is what I see when I turned on debugging on the library:

Code:
USB Host Testing
960
sizeof Device = 36
sizeof Pipe = 96
sizeof Transfer = 64
power up USBHS PHY
port change: 10001803
    connect
  begin reset
port change: 10001005
  port enabled
  end recovery
new_Device: 12 Mbit/sec
new_Pipe
enumeration:
enumeration:
enumeration:
enumeration:
enumeration:
enumeration:
enumeration:
enumeration:
Config data length = 43
enumeration:
bNumInterfaces = 2
bConfigurationValue = 1
enumeration:
USBHub memory usage = 960
USBHub claim_device this=1FFF3B20
USBHub memory usage = 960
USBHub claim_device this=1FFF3F40
USBHub memory usage = 960
USBHub claim_device this=1FFF2E80
USBHub memory usage = 960
USBHub claim_device this=1FFF3240
KeyboardController claim this=1FFF2500
KeyboardController claim this=1FFF2740
HIDParser claim this=1FFF3600
HIDParser claim this=1FFF4300
HIDParser claim this=1FFF47E0
HIDParser claim this=1FFF29A0
HIDParser claim this=1FFF2020
Descriptor 4 = INTERFACE
KeyboardController claim this=1FFF2500
KeyboardController claim this=1FFF2740
HIDParser claim this=1FFF3600
HIDParser claim this=1FFF4300
HIDParser claim this=1FFF47E0
HIDParser claim this=1FFF29A0
HIDParser claim this=1FFF2020
Descriptor 4 = INTERFACE
KeyboardController claim this=1FFF2500
KeyboardController claim this=1FFF2740
HIDParser claim this=1FFF3600
 bInterfaceClass =    3
 bInterfaceSubClass = 0
 bInterfaceProtocol = 1
HID Parser Claim: 09 04 01 00 01 03 00 01 07 09 21 10 01 00 01 22 3F 00 07 05 81 03 08 00 01 
report descriptor size = 63
Single endpoint HID:
  endpoint = 81
   size = 8
   interval = 1
new_Pipe
allocate_interrupt_pipe_bandwidth
 best_bandwidth = 3, at offset = 0, shift= 0
Descriptor 33 = HID
Descriptor 5 = ENDPOINT
*** Device HID2 ab1:2 - connected ***
  manufacturer: FEIG ELECTRONIC GmbH
  product: OBID RFID-Reader
  Serial: 1D437A32
control callback (hid)
05 01 09 06 A1 01 05 07 19 E0 29 E7 15 00 25 01 75 01 95 08 81 02 95 01 75 08 81 01 95 05 75 01 05 08 19 01 29 03 91 02 95 01 75 03 91 01 95 06 75 08 15 00 25 65 05 07 19 00 29 FF 81 00 C0 
  mesg = 22000681
  got report descriptor
Found top level collection 10006
find_driver
  driver 1FFF3EE0
  driver 1FFF3F14
  driver 1FFF3AE0

And this is what I see with debugging on when the reader sees a tag.

Code:
HID: 02 00 08 00 00 00 00 00 
HID: 00 00 00 00 00 00 00 00 
HID: 00 00 27 00 00 00 00 00 
HID: 00 00 00 00 00 00 00 00 
HID: 00 00 27 00 00 00 00 00 
HID: 00 00 00 00 00 00 00 00 
HID: 00 00 24 00 00 00 00 00 
HID: 00 00 00 00 00 00 00 00 
HID: 02 00 06 00 00 00 00 00 
HID: 00 00 00 00 00 00 00 00 
HID: 00 00 1E 00 00 00 00 00 
HID: 00 00 00 00 00 00 00 00 
HID: 02 00 07 00 00 00 00 00 
HID: 00 00 00 00 00 00 00 00 
HID: 00 00 23 00 00 00 00 00 
HID: 00 00 00 00 00 00 00 00 
HID: 00 00 22 00 00 00 00 00 
HID: 00 00 00 00 00 00 00 00 
HID: 00 00 23 00 00 00 00 00 
HID: 00 00 00 00 00 00 00 00 
HID: 00 00 20 00 00 00 00 00 
HID: 00 00 00 00 00 00 00 00 
HID: 00 00 1E 00 00 00 00 00 
HID: 00 00 00 00 00 00 00 00 
HID: 00 00 1E 00 00 00 00 00 
HID: 00 00 00 00 00 00 00 00 
HID: 00 00 22 00 00 00 00 00 
HID: 00 00 00 00 00 00 00 00 
HID: 00 00 22 00 00 00 00 00 
HID: 00 00 00 00 00 00 00 00 
HID: 00 00 24 00 00 00 00 00 
HID: 00 00 00 00 00 00 00 00 
HID: 00 00 28 00 00 00 00 00 
HID: 00 00 00 00 00 00 00 00

That means: E007C1D656311557

So I'm getting the data from the reader (only with debugging on), but the library doesn't think that it's a keyboard. Can anyone point out something I could try to get the key presses out of there easily? Or is there something in the HID part already implemented that I could use to get the data parsed?
 
Looks like it's not being claimed by the keyboard driver, even though it says it's a boot protocol keyboard. Very strange....
 
It's this one: http://www.feig.de/en/products/identification/product/id-iscpr101/ Not very easy to buy at the moment, but I've been using this and other similar readers (RS232) from Feig for many years on some installations. Got mine from a shop here in Finland.

Might help to see some more of the information about this device.

You might try editing the library in Keyboard.cpp in the claim function.

Maybe have the start of it look like:
Code:
bool KeyboardController::claim(Device_t *dev, int type, const uint8_t *descriptors, uint32_t len)
{
	println("KeyboardController claim this=", (uint32_t)this, HEX);
	[COLOR="#FF0000"]print("vid=", dev->idVendor, HEX);
	print(", pid=", dev->idProduct, HEX);
	print(", bDeviceClass = ", dev->bDeviceClass);
   	print(", bDeviceSubClass = ", dev->bDeviceSubClass);
   	println(", bDeviceProtocol = ", dev->bDeviceProtocol);
	print_hexbytes(descriptors, len);[/COLOR]

	// only claim at interface level
	if (type != 1) return false;
	if (len < 9+9+7) return false;
...
That we we can see the whole descriptor to see more information on the device...

But maybe you already gave me most of this information from the HID parser:
Code:
HIDParser claim this=1FFF3600
 bInterfaceClass =    3
 bInterfaceSubClass = 0
 bInterfaceProtocol = 1
HID Parser Claim: 09 04 01 00 01 03 [COLOR="#FF0000"]00 [/COLOR]01 07 09 21 10 01 00 01 22 3F 00 07 05 81 03 08 00 01

From This I am seeing that it is marked as HID device, Interface protocol 1 (Keyboard), but descriptors[6] == 0 (not 1) so not marked as boot device. So Keyboard code will bail.

Might help to again see more details about this one. When I am looking at a new device, I have a tendency to look at data about it from a Linux box... Currently I am using an UP board which is 64 bit intel... But would probably work equally with ARM based boards like RPI3...

Example for a Dell keyboard, I do the following commands:
Code:
[COLOR="#FF0000"]kurt@kurt-UP-APL01:~$ dmesg | tail -20[/COLOR]
[31903.147718] cfg80211:  DFS Master region: FCC
[31903.147720] cfg80211:   (start_freq - end_freq @ bandwidth), (max_antenna_gain, max_eirp), (dfs_cac_time)
[31903.147723] cfg80211:   (2402000 KHz - 2472000 KHz @ 40000 KHz), (N/A, 3000 mBm), (N/A)
[31903.147726] cfg80211:   (5170000 KHz - 5250000 KHz @ 80000 KHz, 160000 KHz AUTO), (N/A, 1700 mBm), (N/A)
[31903.147729] cfg80211:   (5250000 KHz - 5330000 KHz @ 80000 KHz, 160000 KHz AUTO), (N/A, 2300 mBm), (0 s)
[31903.147731] cfg80211:   (5490000 KHz - 5730000 KHz @ 160000 KHz), (N/A, 2300 mBm), (0 s)
[31903.147733] cfg80211:   (5735000 KHz - 5835000 KHz @ 80000 KHz), (N/A, 3000 mBm), (N/A)
[31903.147735] cfg80211:   (57240000 KHz - 63720000 KHz @ 2160000 KHz), (N/A, 4000 mBm), (N/A)
[31903.151022] wlp4s0: Limiting TX power to 30 (30 - 0) dBm as advertised by 14:91:82:a1:0d:bc
[34092.671088] usb 1-4: new low-speed USB device number 7 using xhci_hcd
[34092.864779] usb 1-4: New USB device found, idVendor=04ca, idProduct=0027
[34092.864793] usb 1-4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[34092.864801] usb 1-4: Product: USB Multimedia Keyboard
[34092.864807] usb 1-4: Manufacturer: Lite-On Technology Corp.
[34092.865187] usb 1-4: ep 0x81 - rounding interval to 128 microframes, ep desc says 192 microframes
[34092.865203] usb 1-4: ep 0x82 - rounding interval to 64 microframes, ep desc says 80 microframes
[34092.872990] input: Lite-On Technology Corp. USB Multimedia Keyboard as /devices/pci0000:00/0000:00:15.0/usb1/1-4/1-4:1.0/0003:04CA:0027.0006/input/input11
[34092.927815] hid-generic 0003:04CA:0027.0006: input,hidraw0: USB HID v1.10 Keyboard [Lite-On Technology Corp. USB Multimedia Keyboard] on usb-0000:00:15.0-4/input0
[34092.936850] input: Lite-On Technology Corp. USB Multimedia Keyboard as /devices/pci0000:00/0000:00:15.0/usb1/1-4/1-4:1.1/0003:04CA:0027.0007/input/input12
[34092.991813] hid-generic 0003:04CA:0027.0007: input,hiddev0,hidraw1: USB HID v1.10 Device [Lite-On Technology Corp. USB Multimedia Keyboard] on usb-0000:00:15.0-4/input1
[COLOR="#FF0000"]kurt@kurt-UP-APL01:~$ lsusb[/COLOR]
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 8087:0a2a Intel Corp.
Bus 001 Device 007: ID 04ca:0027 Lite-On Technology Corp.
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
[COLOR="#FF0000"]kurt@kurt-UP-APL01:~$ lsusb -v -d 04ca:0027[/COLOR]

Bus 001 Device 007: ID 04ca:0027 Lite-On Technology Corp.
Couldn't open device, some information will be missing
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               1.10
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0
  bDeviceProtocol         0
  bMaxPacketSize0         8
  idVendor           0x04ca Lite-On Technology Corp.
  idProduct          0x0027
  bcdDevice            1.18
  iManufacturer           1
  iProduct                2
  iSerial                 0
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           59
    bNumInterfaces          2
    bConfigurationValue     1
    iConfiguration          0
    bmAttributes         0xa0
      (Bus Powered)
      Remote Wakeup
    MaxPower              100mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      1 Boot Interface Subclass
      bInterfaceProtocol      1 Keyboard
      iInterface              0
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength      65
         Report Descriptors:
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x81  EP 1 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval              24
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        1
      bAlternateSetting       0
      bNumEndpoints           1
      bInterfaceClass         3 Human Interface Device
      bInterfaceSubClass      0 No Subclass
      bInterfaceProtocol      0 None
      iInterface              0
        HID Device Descriptor:
          bLength                 9
          bDescriptorType        33
          bcdHID               1.10
          bCountryCode            0 Not supported
          bNumDescriptors         1
          bDescriptorType        34 Report
          wDescriptorLength     159
         Report Descriptors:
           ** UNAVAILABLE **
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0008  1x 8 bytes
        bInterval              10
[COLOR="#FF0000"]kurt@kurt-UP-APL01:~$ sudo usbhid-dump  -i0 | grep -v : | xxd -r -p | hidrd-convert -o spec[/COLOR]
[sudo] password for kurt:
Usage Page (Desktop),               ; Generic desktop controls (01h)
Usage (Keyboard),                   ; Keyboard (06h, application collection)
Collection (Application),
    Usage Page (Keyboard),          ; Keyboard/keypad (07h)
    Usage Minimum (KB Leftcontrol), ; Keyboard left control (E0h, dynamic value)
    Usage Maximum (KB Right GUI),   ; Keyboard right GUI (E7h, dynamic value)
    Logical Minimum (0),
    Logical Maximum (1),
    Report Count (8),
    Report Size (1),
    Input (Variable),
    Report Count (8),
    Report Size (1),
    Input (Constant),
    Usage Page (LED),               ; LEDs (08h)
    Usage Minimum (01h),
    Usage Maximum (03h),
    Report Count (3),
    Report Size (1),
    Output (Variable),
    Report Count (1),
    Report Size (5),
    Output (Constant),
    Usage Page (Keyboard),          ; Keyboard/keypad (07h)
    Usage Minimum (None),           ; No event (00h, selector)
    Usage Maximum (FFh),
    Logical Minimum (0),
    Logical Maximum (255),
    Report Count (6),
    Report Size (8),
    Input,
End Collection
[COLOR="#FF0000"]kurt@kurt-UP-APL01:~$ sudo usbhid-dump  -i1 | grep -v : | xxd -r -p | hidrd-convert -o spec[/COLOR]
Usage Page (Desktop),                   ; Generic desktop controls (01h)
Usage (Sys Control),                    ; System control (80h, application collection)
Collection (Application),
    Report ID (1),
    Usage Page (Desktop),               ; Generic desktop controls (01h)
    Usage Minimum (Sys Power Down),     ; System power down (81h, one-shot control)
    Usage Maximum (Sys Menu Exit),      ; System menu exit (88h, one-shot control)
    Logical Minimum (0),
    Logical Maximum (1),
    Report Count (8),
    Report Size (1),
    Input (Variable),
End Collection,
Usage Page (Consumer),                  ; Consumer (0Ch)
Usage (Consumer Control),               ; Consumer control (01h, application collection)
Collection (Application),
    Report ID (2),
    Logical Minimum (0),
    Logical Maximum (1),
    Usage (AL Consumer Control Config), ; AL consumer control configuration (0183h, selector)
    Usage (Play Pause),                 ; Play/pause (CDh, one-shot control)
    Usage (Stop),                       ; Stop (B7h, one-shot control)
    Usage (Volume Inc),                 ; Volume increment (E9h, re-trigger control)
    Usage (Volume Dec),                 ; Volume decrement (EAh, re-trigger control)
    Usage (Mute),                       ; Mute (E2h, on/off control)
    Usage (Scan Previous Track),        ; Scan previous track (B6h, one-shot control)
    Usage (Scan Next Track),            ; Scan next track (B5h, one-shot control)
    Usage (AL Email Reader),            ; AL email reader (018Ah, selector)
    Usage (AL Calculator),              ; AL calculator (0192h, selector)
    Usage (AL Local Machine Brwsr),     ; AL local machine browser (0194h, selector)
    Usage (AC Search),                  ; AC search (0221h, selector)
    Usage (AC Home),                    ; AC home (0223h, selector)
    Usage (AC Back),                    ; AC back (0224h, selector)
    Usage (AC Forward),                 ; AC forward (0225h, selector)
    Usage (AC Stop),                    ; AC stop (0226h, selector)
    Usage (AC Refresh),                 ; AC refresh (0227h, selector)
    Usage (AC Bookmarks),               ; AC bookmarks (022Ah, selector)
    Report Count (18),
    Report Size (1),
    Input (Variable),
    Report Count (1),
    Report Size (6),
    Input (Constant),
End Collection,
Usage Page (Button),                    ; Button (09h)
Usage (01h),
Collection (Application),
    Report ID (3),
    Logical Minimum (0),
    Logical Maximum (1),
    Usage (2Ch),
    Usage (18h),
    Usage (20h),
    Usage (1Fh),
    Usage (1Ch),
    Usage (3Dh),
    Usage (41h),
    Usage (42h),
    Usage (43h),
    Usage (46h),
    Report Count (10),
    Report Size (1),
    Input (Variable),
    Report Count (1),
    Report Size (6),
    Input (Constant),
End Collection
kurt@kurt-UP-APL01:~$
Note: the usbhid-dump command, I needed to install a package for it. There is probably ways to do this on windows or MAC, but this is what I have tried, even though my main DEV machine is PC/Windows 10...
 
Status
Not open for further replies.
Back
Top