EFM32 Wonder Gecko Software Documentation  efm32wg-doc-5.1.2
em_usbd.c
Go to the documentation of this file.
1 /**************************************************************************/
16 #include "em_device.h"
17 #if defined( USB_PRESENT ) && ( USB_COUNT == 1 )
18 #include "em_usb.h"
19 #if defined( USB_DEVICE )
20 
21 #include "em_cmu.h"
22 #include "em_core.h"
23 #include "em_system.h"
24 #include "em_usbtypes.h"
25 #include "em_usbhal.h"
26 #include "em_usbd.h"
27 
30 static USBD_Device_TypeDef device;
31 USBD_Device_TypeDef *dev = &device;
32 
33 static const char *stateNames[] =
34 {
35  [ USBD_STATE_NONE ] = "NONE ",
36  [ USBD_STATE_ATTACHED ] = "ATTACHED ",
37  [ USBD_STATE_POWERED ] = "POWERED ",
38  [ USBD_STATE_DEFAULT ] = "DEFAULT ",
39  [ USBD_STATE_ADDRESSED ] = "ADDRESSED ",
40  [ USBD_STATE_CONFIGURED ] = "CONFIGURED",
41  [ USBD_STATE_SUSPENDED ] = "SUSPENDED ",
42  [ USBD_STATE_LASTMARKER ] = "UNDEFINED "
43 };
44 
47 /***************************************************************************/
56 {
58  USBDHAL_AbortAllTransfers( USB_STATUS_EP_ABORTED );
59  )
60 }
61 
62 /***************************************************************************/
73 int USBD_AbortTransfer( int epAddr )
74 {
76  USBD_Ep_TypeDef *ep = USBD_GetEpFromAddr( epAddr );
78 
79  if ( ep == NULL )
80  {
81  DEBUG_USB_API_PUTS( "\nUSBD_AbortTransfer(), Illegal endpoint" );
82  EFM_ASSERT( false );
83  return USB_STATUS_ILLEGAL;
84  }
85 
86  if ( ep->num == 0 )
87  {
88  DEBUG_USB_API_PUTS( "\nUSBD_AbortTransfer(), Illegal endpoint" );
89  EFM_ASSERT( false );
90  return USB_STATUS_ILLEGAL;
91  }
92 
94  if ( ep->state == D_EP_IDLE )
95  {
97  return USB_STATUS_OK;
98  }
99 
100  USBD_AbortEp( ep );
101 
102  ep->state = D_EP_IDLE;
103  if ( ep->xferCompleteCb )
104  {
105  callback = ep->xferCompleteCb;
106  ep->xferCompleteCb = NULL;
107 
108  if ( ( dev->lastState == USBD_STATE_CONFIGURED ) &&
109  ( dev->state == USBD_STATE_ADDRESSED ) )
110  {
111  USBDHAL_DeactivateEp( ep );
112  }
113 
114  DEBUG_TRACE_ABORT( USB_STATUS_EP_ABORTED );
115  callback( USB_STATUS_EP_ABORTED, ep->xferred, ep->remaining );
116  }
117 
119  return USB_STATUS_OK;
120 }
121 
122 /***************************************************************************/
130 void USBD_Connect( void )
131 {
133  USBDHAL_Connect();
134  )
135 }
136 
137 /***************************************************************************/
145 void USBD_Disconnect( void )
146 {
148  USBDHAL_Disconnect();
149  )
150 }
151 
152 /***************************************************************************/
162 bool USBD_EpIsBusy( int epAddr )
163 {
164  USBD_Ep_TypeDef *ep = USBD_GetEpFromAddr( epAddr );
165 
166  if ( ep == NULL )
167  {
168  DEBUG_USB_API_PUTS( "\nUSBD_EpIsBusy(), Illegal endpoint" );
169  EFM_ASSERT( false );
170  return USB_STATUS_ILLEGAL;
171  }
172 
173  if ( ep->state == D_EP_IDLE )
174  return false;
175 
176  return true;
177 }
178 
179 /***************************************************************************/
187 {
188  return dev->state;
189 }
190 
191 /***************************************************************************/
202 {
203  if ( state > USBD_STATE_LASTMARKER )
204  state = USBD_STATE_LASTMARKER;
205 
206  return stateNames[ state ];
207 }
208 
209 /***************************************************************************/
227 {
228  int numEps;
229  USBD_Ep_TypeDef *ep;
230  uint8_t txFifoNum;
231  uint8_t *conf, *confEnd;
232 #if defined( CMU_OSCENCMD_USHFRCOEN )
234 #endif
237  uint32_t totalRxFifoSize, totalTxFifoSize, numInEps, numOutEps;
239 
240 #if !defined( USB_CORECLK_HFRCO ) || !defined( CMU_OSCENCMD_USHFRCOEN )
241  /* Devices supporting crystal-less USB can use HFRCO or HFXO as core clock. */
242  /* All other devices must use HFXO as core clock. */
244  {
246  }
247 #endif
248 
249 #if !defined( CMU_OSCENCMD_USHFRCOEN )
250 #if ( USB_USBC_32kHz_CLK == USB_USBC_32kHz_CLK_LFXO )
251  CMU_OscillatorEnable(cmuOsc_LFXO, true, false);
252 #else
253  CMU_OscillatorEnable(cmuOsc_LFRCO, true, false);
254 #endif
255 
256 #else
257  CMU_ClockEnable(cmuClock_CORELE, true);
258  /* LFC clock is needed to detect USB suspend when LEMIDLE is activated. */
259 #if ( USB_USBC_32kHz_CLK == USB_USBC_32kHz_CLK_LFXO )
260  CMU_ClockSelectSet(cmuClock_LFC, cmuSelect_LFXO);
261 #else
262  CMU_ClockSelectSet(cmuClock_LFC, cmuSelect_LFRCO);
263 #endif
264  CMU_ClockEnable(cmuClock_USBLE, true);
265 #endif
266 
267  USBTIMER_Init();
268 
269  memset( dev, 0, sizeof( USBD_Device_TypeDef ) );
270 
271  dev->setup = dev->setupPkt;
272  dev->deviceDescriptor = p->deviceDescriptor;
273  dev->configDescriptor = (USB_ConfigurationDescriptor_TypeDef*)
274  p->configDescriptor;
275  dev->stringDescriptors = p->stringDescriptors;
276  dev->numberOfStrings = p->numberOfStrings;
277  dev->state = USBD_STATE_LASTMARKER;
278  dev->savedState = USBD_STATE_NONE;
279  dev->lastState = USBD_STATE_NONE;
280  dev->callbacks = p->callbacks;
281  dev->remoteWakeupEnabled = false;
282 
283  /* Initialize EP0 */
284 
285  ep = &dev->ep[ 0 ];
286  ep->in = false;
287  ep->buf = NULL;
288  ep->num = 0;
289  ep->mask = 1;
290  ep->addr = 0;
291  ep->type = USB_EPTYPE_CTRL;
292  ep->txFifoNum = 0;
293  ep->packetSize = p->deviceDescriptor->bMaxPacketSize0;
294 
295  if ( ep->packetSize == 32 )
296  {
297  dev->ep0MpsCode = _USB_DOEP0CTL_MPS_32B;
298  }
299  else if ( ep->packetSize == 64 )
300  {
301  dev->ep0MpsCode = _USB_DOEP0CTL_MPS_64B;
302  }
303  else
304  {
305  return USB_STATUS_ILLEGAL;
306  }
307 
308  ep->remaining = 0;
309  ep->xferred = 0;
310  ep->state = D_EP_IDLE;
311  ep->xferCompleteCb = NULL;
312  ep->fifoSize = ep->packetSize / 4;
313 
314  totalTxFifoSize = ep->fifoSize * p->bufferingMultiplier[ 0 ];
315  totalRxFifoSize = (ep->fifoSize + 1) * p->bufferingMultiplier[ 0 ];
316 
317 #if defined( DEBUG_USB_API )
318  /* Do a sanity check on the configuration descriptor */
319  {
320  int i;
321 
322  /* Check if bLength's adds up exactly to wTotalLength */
323  i = 0;
324  conf = (uint8_t*)dev->configDescriptor;
325  confEnd = conf + dev->configDescriptor->wTotalLength;
326 
327  while ( conf < confEnd )
328  {
329  if ( *conf == 0 )
330  break;
331 
332  i += *conf;
333  conf += *conf;
334  }
335 
336  if ( ( conf != confEnd ) ||
337  ( i != dev->configDescriptor->wTotalLength ) )
338  {
339  DEBUG_USB_API_PUTS( "\nUSBD_Init(), Illegal configuration descriptor" );
340  EFM_ASSERT( false );
341  return USB_STATUS_ILLEGAL;
342  }
343  }
344 #endif /* defined( DEBUG_USB_API ) */
345 
346  /* Parse configuration decriptor */
347  numEps = 0;
348  numInEps = 0;
349  numOutEps = 0;
350  conf = (uint8_t*)dev->configDescriptor;
351  confEnd = conf + dev->configDescriptor->wTotalLength;
352 
353  txFifoNum = 1;
354  while ( conf < confEnd )
355  {
356  if ( *conf == 0 )
357  {
358  DEBUG_USB_API_PUTS( "\nUSBD_Init(), Illegal configuration descriptor" );
359  EFM_ASSERT( false );
360  return USB_STATUS_ILLEGAL;
361  }
362 
363  if ( *(conf + 1) == USB_ENDPOINT_DESCRIPTOR )
364  {
365  numEps++;
366  epd = (USB_EndpointDescriptor_TypeDef*)conf;
367 
368 #if defined( __GNUC__ )
369 #pragma GCC diagnostic push
370 #pragma GCC diagnostic ignored "-Warray-bounds"
371 #endif
372  ep = &dev->ep[ numEps ];
373 #if defined( __GNUC__ )
374 #pragma GCC diagnostic pop
375 #endif
376 
377  ep->in = ( epd->bEndpointAddress & USB_SETUP_DIR_MASK ) != 0;
378  ep->buf = NULL;
379  ep->addr = epd->bEndpointAddress;
380  ep->num = ep->addr & USB_EPNUM_MASK;
381  ep->mask = 1 << ep->num;
382  ep->type = epd->bmAttributes & CONFIG_DESC_BM_TRANSFERTYPE;
383  ep->packetSize = epd->wMaxPacketSize;
384  ep->remaining = 0;
385  ep->xferred = 0;
386  ep->state = D_EP_IDLE;
387  ep->xferCompleteCb = NULL;
388 
389  if ( p->bufferingMultiplier[ numEps ] == 0 )
390  {
391  DEBUG_USB_API_PUTS( "\nUSBD_Init(), Illegal EP fifo buffer configuration" );
392  EFM_ASSERT( false );
393  return USB_STATUS_ILLEGAL;
394  }
395 
396  if ( ep->in )
397  {
398  numInEps++;
399  ep->txFifoNum = txFifoNum++;
400  ep->fifoSize = ( ( ep->packetSize + 3 ) / 4 )
401  * p->bufferingMultiplier[ numEps ];
402  dev->inEpAddr2EpIndex[ ep->num ] = numEps;
403  totalTxFifoSize += ep->fifoSize;
404  if ( ep->num > MAX_NUM_IN_EPS )
405  {
406  DEBUG_USB_API_PUTS( "\nUSBD_Init(), Illegal IN EP address" );
407  EFM_ASSERT( false );
408  return USB_STATUS_ILLEGAL;
409  }
410  }
411  else
412  {
413  numOutEps++;
414  ep->fifoSize = ( ( ( ep->packetSize + 3 ) / 4 ) + 1 )
415  * p->bufferingMultiplier[ numEps ];
416  dev->outEpAddr2EpIndex[ ep->num ] = numEps;
417  totalRxFifoSize += ep->fifoSize;
418  if ( ep->num > MAX_NUM_OUT_EPS )
419  {
420  DEBUG_USB_API_PUTS( "\nUSBD_Init(), Illegal OUT EP address" );
421  EFM_ASSERT( false );
422  return USB_STATUS_ILLEGAL;
423  }
424  }
425  }
426  else if ( *(conf + 1) == USB_INTERFACE_DESCRIPTOR )
427  {
429 
430  if ( id->bAlternateSetting == 0 ) // Only check default interfaces
431  {
432  if ( dev->numberOfInterfaces != id->bInterfaceNumber )
433  {
434  DEBUG_USB_API_PUTS( "\nUSBD_Init(), Illegal interface number" );
435  EFM_ASSERT( false );
436  return USB_STATUS_ILLEGAL;
437  }
438  dev->numberOfInterfaces++;
439  }
440  }
441 
442  conf += *conf;
443  }
444 
445  /* Rx-FIFO size: SETUP packets : 4*n + 6 n=#CTRL EP's
446  * GOTNAK : 1
447  * Status info : 2*n n=#OUT EP's (EP0 included) in HW
448  */
449  totalRxFifoSize += 10 + 1 + ( 2 * (MAX_NUM_OUT_EPS + 1) );
450 
451  if ( dev->configDescriptor->bNumInterfaces != dev->numberOfInterfaces )
452  {
453  DEBUG_USB_API_PUTS( "\nUSBD_Init(), Illegal interface count" );
454  EFM_ASSERT( false );
455  return USB_STATUS_ILLEGAL;
456  }
457 
458  if ( numEps != NUM_EP_USED )
459  {
460  DEBUG_USB_API_PUTS( "\nUSBD_Init(), Illegal EP count" );
461  EFM_ASSERT( false );
462  return USB_STATUS_ILLEGAL;
463  }
464 
465  if ( numInEps > MAX_NUM_IN_EPS )
466  {
467  DEBUG_USB_API_PUTS( "\nUSBD_Init(), Illegal IN EP count" );
468  EFM_ASSERT( false );
469  return USB_STATUS_ILLEGAL;
470  }
471 
472  if ( numOutEps > MAX_NUM_OUT_EPS )
473  {
474  DEBUG_USB_API_PUTS( "\nUSBD_Init(), Illegal OUT EP count" );
475  EFM_ASSERT( false );
476  return USB_STATUS_ILLEGAL;
477  }
478 
480 
481  /* Enable USB clock */
483 
484 #if defined( CMU_OSCENCMD_USHFRCOEN )
485  CMU->USHFRCOCONF = CMU_USHFRCOCONF_BAND_48MHZ;
486  CMU_ClockSelectSet( cmuClock_USBC, cmuSelect_USHFRCO );
487 
488  /* Enable USHFRCO Clock Recovery mode. */
489  CMU->USBCRCTRL |= CMU_USBCRCTRL_EN;
490 
491  /* Turn on Low Energy Mode (LEM) features. */
492  SYSTEM_ChipRevisionGet(&chipRev);
493  if ((chipRev.family == 5)
494  && (chipRev.major == 1)
495  && (chipRev.minor == 0))
496  {
497  /* First Happy Gecko chip revision did not have all LEM features enabled. */
498  USB->CTRL = USB_CTRL_LEMOSCCTRL_GATE
499  | USB_CTRL_LEMIDLEEN
500  | USB_CTRL_LEMPHYCTRL;
501  }
502  else
503  {
504  USB->CTRL = USB_CTRL_LEMOSCCTRL_GATE
505  | USB_CTRL_LEMIDLEEN
506  | USB_CTRL_LEMPHYCTRL
507  | USB_CTRL_LEMNAKEN
508  | USB_CTRL_LEMADDRMEN;
509  }
510 #else
512 #endif
513 
514  USBHAL_DisableGlobalInt();
515 
516  if ( USBDHAL_CoreInit( totalRxFifoSize, totalTxFifoSize ) == USB_STATUS_OK )
517  {
518  USBDHAL_EnableUsbResetAndSuspendInt();
519  USBHAL_EnableGlobalInt();
520  NVIC_ClearPendingIRQ( USB_IRQn );
521  NVIC_EnableIRQ( USB_IRQn );
522  }
523  else
524  {
526  DEBUG_USB_API_PUTS( "\nUSBD_Init(), FIFO setup error" );
527  EFM_ASSERT( false );
528  return USB_STATUS_ILLEGAL;
529  }
530 
531 #if ( USB_PWRSAVE_MODE & USB_PWRSAVE_MODE_ONVBUSOFF )
532  if ( USBHAL_VbusIsOn() )
533  {
534  USBD_SetUsbState( USBD_STATE_POWERED );
535  }
536  else
537 #endif
538  {
539  USBD_SetUsbState( USBD_STATE_NONE );
540  }
541 
543  return USB_STATUS_OK;
544 }
545 
546 /***************************************************************************/
573 int USBD_Read( int epAddr, void *data, int byteCount,
574  USB_XferCompleteCb_TypeDef callback )
575 {
577  USBD_Ep_TypeDef *ep = USBD_GetEpFromAddr( epAddr );
578 
579  if ( ep == NULL )
580  {
581  DEBUG_USB_API_PUTS( "\nUSBD_Read(), Illegal endpoint" );
582  EFM_ASSERT( false );
583  return USB_STATUS_ILLEGAL;
584  }
585 
586  if ( ( byteCount > MAX_XFER_LEN ) ||
587  ( ( byteCount / ep->packetSize ) > MAX_PACKETS_PR_XFER ) )
588  {
589  DEBUG_USB_API_PUTS( "\nUSBD_Read(), Illegal transfer size" );
590  EFM_ASSERT( false );
591  return USB_STATUS_ILLEGAL;
592  }
593 
594  if ( (uint32_t)data & 3 )
595  {
596  DEBUG_USB_API_PUTS( "\nUSBD_Read(), Misaligned data buffer" );
597  EFM_ASSERT( false );
598  return USB_STATUS_ILLEGAL;
599  }
600 
602  if ( USBDHAL_EpIsStalled( ep ) )
603  {
605  DEBUG_USB_API_PUTS( "\nUSBD_Read(), Endpoint is halted" );
606  return USB_STATUS_EP_STALLED;
607  }
608 
609  if ( ep->state != D_EP_IDLE )
610  {
612  DEBUG_USB_API_PUTS( "\nUSBD_Read(), Endpoint is busy" );
613  return USB_STATUS_EP_BUSY;
614  }
615 
616  if ( ( ep->num > 0 ) && ( USBD_GetUsbState() != USBD_STATE_CONFIGURED ) )
617  {
619  DEBUG_USB_API_PUTS( "\nUSBD_Read(), Device not configured" );
621  }
622 
623  ep->buf = (uint8_t*)data;
624  ep->remaining = byteCount;
625  ep->xferred = 0;
626 
627  if ( ep->num == 0 )
628  {
629  ep->in = false;
630  }
631  else if ( ep->in != false )
632  {
634  DEBUG_USB_API_PUTS( "\nUSBD_Read(), Illegal EP direction" );
635  EFM_ASSERT( false );
636  return USB_STATUS_ILLEGAL;
637  }
638 
639  ep->state = D_EP_RECEIVING;
640  ep->xferCompleteCb = callback;
641 
642  USBD_ArmEp( ep );
644  return USB_STATUS_OK;
645 }
646 
647 /***************************************************************************/
661 int USBD_RemoteWakeup( void )
662 {
664 
666 
667  if ( ( dev->state != USBD_STATE_SUSPENDED ) ||
668  ( dev->remoteWakeupEnabled == false ) )
669  {
671  DEBUG_USB_API_PUTS( "\nUSBD_RemoteWakeup(), Illegal remote wakeup" );
672  return USB_STATUS_ILLEGAL;
673  }
674 
675  USBDINT_RemoteWakeup();
677  return USB_STATUS_OK;
678 }
679 
680 /***************************************************************************/
694 {
695 #if ( USB_PWRSAVE_MODE )
696  return USBD_poweredDown ? true : false;
697 #else
698  return false;
699 #endif
700 }
701 
704 void USBD_SetUsbState( USBD_State_TypeDef newState )
705 {
706  USBD_State_TypeDef currentState;
707 
708  currentState = dev->state;
709  if ( newState == USBD_STATE_SUSPENDED )
710  {
711  dev->savedState = currentState;
712  }
713 
714  dev->lastState = dev->state;
715  dev->state = newState;
716 
717  if ( ( dev->callbacks->usbStateChange ) &&
718  ( currentState != newState ) )
719  {
720  dev->callbacks->usbStateChange( currentState, newState );
721  }
722 }
723 
726 /***************************************************************************/
737 int USBD_StallEp( int epAddr )
738 {
739  USB_Status_TypeDef retVal;
740  USBD_Ep_TypeDef *ep = USBD_GetEpFromAddr( epAddr );
741 
742  if ( ep == NULL )
743  {
744  DEBUG_USB_API_PUTS( "\nUSBD_StallEp(), Illegal request" );
745  EFM_ASSERT( false );
746  return USB_STATUS_ILLEGAL;
747  }
748 
749  if ( ep->num == 0 )
750  {
751  DEBUG_USB_API_PUTS( "\nUSBD_StallEp(), Illegal endpoint" );
752  EFM_ASSERT( false );
753  return USB_STATUS_ILLEGAL;
754  }
755 
757  retVal = USBDHAL_StallEp( ep );
758  )
759 
760  if ( retVal != USB_STATUS_OK )
761  {
762  retVal = USB_STATUS_ILLEGAL;
763  }
764 
765  return retVal;
766 }
767 
768 /***************************************************************************/
776 void USBD_Stop( void )
777 {
778  USBD_Disconnect();
779  NVIC_DisableIRQ( USB_IRQn );
780  USBHAL_DisableGlobalInt();
781  USBHAL_DisableUsbInt();
782  USBHAL_DisablePhyPins();
783  USBD_SetUsbState( USBD_STATE_NONE );
784  /* Turn off USB clocks. */
785  CMU->HFCORECLKEN0 &= ~(CMU_HFCORECLKEN0_USB | CMU_HFCORECLKEN0_USBC);
786 }
787 
788 /***************************************************************************/
799 int USBD_UnStallEp( int epAddr )
800 {
801  USB_Status_TypeDef retVal;
802  USBD_Ep_TypeDef *ep = USBD_GetEpFromAddr( epAddr );
803 
804  if ( ep == NULL )
805  {
806  DEBUG_USB_API_PUTS( "\nUSBD_UnStallEp(), Illegal request" );
807  EFM_ASSERT( false );
808  return USB_STATUS_ILLEGAL;
809  }
810 
811  if ( ep->num == 0 )
812  {
813  DEBUG_USB_API_PUTS( "\nUSBD_UnStallEp(), Illegal endpoint" );
814  EFM_ASSERT( false );
815  return USB_STATUS_ILLEGAL;
816  }
817 
819  retVal = USBDHAL_UnStallEp( ep );
820  )
821 
822  if ( retVal != USB_STATUS_OK )
823  {
824  retVal = USB_STATUS_ILLEGAL;
825  }
826 
827  return retVal;
828 }
829 
830 /***************************************************************************/
851 int USBD_Write( int epAddr, void *data, int byteCount,
852  USB_XferCompleteCb_TypeDef callback )
853 {
855  USBD_Ep_TypeDef *ep = USBD_GetEpFromAddr( epAddr );
856 
857  if ( ep == NULL )
858  {
859  DEBUG_USB_API_PUTS( "\nUSBD_Write(), Illegal endpoint" );
860  EFM_ASSERT( false );
861  return USB_STATUS_ILLEGAL;
862  }
863 
864  if ( ( byteCount > MAX_XFER_LEN ) ||
865  ( ( byteCount / ep->packetSize ) > MAX_PACKETS_PR_XFER ) )
866  {
867  DEBUG_USB_API_PUTS( "\nUSBD_Write(), Illegal transfer size" );
868  EFM_ASSERT( false );
869  return USB_STATUS_ILLEGAL;
870  }
871 
872  if ( (uint32_t)data & 3 )
873  {
874  DEBUG_USB_API_PUTS( "\nUSBD_Write(), Misaligned data buffer" );
875  EFM_ASSERT( false );
876  return USB_STATUS_ILLEGAL;
877  }
878 
880  if ( USBDHAL_EpIsStalled( ep ) )
881  {
883  DEBUG_USB_API_PUTS( "\nUSBD_Write(), Endpoint is halted" );
884  return USB_STATUS_EP_STALLED;
885  }
886 
887  if ( ep->state != D_EP_IDLE )
888  {
890  DEBUG_USB_API_PUTS( "\nUSBD_Write(), Endpoint is busy" );
891  return USB_STATUS_EP_BUSY;
892  }
893 
894  if ( ( ep->num > 0 ) && ( USBD_GetUsbState() != USBD_STATE_CONFIGURED ) )
895  {
897  DEBUG_USB_API_PUTS( "\nUSBD_Write(), Device not configured" );
899  }
900 
901  ep->buf = (uint8_t*)data;
902  ep->remaining = byteCount;
903  ep->xferred = 0;
904 
905  if ( ep->num == 0 )
906  {
907  ep->in = true;
908  }
909  else if ( ep->in != true )
910  {
912  DEBUG_USB_API_PUTS( "\nUSBD_Write(), Illegal EP direction" );
913  EFM_ASSERT( false );
914  return USB_STATUS_ILLEGAL;
915  }
916 
917  ep->state = D_EP_TRANSMITTING;
918  ep->xferCompleteCb = callback;
919 
920  USBD_ArmEp( ep );
922  return USB_STATUS_OK;
923 }
924 
925 #if defined(USB_HOST)
926 /***************************************************************************/
933 /***************************************************************************/
941 /***************************************************************************/
947 #else
948 /***************************************************************************/
955 /***************************************************************************/
962 #endif
963 /***************************************************************************/
972 /******** THE REST OF THE FILE IS DOCUMENTATION ONLY !**********************/
1471 #endif /* defined( USB_DEVICE ) */
1472 #endif /* defined( USB_PRESENT ) && ( USB_COUNT == 1 ) */
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.
Definition: em_cmu.c:2521
const uint8_t * bufferingMultiplier
Definition: em_usb.h:782
#define USB_EPNUM_MASK
Definition: em_usb.h:187
#define CORE_DECLARE_IRQ_STATE
Definition: em_core.h:85
USB Device stack initialization structure.
Definition: em_usb.h:776
void SYSTEM_ChipRevisionGet(SYSTEM_ChipRevision_TypeDef *rev)
Get chip major/minor revision.
Definition: em_system.c:58
#define CMU
CMSIS Cortex-M Peripheral Access Layer for Silicon Laboratories microcontroller devices.
#define USB_SETUP_DIR_MASK
Definition: em_usb.h:68
const USB_DeviceDescriptor_TypeDef * deviceDescriptor
Definition: em_usb.h:778
void USBD_Connect(void)
Start USB device operation.
Definition: em_usbd.c:130
#define _USB_DOEP0CTL_MPS_32B
Definition: efm32wg_usb.h:2214
USB Interface Descriptor.
Definition: em_usb.h:459
int USBD_Init(const USBD_Init_TypeDef *p)
Initializes USB device hardware and internal protocol stack data structures, then connects the data-l...
Definition: em_usbd.c:226
USBD_State_TypeDef
USB device state enumerator.
Definition: em_usb.h:358
int(* USB_XferCompleteCb_TypeDef)(USB_Status_TypeDef status, uint32_t xferred, uint32_t remaining)
USB transfer callback function.
Definition: em_usb.h:663
void USBD_AbortAllTransfers(void)
Abort all pending transfers.
Definition: em_usbd.c:55
USB_Status_TypeDef
USB transfer status enumerator.
Definition: em_usb.h:319
#define CORE_ENTER_ATOMIC()
Definition: em_core.h:138
const uint8_t * configDescriptor
Definition: em_usb.h:779
#define CORE_ATOMIC_SECTION(yourcode)
Definition: em_core.h:126
#define CMU_HFCORECLKEN0_USBC
Definition: efm32wg_cmu.h:825
#define USB
const void *const * stringDescriptors
Definition: em_usb.h:780
#define USB_EPTYPE_CTRL
Definition: em_usb.h:177
int USBD_AbortTransfer(int epAddr)
Abort a pending transfer on a specific endpoint.
Definition: em_usbd.c:73
#define CONFIG_DESC_BM_TRANSFERTYPE
Definition: em_usb.h:194
USB protocol stack library API for EFM32/EZR32.
USB Endpoint Descriptor.
Definition: em_usb.h:500
Core interrupt handling API.
void CMU_ClockEnable(CMU_Clock_TypeDef clock, bool enable)
Enable/disable a clock.
Definition: em_cmu.c:1453
USBD_Callbacks_TypeDef_Pointer callbacks
Definition: em_usb.h:787
#define CMU_HFCORECLKEN0_USB
Definition: efm32wg_cmu.h:830
int USBD_RemoteWakeup(void)
Perform a remote wakeup signalling sequence.
Definition: em_usbd.c:661
int USBD_StallEp(int epAddr)
Set an endpoint in the stalled (halted) state.
Definition: em_usbd.c:737
#define CORE_EXIT_ATOMIC()
Definition: em_core.h:142
USBD_State_TypeDef USBD_GetUsbState(void)
Get current USB device state.
Definition: em_usbd.c:186
#define USB_INTERFACE_DESCRIPTOR
Definition: em_usb.h:128
void CMU_OscillatorEnable(CMU_Osc_TypeDef osc, bool enable, bool wait)
Enable/disable oscillator.
Definition: em_cmu.c:3594
int USBD_Write(int epAddr, void *data, int byteCount, USB_XferCompleteCb_TypeDef callback)
Start a write (IN) transfer on an endpoint.
Definition: em_usbd.c:851
int USBD_UnStallEp(int epAddr)
Reset stall state on a stalled (halted) endpoint.
Definition: em_usbd.c:799
const uint8_t numberOfStrings
Definition: em_usb.h:781
void USBD_Stop(void)
Stop USB device stack operation.
Definition: em_usbd.c:776
#define _USB_DOEP0CTL_MPS_64B
Definition: efm32wg_usb.h:2213
USB protocol stack library, low level USB peripheral access.
void USBD_Disconnect(void)
Stop USB device operation.
Definition: em_usbd.c:145
void USBTIMER_Init(void)
Activate the hardware timer used to pace the 1 millisecond timer system.
Definition: em_usbtimer.c:193
USB Configuration Descriptor.
Definition: em_usb.h:430
System API.
const char * USBD_GetUsbStateName(USBD_State_TypeDef state)
Get a string naming a device USB state.
Definition: em_usbd.c:201
USB protocol stack library, internal type definitions.
bool USBD_SafeToEnterEM2(void)
Check if it is ok to enter energy mode EM2.
Definition: em_usbd.c:693
#define USB_ENDPOINT_DESCRIPTOR
Definition: em_usb.h:129
bool USBD_EpIsBusy(int epAddr)
Check if an endpoint is busy doing a transfer.
Definition: em_usbd.c:162
int USBD_Read(int epAddr, void *data, int byteCount, USB_XferCompleteCb_TypeDef callback)
Start a read (OUT) transfer on an endpoint.
Definition: em_usbd.c:573
CMU_Select_TypeDef CMU_ClockSelectGet(CMU_Clock_TypeDef clock)
Get currently selected reference clock used for a clock branch.
Definition: em_cmu.c:2146