a
Fork of USBDevice by
Diff: USBDevice/TARGET_Silicon_Labs/src/em_usbhal.c
- 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 ) */
