New USB Type, RAW HID Without Serial Emulation

Status
Not open for further replies.

jerwood

Member
I've been trying to use RAW HID on the Teensy 3.2 with some existing code, and ran into problems with having two HID interfaces in the RAW HID configuration. My tools didn't know what to make of it.

So I made a variant of RAW HID without serial emulation.

In usb_desc.h, I created a new interface definition:

Code:
#elif defined(USB_RAWHID_NOSERIAL)
  #define VENDOR_ID		0x16C0
  #define PRODUCT_ID		0x0486	// Not unique!
  #define RAWHID_USAGE_PAGE	0xFFAB  // recommended: 0xFF00 to 0xFFFF
  #define RAWHID_USAGE		0x0200  // recommended: 0x0100 to 0xFFFF
  #define MANUFACTURER_NAME	{'T','e','e','n','s','y','d','u','i','n','o'}
  #define MANUFACTURER_NAME_LEN	11
  #define PRODUCT_NAME		{'T','e','e','n','s','y','d','u','i','n','o',' ','R','a','w','H','I','D',' ','N','o',' ','S','e','r','i','a','l'}
  #define PRODUCT_NAME_LEN	28
  #define EP0_SIZE		64
  #define NUM_ENDPOINTS         2
  #define NUM_USB_BUFFERS	12
  #define NUM_INTERFACE		1
  #define RAWHID_INTERFACE      0	// RawHID
  #define RAWHID_TX_ENDPOINT    1
  #define RAWHID_TX_SIZE        64
  #define RAWHID_TX_INTERVAL    1
  #define RAWHID_RX_ENDPOINT    2
  #define RAWHID_RX_SIZE        64
  #define RAWHID_RX_INTERVAL    1
  #define RAWHID_DESC_OFFSET    (9 + 9) 
  #define ENDPOINT1_CONFIG	ENDPOINT_TRANSIMIT_ONLY
  #define ENDPOINT2_CONFIG	ENDPOINT_RECEIVE_ONLY

In usb_raw.h I added RAWHID_INTERFACE_NOSERIAL to the #ifdefined guard:

Code:
#if defined(RAWHID_INTERFACE) [B]|| defined(RAWHID_INTERFACE_NOSERIAL)[/B]

I added my variant to boards.txt:

Code:
teensy31.menu.usb.rawhidnoserial=Raw HID No Serial
teensy31.menu.usb.rawhidnoserial.build.usbtype=USB_RAWHID_NOSERIAL

I added this to usb_inst.cpp:

Code:
#ifdef RAWHID_INTERFACE_NOSERIAL
usb_rawhid_class RawHID;
#endif

Finally, I found that I needed to modify yield.cpp to avoid trying to use the uninstantiated Serial instance. I wrapped the call to Serial in a SEREMU_INTERFACE #ifdef.

Code:
	[B]#if defined (SEREMU_INTERFACE)[/B]
	if (Serial.available()) serialEvent();
	[B]#endif[/B]

This works, and now my older tools that expect a single HID endpoint work again.
 
I've been trying to use RAW HID on the Teensy 3.2 with some existing code, and ran into problems with having two HID interfaces in the RAW HID configuration. My tools didn't know what to make of it.

So I made a variant of RAW HID without serial emulation.

In usb_desc.h, I created a new interface definition:

Code:
#elif defined(USB_RAWHID_NOSERIAL)
  #define VENDOR_ID		0x16C0
  #define PRODUCT_ID		0x0486	// Not unique!
  #define RAWHID_USAGE_PAGE	0xFFAB  // recommended: 0xFF00 to 0xFFFF
  #define RAWHID_USAGE		0x0200  // recommended: 0x0100 to 0xFFFF
  #define MANUFACTURER_NAME	{'T','e','e','n','s','y','d','u','i','n','o'}
  #define MANUFACTURER_NAME_LEN	11
  #define PRODUCT_NAME		{'T','e','e','n','s','y','d','u','i','n','o',' ','R','a','w','H','I','D',' ','N','o',' ','S','e','r','i','a','l'}
  #define PRODUCT_NAME_LEN	28
  #define EP0_SIZE		64
  #define NUM_ENDPOINTS         2
  #define NUM_USB_BUFFERS	12
  #define NUM_INTERFACE		1
  #define RAWHID_INTERFACE      0	// RawHID
  #define RAWHID_TX_ENDPOINT    1
  #define RAWHID_TX_SIZE        64
  #define RAWHID_TX_INTERVAL    1
  #define RAWHID_RX_ENDPOINT    2
  #define RAWHID_RX_SIZE        64
  #define RAWHID_RX_INTERVAL    1
  #define RAWHID_DESC_OFFSET    (9 + 9) 
  #define ENDPOINT1_CONFIG	ENDPOINT_TRANSIMIT_ONLY
  #define ENDPOINT2_CONFIG	ENDPOINT_RECEIVE_ONLY

In usb_raw.h I added RAWHID_INTERFACE_NOSERIAL to the #ifdefined guard:

Code:
#if defined(RAWHID_INTERFACE) [B]|| defined(RAWHID_INTERFACE_NOSERIAL)[/B]

i'm not an expert in defining USB instances, but I am wondering if the following line is correct

Code:
  #define RAWHID_RX_ENDPOINT    2
should it not also read
Code:
  #define RAWHID_RX_ENDPOINT    1
?
 
WMXZ - reading the structure and taking it literally ... it looks like there are two?

Code:
  #define RAWHID_TX_ENDPOINT    1
...
  #define RAWHID_RX_ENDPOINT    2
...
  #define ENDPOINT1_CONFIG	ENDPOINT_TRANSIMIT_ONLY
  #define ENDPOINT2_CONFIG	ENDPOINT_RECEIVE_ONLY
 
WMXZ - reading the structure and taking it literally ... it looks like there are two?

Code:
  #define RAWHID_TX_ENDPOINT    1
...
  #define RAWHID_RX_ENDPOINT    2
...
  #define ENDPOINT1_CONFIG	ENDPOINT_TRANSIMIT_ONLY
  #define ENDPOINT2_CONFIG	ENDPOINT_RECEIVE_ONLY

after rewriting this reply 3 times, now I understand (the number is NOT a count but the index of the endpoint)
(learned something, even before breakfast)
 
Breakfast - why would you eat breakfast at bedtime :)

Good to learn something - whatever the time of day/night! Where did you learn that? I've only seen one of these descriptors - and it is the one in OP. So there is a _NUM of two indexed endpoints Index 1 is TX and index 2 is RX. They each have a unique buffer space to which the HID message refers? That is what I inferred from my literal reading.
 
Where did you learn that? I've only seen one of these descriptors - and it is the one in OP. So there is a _NUM of two indexed endpoints Index 1 is TX and index 2 is RX. They each have a unique buffer space to which the HID message refers? That is what I inferred from my literal reading.
Well, the problem with cognitive processing is that you only see what you expect to see (high-speed model-based processing).
To answer your question, I compared the OP with the original raw_hid+seremu descriptor which was initially more confusing, as this did not match my expectation. So, it took me a while to get the message you where trying to convey.
 
I based my configuration on the original RAWHID setup, I'm not sure what's correct. I do think that Tx and Rx need their own endpoints, but that's an educated guess. So far it seems to work.
 
Well, the problem with cognitive processing is that you only see what you expect to see ...

Makes sense - and makes sense why I felt the need to follow up - I wasn't sure if I connected something - or missed something. Looking at code can be fun - when you see what you expected.

cognitive processing > my wife borrowed an Amazon ECHO from work - I told 'Alexa" my cat's name and "she" didn't see it as a question - later I asked her the cat's name and she acted like it wasn't a valid question. Seems like that would be a good programmed interaction.

It has this multi LED light ring on top that is BLUE during "inquisition" and CYAN in the direction the mic's picked up the sound - my "cognitive processing" thought that was 'funny'. I said "you're funny" . . . she said "I hope funny in a good way".
 
You can actually use the same endpoint for transmit and receive. If you do, you also must define the endpoint config as ENDPOINT_TRANSMIT_AND_RECEIVE.
 
Jerwood,

Are you using c# as the Windows interface to your rawhid project? I am having a fit trying to mate my rawhid teensy to a xaml application...
 
I'm writing my host application in Xojo (with a third party HID plug-in) for Mac and Windows. Sorry, I don't have any experience trying to get it to work with anything else.
 
Status
Not open for further replies.
Back
Top