AnsweredAssumed Answered

SDK 2.6.1 on RT1050 - Incorrect EHCI instance for USB OTG2?

Question asked by David Rodgers on Dec 19, 2019
Latest reply on Jun 13, 2020 by David Rodgers

I'm trying to bring up a USB CDC host instance on an RT1050, specifically on USB2.  (I've verified port USB1 is functional for the serial downloader.)  I'm using SDK 2.6.1 on a custom board with an RT1052 (MIMXRT1052CVJ5B) and MCUX 11.0.1.

 

I'm using the middleware component of MCUX to generate the code for both the CDC device instance on USB1 (not tested yet) and the CDC host instance on USB2.  Here's my configuration screen for USB2:

Configuration for USB2 as CDC host

 

Pretty standard stuff.  I'm letting MCUX generate all the necessary source code, then I'm making copies of a couple of the generated files (usb_host_interface_0_cic.c and usb_host_app.c), customizing those, and removing the originals from the build configuration.

 

I don't have it working yet, and I'm still debugging that, but I think I've noticed one glaring oversight in the generated middleware code; I believe that usb_host_app.h is calling out the wrong EHCI instance.  Here's the source:

#ifndef __USB_HOST_APP_H__
#define __USB_HOST_APP_H__
#include "usb_host_config.h"
#include "usb_host.h"
#include "fsl_device_registers.h"

/*******************************************************************************
* Definitions
******************************************************************************/


#if ((defined USB_HOST_CONFIG_KHCI) && (USB_HOST_CONFIG_KHCI))
#define USB_HOST_CONTROLLER_ID kUSB_ControllerKhci0
#endif /* USB_HOST_CONFIG_KHCI */
#if ((defined USB_HOST_CONFIG_EHCI) && (USB_HOST_CONFIG_EHCI))
#define USB_HOST_CONTROLLER_ID kUSB_ControllerEhci0
#endif /* USB_HOST_CONFIG_EHCI */
#if ((defined USB_HOST_CONFIG_OHCI) && (USB_HOST_CONFIG_OHCI))
#define USB_HOST_CONTROLLER_ID kUSB_ControllerOhci0
#endif /* USB_HOST_CONFIG_OHCI */
#if ((defined USB_HOST_CONFIG_IP3516HS) && (USB_HOST_CONFIG_IP3516HS))
#define USB_HOST_CONTROLLER_ID kUSB_ControllerIp3516Hs0
#endif /* USB_HOST_CONFIG_IP3516HS */

 

And here's relevant bits of source from usb_host_app.c, condensed:

void USB_OTG2_IRQHandler(void) {
USB_HostEhciIsrFunction(g_HostHandle);
}

void USB_HostClockInit(void) {
usb_phy_config_struct_t phyConfig = {
BOARD_USB_PHY_D_CAL, BOARD_USB_PHY_TXCAL45DP, BOARD_USB_PHY_TXCAL45DM, };
uint32_t notUsed = 0;

if (USB_HOST_CONTROLLER_ID == kUSB_ControllerEhci0) {
CLOCK_EnableUsbhs0PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
CLOCK_EnableUsbhs0Clock(kCLOCK_Usb480M, 480000000U);
} else {
CLOCK_EnableUsbhs1PhyPllClock(kCLOCK_Usbphy480M, 480000000U);
CLOCK_EnableUsbhs1Clock(kCLOCK_Usb480M, 480000000U);
}

USB_EhciPhyInit(USB_HOST_CONTROLLER_ID, notUsed, &phyConfig);
}

void USB_HostIsrEnable(void) {
uint8_t irqNumber;
IRQn_Type usbHOSTEhciIrq[] = USBHS_IRQS;
irqNumber = usbHOSTEhciIrq[USB_HOST_CONTROLLER_ID - kUSB_ControllerEhci0];

/* Install isr, set priority, and enable IRQ. */
NVIC_SetPriority((IRQn_Type) irqNumber, USB_HOST_INTERRUPT_PRIORITY);
EnableIRQ((IRQn_Type) irqNumber);
}

 

For reference, here's the definition of USBHS_IRQS from the chip header file:

#define USBHS_IRQS { USB_OTG1_IRQn, USB_OTG2_IRQn }

 

So in USB_HostIsrEnable(), clearly what's going on is if USB_HOST_CONTROLLER_ID is kUSB_ControllerEhci0, that yields an array index of 0, pointing to USB_OTG1_IRQn.  If USB_HOST_CONTROLLER_ID is kUSB_ControllerEhci1, then the array index is 1, pointing to USB_OTG2_IRQn.  Seems clear that EHCI0 --> USB1 and EHCI1 --> USB2.  This is also borne out by USB_HostClockInit(); if the host controller is defined as EHCI0, then the "Usbhs0" PHY and module clocks are initialized, whereas if EHCI1 is selectedn then "Usbhs1" clocks are initialized.

 

So why is the middleware generating this line:

#define USB_HOST_CONTROLLER_ID kUSB_ControllerEhci0

 

It seems pretty clear that USB2 corresponds to EHCI1, not EHCI0, unless I'm misinterpreting the startup code.  Further, in the usb.h header file, there's this block of definitions:

/*! @brief USB controller ID */
typedef enum _usb_controller_index
{
kUSB_ControllerKhci0 = 0U, /*!< KHCI 0U */
kUSB_ControllerKhci1 = 1U, /*!< KHCI 1U, Currently, there are no platforms which have two KHCI IPs, this is reserved
to be used in the future. */

kUSB_ControllerEhci0 = 2U, /*!< EHCI 0U */
kUSB_ControllerEhci1 = 3U, /*!< EHCI 1U, Currently, there are no platforms which have two EHCI IPs, this is reserved
to be used in the future. */

kUSB_ControllerLpcIp3511Fs0 = 4U, /*!< LPC USB IP3511 FS controller 0 */
kUSB_ControllerLpcIp3511Fs1 =
5U, /*!< LPC USB IP3511 FS controller 1, there are no platforms which have two IP3511 IPs, this is reserved
to be used in the future. */

kUSB_ControllerLpcIp3511Hs0 = 6U, /*!< LPC USB IP3511 HS controller 0 */
kUSB_ControllerLpcIp3511Hs1 =
7U, /*!< LPC USB IP3511 HS controller 1, there are no platforms which have two IP3511 IPs, this is reserved
to be used in the future. */

kUSB_ControllerOhci0 = 8U, /*!< OHCI 0U */
kUSB_ControllerOhci1 = 9U, /*!< OHCI 1U, Currently, there are no platforms which have two OHCI IPs, this is reserved
to be used in the future. */

kUSB_ControllerIp3516Hs0 = 10U, /*!< IP3516HS 0U */
kUSB_ControllerIp3516Hs1 =
11U, /*!< IP3516HS 1U, Currently, there are no platforms which have two IP3516HS IPs, this is reserved
to be used in the future. */

kUSB_ControllerDwc30 = 12U, /*!< DWC3 0U */
kUSB_ControllerDwc31 =
13U, /*!< DWC3 1U Currently, there are no platforms which have two Dwc IPs, this is reserved
to be used in the future.*/

} usb_controller_index_t;

 

The comment reads, "EHCI 1U, Currently, there are no platforms which have two EHCI IPs, this is reserved to be used in the future."  It would seem that this is no longer true, as the RT1050 has two EHCI controllers, EHCI0 for USB1 and EHCI1 for USB2.  Is this correct?

 

Please let know if I'm understanding this issue correctly, and whether I should edit usb_host_app.h to read:

#define USB_HOST_CONTROLLER_ID kUSB_ControllerEhci1

 

David R.

Outcomes