/** * @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 PCD interrupt request. * @param hpcd: PCD handle * @retval HAL status */ void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd) { uint32_t wInterrupt_Mask = 0U; if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_CTR)) { /* servicing of the endpoint correct transfer interrupt */ /* clear of the CTR flag into the sub */ PCD_EP_ISR_Handler(hpcd); } if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_RESET)) { __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET); HAL_PCD_ResetCallback(hpcd); HAL_PCD_SetAddress(hpcd, 0U); } if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_PMAOVR)) { __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR); } if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ERR)) { __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR); } if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP)) { hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_LPMODE); /*set wInterrupt_Mask global variable*/ wInterrupt_Mask = USB_CNTR_CTRM | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_ERRM \ | USB_CNTR_SOFM | USB_CNTR_ESOFM | USB_CNTR_RESETM; /*Set interrupt mask*/ hpcd->Instance->CNTR = wInterrupt_Mask; /* enable L1REQ interrupt */ if (hpcd->Init.lpm_enable ==1) { wInterrupt_Mask |= USB_CNTR_L1REQM; /* Enable LPM support and enable ACK answer to LPM request*/ USB_TypeDef *USBx = hpcd->Instance; hpcd->lpm_active = ENABLE; hpcd->LPM_State = LPM_L0; USBx->LPMCSR |= (USB_LPMCSR_LMPEN); USBx->LPMCSR |= (USB_LPMCSR_LPMACK); } HAL_PCD_ResumeCallback(hpcd); __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP); } if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SUSP)) { /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP); /* Force low-power mode in the macrocell */ hpcd->Instance->CNTR |= USB_CNTR_FSUSP; hpcd->Instance->CNTR |= USB_CNTR_LPMODE; if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP) == 0U) { HAL_PCD_SuspendCallback(hpcd); } } /* Handle LPM Interrupt */ if(__HAL_PCD_GET_FLAG(hpcd, USB_ISTR_L1REQ)) { __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_L1REQ); if( hpcd->LPM_State == LPM_L0) { /* Force suspend and low-power mode before going to L1 state*/ hpcd->Instance->CNTR |= USB_CNTR_LPMODE; hpcd->Instance->CNTR |= USB_CNTR_FSUSP; hpcd->LPM_State = LPM_L1; hpcd->BESL = (hpcd->Instance->LPMCSR & USB_LPMCSR_BESL) >>2 ; HAL_PCDEx_LPM_Callback(hpcd, PCD_LPM_L1_ACTIVE); } else {
/** * @brief This function handles PCD interrupt request. * @param hpcd: PCD handle * @retval HAL status */ void HAL_PCD_IRQHandler(PCD_HandleTypeDef *hpcd) { uint32_t wInterrupt_Mask = 0; if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_CTR)) { /* servicing of the endpoint correct transfer interrupt */ /* clear of the CTR flag into the sub */ PCD_EP_ISR_Handler(hpcd); } if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_RESET)) { __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_RESET); HAL_PCD_ResetCallback(hpcd); HAL_PCD_SetAddress(hpcd, 0); } if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_PMAOVR)) { __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_PMAOVR); } if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ERR)) { __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ERR); } if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP)) { hpcd->Instance->CNTR &= (uint16_t) ~(USB_CNTR_LPMODE); /*set wInterrupt_Mask global variable*/ wInterrupt_Mask = USB_CNTR_CTRM | USB_CNTR_WKUPM | USB_CNTR_SUSPM | USB_CNTR_ERRM \ | USB_CNTR_ESOFM | USB_CNTR_RESETM; /*Set interrupt mask*/ hpcd->Instance->CNTR = wInterrupt_Mask; HAL_PCD_ResumeCallback(hpcd); __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_WKUP); } if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SUSP)) { /* clear of the ISTR bit must be done after setting of CNTR_FSUSP */ __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SUSP); /* Force low-power mode in the macrocell */ hpcd->Instance->CNTR |= USB_CNTR_FSUSP; hpcd->Instance->CNTR |= USB_CNTR_LPMODE; if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_WKUP) == 0) { HAL_PCD_SuspendCallback(hpcd); } } if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_SOF)) { __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_SOF); HAL_PCD_SOFCallback(hpcd); } if (__HAL_PCD_GET_FLAG (hpcd, USB_ISTR_ESOF)) { /* clear ESOF flag in ISTR */ __HAL_PCD_CLEAR_FLAG(hpcd, USB_ISTR_ESOF); } }
/** * @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); } }