USBDevice with MAX32620HSP platform support

Fork of USBDevice by mbed official

Committer:
mbed_official
Date:
Thu Aug 13 15:46:06 2015 +0100
Revision:
59:2af474687369
Synchronized with git revision 376d6a73e345b728a788041adb166b08cd8d2b95

Full URL: https://github.com/mbedmicro/mbed/commit/376d6a73e345b728a788041adb166b08cd8d2b95/

Silicon Labs - Add support for USBDevice

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 59:2af474687369 1 /**************************************************************************//**
mbed_official 59:2af474687369 2 * @file em_usbdint.c
mbed_official 59:2af474687369 3 * @brief USB protocol stack library, USB device peripheral interrupt handlers.
mbed_official 59:2af474687369 4 * @version 3.20.14
mbed_official 59:2af474687369 5 ******************************************************************************
mbed_official 59:2af474687369 6 * @section License
mbed_official 59:2af474687369 7 * <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b>
mbed_official 59:2af474687369 8 *******************************************************************************
mbed_official 59:2af474687369 9 *
mbed_official 59:2af474687369 10 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 59:2af474687369 11 * you may not use this file except in compliance with the License.
mbed_official 59:2af474687369 12 * You may obtain a copy of the License at
mbed_official 59:2af474687369 13 *
mbed_official 59:2af474687369 14 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 59:2af474687369 15 *
mbed_official 59:2af474687369 16 * Unless required by applicable law or agreed to in writing, software
mbed_official 59:2af474687369 17 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 59:2af474687369 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 59:2af474687369 19 * See the License for the specific language governing permissions and
mbed_official 59:2af474687369 20 * limitations under the License.
mbed_official 59:2af474687369 21 *
mbed_official 59:2af474687369 22 ******************************************************************************/
mbed_official 59:2af474687369 23
mbed_official 59:2af474687369 24 #include "em_device.h"
mbed_official 59:2af474687369 25 #if defined( USB_PRESENT ) && ( USB_COUNT == 1 )
mbed_official 59:2af474687369 26 #include "em_usb.h"
mbed_official 59:2af474687369 27 #if defined( USB_DEVICE )
mbed_official 59:2af474687369 28
mbed_official 59:2af474687369 29 #include "em_cmu.h"
mbed_official 59:2af474687369 30 #include "em_usbtypes.h"
mbed_official 59:2af474687369 31 #include "em_usbhal.h"
mbed_official 59:2af474687369 32 #include "em_usbd.h"
mbed_official 59:2af474687369 33
mbed_official 59:2af474687369 34 #ifdef __MBED__
mbed_official 59:2af474687369 35 extern void usbhal_allow_em2(bool em2_allow);
mbed_official 59:2af474687369 36 #endif
mbed_official 59:2af474687369 37
mbed_official 59:2af474687369 38 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */
mbed_official 59:2af474687369 39
mbed_official 59:2af474687369 40 #define HANDLE_INT( x ) if ( status & x ) { Handle_##x(); status &= ~x; }
mbed_official 59:2af474687369 41
mbed_official 59:2af474687369 42 static void Handle_USB_GINTSTS_ENUMDONE ( void );
mbed_official 59:2af474687369 43 static void Handle_USB_GINTSTS_IEPINT ( void );
mbed_official 59:2af474687369 44 static void Handle_USB_GINTSTS_OEPINT ( void );
mbed_official 59:2af474687369 45 static void Handle_USB_GINTSTS_RESETDET ( void );
mbed_official 59:2af474687369 46 static void Handle_USB_GINTSTS_SOF ( void );
mbed_official 59:2af474687369 47 static void Handle_USB_GINTSTS_USBRST ( void );
mbed_official 59:2af474687369 48 static void Handle_USB_GINTSTS_USBSUSP ( void );
mbed_official 59:2af474687369 49 static void Handle_USB_GINTSTS_WKUPINT ( void );
mbed_official 59:2af474687369 50 #if defined( USB_DOEP0INT_STUPPKTRCVD )
mbed_official 59:2af474687369 51 static void HandleOutEpIntr( uint32_t status, USBD_Ep_TypeDef *ep );
mbed_official 59:2af474687369 52 #else
mbed_official 59:2af474687369 53 static void ProcessSetup ( void );
mbed_official 59:2af474687369 54 static void ProcessOepData ( USBD_Ep_TypeDef *ep );
mbed_official 59:2af474687369 55 #endif
mbed_official 59:2af474687369 56
mbed_official 59:2af474687369 57 #if ( USB_PWRSAVE_MODE )
mbed_official 59:2af474687369 58 /* Variables and prototypes for USB powerdown (suspend) functionality. */
mbed_official 59:2af474687369 59 static bool UsbPowerDown( void );
mbed_official 59:2af474687369 60 static bool UsbPowerUp( void );
mbed_official 59:2af474687369 61
mbed_official 59:2af474687369 62 volatile bool USBD_poweredDown = false;
mbed_official 59:2af474687369 63
mbed_official 59:2af474687369 64 /* Storage for backing up USB core registers. */
mbed_official 59:2af474687369 65 static uint32_t x_USB_GINTMSK;
mbed_official 59:2af474687369 66 #if defined(_USB_GOTGCTL_MASK)
mbed_official 59:2af474687369 67 static uint32_t x_USB_GOTGCTL;
mbed_official 59:2af474687369 68 #endif
mbed_official 59:2af474687369 69 static uint32_t x_USB_GAHBCFG;
mbed_official 59:2af474687369 70 static uint32_t x_USB_GUSBCFG;
mbed_official 59:2af474687369 71 static uint32_t x_USB_GRXFSIZ;
mbed_official 59:2af474687369 72 static uint32_t x_USB_GNPTXFSIZ;
mbed_official 59:2af474687369 73 static uint32_t x_USB_DCFG;
mbed_official 59:2af474687369 74 static uint32_t x_USB_DCTL;
mbed_official 59:2af474687369 75 static uint32_t x_USB_DAINTMSK;
mbed_official 59:2af474687369 76 static uint32_t x_USB_DIEPMSK;
mbed_official 59:2af474687369 77 static uint32_t x_USB_DOEPMSK;
mbed_official 59:2af474687369 78 static uint32_t x_USB_PCGCCTL;
mbed_official 59:2af474687369 79
mbed_official 59:2af474687369 80 #if ( NUM_EP_USED > 0 )
mbed_official 59:2af474687369 81 static uint32_t x_USB_EP_CTL[ NUM_EP_USED ];
mbed_official 59:2af474687369 82 static uint32_t x_USB_EP_TSIZ[ NUM_EP_USED ];
mbed_official 59:2af474687369 83 static uint32_t x_USB_EP_DMAADDR[ NUM_EP_USED ];
mbed_official 59:2af474687369 84 #endif
mbed_official 59:2af474687369 85
mbed_official 59:2af474687369 86 #if ( NUM_EP_USED > MAX_NUM_TX_FIFOS )
mbed_official 59:2af474687369 87 #define FIFO_CNT MAX_NUM_TX_FIFOS
mbed_official 59:2af474687369 88 #else
mbed_official 59:2af474687369 89 #define FIFO_CNT NUM_EP_USED
mbed_official 59:2af474687369 90 #endif
mbed_official 59:2af474687369 91
mbed_official 59:2af474687369 92 #if ( FIFO_CNT > 0 )
mbed_official 59:2af474687369 93 static uint32_t x_USB_DIEPTXFS[ FIFO_CNT ];
mbed_official 59:2af474687369 94 #endif
mbed_official 59:2af474687369 95
mbed_official 59:2af474687369 96 #if ( USB_PWRSAVE_MODE )
mbed_official 59:2af474687369 97 static uint32_t cmuStatus = 0;
mbed_official 59:2af474687369 98 #endif
mbed_official 59:2af474687369 99
mbed_official 59:2af474687369 100 #endif /* if ( USB_PWRSAVE_MODE ) */
mbed_official 59:2af474687369 101
mbed_official 59:2af474687369 102 /*
mbed_official 59:2af474687369 103 * USB_IRQHandler() is the first level handler for the USB peripheral interrupt.
mbed_official 59:2af474687369 104 */
mbed_official 59:2af474687369 105 void USB_IRQHandler( void )
mbed_official 59:2af474687369 106 {
mbed_official 59:2af474687369 107 uint32_t status;
mbed_official 59:2af474687369 108 bool servedVbusInterrupt = false;
mbed_official 59:2af474687369 109
mbed_official 59:2af474687369 110 INT_Disable();
mbed_official 59:2af474687369 111
mbed_official 59:2af474687369 112 #if ( USB_PWRSAVE_MODE )
mbed_official 59:2af474687369 113 if ( USBD_poweredDown )
mbed_official 59:2af474687369 114 {
mbed_official 59:2af474687369 115 /* Switch USBC clock from 32kHz to a 48MHz clock to be able to */
mbed_official 59:2af474687369 116 /* read USB peripheral registers. */
mbed_official 59:2af474687369 117 /* If we woke up from EM2, HFCLK is now HFRCO. */
mbed_official 59:2af474687369 118
mbed_official 59:2af474687369 119 /* Restore clock oscillators.*/
mbed_official 59:2af474687369 120 #if defined( CMU_OSCENCMD_USHFRCOEN )
mbed_official 59:2af474687369 121 if ( ( CMU->STATUS & CMU_STATUS_USHFRCOENS ) == 0 )/*Wakeup from EM2 ?*/
mbed_official 59:2af474687369 122 {
mbed_official 59:2af474687369 123 CMU->OSCENCMD = ( cmuStatus
mbed_official 59:2af474687369 124 & ( CMU_STATUS_AUXHFRCOENS | CMU_STATUS_HFXOENS ) )
mbed_official 59:2af474687369 125 | CMU_OSCENCMD_USHFRCOEN;
mbed_official 59:2af474687369 126 }
mbed_official 59:2af474687369 127 #else
mbed_official 59:2af474687369 128 if ( ( CMU->STATUS & CMU_STATUS_HFXOENS ) == 0 ) /* Wakeup from EM2 ? */
mbed_official 59:2af474687369 129 {
mbed_official 59:2af474687369 130 CMU->OSCENCMD = cmuStatus
mbed_official 59:2af474687369 131 & ( CMU_STATUS_AUXHFRCOENS | CMU_STATUS_HFXOENS );
mbed_official 59:2af474687369 132 }
mbed_official 59:2af474687369 133 #endif
mbed_official 59:2af474687369 134
mbed_official 59:2af474687369 135 /* Select correct USBC clock.*/
mbed_official 59:2af474687369 136 #if defined( CMU_OSCENCMD_USHFRCOEN )
mbed_official 59:2af474687369 137 CMU->CMD = CMU_CMD_USBCCLKSEL_USHFRCO;
mbed_official 59:2af474687369 138 while ( ( CMU->STATUS & CMU_STATUS_USBCUSHFRCOSEL ) == 0 ){}
mbed_official 59:2af474687369 139 #else
mbed_official 59:2af474687369 140 CMU->CMD = CMU_CMD_USBCCLKSEL_HFCLKNODIV;
mbed_official 59:2af474687369 141 while ( ( CMU->STATUS & CMU_STATUS_USBCHFCLKSEL ) == 0 ){}
mbed_official 59:2af474687369 142 #endif
mbed_official 59:2af474687369 143 }
mbed_official 59:2af474687369 144 #endif /* if ( USB_PWRSAVE_MODE ) */
mbed_official 59:2af474687369 145
mbed_official 59:2af474687369 146 if ( USB->IF && ( USB->CTRL & USB_CTRL_VREGOSEN ) )
mbed_official 59:2af474687369 147 {
mbed_official 59:2af474687369 148 if ( USB->IF & USB_IF_VREGOSH )
mbed_official 59:2af474687369 149 {
mbed_official 59:2af474687369 150 USB->IFC = USB_IFC_VREGOSH;
mbed_official 59:2af474687369 151
mbed_official 59:2af474687369 152 if ( USB->STATUS & USB_STATUS_VREGOS )
mbed_official 59:2af474687369 153 {
mbed_official 59:2af474687369 154 servedVbusInterrupt = true;
mbed_official 59:2af474687369 155 DEBUG_USB_INT_LO_PUTS( "\nVboN" );
mbed_official 59:2af474687369 156
mbed_official 59:2af474687369 157 #if ( USB_PWRSAVE_MODE )
mbed_official 59:2af474687369 158 if ( UsbPowerUp() )
mbed_official 59:2af474687369 159 {
mbed_official 59:2af474687369 160 USBDHAL_EnableUsbResetAndSuspendInt();
mbed_official 59:2af474687369 161 }
mbed_official 59:2af474687369 162 USBD_SetUsbState( USBD_STATE_POWERED );
mbed_official 59:2af474687369 163 #endif
mbed_official 59:2af474687369 164 }
mbed_official 59:2af474687369 165 }
mbed_official 59:2af474687369 166
mbed_official 59:2af474687369 167 if ( USB->IF & USB_IF_VREGOSL )
mbed_official 59:2af474687369 168 {
mbed_official 59:2af474687369 169 USB->IFC = USB_IFC_VREGOSL;
mbed_official 59:2af474687369 170
mbed_official 59:2af474687369 171 if ( ( USB->STATUS & USB_STATUS_VREGOS ) == 0 )
mbed_official 59:2af474687369 172 {
mbed_official 59:2af474687369 173 servedVbusInterrupt = true;
mbed_official 59:2af474687369 174 DEBUG_USB_INT_LO_PUTS( "\nVboF" );
mbed_official 59:2af474687369 175
mbed_official 59:2af474687369 176 #if ( USB_PWRSAVE_MODE )
mbed_official 59:2af474687369 177 #if ( USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF )
mbed_official 59:2af474687369 178 if ( !USBD_poweredDown )
mbed_official 59:2af474687369 179 {
mbed_official 59:2af474687369 180 USB->GINTMSK = 0;
mbed_official 59:2af474687369 181 USB->GINTSTS = 0xFFFFFFFF;
mbed_official 59:2af474687369 182 }
mbed_official 59:2af474687369 183
mbed_official 59:2af474687369 184 UsbPowerDown();
mbed_official 59:2af474687369 185 #endif
mbed_official 59:2af474687369 186 USBD_SetUsbState( USBD_STATE_NONE );
mbed_official 59:2af474687369 187 #endif
mbed_official 59:2af474687369 188 }
mbed_official 59:2af474687369 189 }
mbed_official 59:2af474687369 190 }
mbed_official 59:2af474687369 191
mbed_official 59:2af474687369 192 status = USBHAL_GetCoreInts();
mbed_official 59:2af474687369 193 if ( status == 0 )
mbed_official 59:2af474687369 194 {
mbed_official 59:2af474687369 195 INT_Enable();
mbed_official 59:2af474687369 196 if ( !servedVbusInterrupt )
mbed_official 59:2af474687369 197 {
mbed_official 59:2af474687369 198 DEBUG_USB_INT_LO_PUTS( "\nSinT" );
mbed_official 59:2af474687369 199 }
mbed_official 59:2af474687369 200 return;
mbed_official 59:2af474687369 201 }
mbed_official 59:2af474687369 202
mbed_official 59:2af474687369 203 HANDLE_INT( USB_GINTSTS_RESETDET )
mbed_official 59:2af474687369 204 HANDLE_INT( USB_GINTSTS_WKUPINT )
mbed_official 59:2af474687369 205 HANDLE_INT( USB_GINTSTS_USBSUSP )
mbed_official 59:2af474687369 206 HANDLE_INT( USB_GINTSTS_SOF )
mbed_official 59:2af474687369 207 HANDLE_INT( USB_GINTSTS_ENUMDONE )
mbed_official 59:2af474687369 208 HANDLE_INT( USB_GINTSTS_USBRST )
mbed_official 59:2af474687369 209 HANDLE_INT( USB_GINTSTS_IEPINT )
mbed_official 59:2af474687369 210 HANDLE_INT( USB_GINTSTS_OEPINT )
mbed_official 59:2af474687369 211
mbed_official 59:2af474687369 212 INT_Enable();
mbed_official 59:2af474687369 213
mbed_official 59:2af474687369 214 if ( status != 0 )
mbed_official 59:2af474687369 215 {
mbed_official 59:2af474687369 216 DEBUG_USB_INT_LO_PUTS( "\nUinT" );
mbed_official 59:2af474687369 217 }
mbed_official 59:2af474687369 218 }
mbed_official 59:2af474687369 219
mbed_official 59:2af474687369 220 /*
mbed_official 59:2af474687369 221 * Handle port enumeration interrupt. This has nothing to do with normal
mbed_official 59:2af474687369 222 * device enumeration.
mbed_official 59:2af474687369 223 */
mbed_official 59:2af474687369 224 static void Handle_USB_GINTSTS_ENUMDONE( void )
mbed_official 59:2af474687369 225 {
mbed_official 59:2af474687369 226 #if ( USB_PWRSAVE_MODE )
mbed_official 59:2af474687369 227 UsbPowerUp();
mbed_official 59:2af474687369 228 #endif
mbed_official 59:2af474687369 229
mbed_official 59:2af474687369 230 USBDHAL_Ep0Activate( dev->ep0MpsCode );
mbed_official 59:2af474687369 231 dev->ep[ 0 ].state = D_EP_IDLE;
mbed_official 59:2af474687369 232 USBDHAL_EnableInts( dev );
mbed_official 59:2af474687369 233 DEBUG_USB_INT_LO_PUTS( "EnumD" );
mbed_official 59:2af474687369 234 }
mbed_official 59:2af474687369 235
mbed_official 59:2af474687369 236 /*
mbed_official 59:2af474687369 237 * Handle IN endpoint transfer interrupt.
mbed_official 59:2af474687369 238 */
mbed_official 59:2af474687369 239 static void Handle_USB_GINTSTS_IEPINT( void )
mbed_official 59:2af474687369 240 {
mbed_official 59:2af474687369 241 int epnum;
mbed_official 59:2af474687369 242 uint16_t epint;
mbed_official 59:2af474687369 243 uint16_t epmask;
mbed_official 59:2af474687369 244 uint32_t status;
mbed_official 59:2af474687369 245 USBD_Ep_TypeDef *ep;
mbed_official 59:2af474687369 246
mbed_official 59:2af474687369 247 DEBUG_USB_INT_HI_PUTCHAR( 'i' );
mbed_official 59:2af474687369 248
mbed_official 59:2af474687369 249 epint = USBDHAL_GetAllInEpInts();
mbed_official 59:2af474687369 250 for ( epnum = 0, epmask = 1;
mbed_official 59:2af474687369 251 epnum <= MAX_NUM_IN_EPS;
mbed_official 59:2af474687369 252 epnum++, epmask <<= 1 )
mbed_official 59:2af474687369 253 {
mbed_official 59:2af474687369 254 if ( epint & epmask )
mbed_official 59:2af474687369 255 {
mbed_official 59:2af474687369 256 ep = USBD_GetEpFromAddr( USB_SETUP_DIR_MASK | epnum );
mbed_official 59:2af474687369 257 status = USBDHAL_GetInEpInts( ep );
mbed_official 59:2af474687369 258
mbed_official 59:2af474687369 259 if ( status & USB_DIEP_INT_XFERCOMPL )
mbed_official 59:2af474687369 260 {
mbed_official 59:2af474687369 261 USB_DINEPS[ epnum ].INT = USB_DIEP_INT_XFERCOMPL;
mbed_official 59:2af474687369 262
mbed_official 59:2af474687369 263 DEBUG_USB_INT_HI_PUTCHAR( 'c' );
mbed_official 59:2af474687369 264
mbed_official 59:2af474687369 265 if ( epnum == 0 )
mbed_official 59:2af474687369 266 {
mbed_official 59:2af474687369 267 if ( ep->remaining > ep->packetSize )
mbed_official 59:2af474687369 268 {
mbed_official 59:2af474687369 269 ep->remaining -= ep->packetSize;
mbed_official 59:2af474687369 270 ep->xferred += ep->packetSize;
mbed_official 59:2af474687369 271 }
mbed_official 59:2af474687369 272 else
mbed_official 59:2af474687369 273 {
mbed_official 59:2af474687369 274 ep->xferred += ep->remaining;
mbed_official 59:2af474687369 275 ep->remaining = 0;
mbed_official 59:2af474687369 276 }
mbed_official 59:2af474687369 277 USBDEP_Ep0Handler( dev );
mbed_official 59:2af474687369 278 }
mbed_official 59:2af474687369 279 else
mbed_official 59:2af474687369 280 {
mbed_official 59:2af474687369 281 ep->xferred = ep->remaining -
mbed_official 59:2af474687369 282 ( ( USB_DINEPS[ epnum ].TSIZ &
mbed_official 59:2af474687369 283 _USB_DIEP_TSIZ_XFERSIZE_MASK ) >>
mbed_official 59:2af474687369 284 _USB_DIEP_TSIZ_XFERSIZE_SHIFT );
mbed_official 59:2af474687369 285 ep->remaining -= ep->xferred;
mbed_official 59:2af474687369 286
mbed_official 59:2af474687369 287 USBDEP_EpHandler( ep->addr );
mbed_official 59:2af474687369 288 #if defined( USB_DOEP0INT_STUPPKTRCVD )
mbed_official 59:2af474687369 289 if ( USB_DINEPS[ ep->num ].INT & USB_DIEP_INT_NAKINTRPT )
mbed_official 59:2af474687369 290 {
mbed_official 59:2af474687369 291 USB_DINEPS[ ep->num ].INT = USB_DIEP_INT_NAKINTRPT;
mbed_official 59:2af474687369 292 }
mbed_official 59:2af474687369 293 #endif
mbed_official 59:2af474687369 294 }
mbed_official 59:2af474687369 295 }
mbed_official 59:2af474687369 296 }
mbed_official 59:2af474687369 297 }
mbed_official 59:2af474687369 298 }
mbed_official 59:2af474687369 299
mbed_official 59:2af474687369 300 /*
mbed_official 59:2af474687369 301 * Handle OUT endpoint transfer interrupt.
mbed_official 59:2af474687369 302 */
mbed_official 59:2af474687369 303 static void Handle_USB_GINTSTS_OEPINT( void )
mbed_official 59:2af474687369 304 {
mbed_official 59:2af474687369 305 int epnum;
mbed_official 59:2af474687369 306 uint16_t epint;
mbed_official 59:2af474687369 307 uint16_t epmask;
mbed_official 59:2af474687369 308 uint32_t status;
mbed_official 59:2af474687369 309 USBD_Ep_TypeDef *ep;
mbed_official 59:2af474687369 310
mbed_official 59:2af474687369 311 DEBUG_USB_INT_HI_PUTCHAR( 'o' );
mbed_official 59:2af474687369 312
mbed_official 59:2af474687369 313 epint = USBDHAL_GetAllOutEpInts();
mbed_official 59:2af474687369 314 for ( epnum = 0, epmask = 1;
mbed_official 59:2af474687369 315 epnum <= MAX_NUM_OUT_EPS;
mbed_official 59:2af474687369 316 epnum++, epmask <<= 1 )
mbed_official 59:2af474687369 317 {
mbed_official 59:2af474687369 318 if ( epint & epmask )
mbed_official 59:2af474687369 319 {
mbed_official 59:2af474687369 320 ep = USBD_GetEpFromAddr( epnum );
mbed_official 59:2af474687369 321 status = USBDHAL_GetOutEpInts( ep );
mbed_official 59:2af474687369 322
mbed_official 59:2af474687369 323 #if defined( USB_DOEP0INT_STUPPKTRCVD )
mbed_official 59:2af474687369 324 HandleOutEpIntr( status, ep );
mbed_official 59:2af474687369 325 #else
mbed_official 59:2af474687369 326 if ( status & USB_DOEP_INT_XFERCOMPL )
mbed_official 59:2af474687369 327 {
mbed_official 59:2af474687369 328 USB_DOUTEPS[ epnum ].INT = USB_DOEP_INT_XFERCOMPL;
mbed_official 59:2af474687369 329 DEBUG_USB_INT_HI_PUTCHAR( 'c' );
mbed_official 59:2af474687369 330 ProcessOepData( ep );
mbed_official 59:2af474687369 331 }
mbed_official 59:2af474687369 332
mbed_official 59:2af474687369 333 /* Setup Phase Done */
mbed_official 59:2af474687369 334 if ( status & USB_DOEP0INT_SETUP )
mbed_official 59:2af474687369 335 {
mbed_official 59:2af474687369 336 ProcessSetup();
mbed_official 59:2af474687369 337 }
mbed_official 59:2af474687369 338 #endif
mbed_official 59:2af474687369 339 }
mbed_official 59:2af474687369 340 }
mbed_official 59:2af474687369 341 }
mbed_official 59:2af474687369 342
mbed_official 59:2af474687369 343 #if !defined( USB_DOEP0INT_STUPPKTRCVD )
mbed_official 59:2af474687369 344 static void ProcessOepData( USBD_Ep_TypeDef *ep )
mbed_official 59:2af474687369 345 {
mbed_official 59:2af474687369 346 if ( ep->num == 0 )
mbed_official 59:2af474687369 347 {
mbed_official 59:2af474687369 348
mbed_official 59:2af474687369 349 #ifdef __MBED__
mbed_official 59:2af474687369 350 int xfer_size = ep->packetSize - (( USB->DOEP0TSIZ & _USB_DOEP0TSIZ_XFERSIZE_MASK )
mbed_official 59:2af474687369 351 >> _USB_DOEP0TSIZ_XFERSIZE_SHIFT);
mbed_official 59:2af474687369 352 int setup_pkt_received = USBDHAL_GetOutEpInts( ep ) & USB_DOEP0INT_SETUP;
mbed_official 59:2af474687369 353
mbed_official 59:2af474687369 354 if ( (!setup_pkt_received && xfer_size == 0) ||
mbed_official 59:2af474687369 355 (setup_pkt_received && xfer_size == 8) )
mbed_official 59:2af474687369 356 {
mbed_official 59:2af474687369 357 /* Higher levels need to see the correct transfer amount for ZLPs */
mbed_official 59:2af474687369 358 ep->remaining = 0;
mbed_official 59:2af474687369 359 ep->xferred = 0;
mbed_official 59:2af474687369 360 }
mbed_official 59:2af474687369 361 else
mbed_official 59:2af474687369 362 {
mbed_official 59:2af474687369 363 /* FIXME - does not work if actual read size > 56 */
mbed_official 59:2af474687369 364 if ( setup_pkt_received ) xfer_size -= 8;
mbed_official 59:2af474687369 365
mbed_official 59:2af474687369 366 ep->xferred = xfer_size;
mbed_official 59:2af474687369 367 ep->remaining -= xfer_size;
mbed_official 59:2af474687369 368 }
mbed_official 59:2af474687369 369 #else
mbed_official 59:2af474687369 370 if ( ep->remaining > ep->packetSize )
mbed_official 59:2af474687369 371 {
mbed_official 59:2af474687369 372 ep->remaining -= ep->packetSize;
mbed_official 59:2af474687369 373 ep->xferred += ep->packetSize;
mbed_official 59:2af474687369 374 }
mbed_official 59:2af474687369 375 else
mbed_official 59:2af474687369 376 {
mbed_official 59:2af474687369 377 ep->xferred += ep->remaining;
mbed_official 59:2af474687369 378 ep->remaining = 0;
mbed_official 59:2af474687369 379 }
mbed_official 59:2af474687369 380 #endif
mbed_official 59:2af474687369 381
mbed_official 59:2af474687369 382 USBDEP_Ep0Handler( dev );
mbed_official 59:2af474687369 383 }
mbed_official 59:2af474687369 384 else
mbed_official 59:2af474687369 385 {
mbed_official 59:2af474687369 386 ep->xferred = ep->hwXferSize -
mbed_official 59:2af474687369 387 ( ( USB_DOUTEPS[ ep->num ].TSIZ & _USB_DOEP_TSIZ_XFERSIZE_MASK )>>
mbed_official 59:2af474687369 388 _USB_DOEP_TSIZ_XFERSIZE_SHIFT );
mbed_official 59:2af474687369 389 ep->remaining -= ep->xferred;
mbed_official 59:2af474687369 390 USBDEP_EpHandler( ep->addr );
mbed_official 59:2af474687369 391 }
mbed_official 59:2af474687369 392 }
mbed_official 59:2af474687369 393 #endif
mbed_official 59:2af474687369 394
mbed_official 59:2af474687369 395 #if !defined( USB_DOEP0INT_STUPPKTRCVD )
mbed_official 59:2af474687369 396 static void ProcessSetup( void )
mbed_official 59:2af474687369 397 {
mbed_official 59:2af474687369 398 DEBUG_USB_INT_LO_PUTS( "\nS" );
mbed_official 59:2af474687369 399
mbed_official 59:2af474687369 400 if ( USB->DOEP0INT & USB_DOEP0INT_BACK2BACKSETUP )
mbed_official 59:2af474687369 401 { /* Back to back setup packets received */
mbed_official 59:2af474687369 402 USB->DOEP0INT = USB_DOEP0INT_BACK2BACKSETUP;
mbed_official 59:2af474687369 403 DEBUG_USB_INT_LO_PUTS( "B2B" );
mbed_official 59:2af474687369 404
mbed_official 59:2af474687369 405 dev->setup = (USB_Setup_TypeDef*)( USB->DOEP0DMAADDR - USB_SETUP_PKT_SIZE );
mbed_official 59:2af474687369 406 }
mbed_official 59:2af474687369 407 else
mbed_official 59:2af474687369 408 {
mbed_official 59:2af474687369 409 /* Read SETUP packet counter from hw. */
mbed_official 59:2af474687369 410 int supCnt = ( USB->DOEP0TSIZ & _USB_DOEP0TSIZ_SUPCNT_MASK )
mbed_official 59:2af474687369 411 >> _USB_DOEP0TSIZ_SUPCNT_SHIFT;
mbed_official 59:2af474687369 412
mbed_official 59:2af474687369 413 if ( supCnt == 3 )
mbed_official 59:2af474687369 414 supCnt = 2;
mbed_official 59:2af474687369 415
mbed_official 59:2af474687369 416 dev->setup = &dev->setupPkt[ 2 - supCnt ];
mbed_official 59:2af474687369 417 }
mbed_official 59:2af474687369 418 USB->DOEP0TSIZ |= 3 << _USB_DOEP0TSIZ_SUPCNT_SHIFT;
mbed_official 59:2af474687369 419 USB->DOEP0DMAADDR = (uint32_t)dev->setupPkt;
mbed_official 59:2af474687369 420 USB->DOEP0INT = USB_DOEP0INT_SETUP;
mbed_official 59:2af474687369 421
mbed_official 59:2af474687369 422 USBDEP_Ep0Handler( dev ); /* Call the SETUP handler for EP0 */
mbed_official 59:2af474687369 423 }
mbed_official 59:2af474687369 424 #endif
mbed_official 59:2af474687369 425
mbed_official 59:2af474687369 426 /*
mbed_official 59:2af474687369 427 * Handle USB reset detected interrupt in suspend mode.
mbed_official 59:2af474687369 428 */
mbed_official 59:2af474687369 429 static void Handle_USB_GINTSTS_RESETDET ( void )
mbed_official 59:2af474687369 430 {
mbed_official 59:2af474687369 431 #if ( USB_PWRSAVE_MODE )
mbed_official 59:2af474687369 432 if ( ! USBD_poweredDown )
mbed_official 59:2af474687369 433 {
mbed_official 59:2af474687369 434 USB->GINTSTS = USB_GINTSTS_RESETDET;
mbed_official 59:2af474687369 435 }
mbed_official 59:2af474687369 436
mbed_official 59:2af474687369 437 if ( UsbPowerUp() )
mbed_official 59:2af474687369 438 {
mbed_official 59:2af474687369 439 USB->GINTSTS = USB_GINTSTS_RESETDET;
mbed_official 59:2af474687369 440 }
mbed_official 59:2af474687369 441
mbed_official 59:2af474687369 442 #if ( USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF )
mbed_official 59:2af474687369 443 /* Power down immediately if VBUS is off. */
mbed_official 59:2af474687369 444 if ( ! ( USB->STATUS & USB_STATUS_VREGOS ) )
mbed_official 59:2af474687369 445 {
mbed_official 59:2af474687369 446 UsbPowerDown();
mbed_official 59:2af474687369 447 }
mbed_official 59:2af474687369 448 #endif
mbed_official 59:2af474687369 449
mbed_official 59:2af474687369 450 #else
mbed_official 59:2af474687369 451 USB->GINTSTS = USB_GINTSTS_RESETDET;
mbed_official 59:2af474687369 452 #endif /* if ( USB_PWRSAVE_MODE ) */
mbed_official 59:2af474687369 453
mbed_official 59:2af474687369 454 if ( USB->STATUS & USB_STATUS_VREGOS )
mbed_official 59:2af474687369 455 {
mbed_official 59:2af474687369 456 USBD_SetUsbState( USBD_STATE_DEFAULT );
mbed_official 59:2af474687369 457 }
mbed_official 59:2af474687369 458 else
mbed_official 59:2af474687369 459 {
mbed_official 59:2af474687369 460 USBD_SetUsbState( USBD_STATE_NONE );
mbed_official 59:2af474687369 461 }
mbed_official 59:2af474687369 462 DEBUG_USB_INT_LO_PUTS( "RsuP\n" );
mbed_official 59:2af474687369 463 }
mbed_official 59:2af474687369 464
mbed_official 59:2af474687369 465 /*
mbed_official 59:2af474687369 466 * Handle Start Of Frame (SOF) interrupt.
mbed_official 59:2af474687369 467 */
mbed_official 59:2af474687369 468 static void Handle_USB_GINTSTS_SOF( void )
mbed_official 59:2af474687369 469 {
mbed_official 59:2af474687369 470 USB->GINTSTS = USB_GINTSTS_SOF;
mbed_official 59:2af474687369 471
mbed_official 59:2af474687369 472 if ( dev->callbacks->sofInt )
mbed_official 59:2af474687369 473 {
mbed_official 59:2af474687369 474 dev->callbacks->sofInt(
mbed_official 59:2af474687369 475 ( USB->DSTS & _USB_DSTS_SOFFN_MASK ) >> _USB_DSTS_SOFFN_SHIFT );
mbed_official 59:2af474687369 476 }
mbed_official 59:2af474687369 477 }
mbed_official 59:2af474687369 478
mbed_official 59:2af474687369 479 /*
mbed_official 59:2af474687369 480 * Handle USB port reset interrupt.
mbed_official 59:2af474687369 481 */
mbed_official 59:2af474687369 482 static void Handle_USB_GINTSTS_USBRST( void )
mbed_official 59:2af474687369 483 {
mbed_official 59:2af474687369 484 int i;
mbed_official 59:2af474687369 485
mbed_official 59:2af474687369 486 DEBUG_USB_INT_LO_PUTS( "ReseT" );
mbed_official 59:2af474687369 487
mbed_official 59:2af474687369 488 /* Clear Remote Wakeup Signalling */
mbed_official 59:2af474687369 489 USB->DCTL &= ~( DCTL_WO_BITMASK | USB_DCTL_RMTWKUPSIG );
mbed_official 59:2af474687369 490 USBHAL_FlushTxFifo( 0 );
mbed_official 59:2af474687369 491
mbed_official 59:2af474687369 492 /* Clear pending interrupts */
mbed_official 59:2af474687369 493 for ( i = 0; i <= MAX_NUM_IN_EPS; i++ )
mbed_official 59:2af474687369 494 {
mbed_official 59:2af474687369 495 USB_DINEPS[ i ].INT = 0xFFFFFFFF;
mbed_official 59:2af474687369 496 }
mbed_official 59:2af474687369 497
mbed_official 59:2af474687369 498 for ( i = 0; i <= MAX_NUM_OUT_EPS; i++ )
mbed_official 59:2af474687369 499 {
mbed_official 59:2af474687369 500 USB_DOUTEPS[ i ].INT = 0xFFFFFFFF;
mbed_official 59:2af474687369 501 }
mbed_official 59:2af474687369 502
mbed_official 59:2af474687369 503 USB->DAINTMSK = USB_DAINTMSK_INEPMSK0 | USB_DAINTMSK_OUTEPMSK0;
mbed_official 59:2af474687369 504 #if defined( USB_DOEPMSK_STSPHSERCVDMSK )
mbed_official 59:2af474687369 505 USB->DOEPMSK = USB_DOEPMSK_SETUPMSK | USB_DOEPMSK_XFERCOMPLMSK
mbed_official 59:2af474687369 506 | USB_DOEPMSK_STSPHSERCVDMSK;
mbed_official 59:2af474687369 507 #else
mbed_official 59:2af474687369 508 USB->DOEPMSK = USB_DOEPMSK_SETUPMSK | USB_DOEPMSK_XFERCOMPLMSK;
mbed_official 59:2af474687369 509 #endif
mbed_official 59:2af474687369 510 USB->DIEPMSK = USB_DIEPMSK_XFERCOMPLMSK;
mbed_official 59:2af474687369 511
mbed_official 59:2af474687369 512 /* Reset Device Address */
mbed_official 59:2af474687369 513 USB->DCFG &= ~_USB_DCFG_DEVADDR_MASK;
mbed_official 59:2af474687369 514
mbed_official 59:2af474687369 515 /* Setup EP0 to receive SETUP packets */
mbed_official 59:2af474687369 516 USBDHAL_StartEp0Setup( dev );
mbed_official 59:2af474687369 517 USBDHAL_EnableInts( dev );
mbed_official 59:2af474687369 518
mbed_official 59:2af474687369 519 if ( dev->callbacks->usbReset )
mbed_official 59:2af474687369 520 {
mbed_official 59:2af474687369 521 dev->callbacks->usbReset();
mbed_official 59:2af474687369 522 }
mbed_official 59:2af474687369 523
mbed_official 59:2af474687369 524 USBD_SetUsbState( USBD_STATE_DEFAULT );
mbed_official 59:2af474687369 525 USBDHAL_AbortAllTransfers( USB_STATUS_DEVICE_RESET );
mbed_official 59:2af474687369 526 }
mbed_official 59:2af474687369 527
mbed_official 59:2af474687369 528 /*
mbed_official 59:2af474687369 529 * Handle USB port suspend interrupt.
mbed_official 59:2af474687369 530 */
mbed_official 59:2af474687369 531 static void Handle_USB_GINTSTS_USBSUSP( void )
mbed_official 59:2af474687369 532 {
mbed_official 59:2af474687369 533 USBD_State_TypeDef state;
mbed_official 59:2af474687369 534
mbed_official 59:2af474687369 535 USB->GINTSTS = USB_GINTSTS_USBSUSP;
mbed_official 59:2af474687369 536 USBDHAL_AbortAllTransfers( USB_STATUS_DEVICE_SUSPENDED );
mbed_official 59:2af474687369 537 DEBUG_USB_INT_LO_PUTS( "\nSusP" );
mbed_official 59:2af474687369 538
mbed_official 59:2af474687369 539 if ( USBD_GetUsbState() == USBD_STATE_NONE )
mbed_official 59:2af474687369 540 {
mbed_official 59:2af474687369 541 USBD_SetUsbState( USBD_STATE_POWERED );
mbed_official 59:2af474687369 542 }
mbed_official 59:2af474687369 543
mbed_official 59:2af474687369 544 state = USBD_GetUsbState();
mbed_official 59:2af474687369 545 if ( ( state == USBD_STATE_POWERED ) ||
mbed_official 59:2af474687369 546 ( state == USBD_STATE_DEFAULT ) ||
mbed_official 59:2af474687369 547 ( state == USBD_STATE_ADDRESSED ) ||
mbed_official 59:2af474687369 548 ( state == USBD_STATE_CONFIGURED ) )
mbed_official 59:2af474687369 549 {
mbed_official 59:2af474687369 550 #if ( USB_PWRSAVE_MODE )
mbed_official 59:2af474687369 551 UsbPowerDown();
mbed_official 59:2af474687369 552 #endif
mbed_official 59:2af474687369 553 USBD_SetUsbState( USBD_STATE_SUSPENDED );
mbed_official 59:2af474687369 554 }
mbed_official 59:2af474687369 555 }
mbed_official 59:2af474687369 556
mbed_official 59:2af474687369 557 /*
mbed_official 59:2af474687369 558 * Handle USB port wakeup interrupt.
mbed_official 59:2af474687369 559 */
mbed_official 59:2af474687369 560 static void Handle_USB_GINTSTS_WKUPINT( void )
mbed_official 59:2af474687369 561 {
mbed_official 59:2af474687369 562 #if ( USB_PWRSAVE_MODE )
mbed_official 59:2af474687369 563 if ( ! USBD_poweredDown )
mbed_official 59:2af474687369 564 {
mbed_official 59:2af474687369 565 USB->GINTSTS = USB_GINTSTS_WKUPINT;
mbed_official 59:2af474687369 566 }
mbed_official 59:2af474687369 567
mbed_official 59:2af474687369 568 if ( UsbPowerUp() )
mbed_official 59:2af474687369 569 {
mbed_official 59:2af474687369 570 USB->GINTSTS = USB_GINTSTS_WKUPINT;
mbed_official 59:2af474687369 571 USBDHAL_StartEp0Setup( dev );
mbed_official 59:2af474687369 572 USBDHAL_Ep0Activate( dev->ep0MpsCode );
mbed_official 59:2af474687369 573 }
mbed_official 59:2af474687369 574 #else
mbed_official 59:2af474687369 575 USB->GINTSTS = USB_GINTSTS_WKUPINT;
mbed_official 59:2af474687369 576 #endif
mbed_official 59:2af474687369 577
mbed_official 59:2af474687369 578 USBD_SetUsbState( dev->savedState );
mbed_official 59:2af474687369 579 DEBUG_USB_INT_LO_PUTS( "WkuP\n" );
mbed_official 59:2af474687369 580 }
mbed_official 59:2af474687369 581
mbed_official 59:2af474687369 582 #if ( USB_PWRSAVE_MODE )
mbed_official 59:2af474687369 583 /*
mbed_official 59:2af474687369 584 * Backup essential USB core registers, and set the core in partial powerdown
mbed_official 59:2af474687369 585 * mode. Optionally prepare entry into EM2.
mbed_official 59:2af474687369 586 */
mbed_official 59:2af474687369 587 static bool UsbPowerDown( void )
mbed_official 59:2af474687369 588 {
mbed_official 59:2af474687369 589 #if ( NUM_EP_USED > 0 ) || ( FIFO_CNT > 0 )
mbed_official 59:2af474687369 590 int i;
mbed_official 59:2af474687369 591 #endif
mbed_official 59:2af474687369 592 #if ( NUM_EP_USED > 0 )
mbed_official 59:2af474687369 593 int epNum;
mbed_official 59:2af474687369 594 USBD_Ep_TypeDef *ep;
mbed_official 59:2af474687369 595 #endif
mbed_official 59:2af474687369 596
mbed_official 59:2af474687369 597 if ( !USBD_poweredDown )
mbed_official 59:2af474687369 598 {
mbed_official 59:2af474687369 599 USBD_poweredDown = true;
mbed_official 59:2af474687369 600 DEBUG_USB_INT_LO_PUTCHAR( '\\' );
mbed_official 59:2af474687369 601
mbed_official 59:2af474687369 602 /* Backup USB core registers. */
mbed_official 59:2af474687369 603 x_USB_GINTMSK = USB->GINTMSK;
mbed_official 59:2af474687369 604 #if defined(_USB_GOTGCTL_MASK)
mbed_official 59:2af474687369 605 x_USB_GOTGCTL = USB->GOTGCTL;
mbed_official 59:2af474687369 606 #endif
mbed_official 59:2af474687369 607 x_USB_GAHBCFG = USB->GAHBCFG;
mbed_official 59:2af474687369 608 x_USB_GUSBCFG = USB->GUSBCFG;
mbed_official 59:2af474687369 609 x_USB_GRXFSIZ = USB->GRXFSIZ;
mbed_official 59:2af474687369 610 x_USB_GNPTXFSIZ = USB->GNPTXFSIZ;
mbed_official 59:2af474687369 611 x_USB_DCFG = USB->DCFG;
mbed_official 59:2af474687369 612 x_USB_DCTL = USB->DCTL;
mbed_official 59:2af474687369 613 x_USB_DAINTMSK = USB->DAINTMSK;
mbed_official 59:2af474687369 614 x_USB_DIEPMSK = USB->DIEPMSK;
mbed_official 59:2af474687369 615 x_USB_DOEPMSK = USB->DOEPMSK;
mbed_official 59:2af474687369 616 x_USB_PCGCCTL = USB->PCGCCTL;
mbed_official 59:2af474687369 617
mbed_official 59:2af474687369 618 #if ( NUM_EP_USED > 0 )
mbed_official 59:2af474687369 619 for ( i = 0; i < NUM_EP_USED; i++ )
mbed_official 59:2af474687369 620 {
mbed_official 59:2af474687369 621 ep = &dev->ep[ i+1 ];
mbed_official 59:2af474687369 622 epNum = ep->num;
mbed_official 59:2af474687369 623 if ( ep->in )
mbed_official 59:2af474687369 624 {
mbed_official 59:2af474687369 625 x_USB_EP_CTL[ i ] = USB_DINEPS[ epNum ].CTL;
mbed_official 59:2af474687369 626 x_USB_EP_TSIZ[ i ] = USB_DINEPS[ epNum ].TSIZ;
mbed_official 59:2af474687369 627 x_USB_EP_DMAADDR[ i ] = USB_DINEPS[ epNum ].DMAADDR;
mbed_official 59:2af474687369 628 }
mbed_official 59:2af474687369 629 else
mbed_official 59:2af474687369 630 {
mbed_official 59:2af474687369 631 x_USB_EP_CTL[ i ] = USB_DOUTEPS[ epNum ].CTL;
mbed_official 59:2af474687369 632 x_USB_EP_TSIZ[ i ] = USB_DOUTEPS[ epNum ].TSIZ;
mbed_official 59:2af474687369 633 x_USB_EP_DMAADDR[ i ] = USB_DOUTEPS[ epNum ].DMAADDR;
mbed_official 59:2af474687369 634 }
mbed_official 59:2af474687369 635 }
mbed_official 59:2af474687369 636 #endif
mbed_official 59:2af474687369 637
mbed_official 59:2af474687369 638 #if ( FIFO_CNT > 0 )
mbed_official 59:2af474687369 639 for ( i = 0; i < FIFO_CNT; i++ )
mbed_official 59:2af474687369 640 {
mbed_official 59:2af474687369 641 x_USB_DIEPTXFS[ i ] = USB_DIEPTXFS[ i ];
mbed_official 59:2af474687369 642 }
mbed_official 59:2af474687369 643 #endif
mbed_official 59:2af474687369 644
mbed_official 59:2af474687369 645 /* Prepare for wakeup on resume and reset. */
mbed_official 59:2af474687369 646 USB->DCFG = (USB->DCFG & ~_USB_DCFG_RESVALID_MASK) |
mbed_official 59:2af474687369 647 (4 << _USB_DCFG_RESVALID_SHIFT);
mbed_official 59:2af474687369 648 USB->DCFG |= USB_DCFG_ENA32KHZSUSP;
mbed_official 59:2af474687369 649 USB->GINTMSK = USB_GINTMSK_RESETDETMSK | USB_GINTMSK_WKUPINTMSK;
mbed_official 59:2af474687369 650
mbed_official 59:2af474687369 651 /* Enter partial powerdown mode. */
mbed_official 59:2af474687369 652 USB->PCGCCTL |= USB_PCGCCTL_PWRCLMP;
mbed_official 59:2af474687369 653 USB->PCGCCTL |= USB_PCGCCTL_RSTPDWNMODULE;
mbed_official 59:2af474687369 654 USB->PCGCCTL |= USB_PCGCCTL_STOPPCLK;
mbed_official 59:2af474687369 655
mbed_official 59:2af474687369 656 /* Record current clock settings. */
mbed_official 59:2af474687369 657 cmuStatus = CMU->STATUS;
mbed_official 59:2af474687369 658
mbed_official 59:2af474687369 659 #if ( USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ENTEREM2 )
mbed_official 59:2af474687369 660 #ifndef __MBED__
mbed_official 59:2af474687369 661 /* Enter EM2 on interrupt exit. */
mbed_official 59:2af474687369 662 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk;
mbed_official 59:2af474687369 663 #else
mbed_official 59:2af474687369 664 usbhal_allow_em2(true);
mbed_official 59:2af474687369 665 #endif
mbed_official 59:2af474687369 666 #endif
mbed_official 59:2af474687369 667
mbed_official 59:2af474687369 668 /* Switch USBC clock to 32 kHz. */
mbed_official 59:2af474687369 669 #if ( USB_USBC_32kHz_CLK == USB_USBC_32kHz_CLK_LFXO )
mbed_official 59:2af474687369 670 CMU->CMD = CMU_CMD_USBCCLKSEL_LFXO;
mbed_official 59:2af474687369 671 while ( ( CMU->STATUS & CMU_STATUS_USBCLFXOSEL ) == 0 ){}
mbed_official 59:2af474687369 672 #else
mbed_official 59:2af474687369 673 CMU->CMD = CMU_CMD_USBCCLKSEL_LFRCO;
mbed_official 59:2af474687369 674 while ( ( CMU->STATUS & CMU_STATUS_USBCLFRCOSEL ) == 0 ){}
mbed_official 59:2af474687369 675 #endif
mbed_official 59:2af474687369 676
mbed_official 59:2af474687369 677 return true;
mbed_official 59:2af474687369 678 }
mbed_official 59:2af474687369 679 return false;
mbed_official 59:2af474687369 680 }
mbed_official 59:2af474687369 681 #endif /* if ( USB_PWRSAVE_MODE ) */
mbed_official 59:2af474687369 682
mbed_official 59:2af474687369 683 #if ( USB_PWRSAVE_MODE )
mbed_official 59:2af474687369 684 /*
mbed_official 59:2af474687369 685 * Exit USB core partial powerdown mode, restore essential USB core registers.
mbed_official 59:2af474687369 686 * Will prevent re-entry back to EM2.
mbed_official 59:2af474687369 687 * Returns true if a powerup sequence was performed.
mbed_official 59:2af474687369 688 */
mbed_official 59:2af474687369 689 static bool UsbPowerUp( void )
mbed_official 59:2af474687369 690 {
mbed_official 59:2af474687369 691 #if ( NUM_EP_USED > 0 ) || ( FIFO_CNT > 0 )
mbed_official 59:2af474687369 692 int i;
mbed_official 59:2af474687369 693 #endif
mbed_official 59:2af474687369 694 #if ( NUM_EP_USED > 0 )
mbed_official 59:2af474687369 695 int epNum;
mbed_official 59:2af474687369 696 uint32_t tmp;
mbed_official 59:2af474687369 697 USBD_Ep_TypeDef *ep;
mbed_official 59:2af474687369 698 #endif
mbed_official 59:2af474687369 699
mbed_official 59:2af474687369 700 if ( USBD_poweredDown )
mbed_official 59:2af474687369 701 {
mbed_official 59:2af474687369 702 USBD_poweredDown = false;
mbed_official 59:2af474687369 703 DEBUG_USB_INT_LO_PUTCHAR( '/' );
mbed_official 59:2af474687369 704
mbed_official 59:2af474687369 705 #if !defined( USB_CORECLK_HFRCO ) || !defined( CMU_OSCENCMD_USHFRCOEN )
mbed_official 59:2af474687369 706 /* Switch HFCLK from HFRCO to HFXO. */
mbed_official 59:2af474687369 707 CMU_ClockSelectSet( cmuClock_HF, cmuSelect_HFXO );
mbed_official 59:2af474687369 708 #endif
mbed_official 59:2af474687369 709
mbed_official 59:2af474687369 710 /* Turn off HFRCO when not needed. */
mbed_official 59:2af474687369 711 if ( ( cmuStatus & CMU_STATUS_HFRCOENS ) == 0 )
mbed_official 59:2af474687369 712 {
mbed_official 59:2af474687369 713 CMU->OSCENCMD = CMU_OSCENCMD_HFRCODIS;
mbed_official 59:2af474687369 714 }
mbed_official 59:2af474687369 715
mbed_official 59:2af474687369 716 /* Exit partial powerdown mode. */
mbed_official 59:2af474687369 717 USB->PCGCCTL &= ~USB_PCGCCTL_STOPPCLK;
mbed_official 59:2af474687369 718 USB->PCGCCTL &= ~(USB_PCGCCTL_PWRCLMP | USB_PCGCCTL_RSTPDWNMODULE);
mbed_official 59:2af474687369 719
mbed_official 59:2af474687369 720 if (( USB->GINTSTS & ( USB_GINTSTS_WKUPINT | USB_GINTSTS_RESETDET ) ) == 0)
mbed_official 59:2af474687369 721 {
mbed_official 59:2af474687369 722 USB->DCTL = x_USB_DCTL | USB_DCTL_RMTWKUPSIG;
mbed_official 59:2af474687369 723 USB->DCTL = x_USB_DCTL;
mbed_official 59:2af474687369 724 }
mbed_official 59:2af474687369 725
mbed_official 59:2af474687369 726 /* Restore USB core registers. */
mbed_official 59:2af474687369 727 USB->GUSBCFG = x_USB_GUSBCFG;
mbed_official 59:2af474687369 728 USB->DCFG = x_USB_DCFG;
mbed_official 59:2af474687369 729
mbed_official 59:2af474687369 730 #if ( FIFO_CNT > 0 )
mbed_official 59:2af474687369 731 for ( i = 0; i < FIFO_CNT; i++ )
mbed_official 59:2af474687369 732 {
mbed_official 59:2af474687369 733 USB_DIEPTXFS[ i ] = x_USB_DIEPTXFS[ i ];
mbed_official 59:2af474687369 734 }
mbed_official 59:2af474687369 735 #endif
mbed_official 59:2af474687369 736
mbed_official 59:2af474687369 737 #if ( NUM_EP_USED > 0 )
mbed_official 59:2af474687369 738 for ( i = 0; i < NUM_EP_USED; i++ )
mbed_official 59:2af474687369 739 {
mbed_official 59:2af474687369 740 ep = &dev->ep[ i+1 ];
mbed_official 59:2af474687369 741 epNum = ep->num;
mbed_official 59:2af474687369 742
mbed_official 59:2af474687369 743 tmp = x_USB_EP_CTL[ i ] &
mbed_official 59:2af474687369 744 ~( USB_DIEP_CTL_CNAK | USB_DIEP_CTL_SNAK |
mbed_official 59:2af474687369 745 USB_DIEP_CTL_SETD0PIDEF | USB_DIEP_CTL_SETD1PIDOF );
mbed_official 59:2af474687369 746
mbed_official 59:2af474687369 747 if ( x_USB_EP_CTL[ i ] & USB_DIEP_CTL_DPIDEOF )
mbed_official 59:2af474687369 748 tmp |= USB_DIEP_CTL_SETD1PIDOF;
mbed_official 59:2af474687369 749 else
mbed_official 59:2af474687369 750 tmp |= USB_DIEP_CTL_SETD0PIDEF;
mbed_official 59:2af474687369 751
mbed_official 59:2af474687369 752 if ( x_USB_EP_CTL[ i ] & USB_DIEP_CTL_NAKSTS )
mbed_official 59:2af474687369 753 tmp |= USB_DIEP_CTL_SNAK;
mbed_official 59:2af474687369 754 else
mbed_official 59:2af474687369 755 tmp |= USB_DIEP_CTL_CNAK;
mbed_official 59:2af474687369 756
mbed_official 59:2af474687369 757 if ( ep->in )
mbed_official 59:2af474687369 758 {
mbed_official 59:2af474687369 759 USB_DINEPS[ epNum ].CTL = tmp;
mbed_official 59:2af474687369 760 USB_DINEPS[ epNum ].TSIZ = x_USB_EP_TSIZ[ i ];
mbed_official 59:2af474687369 761 USB_DINEPS[ epNum ].DMAADDR = x_USB_EP_DMAADDR[ i ];
mbed_official 59:2af474687369 762 }
mbed_official 59:2af474687369 763 else
mbed_official 59:2af474687369 764 {
mbed_official 59:2af474687369 765 USB_DOUTEPS[ epNum ].CTL = tmp;
mbed_official 59:2af474687369 766 USB_DOUTEPS[ epNum ].TSIZ = x_USB_EP_TSIZ[ i ];
mbed_official 59:2af474687369 767 USB_DOUTEPS[ epNum ].DMAADDR = x_USB_EP_DMAADDR[ i ];
mbed_official 59:2af474687369 768 }
mbed_official 59:2af474687369 769 }
mbed_official 59:2af474687369 770 #endif
mbed_official 59:2af474687369 771
mbed_official 59:2af474687369 772 USB->PCGCCTL = x_USB_PCGCCTL;
mbed_official 59:2af474687369 773 USB->DOEPMSK = x_USB_DOEPMSK;
mbed_official 59:2af474687369 774 USB->DIEPMSK = x_USB_DIEPMSK;
mbed_official 59:2af474687369 775 USB->DAINTMSK = x_USB_DAINTMSK;
mbed_official 59:2af474687369 776 USB->DCTL = x_USB_DCTL;
mbed_official 59:2af474687369 777 USB->GNPTXFSIZ = x_USB_GNPTXFSIZ;
mbed_official 59:2af474687369 778 USB->GRXFSIZ = x_USB_GRXFSIZ;
mbed_official 59:2af474687369 779 USB->GAHBCFG = x_USB_GAHBCFG;
mbed_official 59:2af474687369 780 #if defined(_USB_GOTGCTL_MASK)
mbed_official 59:2af474687369 781 USB->GOTGCTL = x_USB_GOTGCTL;
mbed_official 59:2af474687369 782 #endif
mbed_official 59:2af474687369 783 USB->GINTMSK = x_USB_GINTMSK;
mbed_official 59:2af474687369 784
mbed_official 59:2af474687369 785 USB->DCTL |= USB_DCTL_PWRONPRGDONE;
mbed_official 59:2af474687369 786
mbed_official 59:2af474687369 787 #if ( USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ENTEREM2 )
mbed_official 59:2af474687369 788 #ifndef __MBED__
mbed_official 59:2af474687369 789 /* Do not reenter EM2 on interrupt exit. */
mbed_official 59:2af474687369 790 SCB->SCR &= ~(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk);
mbed_official 59:2af474687369 791 #else
mbed_official 59:2af474687369 792 usbhal_allow_em2(false);
mbed_official 59:2af474687369 793 #endif
mbed_official 59:2af474687369 794 #endif
mbed_official 59:2af474687369 795
mbed_official 59:2af474687369 796 return true;
mbed_official 59:2af474687369 797 }
mbed_official 59:2af474687369 798 return false;
mbed_official 59:2af474687369 799 }
mbed_official 59:2af474687369 800 #endif /* if ( USB_PWRSAVE_MODE ) */
mbed_official 59:2af474687369 801
mbed_official 59:2af474687369 802 #if defined( USB_DOEP0INT_STUPPKTRCVD )
mbed_official 59:2af474687369 803 static void HandleOutEpIntr( uint32_t status, USBD_Ep_TypeDef *ep )
mbed_official 59:2af474687369 804 {
mbed_official 59:2af474687369 805 uint32_t doeptsiz;
mbed_official 59:2af474687369 806
mbed_official 59:2af474687369 807 if ( ep->num == 0 )
mbed_official 59:2af474687369 808 {
mbed_official 59:2af474687369 809 if ( status & USB_DOEP0INT_XFERCOMPL )
mbed_official 59:2af474687369 810 {
mbed_official 59:2af474687369 811 USB->DOEP0INT = USB_DOEP0INT_XFERCOMPL;
mbed_official 59:2af474687369 812 doeptsiz = USB->DOEP0TSIZ;
mbed_official 59:2af474687369 813
mbed_official 59:2af474687369 814 if ( ep->state == D_EP_IDLE )
mbed_official 59:2af474687369 815 {
mbed_official 59:2af474687369 816 if ( status & USB_DOEP0INT_STUPPKTRCVD )
mbed_official 59:2af474687369 817 {
mbed_official 59:2af474687369 818 USB->DOEP0INT = USB_DOEP0INT_STUPPKTRCVD;
mbed_official 59:2af474687369 819 }
mbed_official 59:2af474687369 820 status = USBDHAL_GetOutEpInts( ep );
mbed_official 59:2af474687369 821 doeptsiz = USB->DOEP0TSIZ;
mbed_official 59:2af474687369 822
mbed_official 59:2af474687369 823 if ( status & USB_DOEP0INT_SETUP )
mbed_official 59:2af474687369 824 {
mbed_official 59:2af474687369 825 retry:
mbed_official 59:2af474687369 826 /* Already started data stage, clear setup */
mbed_official 59:2af474687369 827 USB->DOEP0INT = USB_DOEP0INT_SETUP;
mbed_official 59:2af474687369 828 status &= ~USB_DOEP0INT_SETUP;
mbed_official 59:2af474687369 829 {
mbed_official 59:2af474687369 830 int supCnt = ( doeptsiz & _USB_DOEP0TSIZ_SUPCNT_MASK )
mbed_official 59:2af474687369 831 >> _USB_DOEP0TSIZ_SUPCNT_SHIFT;
mbed_official 59:2af474687369 832
mbed_official 59:2af474687369 833 if ( supCnt == 3 )
mbed_official 59:2af474687369 834 supCnt = 2;
mbed_official 59:2af474687369 835
mbed_official 59:2af474687369 836 dev->setup = &dev->setupPkt[ 2 - supCnt ];
mbed_official 59:2af474687369 837 }
mbed_official 59:2af474687369 838 DEBUG_USB_INT_LO_PUTS( "\nS" );
mbed_official 59:2af474687369 839 USBDEP_Ep0Handler( dev );
mbed_official 59:2af474687369 840
mbed_official 59:2af474687369 841 /* Prepare for more setup packets */
mbed_official 59:2af474687369 842 if ( ep->state == D_EP0_IN_STATUS || ep->state == D_EP_TRANSMITTING )
mbed_official 59:2af474687369 843 {
mbed_official 59:2af474687369 844 USBDHAL_StartEp0Setup( dev );
mbed_official 59:2af474687369 845 }
mbed_official 59:2af474687369 846 }
mbed_official 59:2af474687369 847 else /* xfercompl && idle && !setup */
mbed_official 59:2af474687369 848 {
mbed_official 59:2af474687369 849 status = USBDHAL_GetOutEpInts( ep );
mbed_official 59:2af474687369 850 if ( status & USB_DOEP0INT_SETUP )
mbed_official 59:2af474687369 851 goto retry;
mbed_official 59:2af474687369 852 USBDHAL_StartEp0Setup( dev );
mbed_official 59:2af474687369 853 }
mbed_official 59:2af474687369 854 }
mbed_official 59:2af474687369 855 else /* ep0state != EP0_IDLE */
mbed_official 59:2af474687369 856 {
mbed_official 59:2af474687369 857 #ifdef __MBED__
mbed_official 59:2af474687369 858 if ( ep->state == D_EP_RECEIVING )
mbed_official 59:2af474687369 859 {
mbed_official 59:2af474687369 860 int xfer_size = ep->packetSize - (( USB->DOEP0TSIZ & _USB_DOEP0TSIZ_XFERSIZE_MASK )
mbed_official 59:2af474687369 861 >> _USB_DOEP0TSIZ_XFERSIZE_SHIFT);
mbed_official 59:2af474687369 862 int setup_pkt_received = status & USB_DOEP0INT_SETUP;
mbed_official 59:2af474687369 863
mbed_official 59:2af474687369 864 if ( (!setup_pkt_received && xfer_size == 0) ||
mbed_official 59:2af474687369 865 (setup_pkt_received && xfer_size == 8) )
mbed_official 59:2af474687369 866 {
mbed_official 59:2af474687369 867 /* Higher levels need to see the correct transfer amount for ZLPs */
mbed_official 59:2af474687369 868 ep->remaining = 0;
mbed_official 59:2af474687369 869 ep->xferred = 0;
mbed_official 59:2af474687369 870 }
mbed_official 59:2af474687369 871 else
mbed_official 59:2af474687369 872 {
mbed_official 59:2af474687369 873 /* FIXME - does not work if actual read size > 56 */
mbed_official 59:2af474687369 874 if ( setup_pkt_received ) xfer_size -= 8;
mbed_official 59:2af474687369 875
mbed_official 59:2af474687369 876 ep->xferred = xfer_size;
mbed_official 59:2af474687369 877 ep->remaining -= xfer_size;
mbed_official 59:2af474687369 878 }
mbed_official 59:2af474687369 879
mbed_official 59:2af474687369 880 USBDEP_Ep0Handler( dev );
mbed_official 59:2af474687369 881 }
mbed_official 59:2af474687369 882 #else
mbed_official 59:2af474687369 883 if ( ep->state == D_EP_RECEIVING )
mbed_official 59:2af474687369 884 {
mbed_official 59:2af474687369 885 if ( ep->remaining > ep->packetSize )
mbed_official 59:2af474687369 886 {
mbed_official 59:2af474687369 887 ep->remaining -= ep->packetSize;
mbed_official 59:2af474687369 888 ep->xferred += ep->packetSize;
mbed_official 59:2af474687369 889 }
mbed_official 59:2af474687369 890 else
mbed_official 59:2af474687369 891 {
mbed_official 59:2af474687369 892 ep->xferred += ep->remaining;
mbed_official 59:2af474687369 893 ep->remaining = 0;
mbed_official 59:2af474687369 894 }
mbed_official 59:2af474687369 895 USBDEP_Ep0Handler( dev );
mbed_official 59:2af474687369 896 }
mbed_official 59:2af474687369 897 else if ( ep->state == D_EP0_OUT_STATUS )
mbed_official 59:2af474687369 898 {
mbed_official 59:2af474687369 899 USBDEP_Ep0Handler( dev );
mbed_official 59:2af474687369 900 }
mbed_official 59:2af474687369 901 #endif
mbed_official 59:2af474687369 902 }
mbed_official 59:2af474687369 903 } /* if ( status & USB_DOEP0INT_XFERCOMPL ) */
mbed_official 59:2af474687369 904
mbed_official 59:2af474687369 905 if ( status & USB_DOEP0INT_STSPHSERCVD )
mbed_official 59:2af474687369 906 {
mbed_official 59:2af474687369 907 USB->DOEP0INT = USB_DOEP0INT_STSPHSERCVD;
mbed_official 59:2af474687369 908 }
mbed_official 59:2af474687369 909
mbed_official 59:2af474687369 910 if ( status & USB_DOEP0INT_SETUP )
mbed_official 59:2af474687369 911 {
mbed_official 59:2af474687369 912 USB->DOEP0INT = USB_DOEP0INT_SETUP;
mbed_official 59:2af474687369 913 {
mbed_official 59:2af474687369 914 int supCnt = ( USB->DOEP0TSIZ & _USB_DOEP0TSIZ_SUPCNT_MASK )
mbed_official 59:2af474687369 915 >> _USB_DOEP0TSIZ_SUPCNT_SHIFT;
mbed_official 59:2af474687369 916
mbed_official 59:2af474687369 917 if ( supCnt == 3 )
mbed_official 59:2af474687369 918 supCnt = 2;
mbed_official 59:2af474687369 919
mbed_official 59:2af474687369 920 dev->setup = &dev->setupPkt[ 2 - supCnt ];
mbed_official 59:2af474687369 921 }
mbed_official 59:2af474687369 922 DEBUG_USB_INT_LO_PUTS( "\nS" );
mbed_official 59:2af474687369 923 USBDEP_Ep0Handler( dev );
mbed_official 59:2af474687369 924 }
mbed_official 59:2af474687369 925 }
mbed_official 59:2af474687369 926 else /* epnum != 0 */
mbed_official 59:2af474687369 927 {
mbed_official 59:2af474687369 928 if ( status & USB_DOEP_INT_XFERCOMPL )
mbed_official 59:2af474687369 929 {
mbed_official 59:2af474687369 930 USB_DOUTEPS[ ep->num ].INT = USB_DOEP_INT_XFERCOMPL;
mbed_official 59:2af474687369 931
mbed_official 59:2af474687369 932 ep->xferred = ep->hwXferSize -
mbed_official 59:2af474687369 933 ( ( USB_DOUTEPS[ ep->num ].TSIZ & _USB_DOEP_TSIZ_XFERSIZE_MASK )>>
mbed_official 59:2af474687369 934 _USB_DOEP_TSIZ_XFERSIZE_SHIFT );
mbed_official 59:2af474687369 935 ep->remaining -= ep->xferred;
mbed_official 59:2af474687369 936
mbed_official 59:2af474687369 937 USBDEP_EpHandler( ep->addr );
mbed_official 59:2af474687369 938 }
mbed_official 59:2af474687369 939 }
mbed_official 59:2af474687369 940 }
mbed_official 59:2af474687369 941 #endif
mbed_official 59:2af474687369 942
mbed_official 59:2af474687369 943 /** @endcond */
mbed_official 59:2af474687369 944
mbed_official 59:2af474687369 945 #endif /* defined( USB_DEVICE ) */
mbed_official 59:2af474687369 946 #endif /* defined( USB_PRESENT ) && ( USB_COUNT == 1 ) */