USB device stack

Dependents:   mbed_11U24_CapacitorDose_V001

Committer:
H_Tsunemoto
Date:
Fri Nov 22 08:17:42 2019 +0000
Revision:
72:ff90dd9ad449
Parent:
71:53949e6131f6
CpaDose

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