/******************************************************************************* * Function Name : OTGD_FS_Handle_IsoOutDrop_ISR * Description : Handles the Isochronous Out packet Dropped interrupt. * Input : None * Output : None * Return : status *******************************************************************************/ uint32_t OTGD_FS_Handle_IsoOutDrop_ISR(void) { USB_OTG_GINTSTS_TypeDef gintsts; gintsts.d32 = 0; /* Call user function */ INTR_ISOOUTDROP_Callback(); /* Clear interrupt */ gintsts.b.isooutdrop = 1; USB_OTG_WRITE_REG32(&USB_OTG_FS_regs.GREGS->GINTSTS, gintsts.d32); return 1; }
/******************************************************************************* * Function Name : OTGD_FS_Handle_Sof_ISR * Description : Handles the Start Of Frame detected interrupt. * Input : None * Output : None * Return : status *******************************************************************************/ uint32_t OTGD_FS_Handle_Sof_ISR(void) { USB_OTG_GINTSTS_TypeDef GINTSTS ; GINTSTS.d32 = 0; /* Call user function */ INTR_SOFINTR_Callback(); /* Clear interrupt */ GINTSTS.b.sofintr = 1; USB_OTG_WRITE_REG32 (&USB_OTG_FS_regs.GREGS->GINTSTS, GINTSTS.d32); return 1; }
/******************************************************************************* * Function Name : OTGD_FS_Handle_EnumDone_ISR * Description : Reads the device status register and set the device speed * Input : None * Output : None * Return : status *******************************************************************************/ uint32_t OTGD_FS_Handle_EnumDone_ISR(void) { USB_OTG_GINTSTS_TypeDef gintsts; USB_OTG_GUSBCFG_TypeDef gusbcfg; gintsts.d32 = 0; gusbcfg.d32 = 0; OTGD_FS_EP0Activate(); /* Set USB turnaround time */ gusbcfg.d32 = USB_OTG_READ_REG32(&USB_OTG_FS_regs.GREGS->GUSBCFG); gusbcfg.b.usbtrdtim = 9; USB_OTG_WRITE_REG32(&USB_OTG_FS_regs.GREGS->GUSBCFG, gusbcfg.d32); /* Call user function */ INTR_ENUMDONE_Callback(); /* Clear interrupt */ gintsts.b.enumdone = 1; USB_OTG_WRITE_REG32( &USB_OTG_FS_regs.GREGS->GINTSTS, gintsts.d32 ); return 1; }
/******************************************************************************* * Function Name : OTGD_FS_Handle_USBSuspend_ISR * Description : Handles the Suspend condition detected interrupt. * Input : None * Output : None * Return : status *******************************************************************************/ uint32_t OTGD_FS_Handle_USBSuspend_ISR(void) { USB_OTG_GINTSTS_TypeDef gintsts; gintsts.d32 = 0; /* Call user function */ INTR_USBSUSPEND_Callback(); /* Clear interrupt */ gintsts.b.usbsuspend = 1; USB_OTG_WRITE_REG32(&USB_OTG_FS_regs.GREGS->GINTSTS, gintsts.d32); return 1; }
/** * @brief USB_OTG_USBH_handle_Disconnect_ISR * Handles disconnect event. * @param pdev: Selected device * @retval status */ static uint32_t USB_OTG_USBH_handle_Disconnect_ISR (USB_OTG_CORE_HANDLE *pdev) { USB_OTG_GINTSTS_TypeDef gintsts; gintsts.d32 = 0; //USBH_HCD_INT_fops->DevDisconnected(pdev); pdev->host.ConnSts = 0; /* Clear interrupt */ gintsts.b.disconnect = 1; USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); return 1; }
/******************************************************************************* * Function Name : OTGD_FS_Handle_Wakeup_ISR * Description : Handles the Wakeup or Remote Wakeup detected interrupt. * Input : None * Output : None * Return : status *******************************************************************************/ uint32_t OTGD_FS_Handle_Wakeup_ISR(void) { USB_OTG_GINTSTS_TypeDef gintsts; gintsts.d32 = 0; /* Call user function */ INTR_WKUPINTR_Callback(); /* Clear interrupt */ gintsts.b.wkupintr = 1; USB_OTG_WRITE_REG32 (&USB_OTG_FS_regs.GREGS->GINTSTS, gintsts.d32); 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; }
/******************************************************************************* * Function Name : OTGD_FS_ResetRemoteWakeup * Description : Disable Remote wakeup signaling * Input : None * Output : None * Return : status *******************************************************************************/ void OTGD_FS_ResetRemoteWakeup() { USB_OTG_DCTL_TypeDef devctl; devctl.d32 = 0; devctl.d32 = USB_OTG_READ_REG32(&USB_OTG_FS_regs.DEV->DCTL); /* Disable the Remote Wakeup signal */ devctl.b.rmtwkupsig = 0; USB_OTG_WRITE_REG32(&USB_OTG_FS_regs.DEV->DCTL, devctl.d32); }
/******************************************************************************* * Function Name : PCD_EP0_OutStart * Description : Configures EPO to receive SETUP packets. * Input : None * Output : None * Return : None *******************************************************************************/ void PCD_EP0_OutStart(void) { USB_OTG_DOEPTSIZ0_TypeDef doeptsize0; doeptsize0.d32 = 0; doeptsize0.b.supcnt = 3; doeptsize0.b.pktcnt = 1; doeptsize0.b.xfersize = 8 * 3; USB_OTG_WRITE_REG32( &USB_OTG_FS_regs.DOUTEPS[0]->DOEPTSIZx, doeptsize0.d32 ); }
/** * @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; }
/******************************************************************************* * Function Name : PCD_DevDisconnect * Description : Disconnect device * Input : None * Output : None * Return : status *******************************************************************************/ void PCD_DevDisconnect (void) { USB_OTG_DCTL_TypeDef dctl; dctl.d32 = 0; dctl.d32 = USB_OTG_READ_REG32(&USB_OTG_FS_regs.DEV->DCTL); /* Disconnect device for 20ms */ dctl.b.sftdiscon = 1; USB_OTG_WRITE_REG32(&USB_OTG_FS_regs.DEV->DCTL, dctl.d32); mDELAY(25); }
/** * @brief USB_OTG_InitiateSRP * Initiate an srp session * @param None * @retval : None */ void USB_OTG_InitiateSRP(USB_OTG_CORE_HANDLE *pdev) { USB_OTG_GOTGCTL_TypeDef otgctl; otgctl.d32 = 0; otgctl.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GOTGCTL ); if (otgctl.b.sesreq) { return; /* SRP in progress */ } otgctl.b.sesreq = 1; USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GOTGCTL, otgctl.d32); }
/******************************************************************************* * Function Name : OTGD_FS_Handle_IncomplIsoOut_ISR * Description : Handles the Incomplete Isochronous OUT transfer error interrupt. * Input : None * Output : None * Return : status *******************************************************************************/ uint32_t OTGD_FS_Handle_IncomplIsoOut_ISR(void) { USB_OTG_GINTSTS_TypeDef gintsts; gintsts.d32 = 0; /* Call user function */ INTR_INCOMPLISOOUT_Callback(); /* Clear interrupt */ gintsts.b.outepintr = 1; USB_OTG_WRITE_REG32(&USB_OTG_FS_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; }
//-------------------------------------------------------------- void USB_OTG_DriveVbus (USB_OTG_CORE_HANDLE *pdev, uint8_t state) { USB_OTG_HPRT0_TypeDef hprt0; hprt0.d32 = 0; /* enable disable the external charge pump */ USB_OTG_BSP_DriveVBUS(pdev, state); /* Turn on the Host port power. */ hprt0.d32 = USB_OTG_ReadHPRT0(pdev); if ((hprt0.b.prtpwr == 0 ) && (state == 1 )) { hprt0.b.prtpwr = 1; USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32); } if ((hprt0.b.prtpwr == 1 ) && (state == 0 )) { hprt0.b.prtpwr = 0; USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32); } USB_OTG_BSP_mDelay(200); }
/** * @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 */ #pragma GCC diagnostic push // HJI #pragma GCC diagnostic ignored "-Wstrict-aliasing" // HJI power.d32 = USB_OTG_READ_REG32(&pdev->regs.PCGCCTL); #pragma GCC diagnostic pop // HJI 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_otg_hcd_handle_sof_intr * Handles the start-of-frame interrupt in host mode. * @param pdev: Selected device * @retval status */ static uint32_t USB_OTG_USBH_handle_sof_ISR (USB_OTG_CORE_HANDLE *pdev) { USB_OTG_GINTSTS_TypeDef gintsts; gintsts.d32 = 0; //USBH_HCD_INT_fops->SOF(pdev); /* Clear interrupt */ gintsts.b.sofintr = 1; USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); pdev->host.SofHits++; return 1; }
/** * @brief USB_OTG_otg_hcd_handle_sof_intr * Handles the start-of-frame interrupt in host mode. * @param pdev: Selected device * @retval status */ static uint32_t USB_OTG_USBH_handle_sof_ISR (USB_OTG_CORE_HANDLE *pdev) { USB_OTG_GINTSTS_TypeDef gintsts; gintsts.d32 = 0; /* This callback could be used to implement a scheduler process */ //USBH_HCD_INT_fops->SOF(pdev); /* Clear interrupt */ gintsts.b.sofintr = 1; USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32); pdev->host.SofHits++; return 1; }
/** * @brief USB_OTG_BSP_Suspend * Handles the Enter USB to Suspend Mode * @param pdev: Selected device * @retval Status */ void USB_OTG_BSP_Suspend(USB_OTG_CORE_HANDLE *pdev) { USB_OTG_HPRT0_TypeDef hprt0; USB_OTG_PCGCCTL_TypeDef power; hprt0.d32 = 0; hprt0.d32 = USB_OTG_ReadHPRT0(pdev); hprt0.b.prtsusp = 1; USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0.d32); /* 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); }
//-------------------------------------------------------------- static void USBD_SetFeature(USB_OTG_CORE_HANDLE *pdev, USB_SETUP_REQ *req) { USB_OTG_DCTL_TypeDef dctl; uint8_t test_mode = 0; if (req->wValue == USB_FEATURE_REMOTE_WAKEUP) { pdev->dev.DevRemoteWakeup = 1; pdev->dev.class_cb->Setup (pdev, req); USBD_CtlSendStatus(pdev); } else if ((req->wValue == USB_FEATURE_TEST_MODE) && ((req->wIndex & 0xFF) == 0)) { dctl.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DCTL); test_mode = req->wIndex >> 8; switch (test_mode) { case 1: // TEST_J dctl.b.tstctl = 1; break; case 2: // TEST_K dctl.b.tstctl = 2; break; case 3: // TEST_SE0_NAK dctl.b.tstctl = 3; break; case 4: // TEST_PACKET dctl.b.tstctl = 4; break; case 5: // TEST_FORCE_ENABLE dctl.b.tstctl = 5; break; } USB_OTG_WRITE_REG32(&pdev->regs.DREGS->DCTL, dctl.d32); USBD_CtlSendStatus(pdev); }
/******************************************************************************* * Function Name : OTGD_FS_SetDeviceMode * Description : Set device mode * Input : None * Output : None * Return : Status *******************************************************************************/ USB_OTG_Status OTGD_FS_SetDeviceMode(void) { USB_OTG_Status status = USB_OTG_OK; USB_OTG_GUSBCFG_TypeDef usbcfg ; usbcfg.d32 = 0; usbcfg.d32 = USB_OTG_READ_REG32(&USB_OTG_FS_regs.GREGS->GUSBCFG); usbcfg.b.force_dev = 1; USB_OTG_WRITE_REG32(&USB_OTG_FS_regs.GREGS->GUSBCFG, usbcfg.d32); mDELAY(50); return status; }
/******************************************************************************* * Function Name : OTGD_FS_EP0Activate * Description : enables EP0 OUT to receive SETUP packets and configures EP0 IN for transmitting packets * Input : None * Output : None * Return : status *******************************************************************************/ USB_OTG_Status OTGD_FS_EP0Activate(void) { USB_OTG_Status status = USB_OTG_OK; USB_OTG_DEPCTLx_TypeDef diepctl; USB_OTG_DCTL_TypeDef dctl; diepctl.d32 = 0; dctl.d32 = 0; diepctl.d32 = USB_OTG_READ_REG32(&USB_OTG_FS_regs.DINEPS[0]->DIEPCTLx); diepctl.b.mps = DEP0CTL_MPS_64; USB_OTG_WRITE_REG32(&USB_OTG_FS_regs.DINEPS[0]->DIEPCTLx, diepctl.d32); dctl.b.cgnpinnak = 1; USB_OTG_MODIFY_REG32(&USB_OTG_FS_regs.DEV->DCTL, dctl.d32, dctl.d32); return status; }
/******************************************************************************* * Function Name : OTGD_FS_Handle_EOPF_ISR * Description : Handles the Expected End Of Periodic Frame interrupt. * Input : None * Output : None * Return : status *******************************************************************************/ uint32_t OTGD_FS_Handle_EOPF_ISR(void) { USB_OTG_GINTSTS_TypeDef gintsts; USB_OTG_GINTMSK_TypeDef gintmsk; gintsts.d32 = 0; gintmsk.d32 = 0; gintmsk.b.eopframe = 1; USB_OTG_MODIFY_REG32(&USB_OTG_FS_regs.GREGS->GINTMSK, gintmsk.d32, 0); /* Call user function */ INTR_EOPFRAME_Callback(); /* Clear interrupt */ gintsts.b.eopframe = 1; USB_OTG_WRITE_REG32(&USB_OTG_FS_regs.GREGS->GINTSTS, gintsts.d32); return 1; }
/******************************************************************************* * Function Name : OTGD_FS_Handle_EarlySuspend_ISR * Description : Handles the Early Suspend detected interrupt. * Input : None * Output : None * Return : status *******************************************************************************/ uint32_t OTGD_FS_Handle_EarlySuspend_ISR(void) { USB_OTG_GINTSTS_TypeDef gintsts; USB_OTG_GINTMSK_TypeDef gintmsk; gintsts.d32 = 0; gintmsk.d32 = 0; /* Call user function */ INTR_ERLYSUSPEND_Callback(); gintmsk.b.erlysuspend = 1; USB_OTG_MODIFY_REG32(&USB_OTG_FS_regs.GREGS->GINTMSK, gintmsk.d32, 0); /* Clear interrupt */ gintsts.b.erlysuspend = 1; USB_OTG_WRITE_REG32(&USB_OTG_FS_regs.GREGS->GINTSTS, gintsts.d32); return 1; }
/******************************************************************************* * Function Name : OTGD_FS_WritePacket * Description : Writes a packet into the Tx FIFO associated with the EP * Input : None * Output : None * Return : Status *******************************************************************************/ USB_OTG_Status OTGD_FS_WritePacket(uint8_t *src, uint8_t ep_num, uint16_t bytes) { USB_OTG_Status status = USB_OTG_OK; uint32_t dword_count = 0 , i = 0; __IO uint32_t *fifo; /* Find the DWORD length, padded by extra bytes as necessary if MPS * is not a multiple of DWORD */ dword_count = (bytes + 3) / 4; fifo = USB_OTG_FS_regs.FIFO[ep_num]; for (i = 0; i < dword_count; i++, src += 4) { USB_OTG_WRITE_REG32( fifo, *((__packed uint32_t *)src) ); } return status; }
//-------------------------------------------------------------- void USB_OTG_UngateClock(USB_OTG_CORE_HANDLE * pdev) { if (pdev->cfg.low_power) { USB_OTG_DSTS_TypeDef dsts; USB_OTG_PCGCCTL_TypeDef power; dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS); if (dsts.b.suspsts == 1) { /* 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); } } }
//-------------------------------------------------------------- USB_OTG_STS USB_OTG_WritePacket(USB_OTG_CORE_HANDLE *pdev, uint8_t *src, uint8_t ch_ep_num, uint16_t len) { USB_OTG_STS status = USB_OTG_OK; if (pdev->cfg.dma_enable == 0) { uint32_t count32b= 0 , i= 0; __IO uint32_t *fifo; count32b = (len + 3) / 4; fifo = pdev->regs.DFIFO[ch_ep_num]; for (i = 0; i < count32b; i++, src+=4) { USB_OTG_WRITE_REG32( fifo, *((__packed uint32_t *)src) ); } } return status; }
//-------------------------------------------------------------- USB_OTG_STS USB_OTG_SetCurrentMode(USB_OTG_CORE_HANDLE * pdev, uint8_t mode) { USB_OTG_STS status = USB_OTG_OK; USB_OTG_GUSBCFG_TypeDef usbcfg; usbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG); usbcfg.b.force_host = 0; usbcfg.b.force_dev = 0; if (mode == HOST_MODE) { usbcfg.b.force_host = 1; } else if (mode == DEVICE_MODE) { usbcfg.b.force_dev = 1; } USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, usbcfg.d32); USB_OTG_BSP_mDelay(50); return status; }
//-------------------------------------------------------------- USB_OTG_STS USB_OTG_FlushRxFifo(USB_OTG_CORE_HANDLE * pdev) { USB_OTG_STS status = USB_OTG_OK; __IO USB_OTG_GRSTCTL_TypeDef greset; uint32_t count = 0; greset.d32 = 0; greset.b.rxfflsh = 1; USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GRSTCTL, greset.d32); do { greset.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRSTCTL); if (++count > 200000) { break; } } while (greset.b.rxfflsh == 1); /* Wait for 3 PHY Clocks */ USB_OTG_BSP_uDelay(3); return status; }
/******************************************************************************* * Function Name : OTGD_FS_EPActivate * Description : Activates an EP * Input : ep * Output : None * Return : num_in_ep *******************************************************************************/ USB_OTG_Status OTGD_FS_EPActivate(USB_OTG_EP *ep) { USB_OTG_Status status = USB_OTG_OK; USB_OTG_DEPCTLx_TypeDef depctl; USB_OTG_DAINT_TypeDef daintmsk; __IO uint32_t *addr; depctl.d32 = 0; daintmsk.d32 = 0; /* Read DEPCTLn register */ if (ep->is_in == 1) { addr = &USB_OTG_FS_regs.DINEPS[ep->num]->DIEPCTLx; daintmsk.ep.in = 1 << ep->num; } else { addr = &USB_OTG_FS_regs.DOUTEPS[ep->num]->DOEPCTLx; daintmsk.ep.out = 1 << ep->num; } /* If the EP is already active don't change the EP Control * register. */ depctl.d32 = USB_OTG_READ_REG32(addr); if (!depctl.b.usbactep) { depctl.b.mps = ep->maxpacket; depctl.b.eptype = ep->type; depctl.b.txfnum = ep->tx_fifo_num; depctl.b.setd0pid = 1; depctl.b.usbactep = 1; USB_OTG_WRITE_REG32(addr, depctl.d32); } /* Enable the Interrupt for this EP */ USB_OTG_MODIFY_REG32(&USB_OTG_FS_regs.DEV->DAINTMSK, 0, daintmsk.d32); return status; }