USB device stack

Dependents:   mbed-mX-USB-TEST1 USBMSD_SD_HID_HelloWorld HidTest MIDI_usb_bridge ... more

Legacy Warning

This is an mbed 2 library. To learn more about mbed OS 5, visit the docs.

Pull requests against this repository are no longer supported. Please raise against mbed OS 5 as documented above.

Revision:
71:53949e6131f6
Parent:
70:2c525a50f1b6
--- a/USBDevice/TARGET_Silicon_Labs/src/em_usbhal.c	Thu Jul 20 10:14:36 2017 +0100
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,799 +0,0 @@
-/**************************************************************************//**
- * @file em_usbhal.c
- * @brief USB protocol stack library, low level USB peripheral access.
- * @version 3.20.14
- ******************************************************************************
- * @section License
- * <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
- *******************************************************************************
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************************/
-
-#include "em_device.h"
-#if defined( USB_PRESENT ) && ( USB_COUNT == 1 )
-#include "em_usb.h"
-#if defined( USB_DEVICE ) || defined( USB_HOST )
-
-#include "em_usbtypes.h"
-#include "em_usbhal.h"
-#if defined( USB_DEVICE )
-#include "em_usbd.h"
-#endif
-#if defined( USB_HOST )
-#include "em_usbh.h"
-#endif
-#include "em_cmu.h"
-#include "em_gpio.h"
-
-/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
-
-#define EPABORT_BREAK_LOOP_COUNT 15000              /* Approx. 100 ms */
-
-/* NOTE: The sequence of error message strings must agree with the    */
-/*       definition of USB_Status_TypeDef enum.                       */
-static const char * const errMsg[] =
-{
-  [  USB_STATUS_OK                  ] = "No errors",
-  [ -USB_STATUS_REQ_ERR             ] = "Setup request error",
-  [ -USB_STATUS_EP_BUSY             ] = "Endpoint is busy",
-  [ -USB_STATUS_REQ_UNHANDLED       ] = "Setup request not handled",
-  [ -USB_STATUS_ILLEGAL             ] = "Illegal operation attempted",
-  [ -USB_STATUS_EP_STALLED          ] = "Endpoint is stalled",
-  [ -USB_STATUS_EP_ABORTED          ] = "Transfer aborted",
-  [ -USB_STATUS_EP_ERROR            ] = "Transfer error",
-  [ -USB_STATUS_EP_NAK              ] = "Endpoint NAK",
-  [ -USB_STATUS_DEVICE_UNCONFIGURED ] = "Device is not configured",
-  [ -USB_STATUS_DEVICE_SUSPENDED    ] = "Device is suspended",
-  [ -USB_STATUS_DEVICE_RESET        ] = "Device has been reset",
-  [ -USB_STATUS_TIMEOUT             ] = "Transfer timeout",
-  [ -USB_STATUS_DEVICE_REMOVED      ] = "Device removed",
-  [ -USB_STATUS_HC_BUSY             ] = "Host channel is busy",
-  [ -USB_STATUS_DEVICE_MALFUNCTION  ] = "Device malfunction",
-  [ -USB_STATUS_PORT_OVERCURRENT    ] = "VBUS overcurrent",
-};
-/** @endcond */
-
-
-/***************************************************************************//**
- * @brief
- *   Return an error message string for a given error code.
- *
- * @param[in] error
- *   Error code, see \ref USB_Status_TypeDef.
- *
- * @return
- *   Error message string pointer.
- ******************************************************************************/
-char *USB_GetErrorMsgString( int error )
-{
-  if ( error >= 0 )
-    return (char*)errMsg[ 0 ];
-
-  return (char*)errMsg[ -error ];
-}
-
-
-#if defined( USB_USE_PRINTF )
-/***************************************************************************//**
- * @brief
- *   Format and print a text string given an error code, prepends an optional user
- *   supplied leader string.
- *
- * @param[in] pre
- *   Optional leader string to prepend to error message string.
- *
- * @param[in] error
- *   Error code, see \ref USB_Status_TypeDef.
- ******************************************************************************/
-void USB_PrintErrorMsgString( char *pre, int error )
-{
-  if ( pre )
-  {
-    USB_PRINTF( "%s", pre );
-  }
-
-  if ( error > USB_STATUS_OK )
-  {
-    USB_PRINTF( "%d", error );
-  }
-  else
-  {
-    USB_PRINTF( "%s", USB_GetErrorMsgString( error ) );
-  }
-}
-#endif /* defined( USB_USE_PRINTF ) */
-
-/** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
-
-#if defined( DEBUG_EFM_USER )
-static void PrintI( int i )
-{
-#if !defined ( USER_PUTCHAR )
-  (void)i;
-#else
-  if ( i >= 10 )
-  {
-    PrintI( i / 10 );
-  }
-
-  DEBUG_USB_API_PUTCHAR( ( i % 10 ) + '0' );
-#endif
-}
-
-void assertEFM( const char *file, int line )
-{
-#if !defined ( USER_PUTCHAR )
-  (void)file;
-#endif
-
-  DEBUG_USB_API_PUTS( "\nASSERT " );
-  DEBUG_USB_API_PUTS( file );
-  DEBUG_USB_API_PUTCHAR( ' ' );
-  PrintI( line );
-  for(;;){}
-}
-#endif /* defined( DEBUG_EFM_USER ) */
-
-#if defined ( USER_PUTCHAR )
-void USB_Puts( const char *p )
-{
-  while( *p )
-    USB_PUTCHAR( *p++ );
-}
-#endif /* defined ( USER_PUTCHAR ) */
-
-void USBHAL_CoreReset( void )
-{
-  USB->PCGCCTL &= ~USB_PCGCCTL_STOPPCLK;
-  USB->PCGCCTL &= ~(USB_PCGCCTL_PWRCLMP | USB_PCGCCTL_RSTPDWNMODULE);
-
-  /* Core Soft Reset */
-  USB->GRSTCTL |= USB_GRSTCTL_CSFTRST;
-  while ( USB->GRSTCTL & USB_GRSTCTL_CSFTRST ) {}
-
-  USBTIMER_DelayUs( 1 );
-
-  /* Wait for AHB master IDLE state. */
-  while ( !( USB->GRSTCTL & USB_GRSTCTL_AHBIDLE ) ) {}
-}
-
-#ifdef USB_DEVICE
-void USBDHAL_Connect( void )
-{
-  USB->DCTL &= ~( DCTL_WO_BITMASK | USB_DCTL_SFTDISCON );
-}
-
-USB_Status_TypeDef USBDHAL_CoreInit( uint32_t totalRxFifoSize,
-                                     uint32_t totalTxFifoSize )
-{
-  uint8_t i, j;
-  uint16_t start, depth;
-  USBD_Ep_TypeDef *ep;
-
-#if !defined( USB_VBUS_SWITCH_NOT_PRESENT )
-  CMU_ClockEnable( cmuClock_GPIO, true );
-  GPIO_PinModeSet( gpioPortF, 5, gpioModePushPull, 0 ); /* Enable VBUSEN pin */
-  USB->ROUTE = USB_ROUTE_PHYPEN | USB_ROUTE_VBUSENPEN;  /* Enable PHY pins.  */
-#else
-  USB->ROUTE = USB_ROUTE_PHYPEN;                        /* Enable PHY pins.  */
-#endif
-
-  USBHAL_CoreReset();                                   /* Reset USB core    */
-
-#if defined( USB_GUSBCFG_FORCEHSTMODE )
-  /* Force Device Mode */
-  USB->GUSBCFG = ( USB->GUSBCFG                                    &
-                  ~(GUSBCFG_WO_BITMASK | USB_GUSBCFG_FORCEHSTMODE )  ) |
-                 USB_GUSBCFG_FORCEDEVMODE;
-#endif
-
-  INT_Enable();
-  USBTIMER_DelayMs( 50 );
-  INT_Disable();
-
-  /* Set device speed */
-  USB->DCFG = ( USB->DCFG & ~_USB_DCFG_DEVSPD_MASK ) | 3; /* Full speed PHY */
-
-  /* Stall on non-zero len status OUT packets (ctrl transfers). */
-  USB->DCFG |= USB_DCFG_NZSTSOUTHSHK;
-
-  /* Set periodic frame interval to 80% */
-  USB->DCFG &= ~_USB_DCFG_PERFRINT_MASK;
-
-  USB->GAHBCFG = ( USB->GAHBCFG & ~_USB_GAHBCFG_HBSTLEN_MASK ) |
-                 USB_GAHBCFG_DMAEN | USB_GAHBCFG_HBSTLEN_INCR;
-
-  /* Ignore frame numbers on ISO transfers. */
-  USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_IGNRFRMNUM;
-
-  /* Set Rx FIFO size */
-  start = EFM32_MAX( totalRxFifoSize, MIN_EP_FIFO_SIZE_INWORDS );
-  USB->GRXFSIZ = ( start << _USB_GRXFSIZ_RXFDEP_SHIFT ) &
-                 _USB_GRXFSIZ_RXFDEP_MASK;
-
-  /* Set Tx EP0 FIFO size */
-  depth = EFM32_MAX( dev->ep[ 0 ].fifoSize, MIN_EP_FIFO_SIZE_INWORDS );
-  USB->GNPTXFSIZ = ( ( depth << _USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_SHIFT ) &
-                     _USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_MASK                 ) |
-                   ( ( start << _USB_GNPTXFSIZ_NPTXFSTADDR_SHIFT ) &
-                     _USB_GNPTXFSIZ_NPTXFSTADDR_MASK                      );
-
-
-  /* Set Tx EP FIFO sizes for all IN ep's */
-  for ( j = 1; j <= MAX_NUM_TX_FIFOS; j++ )
-  {
-    for ( i = 1; i <= MAX_NUM_IN_EPS; i++ )
-    {
-      ep = USBD_GetEpFromAddr( USB_SETUP_DIR_MASK | i );
-      if ( ep )                             /* Is EP in use ? */
-      {
-        if ( ep->txFifoNum == j )           /* Is it correct FIFO number ? */
-        {
-          start += depth;
-          depth = EFM32_MAX( ep->fifoSize, MIN_EP_FIFO_SIZE_INWORDS );
-          USB_DIEPTXFS[ ep->txFifoNum - 1 ] =
-                              ( depth << _USB_DIEPTXF1_INEPNTXFDEP_SHIFT   ) |
-                              ( start &  _USB_DIEPTXF1_INEPNTXFSTADDR_MASK );
-        }
-      }
-    }
-  }
-
-  if ( totalRxFifoSize + totalTxFifoSize > MAX_DEVICE_FIFO_SIZE_INWORDS )
-    return USB_STATUS_ILLEGAL;
-
-  if ( start > MAX_DEVICE_FIFO_SIZE_INWORDS )
-    return USB_STATUS_ILLEGAL;
-
-  /* Flush the FIFO's */
-  USBHAL_FlushTxFifo( 0x10 );      /* All Tx FIFO's */
-  USBHAL_FlushRxFifo();            /* The Rx FIFO   */
-
-  /* Disable all device interrupts */
-  USB->DIEPMSK  = 0;
-  USB->DOEPMSK  = 0;
-  USB->DAINTMSK = 0;
-  USB->DIEPEMPMSK = 0;
-
-  /* Disable all EP's, clear all EP ints. */
-  for ( i = 0; i <= MAX_NUM_IN_EPS; i++ )
-  {
-    USB_DINEPS[ i ].CTL  = 0;
-    USB_DINEPS[ i ].TSIZ = 0;
-    USB_DINEPS[ i ].INT  = 0xFFFFFFFF;
-  }
-
-  for ( i = 0; i <= MAX_NUM_OUT_EPS; i++ )
-  {
-    USB_DOUTEPS[ i ].CTL  = 0;
-    USB_DOUTEPS[ i ].TSIZ = 0;
-    USB_DOUTEPS[ i ].INT  = 0xFFFFFFFF;
-  }
-
-#if ( USB_DCTL_SFTDISCON_DEFAULT != 0 )
-  USBD_Connect();
-#endif
-
-  /* Enable VREGO sense. */
-  USB->CTRL |= USB_CTRL_VREGOSEN;
-  USB->IFC   = USB_IFC_VREGOSH | USB_IFC_VREGOSL;
-  USB->IEN   = USB_IFC_VREGOSH | USB_IFC_VREGOSL;
-  /* Force a VREGO interrupt. */
-  if ( USB->STATUS & USB_STATUS_VREGOS)
-    USB->IFS = USB_IFS_VREGOSH;
-  else
-    USB->IFS = USB_IFS_VREGOSL;
-
-  return USB_STATUS_OK;
-}
-
-USB_Status_TypeDef USBDHAL_ReconfigureFifos( uint32_t totalRxFifoSize,
-                                             uint32_t totalTxFifoSize )
-{
-  uint8_t i, j;
-  uint16_t start, depth;
-  USBD_Ep_TypeDef *ep;
-
-  /* Set Rx FIFO size */
-  start = EFM32_MAX( totalRxFifoSize, MIN_EP_FIFO_SIZE_INWORDS );
-  USB->GRXFSIZ = ( start << _USB_GRXFSIZ_RXFDEP_SHIFT ) &
-                 _USB_GRXFSIZ_RXFDEP_MASK;
-
-  /* Set Tx EP0 FIFO size */
-  depth = EFM32_MAX( dev->ep[ 0 ].fifoSize, MIN_EP_FIFO_SIZE_INWORDS );
-  USB->GNPTXFSIZ = ( ( depth << _USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_SHIFT ) &
-                     _USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_MASK                 ) |
-                   ( ( start << _USB_GNPTXFSIZ_NPTXFSTADDR_SHIFT ) &
-                     _USB_GNPTXFSIZ_NPTXFSTADDR_MASK                      );
-
-
-  /* Set Tx EP FIFO sizes for all IN ep's */
-  for ( j = 1; j <= MAX_NUM_TX_FIFOS; j++ )
-  {
-    for ( i = 1; i <= MAX_NUM_IN_EPS; i++ )
-    {
-      ep = USBD_GetEpFromAddr( USB_SETUP_DIR_MASK | i );
-      if ( ep )                             /* Is EP in use ? */
-      {
-        if ( ep->txFifoNum == j )           /* Is it correct FIFO number ? */
-        {
-          start += depth;
-          depth = EFM32_MAX( ep->fifoSize, MIN_EP_FIFO_SIZE_INWORDS );
-          USB_DIEPTXFS[ ep->txFifoNum - 1 ] =
-                              ( depth << _USB_DIEPTXF1_INEPNTXFDEP_SHIFT   ) |
-                              ( start &  _USB_DIEPTXF1_INEPNTXFSTADDR_MASK );
-        }
-      }
-    }
-  }
-
-  if ( totalRxFifoSize + totalTxFifoSize > MAX_DEVICE_FIFO_SIZE_INWORDS )
-    return USB_STATUS_ILLEGAL;
-
-  if ( start > MAX_DEVICE_FIFO_SIZE_INWORDS )
-    return USB_STATUS_ILLEGAL;
-
-  /* Flush the FIFO's */
-  USBHAL_FlushTxFifo( 0x10 );      /* All Tx FIFO's */
-  USBHAL_FlushRxFifo();            /* The Rx FIFO   */
-
-  return USB_STATUS_OK;
-}
-
-void USBDHAL_Disconnect( void )
-{
-  USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_SFTDISCON;
-}
-
-void USBDHAL_AbortEpIn( USBD_Ep_TypeDef *ep )
-{
-  /* Clear epdis & inepnakeff INT's */
-  USB_DINEPS[ ep->num ].INT |= USB_DIEP_INT_EPDISBLD |
-                               USB_DIEP_INT_INEPNAKEFF;
-
-  /* Enable epdis & inepnakeff INT's */
-  USB->DIEPMSK |= USB_DIEPMSK_EPDISBLDMSK | USB_DIEPMSK_INEPNAKEFFMSK;
-  USB_DINEPS[ ep->num ].CTL = ( USB_DINEPS[ ep->num ].CTL  &
-                                ~DEPCTL_WO_BITMASK           ) |
-                              USB_DIEP_CTL_SNAK;
-
-  /* Wait for inepnakeff INT */
-  while ( !( USBDHAL_GetInEpInts( ep ) & USB_DIEP_INT_INEPNAKEFF ) ) {}
-  USB_DINEPS[ ep->num ].INT = USB_DIEP_INT_INEPNAKEFF;
-  USB->DIEPMSK &= ~USB_DIEPMSK_INEPNAKEFFMSK;
-
-  DEBUG_USB_INT_LO_PUTCHAR( '.' );
-
-  USBDHAL_SetEPDISNAK( ep );
-  /* Wait for epdis INT */
-  while ( !( USBDHAL_GetInEpInts( ep ) & USB_DIEP_INT_EPDISBLD ) ) {}
-  USB_DINEPS[ ep->num ].INT = USB_DIEP_INT_EPDISBLD;
-  USB->DIEPMSK &= ~USB_DIEPMSK_EPDISBLDMSK;
-  USBHAL_FlushTxFifo( ep->txFifoNum );
-
-  /* Clear any interrupts generated by the abort sequence. */
-  NVIC_ClearPendingIRQ( USB_IRQn );
-
-  DEBUG_USB_INT_LO_PUTCHAR( '.' );
-}
-
-void USBDHAL_AbortEpOut( USBD_Ep_TypeDef *ep )
-{
-  int cnt;
-
-  /* Clear epdis INT's */
-  USB_DOUTEPS[ ep->num ].INT |= USB_DOEP_INT_EPDISBLD;
-
-  /* Clear Global OUT NAK if already set */
-  USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_CGOUTNAK;
-  USB->GINTMSK |= USB_GINTMSK_GOUTNAKEFFMSK;    /* Enable GOUTNAKEFF int */
-
-  /* Set Global OUT NAK */
-  USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_SGOUTNAK;
-
-  /* Wait for goutnakeff */
-  cnt = EPABORT_BREAK_LOOP_COUNT;
-  while ( !( USB->GINTSTS & USB_GINTSTS_GOUTNAKEFF ) && cnt )
-  {
-    cnt--;
-  }
-
-  USB->GINTMSK &= ~USB_GINTMSK_GOUTNAKEFFMSK; /* Disable GOUTNAKEFF int  */
-  USB->DOEPMSK |= USB_DOEPMSK_EPDISBLDMSK;    /* Enable EPDIS interrupt  */
-
-  DEBUG_USB_INT_LO_PUTCHAR( ',' );
-
-  USBDHAL_SetEPDISNAK( ep );                  /* Disable ep */
-
-  /* Wait for epdis INT */
-  cnt = EPABORT_BREAK_LOOP_COUNT;
-  while ( !( USBDHAL_GetOutEpInts( ep ) & USB_DOEP_INT_EPDISBLD ) && cnt )
-  {
-    cnt--;
-  }
-
-  USB_DOUTEPS[ ep->num ].INT = USB_DOEP_INT_EPDISBLD;
-  USB->DOEPMSK &= ~USB_DOEPMSK_EPDISBLDMSK;     /* Disable EPDIS interrupt */
-
-  /* Clear Global OUT NAK */
-  USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_CGOUTNAK;
-
-  /* Clear any interrupts generated by the abort sequence. */
-  NVIC_ClearPendingIRQ( USB_IRQn );
-
-  DEBUG_USB_INT_LO_PUTCHAR( ',' );
-}
-
-void USBDHAL_AbortAllEps( void )
-{
-  int i, cnt;
-  USBD_Ep_TypeDef *ep;
-  uint16_t im, om, inmask=0, outmask=0;
-
-  /* Clear epdis & inepnakeff INT's */
-  for ( i = 1; i <= NUM_EP_USED; i++ )
-  {
-    ep = &dev->ep[i];
-    if ( ep->state != D_EP_IDLE )
-    {
-      if ( ep->in )
-      {
-        inmask |= ep->mask;
-        USB_DINEPS[ ep->num ].INT |= USB_DIEP_INT_EPDISBLD |
-                                     USB_DIEP_INT_INEPNAKEFF;
-      }
-      else
-      {
-        outmask |= ep->mask;
-        USB_DOUTEPS[ ep->num ].INT |= USB_DOEP_INT_EPDISBLD;
-      }
-    }
-  }
-
-  if ( inmask )
-  {
-    /* Enable epdis & inepnakeff INT's */
-    USB->DIEPMSK |= USB_DIEPMSK_EPDISBLDMSK | USB_DIEPMSK_INEPNAKEFFMSK;
-
-    /* Set NAK on all IN ep's */
-    im = inmask;
-    for ( i = 1; i <= NUM_EP_USED; i++ )
-    {
-      ep = &dev->ep[i];
-      if ( im & ep->mask )
-      {
-        USB_DINEPS[ ep->num ].CTL = ( USB_DINEPS[ ep->num ].CTL &
-                                      ~DEPCTL_WO_BITMASK          ) |
-                                    USB_DIEP_CTL_SNAK;
-      }
-    }
-  }
-
-  if ( outmask )
-  {
-    /* Clear Global OUT NAK if already set */
-    USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_CGOUTNAK;
-
-    USB->GINTMSK |= USB_GINTMSK_GOUTNAKEFFMSK;    /* Enable GOUTNAKEFF int */
-
-    /* Set Global OUT NAK */
-    USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_SGOUTNAK;
-
-    /* Wait for goutnakeff */
-    cnt = EPABORT_BREAK_LOOP_COUNT;
-    while ( !( USB->GINTSTS & USB_GINTSTS_GOUTNAKEFF ) && cnt )
-    {
-      cnt--;
-    }
-    USB->GINTMSK &= ~USB_GINTMSK_GOUTNAKEFFMSK; /* Disable GOUTNAKEFF int  */
-    USB->DOEPMSK |= USB_DOEPMSK_EPDISBLDMSK;    /* Enable EPDIS interrupt  */
-  }
-
-  if ( inmask )
-  {
-    /* Wait for inepnakeff INT on all IN ep's */
-    im  = inmask;
-    cnt = EPABORT_BREAK_LOOP_COUNT;
-    do
-    {
-      for ( i = 1; i <= NUM_EP_USED; i++ )
-      {
-        ep = &dev->ep[i];
-        if ( im & ep->mask )
-        {
-          if ( USBDHAL_GetInEpInts( ep ) & USB_DIEP_INT_INEPNAKEFF )
-          {
-            USB_DINEPS[ ep->num ].INT = USB_DIEP_INT_INEPNAKEFF;
-            im &= ~ep->mask;
-          }
-        }
-      }
-      cnt--;
-    } while ( im && cnt );
-    USB->DIEPMSK &= ~USB_DIEPMSK_INEPNAKEFFMSK;
-  }
-
-  DEBUG_USB_INT_LO_PUTCHAR( '\'' );
-
-  /* Disable ep's */
-  for ( i = 1; i <= NUM_EP_USED; i++ )
-  {
-    ep = &dev->ep[i];
-    if ( ep->state != D_EP_IDLE )
-    {
-      USBDHAL_SetEPDISNAK( ep );
-    }
-  }
-
-  /* Wait for epdis INT */
-  im  = inmask;
-  om  = outmask;
-  cnt = EPABORT_BREAK_LOOP_COUNT;
-  do
-  {
-    for ( i = 1; i <= NUM_EP_USED; i++ )
-    {
-      ep = &dev->ep[i];
-      if ( ep->in && ( im & ep->mask ) )
-      {
-        if ( USBDHAL_GetInEpInts( ep ) & USB_DIEP_INT_EPDISBLD )
-        {
-          USB_DINEPS[ ep->num ].INT = USB_DIEP_INT_EPDISBLD;
-          im &= ~ep->mask;
-        }
-      }
-
-      if ( !ep->in && ( om & ep->mask ) )
-      {
-        if ( USBDHAL_GetOutEpInts( ep ) & USB_DOEP_INT_EPDISBLD )
-        {
-          USB_DOUTEPS[ ep->num ].INT = USB_DOEP_INT_EPDISBLD;
-          om &= ~ep->mask;
-        }
-      }
-    }
-    cnt--;
-  } while ( ( im || om ) && cnt );
-
-  if ( inmask )
-  {
-    USB->DIEPMSK &= ~USB_DIEPMSK_EPDISBLDMSK;     /* Disable EPDIS interrupt */
-    USBHAL_FlushTxFifo( 0x10 );                   /* Flush all Tx FIFO's     */
-  }
-
-  if ( outmask )
-  {
-    USB->DOEPMSK &= ~USB_DOEPMSK_EPDISBLDMSK;     /* Disable EPDIS interrupt */
-    /* Clear Global OUT NAK */
-    USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_CGOUTNAK;
-  }
-
-  DEBUG_USB_INT_LO_PUTCHAR( '\'' );
-}
-
-void USBDHAL_AbortAllTransfers( USB_Status_TypeDef reason )
-{
-  int i;
-  USBD_Ep_TypeDef *ep;
-  USB_XferCompleteCb_TypeDef callback;
-
-  if ( reason != USB_STATUS_DEVICE_RESET )
-  {
-    USBDHAL_AbortAllEps();
-  }
-
-  for ( i = 1; i <= NUM_EP_USED; i++ )
-  {
-    ep = &(dev->ep[i]);
-    if ( ep->state != D_EP_IDLE )
-    {
-      ep->state = D_EP_IDLE;
-      if ( ep->xferCompleteCb )
-      {
-        callback = ep->xferCompleteCb;
-        ep->xferCompleteCb = NULL;
-
-        if ( ( dev->lastState == USBD_STATE_CONFIGURED ) &&
-             ( dev->state     == USBD_STATE_ADDRESSED  )    )
-        {
-          USBDHAL_DeactivateEp( ep );
-        }
-
-        DEBUG_TRACE_ABORT( reason );
-        callback( reason, ep->xferred, ep->remaining );
-      }
-    }
-  }
-
-  /* Clear any interrupts generated by the abort sequence. */
-  NVIC_ClearPendingIRQ( USB_IRQn );
-}
-#endif /* defined( USB_DEVICE ) */
-
-#if defined( USB_HOST )
-USB_Status_TypeDef USBHHAL_CoreInit( uint32_t rxFifoSize,
-                                     uint32_t nptxFifoSize,
-                                     uint32_t ptxFifoSize )
-{
-  uint8_t i;
-
-  rxFifoSize   /= 4;              /* Convert from byte count to word count.  */
-  nptxFifoSize /= 4;
-  ptxFifoSize  /= 4;
-
-  CMU_ClockEnable( cmuClock_GPIO, true );
-  GPIO_PinModeSet( gpioPortF, 5, gpioModePushPull, 0 ); /* Enable VBUSEN pin */
-
-#if ( USB_VBUSOVRCUR_PORT != USB_VBUSOVRCUR_PORT_NONE )
-  /* Enable VBUS overcurrent flag pin. */
-  GPIO_PinModeSet( USB_VBUSOVRCUR_PORT, USB_VBUSOVRCUR_PIN, gpioModeInput, 0 );
-#endif
-
-  USB->ROUTE = USB_ROUTE_PHYPEN | USB_ROUTE_VBUSENPEN;  /* Enable PHY pins.  */
-  USBHAL_CoreReset();                                   /* Reset USB core    */
-
-  /* Force Host Mode */
-  USB->GUSBCFG = ( USB->GUSBCFG                                     &
-                   ~(GUSBCFG_WO_BITMASK | USB_GUSBCFG_FORCEDEVMODE )  ) |
-                 USB_GUSBCFG_FORCEHSTMODE;
-
-  INT_Enable();
-  USBTIMER_DelayMs( 100 );
-  INT_Disable();
-
-  /* Set 48 MHz PHY clock, FS/LS mode */
-  USB->HCFG = ( USB->HCFG & ~_USB_HCFG_FSLSPCLKSEL_MASK ) |
-              ( 1 << _USB_HCFG_FSLSPCLKSEL_SHIFT        ) |
-              ( USB_HCFG_FSLSSUPP                       );
-
-  USB->GAHBCFG = ( USB->GAHBCFG & ~_USB_GAHBCFG_HBSTLEN_MASK ) |
-                 USB_GAHBCFG_DMAEN | USB_GAHBCFG_HBSTLEN_INCR;
-
-  /* Set Rx FIFO size */
-  USB->GRXFSIZ = ( rxFifoSize << _USB_GRXFSIZ_RXFDEP_SHIFT ) &
-                 _USB_GRXFSIZ_RXFDEP_MASK;
-
-  /* Set Tx FIFO sizes */
-  USB->GNPTXFSIZ = ( ( nptxFifoSize <<
-                       _USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_SHIFT ) &
-                     _USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_MASK        ) |
-                   ( ( rxFifoSize <<
-                       _USB_GNPTXFSIZ_NPTXFSTADDR_SHIFT      ) &
-                     _USB_GNPTXFSIZ_NPTXFSTADDR_MASK             );
-
-  USB->HPTXFSIZ  = ( ( ptxFifoSize  << _USB_HPTXFSIZ_PTXFSIZE_SHIFT   ) &
-                     _USB_HPTXFSIZ_PTXFSIZE_MASK                          ) |
-                   ( ( ( rxFifoSize + nptxFifoSize )
-                                    << _USB_HPTXFSIZ_PTXFSTADDR_SHIFT ) &
-                     _USB_HPTXFSIZ_PTXFSTADDR_MASK                        );
-
-  /* Flush Tx and Rx FIFO's */
-  USBHAL_FlushTxFifo( 0x10 );
-  USBHAL_FlushRxFifo();
-
-  for ( i = 0; i < MAX_NUM_HOSTCHANNELS; i++ )
-  {
-    USB->HC[ i ].CHAR = USB_HC_CHAR_CHDIS;      /* Disable channel          */
-    USB->HC[ i ].INT = 0xFFFFFFFF;              /* Clear pending interrupts */
-  }
-
-  /* Enable and halt all channels */
-  for ( i = 0; i < MAX_NUM_HOSTCHANNELS; i++ )
-  {
-    USB->HC[ i ].CHAR |= USB_HC_CHAR_CHDIS | USB_HC_CHAR_CHENA;
-    do
-    {
-      __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
-    }
-    while ( USB->HC[ i ].CHAR & USB_HC_CHAR_CHENA );
-  }
-
-  /* Disable all interrupts */
-  for ( i = 0; i < MAX_NUM_HOSTCHANNELS; i++ )
-  {
-    USB->HC[ i ].INTMSK = 0;
-  }
-
-  USB->HAINTMSK = 0;
-
-  return USB_STATUS_OK;
-}
-
-void USBHHAL_HCHalt( int hcnum, uint32_t hcchar )
-{
-  hcchar |= USB_HC_CHAR_CHENA | USB_HC_CHAR_CHDIS;
-  USB->HC[ hcnum ].CHAR = hcchar;
-}
-
-void USBHHAL_HCInit( int hcnum )
-{
-  USBH_Ep_TypeDef *ep;
-
-  ep = hcs[ hcnum ].ep;
-  USB->HC[ hcnum ].INT = 0xFFFFFFFF;      /* Clear all interrupt flags      */
-
-  switch ( ep->type )                     /* Enable host channel int. types */
-  {
-    case USB_EPTYPE_CTRL:
-    case USB_EPTYPE_BULK:
-    case USB_EPTYPE_INTR:
-      USB->HC[ hcnum ].INTMSK = USB_HC_INT_CHHLTD;
-      break;
-  }
-
-  hcs[ hcnum ].errorCnt = 0;
-
-  USB->HAINTMSK |= 1 << hcnum;            /* Enable host channel interrupt  */
-
-  USB->HC[ hcnum ].CHAR =                 /* Program HCCHAR register        */
-      ( ep->parentDevice->addr     <<   _USB_HC_CHAR_DEVADDR_SHIFT     ) |
-      ( ( ep->addr & USB_EPNUM_MASK ) << _USB_HC_CHAR_EPNUM_SHIFT      ) |
-      ( ep->type                   <<   _USB_HC_CHAR_EPTYPE_SHIFT      ) |
-      ( ep->packetSize             <<   _USB_HC_CHAR_MPS_SHIFT         ) |
-      ( ep->in                      ?   USB_HC_CHAR_EPDIR         : 0  ) |
-      ( ep->parentDevice->speed ==
-                           HPRT_L_SPEED >> _USB_HPRT_PRTSPD_SHIFT
-                                    ?   USB_HC_CHAR_LSPDDEV       : 0  );
-}
-
-void USBHHAL_HCStart( int hcnum )
-{
-  USBH_Hc_TypeDef *hc;
-  uint16_t packets, len;
-
-  hc = &hcs[ hcnum ];
-  hc->status = 0;
-  hc->idle = false;
-
-  if ( hc->remaining > 0 )
-  {
-    packets = ( hc->remaining + hc->ep->packetSize - 1 ) / hc->ep->packetSize;
-  }
-  else
-  {
-    packets = 1;
-  }
-
-  if ( hc->ep->in )
-  {
-    len = packets * hc->ep->packetSize;
-  }
-  else
-  {
-    len = hc->remaining;
-  }
-
-  /* Initialize the HCTSIZn register */
-  hc->hwXferSize = len;
-  USB->HC[ hcnum ].TSIZ =
-          ( ( len             << _USB_HC_TSIZ_XFERSIZE_SHIFT ) &
-                                 _USB_HC_TSIZ_XFERSIZE_MASK       ) |
-          ( ( packets         << _USB_HC_TSIZ_PKTCNT_SHIFT   ) &
-                                 _USB_HC_TSIZ_PKTCNT_MASK         ) |
-          ( ( hc->ep->toggle  << _USB_HC_TSIZ_PID_SHIFT      ) &
-                                 _USB_HC_TSIZ_PID_MASK            );
-
-  USB->HC[ hcnum ].DMAADDR = (uint32_t)hc->buf;
-
-  USBHHAL_HCActivate( hcnum,
-                      USB->HC[ hcnum ].CHAR,
-                      hc->ep->type == USB_EPTYPE_INTR );
-}
-#endif /* defined( USB_HOST ) */
-
-/** @endcond */
-
-#endif /* defined( USB_DEVICE ) || defined( USB_HOST ) */
-#endif /* defined( USB_PRESENT ) && ( USB_COUNT == 1 ) */