Why USB keeps attach/reset/detach in _usb_khci_task()?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Why USB keeps attach/reset/detach in _usb_khci_task()?

Jump to solution
2,054 Views
kai_liu
Senior Contributor I

I have tried HID (mouse/keyboard+mouse) demos on FRDM-KL25Z with hyper terminal. It works in most cases with some exceptions.

If I plug K/B and run HID project, it keeps on attach/reset/detach in khci_kinetis.c::_usb_khci_task(). And it will not goes to usb_host_hid_keyboard_event().

Even I run HID project before connecting K/B, it runs to usb_host_hid_keyboard_event(), only after quite a long attach/reset/detach loops. The time is at least longer than a normal debounce time of connecting USB device.

Here is a complete debug log to show that case.

USB HID Keyboard + Mouse
Waiting for USB Keyboard or mouse to be attached...
events:01
khci_event:01,event_attach
khci_event:02,event_reset
khci_event:10,event_detach
events:01
khci_event:01,event_attach
khci_event:02,event_reset
khci_event:10,event_detach
events:01
khci_event:01,event_attach
khci_event:02,event_reset
khci_event:10,event_detach
events:01
khci_event:01,event_attach
khci_event:02,event_reset
khci_event:10,event_detach
events:01
khci_event:01,event_attach
khci_event:02,event_reset
khci_event:10,event_detach
events:01
khci_event:01,event_attach
khci_event:02,event_reset
khci_event:10,event_detach
events:01
khci_event:01,event_attach
khci_event:02,event_reset
khci_event:10,event_detach
events:01
khci_event:01,event_attach
khci_event:02,event_reset
khci_event:10,event_detach
events:01
khci_event:01,event_attach
khci_event:02,event_reset
khci_event:10,event_detach
events:01
khci_event:01,event_attach
khci_event:02,event_reset
khci_event:10,event_detach
events:01
khci_event:01,event_attach
khci_event:02,event_reset
khci_event:10,event_detach
events:01
khci_event:01,event_attach
khci_event:02,event_reset
----- Attach Event -----
State = 0  Class = 3  SubClass = 1  Protocol = 1
----- Interfaced Event -----
Keyboard device interfaced, setting protocol...
Keyboard device ready, try to press the keyboard
abcdeffghijklmnopqrstuvwxyz

The khci_event value is set in USB_ISR_HOST() by calling _usb_event_set(). But I don't understand why there are so many KHCI_EVENT_RESET event? And what is different between executing order of connection USB devices and running code?

Tags (1)
0 Kudos
1 Solution
832 Views
kai_liu
Senior Contributor I

It seems that we need an small delay in _usb_khci_reset(). Please verify it on your platform and give me your testing results. Here is the whole story.

Project: Freescale USB v4.0.3 USB HID Keyboard mouse

Platform: Kinetis L2K,

CC: EWARM

Hardware: FRDM with add-on USB host port.

In driver\khci_kinetis.c, there is one USB ISR:

    USB_ISR_HOST()

        USB_ISTAT_ATTACH_MASK

            USB_INTEN_ATTACHEN_MASK (disabled), only enabled by _usb_khci_init() and _usb_khci_detach()

        USB_ISTAT_TOKDNE_MASK

        USB_ISTAT_USBRST_MASK

There is one main loop in khci driver layer

    _usb_khci_task()

        _usb_khci_attach(),

            clear all pending interrupts in USB0_ISTAT,

            reset bus,

            delay,

            enable USB_ISTAT_TOKDNE_MASK + USB_ISTAT_USBRST_MASK

            usb_dev_list_attach_device()

        _usb_khci_reset()

            clear USB_ISTAT_ATTACH_MASK in USB0_ISTAT

            if USB_ISTAT_ATTACH_MASK again

                USB0_ADDR = 0, USB0_ENDPT0 ...

            else

                goes to detach

        _usb_khci_detach()

            Disable bus control

            Clear pending interrupts

            Enable USB_ISTAT_ATTACH_MASK

You will find USB_ISTAT_ATTACH_MASK is only enabled in _usb_khci_init() and _usb_khci_detach(), and checked in _usb_khci_reset().

If _usb_khci_reset() clears USB_ISTAT_ATTACH_MASK then check it again. The MCU runs too fast to get another ATTACH interrupt, so I put a time_delay(1) here.

Now, it only requires 1 bus reset operation before enumeration. Not only HID projects, my ADB project goes well too.

I would like to suggest to add such statement into future FSL USB stack, if FSL FAE verifies it.

View solution in original post

0 Kudos
5 Replies
833 Views
kai_liu
Senior Contributor I

It seems that we need an small delay in _usb_khci_reset(). Please verify it on your platform and give me your testing results. Here is the whole story.

Project: Freescale USB v4.0.3 USB HID Keyboard mouse

Platform: Kinetis L2K,

CC: EWARM

Hardware: FRDM with add-on USB host port.

In driver\khci_kinetis.c, there is one USB ISR:

    USB_ISR_HOST()

        USB_ISTAT_ATTACH_MASK

            USB_INTEN_ATTACHEN_MASK (disabled), only enabled by _usb_khci_init() and _usb_khci_detach()

        USB_ISTAT_TOKDNE_MASK

        USB_ISTAT_USBRST_MASK

There is one main loop in khci driver layer

    _usb_khci_task()

        _usb_khci_attach(),

            clear all pending interrupts in USB0_ISTAT,

            reset bus,

            delay,

            enable USB_ISTAT_TOKDNE_MASK + USB_ISTAT_USBRST_MASK

            usb_dev_list_attach_device()

        _usb_khci_reset()

            clear USB_ISTAT_ATTACH_MASK in USB0_ISTAT

            if USB_ISTAT_ATTACH_MASK again

                USB0_ADDR = 0, USB0_ENDPT0 ...

            else

                goes to detach

        _usb_khci_detach()

            Disable bus control

            Clear pending interrupts

            Enable USB_ISTAT_ATTACH_MASK

You will find USB_ISTAT_ATTACH_MASK is only enabled in _usb_khci_init() and _usb_khci_detach(), and checked in _usb_khci_reset().

If _usb_khci_reset() clears USB_ISTAT_ATTACH_MASK then check it again. The MCU runs too fast to get another ATTACH interrupt, so I put a time_delay(1) here.

Now, it only requires 1 bus reset operation before enumeration. Not only HID projects, my ADB project goes well too.

I would like to suggest to add such statement into future FSL USB stack, if FSL FAE verifies it.

0 Kudos
832 Views
kai_liu
Senior Contributor I

It seems USB bus reset is generated by host stack on purpose.

_usb_khci_task() is called by POLL()

_usb_khci_attach() when attach event occurs,

USB0_CTL |= USB_CTRL_RESET_MASK;
time_delay(30);
USB0_CTL &= ~ USB_CTRL_RESET_MASK;

That is why the USB0 detects a bus reset events after _usb_khci_attach().

However, I can not figure out why we must generate USB BUS RESET many times. And on what exit conditions, we can go on for enumeration process? I checked many times, the ATTACH/RESET/DETACH process times are not constant. Sometimes it takes two, sometimes it takes more than 16 and goes to idle.

0 Kudos
832 Views
bobpaddock
Senior Contributor III

"I have tried HID (mouse/keyboard+mouse) demos on FRDM-KL25Z with hyper terminal."

Read this link on the enumeration process: Jan Axelson's Lakeview Research

On WIndows there will always be two resets, this gets many people when they design their first USB device.

" I checked VBUS for FRDM USB host, which is 4.92V, it is enough as VBUS."

As to more than two, I'd replace the USB cable from the host to the board, preferably with a short one.

I've experienced cables that had too high of a resistance and would not support a dynamic load.

The typical voltmeter does not respond to the current spikes generated during device startup and enumeration, so the voltage may look good on your meter.  Use a True RMS rated meter or a good O'scope.

Also try your device on a different port on your PC.  I've run into cases, non-Freescale, where devices worked with Intel hub controllers but failed with NEC hub controllers on the motherboard of the same PC.

832 Views
kai_liu
Senior Contributor I

Thanks Bob.

I am sorry I didn't express myself clearly. Actually I am developing a USB host for HID devices. The BUS RESET is generated by KL25Z to MICE/KB. Now I know BUS RESET seems an action on purpose. However I have no idea how many RESET events are accepatable in practical design?

For cable and PC and power supply, I will try other combinations. Thanks for advice.

0 Kudos
832 Views
kai_liu
Senior Contributor I

Actually, USB bus reset should be generated by USB host, and it is a USB host application. I don't know which function makes a bus reset. and Why? I checked VBUS for FRDM USB host, which is 4.92V, it is enough as VBUS.

Anyone knows?

0 Kudos