text: /*
   * Copyright (c) 2015 - 2016, Freescale Semiconductor, Inc.
   * Copyright 2016 - 2017 NXP
   * All rights reserved.
   *
   * SPDX-License-Identifier: BSD-3-Clause
   */
  
  #include "usb_host_config.h"
  #include "usb_host.h"
  #include "fsl_device_registers.h"
  #include "usb_host_msd.h"
  #include "host_msd_command.h"
  #include "fsl_common.h"
  #include "pin_mux.h"
  #include "clock_config.h"
  #include "board.h"
  #if (defined(FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT > 0U))
  #include "fsl_sysmpu.h"
  #endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
  #include "app.h"
  
  #if ((!USB_HOST_CONFIG_KHCI) && (!USB_HOST_CONFIG_EHCI) && (!USB_HOST_CONFIG_OHCI) && (!USB_HOST_CONFIG_IP3516HS))
  #error Please enable USB_HOST_CONFIG_KHCI, USB_HOST_CONFIG_EHCI, USB_HOST_CONFIG_OHCI, or USB_HOST_CONFIG_IP3516HS in file usb_host_config.
  #endif
  
  /*******************************************************************************
   * Definitions
   ******************************************************************************/
  /*******************************************************************************
   * Prototypes
   ******************************************************************************/
  
  /*!
   * @brief host callback function.
   *
   * device attach/detach callback function.
   *
   * @param deviceHandle        device handle.
   * @param configurationHandle attached device's configuration descriptor information.
   * @param eventCode           callback event code, please reference to enumeration host_event_t.
   *
   * @retval kStatus_USB_Success              The host is initialized successfully.
   * @retval kStatus_USB_NotSupported         The application don't support the configuration.
   */
  static usb_status_t USB_HostEvent(usb_device_handle deviceHandle,
                                    usb_host_configuration_handle configurationHandle,
                                    uint32_t eventCode);
  
  /*!
   * @brief application initialization.
   */
  static void USB_HostApplicationInit(void);
  
  extern void USB_HostClockInit(void);
  extern void USB_HostIsrEnable(void);
  extern void USB_HostTaskFn(void *param);
  void BOARD_InitHardware(void);
  
  /*******************************************************************************
   * Variables
   ******************************************************************************/
  
  /*! @brief USB host msd command instance global variable */
  extern usb_host_msd_command_instance_t g_MsdCommandInstance;
  usb_host_handle g_HostHandle;
  
  /*******************************************************************************
   * Code
   ******************************************************************************/
  
  void USB0_IRQHandler(void)
  {
      USB_HostKhciIsrFunction(g_HostHandle);
      /* Add for ARM errata 838869, affects Cortex-M4, Cortex-M4F Store immediate overlapping
      exception return operation might vector to incorrect interrupt */
      __DSB();
  }
  
  void USB_HostClockInit(void)
  {
      SystemCoreClockUpdate();
      CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcPll0, CLOCK_GetFreq(kCLOCK_PllFllSelClk));
  }
  
  void USB_HostIsrEnable(void)
  {
      uint8_t irqNumber;
  
      uint8_t usbHOSTKhciIrq[] = USB_IRQS;
      irqNumber                = usbHOSTKhciIrq[CONTROLLER_ID - kUSB_ControllerKhci0];
  
  /* Install isr, set priority, and enable IRQ. */
  #if defined(__GIC_PRIO_BITS)
      GIC_SetPriority((IRQn_Type)irqNumber, USB_HOST_INTERRUPT_PRIORITY);
  #else
      NVIC_SetPriority((IRQn_Type)irqNumber, USB_HOST_INTERRUPT_PRIORITY);
  #endif
      EnableIRQ((IRQn_Type)irqNumber);
  }
  
  void USB_HostTaskFn(void *param)
  {
      USB_HostKhciTaskFunction(param);
  }
  
  /*!
   * @brief USB isr function.
   */
  
  static usb_status_t USB_HostEvent(usb_device_handle deviceHandle,
                                    usb_host_configuration_handle configurationHandle,
                                    uint32_t eventCode)
  {
      usb_status_t status = kStatus_USB_Success;
      switch (eventCode & 0x0000FFFFU)
      {
          case kUSB_HostEventAttach:
              status = USB_HostMsdEvent(deviceHandle, configurationHandle, eventCode);
              break;
  
          case kUSB_HostEventNotSupported:
              usb_echo("device not supported.\r\n");
              break;
  
          case kUSB_HostEventEnumerationDone:
              status = USB_HostMsdEvent(deviceHandle, configurationHandle, eventCode);
              break;
  
          case kUSB_HostEventDetach:
              status = USB_HostMsdEvent(deviceHandle, configurationHandle, eventCode);
              break;
  
          case kUSB_HostEventEnumerationFail:
              usb_echo("enumeration failed\r\n");
              break;
  
          default:
              break;
      }
      return status;
  }
  
  static void USB_HostApplicationInit(void)
  {
      usb_status_t status = kStatus_USB_Success;
  
      USB_HostClockInit();
  
  #if ((defined FSL_FEATURE_SOC_SYSMPU_COUNT) && (FSL_FEATURE_SOC_SYSMPU_COUNT))
      SYSMPU_Enable(SYSMPU, 0);
  #endif /* FSL_FEATURE_SOC_SYSMPU_COUNT */
  
      status = USB_HostInit(CONTROLLER_ID, &g_HostHandle, USB_HostEvent);
      if (status != kStatus_USB_Success)
      {
          usb_echo("host init error\r\n");
          return;
      }
      USB_HostIsrEnable();
  
      usb_echo("host init done\r\n");
  }
  
  int main(void)
  {
      BOARD_InitPins();
      BOARD_BootClockRUN();
      BOARD_InitDebugConsole();
  
      USB_HostApplicationInit();
  
      while (1)
      {
          USB_HostTaskFn(g_HostHandle);
          USB_HostMsdTask(&g_MsdCommandInstance);
      }
  }
  