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.

Committer:
Kojto
Date:
Thu Jul 27 12:14:04 2017 +0100
Revision:
71:53949e6131f6
Update libraries

Fixes the previous commmit, as some devices were not copied. USBDevice contains
now targets directory with all targets implementations

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Kojto 71:53949e6131f6 1 /**************************************************************************//**
Kojto 71:53949e6131f6 2 * @file em_usbhal.c
Kojto 71:53949e6131f6 3 * @brief USB protocol stack library, low level USB peripheral access.
Kojto 71:53949e6131f6 4 * @version 3.20.14
Kojto 71:53949e6131f6 5 ******************************************************************************
Kojto 71:53949e6131f6 6 * @section License
Kojto 71:53949e6131f6 7 * <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
Kojto 71:53949e6131f6 8 *******************************************************************************
Kojto 71:53949e6131f6 9 *
Kojto 71:53949e6131f6 10 * Licensed under the Apache License, Version 2.0 (the "License");
Kojto 71:53949e6131f6 11 * you may not use this file except in compliance with the License.
Kojto 71:53949e6131f6 12 * You may obtain a copy of the License at
Kojto 71:53949e6131f6 13 *
Kojto 71:53949e6131f6 14 * http://www.apache.org/licenses/LICENSE-2.0
Kojto 71:53949e6131f6 15 *
Kojto 71:53949e6131f6 16 * Unless required by applicable law or agreed to in writing, software
Kojto 71:53949e6131f6 17 * distributed under the License is distributed on an "AS IS" BASIS,
Kojto 71:53949e6131f6 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Kojto 71:53949e6131f6 19 * See the License for the specific language governing permissions and
Kojto 71:53949e6131f6 20 * limitations under the License.
Kojto 71:53949e6131f6 21 *
Kojto 71:53949e6131f6 22 ******************************************************************************/
Kojto 71:53949e6131f6 23
Kojto 71:53949e6131f6 24 #include "em_device.h"
Kojto 71:53949e6131f6 25 #if defined( USB_PRESENT ) && ( USB_COUNT == 1 )
Kojto 71:53949e6131f6 26 #include "em_usb.h"
Kojto 71:53949e6131f6 27 #if defined( USB_DEVICE ) || defined( USB_HOST )
Kojto 71:53949e6131f6 28
Kojto 71:53949e6131f6 29 #include "em_usbtypes.h"
Kojto 71:53949e6131f6 30 #include "em_usbhal.h"
Kojto 71:53949e6131f6 31 #if defined( USB_DEVICE )
Kojto 71:53949e6131f6 32 #include "em_usbd.h"
Kojto 71:53949e6131f6 33 #endif
Kojto 71:53949e6131f6 34 #if defined( USB_HOST )
Kojto 71:53949e6131f6 35 #include "em_usbh.h"
Kojto 71:53949e6131f6 36 #endif
Kojto 71:53949e6131f6 37 #include "em_cmu.h"
Kojto 71:53949e6131f6 38 #include "em_gpio.h"
Kojto 71:53949e6131f6 39
Kojto 71:53949e6131f6 40 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
Kojto 71:53949e6131f6 41
Kojto 71:53949e6131f6 42 #define EPABORT_BREAK_LOOP_COUNT 15000 /* Approx. 100 ms */
Kojto 71:53949e6131f6 43
Kojto 71:53949e6131f6 44 /* NOTE: The sequence of error message strings must agree with the */
Kojto 71:53949e6131f6 45 /* definition of USB_Status_TypeDef enum. */
Kojto 71:53949e6131f6 46 static const char * const errMsg[] =
Kojto 71:53949e6131f6 47 {
Kojto 71:53949e6131f6 48 [ USB_STATUS_OK ] = "No errors",
Kojto 71:53949e6131f6 49 [ -USB_STATUS_REQ_ERR ] = "Setup request error",
Kojto 71:53949e6131f6 50 [ -USB_STATUS_EP_BUSY ] = "Endpoint is busy",
Kojto 71:53949e6131f6 51 [ -USB_STATUS_REQ_UNHANDLED ] = "Setup request not handled",
Kojto 71:53949e6131f6 52 [ -USB_STATUS_ILLEGAL ] = "Illegal operation attempted",
Kojto 71:53949e6131f6 53 [ -USB_STATUS_EP_STALLED ] = "Endpoint is stalled",
Kojto 71:53949e6131f6 54 [ -USB_STATUS_EP_ABORTED ] = "Transfer aborted",
Kojto 71:53949e6131f6 55 [ -USB_STATUS_EP_ERROR ] = "Transfer error",
Kojto 71:53949e6131f6 56 [ -USB_STATUS_EP_NAK ] = "Endpoint NAK",
Kojto 71:53949e6131f6 57 [ -USB_STATUS_DEVICE_UNCONFIGURED ] = "Device is not configured",
Kojto 71:53949e6131f6 58 [ -USB_STATUS_DEVICE_SUSPENDED ] = "Device is suspended",
Kojto 71:53949e6131f6 59 [ -USB_STATUS_DEVICE_RESET ] = "Device has been reset",
Kojto 71:53949e6131f6 60 [ -USB_STATUS_TIMEOUT ] = "Transfer timeout",
Kojto 71:53949e6131f6 61 [ -USB_STATUS_DEVICE_REMOVED ] = "Device removed",
Kojto 71:53949e6131f6 62 [ -USB_STATUS_HC_BUSY ] = "Host channel is busy",
Kojto 71:53949e6131f6 63 [ -USB_STATUS_DEVICE_MALFUNCTION ] = "Device malfunction",
Kojto 71:53949e6131f6 64 [ -USB_STATUS_PORT_OVERCURRENT ] = "VBUS overcurrent",
Kojto 71:53949e6131f6 65 };
Kojto 71:53949e6131f6 66 /** @endcond */
Kojto 71:53949e6131f6 67
Kojto 71:53949e6131f6 68
Kojto 71:53949e6131f6 69 /***************************************************************************//**
Kojto 71:53949e6131f6 70 * @brief
Kojto 71:53949e6131f6 71 * Return an error message string for a given error code.
Kojto 71:53949e6131f6 72 *
Kojto 71:53949e6131f6 73 * @param[in] error
Kojto 71:53949e6131f6 74 * Error code, see \ref USB_Status_TypeDef.
Kojto 71:53949e6131f6 75 *
Kojto 71:53949e6131f6 76 * @return
Kojto 71:53949e6131f6 77 * Error message string pointer.
Kojto 71:53949e6131f6 78 ******************************************************************************/
Kojto 71:53949e6131f6 79 char *USB_GetErrorMsgString( int error )
Kojto 71:53949e6131f6 80 {
Kojto 71:53949e6131f6 81 if ( error >= 0 )
Kojto 71:53949e6131f6 82 return (char*)errMsg[ 0 ];
Kojto 71:53949e6131f6 83
Kojto 71:53949e6131f6 84 return (char*)errMsg[ -error ];
Kojto 71:53949e6131f6 85 }
Kojto 71:53949e6131f6 86
Kojto 71:53949e6131f6 87
Kojto 71:53949e6131f6 88 #if defined( USB_USE_PRINTF )
Kojto 71:53949e6131f6 89 /***************************************************************************//**
Kojto 71:53949e6131f6 90 * @brief
Kojto 71:53949e6131f6 91 * Format and print a text string given an error code, prepends an optional user
Kojto 71:53949e6131f6 92 * supplied leader string.
Kojto 71:53949e6131f6 93 *
Kojto 71:53949e6131f6 94 * @param[in] pre
Kojto 71:53949e6131f6 95 * Optional leader string to prepend to error message string.
Kojto 71:53949e6131f6 96 *
Kojto 71:53949e6131f6 97 * @param[in] error
Kojto 71:53949e6131f6 98 * Error code, see \ref USB_Status_TypeDef.
Kojto 71:53949e6131f6 99 ******************************************************************************/
Kojto 71:53949e6131f6 100 void USB_PrintErrorMsgString( char *pre, int error )
Kojto 71:53949e6131f6 101 {
Kojto 71:53949e6131f6 102 if ( pre )
Kojto 71:53949e6131f6 103 {
Kojto 71:53949e6131f6 104 USB_PRINTF( "%s", pre );
Kojto 71:53949e6131f6 105 }
Kojto 71:53949e6131f6 106
Kojto 71:53949e6131f6 107 if ( error > USB_STATUS_OK )
Kojto 71:53949e6131f6 108 {
Kojto 71:53949e6131f6 109 USB_PRINTF( "%d", error );
Kojto 71:53949e6131f6 110 }
Kojto 71:53949e6131f6 111 else
Kojto 71:53949e6131f6 112 {
Kojto 71:53949e6131f6 113 USB_PRINTF( "%s", USB_GetErrorMsgString( error ) );
Kojto 71:53949e6131f6 114 }
Kojto 71:53949e6131f6 115 }
Kojto 71:53949e6131f6 116 #endif /* defined( USB_USE_PRINTF ) */
Kojto 71:53949e6131f6 117
Kojto 71:53949e6131f6 118 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
Kojto 71:53949e6131f6 119
Kojto 71:53949e6131f6 120 #if defined( DEBUG_EFM_USER )
Kojto 71:53949e6131f6 121 static void PrintI( int i )
Kojto 71:53949e6131f6 122 {
Kojto 71:53949e6131f6 123 #if !defined ( USER_PUTCHAR )
Kojto 71:53949e6131f6 124 (void)i;
Kojto 71:53949e6131f6 125 #else
Kojto 71:53949e6131f6 126 if ( i >= 10 )
Kojto 71:53949e6131f6 127 {
Kojto 71:53949e6131f6 128 PrintI( i / 10 );
Kojto 71:53949e6131f6 129 }
Kojto 71:53949e6131f6 130
Kojto 71:53949e6131f6 131 DEBUG_USB_API_PUTCHAR( ( i % 10 ) + '0' );
Kojto 71:53949e6131f6 132 #endif
Kojto 71:53949e6131f6 133 }
Kojto 71:53949e6131f6 134
Kojto 71:53949e6131f6 135 void assertEFM( const char *file, int line )
Kojto 71:53949e6131f6 136 {
Kojto 71:53949e6131f6 137 #if !defined ( USER_PUTCHAR )
Kojto 71:53949e6131f6 138 (void)file;
Kojto 71:53949e6131f6 139 #endif
Kojto 71:53949e6131f6 140
Kojto 71:53949e6131f6 141 DEBUG_USB_API_PUTS( "\nASSERT " );
Kojto 71:53949e6131f6 142 DEBUG_USB_API_PUTS( file );
Kojto 71:53949e6131f6 143 DEBUG_USB_API_PUTCHAR( ' ' );
Kojto 71:53949e6131f6 144 PrintI( line );
Kojto 71:53949e6131f6 145 for(;;){}
Kojto 71:53949e6131f6 146 }
Kojto 71:53949e6131f6 147 #endif /* defined( DEBUG_EFM_USER ) */
Kojto 71:53949e6131f6 148
Kojto 71:53949e6131f6 149 #if defined ( USER_PUTCHAR )
Kojto 71:53949e6131f6 150 void USB_Puts( const char *p )
Kojto 71:53949e6131f6 151 {
Kojto 71:53949e6131f6 152 while( *p )
Kojto 71:53949e6131f6 153 USB_PUTCHAR( *p++ );
Kojto 71:53949e6131f6 154 }
Kojto 71:53949e6131f6 155 #endif /* defined ( USER_PUTCHAR ) */
Kojto 71:53949e6131f6 156
Kojto 71:53949e6131f6 157 void USBHAL_CoreReset( void )
Kojto 71:53949e6131f6 158 {
Kojto 71:53949e6131f6 159 USB->PCGCCTL &= ~USB_PCGCCTL_STOPPCLK;
Kojto 71:53949e6131f6 160 USB->PCGCCTL &= ~(USB_PCGCCTL_PWRCLMP | USB_PCGCCTL_RSTPDWNMODULE);
Kojto 71:53949e6131f6 161
Kojto 71:53949e6131f6 162 /* Core Soft Reset */
Kojto 71:53949e6131f6 163 USB->GRSTCTL |= USB_GRSTCTL_CSFTRST;
Kojto 71:53949e6131f6 164 while ( USB->GRSTCTL & USB_GRSTCTL_CSFTRST ) {}
Kojto 71:53949e6131f6 165
Kojto 71:53949e6131f6 166 USBTIMER_DelayUs( 1 );
Kojto 71:53949e6131f6 167
Kojto 71:53949e6131f6 168 /* Wait for AHB master IDLE state. */
Kojto 71:53949e6131f6 169 while ( !( USB->GRSTCTL & USB_GRSTCTL_AHBIDLE ) ) {}
Kojto 71:53949e6131f6 170 }
Kojto 71:53949e6131f6 171
Kojto 71:53949e6131f6 172 #ifdef USB_DEVICE
Kojto 71:53949e6131f6 173 void USBDHAL_Connect( void )
Kojto 71:53949e6131f6 174 {
Kojto 71:53949e6131f6 175 USB->DCTL &= ~( DCTL_WO_BITMASK | USB_DCTL_SFTDISCON );
Kojto 71:53949e6131f6 176 }
Kojto 71:53949e6131f6 177
Kojto 71:53949e6131f6 178 USB_Status_TypeDef USBDHAL_CoreInit( uint32_t totalRxFifoSize,
Kojto 71:53949e6131f6 179 uint32_t totalTxFifoSize )
Kojto 71:53949e6131f6 180 {
Kojto 71:53949e6131f6 181 uint8_t i, j;
Kojto 71:53949e6131f6 182 uint16_t start, depth;
Kojto 71:53949e6131f6 183 USBD_Ep_TypeDef *ep;
Kojto 71:53949e6131f6 184
Kojto 71:53949e6131f6 185 #if !defined( USB_VBUS_SWITCH_NOT_PRESENT )
Kojto 71:53949e6131f6 186 CMU_ClockEnable( cmuClock_GPIO, true );
Kojto 71:53949e6131f6 187 GPIO_PinModeSet( gpioPortF, 5, gpioModePushPull, 0 ); /* Enable VBUSEN pin */
Kojto 71:53949e6131f6 188 USB->ROUTE = USB_ROUTE_PHYPEN | USB_ROUTE_VBUSENPEN; /* Enable PHY pins. */
Kojto 71:53949e6131f6 189 #else
Kojto 71:53949e6131f6 190 USB->ROUTE = USB_ROUTE_PHYPEN; /* Enable PHY pins. */
Kojto 71:53949e6131f6 191 #endif
Kojto 71:53949e6131f6 192
Kojto 71:53949e6131f6 193 USBHAL_CoreReset(); /* Reset USB core */
Kojto 71:53949e6131f6 194
Kojto 71:53949e6131f6 195 #if defined( USB_GUSBCFG_FORCEHSTMODE )
Kojto 71:53949e6131f6 196 /* Force Device Mode */
Kojto 71:53949e6131f6 197 USB->GUSBCFG = ( USB->GUSBCFG &
Kojto 71:53949e6131f6 198 ~(GUSBCFG_WO_BITMASK | USB_GUSBCFG_FORCEHSTMODE ) ) |
Kojto 71:53949e6131f6 199 USB_GUSBCFG_FORCEDEVMODE;
Kojto 71:53949e6131f6 200 #endif
Kojto 71:53949e6131f6 201
Kojto 71:53949e6131f6 202 INT_Enable();
Kojto 71:53949e6131f6 203 USBTIMER_DelayMs( 50 );
Kojto 71:53949e6131f6 204 INT_Disable();
Kojto 71:53949e6131f6 205
Kojto 71:53949e6131f6 206 /* Set device speed */
Kojto 71:53949e6131f6 207 USB->DCFG = ( USB->DCFG & ~_USB_DCFG_DEVSPD_MASK ) | 3; /* Full speed PHY */
Kojto 71:53949e6131f6 208
Kojto 71:53949e6131f6 209 /* Stall on non-zero len status OUT packets (ctrl transfers). */
Kojto 71:53949e6131f6 210 USB->DCFG |= USB_DCFG_NZSTSOUTHSHK;
Kojto 71:53949e6131f6 211
Kojto 71:53949e6131f6 212 /* Set periodic frame interval to 80% */
Kojto 71:53949e6131f6 213 USB->DCFG &= ~_USB_DCFG_PERFRINT_MASK;
Kojto 71:53949e6131f6 214
Kojto 71:53949e6131f6 215 USB->GAHBCFG = ( USB->GAHBCFG & ~_USB_GAHBCFG_HBSTLEN_MASK ) |
Kojto 71:53949e6131f6 216 USB_GAHBCFG_DMAEN | USB_GAHBCFG_HBSTLEN_INCR;
Kojto 71:53949e6131f6 217
Kojto 71:53949e6131f6 218 /* Ignore frame numbers on ISO transfers. */
Kojto 71:53949e6131f6 219 USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_IGNRFRMNUM;
Kojto 71:53949e6131f6 220
Kojto 71:53949e6131f6 221 /* Set Rx FIFO size */
Kojto 71:53949e6131f6 222 start = EFM32_MAX( totalRxFifoSize, MIN_EP_FIFO_SIZE_INWORDS );
Kojto 71:53949e6131f6 223 USB->GRXFSIZ = ( start << _USB_GRXFSIZ_RXFDEP_SHIFT ) &
Kojto 71:53949e6131f6 224 _USB_GRXFSIZ_RXFDEP_MASK;
Kojto 71:53949e6131f6 225
Kojto 71:53949e6131f6 226 /* Set Tx EP0 FIFO size */
Kojto 71:53949e6131f6 227 depth = EFM32_MAX( dev->ep[ 0 ].fifoSize, MIN_EP_FIFO_SIZE_INWORDS );
Kojto 71:53949e6131f6 228 USB->GNPTXFSIZ = ( ( depth << _USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_SHIFT ) &
Kojto 71:53949e6131f6 229 _USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_MASK ) |
Kojto 71:53949e6131f6 230 ( ( start << _USB_GNPTXFSIZ_NPTXFSTADDR_SHIFT ) &
Kojto 71:53949e6131f6 231 _USB_GNPTXFSIZ_NPTXFSTADDR_MASK );
Kojto 71:53949e6131f6 232
Kojto 71:53949e6131f6 233
Kojto 71:53949e6131f6 234 /* Set Tx EP FIFO sizes for all IN ep's */
Kojto 71:53949e6131f6 235 for ( j = 1; j <= MAX_NUM_TX_FIFOS; j++ )
Kojto 71:53949e6131f6 236 {
Kojto 71:53949e6131f6 237 for ( i = 1; i <= MAX_NUM_IN_EPS; i++ )
Kojto 71:53949e6131f6 238 {
Kojto 71:53949e6131f6 239 ep = USBD_GetEpFromAddr( USB_SETUP_DIR_MASK | i );
Kojto 71:53949e6131f6 240 if ( ep ) /* Is EP in use ? */
Kojto 71:53949e6131f6 241 {
Kojto 71:53949e6131f6 242 if ( ep->txFifoNum == j ) /* Is it correct FIFO number ? */
Kojto 71:53949e6131f6 243 {
Kojto 71:53949e6131f6 244 start += depth;
Kojto 71:53949e6131f6 245 depth = EFM32_MAX( ep->fifoSize, MIN_EP_FIFO_SIZE_INWORDS );
Kojto 71:53949e6131f6 246 USB_DIEPTXFS[ ep->txFifoNum - 1 ] =
Kojto 71:53949e6131f6 247 ( depth << _USB_DIEPTXF1_INEPNTXFDEP_SHIFT ) |
Kojto 71:53949e6131f6 248 ( start & _USB_DIEPTXF1_INEPNTXFSTADDR_MASK );
Kojto 71:53949e6131f6 249 }
Kojto 71:53949e6131f6 250 }
Kojto 71:53949e6131f6 251 }
Kojto 71:53949e6131f6 252 }
Kojto 71:53949e6131f6 253
Kojto 71:53949e6131f6 254 if ( totalRxFifoSize + totalTxFifoSize > MAX_DEVICE_FIFO_SIZE_INWORDS )
Kojto 71:53949e6131f6 255 return USB_STATUS_ILLEGAL;
Kojto 71:53949e6131f6 256
Kojto 71:53949e6131f6 257 if ( start > MAX_DEVICE_FIFO_SIZE_INWORDS )
Kojto 71:53949e6131f6 258 return USB_STATUS_ILLEGAL;
Kojto 71:53949e6131f6 259
Kojto 71:53949e6131f6 260 /* Flush the FIFO's */
Kojto 71:53949e6131f6 261 USBHAL_FlushTxFifo( 0x10 ); /* All Tx FIFO's */
Kojto 71:53949e6131f6 262 USBHAL_FlushRxFifo(); /* The Rx FIFO */
Kojto 71:53949e6131f6 263
Kojto 71:53949e6131f6 264 /* Disable all device interrupts */
Kojto 71:53949e6131f6 265 USB->DIEPMSK = 0;
Kojto 71:53949e6131f6 266 USB->DOEPMSK = 0;
Kojto 71:53949e6131f6 267 USB->DAINTMSK = 0;
Kojto 71:53949e6131f6 268 USB->DIEPEMPMSK = 0;
Kojto 71:53949e6131f6 269
Kojto 71:53949e6131f6 270 /* Disable all EP's, clear all EP ints. */
Kojto 71:53949e6131f6 271 for ( i = 0; i <= MAX_NUM_IN_EPS; i++ )
Kojto 71:53949e6131f6 272 {
Kojto 71:53949e6131f6 273 USB_DINEPS[ i ].CTL = 0;
Kojto 71:53949e6131f6 274 USB_DINEPS[ i ].TSIZ = 0;
Kojto 71:53949e6131f6 275 USB_DINEPS[ i ].INT = 0xFFFFFFFF;
Kojto 71:53949e6131f6 276 }
Kojto 71:53949e6131f6 277
Kojto 71:53949e6131f6 278 for ( i = 0; i <= MAX_NUM_OUT_EPS; i++ )
Kojto 71:53949e6131f6 279 {
Kojto 71:53949e6131f6 280 USB_DOUTEPS[ i ].CTL = 0;
Kojto 71:53949e6131f6 281 USB_DOUTEPS[ i ].TSIZ = 0;
Kojto 71:53949e6131f6 282 USB_DOUTEPS[ i ].INT = 0xFFFFFFFF;
Kojto 71:53949e6131f6 283 }
Kojto 71:53949e6131f6 284
Kojto 71:53949e6131f6 285 #if ( USB_DCTL_SFTDISCON_DEFAULT != 0 )
Kojto 71:53949e6131f6 286 USBD_Connect();
Kojto 71:53949e6131f6 287 #endif
Kojto 71:53949e6131f6 288
Kojto 71:53949e6131f6 289 /* Enable VREGO sense. */
Kojto 71:53949e6131f6 290 USB->CTRL |= USB_CTRL_VREGOSEN;
Kojto 71:53949e6131f6 291 USB->IFC = USB_IFC_VREGOSH | USB_IFC_VREGOSL;
Kojto 71:53949e6131f6 292 USB->IEN = USB_IFC_VREGOSH | USB_IFC_VREGOSL;
Kojto 71:53949e6131f6 293 /* Force a VREGO interrupt. */
Kojto 71:53949e6131f6 294 if ( USB->STATUS & USB_STATUS_VREGOS)
Kojto 71:53949e6131f6 295 USB->IFS = USB_IFS_VREGOSH;
Kojto 71:53949e6131f6 296 else
Kojto 71:53949e6131f6 297 USB->IFS = USB_IFS_VREGOSL;
Kojto 71:53949e6131f6 298
Kojto 71:53949e6131f6 299 return USB_STATUS_OK;
Kojto 71:53949e6131f6 300 }
Kojto 71:53949e6131f6 301
Kojto 71:53949e6131f6 302 USB_Status_TypeDef USBDHAL_ReconfigureFifos( uint32_t totalRxFifoSize,
Kojto 71:53949e6131f6 303 uint32_t totalTxFifoSize )
Kojto 71:53949e6131f6 304 {
Kojto 71:53949e6131f6 305 uint8_t i, j;
Kojto 71:53949e6131f6 306 uint16_t start, depth;
Kojto 71:53949e6131f6 307 USBD_Ep_TypeDef *ep;
Kojto 71:53949e6131f6 308
Kojto 71:53949e6131f6 309 /* Set Rx FIFO size */
Kojto 71:53949e6131f6 310 start = EFM32_MAX( totalRxFifoSize, MIN_EP_FIFO_SIZE_INWORDS );
Kojto 71:53949e6131f6 311 USB->GRXFSIZ = ( start << _USB_GRXFSIZ_RXFDEP_SHIFT ) &
Kojto 71:53949e6131f6 312 _USB_GRXFSIZ_RXFDEP_MASK;
Kojto 71:53949e6131f6 313
Kojto 71:53949e6131f6 314 /* Set Tx EP0 FIFO size */
Kojto 71:53949e6131f6 315 depth = EFM32_MAX( dev->ep[ 0 ].fifoSize, MIN_EP_FIFO_SIZE_INWORDS );
Kojto 71:53949e6131f6 316 USB->GNPTXFSIZ = ( ( depth << _USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_SHIFT ) &
Kojto 71:53949e6131f6 317 _USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_MASK ) |
Kojto 71:53949e6131f6 318 ( ( start << _USB_GNPTXFSIZ_NPTXFSTADDR_SHIFT ) &
Kojto 71:53949e6131f6 319 _USB_GNPTXFSIZ_NPTXFSTADDR_MASK );
Kojto 71:53949e6131f6 320
Kojto 71:53949e6131f6 321
Kojto 71:53949e6131f6 322 /* Set Tx EP FIFO sizes for all IN ep's */
Kojto 71:53949e6131f6 323 for ( j = 1; j <= MAX_NUM_TX_FIFOS; j++ )
Kojto 71:53949e6131f6 324 {
Kojto 71:53949e6131f6 325 for ( i = 1; i <= MAX_NUM_IN_EPS; i++ )
Kojto 71:53949e6131f6 326 {
Kojto 71:53949e6131f6 327 ep = USBD_GetEpFromAddr( USB_SETUP_DIR_MASK | i );
Kojto 71:53949e6131f6 328 if ( ep ) /* Is EP in use ? */
Kojto 71:53949e6131f6 329 {
Kojto 71:53949e6131f6 330 if ( ep->txFifoNum == j ) /* Is it correct FIFO number ? */
Kojto 71:53949e6131f6 331 {
Kojto 71:53949e6131f6 332 start += depth;
Kojto 71:53949e6131f6 333 depth = EFM32_MAX( ep->fifoSize, MIN_EP_FIFO_SIZE_INWORDS );
Kojto 71:53949e6131f6 334 USB_DIEPTXFS[ ep->txFifoNum - 1 ] =
Kojto 71:53949e6131f6 335 ( depth << _USB_DIEPTXF1_INEPNTXFDEP_SHIFT ) |
Kojto 71:53949e6131f6 336 ( start & _USB_DIEPTXF1_INEPNTXFSTADDR_MASK );
Kojto 71:53949e6131f6 337 }
Kojto 71:53949e6131f6 338 }
Kojto 71:53949e6131f6 339 }
Kojto 71:53949e6131f6 340 }
Kojto 71:53949e6131f6 341
Kojto 71:53949e6131f6 342 if ( totalRxFifoSize + totalTxFifoSize > MAX_DEVICE_FIFO_SIZE_INWORDS )
Kojto 71:53949e6131f6 343 return USB_STATUS_ILLEGAL;
Kojto 71:53949e6131f6 344
Kojto 71:53949e6131f6 345 if ( start > MAX_DEVICE_FIFO_SIZE_INWORDS )
Kojto 71:53949e6131f6 346 return USB_STATUS_ILLEGAL;
Kojto 71:53949e6131f6 347
Kojto 71:53949e6131f6 348 /* Flush the FIFO's */
Kojto 71:53949e6131f6 349 USBHAL_FlushTxFifo( 0x10 ); /* All Tx FIFO's */
Kojto 71:53949e6131f6 350 USBHAL_FlushRxFifo(); /* The Rx FIFO */
Kojto 71:53949e6131f6 351
Kojto 71:53949e6131f6 352 return USB_STATUS_OK;
Kojto 71:53949e6131f6 353 }
Kojto 71:53949e6131f6 354
Kojto 71:53949e6131f6 355 void USBDHAL_Disconnect( void )
Kojto 71:53949e6131f6 356 {
Kojto 71:53949e6131f6 357 USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_SFTDISCON;
Kojto 71:53949e6131f6 358 }
Kojto 71:53949e6131f6 359
Kojto 71:53949e6131f6 360 void USBDHAL_AbortEpIn( USBD_Ep_TypeDef *ep )
Kojto 71:53949e6131f6 361 {
Kojto 71:53949e6131f6 362 /* Clear epdis & inepnakeff INT's */
Kojto 71:53949e6131f6 363 USB_DINEPS[ ep->num ].INT |= USB_DIEP_INT_EPDISBLD |
Kojto 71:53949e6131f6 364 USB_DIEP_INT_INEPNAKEFF;
Kojto 71:53949e6131f6 365
Kojto 71:53949e6131f6 366 /* Enable epdis & inepnakeff INT's */
Kojto 71:53949e6131f6 367 USB->DIEPMSK |= USB_DIEPMSK_EPDISBLDMSK | USB_DIEPMSK_INEPNAKEFFMSK;
Kojto 71:53949e6131f6 368 USB_DINEPS[ ep->num ].CTL = ( USB_DINEPS[ ep->num ].CTL &
Kojto 71:53949e6131f6 369 ~DEPCTL_WO_BITMASK ) |
Kojto 71:53949e6131f6 370 USB_DIEP_CTL_SNAK;
Kojto 71:53949e6131f6 371
Kojto 71:53949e6131f6 372 /* Wait for inepnakeff INT */
Kojto 71:53949e6131f6 373 while ( !( USBDHAL_GetInEpInts( ep ) & USB_DIEP_INT_INEPNAKEFF ) ) {}
Kojto 71:53949e6131f6 374 USB_DINEPS[ ep->num ].INT = USB_DIEP_INT_INEPNAKEFF;
Kojto 71:53949e6131f6 375 USB->DIEPMSK &= ~USB_DIEPMSK_INEPNAKEFFMSK;
Kojto 71:53949e6131f6 376
Kojto 71:53949e6131f6 377 DEBUG_USB_INT_LO_PUTCHAR( '.' );
Kojto 71:53949e6131f6 378
Kojto 71:53949e6131f6 379 USBDHAL_SetEPDISNAK( ep );
Kojto 71:53949e6131f6 380 /* Wait for epdis INT */
Kojto 71:53949e6131f6 381 while ( !( USBDHAL_GetInEpInts( ep ) & USB_DIEP_INT_EPDISBLD ) ) {}
Kojto 71:53949e6131f6 382 USB_DINEPS[ ep->num ].INT = USB_DIEP_INT_EPDISBLD;
Kojto 71:53949e6131f6 383 USB->DIEPMSK &= ~USB_DIEPMSK_EPDISBLDMSK;
Kojto 71:53949e6131f6 384 USBHAL_FlushTxFifo( ep->txFifoNum );
Kojto 71:53949e6131f6 385
Kojto 71:53949e6131f6 386 /* Clear any interrupts generated by the abort sequence. */
Kojto 71:53949e6131f6 387 NVIC_ClearPendingIRQ( USB_IRQn );
Kojto 71:53949e6131f6 388
Kojto 71:53949e6131f6 389 DEBUG_USB_INT_LO_PUTCHAR( '.' );
Kojto 71:53949e6131f6 390 }
Kojto 71:53949e6131f6 391
Kojto 71:53949e6131f6 392 void USBDHAL_AbortEpOut( USBD_Ep_TypeDef *ep )
Kojto 71:53949e6131f6 393 {
Kojto 71:53949e6131f6 394 int cnt;
Kojto 71:53949e6131f6 395
Kojto 71:53949e6131f6 396 /* Clear epdis INT's */
Kojto 71:53949e6131f6 397 USB_DOUTEPS[ ep->num ].INT |= USB_DOEP_INT_EPDISBLD;
Kojto 71:53949e6131f6 398
Kojto 71:53949e6131f6 399 /* Clear Global OUT NAK if already set */
Kojto 71:53949e6131f6 400 USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_CGOUTNAK;
Kojto 71:53949e6131f6 401 USB->GINTMSK |= USB_GINTMSK_GOUTNAKEFFMSK; /* Enable GOUTNAKEFF int */
Kojto 71:53949e6131f6 402
Kojto 71:53949e6131f6 403 /* Set Global OUT NAK */
Kojto 71:53949e6131f6 404 USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_SGOUTNAK;
Kojto 71:53949e6131f6 405
Kojto 71:53949e6131f6 406 /* Wait for goutnakeff */
Kojto 71:53949e6131f6 407 cnt = EPABORT_BREAK_LOOP_COUNT;
Kojto 71:53949e6131f6 408 while ( !( USB->GINTSTS & USB_GINTSTS_GOUTNAKEFF ) && cnt )
Kojto 71:53949e6131f6 409 {
Kojto 71:53949e6131f6 410 cnt--;
Kojto 71:53949e6131f6 411 }
Kojto 71:53949e6131f6 412
Kojto 71:53949e6131f6 413 USB->GINTMSK &= ~USB_GINTMSK_GOUTNAKEFFMSK; /* Disable GOUTNAKEFF int */
Kojto 71:53949e6131f6 414 USB->DOEPMSK |= USB_DOEPMSK_EPDISBLDMSK; /* Enable EPDIS interrupt */
Kojto 71:53949e6131f6 415
Kojto 71:53949e6131f6 416 DEBUG_USB_INT_LO_PUTCHAR( ',' );
Kojto 71:53949e6131f6 417
Kojto 71:53949e6131f6 418 USBDHAL_SetEPDISNAK( ep ); /* Disable ep */
Kojto 71:53949e6131f6 419
Kojto 71:53949e6131f6 420 /* Wait for epdis INT */
Kojto 71:53949e6131f6 421 cnt = EPABORT_BREAK_LOOP_COUNT;
Kojto 71:53949e6131f6 422 while ( !( USBDHAL_GetOutEpInts( ep ) & USB_DOEP_INT_EPDISBLD ) && cnt )
Kojto 71:53949e6131f6 423 {
Kojto 71:53949e6131f6 424 cnt--;
Kojto 71:53949e6131f6 425 }
Kojto 71:53949e6131f6 426
Kojto 71:53949e6131f6 427 USB_DOUTEPS[ ep->num ].INT = USB_DOEP_INT_EPDISBLD;
Kojto 71:53949e6131f6 428 USB->DOEPMSK &= ~USB_DOEPMSK_EPDISBLDMSK; /* Disable EPDIS interrupt */
Kojto 71:53949e6131f6 429
Kojto 71:53949e6131f6 430 /* Clear Global OUT NAK */
Kojto 71:53949e6131f6 431 USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_CGOUTNAK;
Kojto 71:53949e6131f6 432
Kojto 71:53949e6131f6 433 /* Clear any interrupts generated by the abort sequence. */
Kojto 71:53949e6131f6 434 NVIC_ClearPendingIRQ( USB_IRQn );
Kojto 71:53949e6131f6 435
Kojto 71:53949e6131f6 436 DEBUG_USB_INT_LO_PUTCHAR( ',' );
Kojto 71:53949e6131f6 437 }
Kojto 71:53949e6131f6 438
Kojto 71:53949e6131f6 439 void USBDHAL_AbortAllEps( void )
Kojto 71:53949e6131f6 440 {
Kojto 71:53949e6131f6 441 int i, cnt;
Kojto 71:53949e6131f6 442 USBD_Ep_TypeDef *ep;
Kojto 71:53949e6131f6 443 uint16_t im, om, inmask=0, outmask=0;
Kojto 71:53949e6131f6 444
Kojto 71:53949e6131f6 445 /* Clear epdis & inepnakeff INT's */
Kojto 71:53949e6131f6 446 for ( i = 1; i <= NUM_EP_USED; i++ )
Kojto 71:53949e6131f6 447 {
Kojto 71:53949e6131f6 448 ep = &dev->ep[i];
Kojto 71:53949e6131f6 449 if ( ep->state != D_EP_IDLE )
Kojto 71:53949e6131f6 450 {
Kojto 71:53949e6131f6 451 if ( ep->in )
Kojto 71:53949e6131f6 452 {
Kojto 71:53949e6131f6 453 inmask |= ep->mask;
Kojto 71:53949e6131f6 454 USB_DINEPS[ ep->num ].INT |= USB_DIEP_INT_EPDISBLD |
Kojto 71:53949e6131f6 455 USB_DIEP_INT_INEPNAKEFF;
Kojto 71:53949e6131f6 456 }
Kojto 71:53949e6131f6 457 else
Kojto 71:53949e6131f6 458 {
Kojto 71:53949e6131f6 459 outmask |= ep->mask;
Kojto 71:53949e6131f6 460 USB_DOUTEPS[ ep->num ].INT |= USB_DOEP_INT_EPDISBLD;
Kojto 71:53949e6131f6 461 }
Kojto 71:53949e6131f6 462 }
Kojto 71:53949e6131f6 463 }
Kojto 71:53949e6131f6 464
Kojto 71:53949e6131f6 465 if ( inmask )
Kojto 71:53949e6131f6 466 {
Kojto 71:53949e6131f6 467 /* Enable epdis & inepnakeff INT's */
Kojto 71:53949e6131f6 468 USB->DIEPMSK |= USB_DIEPMSK_EPDISBLDMSK | USB_DIEPMSK_INEPNAKEFFMSK;
Kojto 71:53949e6131f6 469
Kojto 71:53949e6131f6 470 /* Set NAK on all IN ep's */
Kojto 71:53949e6131f6 471 im = inmask;
Kojto 71:53949e6131f6 472 for ( i = 1; i <= NUM_EP_USED; i++ )
Kojto 71:53949e6131f6 473 {
Kojto 71:53949e6131f6 474 ep = &dev->ep[i];
Kojto 71:53949e6131f6 475 if ( im & ep->mask )
Kojto 71:53949e6131f6 476 {
Kojto 71:53949e6131f6 477 USB_DINEPS[ ep->num ].CTL = ( USB_DINEPS[ ep->num ].CTL &
Kojto 71:53949e6131f6 478 ~DEPCTL_WO_BITMASK ) |
Kojto 71:53949e6131f6 479 USB_DIEP_CTL_SNAK;
Kojto 71:53949e6131f6 480 }
Kojto 71:53949e6131f6 481 }
Kojto 71:53949e6131f6 482 }
Kojto 71:53949e6131f6 483
Kojto 71:53949e6131f6 484 if ( outmask )
Kojto 71:53949e6131f6 485 {
Kojto 71:53949e6131f6 486 /* Clear Global OUT NAK if already set */
Kojto 71:53949e6131f6 487 USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_CGOUTNAK;
Kojto 71:53949e6131f6 488
Kojto 71:53949e6131f6 489 USB->GINTMSK |= USB_GINTMSK_GOUTNAKEFFMSK; /* Enable GOUTNAKEFF int */
Kojto 71:53949e6131f6 490
Kojto 71:53949e6131f6 491 /* Set Global OUT NAK */
Kojto 71:53949e6131f6 492 USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_SGOUTNAK;
Kojto 71:53949e6131f6 493
Kojto 71:53949e6131f6 494 /* Wait for goutnakeff */
Kojto 71:53949e6131f6 495 cnt = EPABORT_BREAK_LOOP_COUNT;
Kojto 71:53949e6131f6 496 while ( !( USB->GINTSTS & USB_GINTSTS_GOUTNAKEFF ) && cnt )
Kojto 71:53949e6131f6 497 {
Kojto 71:53949e6131f6 498 cnt--;
Kojto 71:53949e6131f6 499 }
Kojto 71:53949e6131f6 500 USB->GINTMSK &= ~USB_GINTMSK_GOUTNAKEFFMSK; /* Disable GOUTNAKEFF int */
Kojto 71:53949e6131f6 501 USB->DOEPMSK |= USB_DOEPMSK_EPDISBLDMSK; /* Enable EPDIS interrupt */
Kojto 71:53949e6131f6 502 }
Kojto 71:53949e6131f6 503
Kojto 71:53949e6131f6 504 if ( inmask )
Kojto 71:53949e6131f6 505 {
Kojto 71:53949e6131f6 506 /* Wait for inepnakeff INT on all IN ep's */
Kojto 71:53949e6131f6 507 im = inmask;
Kojto 71:53949e6131f6 508 cnt = EPABORT_BREAK_LOOP_COUNT;
Kojto 71:53949e6131f6 509 do
Kojto 71:53949e6131f6 510 {
Kojto 71:53949e6131f6 511 for ( i = 1; i <= NUM_EP_USED; i++ )
Kojto 71:53949e6131f6 512 {
Kojto 71:53949e6131f6 513 ep = &dev->ep[i];
Kojto 71:53949e6131f6 514 if ( im & ep->mask )
Kojto 71:53949e6131f6 515 {
Kojto 71:53949e6131f6 516 if ( USBDHAL_GetInEpInts( ep ) & USB_DIEP_INT_INEPNAKEFF )
Kojto 71:53949e6131f6 517 {
Kojto 71:53949e6131f6 518 USB_DINEPS[ ep->num ].INT = USB_DIEP_INT_INEPNAKEFF;
Kojto 71:53949e6131f6 519 im &= ~ep->mask;
Kojto 71:53949e6131f6 520 }
Kojto 71:53949e6131f6 521 }
Kojto 71:53949e6131f6 522 }
Kojto 71:53949e6131f6 523 cnt--;
Kojto 71:53949e6131f6 524 } while ( im && cnt );
Kojto 71:53949e6131f6 525 USB->DIEPMSK &= ~USB_DIEPMSK_INEPNAKEFFMSK;
Kojto 71:53949e6131f6 526 }
Kojto 71:53949e6131f6 527
Kojto 71:53949e6131f6 528 DEBUG_USB_INT_LO_PUTCHAR( '\'' );
Kojto 71:53949e6131f6 529
Kojto 71:53949e6131f6 530 /* Disable ep's */
Kojto 71:53949e6131f6 531 for ( i = 1; i <= NUM_EP_USED; i++ )
Kojto 71:53949e6131f6 532 {
Kojto 71:53949e6131f6 533 ep = &dev->ep[i];
Kojto 71:53949e6131f6 534 if ( ep->state != D_EP_IDLE )
Kojto 71:53949e6131f6 535 {
Kojto 71:53949e6131f6 536 USBDHAL_SetEPDISNAK( ep );
Kojto 71:53949e6131f6 537 }
Kojto 71:53949e6131f6 538 }
Kojto 71:53949e6131f6 539
Kojto 71:53949e6131f6 540 /* Wait for epdis INT */
Kojto 71:53949e6131f6 541 im = inmask;
Kojto 71:53949e6131f6 542 om = outmask;
Kojto 71:53949e6131f6 543 cnt = EPABORT_BREAK_LOOP_COUNT;
Kojto 71:53949e6131f6 544 do
Kojto 71:53949e6131f6 545 {
Kojto 71:53949e6131f6 546 for ( i = 1; i <= NUM_EP_USED; i++ )
Kojto 71:53949e6131f6 547 {
Kojto 71:53949e6131f6 548 ep = &dev->ep[i];
Kojto 71:53949e6131f6 549 if ( ep->in && ( im & ep->mask ) )
Kojto 71:53949e6131f6 550 {
Kojto 71:53949e6131f6 551 if ( USBDHAL_GetInEpInts( ep ) & USB_DIEP_INT_EPDISBLD )
Kojto 71:53949e6131f6 552 {
Kojto 71:53949e6131f6 553 USB_DINEPS[ ep->num ].INT = USB_DIEP_INT_EPDISBLD;
Kojto 71:53949e6131f6 554 im &= ~ep->mask;
Kojto 71:53949e6131f6 555 }
Kojto 71:53949e6131f6 556 }
Kojto 71:53949e6131f6 557
Kojto 71:53949e6131f6 558 if ( !ep->in && ( om & ep->mask ) )
Kojto 71:53949e6131f6 559 {
Kojto 71:53949e6131f6 560 if ( USBDHAL_GetOutEpInts( ep ) & USB_DOEP_INT_EPDISBLD )
Kojto 71:53949e6131f6 561 {
Kojto 71:53949e6131f6 562 USB_DOUTEPS[ ep->num ].INT = USB_DOEP_INT_EPDISBLD;
Kojto 71:53949e6131f6 563 om &= ~ep->mask;
Kojto 71:53949e6131f6 564 }
Kojto 71:53949e6131f6 565 }
Kojto 71:53949e6131f6 566 }
Kojto 71:53949e6131f6 567 cnt--;
Kojto 71:53949e6131f6 568 } while ( ( im || om ) && cnt );
Kojto 71:53949e6131f6 569
Kojto 71:53949e6131f6 570 if ( inmask )
Kojto 71:53949e6131f6 571 {
Kojto 71:53949e6131f6 572 USB->DIEPMSK &= ~USB_DIEPMSK_EPDISBLDMSK; /* Disable EPDIS interrupt */
Kojto 71:53949e6131f6 573 USBHAL_FlushTxFifo( 0x10 ); /* Flush all Tx FIFO's */
Kojto 71:53949e6131f6 574 }
Kojto 71:53949e6131f6 575
Kojto 71:53949e6131f6 576 if ( outmask )
Kojto 71:53949e6131f6 577 {
Kojto 71:53949e6131f6 578 USB->DOEPMSK &= ~USB_DOEPMSK_EPDISBLDMSK; /* Disable EPDIS interrupt */
Kojto 71:53949e6131f6 579 /* Clear Global OUT NAK */
Kojto 71:53949e6131f6 580 USB->DCTL = ( USB->DCTL & ~DCTL_WO_BITMASK ) | USB_DCTL_CGOUTNAK;
Kojto 71:53949e6131f6 581 }
Kojto 71:53949e6131f6 582
Kojto 71:53949e6131f6 583 DEBUG_USB_INT_LO_PUTCHAR( '\'' );
Kojto 71:53949e6131f6 584 }
Kojto 71:53949e6131f6 585
Kojto 71:53949e6131f6 586 void USBDHAL_AbortAllTransfers( USB_Status_TypeDef reason )
Kojto 71:53949e6131f6 587 {
Kojto 71:53949e6131f6 588 int i;
Kojto 71:53949e6131f6 589 USBD_Ep_TypeDef *ep;
Kojto 71:53949e6131f6 590 USB_XferCompleteCb_TypeDef callback;
Kojto 71:53949e6131f6 591
Kojto 71:53949e6131f6 592 if ( reason != USB_STATUS_DEVICE_RESET )
Kojto 71:53949e6131f6 593 {
Kojto 71:53949e6131f6 594 USBDHAL_AbortAllEps();
Kojto 71:53949e6131f6 595 }
Kojto 71:53949e6131f6 596
Kojto 71:53949e6131f6 597 for ( i = 1; i <= NUM_EP_USED; i++ )
Kojto 71:53949e6131f6 598 {
Kojto 71:53949e6131f6 599 ep = &(dev->ep[i]);
Kojto 71:53949e6131f6 600 if ( ep->state != D_EP_IDLE )
Kojto 71:53949e6131f6 601 {
Kojto 71:53949e6131f6 602 ep->state = D_EP_IDLE;
Kojto 71:53949e6131f6 603 if ( ep->xferCompleteCb )
Kojto 71:53949e6131f6 604 {
Kojto 71:53949e6131f6 605 callback = ep->xferCompleteCb;
Kojto 71:53949e6131f6 606 ep->xferCompleteCb = NULL;
Kojto 71:53949e6131f6 607
Kojto 71:53949e6131f6 608 if ( ( dev->lastState == USBD_STATE_CONFIGURED ) &&
Kojto 71:53949e6131f6 609 ( dev->state == USBD_STATE_ADDRESSED ) )
Kojto 71:53949e6131f6 610 {
Kojto 71:53949e6131f6 611 USBDHAL_DeactivateEp( ep );
Kojto 71:53949e6131f6 612 }
Kojto 71:53949e6131f6 613
Kojto 71:53949e6131f6 614 DEBUG_TRACE_ABORT( reason );
Kojto 71:53949e6131f6 615 callback( reason, ep->xferred, ep->remaining );
Kojto 71:53949e6131f6 616 }
Kojto 71:53949e6131f6 617 }
Kojto 71:53949e6131f6 618 }
Kojto 71:53949e6131f6 619
Kojto 71:53949e6131f6 620 /* Clear any interrupts generated by the abort sequence. */
Kojto 71:53949e6131f6 621 NVIC_ClearPendingIRQ( USB_IRQn );
Kojto 71:53949e6131f6 622 }
Kojto 71:53949e6131f6 623 #endif /* defined( USB_DEVICE ) */
Kojto 71:53949e6131f6 624
Kojto 71:53949e6131f6 625 #if defined( USB_HOST )
Kojto 71:53949e6131f6 626 USB_Status_TypeDef USBHHAL_CoreInit( uint32_t rxFifoSize,
Kojto 71:53949e6131f6 627 uint32_t nptxFifoSize,
Kojto 71:53949e6131f6 628 uint32_t ptxFifoSize )
Kojto 71:53949e6131f6 629 {
Kojto 71:53949e6131f6 630 uint8_t i;
Kojto 71:53949e6131f6 631
Kojto 71:53949e6131f6 632 rxFifoSize /= 4; /* Convert from byte count to word count. */
Kojto 71:53949e6131f6 633 nptxFifoSize /= 4;
Kojto 71:53949e6131f6 634 ptxFifoSize /= 4;
Kojto 71:53949e6131f6 635
Kojto 71:53949e6131f6 636 CMU_ClockEnable( cmuClock_GPIO, true );
Kojto 71:53949e6131f6 637 GPIO_PinModeSet( gpioPortF, 5, gpioModePushPull, 0 ); /* Enable VBUSEN pin */
Kojto 71:53949e6131f6 638
Kojto 71:53949e6131f6 639 #if ( USB_VBUSOVRCUR_PORT != USB_VBUSOVRCUR_PORT_NONE )
Kojto 71:53949e6131f6 640 /* Enable VBUS overcurrent flag pin. */
Kojto 71:53949e6131f6 641 GPIO_PinModeSet( USB_VBUSOVRCUR_PORT, USB_VBUSOVRCUR_PIN, gpioModeInput, 0 );
Kojto 71:53949e6131f6 642 #endif
Kojto 71:53949e6131f6 643
Kojto 71:53949e6131f6 644 USB->ROUTE = USB_ROUTE_PHYPEN | USB_ROUTE_VBUSENPEN; /* Enable PHY pins. */
Kojto 71:53949e6131f6 645 USBHAL_CoreReset(); /* Reset USB core */
Kojto 71:53949e6131f6 646
Kojto 71:53949e6131f6 647 /* Force Host Mode */
Kojto 71:53949e6131f6 648 USB->GUSBCFG = ( USB->GUSBCFG &
Kojto 71:53949e6131f6 649 ~(GUSBCFG_WO_BITMASK | USB_GUSBCFG_FORCEDEVMODE ) ) |
Kojto 71:53949e6131f6 650 USB_GUSBCFG_FORCEHSTMODE;
Kojto 71:53949e6131f6 651
Kojto 71:53949e6131f6 652 INT_Enable();
Kojto 71:53949e6131f6 653 USBTIMER_DelayMs( 100 );
Kojto 71:53949e6131f6 654 INT_Disable();
Kojto 71:53949e6131f6 655
Kojto 71:53949e6131f6 656 /* Set 48 MHz PHY clock, FS/LS mode */
Kojto 71:53949e6131f6 657 USB->HCFG = ( USB->HCFG & ~_USB_HCFG_FSLSPCLKSEL_MASK ) |
Kojto 71:53949e6131f6 658 ( 1 << _USB_HCFG_FSLSPCLKSEL_SHIFT ) |
Kojto 71:53949e6131f6 659 ( USB_HCFG_FSLSSUPP );
Kojto 71:53949e6131f6 660
Kojto 71:53949e6131f6 661 USB->GAHBCFG = ( USB->GAHBCFG & ~_USB_GAHBCFG_HBSTLEN_MASK ) |
Kojto 71:53949e6131f6 662 USB_GAHBCFG_DMAEN | USB_GAHBCFG_HBSTLEN_INCR;
Kojto 71:53949e6131f6 663
Kojto 71:53949e6131f6 664 /* Set Rx FIFO size */
Kojto 71:53949e6131f6 665 USB->GRXFSIZ = ( rxFifoSize << _USB_GRXFSIZ_RXFDEP_SHIFT ) &
Kojto 71:53949e6131f6 666 _USB_GRXFSIZ_RXFDEP_MASK;
Kojto 71:53949e6131f6 667
Kojto 71:53949e6131f6 668 /* Set Tx FIFO sizes */
Kojto 71:53949e6131f6 669 USB->GNPTXFSIZ = ( ( nptxFifoSize <<
Kojto 71:53949e6131f6 670 _USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_SHIFT ) &
Kojto 71:53949e6131f6 671 _USB_GNPTXFSIZ_NPTXFINEPTXF0DEP_MASK ) |
Kojto 71:53949e6131f6 672 ( ( rxFifoSize <<
Kojto 71:53949e6131f6 673 _USB_GNPTXFSIZ_NPTXFSTADDR_SHIFT ) &
Kojto 71:53949e6131f6 674 _USB_GNPTXFSIZ_NPTXFSTADDR_MASK );
Kojto 71:53949e6131f6 675
Kojto 71:53949e6131f6 676 USB->HPTXFSIZ = ( ( ptxFifoSize << _USB_HPTXFSIZ_PTXFSIZE_SHIFT ) &
Kojto 71:53949e6131f6 677 _USB_HPTXFSIZ_PTXFSIZE_MASK ) |
Kojto 71:53949e6131f6 678 ( ( ( rxFifoSize + nptxFifoSize )
Kojto 71:53949e6131f6 679 << _USB_HPTXFSIZ_PTXFSTADDR_SHIFT ) &
Kojto 71:53949e6131f6 680 _USB_HPTXFSIZ_PTXFSTADDR_MASK );
Kojto 71:53949e6131f6 681
Kojto 71:53949e6131f6 682 /* Flush Tx and Rx FIFO's */
Kojto 71:53949e6131f6 683 USBHAL_FlushTxFifo( 0x10 );
Kojto 71:53949e6131f6 684 USBHAL_FlushRxFifo();
Kojto 71:53949e6131f6 685
Kojto 71:53949e6131f6 686 for ( i = 0; i < MAX_NUM_HOSTCHANNELS; i++ )
Kojto 71:53949e6131f6 687 {
Kojto 71:53949e6131f6 688 USB->HC[ i ].CHAR = USB_HC_CHAR_CHDIS; /* Disable channel */
Kojto 71:53949e6131f6 689 USB->HC[ i ].INT = 0xFFFFFFFF; /* Clear pending interrupts */
Kojto 71:53949e6131f6 690 }
Kojto 71:53949e6131f6 691
Kojto 71:53949e6131f6 692 /* Enable and halt all channels */
Kojto 71:53949e6131f6 693 for ( i = 0; i < MAX_NUM_HOSTCHANNELS; i++ )
Kojto 71:53949e6131f6 694 {
Kojto 71:53949e6131f6 695 USB->HC[ i ].CHAR |= USB_HC_CHAR_CHDIS | USB_HC_CHAR_CHENA;
Kojto 71:53949e6131f6 696 do
Kojto 71:53949e6131f6 697 {
Kojto 71:53949e6131f6 698 __NOP(); __NOP(); __NOP(); __NOP(); __NOP(); __NOP();
Kojto 71:53949e6131f6 699 }
Kojto 71:53949e6131f6 700 while ( USB->HC[ i ].CHAR & USB_HC_CHAR_CHENA );
Kojto 71:53949e6131f6 701 }
Kojto 71:53949e6131f6 702
Kojto 71:53949e6131f6 703 /* Disable all interrupts */
Kojto 71:53949e6131f6 704 for ( i = 0; i < MAX_NUM_HOSTCHANNELS; i++ )
Kojto 71:53949e6131f6 705 {
Kojto 71:53949e6131f6 706 USB->HC[ i ].INTMSK = 0;
Kojto 71:53949e6131f6 707 }
Kojto 71:53949e6131f6 708
Kojto 71:53949e6131f6 709 USB->HAINTMSK = 0;
Kojto 71:53949e6131f6 710
Kojto 71:53949e6131f6 711 return USB_STATUS_OK;
Kojto 71:53949e6131f6 712 }
Kojto 71:53949e6131f6 713
Kojto 71:53949e6131f6 714 void USBHHAL_HCHalt( int hcnum, uint32_t hcchar )
Kojto 71:53949e6131f6 715 {
Kojto 71:53949e6131f6 716 hcchar |= USB_HC_CHAR_CHENA | USB_HC_CHAR_CHDIS;
Kojto 71:53949e6131f6 717 USB->HC[ hcnum ].CHAR = hcchar;
Kojto 71:53949e6131f6 718 }
Kojto 71:53949e6131f6 719
Kojto 71:53949e6131f6 720 void USBHHAL_HCInit( int hcnum )
Kojto 71:53949e6131f6 721 {
Kojto 71:53949e6131f6 722 USBH_Ep_TypeDef *ep;
Kojto 71:53949e6131f6 723
Kojto 71:53949e6131f6 724 ep = hcs[ hcnum ].ep;
Kojto 71:53949e6131f6 725 USB->HC[ hcnum ].INT = 0xFFFFFFFF; /* Clear all interrupt flags */
Kojto 71:53949e6131f6 726
Kojto 71:53949e6131f6 727 switch ( ep->type ) /* Enable host channel int. types */
Kojto 71:53949e6131f6 728 {
Kojto 71:53949e6131f6 729 case USB_EPTYPE_CTRL:
Kojto 71:53949e6131f6 730 case USB_EPTYPE_BULK:
Kojto 71:53949e6131f6 731 case USB_EPTYPE_INTR:
Kojto 71:53949e6131f6 732 USB->HC[ hcnum ].INTMSK = USB_HC_INT_CHHLTD;
Kojto 71:53949e6131f6 733 break;
Kojto 71:53949e6131f6 734 }
Kojto 71:53949e6131f6 735
Kojto 71:53949e6131f6 736 hcs[ hcnum ].errorCnt = 0;
Kojto 71:53949e6131f6 737
Kojto 71:53949e6131f6 738 USB->HAINTMSK |= 1 << hcnum; /* Enable host channel interrupt */
Kojto 71:53949e6131f6 739
Kojto 71:53949e6131f6 740 USB->HC[ hcnum ].CHAR = /* Program HCCHAR register */
Kojto 71:53949e6131f6 741 ( ep->parentDevice->addr << _USB_HC_CHAR_DEVADDR_SHIFT ) |
Kojto 71:53949e6131f6 742 ( ( ep->addr & USB_EPNUM_MASK ) << _USB_HC_CHAR_EPNUM_SHIFT ) |
Kojto 71:53949e6131f6 743 ( ep->type << _USB_HC_CHAR_EPTYPE_SHIFT ) |
Kojto 71:53949e6131f6 744 ( ep->packetSize << _USB_HC_CHAR_MPS_SHIFT ) |
Kojto 71:53949e6131f6 745 ( ep->in ? USB_HC_CHAR_EPDIR : 0 ) |
Kojto 71:53949e6131f6 746 ( ep->parentDevice->speed ==
Kojto 71:53949e6131f6 747 HPRT_L_SPEED >> _USB_HPRT_PRTSPD_SHIFT
Kojto 71:53949e6131f6 748 ? USB_HC_CHAR_LSPDDEV : 0 );
Kojto 71:53949e6131f6 749 }
Kojto 71:53949e6131f6 750
Kojto 71:53949e6131f6 751 void USBHHAL_HCStart( int hcnum )
Kojto 71:53949e6131f6 752 {
Kojto 71:53949e6131f6 753 USBH_Hc_TypeDef *hc;
Kojto 71:53949e6131f6 754 uint16_t packets, len;
Kojto 71:53949e6131f6 755
Kojto 71:53949e6131f6 756 hc = &hcs[ hcnum ];
Kojto 71:53949e6131f6 757 hc->status = 0;
Kojto 71:53949e6131f6 758 hc->idle = false;
Kojto 71:53949e6131f6 759
Kojto 71:53949e6131f6 760 if ( hc->remaining > 0 )
Kojto 71:53949e6131f6 761 {
Kojto 71:53949e6131f6 762 packets = ( hc->remaining + hc->ep->packetSize - 1 ) / hc->ep->packetSize;
Kojto 71:53949e6131f6 763 }
Kojto 71:53949e6131f6 764 else
Kojto 71:53949e6131f6 765 {
Kojto 71:53949e6131f6 766 packets = 1;
Kojto 71:53949e6131f6 767 }
Kojto 71:53949e6131f6 768
Kojto 71:53949e6131f6 769 if ( hc->ep->in )
Kojto 71:53949e6131f6 770 {
Kojto 71:53949e6131f6 771 len = packets * hc->ep->packetSize;
Kojto 71:53949e6131f6 772 }
Kojto 71:53949e6131f6 773 else
Kojto 71:53949e6131f6 774 {
Kojto 71:53949e6131f6 775 len = hc->remaining;
Kojto 71:53949e6131f6 776 }
Kojto 71:53949e6131f6 777
Kojto 71:53949e6131f6 778 /* Initialize the HCTSIZn register */
Kojto 71:53949e6131f6 779 hc->hwXferSize = len;
Kojto 71:53949e6131f6 780 USB->HC[ hcnum ].TSIZ =
Kojto 71:53949e6131f6 781 ( ( len << _USB_HC_TSIZ_XFERSIZE_SHIFT ) &
Kojto 71:53949e6131f6 782 _USB_HC_TSIZ_XFERSIZE_MASK ) |
Kojto 71:53949e6131f6 783 ( ( packets << _USB_HC_TSIZ_PKTCNT_SHIFT ) &
Kojto 71:53949e6131f6 784 _USB_HC_TSIZ_PKTCNT_MASK ) |
Kojto 71:53949e6131f6 785 ( ( hc->ep->toggle << _USB_HC_TSIZ_PID_SHIFT ) &
Kojto 71:53949e6131f6 786 _USB_HC_TSIZ_PID_MASK );
Kojto 71:53949e6131f6 787
Kojto 71:53949e6131f6 788 USB->HC[ hcnum ].DMAADDR = (uint32_t)hc->buf;
Kojto 71:53949e6131f6 789
Kojto 71:53949e6131f6 790 USBHHAL_HCActivate( hcnum,
Kojto 71:53949e6131f6 791 USB->HC[ hcnum ].CHAR,
Kojto 71:53949e6131f6 792 hc->ep->type == USB_EPTYPE_INTR );
Kojto 71:53949e6131f6 793 }
Kojto 71:53949e6131f6 794 #endif /* defined( USB_HOST ) */
Kojto 71:53949e6131f6 795
Kojto 71:53949e6131f6 796 /** @endcond */
Kojto 71:53949e6131f6 797
Kojto 71:53949e6131f6 798 #endif /* defined( USB_DEVICE ) || defined( USB_HOST ) */
Kojto 71:53949e6131f6 799 #endif /* defined( USB_PRESENT ) && ( USB_COUNT == 1 ) */