EZR32 Wonder Gecko Software Documentation  ezr32wg-doc-4.2.1
em_usbh.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_HOST )
20 
21 #include "em_cmu.h"
22 #include "em_usbtypes.h"
23 #include "em_usbhal.h"
24 #include "em_usbh.h"
25 #if ( USB_VBUSOVRCUR_PORT != USB_VBUSOVRCUR_PORT_NONE )
26 #include "em_gpio.h"
27 #endif
28 
31 USBH_Hc_TypeDef hcs[ NUM_HC_USED + 2 ];
32 int USBH_attachRetryCount;
33 USBH_Init_TypeDef USBH_initData;
34 volatile USBH_PortState_TypeDef USBH_portStatus;
35 const USBH_AttachTiming_TypeDef USBH_attachTiming[]=
36 {
37  /* debounceTime resetTime */
38  { 200, 75 },
39  { 200, 100 },
40  { 200, 50 },
41 };
42 
43 #define PORT_VBUS_DELAY 250
44 #define DEFAULT_CTRL_TIMEOUT 1000
45 
46 static void Timeout( int hcnum );
47 
48 #if defined( __ICCARM__ )
49 #pragma diag_suppress=Pe175
50 #endif
51 
52 static void Timeout0(void){ Timeout(0); }
53 static void Timeout1(void){ Timeout(1); }
54 static void Timeout2(void){ Timeout(2); }
55 static void Timeout3(void){ Timeout(3); }
56 static void Timeout4(void){ Timeout(4); }
57 static void Timeout5(void){ Timeout(5); }
58 static void Timeout6(void){ Timeout(6); }
59 static void Timeout7(void){ Timeout(7); }
60 static void Timeout8(void){ Timeout(8); }
61 static void Timeout9(void){ Timeout(9); }
62 static void Timeout10(void){ Timeout(10); }
63 static void Timeout11(void){ Timeout(11); }
64 static void Timeout12(void){ Timeout(12); }
65 static void Timeout13(void){ Timeout(13); }
66 
67 #if defined( __ICCARM__ )
68 #pragma diag_default=Pe175
69 #endif
70 
71 static const USBTIMER_Callback_TypeDef hcTimeoutFunc[ MAX_NUM_HOSTCHANNELS ]=
72 {
73  Timeout0, Timeout1, Timeout2, Timeout3, Timeout4, Timeout5,
74  Timeout6, Timeout7, Timeout8, Timeout9, Timeout10, Timeout11,
75  Timeout12, Timeout13
76 };
77 
78 static void Timeout( int hcnum )
79 {
80  uint32_t hcchar;
81  USBH_Hc_TypeDef *hc;
82  USBH_Ep_TypeDef *ep;
83 
84 #if defined( __GNUC__ )
85 #pragma GCC diagnostic push
86 #pragma GCC diagnostic ignored "-Warray-bounds"
87 #endif
88 
89  hc = &hcs[ hcnum ];
90 
91 #if defined( __GNUC__ )
92 #pragma GCC diagnostic pop
93 #endif
94 
95  hcchar = USBHHAL_GetHcChar( hcnum );
96  ep = hc->ep;
97 
98  if ( ep->type != USB_EPTYPE_INTR )
99  {
100  USBHHAL_HCHalt( hcnum, hcchar );
101  hc->status |= HCS_TIMEOUT;
102  ep->timeout = 0;
103  if ( !hc->idle )
104  USBHEP_TransferDone( hc->ep, USB_STATUS_TIMEOUT );
105  }
106  else
107  {
108  if ( !ep->timeout )
109  {
110  /* Restart the channel */
111  USBHHAL_HCStart( hcnum );
112  USBTIMER_Start( hcnum + HOSTCH_TIMER_INDEX,
113  ep->epDesc.bInterval, hcTimeoutFunc[ hcnum ] );
114  }
115  else
116  {
117  ep->timeout -= EFM32_MIN( ep->timeout, ep->epDesc.bInterval );
118  if ( ep->timeout )
119  {
120  /* Restart the channel */
121  USBHHAL_HCStart( hcnum );
122  USBTIMER_Start( hcnum + HOSTCH_TIMER_INDEX,
123  EFM32_MIN( ep->timeout, ep->epDesc.bInterval ),
124  hcTimeoutFunc[ hcnum ] );
125  }
126  else
127  {
128  USBHHAL_HCHalt( hcnum, hcchar );
129  hc->status |= HCS_TIMEOUT;
130  if ( !hc->idle )
131  USBHEP_TransferDone( hc->ep, USB_STATUS_TIMEOUT );
132  }
133  }
134  }
135 }
136 
139 /***************************************************************************/
160 int USBH_AssignHostChannel( USBH_Ep_TypeDef *ep, uint8_t hcnum )
161 {
163  ep->in = ( ep->epDesc.bEndpointAddress & USB_SETUP_DIR_MASK ) != 0;
164  ep->packetSize = ep->epDesc.wMaxPacketSize;
165  ep->addr = ep->epDesc.bEndpointAddress;
166  ep->state = H_EP_IDLE;
167 
168  if ( ep == NULL )
169  {
170  DEBUG_USB_API_PUTS( "\nUSBH_AssignHostChannel(),"
171  " ep NULL pointer" );
172  EFM_ASSERT( false );
173  return USB_STATUS_ILLEGAL;
174  }
175 
176  if ( hcnum >= MAX_NUM_HOSTCHANNELS )
177  {
178  DEBUG_USB_API_PUTS( "\nUSBH_AssignHostChannel(),"
179  " Illegal host channel number" );
180  EFM_ASSERT( false );
181  return USB_STATUS_ILLEGAL;
182  }
183 
184  if ( ep->in )
185  {
186  ep->hcIn = hcnum;
187  }
188  else
189  {
190  ep->hcOut = hcnum;
191  }
192 
193  return USB_STATUS_OK;
194 }
195 
196 /***************************************************************************/
247  uint8_t bmRequestType,
248  uint8_t bRequest,
249  uint16_t wValue,
250  uint16_t wIndex,
251  uint16_t wLength,
252  void *data,
253  int timeout,
254  USB_XferCompleteCb_TypeDef callback )
255 {
256  if ( ep == NULL )
257  {
258  DEBUG_USB_API_PUTS( "\nUSBH_ControlMsg(), ep NULL pointer" );
259  EFM_ASSERT( false );
260  return USB_STATUS_ILLEGAL;
261  }
262 
263  if ( !USBH_DeviceConnected() )
264  {
265  DEBUG_USB_API_PUTS( "\nUSBH_ControlMsg(), No device connected" );
266  return USB_STATUS_ILLEGAL;
267  }
268 
269  if ( (uint32_t)data & 3 )
270  {
271  DEBUG_USB_API_PUTS( "\nUSBH_ControlMsg(), Misaligned data buffer" );
272  EFM_ASSERT( false );
273  return USB_STATUS_ILLEGAL;
274  }
275 
276  INT_Disable();
277  if ( ep->state != H_EP_IDLE )
278  {
279  INT_Enable();
280  DEBUG_USB_API_PUTS( "\nUSBH_ControlMsg(), Endpoint is busy" );
281  return USB_STATUS_EP_BUSY;
282  }
283 
284  if ( !hcs[ ep->hcIn ].idle || !hcs[ ep->hcOut ].idle )
285  {
286  INT_Enable();
287  DEBUG_USB_API_PUTS( "\nUSBH_ControlMsg(), Host channel is busy" );
288  return USB_STATUS_HC_BUSY;
289  }
290 
291  ep->setup.bmRequestType = bmRequestType;
292  ep->setup.bRequest = bRequest;
293  ep->setup.wValue = wValue;
294  ep->setup.wIndex = wIndex;
295  ep->setup.wLength = wLength;
296 
297  ep->xferCompleted = false;
298  ep->state = H_EP_SETUP;
299  ep->xferCompleteCb = callback;
300  ep->buf = data;
301  ep->xferred = 0;
302  ep->timeout = timeout;
303  ep->setupErrCnt = 0;
304 
305  if ( timeout )
306  {
307  USBTIMER_Start( ep->hcOut + HOSTCH_TIMER_INDEX,
308  timeout, hcTimeoutFunc[ ep->hcOut ] );
309  }
310 
311  USBH_CtlSendSetup( ep );
312 
313  INT_Enable();
314 
315  return USB_STATUS_OK;
316 }
317 
318 /***************************************************************************/
368  uint8_t bmRequestType,
369  uint8_t bRequest,
370  uint16_t wValue,
371  uint16_t wIndex,
372  uint16_t wLength,
373  void *data,
374  int timeout )
375 {
376  int retVal;
377 
378  if ( INT_Disable() > 1 )
379  {
380  INT_Enable();
381  DEBUG_USB_API_PUTS( "\nUSBH_ControlMsgB() called with int's disabled" );
382  EFM_ASSERT( false );
383  return USB_STATUS_ILLEGAL;
384  }
385 
386  retVal = USBH_ControlMsg( ep,
387  bmRequestType,
388  bRequest,
389  wValue,
390  wIndex,
391  wLength,
392  data,
393  timeout,
394  NULL );
395  INT_Enable();
396 
397  if ( retVal == USB_STATUS_OK )
398  {
399  while ( ! ep->xferCompleted );
400 
401  if ( ( retVal = ep->xferStatus ) == USB_STATUS_OK )
402  {
403  retVal = ep->xferred;
404  }
405  }
406 
407  return retVal;
408 }
409 
412 USB_Status_TypeDef USBH_CtlReceiveData( USBH_Ep_TypeDef *ep, uint16_t length )
413 {
414  USBH_Hc_TypeDef *hc;
415 
416  ep->in = true;
417  ep->toggle = USB_PID_DATA1;
418  ep->remaining = length;
419 
420  hc = &hcs[ ep->hcIn ];
421  hc->buf = ep->buf;
422  hc->xferred = 0;
423  hc->remaining = length;
424 
425  USBHHAL_HCStart( ep->hcIn );
426 
427  return USB_STATUS_OK;
428 }
429 
430 #if defined( USB_RAW_API )
431 int USBH_CtlRxRaw( uint8_t pid, USBH_Ep_TypeDef *ep, void *data, int byteCount )
432 {
433  uint16_t packets, len;
434  int hcnum, retval;
435  uint32_t hcchar, status;
436 
437  hcnum = ep->hcIn;
438  if ( byteCount > 0 )
439  packets = ( byteCount + ep->packetSize - 1 ) / ep->packetSize;
440  else
441  packets = 1;
442  len = packets * ep->packetSize;
443 
444  INT_Disable();
445 
446  USB->HC[ hcnum ].INTMSK = USB_HC_INT_STALL | USB_HC_INT_NAK | USB_HC_INT_ACK;
447  USB->HC[ hcnum ].INT = 0xFFFFFFFF; /* Clear all interrupt flags */
448  NVIC_ClearPendingIRQ( USB_IRQn );
449  USB->HAINTMSK |= 1 << hcnum; /* Enable host channel interrupt */
450  USB->HC[ hcnum ].CHAR = /* Program HCCHAR register */
452  ( ( ep->addr & USB_EPNUM_MASK ) << _USB_HC_CHAR_EPNUM_SHIFT ) |
453  ( ep->type << _USB_HC_CHAR_EPTYPE_SHIFT ) |
455  ( USB_HC_CHAR_EPDIR ) |
456  ( ep->parentDevice->speed ==
457  HPRT_L_SPEED >> _USB_HPRT_PRTSPD_SHIFT
458  ? USB_HC_CHAR_LSPDDEV : 0 );
459  USB->HC[ hcnum ].TSIZ =
460  ( ( len << _USB_HC_TSIZ_XFERSIZE_SHIFT ) &
462  ( ( packets << _USB_HC_TSIZ_PKTCNT_SHIFT ) &
464  ( ( pid << _USB_HC_TSIZ_PID_SHIFT ) &
466  USB->HC[ hcnum ].DMAADDR = (uint32_t)data;
467  hcchar = ( USB->HC[ hcnum ].CHAR & ~USB_HC_CHAR_CHDIS ) | USB_HC_CHAR_CHENA;
468  USB->HC[ hcnum ].CHAR = hcchar;
469 
470  /* Start polling for interrupt */
471  retval = USB_STATUS_EP_ERROR;
472  while ( ( USBHAL_GetCoreInts() & USB_GINTSTS_HCHINT ) == 0 ){}
473  if ( USBHHAL_GetHostChannelInts() & ( 1 << hcnum ) )
474  {
475  status = USBHHAL_GetHcInts( hcnum );
476  hcchar |= USB_HC_CHAR_CHDIS;
477  USB->HC[ hcnum ].CHAR = hcchar;
478  USB->HC[ hcnum ].INTMSK = 0;
479  USB->HC[ hcnum ].INT = 0xFFFFFFFF;
480 
481  if ( status & USB_HC_INT_STALL )
482  retval = USB_STATUS_EP_STALLED;
483  else if ( status & USB_HC_INT_NAK )
484  retval = USB_STATUS_EP_NAK;
485  else if ( status & USB_HC_INT_ACK )
486  retval = USB_STATUS_OK;
487  }
488 
489  NVIC_ClearPendingIRQ( USB_IRQn );
490  INT_Enable();
491 
492  return retval;
493 }
494 #endif
495 
496 USB_Status_TypeDef USBH_CtlSendData( USBH_Ep_TypeDef *ep, uint16_t length )
497 {
498  USBH_Hc_TypeDef *hc;
499 
500  ep->in = false;
501  ep->toggle = USB_PID_DATA1;
502  ep->remaining = length;
503 
504  hc = &hcs[ ep->hcOut ];
505  hc->buf = ep->buf;
506  hc->xferred = 0;
507  hc->remaining = length;
508 
509  USBHHAL_HCStart( ep->hcOut );
510 
511  return USB_STATUS_OK;
512 }
513 
514 USB_Status_TypeDef USBH_CtlSendSetup( USBH_Ep_TypeDef *ep )
515 {
516  USBH_Hc_TypeDef *hc;
517 
518  hc = &hcs[ ep->hcOut ];
519  hc->buf = (uint8_t*)&ep->setup;
520  hc->xferred = 0;
521  hc->remaining = USB_SETUP_PKT_SIZE;
522  hc->ep = ep;
523  hcs[ ep->hcIn ].ep = ep;
524 
525  ep->toggle = USB_PID_SETUP;
527 
528  ep->in = true;
529  USBHHAL_HCInit( ep->hcIn );
530 
531  ep->in = false;
532  USBHHAL_HCInit( ep->hcOut );
533 
534  USBHHAL_HCStart( ep->hcOut );
535 
536  return USB_STATUS_OK;
537 }
538 
539 #if defined( USB_RAW_API )
540 int USBH_CtlTxRaw( uint8_t pid, USBH_Ep_TypeDef *ep, void *data, int byteCount )
541 {
542  uint16_t packets;
543  int hcnum, retval;
544  uint32_t hcchar, status;
545 
546  hcnum = ep->hcOut;
547  if ( byteCount > 0 )
548  packets = ( byteCount + ep->packetSize - 1 ) / ep->packetSize;
549  else
550  packets = 1;
551 
552  INT_Disable();
553 
554  USB->HC[ hcnum ].INTMSK = USB_HC_INT_STALL | USB_HC_INT_NAK | USB_HC_INT_ACK;
555  USB->HC[ hcnum ].INT = 0xFFFFFFFF; /* Clear all interrupt flags */
556  NVIC_ClearPendingIRQ( USB_IRQn );
557  USB->HAINTMSK |= 1 << hcnum; /* Enable host channel interrupt */
558  USB->HC[ hcnum ].CHAR = /* Program HCCHAR register */
560  ( ( ep->addr & USB_EPNUM_MASK ) << _USB_HC_CHAR_EPNUM_SHIFT ) |
561  ( ep->type << _USB_HC_CHAR_EPTYPE_SHIFT ) |
563  ( ep->parentDevice->speed ==
564  HPRT_L_SPEED >> _USB_HPRT_PRTSPD_SHIFT
565  ? USB_HC_CHAR_LSPDDEV : 0 );
566  USB->HC[ hcnum ].TSIZ =
567  ( ( byteCount << _USB_HC_TSIZ_XFERSIZE_SHIFT ) &
569  ( ( packets << _USB_HC_TSIZ_PKTCNT_SHIFT ) &
570  _USB_HC_TSIZ_PKTCNT_MASK ) |
571  ( ( pid << _USB_HC_TSIZ_PID_SHIFT ) &
572  _USB_HC_TSIZ_PID_MASK );
573  USB->HC[ hcnum ].DMAADDR = (uint32_t)data;
574  hcchar = ( USB->HC[ hcnum ].CHAR & ~USB_HC_CHAR_CHDIS ) | USB_HC_CHAR_CHENA;
575  USB->HC[ hcnum ].CHAR = hcchar;
576 
577  /* Start polling for interrupt */
578  retval = USB_STATUS_EP_ERROR;
579  while ( ( USBHAL_GetCoreInts() & USB_GINTSTS_HCHINT ) == 0 ){}
580  if ( USBHHAL_GetHostChannelInts() & ( 1 << hcnum ) )
581  {
582  status = USBHHAL_GetHcInts( hcnum );
583  hcchar |= USB_HC_CHAR_CHDIS;
584  USB->HC[ hcnum ].CHAR = hcchar;
585  USB->HC[ hcnum ].INTMSK = 0;
586  USB->HC[ hcnum ].INT = 0xFFFFFFFF;
587 
588  if ( status & USB_HC_INT_STALL )
589  retval = USB_STATUS_EP_STALLED;
590  else if ( status & USB_HC_INT_NAK )
591  retval = USB_STATUS_EP_NAK;
592  else if ( status & USB_HC_INT_ACK )
593  retval = USB_STATUS_OK;
594  }
595 
596  NVIC_ClearPendingIRQ( USB_IRQn );
597  INT_Enable();
598 
599  return retval;
600 }
601 #endif
602 
605 /***************************************************************************/
613 {
614  return USBH_portStatus == H_PORT_CONNECTED;
615 }
616 
617 /***************************************************************************/
648  void *buf, int len,
649  uint8_t configIndex )
650 {
651  if ( device == NULL )
652  {
653  DEBUG_USB_API_PUTS( "\nUSBH_GetConfigurationDescriptorB(),"
654  " device NULL pointer" );
655  EFM_ASSERT( false );
656  return USB_STATUS_ILLEGAL;
657  }
658 
659  if ( buf == NULL )
660  {
661  DEBUG_USB_API_PUTS( "\nUSBH_GetConfigurationDescriptorB(),"
662  " buf NULL pointer" );
663  EFM_ASSERT( false );
664  return USB_STATUS_ILLEGAL;
665  }
666 
667  return USBH_ControlMsgB( &device->ep0,
669  USB_SETUP_TYPE_STANDARD_MASK, /* bmRequestType */
670  GET_DESCRIPTOR, /* bRequest */
671  (USB_CONFIG_DESCRIPTOR << 8) | configIndex,/* wValue */
672  0, /* wIndex */
673  len, /* wLength */
674  buf, /* void* data */
675  DEFAULT_CTRL_TIMEOUT ); /* int timeout */
676 }
677 
678 /***************************************************************************/
705  void *buf, int len )
706 {
707  if ( device == NULL )
708  {
709  DEBUG_USB_API_PUTS( "\nUSBH_GetDeviceDescriptorB(),"
710  " device NULL pointer" );
711  EFM_ASSERT( false );
712  return USB_STATUS_ILLEGAL;
713  }
714 
715  if ( buf == NULL )
716  {
717  DEBUG_USB_API_PUTS( "\nUSBH_GetDeviceDescriptorB(),"
718  " buf NULL pointer" );
719  EFM_ASSERT( false );
720  return USB_STATUS_ILLEGAL;
721  }
722 
723  return USBH_ControlMsgB( &device->ep0,
725  USB_SETUP_TYPE_STANDARD_MASK, /* bmRequestType */
726  GET_DESCRIPTOR, /* bRequest */
727  USB_DEVICE_DESCRIPTOR << 8, /* wValue */
728  0, /* wIndex */
729  len, /* wLength */
730  buf, /* void* data */
731  DEFAULT_CTRL_TIMEOUT ); /* int timeout */
732 }
733 
734 /***************************************************************************/
741 uint8_t USBH_GetPortSpeed( void )
742 {
743  return USBHHAL_GetPortSpeed();
744 }
745 
746 /***************************************************************************/
779 int USBH_GetStringB( USBH_Device_TypeDef *device, uint8_t *buf, int bufLen,
780  uint8_t stringIndex, uint16_t langID )
781 {
782  int retVal;
784 
785  if ( device == NULL )
786  {
787  DEBUG_USB_API_PUTS( "\nUSBH_GetStringB(), device NULL pointer" );
788  EFM_ASSERT( false );
789  return USB_STATUS_ILLEGAL;
790  }
791 
792  if ( buf == NULL )
793  {
794  DEBUG_USB_API_PUTS( "\nUSBH_GetStringB(), buf NULL pointer" );
795  EFM_ASSERT( false );
796  return USB_STATUS_ILLEGAL;
797  }
798 
799  retVal = USBH_ControlMsgB(
800  &device->ep0,
802  USB_SETUP_TYPE_STANDARD_MASK, /* bmRequestType */
803  GET_DESCRIPTOR, /* bRequest */
804  (USB_STRING_DESCRIPTOR << 8) | stringIndex,/* wValue */
805  langID, /* wIndex */
806  EFM32_MIN( bufLen, 255 ), /* wLength */
807  buf, /* void* data */
808  DEFAULT_CTRL_TIMEOUT ); /* int timeout */
809 
810  if ( retVal > 2 )
811  {
812  sd = (USB_StringDescriptor_TypeDef*)buf;
813  if ( sd->len )
814  {
815  sd->name[ (sd->len - 2) / sizeof( char16_t ) ] = '\0';
816  }
817  }
818  return retVal;
819 }
820 
821 /***************************************************************************/
838 {
839  if ( p == NULL )
840  {
841  DEBUG_USB_API_PUTS( "\nUSBH_Init(), init struct NULL pointer" );
842  EFM_ASSERT( false );
843  return USB_STATUS_ILLEGAL;
844  }
845 
846  if ( ( p->rxFifoSize < MIN_EP_FIFO_SIZE_INBYTES )
847  || ( p->nptxFifoSize < MIN_EP_FIFO_SIZE_INBYTES )
848  || ( p->ptxFifoSize < MIN_EP_FIFO_SIZE_INBYTES )
849  || ( (p->rxFifoSize + p->nptxFifoSize + p->ptxFifoSize) >
850  (MAX_HOST_FIFO_SIZE_INWORDS * 4) ) )
851  {
852  DEBUG_USB_API_PUTS( "\nUSBH_Init(), Illegal Tx/Rx FIFO memory configuration" );
853  EFM_ASSERT( false );
854  return USB_STATUS_ILLEGAL;
855  }
856  USBH_initData = *p;
857 
859  USBTIMER_Init();
860  USBH_portStatus = H_PORT_DISCONNECTED;
861 
862  /* Enable USB clock. */
863  INT_Disable();
866  INT_Enable();
867 
868  /* Enable USB interrupt. */
869  NVIC_ClearPendingIRQ( USB_IRQn );
870  NVIC_EnableIRQ( USB_IRQn );
871 
872  return USB_STATUS_OK;
873 }
874 
875 /***************************************************************************/
906  const uint8_t *buf,
907  USBH_Ep_TypeDef *ep,
908  int numEp,
909  uint8_t deviceSpeed )
910 {
911  int i;
912 
913  if ( device == NULL )
914  {
915  DEBUG_USB_API_PUTS( "\nUSBH_InitDeviceData(), device NULL pointer" );
916  EFM_ASSERT( false );
917  return USB_STATUS_ILLEGAL;
918  }
919 
920  memset( device, 0, sizeof( USBH_Device_TypeDef ) );
921 
922  device->ep = ep;
923  device->addr = 0;
924  device->numEp = numEp;
925  device->speed = deviceSpeed;
926 
927  device->ep0.packetSize = 8;
928  if ( buf ) /* Copy EP0 data from buffer filled by USBH_QueryDevice() */
929  {
930  memcpy( &device->ep0,
931  &((USBH_Device_TypeDef*)buf)->ep0, sizeof( USBH_Ep_TypeDef ) );
932  }
933  device->ep0.parentDevice = device;
934  device->ep0.type = USB_EPTYPE_CTRL;
935  device->ep0.hcOut = 0;
936  device->ep0.hcIn = 1;
937 
938  if ( ep )
939  {
940  for ( i=0; i<numEp; i++ )
941  {
942  memset( &device->ep[i], 0, sizeof( USBH_Ep_TypeDef ) );
943  device->ep[i].parentDevice = device;
944  device->ep[i].toggle = USB_PID_DATA0;
945  }
946  }
947 
948  if ( buf )/* Copy descriptor data from buffer filled by USBH_QueryDevice() */
949  {
950  memcpy( &device->devDesc,
951  &((USBH_Device_TypeDef*)buf)->devDesc, USB_DEVICE_DESCSIZE );
952  memcpy( &device->confDesc,
953  &((USBH_Device_TypeDef*)buf)->confDesc, USB_CONFIG_DESCSIZE );
954  memcpy( &device->itfDesc,
956 
957  if ( ep )
958  {
959  for ( i=0; i<numEp; i++ )
960  {
961  memcpy( &device->ep[i].epDesc,
962  USBH_QGetEndpointDescriptor( buf, 0, 0, i ),
964  }
965  }
966  }
967 
968  return USB_STATUS_OK;
969 }
970 
971 /***************************************************************************/
982 int USBH_PortReset( void )
983 {
984  if ( INT_Disable() > 1 )
985  {
986  INT_Enable();
987  DEBUG_USB_API_PUTS( "\nUSBH_PortReset() called with int's disabled" );
988  EFM_ASSERT( false );
989  return USB_STATUS_ILLEGAL;
990  }
991 
992  USBH_portStatus = H_PORT_CONNECTED_RESETTING;
993  USBHHAL_PortReset( true );
994  INT_Enable();
995  USBTIMER_DelayMs( 50 ); /* USB Reset delay */
996  INT_Disable();
997  USBHHAL_PortReset( false );
998  INT_Enable();
999  USBTIMER_DelayMs( 100 ); /* Reset recovery time */
1000  USBH_portStatus = H_PORT_DISCONNECTED;
1001 
1002  return USB_STATUS_OK;
1003 }
1004 
1005 /***************************************************************************/
1012 int USBH_PortResume( void )
1013 {
1014  if ( INT_Disable() > 1 )
1015  {
1016  INT_Enable();
1017  DEBUG_USB_API_PUTS( "\nUSBH_PortResume() called with int's disabled" );
1018  EFM_ASSERT( false );
1019  return USB_STATUS_ILLEGAL;
1020  }
1021 
1022  USBHHAL_PortResume( true );
1023  INT_Enable();
1024  USBTIMER_DelayMs( 30 );
1025  INT_Disable();
1026  USBHHAL_PortResume( false );
1027  INT_Enable();
1028 
1029  return USB_STATUS_OK;
1030 }
1031 
1032 /***************************************************************************/
1036 void USBH_PortSuspend( void )
1037 {
1038  INT_Disable();
1039  USBHHAL_PortSuspend();
1040  INT_Enable();
1041 }
1042 
1045 int USBH_PortVbusOn( bool on )
1046 {
1047  if ( INT_Disable() > 1 )
1048  {
1049  INT_Enable();
1050  DEBUG_USB_API_PUTS( "\nUSBH_PortVbusOn() called with int's disabled" );
1051  EFM_ASSERT( false );
1052  return USB_STATUS_ILLEGAL;
1053  }
1054 
1055  USBHHAL_VbusOn( on );
1056 
1057  if ( !on )
1058  USBH_portStatus = H_PORT_DISCONNECTED;
1059 
1060  INT_Enable();
1061  USBTIMER_DelayMs( PORT_VBUS_DELAY );
1062 
1063  return USB_STATUS_OK;
1064 }
1065 
1068 #if defined( USB_USE_PRINTF )
1069 /***************************************************************************/
1087  int maxLen )
1088 {
1089  char *c;
1090  int remaining;
1091 
1092  if ( config == NULL )
1093  {
1094  DEBUG_USB_API_PUTS( "\nUSBH_PrintConfigurationDescriptor(),"
1095  " config NULL pointer" );
1096  EFM_ASSERT( false );
1097  return USB_STATUS_ILLEGAL;
1098  }
1099 
1100  USB_PRINTF( "\n\nConfiguration descriptor:" );
1101  USB_PRINTF( "\n bLength %d", config->bLength );
1102  USB_PRINTF( "\n bDescriptorType 0x%02X", config->bDescriptorType );
1103  USB_PRINTF( "\n wTotalLength %d", config->wTotalLength );
1104  USB_PRINTF( "\n bNumInterfaces %d", config->bNumInterfaces );
1105  USB_PRINTF( "\n bConfigurationValue %d", config->bConfigurationValue );
1106  USB_PRINTF( "\n iConfiguration %d", config->iConfiguration );
1107  USB_PRINTF( "\n bmAttributes 0x%02X", config->bmAttributes );
1108  USB_PRINTF( "\n bMaxPower %d\n", config->bMaxPower );
1109 
1110  maxLen -= config->bLength;
1111  if ( maxLen > 0 )
1112  {
1113  remaining = EFM32_MIN( config->wTotalLength - config->bLength, maxLen );
1114  if ( remaining > 0 )
1115  {
1116  USB_PUTCHAR( '\n' );
1117  c = (char*)(config + 1);
1118  while ( remaining-- )
1119  {
1120  USB_PRINTF( "0x%02X ", *c++ );
1121  }
1122  USB_PUTCHAR( '\n' );
1123  }
1124  }
1125 
1126  return USB_STATUS_OK;
1127 }
1128 
1129 /***************************************************************************/
1143 {
1144  if ( device == NULL )
1145  {
1146  DEBUG_USB_API_PUTS( "\nUSBH_PrintDeviceDescriptor(),"
1147  " device NULL pointer" );
1148  EFM_ASSERT( false );
1149  return USB_STATUS_ILLEGAL;
1150  }
1151 
1152  USB_PRINTF( "\n\nDevice descriptor:" );
1153  USB_PRINTF( "\n bLength %d", device->bLength );
1154  USB_PRINTF( "\n bDescriptorType 0x%02X", device->bDescriptorType );
1155  USB_PRINTF( "\n bcdUSB 0x%04X", device->bcdUSB );
1156  USB_PRINTF( "\n bDeviceClass %d", device->bDeviceClass );
1157  USB_PRINTF( "\n bDeviceSubClass %d", device->bDeviceSubClass );
1158  USB_PRINTF( "\n bDeviceProtocol %d", device->bDeviceProtocol );
1159  USB_PRINTF( "\n bMaxPacketSize %d", device->bMaxPacketSize0 );
1160  USB_PRINTF( "\n idVendor 0x%04X", device->idVendor );
1161  USB_PRINTF( "\n idProduct 0x%04X", device->idProduct );
1162  USB_PRINTF( "\n bcdDevice 0x%04X", device->bcdDevice );
1163  USB_PRINTF( "\n iManufacturer %d", device->iManufacturer );
1164  USB_PRINTF( "\n iProduct %d", device->iProduct );
1165  USB_PRINTF( "\n iSerialNumber %d", device->iSerialNumber );
1166  USB_PRINTF( "\n bNumConfigurations %d\n", device->bNumConfigurations );
1167 
1168  return USB_STATUS_OK;
1169 }
1170 
1171 /***************************************************************************/
1185  const USB_EndpointDescriptor_TypeDef *endpoint )
1186 {
1187  if ( endpoint == NULL )
1188  {
1189  DEBUG_USB_API_PUTS( "\nUSBH_PrintEndpointDescriptor(),"
1190  " endpoint NULL pointer" );
1191  EFM_ASSERT( false );
1192  return USB_STATUS_ILLEGAL;
1193  }
1194 
1195  USB_PRINTF( "\n\nEndpoint descriptor:" );
1196  USB_PRINTF( "\n bLength %d", endpoint->bLength );
1197  USB_PRINTF( "\n bDescriptorType 0x%02X", endpoint->bDescriptorType );
1198  USB_PRINTF( "\n bEndpointAddress 0x%02X", endpoint->bEndpointAddress );
1199  USB_PRINTF( "\n bmAttributes 0x%02X", endpoint->bmAttributes );
1200  USB_PRINTF( "\n wMaxPacketSize %d", endpoint->wMaxPacketSize );
1201  USB_PRINTF( "\n bInterval %d\n", endpoint->bInterval );
1202 
1203  return USB_STATUS_OK;
1204 }
1205 
1206 /***************************************************************************/
1220  const USB_InterfaceDescriptor_TypeDef *interface )
1221 {
1222  if ( interface == NULL )
1223  {
1224  DEBUG_USB_API_PUTS( "\nUSBH_PrintInterfaceDescriptor(),"
1225  " interface NULL pointer" );
1226  EFM_ASSERT( false );
1227  return USB_STATUS_ILLEGAL;
1228  }
1229 
1230  USB_PRINTF( "\n\nInterface descriptor:" );
1231  USB_PRINTF( "\n bLength %d", interface->bLength );
1232  USB_PRINTF( "\n bDescriptorType 0x%02X", interface->bDescriptorType );
1233  USB_PRINTF( "\n bInterfaceNumber %d", interface->bInterfaceNumber );
1234  USB_PRINTF( "\n bAlternateSetting %d", interface->bAlternateSetting );
1235  USB_PRINTF( "\n bNumEndpoints %d", interface->bNumEndpoints );
1236  USB_PRINTF( "\n bInterfaceClass 0x%02X", interface->bInterfaceClass );
1237  USB_PRINTF( "\n bInterfaceSubClass 0x%02X", interface->bInterfaceSubClass );
1238  USB_PRINTF( "\n bInterfaceProtocol 0x%02X", interface->bInterfaceProtocol );
1239  USB_PRINTF( "\n iInterface %d\n", interface->iInterface );
1240 
1241  return USB_STATUS_OK;
1242 }
1243 #endif /* defined( USB_USE_PRINTF ) */
1244 
1245 #if defined( __ICCARM__ )
1246 #pragma diag_suppress=Pa039
1247 #endif
1248 /***************************************************************************/
1268 void USBH_PrintString( const char *pre,
1270  const char *post )
1271 {
1272  char *c;
1273 
1274  if ( pre )
1275  {
1276  USB_PUTS( pre );
1277  }
1278 
1279  if ( s )
1280  {
1281  c = (char*)&s->name;
1282  while ( *c )
1283  {
1284  USB_PUTCHAR( *c );
1285  c += 2;
1286  }
1287  }
1288 
1289  if ( post )
1290  {
1291  USB_PUTS( post );
1292  }
1293 }
1294 #if defined( __ICCARM__ )
1295 #pragma diag_default=Pa039
1296 #endif
1297 
1298  /*
1299  * A request for a configuration descriptor returns the configuration
1300  * descriptor, all interface descriptors, and endpoint descriptors for all
1301  * of the interfaces in a single request.
1302  * The first interface descriptor follows the configuration descriptor.
1303  * The endpoint descriptors for the first interface follow the first interface
1304  * descriptor.
1305  * If there are additional interfaces, their interface descriptor and endpoint
1306  * descriptors follow the first interface's endpoint descriptors.
1307  * Class-specific and/or vendor-specific descriptors follow the standard
1308  * descriptors they extend or modify.
1309  */
1310 
1311 /***************************************************************************/
1332  const uint8_t *buf, int configIndex )
1333 {
1334  int i;
1335  const uint8_t *start, *end;
1337 
1338  dev = USBH_QGetDeviceDescriptor( buf );
1339  if ( dev )
1340  {
1341  if ( configIndex < dev->bNumConfigurations )
1342  {
1343  /* Start of first configuration descriptor */
1344  start = buf + sizeof( USBH_Device_TypeDef );
1345 
1346  /* Find end of avaiable data, NOTE: ep contains end of buf ! */
1347  end = EFM32_MIN(
1348  start + ((USB_ConfigurationDescriptor_TypeDef*)start)->wTotalLength,
1349  (uint8_t*)(((USBH_Device_TypeDef*)buf)->ep));
1350 
1351  /* Scan through, looking for correct configuration descriptor */
1352  i = 0;
1353  while ( start < end )
1354  {
1355  if ( *start == 0 )
1356  return NULL;
1357 
1358  if ( ( *start == USB_CONFIG_DESCSIZE ) &&
1359  ( *(start+1) == USB_CONFIG_DESCRIPTOR ) )
1360  {
1361  if ( i == configIndex )
1362  {
1363  return (USB_ConfigurationDescriptor_TypeDef*)start;
1364  }
1365  i++;
1366  }
1367 
1368  start += *start;
1369  }
1370  }
1371  }
1372  return NULL;
1373 }
1374 
1375 /***************************************************************************/
1388 {
1389  USB_DeviceDescriptor_TypeDef *dev = &((USBH_Device_TypeDef*)buf)->devDesc;
1390 
1391  if ( buf == NULL )
1392  {
1393  DEBUG_USB_API_PUTS( "\nUSBH_QGetDeviceDescriptor(), buf NULL pointer" );
1394  EFM_ASSERT( false );
1395  return NULL;
1396  }
1397 
1398  if ( ( dev->bLength == USB_DEVICE_DESCSIZE ) &&
1400  {
1401  return dev;
1402  }
1403  return NULL;
1404 }
1405 
1406 /***************************************************************************/
1435  const uint8_t *buf, int configIndex, int interfaceIndex, int endpointIndex )
1436 {
1437  int i;
1438  uint8_t *start, *end;
1440 
1441  itf = USBH_QGetInterfaceDescriptor( buf, configIndex, interfaceIndex );
1442  if ( itf )
1443  {
1444  if ( endpointIndex < itf->bNumEndpoints )
1445  {
1446  /* First possible endpoint descriptor */
1447  start = (uint8_t*)itf + USB_INTERFACE_DESCSIZE;
1448 
1449  /* Search until start of next interface decsriptor, or to end of buf */
1450  end = (uint8_t*)USBH_QGetInterfaceDescriptor(
1451  buf, configIndex, interfaceIndex + 1 );
1452  if ( end == NULL )
1453  {
1454  /* NOTE: ep contains end of buf ! */
1455  end = (uint8_t*)((USBH_Device_TypeDef*)buf)->ep;
1456  }
1457 
1458  /* Scan through, looking for correct endpoint descriptor */
1459  i = 0;
1460  while ( start < end )
1461  {
1462  if ( *start == 0 )
1463  return NULL;
1464 
1465  if ( ( *start == USB_ENDPOINT_DESCSIZE ) &&
1466  ( *(start+1) == USB_ENDPOINT_DESCRIPTOR ) )
1467  {
1468  if ( i == endpointIndex )
1469  {
1470  return (USB_EndpointDescriptor_TypeDef*)start;
1471  }
1472  i++;
1473  }
1474 
1475  start += *start;
1476  }
1477  }
1478  }
1479  return NULL;
1480 }
1481 
1482 /***************************************************************************/
1507  const uint8_t *buf, int configIndex, int interfaceIndex )
1508 {
1509  int i;
1510  uint8_t *start, *end;
1512 
1513  conf = USBH_QGetConfigurationDescriptor( buf, configIndex );
1514  if ( conf )
1515  {
1516  if ( interfaceIndex < conf->bNumInterfaces )
1517  {
1518  /* First interface descriptor */
1519  start = (uint8_t*)conf + USB_CONFIG_DESCSIZE;
1520 
1521  /* Search until start of next config decsriptor, or to end of buf */
1522  end = (uint8_t*)USBH_QGetConfigurationDescriptor( buf, configIndex + 1 );
1523  if ( end == NULL )
1524  {
1525  /* NOTE: ep contains end of buf ! */
1526  end = (uint8_t*)((USBH_Device_TypeDef*)buf)->ep;
1527  }
1528 
1529  /* Scan through, looking for correct interface descriptor */
1530  i = 0;
1531  while ( start < end )
1532  {
1533  if ( *start == 0 )
1534  return NULL;
1535 
1536  if ( ( *start == USB_INTERFACE_DESCSIZE ) &&
1537  ( *(start+1) == USB_INTERFACE_DESCRIPTOR ) )
1538  {
1539  if ( ( i == interfaceIndex ) &&
1540  ( i ==
1541  ((USB_InterfaceDescriptor_TypeDef*)start)->bInterfaceNumber ) )
1542  {
1543  return (USB_InterfaceDescriptor_TypeDef*)start;
1544  }
1545  i++;
1546  }
1547 
1548  start += *start;
1549  }
1550  }
1551  }
1552  return NULL;
1553 }
1554 
1555 /***************************************************************************/
1582 int USBH_QueryDeviceB( uint8_t *buf, size_t bufsize, uint8_t deviceSpeed )
1583 {
1584  USBH_Device_TypeDef *device = (USBH_Device_TypeDef*)buf;
1585 
1586  USBH_InitDeviceData( device, NULL, NULL, 0, deviceSpeed );
1587 
1588  device->speed = deviceSpeed;
1589  device->ep = (USBH_Ep_TypeDef*)(buf+bufsize);/* Save buffer end addr here ! */
1590 
1591  /* Get the first 8 bytes of the device desc to figure out device EP0 size */
1592  if ( 8 != USBH_GetDeviceDescriptorB( device,
1593  &device->devDesc,
1594  EFM32_MIN( 8U, bufsize ) ) )
1595  {
1596  return USB_STATUS_REQ_ERR;
1597  }
1598  device->ep0.packetSize = device->devDesc.bMaxPacketSize0;
1599 
1600  /* Get entire device descriptor */
1602  device,
1603  buf + sizeof( USBH_Device_TypeDef ),
1604  EFM32_MIN( (size_t)USB_DEVICE_DESCSIZE, bufsize ) ) )
1605  {
1606  return USB_STATUS_REQ_ERR;
1607  }
1608  memcpy( &device->devDesc,
1609  buf + sizeof( USBH_Device_TypeDef ), USB_DEVICE_DESCSIZE );
1610 
1611  /* Get configuration descriptor. */
1613  device,
1614  buf + sizeof( USBH_Device_TypeDef ),
1615  EFM32_MIN( (size_t)USB_CONFIG_DESCSIZE,
1616  bufsize - (size_t)USB_DEVICE_DESCSIZE ),
1617  0 ) )
1618  {
1619  return USB_STATUS_REQ_ERR;
1620  }
1621  memcpy( &device->confDesc,
1622  buf + sizeof( USBH_Device_TypeDef ), USB_CONFIG_DESCSIZE );
1623 
1624  /* Get complete configuration descriptor. NOTE: Descriptor data is */
1625  /* appended at the end of the device data structure ! */
1626  if ( ( USB_CONFIG_DESCSIZE + USB_INTERFACE_DESCSIZE ) >
1628  device,
1629  buf + sizeof( USBH_Device_TypeDef ),
1630  EFM32_MIN( device->confDesc.wTotalLength,
1631  bufsize - sizeof( USBH_Device_TypeDef )),
1632  0 ) )
1633  {
1634  return USB_STATUS_REQ_ERR;
1635  }
1636 
1637  return USB_STATUS_OK;
1638 }
1639 
1640 /***************************************************************************/
1672 int USBH_Read( USBH_Ep_TypeDef *ep, void *data, int byteCount, int timeout,
1673  USB_XferCompleteCb_TypeDef callback )
1674 {
1675  USBH_Hc_TypeDef *hc = &hcs[ ep->hcIn ];
1676 
1677  if ( ep == NULL )
1678  {
1679  DEBUG_USB_API_PUTS( "\nUSBH_Read(), ep NULL pointer" );
1680  EFM_ASSERT( false );
1681  return USB_STATUS_ILLEGAL;
1682  }
1683 
1684  if ( !USBH_DeviceConnected() )
1685  {
1686  DEBUG_USB_API_PUTS( "\nUSBH_Read(), No device connected" );
1687  return USB_STATUS_ILLEGAL;
1688  }
1689 
1690  if ( ( byteCount > MAX_XFER_LEN ) ||
1691  ( ( byteCount / ep->packetSize ) > MAX_PACKETS_PR_XFER ) )
1692  {
1693  DEBUG_USB_API_PUTS( "\nUSBH_Read(), Illegal transfer size" );
1694  EFM_ASSERT( false );
1695  return USB_STATUS_ILLEGAL;
1696  }
1697 
1698  if ( (uint32_t)data & 3 )
1699  {
1700  DEBUG_USB_API_PUTS( "\nUSBH_Read(), Misaligned data buffer" );
1701  EFM_ASSERT( false );
1702  return USB_STATUS_ILLEGAL;
1703  }
1704 
1705  INT_Disable();
1706  if ( ep->state != H_EP_IDLE )
1707  {
1708  INT_Enable();
1709  DEBUG_USB_API_PUTS( "\nUSBH_Read(), Endpoint is busy" );
1710  return USB_STATUS_EP_BUSY;
1711  }
1712 
1713  if ( !ep->in )
1714  {
1715  INT_Enable();
1716  DEBUG_USB_API_PUTS( "\nUSBH_Read(), Illegal EP direction" );
1717  EFM_ASSERT( false );
1718  return USB_STATUS_ILLEGAL;
1719  }
1720 
1721  if ( !hc->idle )
1722  {
1723  INT_Enable();
1724  DEBUG_USB_API_PUTS( "\nUSBH_Read(), Host channel is busy" );
1725  return USB_STATUS_HC_BUSY;
1726  }
1727 
1728  ep->xferCompleted = false;
1729  ep->state = H_EP_DATA_IN;
1730  ep->xferCompleteCb = callback;
1731  ep->buf = data;
1732  ep->remaining = byteCount;
1733  ep->xferred = 0;
1734  ep->timeout = timeout;
1735 
1736  hc->buf = data;
1737  hc->xferred = 0;
1738  hc->remaining = byteCount;
1739  hc->ep = ep;
1740 
1741  if ( ep->type == USB_EPTYPE_INTR )
1742  {
1743  if ( timeout )
1744  timeout = EFM32_MIN( timeout, ep->epDesc.bInterval );
1745  else
1746  timeout = ep->epDesc.bInterval;
1747  }
1748 
1749  if ( timeout )
1750  {
1751  USBTIMER_Start( ep->hcIn + HOSTCH_TIMER_INDEX,
1752  timeout, hcTimeoutFunc[ ep->hcIn ] );
1753  }
1754 
1755  USBHHAL_HCInit( ep->hcIn );
1756  USBHHAL_HCStart( ep->hcIn );
1757 
1758  INT_Enable();
1759 
1760  return USB_STATUS_OK;
1761 }
1762 
1763 /***************************************************************************/
1794 int USBH_ReadB( USBH_Ep_TypeDef *ep, void *data, int byteCount, int timeout )
1795 {
1796  int retVal;
1797 
1798  if ( INT_Disable() > 1 )
1799  {
1800  INT_Enable();
1801  DEBUG_USB_API_PUTS( "\nUSBH_ReadB() called with int's disabled" );
1802  EFM_ASSERT( false );
1803  return USB_STATUS_ILLEGAL;
1804  }
1805 
1806  retVal = USBH_Read( ep, data, byteCount, timeout, NULL );
1807  INT_Enable();
1808 
1809  if ( retVal == USB_STATUS_OK )
1810  {
1811  while ( ! ep->xferCompleted );
1812 
1813  if ( ( retVal = ep->xferStatus ) == USB_STATUS_OK )
1814  {
1815  retVal = ep->xferred;
1816  }
1817  }
1818 
1819  return retVal;
1820 }
1821 
1822 /***************************************************************************/
1841 int USBH_SetAddressB( USBH_Device_TypeDef *device, uint8_t deviceAddress )
1842 {
1843  int retVal;
1844 
1845  if ( device == NULL )
1846  {
1847  DEBUG_USB_API_PUTS( "\nUSBH_SetAddressB(), device NULL pointer" );
1848  EFM_ASSERT( false );
1849  return USB_STATUS_ILLEGAL;
1850  }
1851 
1852  if ( deviceAddress > USB_MAX_DEVICE_ADDRESS )
1853  {
1854  DEBUG_USB_API_PUTS( "\nUSBH_SetAddressB(), Illegal device address" );
1855  EFM_ASSERT( false );
1856  return USB_STATUS_ILLEGAL;
1857  }
1858 
1859  retVal = USBH_ControlMsgB(
1860  &device->ep0,
1862  USB_SETUP_TYPE_STANDARD_MASK, /* bmRequestType */
1863  SET_ADDRESS, /* bRequest */
1864  deviceAddress, /* wValue */
1865  0, /* wIndex */
1866  0, /* wLength */
1867  NULL, /* void* data */
1868  DEFAULT_CTRL_TIMEOUT ); /* int timeout */
1869 
1870  if ( retVal == USB_STATUS_OK )
1871  {
1872  device->addr = deviceAddress;
1873  }
1874  return retVal;
1875 }
1876 
1877 /***************************************************************************/
1898  uint8_t interfaceIndex, uint8_t alternateSetting )
1899 {
1900  int i, retVal;
1901 
1902  if ( device == NULL )
1903  {
1904  DEBUG_USB_API_PUTS( "\nUSBH_SetAltInterfaceB(), device NULL pointer" );
1905  EFM_ASSERT( false );
1906  return USB_STATUS_ILLEGAL;
1907  }
1908 
1909  retVal = USBH_ControlMsgB(
1910  &device->ep0,
1912  USB_SETUP_TYPE_STANDARD_MASK, /* bmRequestType */
1913  SET_INTERFACE, /* bRequest */
1914  alternateSetting, /* wValue */
1915  interfaceIndex, /* wIndex */
1916  0, /* wLength */
1917  NULL, /* void* data */
1918  DEFAULT_CTRL_TIMEOUT ); /* int timeout */
1919 
1920  if ( retVal == USB_STATUS_OK )
1921  {
1922  // Alternate settings are mutually exclusive within the interface
1923 
1924  // We should:
1925  // Deactivate ep's in previous alternate interface setting
1926  // Activate ep's in the new alternate setting of the interface
1927 
1928  for ( i=0; i<device->numEp; i++ ) /* Reset all data toggles */
1929  {
1930  device->ep[i].toggle = USB_PID_DATA0;
1931  }
1932  }
1933 
1934  return retVal;
1935 }
1936 
1937 /***************************************************************************/
1956 int USBH_SetConfigurationB( USBH_Device_TypeDef *device, uint8_t configValue )
1957 {
1958  int i, retVal;
1959 
1960  if ( device == NULL )
1961  {
1962  DEBUG_USB_API_PUTS( "\nUSBH_SetConfigurationB(), device NULL pointer" );
1963  EFM_ASSERT( false );
1964  return USB_STATUS_ILLEGAL;
1965  }
1966 
1967  retVal = USBH_ControlMsgB(
1968  &device->ep0,
1970  USB_SETUP_TYPE_STANDARD_MASK, /* bmRequestType */
1971  SET_CONFIGURATION, /* bRequest */
1972  configValue, /* wValue */
1973  0, /* wIndex */
1974  0, /* wLength */
1975  NULL, /* void* data */
1976  DEFAULT_CTRL_TIMEOUT ); /* int timeout */
1977 
1978  if ( retVal == USB_STATUS_OK )
1979  {
1980  // Configurations are mutually exclusive within the device
1981 
1982  // Should:
1983  // Deactivate ep's in previous configuration
1984  // Activate ep's in new configuration
1985 
1986  for ( i=0; i<device->numEp; i++ ) /* Reset all data toggles */
1987  {
1988  device->ep[i].toggle = USB_PID_DATA0;
1989  }
1990  }
1991 
1992  return retVal;
1993 }
1994 
1995 /***************************************************************************/
2010 {
2011  if ( ep == NULL )
2012  {
2013  DEBUG_USB_API_PUTS( "\nUSBH_StallEpB(), ep NULL pointer" );
2014  EFM_ASSERT( false );
2015  return USB_STATUS_ILLEGAL;
2016  }
2017 
2018  return USBH_ControlMsgB( &ep->parentDevice->ep0,
2020  USB_SETUP_TYPE_STANDARD_MASK, /* bmRequestType */
2021  SET_FEATURE, /* bRequest */
2022  USB_FEATURE_ENDPOINT_HALT, /* wValue */
2023  ep->addr, /* wIndex */
2024  0, /* wLength */
2025  NULL, /* void* data */
2026  DEFAULT_CTRL_TIMEOUT ); /* int timeout */
2027 }
2028 
2029 /***************************************************************************/
2036 void USBH_Stop( void )
2037 {
2038  int i;
2039 
2040  USBTIMER_Stop( HOSTPORT_TIMER_INDEX );
2041  for ( i = 0; i < NUM_HC_USED + 2; i++ )
2042  {
2043  USBTIMER_Stop( i + HOSTCH_TIMER_INDEX );
2044  }
2045  INT_Disable();
2046  USBHAL_DisableGlobalInt();
2047  INT_Enable();
2048  USBH_PortVbusOn( false );
2049  USBHAL_DisablePhyPins();
2050  /* Turn off USB clocks. */
2051  CMU->HFCORECLKEN0 &= ~(CMU_HFCORECLKEN0_USB | CMU_HFCORECLKEN0_USBC);
2052 }
2053 
2054 /***************************************************************************/
2069 {
2070  int retVal;
2071 
2072  if ( ep == NULL )
2073  {
2074  DEBUG_USB_API_PUTS( "\nUSBH_UnStallEpB(), ep NULL pointer" );
2075  EFM_ASSERT( false );
2076  return USB_STATUS_ILLEGAL;
2077  }
2078 
2079  retVal = USBH_ControlMsgB( &ep->parentDevice->ep0,
2081  USB_SETUP_TYPE_STANDARD_MASK, /* bmRequestType */
2082  CLEAR_FEATURE, /* bRequest */
2083  USB_FEATURE_ENDPOINT_HALT, /* wValue */
2084  ep->addr, /* wIndex */
2085  0, /* wLength */
2086  NULL, /* void* data */
2087  DEFAULT_CTRL_TIMEOUT ); /* int timeout */
2088 
2089  if ( retVal == USB_STATUS_OK )
2090  {
2091  ep->toggle = USB_PID_DATA0;
2092  }
2093 
2094  return retVal;
2095 }
2096 
2099 static void InitUsb( void )
2100 {
2101  int i;
2102 
2103  memset( hcs, 0, sizeof( hcs ) );
2104  for ( i = 0; i < NUM_HC_USED + 2; i++ )
2105  {
2106  hcs[ i ].idle = true;
2107  }
2108 
2109  INT_Disable();
2110  USBHHAL_CoreInit( USBH_initData.rxFifoSize, USBH_initData.nptxFifoSize,
2111  USBH_initData.ptxFifoSize );
2112 
2113  NVIC_ClearPendingIRQ( USB_IRQn );
2114  INT_Enable();
2115 }
2116 
2119 /***************************************************************************/
2146 int USBH_WaitForDeviceConnectionB( uint8_t *buf, int timeoutInSeconds )
2147 {
2148  bool xferError;
2149  USBH_Device_TypeDef *device;
2150  int accumulatedTime, deadLine;
2151 
2152  if ( buf == NULL )
2153  {
2154  DEBUG_USB_API_PUTS( "\nUSBH_WaitForDeviceConnectionB(),"
2155  " buf NULL pointer" );
2156  EFM_ASSERT( false );
2157  return USB_STATUS_ILLEGAL;
2158  }
2159 
2160  xferError = false;
2161  accumulatedTime = 0;
2162  USBH_attachRetryCount = 0;
2163  deadLine = timeoutInSeconds * 1000;
2164  device = (USBH_Device_TypeDef*)buf;
2165 
2166  while ( 1 )
2167  {
2168  /* If USB is enabled, turn it off. */
2169  if ( USBHHAL_InitializedAndPowered() )
2170  {
2171  USBH_PortVbusOn( false );
2172  if ( deadLine )
2173  accumulatedTime += PORT_VBUS_DELAY;
2174  }
2175 
2176  /* Reset and init USB core. */
2177  InitUsb();
2178  if ( deadLine )
2179  accumulatedTime += 50;
2180 
2181  /* Turn on VBUS. */
2182  USBH_PortVbusOn( true );
2183  DEBUG_USB_INT_LO_PUTCHAR( '1' );
2184  if ( deadLine )
2185  accumulatedTime += PORT_VBUS_DELAY;
2186 
2187  /* Enable interrupts from USB core. */
2188  INT_Disable();
2189  USBHHAL_EnableInts();
2190  USBHAL_EnableGlobalInt();
2191  INT_Enable();
2192 
2193  /* Wait for device connection. */
2194  while ( 1 )
2195  {
2196  if ( USBH_DeviceConnected() )
2197  break;
2198 
2199  if ( ( deadLine ) &&
2200  ( accumulatedTime >= deadLine ) )
2201  {
2202  return USB_STATUS_TIMEOUT;
2203  }
2204 
2205 #if ( USB_VBUSOVRCUR_PORT != USB_VBUSOVRCUR_PORT_NONE )
2206  if ( GPIO_PinInGet( USB_VBUSOVRCUR_PORT, USB_VBUSOVRCUR_PIN ) ==
2207  USB_VBUSOVRCUR_POLARITY )
2208  {
2209  DEBUG_USB_INT_LO_PUTCHAR( '~' );
2210  USBHHAL_PortReset( false );
2211  USBHHAL_VbusOn( false );
2212  USBTIMER_Stop( HOSTPORT_TIMER_INDEX );
2213  USBH_portStatus = H_PORT_OVERCURRENT;
2215  }
2216 #endif
2217  USBTIMER_DelayMs( 50 );
2218  if ( deadLine )
2219  accumulatedTime += 50;
2220  }
2221 
2222  /* Reset recovery time, the USB standard says 10ms. Extend the */
2223  /* timeout to be lenient with non compliant devices. */
2224  USBTIMER_DelayMs( 100 );
2225  if ( deadLine )
2226  accumulatedTime += 100;
2227 
2228  /* Do one USB transfer to check if device connection is OK. */
2229 
2230  USBH_InitDeviceData( device, NULL, NULL, 0, USBH_GetPortSpeed() );
2231 
2232  /* Get the first 8 bytes of the device descriptor */
2233  if ( 8 == USBH_GetDeviceDescriptorB( device, &device->devDesc, 8 ) )
2234  {
2235  return USB_STATUS_OK;
2236  }
2237  else
2238  {
2239  xferError = true;
2240  if ( deadLine )
2241  accumulatedTime += DEFAULT_CTRL_TIMEOUT;
2242  }
2243 
2244  /* Disable USB, power down VBUS. */
2245  USBH_Stop();
2246  /* Enable USB clocks again, USBH_Stop() turns them off. */
2247  CMU->HFCORECLKEN0 |= CMU_HFCORECLKEN0_USB | CMU_HFCORECLKEN0_USBC;
2248 
2249  if ( deadLine )
2250  accumulatedTime += PORT_VBUS_DELAY;
2251 
2252  if ( ( deadLine ) &&
2253  ( accumulatedTime >= deadLine ) )
2254  break;
2255 
2256  USBH_attachRetryCount = ( USBH_attachRetryCount + 1 ) %
2257  ( sizeof( USBH_attachTiming ) /
2258  sizeof( USBH_AttachTiming_TypeDef ) );
2259  }
2260 
2261  if ( xferError )
2263 
2264  return USB_STATUS_TIMEOUT;
2265 }
2266 
2267 /***************************************************************************/
2297 int USBH_Write( USBH_Ep_TypeDef *ep, void *data, int byteCount,
2298  int timeout, USB_XferCompleteCb_TypeDef callback )
2299 {
2300  USBH_Hc_TypeDef *hc = &hcs[ ep->hcOut ];
2301 
2302  if ( ep == NULL )
2303  {
2304  DEBUG_USB_API_PUTS( "\nUSBH_Write(), ep NULL pointer" );
2305  EFM_ASSERT( false );
2306  return USB_STATUS_ILLEGAL;
2307  }
2308 
2309  if ( !USBH_DeviceConnected() )
2310  {
2311  DEBUG_USB_API_PUTS( "\nUSBH_Write(), No device connected" );
2312  return USB_STATUS_ILLEGAL;
2313  }
2314 
2315  if ( ( byteCount > MAX_XFER_LEN ) ||
2316  ( ( byteCount / ep->packetSize ) > MAX_PACKETS_PR_XFER ) )
2317  {
2318  DEBUG_USB_API_PUTS( "\nUSBH_Write(), Illegal transfer size" );
2319  EFM_ASSERT( false );
2320  return USB_STATUS_ILLEGAL;
2321  }
2322 
2323  if ( (uint32_t)data & 3 )
2324  {
2325  DEBUG_USB_API_PUTS( "\nUSBH_Write(), Misaligned data buffer" );
2326  EFM_ASSERT( false );
2327  return USB_STATUS_ILLEGAL;
2328  }
2329 
2330  INT_Disable();
2331  if ( ep->state != H_EP_IDLE )
2332  {
2333  INT_Enable();
2334  DEBUG_USB_API_PUTS( "\nUSBH_Write(), Endpoint is busy" );
2335  return USB_STATUS_EP_BUSY;
2336  }
2337 
2338  if ( ep->in )
2339  {
2340  INT_Enable();
2341  DEBUG_USB_API_PUTS( "\nUSBH_Write(), Illegal EP direction" );
2342  EFM_ASSERT( false );
2343  return USB_STATUS_ILLEGAL;
2344  }
2345 
2346  if ( !hc->idle )
2347  {
2348  INT_Enable();
2349  DEBUG_USB_API_PUTS( "\nUSBH_Write(), Host channel is busy" );
2350  return USB_STATUS_HC_BUSY;
2351  }
2352 
2353  ep->xferCompleted = false;
2354  ep->state = H_EP_DATA_OUT;
2355  ep->xferCompleteCb = callback;
2356  ep->buf = data;
2357  ep->remaining = byteCount;
2358  ep->xferred = 0;
2359  ep->timeout = timeout;
2360 
2361  hc->buf = data;
2362  hc->xferred = 0;
2363  hc->remaining = byteCount;
2364  hc->ep = ep;
2365 
2366  if ( ep->type == USB_EPTYPE_INTR )
2367  {
2368  if ( timeout )
2369  timeout = EFM32_MIN( timeout, ep->epDesc.bInterval );
2370  else
2371  timeout = ep->epDesc.bInterval;
2372  }
2373 
2374  if ( timeout )
2375  {
2376  USBTIMER_Start( ep->hcOut + HOSTCH_TIMER_INDEX,
2377  timeout, hcTimeoutFunc[ ep->hcOut ] );
2378  }
2379 
2380  USBHHAL_HCInit( ep->hcOut );
2381  USBHHAL_HCStart( ep->hcOut );
2382 
2383  INT_Enable();
2384 
2385  return USB_STATUS_OK;
2386 }
2387 
2388 /***************************************************************************/
2417 int USBH_WriteB( USBH_Ep_TypeDef *ep, void *data, int byteCount, int timeout )
2418 {
2419  int retVal;
2420 
2421  if ( INT_Disable() > 1 )
2422  {
2423  INT_Enable();
2424  DEBUG_USB_API_PUTS( "\nUSBH_WriteB() called with int's disabled" );
2425  EFM_ASSERT( false );
2426  return USB_STATUS_ILLEGAL;
2427  }
2428 
2429  retVal = USBH_Write( ep, data, byteCount, timeout, NULL );
2430  INT_Enable();
2431 
2432  if ( retVal == USB_STATUS_OK )
2433  {
2434  while ( ! ep->xferCompleted );
2435 
2436  if ( ( retVal = ep->xferStatus ) == USB_STATUS_OK )
2437  {
2438  retVal = ep->xferred;
2439  }
2440  }
2441 
2442  return retVal;
2443 }
2444 
2445 /******** THE REST OF THE FILE IS DOCUMENTATION ONLY !**********************/
2790 #endif /* defined( USB_HOST ) */
2791 #endif /* defined( USB_PRESENT ) && ( USB_COUNT == 1 ) */
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:2406
#define EFM32_MIN(a, b)
Definition: em_common.h:79
#define SET_INTERFACE
Definition: em_usb.h:88
#define USB_INTERFACE_DESCSIZE
Definition: em_usb.h:146
uint8_t hcIn
Definition: em_usb.h:871
int USBH_WriteB(USBH_Ep_TypeDef *ep, void *data, int byteCount, int timeout)
Write data to device endpoint, blocking version.
Definition: em_usbh.c:2417
#define SET_CONFIGURATION
Definition: em_usb.h:86
int USBH_UnStallEpB(USBH_Ep_TypeDef *ep)
Reset stall state on a stalled (halted) endpoint.
Definition: em_usbh.c:2068
#define CMU_HFCORECLKEN0_USBC
Definition: ezr32wg_cmu.h:826
#define USB_EPNUM_MASK
Definition: em_usb.h:179
#define USB_SETUP_DIR_D2H
Definition: em_usb.h:61
void USBTIMER_Stop(uint32_t id)
Stop a timer.
Definition: em_usbtimer.c:302
USB protocol stack library API for EFM32/EZR32.
void USBH_PortSuspend(void)
Set the USB port in suspend mode.
Definition: em_usbh.c:1036
uint8_t bmRequestType
Definition: em_usb.h:389
#define USB
uint32_t xferred
Definition: em_usb.h:880
#define USB_SETUP_DIR_H2D
Definition: em_usb.h:62
uint32_t ptxFifoSize
Definition: em_usb.h:909
#define USB_STRING_DESCRIPTOR
Definition: em_usb.h:118
uint16_t wValue
Definition: em_usb.h:392
#define USB_SETUP_RECIPIENT_ENDPOINT
Definition: em_usb.h:75
USB HOST device definition.
Definition: em_usb.h:889
int USB_PRINTF(const char *format,...)
Transmit "printf" formated data on the debug serial port.
USB_DeviceDescriptor_TypeDef * USBH_QGetDeviceDescriptor(const uint8_t *buf)
Return a pointer to the device descriptor.
Definition: em_usbh.c:1387
__STATIC_INLINE uint32_t INT_Enable(void)
Enable interrupts.
Definition: em_int.h:94
#define _USB_HC_TSIZ_PID_MASK
Definition: ezr32wg_usb.h:1474
#define CMU_HFCORECLKEN0_USB
Definition: ezr32wg_cmu.h:831
int USBH_ReadB(USBH_Ep_TypeDef *ep, void *data, int byteCount, int timeout)
Read data from device endpoint, blocking version.
Definition: em_usbh.c:1794
USB Host stack initialization structure.
Definition: em_usb.h:905
CMSIS Cortex-M Peripheral Access Layer for Silicon Laboratories microcontroller devices.
USB_InterfaceDescriptor_TypeDef * USBH_QGetInterfaceDescriptor(const uint8_t *buf, int configIndex, int interfaceIndex)
Return a pointer to an interface descriptor.
Definition: em_usbh.c:1506
#define _USB_HC_CHAR_MPS_SHIFT
Definition: ezr32wg_usb.h:1296
int USBH_GetDeviceDescriptorB(USBH_Device_TypeDef *device, void *buf, int len)
Read a device descriptor from a device.
Definition: em_usbh.c:704
int USBH_PrintConfigurationDescriptor(const USB_ConfigurationDescriptor_TypeDef *config, int maxLen)
Pretty print a configuration descriptor on the debug serial port.
Definition: em_usbh.c:1085
#define USB_SETUP_DIR_MASK
Definition: em_usb.h:60
void(* USBTIMER_Callback_TypeDef)(void)
USBTIMER callback function.
Definition: em_usb.h:673
#define _USB_HC_CHAR_EPTYPE_SHIFT
Definition: ezr32wg_usb.h:1318
USBH_Ep_TypeDef * ep
Definition: em_usb.h:895
#define _USB_HC_TSIZ_PKTCNT_SHIFT
Definition: ezr32wg_usb.h:1469
int USBH_ControlMsgB(USBH_Ep_TypeDef *ep, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength, void *data, int timeout)
Send a SETUP command to a device, blocking version.
Definition: em_usbh.c:367
void USBTIMER_DelayMs(uint32_t msec)
Active wait millisecond delay function. Can also be used inside interrupt handlers.
Definition: em_usbtimer.c:135
USB Interface Descriptor.
Definition: em_usb.h:457
uint8_t setupErrCnt
Definition: em_usb.h:865
int(* USB_XferCompleteCb_TypeDef)(USB_Status_TypeDef status, uint32_t xferred, uint32_t remaining)
USB transfer callback function.
Definition: em_usb.h:663
uint16_t packetSize
Definition: em_usb.h:869
#define USB_HC_INT_NAK
Definition: ezr32wg_usb.h:1377
bool USBH_DeviceConnected(void)
Check if a device is connected.
Definition: em_usbh.c:612
USB_Status_TypeDef
USB transfer status enumerator.
Definition: em_usb.h:316
int USBH_GetConfigurationDescriptorB(USBH_Device_TypeDef *device, void *buf, int len, uint8_t configIndex)
Read a configuration descriptor from a device.
Definition: em_usbh.c:647
#define USB_HC_INT_ACK
Definition: ezr32wg_usb.h:1382
uint16_t wIndex
Definition: em_usb.h:393
int USBH_SetAddressB(USBH_Device_TypeDef *device, uint8_t deviceAddress)
Give a device an USB address.
Definition: em_usbh.c:1841
volatile bool xferCompleted
Definition: em_usb.h:877
uint32_t timeout
Definition: em_usb.h:882
USB_Status_TypeDef xferStatus
Definition: em_usb.h:878
#define USB_DEVICE_DESCRIPTOR
Definition: em_usb.h:116
int USBH_StallEpB(USBH_Ep_TypeDef *ep)
Set an endpoint in the stalled (halted) state.
Definition: em_usbh.c:2009
int USBH_SetAltInterfaceB(USBH_Device_TypeDef *device, uint8_t interfaceIndex, uint8_t alternateSetting)
Activate a device interface within current device configuration.
Definition: em_usbh.c:1897
void USBH_PrintString(const char *pre, const USB_StringDescriptor_TypeDef *s, const char *post)
Print a USB string descriptor on the debug serial port.
Definition: em_usbh.c:1268
#define SET_ADDRESS
Definition: em_usb.h:82
#define USB_CONFIG_DESCSIZE
Definition: em_usb.h:145
struct USBH_Device_TypeDef * parentDevice
Definition: em_usb.h:867
void USB_PUTS(const char *p)
Transmit a zero terminated string on the debug serial port.
General Purpose IO (GPIO) peripheral API.
struct USBH_Device_TypeDef USBH_Device_TypeDef
USB HOST device definition.
#define _USB_HC_CHAR_EPNUM_SHIFT
Definition: ezr32wg_usb.h:1300
int USBH_Init(const USBH_Init_TypeDef *p)
Initialize host protocol stack data structures.
Definition: em_usbh.c:837
#define USB_EPTYPE_CTRL
Definition: em_usb.h:169
int USBH_GetStringB(USBH_Device_TypeDef *device, uint8_t *buf, int bufLen, uint8_t stringIndex, uint16_t langID)
Read a string descriptor from a device.
Definition: em_usbh.c:779
#define USB_HC_CHAR_CHENA
Definition: ezr32wg_usb.h:1348
USB_ConfigurationDescriptor_TypeDef confDesc
Definition: em_usb.h:892
unsigned short char16_t
Definition: em_usb.h:238
#define _USB_HC_CHAR_DEVADDR_SHIFT
Definition: ezr32wg_usb.h:1334
#define CONFIG_DESC_BM_TRANSFERTYPE
Definition: em_usb.h:186
USB protocol stack library API for EFM32/EZR32.
USBH_Ep_TypeDef ep0
Definition: em_usb.h:894
USB Endpoint Descriptor.
Definition: em_usb.h:498
int USBH_PortReset(void)
Drive reset signalling on the USB port.
Definition: em_usbh.c:982
#define USB_SETUP_RECIPIENT_DEVICE
Definition: em_usb.h:73
uint8_t addr
Definition: em_usb.h:875
int USBH_Read(USBH_Ep_TypeDef *ep, void *data, int byteCount, int timeout, USB_XferCompleteCb_TypeDef callback)
Read data from device endpoint, non-blocking version.
Definition: em_usbh.c:1672
#define USB_SETUP_RECIPIENT_INTERFACE
Definition: em_usb.h:74
#define USB_DEVICE_DESCSIZE
Definition: em_usb.h:144
#define CLEAR_FEATURE
Definition: em_usb.h:80
#define USB_HC_CHAR_EPDIR
Definition: ezr32wg_usb.h:1304
USB_InterfaceDescriptor_TypeDef itfDesc
Definition: em_usb.h:893
#define USB_HC_INT_STALL
Definition: ezr32wg_usb.h:1372
#define USB_SETUP_TYPE_STANDARD_MASK
Definition: em_usb.h:68
#define _USB_HC_TSIZ_XFERSIZE_MASK
Definition: ezr32wg_usb.h:1466
uint32_t remaining
Definition: em_usb.h:881
int USBH_WaitForDeviceConnectionB(uint8_t *buf, int timeoutInSeconds)
Wait for device connection.
Definition: em_usbh.c:2146
#define CMU_CMD_USBCCLKSEL_HFCLKNODIV
Definition: ezr32wg_cmu.h:493
uint16_t wLength
Definition: em_usb.h:394
#define USB_INTERFACE_DESCRIPTOR
Definition: em_usb.h:120
#define USB_GINTSTS_HCHINT
Definition: ezr32wg_usb.h:720
#define USB_HC_CHAR_LSPDDEV
Definition: ezr32wg_usb.h:1313
#define SET_FEATURE
Definition: em_usb.h:81
#define _USB_HC_TSIZ_PKTCNT_MASK
Definition: ezr32wg_usb.h:1470
uint32_t rxFifoSize
Definition: em_usb.h:907
#define USB_ENDPOINT_DESCSIZE
Definition: em_usb.h:147
#define USB_EPTYPE_INTR
Definition: em_usb.h:172
int USBH_PrintDeviceDescriptor(const USB_DeviceDescriptor_TypeDef *device)
Pretty print a device descriptor on the debug serial port.
Definition: em_usbh.c:1142
uint8_t type
Definition: em_usb.h:868
USB_EndpointDescriptor_TypeDef * USBH_QGetEndpointDescriptor(const uint8_t *buf, int configIndex, int interfaceIndex, int endpointIndex)
Return a pointer to an endpoint descriptor.
Definition: em_usbh.c:1434
USB_DeviceDescriptor_TypeDef devDesc
Definition: em_usb.h:891
uint8_t USBH_GetPortSpeed(void)
Get the bus speed of the device attached to the USB port.
Definition: em_usbh.c:741
USB_Setup_TypeDef setup
Definition: em_usb.h:864
int USBH_PrintEndpointDescriptor(const USB_EndpointDescriptor_TypeDef *endpoint)
Pretty print an endpoint descriptor on the debug serial port.
Definition: em_usbh.c:1184
#define USB_MAX_DEVICE_ADDRESS
Definition: em_usb.h:181
#define GET_DESCRIPTOR
Definition: em_usb.h:83
#define _USB_HPRT_PRTSPD_SHIFT
Definition: ezr32wg_usb.h:1282
#define USB_FEATURE_ENDPOINT_HALT
Definition: em_usb.h:191
USB_ConfigurationDescriptor_TypeDef * USBH_QGetConfigurationDescriptor(const uint8_t *buf, int configIndex)
Return a pointer to a configuration descriptor.
Definition: em_usbh.c:1331
USB protocol stack library, low level USB peripheral access.
int USBH_SetConfigurationB(USBH_Device_TypeDef *device, uint8_t configValue)
Activate a device configuration.
Definition: em_usbh.c:1956
uint32_t nptxFifoSize
Definition: em_usb.h:908
void USBTIMER_Init(void)
Activate the hardware timer used to pace the 1 millisecond timer system.
Definition: em_usbtimer.c:190
USB Configuration Descriptor.
Definition: em_usb.h:428
#define USB_CONFIG_DESCRIPTOR
Definition: em_usb.h:117
USB_EndpointDescriptor_TypeDef epDesc
Definition: em_usb.h:866
USB_XferCompleteCb_TypeDef xferCompleteCb
Definition: em_usb.h:879
int USBH_ControlMsg(USBH_Ep_TypeDef *ep, uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex, uint16_t wLength, void *data, int timeout, USB_XferCompleteCb_TypeDef callback)
Send a SETUP command to a device, non-blocking version.
Definition: em_usbh.c:246
__STATIC_INLINE uint32_t INT_Disable(void)
Disable interrupts.
Definition: em_int.h:71
#define USB_SETUP_PKT_SIZE
Definition: em_usb.h:178
USB HOST endpoint status data.
Definition: em_usb.h:862
int USBH_QueryDeviceB(uint8_t *buf, size_t bufsize, uint8_t deviceSpeed)
Will request both the device descriptor and the entire configuration descriptor from the device at US...
Definition: em_usbh.c:1582
uint8_t toggle
Definition: em_usb.h:873
USB protocol stack library, internal type definitions.
int USBH_PrintInterfaceDescriptor(const USB_InterfaceDescriptor_TypeDef *interface)
Pretty print an interface descriptor on the debug serial port.
Definition: em_usbh.c:1219
int USBH_PortResume(void)
Drive resume signalling on the USB port.
Definition: em_usbh.c:1012
#define USB_HC_CHAR_CHDIS
Definition: ezr32wg_usb.h:1343
#define _USB_HC_TSIZ_PID_SHIFT
Definition: ezr32wg_usb.h:1473
#define CMU
USB Device Descriptor.
Definition: em_usb.h:404
int USBH_InitDeviceData(USBH_Device_TypeDef *device, const uint8_t *buf, USBH_Ep_TypeDef *ep, int numEp, uint8_t deviceSpeed)
Populate device and endpoint data structures with data retrieved during device enumeration.
Definition: em_usbh.c:905
int USB_PUTCHAR(char c)
Transmit a single char on the debug serial port.
void USBTIMER_Start(uint32_t id, uint32_t timeout, USBTIMER_Callback_TypeDef callback)
Start a timer.
Definition: em_usbtimer.c:234
__STATIC_INLINE unsigned int GPIO_PinInGet(GPIO_Port_TypeDef port, unsigned int pin)
Read the pad value for a single pin in a GPIO port.
Definition: em_gpio.h:675
void USBH_Stop(void)
Stop USB host operation.
Definition: em_usbh.c:2036
#define USB_ENDPOINT_DESCRIPTOR
Definition: em_usb.h:121
uint8_t bRequest
Definition: em_usb.h:391
USB String Descriptor.
Definition: em_usb.h:512
int USBH_Write(USBH_Ep_TypeDef *ep, void *data, int byteCount, int timeout, USB_XferCompleteCb_TypeDef callback)
Write data to device endpoint, non-blocking version.
Definition: em_usbh.c:2297
uint8_t hcOut
Definition: em_usb.h:870
uint8_t * buf
Definition: em_usb.h:876
int USBH_AssignHostChannel(USBH_Ep_TypeDef *ep, uint8_t hcnum)
Assign a host channel to a given endpoint.
Definition: em_usbh.c:160
USBH_EpState_TypeDef state
Definition: em_usb.h:874
#define _USB_HC_TSIZ_XFERSIZE_SHIFT
Definition: ezr32wg_usb.h:1465