Hi,
First off, I don't like the EHCI for various reasons, and my suggestion to you is to skip it and move on to one of the other controllers, but this is just my humble opinion.
Second, I have a few questions/comments:
1) You don't have a URL to any other code, so I am assuming the 'ehci_controller' structure is byte packed. yes?
2) While you initialize the 'next_link', to be safe, you should initialize the 'alt_link' as well:
Code:
async_qh->next_link = PTR_TERMINATE;
async_qh->alt_link = 0; //<------- should be PTR_TERMINATE
...and later...
Code:
periodic_qh->alt_link = 0;
...should be set the same. There were faulty EHCI controllers out there that wouldn't handle the NULL pointer well.
3) There should be more than one queue in your Async list.
Code:
async_qh->qh_link_pointer = ((uint32_t)((uintptr_t)async_qh)) | PTR_QH;
Points back to itself. This is valid, but usually not normal. It is normal to have multiple (at least 2) queues in your Async list. A Queue is 48 bytes and must be 32-byte aligned. Does 'ehci_alloc_queue_header()' return a 32-byte aligned memory location?
4) Does 'ehci_alloc_queue_header()' return a 4k aligned address? The Periodical List must be 4k aligned.
5) With...
Code:
/* Wait for halt */
while (ROR(USB_STS) & STS_HCHALTED);
...Maybe change to
Code:
/* After setting the Run but, wait for halt bit to clear, indicating we actually started */
while (ROR(USB_STS) & STS_HCHALTED);
...just so your comment doesn't throw off your thinking. Also, have you taken steps to make sure the while() loop is not optimized out?
6) Do you have a bootable image file you can share?
Ben
-
https://www.fysnet.net/the_universal_serial_bus.htm