/** * @brief This function handles HCD interrupt request. * @param hhcd: HCD handle * @retval none */ void HAL_HCD_IRQHandler(HCD_HandleTypeDef *hhcd) { USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; uint32_t i = 0 , interrupt = 0; /* ensure that we are in device mode */ if (USB_GetMode(hhcd->Instance) == USB_OTG_MODE_HOST) { /* avoid spurious interrupt */ if(__HAL_HCD_IS_INVALID_INTERRUPT(hhcd)) { return; } if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT)) { /* incorrect mode, acknowledge the interrupt */ __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PXFR_INCOMPISOOUT); } if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR)) { /* incorrect mode, acknowledge the interrupt */ __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_IISOIXFR); } if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE)) { /* incorrect mode, acknowledge the interrupt */ __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_PTXFE); } if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_MMIS)) { /* incorrect mode, acknowledge the interrupt */ __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_MMIS); } /* Handle Host Disconnect Interrupts */ if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT)) { /* Cleanup HPRT */ USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\ USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG ); /* Handle Host Port Interrupts */ HAL_HCD_Disconnect_Callback(hhcd); USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ ); __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_DISCINT); } /* Handle Host Port Interrupts */ if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HPRTINT)) { HCD_Port_IRQHandler (hhcd); } /* Handle Host SOF Interrupts */ if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_SOF)) { HAL_HCD_SOF_Callback(hhcd); __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_SOF); } /* Handle Host channel Interrupts */ if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_HCINT)) { interrupt = USB_HC_ReadInterrupt(hhcd->Instance); for (i = 0; i < hhcd->Init.Host_channels ; i++) { if (interrupt & (1 << i)) { if ((USBx_HC(i)->HCCHAR) & USB_OTG_HCCHAR_EPDIR) { HCD_HC_IN_IRQHandler (hhcd, i); } else { HCD_HC_OUT_IRQHandler (hhcd, i); } } } __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT); } /* Handle Rx Queue Level Interrupts */ if(__HAL_HCD_GET_FLAG(hhcd, USB_OTG_GINTSTS_RXFLVL)) { USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL); HCD_RXQLVL_IRQHandler (hhcd); USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_RXFLVL); } } }
/** * @brief This function handles Host Port interrupt requests. * @param hhcd: HCD handle * @retval None */ static void HCD_Port_IRQHandler (HCD_HandleTypeDef *hhcd) { USB_OTG_GlobalTypeDef *USBx = hhcd->Instance; __IO uint32_t hprt0, hprt0_dup; /* Handle Host Port Interrupts */ hprt0 = USBx_HPRT0; hprt0_dup = USBx_HPRT0; hprt0_dup &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\ USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG ); /* Check whether Port Connect Detected */ if((hprt0 & USB_OTG_HPRT_PCDET) == USB_OTG_HPRT_PCDET) { if (DebugConfig.print_hcd_event) { USBH_PutMessage("CONNECT"); } if((hprt0 & USB_OTG_HPRT_PCSTS) == USB_OTG_HPRT_PCSTS) { USB_MASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT); /* connect callback is used for port up only, now */ // HAL_HCD_Connect_Callback(hhcd); } hprt0_dup |= USB_OTG_HPRT_PCDET; } /* Check whether Port Enable Changed */ if((hprt0 & USB_OTG_HPRT_PENCHNG) == USB_OTG_HPRT_PENCHNG) { hprt0_dup |= USB_OTG_HPRT_PENCHNG; if((hprt0 & USB_OTG_HPRT_PENA) == USB_OTG_HPRT_PENA) { if (DebugConfig.print_hcd_event) { USBH_PutMessage("PORTUP"); } if(hhcd->Init.phy_itface == USB_OTG_EMBEDDED_PHY) { if ((hprt0 & USB_OTG_HPRT_PSPD) == (HPRT0_PRTSPD_LOW_SPEED << 17)) { USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_6_MHZ ); } else { USB_InitFSLSPClkSel(hhcd->Instance ,HCFG_48_MHZ ); } } else { if(hhcd->Init.speed == HCD_SPEED_FULL) { USBx_HOST->HFIR = (uint32_t)60000; } } HAL_HCD_Connect_Callback(hhcd); if(hhcd->Init.speed == HCD_SPEED_HIGH) { USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT); } } else { if (DebugConfig.print_hcd_event) { USBH_PutMessage("PORTDOWN"); } /* Cleanup HPRT */ USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\ USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG ); USB_UNMASK_INTERRUPT(hhcd->Instance, USB_OTG_GINTSTS_DISCINT); // This is EXTREMELY important to clean up hardware here // Other ways won't do if DMA is enabled, you got very unstable // enumeration during disconnect and reconnect if (DebugConfig.do_nothing_after_port_down) { } else if (DebugConfig.do_only_disable_global_int_after_port_down) { __HAL_HCD_DISABLE(hhcd); } else { HAL_HCD_Stop(hhcd); } HAL_HCD_Disconnect_Callback(hhcd); } } /* Check for an overcurrent */ if((hprt0 & USB_OTG_HPRT_POCCHNG) == USB_OTG_HPRT_POCCHNG) { hprt0_dup |= USB_OTG_HPRT_POCCHNG; } /* Clear Port Interrupts */ USBx_HPRT0 = hprt0_dup; }