17 #if defined( USB_PRESENT ) && ( USB_COUNT == 1 )
19 #if defined( USB_DEVICE )
28 #define HANDLE_INT( x ) if ( status & x ) { Handle_##x(); status &= ~x; }
30 static void Handle_USB_GINTSTS_ENUMDONE (
void );
31 static void Handle_USB_GINTSTS_IEPINT (
void );
32 static void Handle_USB_GINTSTS_OEPINT (
void );
33 static void Handle_USB_GINTSTS_RESETDET (
void );
34 static void Handle_USB_GINTSTS_SOF (
void );
35 static void Handle_USB_GINTSTS_USBRST (
void );
36 static void Handle_USB_GINTSTS_USBSUSP (
void );
37 static void Handle_USB_GINTSTS_WKUPINT (
void );
38 #if defined( USB_DOEP0INT_STUPPKTRCVD )
39 static void HandleOutEpIntr( uint32_t status, USBD_Ep_TypeDef *ep );
41 static void ProcessSetup (
void );
42 static void ProcessOepData ( USBD_Ep_TypeDef *ep );
45 #if ( USB_PWRSAVE_MODE )
47 static bool UsbPowerDown(
void );
48 static bool UsbPowerUp(
void );
50 volatile bool USBD_poweredDown =
false;
53 static uint32_t x_USB_GINTMSK;
54 #if defined(_USB_GOTGCTL_MASK)
55 static uint32_t x_USB_GOTGCTL;
57 static uint32_t x_USB_GAHBCFG;
58 static uint32_t x_USB_GUSBCFG;
59 static uint32_t x_USB_GRXFSIZ;
60 static uint32_t x_USB_GNPTXFSIZ;
61 static uint32_t x_USB_DCFG;
62 static uint32_t x_USB_DCTL;
63 static uint32_t x_USB_DAINTMSK;
64 static uint32_t x_USB_DIEPMSK;
65 static uint32_t x_USB_DOEPMSK;
66 static uint32_t x_USB_PCGCCTL;
68 #if ( NUM_EP_USED > 0 )
69 static uint32_t x_USB_EP_CTL[ NUM_EP_USED ];
70 static uint32_t x_USB_EP_TSIZ[ NUM_EP_USED ];
71 static uint32_t x_USB_EP_DMAADDR[ NUM_EP_USED ];
74 #if ( NUM_EP_USED > MAX_NUM_TX_FIFOS )
75 #define FIFO_CNT MAX_NUM_TX_FIFOS
77 #define FIFO_CNT NUM_EP_USED
81 static uint32_t x_USB_DIEPTXFS[ FIFO_CNT ];
84 #if ( USB_PWRSAVE_MODE )
85 static uint32_t cmuStatus = 0;
93 void USB_IRQHandler(
void )
96 bool servedVbusInterrupt =
false;
100 #if ( USB_PWRSAVE_MODE )
101 if ( USBD_poweredDown )
108 #if defined( CMU_OSCENCMD_USHFRCOEN )
109 if ( (
CMU->STATUS & CMU_STATUS_USHFRCOENS ) == 0 )
111 CMU->OSCENCMD = ( cmuStatus
113 | CMU_OSCENCMD_USHFRCOEN;
118 CMU->OSCENCMD = cmuStatus
124 #if defined( CMU_OSCENCMD_USHFRCOEN )
125 CMU->CMD = CMU_CMD_USBCCLKSEL_USHFRCO;
126 while ( (
CMU->STATUS & CMU_STATUS_USBCUSHFRCOSEL ) == 0 ){}
142 servedVbusInterrupt =
true;
143 DEBUG_USB_INT_LO_PUTS(
"\nVboN" );
145 #if ( USB_PWRSAVE_MODE )
148 USBDHAL_EnableUsbResetAndSuspendInt();
161 servedVbusInterrupt =
true;
162 DEBUG_USB_INT_LO_PUTS(
"\nVboF" );
164 #if ( USB_PWRSAVE_MODE )
165 #if ( USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF )
166 if ( !USBD_poweredDown )
169 USB->GINTSTS = 0xFFFFFFFF;
180 status = USBHAL_GetCoreInts();
184 if ( !servedVbusInterrupt )
186 DEBUG_USB_INT_LO_PUTS(
"\nSinT" );
204 DEBUG_USB_INT_LO_PUTS(
"\nUinT" );
212 static void Handle_USB_GINTSTS_ENUMDONE(
void )
214 #if ( USB_PWRSAVE_MODE )
218 USBDHAL_Ep0Activate( dev->ep0MpsCode );
219 dev->ep[ 0 ].state = D_EP_IDLE;
220 USBDHAL_EnableInts( dev );
221 DEBUG_USB_INT_LO_PUTS(
"EnumD" );
227 static void Handle_USB_GINTSTS_IEPINT(
void )
235 DEBUG_USB_INT_HI_PUTCHAR(
'i' );
237 epint = USBDHAL_GetAllInEpInts();
238 for ( epnum = 0, epmask = 1;
239 epnum <= MAX_NUM_IN_EPS;
240 epnum++, epmask <<= 1 )
242 if ( epint & epmask )
245 status = USBDHAL_GetInEpInts( ep );
251 DEBUG_USB_INT_HI_PUTCHAR(
'c' );
255 if ( ep->remaining > ep->packetSize )
257 ep->remaining -= ep->packetSize;
258 ep->xferred += ep->packetSize;
262 ep->xferred += ep->remaining;
265 USBDEP_Ep0Handler( dev );
269 ep->xferred = ep->remaining -
270 ( ( USB_DINEPS[ epnum ].TSIZ &
273 ep->remaining -= ep->xferred;
275 USBDEP_EpHandler( ep->addr );
276 #if defined( USB_DOEP0INT_STUPPKTRCVD )
291 static void Handle_USB_GINTSTS_OEPINT(
void )
299 DEBUG_USB_INT_HI_PUTCHAR(
'o' );
301 epint = USBDHAL_GetAllOutEpInts();
302 for ( epnum = 0, epmask = 1;
303 epnum <= MAX_NUM_OUT_EPS;
304 epnum++, epmask <<= 1 )
306 if ( epint & epmask )
308 ep = USBD_GetEpFromAddr( epnum );
309 status = USBDHAL_GetOutEpInts( ep );
311 #if defined( USB_DOEP0INT_STUPPKTRCVD )
312 HandleOutEpIntr( status, ep );
317 DEBUG_USB_INT_HI_PUTCHAR(
'c' );
318 ProcessOepData( ep );
331 #if !defined( USB_DOEP0INT_STUPPKTRCVD )
332 static void ProcessOepData( USBD_Ep_TypeDef *ep )
336 if ( ep->remaining > ep->packetSize )
338 ep->remaining -= ep->packetSize;
339 ep->xferred += ep->packetSize;
343 ep->xferred += ep->remaining;
346 USBDEP_Ep0Handler( dev );
350 ep->xferred = ep->hwXferSize -
353 ep->remaining -= ep->xferred;
354 USBDEP_EpHandler( ep->addr );
359 #if !defined( USB_DOEP0INT_STUPPKTRCVD )
360 static void ProcessSetup(
void )
362 DEBUG_USB_INT_LO_PUTS(
"\nS" );
367 DEBUG_USB_INT_LO_PUTS(
"B2B" );
380 dev->setup = &dev->setupPkt[ 2 - supCnt ];
383 USB->DOEP0DMAADDR = (uint32_t)dev->setupPkt;
386 USBDEP_Ep0Handler( dev );
393 static void Handle_USB_GINTSTS_RESETDET (
void )
395 #if ( USB_PWRSAVE_MODE )
396 if ( ! USBD_poweredDown )
406 #if ( USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF )
426 DEBUG_USB_INT_LO_PUTS(
"RsuP\n" );
432 static void Handle_USB_GINTSTS_SOF(
void )
436 if ( dev->callbacks->sofInt )
438 dev->callbacks->sofInt(
446 static void Handle_USB_GINTSTS_USBRST(
void )
450 DEBUG_USB_INT_LO_PUTS(
"ReseT" );
454 USBHAL_FlushTxFifo( 0 );
457 for ( i = 0; i <= MAX_NUM_IN_EPS; i++ )
459 USB_DINEPS[ i ].INT = 0xFFFFFFFF;
462 for ( i = 0; i <= MAX_NUM_OUT_EPS; i++ )
464 USB_DOUTEPS[ i ].INT = 0xFFFFFFFF;
468 #if defined( USB_DOEPMSK_STSPHSERCVDMSK )
470 | USB_DOEPMSK_STSPHSERCVDMSK;
480 USBDHAL_StartEp0Setup( dev );
481 USBDHAL_EnableInts( dev );
483 if ( dev->callbacks->usbReset )
485 dev->callbacks->usbReset();
495 static void Handle_USB_GINTSTS_USBSUSP(
void )
501 DEBUG_USB_INT_LO_PUTS(
"\nSusP" );
514 #if ( USB_PWRSAVE_MODE )
524 static void Handle_USB_GINTSTS_WKUPINT(
void )
526 #if ( USB_PWRSAVE_MODE )
527 if ( ! USBD_poweredDown )
535 USBDHAL_StartEp0Setup( dev );
536 USBDHAL_Ep0Activate( dev->ep0MpsCode );
542 USBD_SetUsbState( dev->savedState );
543 DEBUG_USB_INT_LO_PUTS(
"WkuP\n" );
546 #if ( USB_PWRSAVE_MODE )
551 static bool UsbPowerDown(
void )
553 #if ( NUM_EP_USED > 0 ) || ( FIFO_CNT > 0 )
556 #if ( NUM_EP_USED > 0 )
561 if ( !USBD_poweredDown )
563 USBD_poweredDown =
true;
564 DEBUG_USB_INT_LO_PUTCHAR(
'\\' );
567 x_USB_GINTMSK =
USB->GINTMSK;
568 #if defined(_USB_GOTGCTL_MASK)
569 x_USB_GOTGCTL =
USB->GOTGCTL;
571 x_USB_GAHBCFG =
USB->GAHBCFG;
572 x_USB_GUSBCFG =
USB->GUSBCFG;
573 x_USB_GRXFSIZ =
USB->GRXFSIZ;
574 x_USB_GNPTXFSIZ =
USB->GNPTXFSIZ;
575 x_USB_DCFG =
USB->DCFG;
576 x_USB_DCTL =
USB->DCTL;
577 x_USB_DAINTMSK =
USB->DAINTMSK;
578 x_USB_DIEPMSK =
USB->DIEPMSK;
579 x_USB_DOEPMSK =
USB->DOEPMSK;
580 x_USB_PCGCCTL =
USB->PCGCCTL;
582 #if ( NUM_EP_USED > 0 )
583 for ( i = 0; i < NUM_EP_USED; i++ )
585 ep = &dev->ep[ i+1 ];
589 x_USB_EP_CTL[ i ] = USB_DINEPS[ epNum ].CTL;
590 x_USB_EP_TSIZ[ i ] = USB_DINEPS[ epNum ].TSIZ;
591 x_USB_EP_DMAADDR[ i ] = USB_DINEPS[ epNum ].DMAADDR;
595 x_USB_EP_CTL[ i ] = USB_DOUTEPS[ epNum ].CTL;
596 x_USB_EP_TSIZ[ i ] = USB_DOUTEPS[ epNum ].TSIZ;
597 x_USB_EP_DMAADDR[ i ] = USB_DOUTEPS[ epNum ].DMAADDR;
603 for ( i = 0; i < FIFO_CNT; i++ )
605 x_USB_DIEPTXFS[ i ] = USB_DIEPTXFS[ i ];
621 cmuStatus =
CMU->STATUS;
623 #if ( USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ENTEREM2 )
625 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk;
629 #if ( USB_USBC_32kHz_CLK == USB_USBC_32kHz_CLK_LFXO )
643 #if ( USB_PWRSAVE_MODE )
649 static bool UsbPowerUp(
void )
651 #if ( NUM_EP_USED > 0 ) || ( FIFO_CNT > 0 )
654 #if ( NUM_EP_USED > 0 )
660 if ( USBD_poweredDown )
662 USBD_poweredDown =
false;
663 DEBUG_USB_INT_LO_PUTCHAR(
'/' );
665 #if !defined( USB_CORECLK_HFRCO ) || !defined( CMU_OSCENCMD_USHFRCOEN )
683 USB->DCTL = x_USB_DCTL;
687 USB->GUSBCFG = x_USB_GUSBCFG;
688 USB->DCFG = x_USB_DCFG;
691 for ( i = 0; i < FIFO_CNT; i++ )
693 USB_DIEPTXFS[ i ] = x_USB_DIEPTXFS[ i ];
697 #if ( NUM_EP_USED > 0 )
698 for ( i = 0; i < NUM_EP_USED; i++ )
700 ep = &dev->ep[ i+1 ];
703 tmp = x_USB_EP_CTL[ i ] &
719 USB_DINEPS[ epNum ].CTL = tmp;
720 USB_DINEPS[ epNum ].TSIZ = x_USB_EP_TSIZ[ i ];
721 USB_DINEPS[ epNum ].DMAADDR = x_USB_EP_DMAADDR[ i ];
725 USB_DOUTEPS[ epNum ].CTL = tmp;
726 USB_DOUTEPS[ epNum ].TSIZ = x_USB_EP_TSIZ[ i ];
727 USB_DOUTEPS[ epNum ].DMAADDR = x_USB_EP_DMAADDR[ i ];
732 USB->PCGCCTL = x_USB_PCGCCTL;
733 USB->DOEPMSK = x_USB_DOEPMSK;
734 USB->DIEPMSK = x_USB_DIEPMSK;
735 USB->DAINTMSK = x_USB_DAINTMSK;
736 USB->DCTL = x_USB_DCTL;
737 USB->GNPTXFSIZ = x_USB_GNPTXFSIZ;
738 USB->GRXFSIZ = x_USB_GRXFSIZ;
739 USB->GAHBCFG = x_USB_GAHBCFG;
740 #if defined(_USB_GOTGCTL_MASK)
741 USB->GOTGCTL = x_USB_GOTGCTL;
743 USB->GINTMSK = x_USB_GINTMSK;
747 #if ( USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ENTEREM2 )
749 SCB->SCR &= ~(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk);
758 #if defined( USB_DOEP0INT_STUPPKTRCVD )
759 static void HandleOutEpIntr( uint32_t status, USBD_Ep_TypeDef *ep )
768 doeptsiz =
USB->DOEP0TSIZ;
770 if ( ep->state == D_EP_IDLE )
772 if ( status & USB_DOEP0INT_STUPPKTRCVD )
774 USB->DOEP0INT = USB_DOEP0INT_STUPPKTRCVD;
776 status = USBDHAL_GetOutEpInts( ep );
777 doeptsiz =
USB->DOEP0TSIZ;
784 status &= ~USB_DOEP0INT_SETUP;
792 dev->setup = &dev->setupPkt[ 2 - supCnt ];
794 DEBUG_USB_INT_LO_PUTS(
"\nS" );
795 USBDEP_Ep0Handler( dev );
798 if ( ep->state == D_EP0_IN_STATUS || ep->state == D_EP_TRANSMITTING )
800 USBDHAL_StartEp0Setup( dev );
805 status = USBDHAL_GetOutEpInts( ep );
806 if ( status & USB_DOEP0INT_SETUP )
808 USBDHAL_StartEp0Setup( dev );
813 if ( ep->state == D_EP_RECEIVING )
815 if ( ep->remaining > ep->packetSize )
817 ep->remaining -= ep->packetSize;
818 ep->xferred += ep->packetSize;
822 ep->xferred += ep->remaining;
825 USBDEP_Ep0Handler( dev );
827 else if ( ep->state == D_EP0_OUT_STATUS )
829 USBDEP_Ep0Handler( dev );
834 if ( status & USB_DOEP0INT_STSPHSERCVD )
836 USB->DOEP0INT = USB_DOEP0INT_STSPHSERCVD;
839 if ( status & USB_DOEP0INT_SETUP )
849 dev->setup = &dev->setupPkt[ 2 - supCnt ];
851 DEBUG_USB_INT_LO_PUTS(
"\nS" );
852 USBDEP_Ep0Handler( dev );
861 ep->xferred = ep->hwXferSize -
864 ep->remaining -= ep->xferred;
866 USBDEP_EpHandler( ep->addr );
USB protocol stack library API for EFM32/EZR32.
Clock management unit (CMU) API.
void CMU_ClockSelectSet(CMU_Clock_TypeDef clock, CMU_Select_TypeDef ref)
Select reference clock/oscillator used for a clock branch.
#define USB_DCTL_PWRONPRGDONE
#define USB_DOEP_INT_XFERCOMPL
#define _USB_DCFG_DEVADDR_MASK
#define _USB_DCFG_RESVALID_MASK
#define USB_DIEP_CTL_SETD1PIDOF
#define USB_GINTSTS_WKUPINT
#define USB_STATUS_VREGOS
#define CMU_CMD_USBCCLKSEL_HFCLKNODIV
#define USB_GINTSTS_OEPINT
#define _USB_DOEP_TSIZ_XFERSIZE_SHIFT
#define CMU_STATUS_HFRCOENS
#define USB_DCFG_ENA32KHZSUSP
__STATIC_INLINE uint32_t INT_Enable(void)
Enable interrupts.
#define USB_DIEP_INT_XFERCOMPL
#define CMU_CMD_USBCCLKSEL_LFRCO
#define USB_PCGCCTL_STOPPCLK
CMSIS Cortex-M Peripheral Access Layer for Silicon Laboratories microcontroller devices.
#define USB_SETUP_DIR_MASK
#define _USB_DSTS_SOFFN_SHIFT
#define CMU_CMD_USBCCLKSEL_LFXO
#define USB_CTRL_VREGOSEN
#define _USB_DOEP0TSIZ_SUPCNT_SHIFT
#define USB_PCGCCTL_PWRCLMP
#define CMU_STATUS_AUXHFRCOENS
#define USB_GINTSTS_USBRST
#define _USB_DSTS_SOFFN_MASK
#define USB_GINTMSK_RESETDETMSK
#define USB_DCTL_RMTWKUPSIG
#define USB_DIEP_CTL_SNAK
USB Setup request package.
#define USB_DIEP_INT_NAKINTRPT
USBD_State_TypeDef
USB device state enumerator.
#define CMU_STATUS_USBCLFRCOSEL
#define USB_DAINTMSK_OUTEPMSK0
#define _USB_DIEP_TSIZ_XFERSIZE_SHIFT
#define USB_DIEPMSK_XFERCOMPLMSK
#define USB_DIEP_CTL_NAKSTS
USB protocol stack library API for EFM32/EZR32.
#define CMU_OSCENCMD_HFRCODIS
#define CMU_STATUS_USBCLFXOSEL
#define USB_DIEP_CTL_DPIDEOF
#define USB_DOEP0INT_XFERCOMPL
#define USB_DIEP_CTL_SETD0PIDEF
#define USB_DOEPMSK_SETUPMSK
#define USB_DOEP0INT_SETUP
#define USB_DOEPMSK_XFERCOMPLMSK
#define _USB_DIEP_TSIZ_XFERSIZE_MASK
#define USB_GINTSTS_RESETDET
USBD_State_TypeDef USBD_GetUsbState(void)
Get current USB device state.
#define USB_DIEP_CTL_CNAK
#define USB_GINTSTS_IEPINT
#define CMU_STATUS_HFXOENS
#define USB_DAINTMSK_INEPMSK0
USB protocol stack library, low level USB peripheral access.
#define USB_PCGCCTL_RSTPDWNMODULE
#define _USB_DCFG_RESVALID_SHIFT
#define CMU_STATUS_USBCHFCLKSEL
#define USB_GINTSTS_ENUMDONE
#define USB_GINTMSK_WKUPINTMSK
__STATIC_INLINE uint32_t INT_Disable(void)
Disable interrupts.
#define USB_SETUP_PKT_SIZE
#define _USB_DOEP_TSIZ_XFERSIZE_MASK
USB protocol stack library, internal type definitions.
#define _USB_DOEP0TSIZ_SUPCNT_MASK
#define USB_GINTSTS_USBSUSP
#define USB_DOEP0INT_BACK2BACKSETUP