| /****************************************************************************** |
| * |
| * Copyright (C) 2016 Xilinx, Inc. All rights reserved. |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining a copy |
| * of this software and associated documentation files (the "Software"), to deal |
| * in the Software without restriction, including without limitation the rights |
| * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
| * copies of the Software, and to permit persons to whom the Software is |
| * furnished to do so, subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be included in |
| * all copies or substantial portions of the Software. |
| * |
| * Use of the Software is limited solely to applications: |
| * (a) running on a Xilinx device, or |
| * (b) that interact with a Xilinx device through a bus or interconnect. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
| * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
| * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
| * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, |
| * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF |
| * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
| * SOFTWARE. |
| * |
| * Except as contained in this notice, the name of the Xilinx shall not be used |
| * in advertising or otherwise to promote the sale, use or other dealings in |
| * this Software without prior written authorization from Xilinx. |
| * |
| ******************************************************************************/ |
| /****************************************************************************/ |
| /** |
| * |
| * @file xusbpsu.c |
| * @addtogroup usbpsu_v1_0 |
| * @{ |
| * |
| * <pre> |
| * |
| * MODIFICATION HISTORY: |
| * |
| * Ver Who Date Changes |
| * ----- ----- -------- ----------------------------------------------------- |
| * 1.0 sg 06/16/16 First release |
| * 1.1 sg 10/24/16 Added new function XUsbPsu_IsSuperSpeed |
| * |
| * </pre> |
| * |
| *****************************************************************************/ |
| |
| /***************************** Include Files ********************************/ |
| |
| #include "xusbpsu.h" |
| |
| /************************** Constant Definitions *****************************/ |
| |
| |
| /**************************** Type Definitions *******************************/ |
| |
| |
| /***************** Macros (Inline Functions) Definitions *********************/ |
| |
| |
| /************************** Function Prototypes ******************************/ |
| |
| |
| /************************** Variable Definitions *****************************/ |
| |
| /*****************************************************************************/ |
| /** |
| * Waits until a bit in a register is cleared or timeout occurs |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance to be worked on. |
| * @param Offset is register offset. |
| * @param BitMask is bit mask of required bit to be checked. |
| * @param Timeout is the time to wait specified in micro seconds. |
| * |
| * @return |
| * - XST_SUCCESS when bit is cleared. |
| * - XST_FAILURE when timed out. |
| * |
| ******************************************************************************/ |
| s32 XUsbPsu_Wait_Clear_Timeout(struct XUsbPsu *InstancePtr, u32 Offset, |
| u32 BitMask, u32 Timeout) |
| { |
| u32 RegVal; |
| u32 LocalTimeout = Timeout; |
| |
| do { |
| RegVal = XUsbPsu_ReadReg(InstancePtr, Offset); |
| if ((RegVal & BitMask) == 0U) { |
| break; |
| } |
| LocalTimeout--; |
| if (LocalTimeout == 0U) { |
| return XST_FAILURE; |
| } |
| XUsbSleep(1U); |
| } while (1); |
| |
| return XST_SUCCESS; |
| } |
| |
| /*****************************************************************************/ |
| /** |
| * Waits until a bit in a register is set or timeout occurs |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance to be worked on. |
| * @param Offset is register offset. |
| * @param BitMask is bit mask of required bit to be checked. |
| * @param Timeout is the time to wait specified in micro seconds. |
| * |
| * @return |
| * - XST_SUCCESS when bit is set. |
| * - XST_FAILURE when timed out. |
| * |
| ******************************************************************************/ |
| s32 XUsbPsu_Wait_Set_Timeout(struct XUsbPsu *InstancePtr, u32 Offset, |
| u32 BitMask, u32 Timeout) |
| { |
| u32 RegVal; |
| u32 LocalTimeout = Timeout; |
| |
| do { |
| RegVal = XUsbPsu_ReadReg(InstancePtr, Offset); |
| if ((RegVal & BitMask) != 0U) { |
| break; |
| } |
| LocalTimeout--; |
| if (LocalTimeout == 0U) { |
| return XST_FAILURE; |
| } |
| XUsbSleep(1U); |
| } while (1); |
| |
| return XST_SUCCESS; |
| } |
| |
| /*****************************************************************************/ |
| /** |
| * Sets mode of Core to USB Device/Host/OTG. |
| * |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance to be worked on. |
| * @param Mode is mode to set |
| * - XUSBPSU_GCTL_PRTCAP_OTG |
| * - XUSBPSU_GCTL_PRTCAP_HOST |
| * - XUSBPSU_GCTL_PRTCAP_DEVICE |
| * |
| * @return None |
| * |
| ******************************************************************************/ |
| void XUsbPsu_SetMode(struct XUsbPsu *InstancePtr, u32 Mode) |
| { |
| u32 RegVal; |
| |
| Xil_AssertVoid(InstancePtr != NULL); |
| Xil_AssertVoid((Mode <= XUSBPSU_GCTL_PRTCAP_OTG) && |
| (Mode >= XUSBPSU_GCTL_PRTCAP_HOST)); |
| |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_GCTL); |
| RegVal &= ~(XUSBPSU_GCTL_PRTCAPDIR(XUSBPSU_GCTL_PRTCAP_OTG)); |
| RegVal |= XUSBPSU_GCTL_PRTCAPDIR(Mode); |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GCTL, RegVal); |
| } |
| |
| /*****************************************************************************/ |
| /** |
| * Issues core PHY reset. |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance to be worked on. |
| * |
| * @return None |
| * |
| ******************************************************************************/ |
| void XUsbPsu_PhyReset(struct XUsbPsu *InstancePtr) |
| { |
| u32 RegVal; |
| |
| Xil_AssertVoid(InstancePtr != NULL); |
| |
| /* Before Resetting PHY, put Core in Reset */ |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_GCTL); |
| RegVal |= XUSBPSU_GCTL_CORESOFTRESET; |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GCTL, RegVal); |
| |
| /* Assert USB3 PHY reset */ |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_GUSB3PIPECTL(0)); |
| RegVal |= XUSBPSU_GUSB3PIPECTL_PHYSOFTRST; |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GUSB3PIPECTL(0), RegVal); |
| |
| /* Assert USB2 PHY reset */ |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_GUSB2PHYCFG(0)); |
| RegVal |= XUSBPSU_GUSB2PHYCFG_PHYSOFTRST; |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GUSB2PHYCFG(0), RegVal); |
| |
| XUsbSleep(XUSBPSU_PHY_TIMEOUT); |
| |
| /* Clear USB3 PHY reset */ |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_GUSB3PIPECTL(0)); |
| RegVal &= ~XUSBPSU_GUSB3PIPECTL_PHYSOFTRST; |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GUSB3PIPECTL(0), RegVal); |
| |
| /* Clear USB2 PHY reset */ |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_GUSB2PHYCFG(0)); |
| RegVal &= ~XUSBPSU_GUSB2PHYCFG_PHYSOFTRST; |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GUSB2PHYCFG(0), RegVal); |
| |
| XUsbSleep(XUSBPSU_PHY_TIMEOUT); |
| |
| /* Take Core out of reset state after PHYS are stable*/ |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_GCTL); |
| RegVal &= ~XUSBPSU_GCTL_CORESOFTRESET; |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GCTL, RegVal); |
| } |
| |
| /*****************************************************************************/ |
| /** |
| * Sets up Event buffers so that events are written by Core. |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance to be worked on. |
| * |
| * @return None |
| * |
| ******************************************************************************/ |
| void XUsbPsu_EventBuffersSetup(struct XUsbPsu *InstancePtr) |
| { |
| struct XUsbPsu_EvtBuffer *Evt; |
| |
| Xil_AssertVoid(InstancePtr != NULL); |
| |
| Evt = &InstancePtr->Evt; |
| Evt->BuffAddr = (void *)InstancePtr->EventBuffer; |
| |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GEVNTADRLO(0), |
| (UINTPTR)InstancePtr->EventBuffer); |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GEVNTADRHI(0), |
| ((UINTPTR)(InstancePtr->EventBuffer) >> 16U) >> 16U); |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GEVNTSIZ(0), |
| XUSBPSU_GEVNTSIZ_SIZE(sizeof(InstancePtr->EventBuffer))); |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GEVNTCOUNT(0), 0); |
| } |
| |
| /*****************************************************************************/ |
| /** |
| * Resets Event buffer Registers to zero so that events are not written by Core. |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance to be worked on. |
| * |
| * @return None |
| * |
| ******************************************************************************/ |
| void XUsbPsu_EventBuffersReset(struct XUsbPsu *InstancePtr) |
| { |
| |
| Xil_AssertVoid(InstancePtr != NULL); |
| |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GEVNTADRLO(0U), 0U); |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GEVNTADRHI(0U), 0U); |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GEVNTSIZ(0U), |
| (u32)XUSBPSU_GEVNTSIZ_INTMASK | XUSBPSU_GEVNTSIZ_SIZE(0U)); |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GEVNTCOUNT(0U), 0U); |
| } |
| |
| /*****************************************************************************/ |
| /** |
| * Reads data from Hardware Params Registers of Core. |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance to be worked on. |
| * @param RegIndex is Register number to read |
| * - XUSBPSU_GHWPARAMS0 |
| * - XUSBPSU_GHWPARAMS1 |
| * - XUSBPSU_GHWPARAMS2 |
| * - XUSBPSU_GHWPARAMS3 |
| * - XUSBPSU_GHWPARAMS4 |
| * - XUSBPSU_GHWPARAMS5 |
| * - XUSBPSU_GHWPARAMS6 |
| * - XUSBPSU_GHWPARAMS7 |
| * |
| * @return One of the GHWPARAMS RegValister contents. |
| * |
| ******************************************************************************/ |
| u32 XUsbPsu_ReadHwParams(struct XUsbPsu *InstancePtr, u8 RegIndex) |
| { |
| u32 RegVal; |
| |
| Xil_AssertNonvoid(InstancePtr != NULL); |
| Xil_AssertNonvoid(RegIndex <= (u8)XUSBPSU_GHWPARAMS7); |
| |
| RegVal = XUsbPsu_ReadReg(InstancePtr, ((u32)XUSBPSU_GHWPARAMS0_OFFSET + |
| ((u32)RegIndex * (u32)4))); |
| return RegVal; |
| } |
| |
| /*****************************************************************************/ |
| /** |
| * Initializes Core. |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance to be worked on. |
| * |
| * @return |
| * - XST_SUCCESS if initialization was successful |
| * - XST_FAILURE if initialization was not successful |
| * |
| ******************************************************************************/ |
| s32 XUsbPsu_CoreInit(struct XUsbPsu *InstancePtr) |
| { |
| u32 RegVal; |
| u32 Hwparams1; |
| |
| /* issue device SoftReset too */ |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCTL, XUSBPSU_DCTL_CSFTRST); |
| |
| if (XUsbPsu_Wait_Clear_Timeout(InstancePtr, XUSBPSU_DCTL, |
| XUSBPSU_DCTL_CSFTRST, 500U) == XST_FAILURE) { |
| /* timed out return failure */ |
| return XST_FAILURE; |
| } |
| |
| XUsbPsu_PhyReset(InstancePtr); |
| |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_GCTL); |
| RegVal &= ~XUSBPSU_GCTL_SCALEDOWN_MASK; |
| RegVal &= ~XUSBPSU_GCTL_DISSCRAMBLE; |
| RegVal |= XUSBPSU_GCTL_U2EXIT_LFPS; |
| |
| Hwparams1 = XUsbPsu_ReadHwParams(InstancePtr, 1U); |
| |
| switch (XUSBPSU_GHWPARAMS1_EN_PWROPT(Hwparams1)) { |
| case XUSBPSU_GHWPARAMS1_EN_PWROPT_CLK: |
| RegVal &= ~XUSBPSU_GCTL_DSBLCLKGTNG; |
| break; |
| |
| case XUSBPSU_GHWPARAMS1_EN_PWROPT_HIB: |
| /* enable hibernation here */ |
| break; |
| |
| default: |
| /* Made for Misra-C Compliance. */ |
| break; |
| } |
| |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GCTL, RegVal); |
| |
| return XST_SUCCESS; |
| } |
| |
| /*****************************************************************************/ |
| /** |
| * Enables an interrupt in Event Enable RegValister. |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance to be worked on |
| * @param Mask is the OR of any Interrupt Enable Masks: |
| * - XUSBPSU_DEVTEN_VNDRDEVTSTRCVEDEN |
| * - XUSBPSU_DEVTEN_EVNTOVERFLOWEN |
| * - XUSBPSU_DEVTEN_CMDCMPLTEN |
| * - XUSBPSU_DEVTEN_ERRTICERREN |
| * - XUSBPSU_DEVTEN_SOFEN |
| * - XUSBPSU_DEVTEN_EOPFEN |
| * - XUSBPSU_DEVTEN_HIBERNATIONREQEVTEN |
| * - XUSBPSU_DEVTEN_WKUPEVTEN |
| * - XUSBPSU_DEVTEN_ULSTCNGEN |
| * - XUSBPSU_DEVTEN_CONNECTDONEEN |
| * - XUSBPSU_DEVTEN_USBRSTEN |
| * - XUSBPSU_DEVTEN_DISCONNEVTEN |
| * |
| * @return None |
| * |
| ******************************************************************************/ |
| void XUsbPsu_EnableIntr(struct XUsbPsu *InstancePtr, u32 Mask) |
| { |
| u32 RegVal; |
| |
| Xil_AssertVoid(InstancePtr != NULL); |
| |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DEVTEN); |
| RegVal |= Mask; |
| |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DEVTEN, RegVal); |
| } |
| |
| /*****************************************************************************/ |
| /** |
| * Disables an interrupt in Event Enable RegValister. |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance to be worked on. |
| * @param Mask is the OR of Interrupt Enable Masks |
| * - XUSBPSU_DEVTEN_VNDRDEVTSTRCVEDEN |
| * - XUSBPSU_DEVTEN_EVNTOVERFLOWEN |
| * - XUSBPSU_DEVTEN_CMDCMPLTEN |
| * - XUSBPSU_DEVTEN_ERRTICERREN |
| * - XUSBPSU_DEVTEN_SOFEN |
| * - XUSBPSU_DEVTEN_EOPFEN |
| * - XUSBPSU_DEVTEN_HIBERNATIONREQEVTEN |
| * - XUSBPSU_DEVTEN_WKUPEVTEN |
| * - XUSBPSU_DEVTEN_ULSTCNGEN |
| * - XUSBPSU_DEVTEN_CONNECTDONEEN |
| * - XUSBPSU_DEVTEN_USBRSTEN |
| * - XUSBPSU_DEVTEN_DISCONNEVTEN |
| * |
| * @return None |
| * |
| ******************************************************************************/ |
| void XUsbPsu_DisableIntr(struct XUsbPsu *InstancePtr, u32 Mask) |
| { |
| u32 RegVal; |
| |
| Xil_AssertVoid(InstancePtr != NULL); |
| |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DEVTEN); |
| RegVal &= ~Mask; |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DEVTEN, RegVal); |
| } |
| |
| /****************************************************************************/ |
| /** |
| * |
| * This function does the following: |
| * - initializes a specific XUsbPsu instance. |
| * - sets up Event Buffer for Core to write events. |
| * - Core Reset and PHY Reset. |
| * - Sets core in Device Mode. |
| * - Sets default speed as HIGH_SPEED. |
| * - Sets Device Address to 0. |
| * - Enables interrupts. |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance. |
| * @param ConfigPtr points to the XUsbPsu device configuration structure. |
| * @param BaseAddress is the device base address in the virtual memory |
| * address space. If the address translation is not used then the |
| * physical address is passed. |
| * Unexpected errors may occur if the address mapping is changed |
| * after this function is invoked. |
| * |
| * @return XST_SUCCESS else XST_FAILURE |
| * |
| * @note None. |
| * |
| *****************************************************************************/ |
| s32 XUsbPsu_CfgInitialize(struct XUsbPsu *InstancePtr, |
| XUsbPsu_Config *ConfigPtr, u32 BaseAddress) |
| { |
| int Status; |
| u32 RegVal; |
| |
| |
| Xil_AssertNonvoid(InstancePtr != NULL); |
| Xil_AssertNonvoid(ConfigPtr != NULL); |
| Xil_AssertNonvoid(BaseAddress != 0U) |
| |
| InstancePtr->ConfigPtr = ConfigPtr; |
| |
| Status = XUsbPsu_CoreInit(InstancePtr); |
| if (Status != XST_SUCCESS) { |
| #ifdef XUSBPSU_DEBUG |
| xil_printf("Core initialization failed\r\n"); |
| #endif |
| return XST_FAILURE; |
| } |
| |
| RegVal = XUsbPsu_ReadHwParams(InstancePtr, 3U); |
| InstancePtr->NumInEps = (u8)XUSBPSU_NUM_IN_EPS(RegVal); |
| InstancePtr->NumOutEps = (u8)(XUSBPSU_NUM_EPS(RegVal) - |
| InstancePtr->NumInEps); |
| |
| /* Map USB and Physical Endpoints */ |
| XUsbPsu_InitializeEps(InstancePtr); |
| |
| XUsbPsu_EventBuffersSetup(InstancePtr); |
| |
| XUsbPsu_SetMode(InstancePtr, XUSBPSU_GCTL_PRTCAP_DEVICE); |
| |
| /* |
| * Setting to max speed to support SS and HS |
| */ |
| XUsbPsu_SetSpeed(InstancePtr, XUSBPSU_DCFG_SUPERSPEED); |
| |
| (void)XUsbPsu_SetDeviceAddress(InstancePtr, 0U); |
| |
| return XST_SUCCESS; |
| } |
| |
| /****************************************************************************/ |
| /** |
| * |
| * Starts the controller so that Host can detect this device. |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance. |
| * |
| * @return XST_SUCCESS else XST_FAILURE |
| * |
| * @note None. |
| * |
| *****************************************************************************/ |
| s32 XUsbPsu_Start(struct XUsbPsu *InstancePtr) |
| { |
| u32 RegVal; |
| |
| Xil_AssertNonvoid(InstancePtr != NULL); |
| |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCTL); |
| |
| RegVal |= XUSBPSU_DCTL_RUN_STOP; |
| |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCTL, RegVal); |
| |
| if (XUsbPsu_Wait_Clear_Timeout(InstancePtr, XUSBPSU_DSTS, |
| XUSBPSU_DSTS_DEVCTRLHLT, 500U) == XST_FAILURE) { |
| return XST_FAILURE; |
| } |
| |
| return XST_SUCCESS; |
| } |
| |
| /****************************************************************************/ |
| /** |
| * |
| * Stops the controller so that Device disconnects from Host. |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance. |
| * |
| * @return XST_SUCCESS else XST_FAILURE |
| * |
| * @note None. |
| * |
| *****************************************************************************/ |
| s32 XUsbPsu_Stop(struct XUsbPsu *InstancePtr) |
| { |
| u32 RegVal; |
| |
| Xil_AssertNonvoid(InstancePtr != NULL); |
| |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCTL); |
| RegVal &= ~XUSBPSU_DCTL_RUN_STOP; |
| |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCTL, RegVal); |
| |
| if (XUsbPsu_Wait_Set_Timeout(InstancePtr, XUSBPSU_DSTS, |
| XUSBPSU_DSTS_DEVCTRLHLT, 500U) == XST_FAILURE) { |
| return XST_FAILURE; |
| } |
| |
| return XST_SUCCESS; |
| } |
| |
| /****************************************************************************/ |
| /** |
| * Enables USB2 Test Modes |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance. |
| * @param Mode is Test mode to set. |
| * |
| * @return XST_SUCCESS else XST_FAILURE |
| * |
| * @note None. |
| * |
| ****************************************************************************/ |
| s32 XUsbPsu_SetTestMode(struct XUsbPsu *InstancePtr, u32 Mode) |
| { |
| u32 RegVal; |
| s32 Status = XST_SUCCESS; |
| |
| Xil_AssertNonvoid(InstancePtr != NULL); |
| Xil_AssertNonvoid((Mode >= XUSBPSU_TEST_J) |
| && (Mode <= XUSBPSU_TEST_FORCE_ENABLE)); |
| |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCTL); |
| RegVal &= ~XUSBPSU_DCTL_TSTCTRL_MASK; |
| |
| switch (Mode) { |
| case XUSBPSU_TEST_J: |
| case XUSBPSU_TEST_K: |
| case XUSBPSU_TEST_SE0_NAK: |
| case XUSBPSU_TEST_PACKET: |
| case XUSBPSU_TEST_FORCE_ENABLE: |
| RegVal |= (u32)Mode << 1; |
| break; |
| |
| default: |
| Status = (s32)XST_FAILURE; |
| break; |
| } |
| |
| if (Status != (s32)XST_FAILURE) { |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCTL, RegVal); |
| Status = XST_SUCCESS; |
| } |
| |
| return Status; |
| } |
| |
| /****************************************************************************/ |
| /** |
| * Gets current State of USB Link |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance. |
| * |
| * @return Link State |
| * |
| * @note None. |
| * |
| ****************************************************************************/ |
| XusbPsuLinkState XUsbPsu_GetLinkState(struct XUsbPsu *InstancePtr) |
| { |
| u32 RegVal; |
| |
| Xil_AssertNonvoid(InstancePtr != NULL); |
| |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DSTS); |
| |
| return XUSBPSU_DSTS_USBLNKST(RegVal); |
| } |
| |
| /****************************************************************************/ |
| /** |
| * Sets USB Link to a particular State |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance. |
| * @param State is State of Link to set. |
| * |
| * @return XST_SUCCESS else XST_FAILURE |
| * |
| * @note None. |
| * |
| ****************************************************************************/ |
| s32 XUsbPsu_SetLinkState(struct XUsbPsu *InstancePtr, |
| XusbPsuLinkStateChange State) |
| { |
| u32 RegVal; |
| |
| Xil_AssertNonvoid(InstancePtr != NULL); |
| |
| /* Wait until device controller is ready. */ |
| if (XUsbPsu_Wait_Clear_Timeout(InstancePtr, XUSBPSU_DSTS, |
| XUSBPSU_DSTS_DCNRD, 500U) == XST_FAILURE) { |
| return XST_FAILURE; |
| } |
| |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCTL); |
| RegVal &= ~XUSBPSU_DCTL_ULSTCHNGREQ_MASK; |
| |
| RegVal |= XUSBPSU_DCTL_ULSTCHNGREQ(State); |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCTL, RegVal); |
| |
| return XST_SUCCESS; |
| } |
| |
| /****************************************************************************/ |
| /** |
| * Sets speed of the Core for connecting to Host |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance. |
| * @param Speed is required speed |
| * - XUSBPSU_DCFG_HIGHSPEED |
| * - XUSBPSU_DCFG_FULLSPEED2 |
| * - XUSBPSU_DCFG_LOWSPEED |
| * - XUSBPSU_DCFG_FULLSPEED1 |
| * |
| * @return None |
| * |
| * @note None. |
| * |
| *****************************************************************************/ |
| void XUsbPsu_SetSpeed(struct XUsbPsu *InstancePtr, u32 Speed) |
| { |
| u32 RegVal; |
| |
| Xil_AssertVoid(InstancePtr != NULL); |
| Xil_AssertVoid(Speed <= (u32)XUSBPSU_DCFG_SUPERSPEED); |
| |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCFG); |
| RegVal &= ~(XUSBPSU_DCFG_SPEED_MASK); |
| RegVal |= Speed; |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCFG, RegVal); |
| } |
| |
| /****************************************************************************/ |
| /** |
| * Sets Device Address of the Core |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance. |
| * @param Addr is address to set. |
| * |
| * @return XST_SUCCESS else XST_FAILURE |
| * |
| * @note None. |
| * |
| *****************************************************************************/ |
| s32 XUsbPsu_SetDeviceAddress(struct XUsbPsu *InstancePtr, u16 Addr) |
| { |
| u32 RegVal; |
| |
| Xil_AssertNonvoid(InstancePtr != NULL); |
| Xil_AssertNonvoid(Addr <= 127U); |
| |
| if (InstancePtr->State == XUSBPSU_STATE_CONFIGURED) { |
| return XST_FAILURE; |
| } |
| |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCFG); |
| RegVal &= ~(XUSBPSU_DCFG_DEVADDR_MASK); |
| RegVal |= XUSBPSU_DCFG_DEVADDR(Addr); |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCFG, RegVal); |
| |
| if (Addr) { |
| InstancePtr->State = XUSBPSU_STATE_ADDRESS; |
| } |
| else { |
| InstancePtr->State = XUSBPSU_STATE_DEFAULT; |
| } |
| |
| return XST_SUCCESS; |
| } |
| |
| /****************************************************************************/ |
| /** |
| * Sets speed of the Core for connecting to Host |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance. |
| * |
| * @return XST_SUCCESS else XST_FAILURE |
| * |
| * @note None. |
| * |
| *****************************************************************************/ |
| s32 XUsbPsu_IsSuperSpeed(struct XUsbPsu *InstancePtr) |
| { |
| if (InstancePtr->Speed != XUSBPSU_SPEED_SUPER) { |
| return XST_FAILURE; |
| } |
| |
| return XST_SUCCESS; |
| } |
| |
| /****************************************************************************/ |
| /** |
| * Set U1 sleep timeout |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance. |
| * @param Sleep is time in microseconds |
| * |
| * @return XST_SUCCESS else XST_FAILURE |
| * |
| * @note None. |
| * |
| *****************************************************************************/ |
| s32 XUsbPsu_SetU1SleepTimeout(struct XUsbPsu *InstancePtr, u8 Sleep) |
| { |
| u32 RegVal; |
| |
| Xil_AssertNonvoid(InstancePtr != NULL); |
| |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_PORTMSC_30); |
| RegVal &= ~XUSBPSU_PORTMSC_30_U1_TIMEOUT_MASK; |
| RegVal |= (Sleep << XUSBPSU_PORTMSC_30_U1_TIMEOUT_SHIFT); |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_PORTMSC_30, RegVal); |
| |
| return XST_SUCCESS; |
| } |
| |
| /****************************************************************************/ |
| /** |
| * Set U2 sleep timeout |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance. |
| * @param Sleep is time in microseconds |
| * |
| * @return XST_SUCCESS else XST_FAILURE |
| * |
| * @note None. |
| * |
| *****************************************************************************/ |
| s32 XUsbPsu_SetU2SleepTimeout(struct XUsbPsu *InstancePtr, u8 Sleep) |
| { |
| u32 RegVal; |
| |
| Xil_AssertNonvoid(InstancePtr != NULL); |
| |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_PORTMSC_30); |
| RegVal &= ~XUSBPSU_PORTMSC_30_U2_TIMEOUT_MASK; |
| RegVal |= (Sleep << XUSBPSU_PORTMSC_30_U2_TIMEOUT_SHIFT); |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_PORTMSC_30, RegVal); |
| |
| return XST_SUCCESS; |
| } |
| /****************************************************************************/ |
| /** |
| * Enable Accept U1 and U2 sleep enable |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance. |
| * |
| * @return XST_SUCCESS else XST_FAILURE |
| * |
| * @note None. |
| * |
| *****************************************************************************/ |
| s32 XUsbPsu_AcceptU1U2Sleep(struct XUsbPsu *InstancePtr) |
| { |
| u32 RegVal; |
| |
| Xil_AssertNonvoid(InstancePtr != NULL); |
| |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCTL); |
| RegVal |= XUSBPSU_DCTL_ACCEPTU2ENA | XUSBPSU_DCTL_ACCEPTU1ENA; |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCTL, RegVal); |
| |
| return XST_SUCCESS; |
| } |
| |
| /****************************************************************************/ |
| /** |
| * Enable U1 enable sleep |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance. |
| * |
| * @return XST_SUCCESS else XST_FAILURE |
| * |
| * @note None. |
| * |
| *****************************************************************************/ |
| s32 XUsbPsu_U1SleepEnable(struct XUsbPsu *InstancePtr) |
| { |
| u32 RegVal; |
| |
| Xil_AssertNonvoid(InstancePtr != NULL); |
| |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCTL); |
| RegVal |= XUSBPSU_DCTL_INITU1ENA; |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCTL, RegVal); |
| |
| return XST_SUCCESS; |
| } |
| |
| /****************************************************************************/ |
| /** |
| * Enable U2 enable sleep |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance. |
| * |
| * @return XST_SUCCESS else XST_FAILURE |
| * |
| * @note None. |
| * |
| *****************************************************************************/ |
| s32 XUsbPsu_U2SleepEnable(struct XUsbPsu *InstancePtr) |
| { |
| u32 RegVal; |
| |
| Xil_AssertNonvoid(InstancePtr != NULL); |
| |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCTL); |
| RegVal |= XUSBPSU_DCTL_INITU2ENA; |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCTL, RegVal); |
| |
| return XST_SUCCESS; |
| } |
| |
| /****************************************************************************/ |
| /** |
| * Enable U1 disable sleep |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance. |
| * |
| * @return XST_SUCCESS else XST_FAILURE |
| * |
| * @note None. |
| * |
| *****************************************************************************/ |
| s32 XUsbPsu_U1SleepDisable(struct XUsbPsu *InstancePtr) |
| { |
| u32 RegVal; |
| |
| Xil_AssertNonvoid(InstancePtr != NULL); |
| |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCTL); |
| RegVal &= ~XUSBPSU_DCTL_INITU1ENA; |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCTL, RegVal); |
| |
| return XST_SUCCESS; |
| } |
| |
| /****************************************************************************/ |
| /** |
| * Enable U2 disable sleep |
| * |
| * @param InstancePtr is a pointer to the XUsbPsu instance. |
| * |
| * @return XST_SUCCESS else XST_FAILURE |
| * |
| * @note None. |
| * |
| *****************************************************************************/ |
| s32 XUsbPsu_U2SleepDisable(struct XUsbPsu *InstancePtr) |
| { |
| u32 RegVal; |
| |
| Xil_AssertNonvoid(InstancePtr != NULL); |
| |
| RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCTL); |
| RegVal &= ~XUSBPSU_DCTL_INITU2ENA; |
| XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCTL, RegVal); |
| |
| return XST_SUCCESS; |
| } |
| /** @} */ |