So, this isn't a bug report, as far as I can tell. I'm simply trying to get the USB CDC host function working on a custom RT1050 board, and having no luck in getting any sort of activity out of the EHCI host driver function. Hopefully someone might have some advice on what I might be doing wrong.
I have a custom RT1050 board (call it the "MCU") that pretty much works as intended, with QSPI boot flash (on the secondary pins, no less), several LPUART, LPSPI, and LPI2C ports, one eMMC device on an SDHC controller, battery-backed RTC, Ethernet, etc., all running under FreeRTOS. What I'm trying to get working is the USB host function, specifically to get a single CDC port working. We have another board (call it the "APU") based on a Kinetis K24 with a USB device function, and that board talks fine to a PC over USB. Under ideal circumstances, the MCU and APU are plugged into a common backplane, which connects their USB port pins together (DP to DP, DN to DN), allowing the MCU to be a USB host to the APU's USB device.
I'm using the MCU Config Tools to create the USB Host peripheral in the project. Here's the CIC setup:
The DIC is also the default setup. I did have to manually edit usb_host_app.h to change the EHCI instance from 0 to 1; I have a separate thread on that here. (I'm currently using SDK 2.7.0. and MCUX 11.1.0.) For what it's worth, I have all caching disabled, because of earlier difficulties encountered while developing Ethernet and SD/MMC code.
What's happening is... well, basically nothing is happening. I originally built up some code around the auto-generated code to do specifically what I want to do, but since that wasn't working, for test purposes I disabled my custom code and instead called directly into the auto-generated code with no modifications. So at startup I call BOARD_InitUsb (the peripheral group containing my USB host instance), which calls USB2_APUHost_init(), which calls USB_HostApplicationInit().
usb_status_t USB_HostApplicationInit(void)
{
usb_status_t status;
USB_HostClockInit();
status = USB_HostInit(USB_HOST_CONTROLLER_ID, &g_HostHandle, USB_HostEvent);
if (status != kStatus_USB_Success)
{
return status;
} else {
USB_HostInterface0CicVcomInit();
}
USB_HostIsrEnable();
return status;
}
I've verified that USB_HostInit() returns OK (and thus USB_HostInterface0CicVcomInit() is called). Later I create a FreeRTOS task that has this as its entry point:
extern "C"
void USB_HostTaskEntry(void * param) {
while (true)
USB_HostTasks();
}
USB_HostTasks() (in usb_host_app.c) is simply this:
void USB_HostTasks(void)
{
USB_HostTaskFn(g_HostHandle);
USB_HostInterface0CicVcomTask();
}
And I haven't modified USB_HostTaskFn() or USB_HostInterface0CicVcomTask(). My issue is that when I launch the task, and USB_HostTaskFn() gets here:
void USB_HostEhciTaskFunction(void *hostHandle)
{
usb_host_ehci_instance_t *ehciInstance;
uint32_t bitSet;
usb_device_handle deviceHandle;
if (hostHandle == NULL)
{
return;
}
ehciInstance = (usb_host_ehci_instance_t *)((usb_host_instance_t *)hostHandle)->controllerHandle;
if (OSA_EventWait(ehciInstance->taskEventHandle, 0xFF, 0, USB_OSA_WAIT_TIMEOUT, &bitSet) ==
KOSA_StatusSuccess) /* wait all event */
{
if (bitSet & EHCI_TASK_EVENT_PORT_CHANGE) /* port change */
{
USB_HostEhciPortChange(ehciInstance);
}
The call for OSA_EventWait() blocks forever. It never gets a single event. The USB2 OTG ISR also never fires. It's as if the USB peripheral is completely dead.
I've been able to run the "host_cdc_bm" example on the EVKB, and it does recognize the "APU" USB device, so the Kinetis on that board is doing what it's supposed to. I've compared the code between that example and my application, and I can't find any real differences between the two, either in initialization or operation. Now, what's not entirely helpful is that there is no "host_cdc_freertos" example, so I can't be sure if I'm supposed to be doing something different because I'm running in FreeRTOS instead of bare-metal.
Anyone have any ideas where I should start looking? (Probably my next experiment will be to try to get the "host_cdc_bm" example running directly on my target hardware. Not trivial, since my peripheral selections are different, and I'm running QSPI flash.)
David R.
已解决! 转到解答。
It seems that we're ultimately suffering some sort of physical layer issue; I removed the APU card from the backplane, tacked a USB-A female pigtail to test points on the backplane, then connected the APU card using a micro-B cable, and it enumerated using USB2 on the RT1050 host. Sorry for the false alarm. (But you should still fix the USB2 host issue in the SDK, and also provide a FreeRTOS version of the CDC host example.)
David R.
OK, brief update... I had a look at another USB host example, "host_hid_generic_freertos", and I observed that the USB Host and HID class functions were each given their own task, rather than being called consecutively as in the bare-metal example. So I implemented this in my own application, using USB1 (normally my device port) as the host port while connected to a free-standing APU board using a micro-B to micro-B cable. And that actually seems to work; I get this on the console:
CDC device attached:
pid=0x94vid=0x1fc9 address=1
CDC device attached
Get serial state value = 3
So, I'm not completely dead in the water. Now I need to figure out if I can make the same thing happen with USB2.
David R.
It seems that we're ultimately suffering some sort of physical layer issue; I removed the APU card from the backplane, tacked a USB-A female pigtail to test points on the backplane, then connected the APU card using a micro-B cable, and it enumerated using USB2 on the RT1050 host. Sorry for the false alarm. (But you should still fix the USB2 host issue in the SDK, and also provide a FreeRTOS version of the CDC host example.)
David R.