17 #if defined( USB_PRESENT ) && ( USB_COUNT == 1 )
19 #if defined( USB_DEVICE )
29 #define HANDLE_INT( x ) if ( status & x ) { Handle_##x(); status &= ~x; }
31 static void Handle_USB_GINTSTS_ENUMDONE (
void );
32 static void Handle_USB_GINTSTS_IEPINT (
void );
33 static void Handle_USB_GINTSTS_OEPINT (
void );
34 static void Handle_USB_GINTSTS_RESETDET (
void );
35 static void Handle_USB_GINTSTS_SOF (
void );
36 static void Handle_USB_GINTSTS_USBRST (
void );
37 static void Handle_USB_GINTSTS_USBSUSP (
void );
38 static void Handle_USB_GINTSTS_WKUPINT (
void );
39 #if defined( USB_DOEP0INT_STUPPKTRCVD )
40 static void HandleOutEpIntr( uint32_t status, USBD_Ep_TypeDef *ep );
42 static void ProcessSetup (
void );
43 static void ProcessOepData ( USBD_Ep_TypeDef *ep );
46 #if ( USB_PWRSAVE_MODE )
48 static bool UsbPowerDown(
void );
49 static bool UsbPowerUp(
void );
50 static void RestoreEpCtrlRegisters(
void);
52 volatile bool USBD_poweredDown =
false;
55 static uint32_t x_USB_GINTMSK;
56 #if defined(_USB_GOTGCTL_MASK)
57 static uint32_t x_USB_GOTGCTL;
59 static uint32_t x_USB_GAHBCFG;
60 static uint32_t x_USB_GUSBCFG;
61 static uint32_t x_USB_GRXFSIZ;
62 static uint32_t x_USB_GNPTXFSIZ;
63 static uint32_t x_USB_DCFG;
64 static uint32_t x_USB_DCTL;
65 static uint32_t x_USB_DAINTMSK;
66 static uint32_t x_USB_DIEPMSK;
67 static uint32_t x_USB_DOEPMSK;
68 static uint32_t x_USB_PCGCCTL;
70 #if ( NUM_EP_USED > 0 )
71 static uint32_t x_USB_EP_CTL[ NUM_EP_USED ];
72 static uint32_t x_USB_EP_TSIZ[ NUM_EP_USED ];
73 static uint32_t x_USB_EP_DMAADDR[ NUM_EP_USED ];
76 #if ( NUM_EP_USED > MAX_NUM_TX_FIFOS )
77 #define FIFO_CNT MAX_NUM_TX_FIFOS
79 #define FIFO_CNT NUM_EP_USED
83 static uint32_t x_USB_DIEPTXFS[ FIFO_CNT ];
86 #if ( USB_PWRSAVE_MODE )
87 static uint32_t cmuStatus = 0;
95 void USB_IRQHandler(
void )
98 bool servedVbusInterrupt =
false;
103 #if ( USB_PWRSAVE_MODE )
104 if ( USBD_poweredDown )
111 #if defined( CMU_OSCENCMD_USHFRCOEN )
114 CMU->OSCENCMD = ( cmuStatus
121 CMU->OSCENCMD = cmuStatus
127 #if defined( CMU_OSCENCMD_USHFRCOEN )
131 CMU->CMD = CMU_CMD_USBCCLKSEL_HFCLKNODIV;
132 while ( (
CMU->STATUS & CMU_STATUS_USBCHFCLKSEL ) == 0 ){}
145 servedVbusInterrupt =
true;
146 DEBUG_USB_INT_LO_PUTS(
"\nVboN" );
148 #if ( USB_PWRSAVE_MODE )
151 USBDHAL_EnableUsbResetAndSuspendInt();
164 servedVbusInterrupt =
true;
165 DEBUG_USB_INT_LO_PUTS(
"\nVboF" );
167 #if ( USB_PWRSAVE_MODE )
168 #if ( USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF )
169 if ( !USBD_poweredDown )
172 USB->GINTSTS = 0xFFFFFFFF;
183 status = USBHAL_GetCoreInts();
187 if ( !servedVbusInterrupt )
189 DEBUG_USB_INT_LO_PUTS(
"\nSinT" );
207 DEBUG_USB_INT_LO_PUTS(
"\nUinT" );
215 static void Handle_USB_GINTSTS_ENUMDONE(
void )
217 #if ( USB_PWRSAVE_MODE )
221 USBDHAL_Ep0Activate( dev->ep0MpsCode );
222 dev->ep[ 0 ].state = D_EP_IDLE;
223 USBDHAL_EnableInts( dev );
224 DEBUG_USB_INT_LO_PUTS(
"EnumD" );
230 static void Handle_USB_GINTSTS_IEPINT(
void )
238 DEBUG_USB_INT_HI_PUTCHAR(
'i' );
243 USBD_SetUsbState( dev->savedState );
246 epint = USBDHAL_GetAllInEpInts();
247 for ( epnum = 0, epmask = 1;
248 epnum <= MAX_NUM_IN_EPS;
249 epnum++, epmask <<= 1 )
251 if ( epint & epmask )
254 status = USBDHAL_GetInEpInts( ep );
260 DEBUG_USB_INT_HI_PUTCHAR(
'c' );
264 if ( ep->remaining > ep->packetSize )
266 ep->remaining -= ep->packetSize;
267 ep->xferred += ep->packetSize;
271 ep->xferred += ep->remaining;
274 USBDEP_Ep0Handler( dev );
278 ep->xferred = ep->remaining -
279 ( ( USB_DINEPS[ epnum ].TSIZ &
282 ep->remaining -= ep->xferred;
284 USBDEP_EpHandler( ep->addr );
285 #if defined( USB_DOEP0INT_STUPPKTRCVD )
300 static void Handle_USB_GINTSTS_OEPINT(
void )
308 DEBUG_USB_INT_HI_PUTCHAR(
'o' );
313 USBD_SetUsbState( dev->savedState );
316 epint = USBDHAL_GetAllOutEpInts();
317 for ( epnum = 0, epmask = 1;
318 epnum <= MAX_NUM_OUT_EPS;
319 epnum++, epmask <<= 1 )
321 if ( epint & epmask )
323 ep = USBD_GetEpFromAddr( epnum );
324 status = USBDHAL_GetOutEpInts( ep );
326 #if defined( USB_DOEP0INT_STUPPKTRCVD )
327 HandleOutEpIntr( status, ep );
332 DEBUG_USB_INT_HI_PUTCHAR(
'c' );
333 ProcessOepData( ep );
346 #if !defined( USB_DOEP0INT_STUPPKTRCVD )
347 static void ProcessOepData( USBD_Ep_TypeDef *ep )
351 if ( ep->remaining > ep->packetSize )
353 ep->remaining -= ep->packetSize;
354 ep->xferred += ep->packetSize;
358 ep->xferred += ep->remaining;
361 USBDEP_Ep0Handler( dev );
365 ep->xferred = ep->hwXferSize -
368 ep->remaining -= ep->xferred;
369 USBDEP_EpHandler( ep->addr );
374 #if !defined( USB_DOEP0INT_STUPPKTRCVD )
375 static void ProcessSetup(
void )
377 DEBUG_USB_INT_LO_PUTS(
"\nS" );
382 DEBUG_USB_INT_LO_PUTS(
"B2B" );
395 dev->setup = &dev->setupPkt[ 2 - supCnt ];
398 USB->DOEP0DMAADDR = (uint32_t)dev->setupPkt;
401 USBDEP_Ep0Handler( dev );
408 static void Handle_USB_GINTSTS_RESETDET (
void )
410 #if ( USB_PWRSAVE_MODE )
411 if ( ! USBD_poweredDown )
421 #if ( USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF )
441 DEBUG_USB_INT_LO_PUTS(
"RsuP\n" );
447 static void Handle_USB_GINTSTS_SOF(
void )
451 if ( dev->callbacks->sofInt )
453 dev->callbacks->sofInt(
461 static void Handle_USB_GINTSTS_USBRST(
void )
465 DEBUG_USB_INT_LO_PUTS(
"ReseT" );
469 USBHAL_FlushTxFifo( 0 );
472 for ( i = 0; i <= MAX_NUM_IN_EPS; i++ )
474 USB_DINEPS[ i ].INT = 0xFFFFFFFF;
477 for ( i = 0; i <= MAX_NUM_OUT_EPS; i++ )
479 USB_DOUTEPS[ i ].INT = 0xFFFFFFFF;
483 #if defined( USB_DOEPMSK_STSPHSERCVDMSK )
495 USBDHAL_StartEp0Setup( dev );
496 USBDHAL_EnableInts( dev );
498 if ( dev->callbacks->usbReset )
500 dev->callbacks->usbReset();
510 static void Handle_USB_GINTSTS_USBSUSP(
void )
516 DEBUG_USB_INT_LO_PUTS(
"\nSusP" );
529 #if ( USB_PWRSAVE_MODE )
539 static void Handle_USB_GINTSTS_WKUPINT(
void )
541 #if ( USB_PWRSAVE_MODE )
542 if ( ! USBD_poweredDown )
550 USBDHAL_StartEp0Setup( dev );
551 USBDHAL_Ep0Activate( dev->ep0MpsCode );
557 USBD_SetUsbState( dev->savedState );
558 DEBUG_USB_INT_LO_PUTS(
"WkuP\n" );
561 #if ( USB_PWRSAVE_MODE )
566 static bool UsbPowerDown(
void )
568 #if ( NUM_EP_USED > 0 ) || ( FIFO_CNT > 0 )
571 #if ( NUM_EP_USED > 0 )
576 if ( !USBD_poweredDown )
578 USBD_poweredDown =
true;
579 DEBUG_USB_INT_LO_PUTCHAR(
'\\' );
582 x_USB_GINTMSK =
USB->GINTMSK;
583 #if defined(_USB_GOTGCTL_MASK)
584 x_USB_GOTGCTL =
USB->GOTGCTL;
586 x_USB_GAHBCFG =
USB->GAHBCFG;
587 x_USB_GUSBCFG =
USB->GUSBCFG;
588 x_USB_GRXFSIZ =
USB->GRXFSIZ;
589 x_USB_GNPTXFSIZ =
USB->GNPTXFSIZ;
590 x_USB_DCFG =
USB->DCFG;
591 x_USB_DCTL =
USB->DCTL;
592 x_USB_DAINTMSK =
USB->DAINTMSK;
593 x_USB_DIEPMSK =
USB->DIEPMSK;
594 x_USB_DOEPMSK =
USB->DOEPMSK;
595 x_USB_PCGCCTL =
USB->PCGCCTL;
597 #if ( NUM_EP_USED > 0 )
598 for ( i = 0; i < NUM_EP_USED; i++ )
600 ep = &dev->ep[ i+1 ];
604 x_USB_EP_CTL[ i ] = USB_DINEPS[ epNum ].CTL;
605 x_USB_EP_TSIZ[ i ] = USB_DINEPS[ epNum ].TSIZ;
606 x_USB_EP_DMAADDR[ i ] = USB_DINEPS[ epNum ].DMAADDR;
610 x_USB_EP_CTL[ i ] = USB_DOUTEPS[ epNum ].CTL;
611 x_USB_EP_TSIZ[ i ] = USB_DOUTEPS[ epNum ].TSIZ;
612 x_USB_EP_DMAADDR[ i ] = USB_DOUTEPS[ epNum ].DMAADDR;
618 for ( i = 0; i < FIFO_CNT; i++ )
620 x_USB_DIEPTXFS[ i ] = USB_DIEPTXFS[ i ];
636 cmuStatus =
CMU->STATUS;
638 #if ( USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ENTEREM2 )
640 SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk;
644 #if ( USB_USBC_32kHz_CLK == USB_USBC_32kHz_CLK_LFXO )
658 #if ( USB_PWRSAVE_MODE )
664 static bool UsbPowerUp(
void )
666 if ( USBD_poweredDown )
668 USBD_poweredDown =
false;
669 DEBUG_USB_INT_LO_PUTCHAR(
'/' );
671 #if !defined( USB_CORECLK_HFRCO ) || !defined( CMU_OSCENCMD_USHFRCOEN )
689 USB->DCTL = x_USB_DCTL;
693 USB->GUSBCFG = x_USB_GUSBCFG;
694 USB->DCFG = x_USB_DCFG;
696 RestoreEpCtrlRegisters();
698 USB->PCGCCTL = x_USB_PCGCCTL;
699 USB->DOEPMSK = x_USB_DOEPMSK;
700 USB->DIEPMSK = x_USB_DIEPMSK;
701 USB->DAINTMSK = x_USB_DAINTMSK;
702 USB->DCTL = x_USB_DCTL;
703 USB->GNPTXFSIZ = x_USB_GNPTXFSIZ;
704 USB->GRXFSIZ = x_USB_GRXFSIZ;
705 USB->GAHBCFG = x_USB_GAHBCFG;
706 #if defined(_USB_GOTGCTL_MASK)
707 USB->GOTGCTL = x_USB_GOTGCTL;
709 USB->GINTMSK = x_USB_GINTMSK;
713 #if ( USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ENTEREM2 )
715 SCB->SCR &= ~(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk);
728 void USBDINT_RemoteWakeup(
void)
730 #if (USB_PWRSAVE_MODE)
731 if (USBD_poweredDown)
733 USBD_poweredDown =
false;
734 DEBUG_USB_INT_LO_PUTCHAR(
'|');
737 #if defined( CMU_OSCENCMD_USHFRCOEN )
740 CMU->OSCENCMD = ( cmuStatus
747 CMU->OSCENCMD = cmuStatus
752 #if !defined( USB_CORECLK_HFRCO ) || !defined( CMU_OSCENCMD_USHFRCOEN )
758 #if defined( CMU_OSCENCMD_USHFRCOEN )
762 CMU->CMD = CMU_CMD_USBCCLKSEL_HFCLKNODIV;
763 while ( (
CMU->STATUS & CMU_STATUS_USBCHFCLKSEL ) == 0 ){}
771 USB->GUSBCFG = x_USB_GUSBCFG;
772 USB->DCFG = x_USB_DCFG;
778 USB->GINTSTS = 0xFFFFFFFF;
780 RestoreEpCtrlRegisters();
782 USB->DOEPMSK = x_USB_DOEPMSK;
783 USB->DIEPMSK = x_USB_DIEPMSK;
784 USB->DAINTMSK = x_USB_DAINTMSK;
785 USB->GNPTXFSIZ = x_USB_GNPTXFSIZ;
786 USB->GRXFSIZ = x_USB_GRXFSIZ;
787 USB->GAHBCFG = x_USB_GAHBCFG;
788 #if defined(_USB_GOTGCTL_MASK)
789 USB->GOTGCTL = x_USB_GOTGCTL;
791 USB->GINTMSK = x_USB_GINTMSK;
793 #if ( USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ENTEREM2 )
795 SCB->SCR &= ~(SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk);
802 USBDHAL_ClearRemoteWakeup();
804 USBDHAL_StartEp0Setup( dev );
805 USBDHAL_Ep0Activate( dev->ep0MpsCode );
809 #endif // if (USB_PWRSAVE_MODE)
810 USBDHAL_SetRemoteWakeup();
816 USBDHAL_ClearRemoteWakeup();
817 #if (USB_PWRSAVE_MODE)
822 #if (USB_PWRSAVE_MODE)
823 static void RestoreEpCtrlRegisters(
void)
825 #if ( NUM_EP_USED > 0 ) || ( FIFO_CNT > 0 )
828 #if ( NUM_EP_USED > 0 )
835 for (i = 0; i < FIFO_CNT; i++)
837 USB_DIEPTXFS[i] = x_USB_DIEPTXFS[i];
841 #if (NUM_EP_USED > 0)
842 for (i = 0; i < NUM_EP_USED; i++)
847 tmp = x_USB_EP_CTL[i]
873 USB_DINEPS[epNum].CTL = tmp;
874 USB_DINEPS[epNum].TSIZ = x_USB_EP_TSIZ[i];
875 USB_DINEPS[epNum].DMAADDR = x_USB_EP_DMAADDR[i];
879 USB_DOUTEPS[epNum].CTL = tmp;
880 USB_DOUTEPS[epNum].TSIZ = x_USB_EP_TSIZ[i];
881 USB_DOUTEPS[epNum].DMAADDR = x_USB_EP_DMAADDR[i];
886 #endif // if (USB_PWRSAVE_MODE)
888 #if defined( USB_DOEP0INT_STUPPKTRCVD )
889 static void HandleOutEpIntr( uint32_t status, USBD_Ep_TypeDef *ep )
898 doeptsiz =
USB->DOEP0TSIZ;
900 if ( ep->state == D_EP_IDLE )
906 status = USBDHAL_GetOutEpInts( ep );
907 doeptsiz =
USB->DOEP0TSIZ;
914 status &= ~USB_DOEP0INT_SETUP;
922 dev->setup = &dev->setupPkt[ 2 - supCnt ];
924 DEBUG_USB_INT_LO_PUTS(
"\nS" );
925 USBDEP_Ep0Handler( dev );
928 if ( ep->state == D_EP0_IN_STATUS || ep->state == D_EP_TRANSMITTING )
930 USBDHAL_StartEp0Setup( dev );
935 status = USBDHAL_GetOutEpInts( ep );
936 if ( status & USB_DOEP0INT_SETUP )
938 USBDHAL_StartEp0Setup( dev );
943 if ( ep->state == D_EP_RECEIVING )
945 if ( ep->remaining > ep->packetSize )
947 ep->remaining -= ep->packetSize;
948 ep->xferred += ep->packetSize;
952 ep->xferred += ep->remaining;
955 USBDEP_Ep0Handler( dev );
957 else if ( ep->state == D_EP0_OUT_STATUS )
959 USBDEP_Ep0Handler( dev );
969 if ( status & USB_DOEP0INT_SETUP )
979 dev->setup = &dev->setupPkt[ 2 - supCnt ];
981 DEBUG_USB_INT_LO_PUTS(
"\nS" );
982 USBDEP_Ep0Handler( dev );
991 ep->xferred = ep->hwXferSize -
994 ep->remaining -= ep->xferred;
996 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_DCFG_ENA32KHZSUSP
#define USB_DIEP_CTL_CNAK
#define USB_DAINTMSK_INEPMSK0
#define CORE_DECLARE_IRQ_STATE
#define USB_GINTMSK_WKUPINTMSK
#define USB_DOEPMSK_XFERCOMPLMSK
#define USB_STATUS_VREGOS
#define USB_DIEP_CTL_NAKSTS
#define USB_DIEP_CTL_SETD0PIDEF
#define CORE_ATOMIC_IRQ_ENABLE()
#define _USB_DOEP0TSIZ_SUPCNT_SHIFT
#define USB_DOEPMSK_SETUPMSK
#define USB_GINTSTS_ENUMDONE
#define _USB_DSTS_SOFFN_MASK
#define CMU_STATUS_USBCUSHFRCOSEL
#define _USB_DIEP_TSIZ_XFERSIZE_SHIFT
CMSIS Cortex-M Peripheral Access Layer for Silicon Laboratories microcontroller devices.
#define _USB_DOEP_TSIZ_XFERSIZE_SHIFT
#define USB_SETUP_DIR_MASK
#define USB_GINTSTS_USBSUSP
#define USB_DIEPMSK_XFERCOMPLMSK
#define CORE_ATOMIC_IRQ_DISABLE()
void USBTIMER_DelayMs(uint32_t msec)
Active wait millisecond delay function. Can also be used inside interrupt handlers.
#define CMU_STATUS_USHFRCOENS
USB Setup request package.
USBD_State_TypeDef
USB device state enumerator.
#define _USB_DOEP0TSIZ_SUPCNT_MASK
#define _USB_DCFG_RESVALID_SHIFT
#define _USB_DCFG_DEVADDR_MASK
#define USB_PCGCCTL_PWRCLMP
#define USB_DCTL_RMTWKUPSIG
#define CORE_ENTER_ATOMIC()
#define USB_DOEP0INT_STUPPKTRCVD
#define _USB_DSTS_SOFFN_SHIFT
#define USB_GINTSTS_IEPINT
#define USB_DIEP_CTL_SNAK
#define CMU_STATUS_AUXHFRCOENS
#define USB_DOEP0INT_BACK2BACKSETUP
#define CMU_STATUS_USBCLFRCOSEL
USB protocol stack library API for EFM32/EZR32.
#define CMU_STATUS_HFXOENS
Core interrupt handling API.
#define USB_DIEP_INT_NAKINTRPT
#define CMU_OSCENCMD_USHFRCOEN
#define USB_GINTSTS_OEPINT
#define CORE_EXIT_ATOMIC()
#define USB_DIEP_INT_XFERCOMPL
USBD_State_TypeDef USBD_GetUsbState(void)
Get current USB device state.
#define _USB_DOEP_TSIZ_XFERSIZE_MASK
#define CMU_CMD_USBCCLKSEL_USHFRCO
#define CMU_STATUS_HFRCOENS
#define USB_DIEP_CTL_DPIDEOF
#define USB_DOEPMSK_STSPHSERCVDMSK
#define CMU_OSCENCMD_HFRCODIS
#define USB_DIEP_CTL_SETD1PIDOF
#define USB_GINTSTS_WKUPINT
#define USB_PCGCCTL_STOPPCLK
USB protocol stack library, low level USB peripheral access.
#define USB_DOEP0INT_STSPHSERCVD
#define USB_DOEP_INT_XFERCOMPL
#define _USB_DCFG_RESVALID_MASK
#define USB_SETUP_PKT_SIZE
#define CMU_CMD_USBCCLKSEL_LFRCO
USB protocol stack library, internal type definitions.
#define USB_DAINTMSK_OUTEPMSK0
#define CMU_STATUS_USBCLFXOSEL
#define USB_CTRL_VREGOSEN
#define USB_DOEP0INT_XFERCOMPL
#define CMU_CMD_USBCCLKSEL_LFXO
#define _USB_DIEP_TSIZ_XFERSIZE_MASK
#define USB_GINTSTS_RESETDET
#define USB_DCTL_PWRONPRGDONE
#define USB_DOEP0INT_SETUP
#define USB_GINTSTS_USBRST
#define USB_PCGCCTL_RSTPDWNMODULE
#define USB_GINTMSK_RESETDETMSK