Teensy 3.6 USB Host - Multiple rawhid devices

Status
Not open for further replies.

yeahtuna

Well-known member
I've been working on a project for the past year. I'm using a Teensy 3.6 and I have a USB Hub and a rawHID device connnected to its USB Host port and everything works great. I was fully expecting to be able to connect multiple rawHID devices, but taking a closer look at the code, it seems it's only designed to support a single rawHID device.

I'm not asking 'how', I just really need to know 'if' it's possible to modify the Teensy Host code to support multiple rawHID devices? Thanks.

Regards,
Rob
 
Each rawhid object can only handle one connection at a time, but you should be able to have more than one of these...

Example the JoystickBT example has two:
Code:
RawHIDController rawhid1(myusb);
RawHIDController rawhid2(myusb, 0xffc90004);
The first one allows any... The second one is looking for specific. There may be holes in the code that maybe specific one is grabbed by generic one ... Been awhile since I played. But if you have several generic ones. When a new one connects it will walk the list of objects and see that the first one is taken and not take it, then ... finds one that is not active and claims it... Or should... Assuming I remember correctly
 
Each rawhid object can only handle one connection at a time, but you should be able to have more than one of these...

Example the JoystickBT example has two:
Code:
RawHIDController rawhid1(myusb);
RawHIDController rawhid2(myusb, 0xffc90004);
The first one allows any... The second one is looking for specific. There may be holes in the code that maybe specific one is grabbed by generic one ... Been awhile since I played. But if you have several generic ones. When a new one connects it will walk the list of objects and see that the first one is taken and not take it, then ... finds one that is not active and claims it... Or should... Assuming I remember correctly

Thanks KurtE. I tried 10 times yesterday and it just wouldn't work. I added some debuging code and tried again this morning, and it works. So strange. Thanks again.
 
I assume you also added some more of the HIDParsers?
USBHIDParser hid1(myusb);
USBHIDParser hid2(myusb);
USBHIDParser hid3(myusb);
USBHIDParser hid4(myusb);

These are the actual objects that talk to the connection, and understand HID, and then ask those objects that are derived from the class USBHIDInput
including RawHIDController.

Code:
class RawHIDController : public USBHIDInput {
 
This is how I'm setup.

Code:
USBHost myusb;
USBHub hub1(myusb);
MIDIDevice midi1(myusb);
MIDIDevice midi2(myusb);
MIDIDevice midi3(myusb);
MIDIDevice midi4(myusb);

USBHIDParser hid1(myusb);
USBHIDParser hid2(myusb);
USBHIDParser hid3(myusb);
USBHIDParser hid4(myusb);

RawHIDController rawHID1(myusb);
RawHIDController rawHID2(myusb);
RawHIDController rawHID3(myusb);
RawHIDController rawHID4(myusb);

RawHIDController* child[4];
MIDIDevice* midi[4];
USBHIDParser* USBInput[4];

I use the pointers to enumerate the connected devices, checking if the value pointed to is not zero before accessing. When I hook up multiple Teensy 3.2 devices this way, my code is rock solid and hotplugging works great. If I start trying to connect more than one Teensy 3.6 based device, the issues begin. I have to do more testing, but often the Teensy 3.6 that is acting as the host is hanging after the second Teensy 3.6 is added.

Could be power issues, could be hub issues, could almost anything. I'll keep testing. If I find anything important I'll share.
 
As best I can tell, the USB Host is hanging. Here is a function that I call periodically to maintain my list of connected devices.

Code:
bool childrenHaveChanged() {
	uint8_t connected = 0;

	uint8_t count = 0;

	for (int i = 0; i < NUM_CHILDREN; i++) {
		if (*child[i]) {
			count ++;
			connected |= (0x01 << i);

			childType[i] = makeDeviceID(USBInput[i]->idProduct(), child[i]->usage());
		}

	}

	if (connected != childrenConnected) {
		if (count > 0) led.setFlashCount(count); else led.setFlashCount(5);
		childrenConnected = connected;
		return true;
	}

	return false;
}

Whenever I plug or unplug a device, I get feedback from the my LED. After some random number of plugs and unplugs, the LED just stops responding, which indicates to me that the bool value of those RawHIDControllers is no longer being updated.

Any ideas what I might do to investigate further?
 
As a further note, I can hotplug my Teensy 3.2 based devices all day long and the Host Port never misses a beat. It's just the teensy 3.6 based units that are causing the issue.
 
It seems to only be an issue when using a hub. If I plug a single T3.6 based device into the host port, I can hotplug it all day long without issue.
 
So increasing the the HUB debounce time has made a huge improvement. I can now hotplug two T3.6 devices without issue. Adding a third often crashes the Host Post (or the hub?).

Code:
void USBHub::start_debounce_timer(uint32_t port)
{
	if (debounce_in_use == 0) debouncetimer.start(200000);
	debounce_in_use |= (1 << port);
}
 
Which hub? Maybe an issue, of some hubs are actually multiple hubs so maybe add another hub object.

Also maybe add a few more HID Parser objects. Some Teensy setups may have more than one HID object and will try to grab more than one HIDParser object (Like mouse, keyboard, RawHID, ...)

Not sure what else yet.
 
The devices I'm plugging in only have a single rawhid interface. The 4 port hub is at least 10 years old. I'll pickup another tomorrow and test for good measure.
 
So I think I've narrowed down the problem somewhat.

Let me give more information about the "child" devices I'm connecting. They are T3.6 composite MIDI / rawHID devices.

If I have a single "child" connected to the hub which is plugged into the Host Port (both the 10 year old hub and the one I bought today), when removing that single "child" from the Hub, the USB host crashes about 70% of the time.

If I have 2 or more "children" plugged into the hub, I can hotplug one of them and the host is stable.

If I have one "child" plugged into the hub and I disconnect the hub, the host is stable.

The crash seems to be occurring when the hub has no more children.

Rob
 
I seem to have resolved all the issues. Here's my updated code for detecting hot plugging of devices. You'll notice that I'm always checking if the hub, rawHID, and USBInput are all valid.

Code:
bool childrenHaveChanged() {

	uint8_t connectedState = 0;
	uint8_t count = 0;

	if (!usingHub && hub1) {
		usingHub = true;
	}

	if (usingHub && !hub1) {
		usingHub = false;
	}


	for (int i = 0; i < NUM_CHILDREN; i++) {
		if (usingHub == hub1 && *USBInput[i] && *child[i]) {
			count ++;
			connectedState |= (0x01 << i);

			childType[i] = makeDeviceID(USBInput[i]->idProduct(), child[i]->usage());

			// IF THE HOST IS ALREADY CONENCT, BUT THIS CHILD WASN'T ALREADY CONENCTED, SEND IT THE CONNECT COMMAND
			if (connected) {
				if ((childrenConnected & (0x01 << i)) != (connectedState & (0x01 << i))) {
					dsptParam p;
					p.appID = 255;
					p.param = kConnect;
					p.value = 1;
					sentPacketToChild(i, (uint8_t*)&p);

					putChildInStandby(i);
					
				}
			}
		}

	}

	if (connectedState != childrenConnected) {
		if (count > 0) led.setFlashCount(count); else led.setFlashCount(5);
		childrenConnected = connectedState;
		return true;
	}

	return false;
}

And here's my code for sending packets to a child.

Code:
void sentPacketToChild(uint8_t childIndex, uint8_t* data) {
	if (usingHub == hub1 && *child[childIndex] && *USBInput[childIndex]) child[childIndex]->sendPacket(data);
}
 
I believe we do have some long-standing bugs in the timer code. Maybe those are playing a role in this problem? Very difficult to know.

Any chance you could try to create a small host and small rawhid example and give the exact model of hub, so I can try to set it up here?
 
Thanks for chiming in, Paul. I'll put something together for you next week--it'll also allow me to confirm that the issue is not related to my many thousands of lines of code for this project. I don't the exact hub is relevant; I used two different 4-port hubs that were created in different decades are the problem is experienced by both.
 
Status
Not open for further replies.
Back
Top