USB HID issue when connected through hub and exposed to EMI

Chris_

New member
Hi all,

We are developing a product using Teensy 4.1 as main CPU and PlatformIO with Arduino framework. One of our requirements is to connect two custom USB HID devices (keypads). As we designed our own board, we decided to choose USB2422 chip as hub and placed it on our board. We use latest USBHost_t36 library. Those keypads are custom HID devices, we had to base our code on HIDDumpController example.

The whole setup worked fine until we started to do electromagnetic compatibility testing. When testing against radiated susceptibility, Teensy started to reboot randomly. We checked the flags, and watchdog was the reason. Adding more protection against EMI (cable shielding, data lines filtering etc.) reduced the probability of reboots, but was still happening.

We have ruled out hardware problems and have spotted that the USB Host stack (particularly hub support) enters some weird states. We enabled debugging of USB Host and we see different failure behaviours listed below.

1. No reaction at all, i.e. the USBHost doesn't print anything and the keypads stop operating. Sometimes reconnection of the hub helps to put the device back to normal operation.

2. USB Host enters followup_Error() and sometimes it crashes in there. We found another post here on forum (https://forum.pjrc.com/index.php?th...ost-with-two-ultrastik-360s.74789/post-341548) with fix related to NULL pointer dereferencing in that function. It seems that it at least helped in random reboots caused by faulty code.

3. Infinite loop of debug output, with the keypads not operating. Two different logs attached:
Code:
power turned on to all ports
device addr = 7
new_Pipe
allocate_interrupt_pipe_bandwidth
  ep interval = 12
  interval = 256
 best_bandwidth = 2, at offset = 0
pipe cap1 = F0012107
HUB Callback (member)
status = 12
getstatus, port = 1
deferred getstatus, port = 4
USBHub control callback
01 01 01 00
New Port Status
  status=10101  port=1
  state=0
  Device is present:
  Has Power
USBHub control callback
Port Status Cleared, port=1
getstatus, port = 4
USBHub control callback
01 01 01 00
New Port Status
  status=10101  port=4
  state=0
  Device is present:
  Has Power
USBHub control callback
Port Status Cleared, port=4
timer event (20000 us): Debounce Timer, this = 200152C0, timer = 200155D8
ports in use bitmask = 12
getstatus, port = 1
deferred getstatus, port = 4
USBHub control callback
01 01 00 00
New Port Status
  status=101  port=1
  state=2
  Device is present:
  Has Power
getstatus, port = 4
timer event (19999 us): Debounce Timer, this = 200152C0, timer = 200155D8
ports in use bitmask = 12
deferred getstatus, port = 1
deferred getstatus, port = 4
timer event (19999 us): Debounce Timer, this = 200152C0, timer = 200155D8
ports in use bitmask = 12
deferred getstatus, port = 1
deferred getstatus, port = 4
timer event (19999 us): Debounce Timer, this = 200152C0, timer = 200155D8
ports in use bitmask = 12
deferred getstatus, port = 1
deferred getstatus, port = 4
timer event (19999 us): Debounce Timer, this = 200152C0, timer = 200155D8
ports in use bitmask = 12
deferred getstatus, port = 1
deferred getstatus, port = 4
timer event (19999 us): Debounce Timer, this = 200152C0, timer = 200155D8
ports in use bitmask = 12
deferred getstatus, port = 1
deferred getstatus, port = 4
...

Code:
...
timer event (19999 us): Debounce Timer, this = 200152C0, timer = 200155D8
ports in use bitmask = 12
getstatus, port = 1
deferred getstatus, port = 4
USBHub control callback
01 01 00 00
New Port Status
  status=101  port=1
  state=6
  Device is present:
  Has Power
getstatus, port = 4
USBHub control callback
01 01 00 00
New Port Status
  status=101  port=4
  state=6
  Device is present:
  Has Power
timer event (19999 us): Debounce Timer, this = 200152C0, timer = 200155D8
ports in use bitmask = 12
getstatus, port = 1
deferred getstatus, port = 4
USBHub control callback
01 01 00 00
New Port Status
  status=101  port=1
  state=6
  Device is present:
  Has Power
getstatus, port = 4
...


Some other conclusions:
1. The keypad works fine when connected directly to Teensy. When exposed to RF field, the keypad stops operating for short period of time and works again. That's acceptable.
2. We tried different off-the-shelf hubs, every one had problems of some sort when exposed to RF field.
3. The same keypads connected to PC through hub worked fine when exposed to RF field. It stoped operating for short period of time and worked again.
4. The keypad is a custom design based on RP2040 microcontroller. Maybe that's a clue? As the keypads are made by a different company, we don't have access to the code right now nor we can't assume that it is 100% compliant with USB spec. What we think anyways is that the USB Host should be immune against non-compliant device. It is another story to improve that keypad.

Sorry for this way too long thread, but I hope you'll at least have some ideas what might be the reason. We might also try connecting JTAG probe to Teensy, but it takes some hacks on the PCB. That's a feature that we miss the most.
 
USB and EMI are not good friends. You should use good shielded cables, filters on data, GND and 5V lines.
Good pcb design also helps, using internal layers for USB signal routing.

At the end, it is still possible the USB peripheral in the Teensy microcontroller is not very good at handling EMI on datalines. With no software handling possible.
That's the case on PC. Most of the EMI tests I made, the device was still working good, but the USB host controllers stopped working. Sometimes unplugging/replugging the device re-initialised the host, but sometimes a power off of the PC was needed.
 
I second that, most USB stuff _including cables_ are awful (most hubs fail EMI compliance). USB cables really need large ferrites on each end and excellent braid-coverage. (this used to be pretty standard back in the early days of USB).
 
Back
Top