USB device stack

Dependents:   USBMSD_step1 USBMSD_step1_5 picossd_step1_2cs

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

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

Who changed what in which revision?

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