Hi -
My USB host is k20d72 and MQX3.8 based board while my USB device is powered by k20d50 and MQX4.1. The communication over USB is HID class based. The enumeration is done by soft-attach via applying power to Vbus each time when the communication is needed.
Usually this way of mechanism is working fine except for enumeration failure with rate like one out of a thousand enumerations. Although it can be worked around by a re-try by powering cycling Vbus but I want to dig into it a bit.
With help by a data logger, I can see that when failure happens, USB device is already powered up but doesn't see USB_APP_ENUM_COMPLETE event even though there is one USB bus reset from host.
For some unusual cases, USB host does send out more than one USB bus resets to device to get enumeration done successfully.
My question is, what is the condition for RESET to be sent out more than once? Why for my failure cases, only one bus reset is sent out? Any other reason could prevent enumeration from going through?
thanks!
Hui
Solved! Go to Solution.
Hello Hui,
Reset condition is sent to device once an attach event is received.
Basically, attach event is detected by hardware and internally, the module sets the USBx_ISTAT[ATTACH] flag, in the USB stack, there is a task that polls for this event (_usb_khci_task), if this attach flag is set, then KHCI controller calls the _usb_khci_attach function (located at khci.c file), in this function, stack does perform the High speed detection handshake to detect device's speed, then, a BUS RESET is applied for 30 ms seconds:
// speed check, set
usb_host_ptr->G.SPEED = (uint8_t)((usb_ptr->CTL & USB_CTL_JSTATE_MASK) ? USB_SPEED_FULL : USB_SPEED_LOW);
if (usb_host_ptr->G.SPEED == USB_SPEED_FULL)
{
usb_ptr->ADDR &= ~USB_ADDR_LSEN_MASK;
}
usb_ptr->ISTAT = 0xff; // clean each int flags
usb_ptr->INTEN = \
USB_INTEN_TOKDNEEN_MASK |
USB_INTEN_USBRSTEN_MASK;
// bus reset
usb_ptr->CTL |= USB_CTL_RESET_MASK;
_time_delay(30); //wait for 30 milliseconds (2.5 is minimum for reset, 10 recommended)
usb_ptr->CTL &= ~USB_CTL_RESET_MASK;
After that, enumeration process is taken place.
Here is an USB capture that shows this process and see that you only need to generate one USB RESET signal on device to enumerate it correctly. (I recommend you to use a USB Host stack newer than 3.8)
I hope this can help you!
Best Regards,
Isaac
Hello Hui,
Reset condition is sent to device once an attach event is received.
Basically, attach event is detected by hardware and internally, the module sets the USBx_ISTAT[ATTACH] flag, in the USB stack, there is a task that polls for this event (_usb_khci_task), if this attach flag is set, then KHCI controller calls the _usb_khci_attach function (located at khci.c file), in this function, stack does perform the High speed detection handshake to detect device's speed, then, a BUS RESET is applied for 30 ms seconds:
// speed check, set
usb_host_ptr->G.SPEED = (uint8_t)((usb_ptr->CTL & USB_CTL_JSTATE_MASK) ? USB_SPEED_FULL : USB_SPEED_LOW);
if (usb_host_ptr->G.SPEED == USB_SPEED_FULL)
{
usb_ptr->ADDR &= ~USB_ADDR_LSEN_MASK;
}
usb_ptr->ISTAT = 0xff; // clean each int flags
usb_ptr->INTEN = \
USB_INTEN_TOKDNEEN_MASK |
USB_INTEN_USBRSTEN_MASK;
// bus reset
usb_ptr->CTL |= USB_CTL_RESET_MASK;
_time_delay(30); //wait for 30 milliseconds (2.5 is minimum for reset, 10 recommended)
usb_ptr->CTL &= ~USB_CTL_RESET_MASK;
After that, enumeration process is taken place.
Here is an USB capture that shows this process and see that you only need to generate one USB RESET signal on device to enumerate it correctly. (I recommend you to use a USB Host stack newer than 3.8)
I hope this can help you!
Best Regards,
Isaac