/** ****************************************************************************** * @file usb_dcd_int.c * @author MCD Application Team * @version V2.1.0 * @date 19-March-2012 * @brief Peripheral Device interrupt subroutines ****************************************************************************** * @attention * *

© COPYRIGHT 2012 STMicroelectronics

* * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License"); * You may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.st.com/software_license_agreement_liberty_v2 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "usb_dcd_int.h" /** @addtogroup USB_OTG_DRIVER * @{ */ /** @defgroup USB_DCD_INT * @brief This file contains the interrupt subroutines for the Device mode. * @{ */ /** @defgroup USB_DCD_INT_Private_Defines * @{ */ /** * @} */ /** @defgroup USB_DCD_INT_Private_TypesDefinitions * @{ */ /** * @} */ /** @defgroup USB_DCD_INT_Private_Macros * @{ */ /** * @} */ /** @defgroup USB_DCD_INT_Private_Variables * @{ */ /** * @} */ /** @defgroup USB_DCD_INT_Private_FunctionPrototypes * @{ */ /* static functions */ static uint32_t DCD_ReadDevInEP (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum); /* Interrupt Handlers */ static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev); static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev); static uint32_t DCD_HandleSof_ISR(USB_OTG_CORE_HANDLE *pdev); static uint32_t DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev); static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev , uint32_t epnum); static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev); static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev); static uint32_t DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE *pdev); static uint32_t DCD_HandleUSBSuspend_ISR(USB_OTG_CORE_HANDLE *pdev); static uint32_t DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev); static uint32_t DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev); #ifdef VBUS_SENSING_ENABLED static uint32_t DCD_SessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev); static uint32_t DCD_OTG_ISR(USB_OTG_CORE_HANDLE *pdev); #endif /** * @} */ /** @defgroup USB_DCD_INT_Private_Functions * @{ */ #ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED /** * @brief USBD_OTG_EP1OUT_ISR_Handler * handles all USB Interrupts * @param pdev: device instance * @retval status */ uint32_t USBD_OTG_EP1OUT_ISR_Handler (USB_OTG_CORE_HANDLE *pdev) { USB_OTG_DOEPINTn_TypeDef doepint; USB_OTG_DEPXFRSIZ_TypeDef deptsiz; doepint.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[1]->DOEPINT); doepint.d32&= USB_OTG_READ_REG32(&pdev->regs.DREGS->DOUTEP1MSK); /* Transfer complete */ if ( doepint.b.xfercompl ) { /* Clear the bit in DOEPINTn for this interrupt */ CLEAR_OUT_EP_INTR(1, xfercompl); if (pdev->cfg.dma_enable == 1) { deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[1]->DOEPTSIZ)); /*ToDo : handle more than one single MPS size packet */ pdev->dev.out_ep[1].xfer_count = pdev->dev.out_ep[1].maxpacket - \ deptsiz.b.xfersize; } /* Inform upper layer: data ready */ /* RX COMPLETE */ USBD_DCD_INT_fops->DataOutStage(pdev , 1); } /* Endpoint disable */ if ( doepint.b.epdisabled ) { /* Clear the bit in DOEPINTn for this interrupt */ CLEAR_OUT_EP_INTR(1, epdisabled); } return 1; } /** * @brief USBD_OTG_EP1IN_ISR_Handler * handles all USB Interrupts * @param pdev: device instance * @retval status */ uint32_t USBD_OTG_EP1IN_ISR_Handler (USB_OTG_CORE_HANDLE *pdev) { USB_OTG_DIEPINTn_TypeDef diepint; uint32_t fifoemptymsk, msk, emp; msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DINEP1MSK); emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK); msk |= ((emp >> 1 ) & 0x1) << 7; diepint.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[1]->DIEPINT) & msk; if ( diepint.b.xfercompl ) { fifoemptymsk = 0x1 << 1; USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0); CLEAR_IN_EP_INTR(1, xfercompl); /* TX COMPLETE */ USBD_DCD_INT_fops->DataInStage(pdev , 1); } if ( diepint.b.epdisabled ) { CLEAR_IN_EP_INTR(1, epdisabled); } if ( diepint.b.timeout ) { CLEAR_IN_EP_INTR(1, timeout); } if (diepint.b.intktxfemp) { CLEAR_IN_EP_INTR(1, intktxfemp); } if (diepint.b.inepnakeff) { CLEAR_IN_EP_INTR(1, inepnakeff); } if (diepint.b.emptyintr) { DCD_WriteEmptyTxFifo(pdev , 1); CLEAR_IN_EP_INTR(1, emptyintr); } return 1; } #endif /** * @brief STM32_USBF_OTG_ISR_Handler * handles all USB Interrupts * @param pdev: device instance * @retval status */ uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev) { USB_OTG_GINTSTS_TypeDef gintr_status; uint32_t retval = 0; if (USB_OTG_IsDeviceMode(pdev)) /* ensure that we are in device mode */ { gintr_status.d32 = USB_OTG_ReadCoreItr(pdev); if (!gintr_status.d32) /* avoid spurious interrupt */ { return 0; } if (gintr_status.b.outepintr) { retval |= DCD_HandleOutEP_ISR(pdev); } if (gintr_status.b.inepint) { retval |= DCD_HandleInEP_ISR(pdev); } if (gintr_status.b.modemismatch) { USB_OTG_GINTSTS_TypeDef gintsts; /* Clear interrupt */ gintsts.d32 = 0; gintsts.b.modemismatch = 1; USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); } if (gintr_status.b.wkupintr) { retval |= DCD_HandleResume_ISR(pdev); } if (gintr_status.b.usbsuspend) { retval |= DCD_HandleUSBSuspend_ISR(pdev); } if (gintr_status.b.sofintr) { retval |= DCD_HandleSof_ISR(pdev); } if (gintr_status.b.rxstsqlvl) { retval |= DCD_HandleRxStatusQueueLevel_ISR(pdev); } if (gintr_status.b.usbreset) { retval |= DCD_HandleUsbReset_ISR(pdev); } if (gintr_status.b.enumdone) { retval |= DCD_HandleEnumDone_ISR(pdev); } if (gintr_status.b.incomplisoin) { retval |= DCD_IsoINIncomplete_ISR(pdev); } if (gintr_status.b.incomplisoout) { retval |= DCD_IsoOUTIncomplete_ISR(pdev); } #ifdef VBUS_SENSING_ENABLED if (gintr_status.b.sessreqintr) { retval |= DCD_SessionRequest_ISR(pdev); } if (gintr_status.b.otgintr) { retval |= DCD_OTG_ISR(pdev); } #endif } return retval; } #ifdef VBUS_SENSING_ENABLED /** * @brief DCD_SessionRequest_ISR * Indicates that the USB_OTG controller has detected a connection * @param pdev: device instance * @retval status */ static uint32_t DCD_SessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev) { USB_OTG_GINTSTS_TypeDef gintsts; USBD_DCD_INT_fops->DevConnected (pdev); /* Clear interrupt */ gintsts.d32 = 0; gintsts.b.sessreqintr = 1; USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32); return 1; } /** * @brief DCD_OTG_ISR * Indicates that the USB_OTG controller has detected an OTG event: * used to detect the end of session i.e. disconnection * @param pdev: device instance * @retval status */ static uint32_t DCD_OTG_ISR(USB_OTG_CORE_HANDLE *pdev) { USB_OTG_GOTGINT_TypeDef gotgint; gotgint.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGINT); if (gotgint.b.sesenddet) { USBD_DCD_INT_fops->DevDisconnected (pdev); } /* Clear OTG interrupt */ USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GOTGINT, gotgint.d32); return 1; } #endif /** * @brief DCD_HandleResume_ISR * Indicates that the USB_OTG controller has detected a resume or * remote Wake-up sequence * @param pdev: device instance * @retval status */ static uint32_t DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE *pdev) { USB_OTG_GINTSTS_TypeDef gintsts; USB_OTG_DCTL_TypeDef devctl; USB_OTG_PCGCCTL_TypeDef power; if(pdev->cfg.low_power) { /* un-gate USB Core clock */ power.d32 = USB_OTG_READ_REG32(&pdev->regs.PCGCCTL); power.b.gatehclk = 0; power.b.stoppclk = 0; USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32); } /* Clear the Remote Wake-up Signaling */ devctl.d32 = 0; devctl.b.rmtwkupsig = 1; USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, devctl.d32, 0); /* Inform upper layer by the Resume Event */ USBD_DCD_INT_fops->Resume (pdev); /* Clear interrupt */ gintsts.d32 = 0; gintsts.b.wkupintr = 1; USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32); return 1; } /** * @brief USB_OTG_HandleUSBSuspend_ISR * Indicates that SUSPEND state has been detected on the USB * @param pdev: device instance * @retval status */ static uint32_t DCD_HandleUSBSuspend_ISR(USB_OTG_CORE_HANDLE *pdev) { USB_OTG_GINTSTS_TypeDef gintsts; USB_OTG_PCGCCTL_TypeDef power; USB_OTG_DSTS_TypeDef dsts; __IO uint8_t prev_status = 0; prev_status = pdev->dev.device_status; USBD_DCD_INT_fops->Suspend (pdev); dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); /* Clear interrupt */ gintsts.d32 = 0; gintsts.b.usbsuspend = 1; USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); if((pdev->cfg.low_power) && (dsts.b.suspsts == 1) && (pdev->dev.connection_status == 1) && (prev_status == USB_OTG_CONFIGURED)) { /* switch-off the clocks */ power.d32 = 0; power.b.stoppclk = 1; USB_OTG_MODIFY_REG32(pdev->regs.PCGCCTL, 0, power.d32); power.b.gatehclk = 1; USB_OTG_MODIFY_REG32(pdev->regs.PCGCCTL, 0, power.d32); /* Request to enter Sleep mode after exit from current ISR */ SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk); } return 1; } /** * @brief DCD_HandleInEP_ISR * Indicates that an IN EP has a pending Interrupt * @param pdev: device instance * @retval status */ static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev) { USB_OTG_DIEPINTn_TypeDef diepint; uint32_t ep_intr; uint32_t epnum = 0; uint32_t fifoemptymsk; diepint.d32 = 0; ep_intr = USB_OTG_ReadDevAllInEPItr(pdev); while ( ep_intr ) { if (ep_intr&0x1) /* In ITR */ { diepint.d32 = DCD_ReadDevInEP(pdev , epnum); /* Get In ITR status */ if ( diepint.b.xfercompl ) { fifoemptymsk = 0x1 << epnum; USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0); CLEAR_IN_EP_INTR(epnum, xfercompl); /* TX COMPLETE */ USBD_DCD_INT_fops->DataInStage(pdev , epnum); if (pdev->cfg.dma_enable == 1) { if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_IN)) { /* prepare to rx more setup packets */ USB_OTG_EP0_OutStart(pdev); } } } if ( diepint.b.timeout ) { CLEAR_IN_EP_INTR(epnum, timeout); } if (diepint.b.intktxfemp) { CLEAR_IN_EP_INTR(epnum, intktxfemp); } if (diepint.b.inepnakeff) { CLEAR_IN_EP_INTR(epnum, inepnakeff); } if ( diepint.b.epdisabled ) { CLEAR_IN_EP_INTR(epnum, epdisabled); } if (diepint.b.emptyintr) { DCD_WriteEmptyTxFifo(pdev , epnum); CLEAR_IN_EP_INTR(epnum, emptyintr); } } epnum++; ep_intr >>= 1; } return 1; } /** * @brief DCD_HandleOutEP_ISR * Indicates that an OUT EP has a pending Interrupt * @param pdev: device instance * @retval status */ static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev) { uint32_t ep_intr; USB_OTG_DOEPINTn_TypeDef doepint; USB_OTG_DEPXFRSIZ_TypeDef deptsiz; uint32_t epnum = 0; doepint.d32 = 0; /* Read in the device interrupt bits */ ep_intr = USB_OTG_ReadDevAllOutEp_itr(pdev); while ( ep_intr ) { if (ep_intr&0x1) { doepint.d32 = USB_OTG_ReadDevOutEP_itr(pdev, epnum); /* Transfer complete */ if ( doepint.b.xfercompl ) { /* Clear the bit in DOEPINTn for this interrupt */ CLEAR_OUT_EP_INTR(epnum, xfercompl); if (pdev->cfg.dma_enable == 1) { deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[epnum]->DOEPTSIZ)); /*ToDo : handle more than one single MPS size packet */ pdev->dev.out_ep[epnum].xfer_count = pdev->dev.out_ep[epnum].maxpacket - \ deptsiz.b.xfersize; } /* Inform upper layer: data ready */ /* RX COMPLETE */ USBD_DCD_INT_fops->DataOutStage(pdev , epnum); if (pdev->cfg.dma_enable == 1) { if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_OUT)) { /* prepare to rx more setup packets */ USB_OTG_EP0_OutStart(pdev); } } } /* Endpoint disable */ if ( doepint.b.epdisabled ) { /* Clear the bit in DOEPINTn for this interrupt */ CLEAR_OUT_EP_INTR(epnum, epdisabled); } /* Setup Phase Done (control EPs) */ if ( doepint.b.setup ) { /* inform the upper layer that a setup packet is available */ /* SETUP COMPLETE */ USBD_DCD_INT_fops->SetupStage(pdev); CLEAR_OUT_EP_INTR(epnum, setup); } } epnum++; ep_intr >>= 1; } return 1; } /** * @brief DCD_HandleSof_ISR * Handles the SOF Interrupts * @param pdev: device instance * @retval status */ static uint32_t DCD_HandleSof_ISR(USB_OTG_CORE_HANDLE *pdev) { USB_OTG_GINTSTS_TypeDef GINTSTS; USBD_DCD_INT_fops->SOF(pdev); /* Clear interrupt */ GINTSTS.d32 = 0; GINTSTS.b.sofintr = 1; USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, GINTSTS.d32); return 1; } /** * @brief DCD_HandleRxStatusQueueLevel_ISR * Handles the Rx Status Queue Level Interrupt * @param pdev: device instance * @retval status */ static uint32_t DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev) { USB_OTG_GINTMSK_TypeDef int_mask; USB_OTG_DRXSTS_TypeDef status; USB_OTG_EP *ep; /* Disable the Rx Status Queue Level interrupt */ int_mask.d32 = 0; int_mask.b.rxstsqlvl = 1; USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, int_mask.d32, 0); /* Get the Status from the top of the FIFO */ status.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRXSTSP ); ep = &pdev->dev.out_ep[status.b.epnum]; switch (status.b.pktsts) { case STS_GOUT_NAK: break; case STS_DATA_UPDT: if (status.b.bcnt) { USB_OTG_ReadPacket(pdev,ep->xfer_buff, status.b.bcnt); ep->xfer_buff += status.b.bcnt; ep->xfer_count += status.b.bcnt; } break; case STS_XFER_COMP: break; case STS_SETUP_COMP: break; case STS_SETUP_UPDT: /* Copy the setup packet received in FIFO into the setup buffer in RAM */ USB_OTG_ReadPacket(pdev , pdev->dev.setup_packet, 8); ep->xfer_count += status.b.bcnt; break; default: break; } /* Enable the Rx Status Queue Level interrupt */ USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, int_mask.d32); return 1; } /** * @brief DCD_WriteEmptyTxFifo * check FIFO for the next packet to be loaded * @param pdev: device instance * @retval status */ static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev, uint32_t epnum) { USB_OTG_DTXFSTSn_TypeDef txstatus; USB_OTG_EP *ep; uint32_t len = 0; uint32_t len32b; txstatus.d32 = 0; ep = &pdev->dev.in_ep[epnum]; len = ep->xfer_len - ep->xfer_count; if (len > ep->maxpacket) { len = ep->maxpacket; } len32b = (len + 3) / 4; txstatus.d32 = USB_OTG_READ_REG32( &pdev->regs.INEP_REGS[epnum]->DTXFSTS); while (txstatus.b.txfspcavail > len32b && ep->xfer_count < ep->xfer_len && ep->xfer_len != 0) { /* Write the FIFO */ len = ep->xfer_len - ep->xfer_count; if (len > ep->maxpacket) { len = ep->maxpacket; } len32b = (len + 3) / 4; USB_OTG_WritePacket (pdev , ep->xfer_buff, epnum, len); ep->xfer_buff += len; ep->xfer_count += len; txstatus.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DTXFSTS); } return 1; } /** * @brief DCD_HandleUsbReset_ISR * This interrupt occurs when a USB Reset is detected * @param pdev: device instance * @retval status */ static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev) { USB_OTG_DAINT_TypeDef daintmsk; USB_OTG_DOEPMSK_TypeDef doepmsk; USB_OTG_DIEPMSK_TypeDef diepmsk; USB_OTG_DCFG_TypeDef dcfg; USB_OTG_DCTL_TypeDef dctl; USB_OTG_GINTSTS_TypeDef gintsts; uint32_t i; dctl.d32 = 0; daintmsk.d32 = 0; doepmsk.d32 = 0; diepmsk.d32 = 0; dcfg.d32 = 0; gintsts.d32 = 0; /* Clear the Remote Wake-up Signaling */ dctl.b.rmtwkupsig = 1; USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, 0 ); /* Flush the Tx FIFO */ USB_OTG_FlushTxFifo(pdev , 0 ); for (i = 0; i < pdev->cfg.dev_endpoints ; i++) { USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF); USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF); } USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF ); daintmsk.ep.in = 1; daintmsk.ep.out = 1; USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, daintmsk.d32 ); doepmsk.b.setup = 1; doepmsk.b.xfercompl = 1; doepmsk.b.epdisabled = 1; USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, doepmsk.d32 ); #ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOUTEP1MSK, doepmsk.d32 ); #endif diepmsk.b.xfercompl = 1; diepmsk.b.timeout = 1; diepmsk.b.epdisabled = 1; USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, diepmsk.d32 ); #ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DINEP1MSK, diepmsk.d32 ); #endif /* Reset Device Address */ dcfg.d32 = USB_OTG_READ_REG32( &pdev->regs.DREGS->DCFG); dcfg.b.devaddr = 0; USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DCFG, dcfg.d32); /* setup EP0 to receive SETUP packets */ USB_OTG_EP0_OutStart(pdev); /* Clear interrupt */ gintsts.d32 = 0; gintsts.b.usbreset = 1; USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32); /*Reset internal state machine */ USBD_DCD_INT_fops->Reset(pdev); return 1; } /** * @brief DCD_HandleEnumDone_ISR * Read the device status register and set the device speed * @param pdev: device instance * @retval status */ static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev) { USB_OTG_GINTSTS_TypeDef gintsts; USB_OTG_GUSBCFG_TypeDef gusbcfg; USB_OTG_EP0Activate(pdev); /* Set USB turn-around time based on device speed and PHY interface. */ gusbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); /* Full or High speed */ if ( USB_OTG_GetDeviceSpeed(pdev) == USB_SPEED_HIGH) { pdev->cfg.speed = USB_OTG_SPEED_HIGH; pdev->cfg.mps = USB_OTG_HS_MAX_PACKET_SIZE ; gusbcfg.b.usbtrdtim = 9; } else { pdev->cfg.speed = USB_OTG_SPEED_FULL; pdev->cfg.mps = USB_OTG_FS_MAX_PACKET_SIZE ; gusbcfg.b.usbtrdtim = 5; } USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, gusbcfg.d32); /* Clear interrupt */ gintsts.d32 = 0; gintsts.b.enumdone = 1; USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, gintsts.d32 ); return 1; } /** * @brief DCD_IsoINIncomplete_ISR * handle the ISO IN incomplete interrupt * @param pdev: device instance * @retval status */ static uint32_t DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev) { USB_OTG_GINTSTS_TypeDef gintsts; gintsts.d32 = 0; USBD_DCD_INT_fops->IsoINIncomplete (pdev); /* Clear interrupt */ gintsts.b.incomplisoin = 1; USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); return 1; } /** * @brief DCD_IsoOUTIncomplete_ISR * handle the ISO OUT incomplete interrupt * @param pdev: device instance * @retval status */ static uint32_t DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev) { USB_OTG_GINTSTS_TypeDef gintsts; gintsts.d32 = 0; USBD_DCD_INT_fops->IsoOUTIncomplete (pdev); /* Clear interrupt */ gintsts.b.incomplisoout = 1; USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); return 1; } /** * @brief DCD_ReadDevInEP * Reads ep flags * @param pdev: device instance * @retval status */ static uint32_t DCD_ReadDevInEP (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum) { uint32_t v, msk, emp; msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPMSK); emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK); msk |= ((emp >> epnum) & 0x1) << 7; v = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DIEPINT) & msk; return v; } /** * @} */ /** * @} */ /** * @} */ /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/