17 #if defined( USB_PRESENT ) && ( USB_COUNT == 1 )
19 #if defined( USB_HOST )
25 #if ( USB_VBUSOVRCUR_PORT != USB_VBUSOVRCUR_PORT_NONE )
31 #define HANDLE_INT( x ) if ( status & x ) { Handle_##x(); status &= ~x; }
33 #define FIFO_TXSTS_HCNUM_MASK 0x78000000
34 #define FIFO_TXSTS_HCNUM_SHIFT 27
36 static void Handle_HcInInt( uint8_t hcnum );
37 static void Handle_HcOutInt( uint8_t hcnum );
38 static void Handle_USB_GINTSTS_DISCONNINT (
void );
39 static void Handle_USB_GINTSTS_HCHINT (
void );
40 static void Handle_USB_GINTSTS_PRTINT (
void );
45 void USB_IRQHandler(
void )
52 status = USBHAL_GetCoreInts();
56 DEBUG_USB_INT_LO_PUTS(
"\nSinT" );
60 HANDLE_INT( USB_GINTSTS_HCHINT )
61 HANDLE_INT( USB_GINTSTS_PRTINT )
62 HANDLE_INT( USB_GINTSTS_DISCONNINT )
68 DEBUG_USB_INT_LO_PUTS(
"\nUinT" );
75 static void Handle_HcInInt( uint8_t hcnum )
79 uint32_t status, hcchar, eptype;
80 #ifdef DEBUG_USB_INT_HI
85 status = USBHHAL_GetHcInts( hcnum );
86 hcchar =
USB->HC[ hcnum ].CHAR;
87 eptype = hcchar & _USB_HC_CHAR_EPTYPE_MASK;
89 DEBUG_USB_INT_HI_PUTCHAR(
'i' );
91 if ( status & USB_HC_INT_CHHLTD )
93 USB->HC[ hcnum ].INT = 0xFFFFFFFF;
95 #ifdef DEBUG_USB_INT_HI
98 status &= USB_HC_INT_XFERCOMPL | USB_HC_INT_STALL | USB_HC_INT_XACTERR |
99 USB_HC_INT_ACK | USB_HC_INT_NAK | USB_HC_INT_DATATGLERR |
102 if ( ( status & ( USB_HC_INT_ACK | USB_HC_INT_XFERCOMPL ) ) ==
103 ( USB_HC_INT_ACK | USB_HC_INT_XFERCOMPL ) )
105 DEBUG_USB_INT_HI_PUTCHAR(
'c' );
107 hc->xferred = hc->hwXferSize -
108 ( (
USB->HC[ hcnum ].TSIZ & _USB_HC_TSIZ_XFERSIZE_MASK ) >>
109 _USB_HC_TSIZ_XFERSIZE_SHIFT );
111 hc->remaining -= hc->xferred;
112 hc->ep->toggle = (
USB->HC[ hcnum ].TSIZ & _USB_HC_TSIZ_PID_MASK ) ==
113 USB_HC_TSIZ_PID_DATA0 ? USB_PID_DATA0 : USB_PID_DATA1;
118 else if ( status & USB_HC_INT_STALL )
121 DEBUG_USB_INT_LO_PUTS(
"StaL" );
124 else if ( status & USB_HC_INT_BBLERR )
127 DEBUG_USB_INT_LO_PUTS(
"BabL" );
130 else if ( ( ( status &
131 ( USB_HC_INT_DATATGLERR | USB_HC_INT_NAK ) )
132 == USB_HC_INT_DATATGLERR ) &&
133 ( !( hc->status & HCS_TIMEOUT ) ) )
137 DEBUG_USB_INT_LO_PUTS(
"TglE" );
140 if ( hc->errorCnt < 3 )
142 USBHHAL_HCStart( hcnum );
147 else if ( ( ( status &
148 ( USB_HC_INT_DATATGLERR | USB_HC_INT_NAK |
149 USB_HC_INT_XACTERR ) )
150 == USB_HC_INT_XACTERR ) &&
151 ( !( hc->status & HCS_TIMEOUT ) ) )
155 DEBUG_USB_INT_LO_PUTS(
"XacT" );
158 if ( hc->errorCnt < 3 )
160 USBHHAL_HCStart( hcnum );
165 else if ( hc->status & HCS_TIMEOUT )
167 DEBUG_USB_INT_HI_PUTCHAR(
't' );
173 #ifdef DEBUG_USB_INT_HI
174 if ( !( ( eptype == HCCHAR_EPTYPE_INTR ) &&
175 ( ( status & USB_HC_INT_NAK ) == USB_HC_INT_NAK ) ) )
183 if ( eptype == HCCHAR_EPTYPE_CTRL )
184 USBHEP_CtrlEpHandler( hc->ep, result );
186 USBHEP_EpHandler( hc->ep, result );
193 static void Handle_HcOutInt( uint8_t hcnum )
197 uint32_t status, hcchar, eptype;
198 #ifdef DEBUG_USB_INT_HI
203 status = USBHHAL_GetHcInts( hcnum );
204 hcchar =
USB->HC[ hcnum ].CHAR;
205 eptype = hcchar & _USB_HC_CHAR_EPTYPE_MASK;
207 DEBUG_USB_INT_HI_PUTCHAR(
'o' );
209 if ( status & USB_HC_INT_CHHLTD )
211 USB->HC[ hcnum ].INT = 0xFFFFFFFF;
213 #ifdef DEBUG_USB_INT_HI
216 status &= USB_HC_INT_XFERCOMPL | USB_HC_INT_STALL | USB_HC_INT_XACTERR |
217 USB_HC_INT_ACK | USB_HC_INT_NAK;
219 if ( ( status & ( USB_HC_INT_ACK | USB_HC_INT_XFERCOMPL ) ) ==
220 ( USB_HC_INT_ACK | USB_HC_INT_XFERCOMPL ) )
222 DEBUG_USB_INT_HI_PUTCHAR(
'c' );
224 hc->xferred = hc->remaining;
226 hc->ep->toggle = (
USB->HC[ hcnum ].TSIZ & _USB_HC_TSIZ_PID_MASK ) ==
227 USB_HC_TSIZ_PID_DATA0 ? USB_PID_DATA0 : USB_PID_DATA1;
232 else if ( status & USB_HC_INT_STALL )
235 DEBUG_USB_INT_LO_PUTS(
"StaL" );
238 else if ( status & USB_HC_INT_XACTERR )
240 DEBUG_USB_INT_LO_PUTS(
"XacT" );
241 if ( status & ( USB_HC_INT_ACK | USB_HC_INT_NAK ) )
244 USBHHAL_HCStart( hcnum );
250 if ( hc->errorCnt < 3 )
252 USBHHAL_HCStart( hcnum );
259 else if ( hc->status & HCS_TIMEOUT )
261 DEBUG_USB_INT_HI_PUTCHAR(
't' );
267 #ifdef DEBUG_USB_INT_HI
268 if ( !( ( eptype == HCCHAR_EPTYPE_INTR ) &&
269 ( ( status & USB_HC_INT_NAK ) == USB_HC_INT_NAK ) ) )
277 if ( eptype == HCCHAR_EPTYPE_CTRL )
278 USBHEP_CtrlEpHandler( hc->ep, result );
280 USBHEP_EpHandler( hc->ep, result );
287 static void Handle_USB_GINTSTS_DISCONNINT(
void )
292 USB->GINTSTS = USB_GINTSTS_DISCONNINT;
295 USBH_portStatus = H_PORT_DISCONNECTED;
297 USBHHAL_PortReset(
false );
299 for ( i=0; i< NUM_HC_USED + 2; i++ )
301 hcchar =
USB->HC[ i ].CHAR;
302 USBHHAL_HCHalt( i, hcchar );
303 USB->HC[ i ].INT = 0xFFFFFFFF;
305 if ( !hcs[ i ].idle )
311 DEBUG_USB_INT_LO_PUTS(
"\nDisC" );
317 static void Handle_USB_GINTSTS_HCHINT(
void )
320 uint32_t hcints, hcmask;
322 hcints = USBHHAL_GetHostChannelInts();
324 for ( hcnum = 0, hcmask = 1;
325 hcnum < NUM_HC_USED + 2;
326 hcnum++, hcmask <<= 1 )
328 if ( hcints & hcmask )
330 if (
USB->HC[ hcnum ].CHAR & USB_HC_CHAR_EPDIR )
332 Handle_HcInInt( hcnum );
336 Handle_HcOutInt( hcnum );
346 static void PortResetComplete(
void )
348 if (
USB->HPRT & USB_HPRT_PRTCONNSTS )
350 DEBUG_USB_INT_LO_PUTCHAR(
'5' );
354 USBH_portStatus = H_PORT_DISCONNECTED;
356 USBHHAL_PortReset(
false );
363 static void PortDebounceComplete(
void )
369 if ( hprt & USB_HPRT_PRTCONNSTS )
371 if ( ( hprt & _USB_HPRT_PRTSPD_MASK ) == HPRT_L_SPEED )
373 DEBUG_USB_INT_LO_PUTCHAR(
'3' );
376 USB->HCFG = (
USB->HCFG & ~_USB_HCFG_FSLSPCLKSEL_MASK ) |
377 ( 2 << _USB_HCFG_FSLSPCLKSEL_SHIFT );
379 else if ( ( hprt & _USB_HPRT_PRTSPD_MASK ) == HPRT_F_SPEED )
381 DEBUG_USB_INT_LO_PUTCHAR(
'4' );
384 USB->HCFG = (
USB->HCFG & ~_USB_HCFG_FSLSPCLKSEL_MASK ) |
385 ( 1 << _USB_HCFG_FSLSPCLKSEL_SHIFT );
388 USBH_portStatus = H_PORT_CONNECTED_RESETTING;
390 USBH_attachTiming[ USBH_attachRetryCount ].resetTime,
392 USBHHAL_PortReset(
true );
396 USBH_portStatus = H_PORT_DISCONNECTED;
403 static void Handle_USB_GINTSTS_PRTINT(
void )
409 DEBUG_USB_INT_LO_PUTCHAR(
'^' );
411 switch ( USBH_portStatus )
413 case H_PORT_DISCONNECTED:
415 if ( ( hprt & USB_HPRT_PRTCONNDET ) &&
416 ( hprt & USB_HPRT_PRTCONNSTS ) )
418 DEBUG_USB_INT_LO_PUTCHAR(
'2' );
419 USBH_portStatus = H_PORT_CONNECTED_DEBOUNCING;
421 USBH_attachTiming[ USBH_attachRetryCount ].debounceTime,
422 PortDebounceComplete );
426 case H_PORT_CONNECTED_DEBOUNCING:
428 DEBUG_USB_INT_LO_PUTCHAR(
'Y' );
431 case H_PORT_CONNECTED_RESETTING:
433 if ( ( hprt & USB_HPRT_PRTENCHNG ) &&
434 ( hprt & USB_HPRT_PRTENA ) &&
435 ( hprt & USB_HPRT_PRTCONNSTS ) )
437 DEBUG_USB_INT_LO_PUTCHAR(
'6' );
438 USBH_portStatus = H_PORT_CONNECTED;
442 case H_PORT_CONNECTED:
444 if ( ( hprt & USB_HPRT_PRTENCHNG ) &&
445 ( !( hprt & USB_HPRT_PRTENA ) ) )
447 DEBUG_USB_INT_LO_PUTCHAR(
'X' );
448 #if ( USB_VBUSOVRCUR_PORT != USB_VBUSOVRCUR_PORT_NONE )
449 if (
GPIO_PinInGet( USB_VBUSOVRCUR_PORT, USB_VBUSOVRCUR_PIN ) ==
450 USB_VBUSOVRCUR_POLARITY )
452 DEBUG_USB_INT_LO_PUTCHAR(
'~' );
453 USBHHAL_PortReset(
false );
454 USBHHAL_VbusOn(
false );
456 USBH_portStatus = H_PORT_OVERCURRENT;
462 case H_PORT_OVERCURRENT:
467 if ( hprt & USB_HPRT_PRTOVRCURRCHNG )
469 DEBUG_USB_INT_LO_PUTCHAR(
'9' );
472 hprt &= ~HPRT_WC_MASK;
473 hprt |= USB_HPRT_PRTCONNDET | USB_HPRT_PRTENCHNG | USB_HPRT_PRTOVRCURRCHNG;
#define CORE_DECLARE_IRQ_STATE
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.
CMSIS Cortex-M Peripheral Access Layer for Silicon Laboratories microcontroller devices.
USB_Status_TypeDef
USB transfer status enumerator.
#define CORE_ENTER_ATOMIC()
General Purpose IO (GPIO) peripheral API.
USB protocol stack library API for EFM32/EZR32.
Core interrupt handling API.
#define CORE_EXIT_ATOMIC()
USB protocol stack library, low level USB peripheral access.
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.