17 #if defined( USB_PRESENT ) && ( USB_COUNT == 1 )
19 #if defined( USB_HOST )
24 #if ( USB_VBUSOVRCUR_PORT != USB_VBUSOVRCUR_PORT_NONE )
30 #define HANDLE_INT( x ) if ( status & x ) { Handle_##x(); status &= ~x; }
32 #define FIFO_TXSTS_HCNUM_MASK 0x78000000
33 #define FIFO_TXSTS_HCNUM_SHIFT 27
35 static void Handle_HcInInt( uint8_t hcnum );
36 static void Handle_HcOutInt( uint8_t hcnum );
37 static void Handle_USB_GINTSTS_DISCONNINT (
void );
38 static void Handle_USB_GINTSTS_HCHINT (
void );
39 static void Handle_USB_GINTSTS_PRTINT (
void );
44 void USB_IRQHandler(
void )
50 status = USBHAL_GetCoreInts();
54 DEBUG_USB_INT_LO_PUTS(
"\nSinT" );
58 HANDLE_INT( USB_GINTSTS_HCHINT )
59 HANDLE_INT( USB_GINTSTS_PRTINT )
60 HANDLE_INT( USB_GINTSTS_DISCONNINT )
66 DEBUG_USB_INT_LO_PUTS(
"\nUinT" );
73 static void Handle_HcInInt( uint8_t hcnum )
77 uint32_t status, hcchar, eptype;
78 #ifdef DEBUG_USB_INT_HI
83 status = USBHHAL_GetHcInts( hcnum );
84 hcchar =
USB->HC[ hcnum ].CHAR;
85 eptype = hcchar & _USB_HC_CHAR_EPTYPE_MASK;
87 DEBUG_USB_INT_HI_PUTCHAR(
'i' );
89 if ( status & USB_HC_INT_CHHLTD )
91 USB->HC[ hcnum ].INT = 0xFFFFFFFF;
93 #ifdef DEBUG_USB_INT_HI
96 status &= USB_HC_INT_XFERCOMPL | USB_HC_INT_STALL | USB_HC_INT_XACTERR |
97 USB_HC_INT_ACK | USB_HC_INT_NAK | USB_HC_INT_DATATGLERR |
100 if ( ( status & ( USB_HC_INT_ACK | USB_HC_INT_XFERCOMPL ) ) ==
101 ( USB_HC_INT_ACK | USB_HC_INT_XFERCOMPL ) )
103 DEBUG_USB_INT_HI_PUTCHAR(
'c' );
105 hc->xferred = hc->hwXferSize -
106 ( (
USB->HC[ hcnum ].TSIZ & _USB_HC_TSIZ_XFERSIZE_MASK ) >>
107 _USB_HC_TSIZ_XFERSIZE_SHIFT );
109 hc->remaining -= hc->xferred;
110 hc->ep->toggle = (
USB->HC[ hcnum ].TSIZ & _USB_HC_TSIZ_PID_MASK ) ==
111 USB_HC_TSIZ_PID_DATA0 ? USB_PID_DATA0 : USB_PID_DATA1;
116 else if ( status & USB_HC_INT_STALL )
119 DEBUG_USB_INT_LO_PUTS(
"StaL" );
122 else if ( status & USB_HC_INT_BBLERR )
125 DEBUG_USB_INT_LO_PUTS(
"BabL" );
128 else if ( ( ( status &
129 ( USB_HC_INT_DATATGLERR | USB_HC_INT_NAK ) )
130 == USB_HC_INT_DATATGLERR ) &&
131 ( !( hc->status & HCS_TIMEOUT ) ) )
135 DEBUG_USB_INT_LO_PUTS(
"TglE" );
138 if ( hc->errorCnt < 3 )
140 USBHHAL_HCStart( hcnum );
145 else if ( ( ( status &
146 ( USB_HC_INT_DATATGLERR | USB_HC_INT_NAK |
147 USB_HC_INT_XACTERR ) )
148 == USB_HC_INT_XACTERR ) &&
149 ( !( hc->status & HCS_TIMEOUT ) ) )
153 DEBUG_USB_INT_LO_PUTS(
"XacT" );
156 if ( hc->errorCnt < 3 )
158 USBHHAL_HCStart( hcnum );
163 else if ( hc->status & HCS_TIMEOUT )
165 DEBUG_USB_INT_HI_PUTCHAR(
't' );
171 #ifdef DEBUG_USB_INT_HI
172 if ( !( ( eptype == HCCHAR_EPTYPE_INTR ) &&
173 ( ( status & USB_HC_INT_NAK ) == USB_HC_INT_NAK ) ) )
181 if ( eptype == HCCHAR_EPTYPE_CTRL )
182 USBHEP_CtrlEpHandler( hc->ep, result );
184 USBHEP_EpHandler( hc->ep, result );
191 static void Handle_HcOutInt( uint8_t hcnum )
195 uint32_t status, hcchar, eptype;
196 #ifdef DEBUG_USB_INT_HI
201 status = USBHHAL_GetHcInts( hcnum );
202 hcchar =
USB->HC[ hcnum ].CHAR;
203 eptype = hcchar & _USB_HC_CHAR_EPTYPE_MASK;
205 DEBUG_USB_INT_HI_PUTCHAR(
'o' );
207 if ( status & USB_HC_INT_CHHLTD )
209 USB->HC[ hcnum ].INT = 0xFFFFFFFF;
211 #ifdef DEBUG_USB_INT_HI
214 status &= USB_HC_INT_XFERCOMPL | USB_HC_INT_STALL | USB_HC_INT_XACTERR |
215 USB_HC_INT_ACK | USB_HC_INT_NAK;
217 if ( ( status & ( USB_HC_INT_ACK | USB_HC_INT_XFERCOMPL ) ) ==
218 ( USB_HC_INT_ACK | USB_HC_INT_XFERCOMPL ) )
220 DEBUG_USB_INT_HI_PUTCHAR(
'c' );
222 hc->xferred = hc->remaining;
224 hc->ep->toggle = (
USB->HC[ hcnum ].TSIZ & _USB_HC_TSIZ_PID_MASK ) ==
225 USB_HC_TSIZ_PID_DATA0 ? USB_PID_DATA0 : USB_PID_DATA1;
230 else if ( status & USB_HC_INT_STALL )
233 DEBUG_USB_INT_LO_PUTS(
"StaL" );
236 else if ( status & USB_HC_INT_XACTERR )
238 DEBUG_USB_INT_LO_PUTS(
"XacT" );
239 if ( status & ( USB_HC_INT_ACK | USB_HC_INT_NAK ) )
242 USBHHAL_HCStart( hcnum );
248 if ( hc->errorCnt < 3 )
250 USBHHAL_HCStart( hcnum );
257 else if ( hc->status & HCS_TIMEOUT )
259 DEBUG_USB_INT_HI_PUTCHAR(
't' );
265 #ifdef DEBUG_USB_INT_HI
266 if ( !( ( eptype == HCCHAR_EPTYPE_INTR ) &&
267 ( ( status & USB_HC_INT_NAK ) == USB_HC_INT_NAK ) ) )
275 if ( eptype == HCCHAR_EPTYPE_CTRL )
276 USBHEP_CtrlEpHandler( hc->ep, result );
278 USBHEP_EpHandler( hc->ep, result );
285 static void Handle_USB_GINTSTS_DISCONNINT(
void )
290 USB->GINTSTS = USB_GINTSTS_DISCONNINT;
293 USBH_portStatus = H_PORT_DISCONNECTED;
295 USBHHAL_PortReset(
false );
297 for ( i=0; i< NUM_HC_USED + 2; i++ )
299 hcchar =
USB->HC[ i ].CHAR;
300 USBHHAL_HCHalt( i, hcchar );
301 USB->HC[ i ].INT = 0xFFFFFFFF;
303 if ( !hcs[ i ].idle )
309 DEBUG_USB_INT_LO_PUTS(
"\nDisC" );
315 static void Handle_USB_GINTSTS_HCHINT(
void )
318 uint32_t hcints, hcmask;
320 hcints = USBHHAL_GetHostChannelInts();
322 for ( hcnum = 0, hcmask = 1;
323 hcnum < NUM_HC_USED + 2;
324 hcnum++, hcmask <<= 1 )
326 if ( hcints & hcmask )
328 if (
USB->HC[ hcnum ].CHAR & USB_HC_CHAR_EPDIR )
330 Handle_HcInInt( hcnum );
334 Handle_HcOutInt( hcnum );
344 static void PortResetComplete(
void )
346 if (
USB->HPRT & USB_HPRT_PRTCONNSTS )
348 DEBUG_USB_INT_LO_PUTCHAR(
'5' );
352 USBH_portStatus = H_PORT_DISCONNECTED;
354 USBHHAL_PortReset(
false );
361 static void PortDebounceComplete(
void )
367 if ( hprt & USB_HPRT_PRTCONNSTS )
369 if ( ( hprt & _USB_HPRT_PRTSPD_MASK ) == HPRT_L_SPEED )
371 DEBUG_USB_INT_LO_PUTCHAR(
'3' );
374 USB->HCFG = (
USB->HCFG & ~_USB_HCFG_FSLSPCLKSEL_MASK ) |
375 ( 2 << _USB_HCFG_FSLSPCLKSEL_SHIFT );
377 else if ( ( hprt & _USB_HPRT_PRTSPD_MASK ) == HPRT_F_SPEED )
379 DEBUG_USB_INT_LO_PUTCHAR(
'4' );
382 USB->HCFG = (
USB->HCFG & ~_USB_HCFG_FSLSPCLKSEL_MASK ) |
383 ( 1 << _USB_HCFG_FSLSPCLKSEL_SHIFT );
386 USBH_portStatus = H_PORT_CONNECTED_RESETTING;
388 USBH_attachTiming[ USBH_attachRetryCount ].resetTime,
390 USBHHAL_PortReset(
true );
394 USBH_portStatus = H_PORT_DISCONNECTED;
401 static void Handle_USB_GINTSTS_PRTINT(
void )
407 DEBUG_USB_INT_LO_PUTCHAR(
'^' );
409 switch ( USBH_portStatus )
411 case H_PORT_DISCONNECTED:
413 if ( ( hprt & USB_HPRT_PRTCONNDET ) &&
414 ( hprt & USB_HPRT_PRTCONNSTS ) )
416 DEBUG_USB_INT_LO_PUTCHAR(
'2' );
417 USBH_portStatus = H_PORT_CONNECTED_DEBOUNCING;
419 USBH_attachTiming[ USBH_attachRetryCount ].debounceTime,
420 PortDebounceComplete );
424 case H_PORT_CONNECTED_DEBOUNCING:
426 DEBUG_USB_INT_LO_PUTCHAR(
'Y' );
429 case H_PORT_CONNECTED_RESETTING:
431 if ( ( hprt & USB_HPRT_PRTENCHNG ) &&
432 ( hprt & USB_HPRT_PRTENA ) &&
433 ( hprt & USB_HPRT_PRTCONNSTS ) )
435 DEBUG_USB_INT_LO_PUTCHAR(
'6' );
436 USBH_portStatus = H_PORT_CONNECTED;
440 case H_PORT_CONNECTED:
442 if ( ( hprt & USB_HPRT_PRTENCHNG ) &&
443 ( !( hprt & USB_HPRT_PRTENA ) ) )
445 DEBUG_USB_INT_LO_PUTCHAR(
'X' );
446 #if ( USB_VBUSOVRCUR_PORT != USB_VBUSOVRCUR_PORT_NONE )
447 if (
GPIO_PinInGet( USB_VBUSOVRCUR_PORT, USB_VBUSOVRCUR_PIN ) ==
448 USB_VBUSOVRCUR_POLARITY )
450 DEBUG_USB_INT_LO_PUTCHAR(
'~' );
451 USBHHAL_PortReset(
false );
452 USBHHAL_VbusOn(
false );
454 USBH_portStatus = H_PORT_OVERCURRENT;
460 case H_PORT_OVERCURRENT:
465 if ( hprt & USB_HPRT_PRTOVRCURRCHNG )
467 DEBUG_USB_INT_LO_PUTCHAR(
'9' );
470 hprt &= ~HPRT_WC_MASK;
471 hprt |= USB_HPRT_PRTCONNDET | USB_HPRT_PRTENCHNG | USB_HPRT_PRTOVRCURRCHNG;
void USBTIMER_Stop(uint32_t id)
Stop a timer.
USB protocol stack library API for EFM32/EZR32.
int USB_PRINTF(const char *format,...)
Transmit "printf" formated data on the debug serial port.
__STATIC_INLINE uint32_t INT_Enable(void)
Enable interrupts.
CMSIS Cortex-M Peripheral Access Layer for Silicon Laboratories microcontroller devices.
USB_Status_TypeDef
USB transfer status enumerator.
General Purpose IO (GPIO) peripheral API.
USB protocol stack library API for EFM32/EZR32.
USB protocol stack library, low level USB peripheral access.
__STATIC_INLINE uint32_t INT_Disable(void)
Disable interrupts.
USB protocol stack library, internal type definitions.
void USBTIMER_Start(uint32_t id, uint32_t timeout, USBTIMER_Callback_TypeDef callback)
Start a timer.
__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.