USB device stack

Dependents:   USBMSD_step1 USBMSD_step1_5 picossd_step1_2cs

Committer:
muraguchi
Date:
Wed Sep 15 16:31:51 2021 +0000
Revision:
73:72808bd55ce2
Parent:
71:53949e6131f6
AirioBase + 2 chip PicoSSD board

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 ) */