/** * @brief This function handles PCD interrupt request. * @param hpcd: PCD handle * @retval HAL status */ void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd) { USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; uint32_t i = 0, ep_intr = 0, epint = 0, epnum = 0; uint32_t fifoemptymsk = 0, temp = 0; USB_OTG_EPTypeDef *ep; /* ensure that we are in device mode */ if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE) { /* avoid spurious interrupt */ if(__HAL_PCD_IS_INVALID_INTERRUPT(hpcd)) { return; } if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS)) { /* incorrect mode, acknowledge the interrupt */ __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS); } if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT)) { epnum = 0; /* Read in the device interrupt bits */ ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance); while ( ep_intr ) { if (ep_intr & 0x1) { epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, epnum); if(( epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC) { CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC); if(hpcd->Init.dma_enable == 1) { hpcd->OUT_ep[epnum].xfer_count = hpcd->OUT_ep[epnum].maxpacket- (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ); hpcd->OUT_ep[epnum].xfer_buff += hpcd->OUT_ep[epnum].maxpacket; } HAL_PCD_DataOutStageCallback(hpcd, epnum); if(hpcd->Init.dma_enable == 1) { if((epnum == 0) && (hpcd->OUT_ep[epnum].xfer_len == 0)) { /* this is ZLP, so prepare EP0 for next setup */ USB_EP0_OutStart(hpcd->Instance, 1, (uint8_t *)hpcd->Setup); } } } if(( epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) { /* Inform the upper layer that a setup packet is available */ HAL_PCD_SetupStageCallback(hpcd); CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP); } if(( epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS) { CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS); } } epnum++; ep_intr >>= 1; } } if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT)) { /* Read in the device interrupt bits */ ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance); epnum = 0; while ( ep_intr ) { if (ep_intr & 0x1) /* In ITR */ { epint = USB_ReadDevInEPInterrupt(hpcd->Instance, epnum); if(( epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC) { fifoemptymsk = 0x1 << epnum; USBx_DEVICE->DIEPEMPMSK &= ~fifoemptymsk; CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC); if (hpcd->Init.dma_enable == 1) { hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket; } HAL_PCD_DataInStageCallback(hpcd, epnum); if (hpcd->Init.dma_enable == 1) { /* this is ZLP, so prepare EP0 for next setup */ if((epnum == 0) && (hpcd->IN_ep[epnum].xfer_len == 0)) { /* prepare to rx more setup packets */ USB_EP0_OutStart(hpcd->Instance, 1, (uint8_t *)hpcd->Setup); } } } if(( epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC) { CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC); } if(( epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE) { CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE); } if(( epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE) { CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE); } if(( epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD) { CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD); } if(( epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE) { PCD_WriteEmptyTxFifo(hpcd , epnum); } } epnum++; ep_intr >>= 1; } } /* Handle Resume Interrupt */ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT)) { /* Clear the Remote Wake-up Signaling */ USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG; if(hpcd->LPM_State == LPM_L1) { hpcd->LPM_State = LPM_L0; HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE); } else { HAL_PCD_ResumeCallback(hpcd); } __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT); } /* Handle Suspend Interrupt */ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP)) { if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS) { HAL_PCD_SuspendCallback(hpcd); } __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP); } /* Handle LPM Interrupt */ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT)) { __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT); if( hpcd->LPM_State == LPM_L0) { hpcd->LPM_State = LPM_L1; hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >>2 ; HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE); } else { HAL_PCD_SuspendCallback(hpcd); } }
/** * @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)) { if (DebugConfig.print_hcd_event) { USBH_PutMessage("DISCONNECT"); } /* Cleanup HPRT */ USBx_HPRT0 &= ~(USB_OTG_HPRT_PENA | USB_OTG_HPRT_PCDET |\ USB_OTG_HPRT_PENCHNG | USB_OTG_HPRT_POCCHNG ); /* Handle Host Port Interrupts */ /* Do this in port down handler, not disconnect handler */ // 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); /* If port down/global interrupt disabled, channel * process should not be processed further. */ if (!(hhcd->Instance->GAHBCFG & USB_OTG_GAHBCFG_GINT)) return; } /* 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); hc_helper_prepare_reports(hhcd, interrupt); for (i = 0; i < hhcd->Init.Host_channels; i++) { if (interrupt & (1 << i)) { hc_helper_report_channel_in(i); if ((USBx_HC(i)->HCCHAR) & USB_OTG_HCCHAR_EPDIR) { HCD_HC_IN_IRQHandler(hhcd, i); } else { HCD_HC_OUT_IRQHandler (hhcd, i); } hc_helper_report_channel_out(i); } } __HAL_HCD_CLEAR_FLAG(hhcd, USB_OTG_GINTSTS_HCINT); hc_helper_send_reports(); } /* 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 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 Handles PCD interrupt request. * @param hpcd: PCD handle * @retval HAL status */ void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd) { USB_OTG_GlobalTypeDef *USBx = hpcd->Instance; uint32_t index = 0U, ep_intr = 0U, epint = 0U, epnum = 0U; uint32_t fifoemptymsk = 0U, temp = 0U; USB_OTG_EPTypeDef *ep = NULL; uint32_t hclk = 80000000; /* ensure that we are in device mode */ if (USB_GetMode(hpcd->Instance) == USB_OTG_MODE_DEVICE) { /* avoid spurious interrupt */ if(__HAL_PCD_IS_INVALID_INTERRUPT(hpcd)) { return; } if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_MMIS)) { /* incorrect mode, acknowledge the interrupt */ __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_MMIS); } if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_OEPINT)) { epnum = 0; /* Read in the device interrupt bits */ ep_intr = USB_ReadDevAllOutEpInterrupt(hpcd->Instance); while (ep_intr) { if (ep_intr & 0x1) { epint = USB_ReadDevOutEPInterrupt(hpcd->Instance, epnum); if (( epint & USB_OTG_DOEPINT_XFRC) == USB_OTG_DOEPINT_XFRC) { CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_XFRC); /* setup/out transaction management for Core ID 310A */ if (USBx->GSNPSID == USB_OTG_CORE_ID_310A) { if (!(USBx_OUTEP(0)->DOEPINT & (0x1 << 15))) { if (hpcd->Init.dma_enable == 1) { hpcd->OUT_ep[epnum].xfer_count = hpcd->OUT_ep[epnum].maxpacket - (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ); hpcd->OUT_ep[epnum].xfer_buff += hpcd->OUT_ep[epnum].maxpacket; } HAL_PCD_DataOutStageCallback(hpcd, epnum); if (hpcd->Init.dma_enable == 1) { if (!epnum && !hpcd->OUT_ep[epnum].xfer_len) { /* this is ZLP, so prepare EP0 for next setup */ USB_EP0_OutStart(hpcd->Instance, 1, (uint8_t *)hpcd->Setup); } } } /* Clear the SetPktRcvd flag*/ USBx_OUTEP(0)->DOEPINT |= (0x1 << 15) | (0x1 << 5); } else { if (hpcd->Init.dma_enable == 1) { hpcd->OUT_ep[epnum].xfer_count = hpcd->OUT_ep[epnum].maxpacket - (USBx_OUTEP(epnum)->DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ); hpcd->OUT_ep[epnum].xfer_buff += hpcd->OUT_ep[epnum].maxpacket; } HAL_PCD_DataOutStageCallback(hpcd, epnum); if (hpcd->Init.dma_enable == 1) { if (!epnum && !hpcd->OUT_ep[epnum].xfer_len) { /* this is ZLP, so prepare EP0 for next setup */ USB_EP0_OutStart(hpcd->Instance, 1, (uint8_t *)hpcd->Setup); } } } } if(( epint & USB_OTG_DOEPINT_STUP) == USB_OTG_DOEPINT_STUP) { /* Inform the upper layer that a setup packet is available */ HAL_PCD_SetupStageCallback(hpcd); CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_STUP); } if(( epint & USB_OTG_DOEPINT_OTEPDIS) == USB_OTG_DOEPINT_OTEPDIS) { CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPDIS); } #ifdef USB_OTG_DOEPINT_OTEPSPR /* Clear Status Phase Received interrupt */ if(( epint & USB_OTG_DOEPINT_OTEPSPR) == USB_OTG_DOEPINT_OTEPSPR) { CLEAR_OUT_EP_INTR(epnum, USB_OTG_DOEPINT_OTEPSPR); } #endif /* USB_OTG_DOEPINT_OTEPSPR */ } epnum++; ep_intr >>= 1; } } if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_IEPINT)) { /* Read in the device interrupt bits */ ep_intr = USB_ReadDevAllInEpInterrupt(hpcd->Instance); epnum = 0; while ( ep_intr ) { if (ep_intr & 0x1) /* In ITR */ { epint = USB_ReadDevInEPInterrupt(hpcd->Instance, epnum); if(( epint & USB_OTG_DIEPINT_XFRC) == USB_OTG_DIEPINT_XFRC) { fifoemptymsk = 0x1 << epnum; // Added for MBED PR #3062 atomic_clr_u32(&USBx_DEVICE->DIEPEMPMSK, fifoemptymsk); CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_XFRC); if (hpcd->Init.dma_enable == 1) { hpcd->IN_ep[epnum].xfer_buff += hpcd->IN_ep[epnum].maxpacket; } HAL_PCD_DataInStageCallback(hpcd, epnum); if (hpcd->Init.dma_enable == 1) { /* this is ZLP, so prepare EP0 for next setup */ if((epnum == 0) && (hpcd->IN_ep[epnum].xfer_len == 0)) { /* prepare to rx more setup packets */ USB_EP0_OutStart(hpcd->Instance, 1, (uint8_t *)hpcd->Setup); } } } if(( epint & USB_OTG_DIEPINT_TOC) == USB_OTG_DIEPINT_TOC) { CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_TOC); } if(( epint & USB_OTG_DIEPINT_ITTXFE) == USB_OTG_DIEPINT_ITTXFE) { CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_ITTXFE); } if(( epint & USB_OTG_DIEPINT_INEPNE) == USB_OTG_DIEPINT_INEPNE) { CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_INEPNE); } if(( epint & USB_OTG_DIEPINT_EPDISD) == USB_OTG_DIEPINT_EPDISD) { CLEAR_IN_EP_INTR(epnum, USB_OTG_DIEPINT_EPDISD); } if(( epint & USB_OTG_DIEPINT_TXFE) == USB_OTG_DIEPINT_TXFE) { PCD_WriteEmptyTxFifo(hpcd , epnum); } } epnum++; ep_intr >>= 1; } } /* Handle Resume Interrupt */ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT)) { /* Clear the Remote Wake-up Signaling */ USBx_DEVICE->DCTL &= ~USB_OTG_DCTL_RWUSIG; if(hpcd->LPM_State == LPM_L1) { hpcd->LPM_State = LPM_L0; HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L0_ACTIVE); } else { HAL_PCD_ResumeCallback(hpcd); } __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_WKUINT); } /* Handle Suspend Interrupt */ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP)) { if((USBx_DEVICE->DSTS & USB_OTG_DSTS_SUSPSTS) == USB_OTG_DSTS_SUSPSTS) { HAL_PCD_SuspendCallback(hpcd); } __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_USBSUSP); } /* Handle LPM Interrupt */ if(__HAL_PCD_GET_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT)) { __HAL_PCD_CLEAR_FLAG(hpcd, USB_OTG_GINTSTS_LPMINT); if( hpcd->LPM_State == LPM_L0) { hpcd->LPM_State = LPM_L1; hpcd->BESL = (hpcd->Instance->GLPMCFG & USB_OTG_GLPMCFG_BESL) >>2 ; HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE); } else { HAL_PCD_SuspendCallback(hpcd); } }