Add RawHID to Keyboard, Mouse and Joystick device on Teensy 4.0

Status
Not open for further replies.

Slion

Member
I've been using this program for years on Teensy 3.2 using that USB_EVERYTHING configuration.
It receives packets over RawHID parses them and sends back corresponding keyboard inputs.
Source code is there: https://github.com/Slion/SharpLibMicroInput

Now I'm trying to port it to Teensy 4.0 which does not have that USB_EVERYTHING configuration out-of-the-box and it does not compile if you just enable it.
See: https://forum.pjrc.com/threads/66162-Using-multiple-USB-Types

So I was trying to create my own configuration but I must have done something wrong.
To start with once I flashed it I need to reset the board to be able to reprogram it. I guess it somehow breaks the Serial Emulation which I suppose is used to upload firmware.
Moreover my program kind of works sometimes but is also full of bugs with a mind of its own, like if the RawHID data it receives is being corrupted.

Here is my configuration. Can you spot anything wrong with it?

Code:
  #define VENDOR_ID		0x16C0
  #define PRODUCT_ID		0x0476
  #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'}
  #define PRODUCT_NAME_LEN	18
  #define EP0_SIZE		64
  #define NUM_ENDPOINTS         8
  #define NUM_USB_BUFFERS	      32
  #define NUM_INTERFACE		      6
  #define SEREMU_INTERFACE      0	// Serial emulation
  #define SEREMU_TX_ENDPOINT    2
  #define SEREMU_TX_SIZE        64
  #define SEREMU_TX_INTERVAL    1
  #define SEREMU_RX_ENDPOINT    2
  #define SEREMU_RX_SIZE        32
  #define SEREMU_RX_INTERVAL    2
  #define RAWHID_INTERFACE      1	// RawHID
  #define RAWHID_TX_ENDPOINT    3
  #define RAWHID_TX_SIZE        64
  #define RAWHID_TX_INTERVAL    1
  #define RAWHID_RX_ENDPOINT    4
  #define RAWHID_RX_SIZE        64
  #define RAWHID_RX_INTERVAL    1
  #define KEYBOARD_INTERFACE    2	// Keyboard
  #define KEYBOARD_ENDPOINT     5
  #define KEYBOARD_SIZE         8
  #define KEYBOARD_INTERVAL     1
  #define KEYMEDIA_INTERFACE    3	// Keyboard Media Keys
  #define KEYMEDIA_ENDPOINT     6
  #define KEYMEDIA_SIZE         8
  #define KEYMEDIA_INTERVAL     4
  #define MOUSE_INTERFACE       4	// Mouse
  #define MOUSE_ENDPOINT        7
  #define MOUSE_SIZE            8
  #define MOUSE_INTERVAL        1
  #define JOYSTICK_INTERFACE    5	// Joystick
  #define JOYSTICK_ENDPOINT     8
  #define JOYSTICK_SIZE         12	//  12 = normal, 64 = extreme joystick
  #define JOYSTICK_INTERVAL     2
  // Serial emulation endpoint RX and TX
  #define ENDPOINT2_CONFIG	ENDPOINT_RECEIVE_INTERRUPT + ENDPOINT_TRANSMIT_INTERRUPT
  // Raw HID endpoints:  
  #define ENDPOINT3_CONFIG	ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT // Transmit only  
  #define ENDPOINT4_CONFIG	ENDPOINT_RECEIVE_INTERRUPT + ENDPOINT_TRANSMIT_UNUSED // Receive only
  // Inputs
  #define ENDPOINT5_CONFIG	ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT
  #define ENDPOINT6_CONFIG	ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT
  #define ENDPOINT7_CONFIG	ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT
  #define ENDPOINT8_CONFIG	ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT
 
Trying to understand what's going on here.

Instead of adding a new USB type I proceeded by modifying the RawHID which works fine with my program BTW according to my serial logs, just without the keyboard part.
First I noticed just changing the PID of RawHID breaks Serial logs and prevents the board from being reflashed without a reset. Is that because of Windows caching somehow?

As soon as I add Keyboard, mouse, media and joystick, RawHID starts to be funny. Recv reads multiple times the only one packet that was sent for instance.
Sound like either bugs or limitation of the Teensy 4.0 implementation, or a misconfiguration of my USB type.

If I add just the keyboard it works fine so maybe the conflict is with mouse, media or joystick?
 
Did further testing to track down that issue.
It looks like RawHID can't operate properly together with Joystick.
My bet is that their Teensy 4.0 implementation is somehow using the same hardware resource causing conflicts and corruptions.

Later: Actually after changing the configuration again when adding the mouse it starts acting up. Windows is actually sowing two mice too...
 
Last edited:
Here is what I got so far:

Code:
  #define VENDOR_ID		0x2808
  #define PRODUCT_ID	0x0000
  #define BCD_DEVICE		0x0001
  #define RAWHID_USAGE_PAGE	0xFFAB  // recommended: 0xFF00 to 0xFFFF
  #define RAWHID_USAGE		0x0200  // recommended: 0x0100 to 0xFFFF
  #define MANUFACTURER_NAME	{'S','l','i','o','n','s'}
  #define MANUFACTURER_NAME_LEN	6
  #define PRODUCT_NAME		{'M','i','c','r','o','I','n','p','u','t'}
  #define PRODUCT_NAME_LEN	10
  #define EP0_SIZE		64
  #define NUM_ENDPOINTS         6
  #define NUM_INTERFACE         4	
  #define NUM_USB_BUFFERS	      24
  // RawHID	
  #define RAWHID_INTERFACE      0	
  #define RAWHID_TX_ENDPOINT    2
  #define RAWHID_TX_SIZE        64
  #define RAWHID_TX_INTERVAL    1	
  #define RAWHID_RX_ENDPOINT    3
  #define RAWHID_RX_SIZE        64
  #define RAWHID_RX_INTERVAL    1	 
  // Serial Emulation
  #define SEREMU_INTERFACE      1
  #define SEREMU_TX_ENDPOINT    4
  #define SEREMU_TX_SIZE        64
  #define SEREMU_TX_INTERVAL    1	 
  #define SEREMU_RX_ENDPOINT    4
  #define SEREMU_RX_SIZE        32
  #define SEREMU_RX_INTERVAL    2	 
  
  #define ENDPOINT2_CONFIG	ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT
  #define ENDPOINT3_CONFIG	ENDPOINT_RECEIVE_INTERRUPT + ENDPOINT_TRANSMIT_UNUSED
  #define ENDPOINT4_CONFIG	ENDPOINT_RECEIVE_INTERRUPT + ENDPOINT_TRANSMIT_INTERRUPT
  
// Keyboard
  #define KEYBOARD_INTERFACE    2	
  #define KEYBOARD_ENDPOINT     5
  #define KEYBOARD_SIZE         8
  #define KEYBOARD_INTERVAL     1
  // Keyboard Media Keys
  #define KEYMEDIA_INTERFACE    3	
  #define KEYMEDIA_ENDPOINT     6
  #define KEYMEDIA_SIZE         8
  #define KEYMEDIA_INTERVAL     4
  // Mouse
  /*
  #define MOUSE_INTERFACE       4	
  #define MOUSE_ENDPOINT        7
  #define MOUSE_SIZE            8
  #define MOUSE_INTERVAL        1
  */
  //SL: Joystick currently not working together with RawHID on Teensy 4.0
  /*
  #define JOYSTICK_INTERFACE    5	// Joystick
  #define JOYSTICK_ENDPOINT     7
  #define JOYSTICK_SIZE         12	//  12 = normal, 64 = extreme joystick
  #define JOYSTICK_INTERVAL     2
  */
  
  #define ENDPOINT5_CONFIG	ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT
  #define ENDPOINT6_CONFIG	ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT
 // #define ENDPOINT7_CONFIG	ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT
  //#define ENDPOINT8_CONFIG	ENDPOINT_RECEIVE_UNUSED + ENDPOINT_TRANSMIT_INTERRUPT

Adding a mouse from there causes two mice device to be detected by Windows and adding the Joystick breaks RawHID as explained above.
@PaulStoffregen Any advice on that?
 
Bin using 1.54.Beta12 maybe that's the problem, I doubt it though, it's also been released now.
 
Sorry, this is probably more of a question for Paul... I have not done that much at this USB end... I have done more at the USB Host end...

But one of the gotchas of the IMXRT USb hardware is: • Up to 8 bidirectional endpoints

This was from section 42.2.1

So I am guessing that we need the control end point... So not sure if that implies you can only define 7...

My guess is maybe...

My gut tells me, if Paul could have implemented the All of the Above... He probably would have. But again guessing
 
Status
Not open for further replies.
Back
Top