max4146x_comp

Dependencies:   MAX14690

Committer:
sdivarci
Date:
Sun Oct 25 20:10:02 2020 +0000
Revision:
0:0061165683ee
sdivarci

Who changed what in which revision?

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