| /****************************************************************************** |
| * |
| * Copyright (C) 2010 - 2015 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 xusbps.c |
| * @addtogroup usbps_v2_2 |
| * @{ |
| * |
| * The XUsbPs driver. Functions in this file are the minimum required |
| * functions for this driver. See xusbps.h for a detailed description of the |
| * driver. |
| * |
| * @note None. |
| * |
| * <pre> |
| * MODIFICATION HISTORY: |
| * |
| * Ver Who Date Changes |
| * ----- ---- -------- -------------------------------------------------------- |
| * 1.00a jz 10/10/10 First release |
| * 2.1 kpc 04/28/14 Removed ununsed functions |
| * </pre> |
| ******************************************************************************/ |
| |
| /***************************** Include Files **********************************/ |
| #include <stdio.h> |
| #include "xusbps.h" |
| |
| /************************** Constant Definitions ******************************/ |
| |
| /**************************** Type Definitions ********************************/ |
| |
| /***************** Macros (Inline Functions) Definitions **********************/ |
| |
| /************************** Variable Definitions ******************************/ |
| |
| /************************** Function Prototypes *******************************/ |
| |
| /*****************************************************************************/ |
| /** |
| * |
| * This function initializes a XUsbPs instance/driver. |
| * |
| * The initialization entails: |
| * - Initialize all members of the XUsbPs structure. |
| * |
| * @param InstancePtr is a pointer to XUsbPs instance of the controller. |
| * @param ConfigPtr is a pointer to a XUsbPs_Config configuration |
| * structure. This structure will contain the requested |
| * configuration for the device. Typically, this is a local |
| * structure and the content of which will be copied into the |
| * configuration structure within XUsbPs. |
| * @param VirtBaseAddress is the base address of the device. For systems |
| * with virtual memory, this address must be the virtual address |
| * of the device. |
| * For systems that do not support virtual memory this address |
| * should be the physical address of the device. For backwards |
| * compatibilty NULL may be passed in systems that do not support |
| * virtual memory (deprecated). |
| * |
| * @return |
| * - XST_SUCCESS no errors occured. |
| * - XST_FAILURE an error occured during initialization. |
| * |
| * @note |
| * After calling XUsbPs_CfgInitialize() the controller |
| * IS NOT READY for use. Before the controller can be used its |
| * DEVICE parameters must be configured. See xusbps.h |
| * for details. |
| * |
| ******************************************************************************/ |
| int XUsbPs_CfgInitialize(XUsbPs *InstancePtr, |
| const XUsbPs_Config *ConfigPtr, u32 VirtBaseAddress) |
| { |
| Xil_AssertNonvoid(InstancePtr != NULL); |
| Xil_AssertNonvoid(ConfigPtr != NULL); |
| |
| /* Copy the config structure. */ |
| InstancePtr->Config = *ConfigPtr; |
| |
| /* Check if the user provided a non-NULL base address. If so, we have |
| * to overwrite the base address in the configuration structure. |
| */ |
| if (0 != VirtBaseAddress) { |
| InstancePtr->Config.BaseAddress = VirtBaseAddress; |
| } |
| |
| /* Initialize the XUsbPs structure to default values. */ |
| InstancePtr->CurrentAltSetting = XUSBPS_DEFAULT_ALT_SETTING; |
| |
| InstancePtr->HandlerFunc = NULL; |
| |
| return XST_SUCCESS; |
| } |
| |
| /*****************************************************************************/ |
| /** |
| * |
| * This function performs device reset, device is stopped at the end. |
| * |
| * @param InstancePtr is a pointer to XUsbPs instance of the controller. |
| * |
| * @return None. |
| * |
| * @note None. |
| * |
| ******************************************************************************/ |
| void XUsbPs_DeviceReset(XUsbPs *InstancePtr) |
| { |
| int Timeout; |
| |
| /* Clear all setup token semaphores by reading the |
| * XUSBPS_EPSTAT_OFFSET register and writing its value back to |
| * itself. |
| */ |
| XUsbPs_WriteReg(InstancePtr->Config.BaseAddress, XUSBPS_EPSTAT_OFFSET, |
| XUsbPs_ReadReg(InstancePtr->Config.BaseAddress, |
| XUSBPS_EPSTAT_OFFSET)); |
| |
| /* Clear all the endpoint complete status bits by reading the |
| * XUSBPS_EPCOMPL_OFFSET register and writings its value back |
| * to itself. |
| */ |
| XUsbPs_WriteReg(InstancePtr->Config.BaseAddress, XUSBPS_EPCOMPL_OFFSET, |
| XUsbPs_ReadReg(InstancePtr->Config.BaseAddress, |
| XUSBPS_EPCOMPL_OFFSET)); |
| |
| /* Cancel all endpoint prime status by waiting until all bits |
| * in XUSBPS_EPPRIME_OFFSET are 0 and then writing 0xFFFFFFFF |
| * to XUSBPS_EPFLUSH_OFFSET. |
| * |
| * Avoid hanging here by using a Timeout counter... |
| */ |
| Timeout = XUSBPS_TIMEOUT_COUNTER; |
| while ((XUsbPs_ReadReg(InstancePtr->Config.BaseAddress, |
| XUSBPS_EPPRIME_OFFSET) & |
| XUSBPS_EP_ALL_MASK) && --Timeout) { |
| /* NOP */ |
| } |
| XUsbPs_WriteReg(InstancePtr->Config.BaseAddress, |
| XUSBPS_EPFLUSH_OFFSET, 0xFFFFFFFF); |
| |
| XUsbPs_Stop(InstancePtr); |
| |
| /* Write to CR register for controller reset */ |
| XUsbPs_WriteReg(InstancePtr->Config.BaseAddress, XUSBPS_CMD_OFFSET, |
| XUsbPs_ReadReg(InstancePtr->Config.BaseAddress, |
| XUSBPS_CMD_OFFSET) | XUSBPS_CMD_RST_MASK); |
| |
| /* Wait for reset to finish, hardware clears the reset bit once done */ |
| Timeout = 1000000; |
| while((XUsbPs_ReadReg(InstancePtr->Config.BaseAddress, |
| XUSBPS_CMD_OFFSET) & |
| XUSBPS_CMD_RST_MASK) && --Timeout) { |
| /* NOP */ |
| } |
| } |
| /*****************************************************************************/ |
| /** |
| * |
| * This function resets the USB device. All the configuration registers are |
| * reset to their default values. The function waits until the reset operation |
| * is complete or for a certain duration within which the reset operation is |
| * expected to be completed. |
| * |
| * @param InstancePtr is a pointer to XUsbPs instance of the controller. |
| * |
| * @return |
| * - XST_SUCCESS Reset operation completed successfully. |
| * - XST_FAILURE Reset operation timed out. |
| * |
| * @note None. |
| * |
| ******************************************************************************/ |
| int XUsbPs_Reset(XUsbPs *InstancePtr) |
| { |
| int Timeout; |
| |
| Xil_AssertNonvoid(InstancePtr != NULL); |
| |
| /* Write a 1 to the RESET bit. The RESET bit is cleared by HW once the |
| * RESET is complete. |
| * |
| * We are going to wait for the RESET bit to clear before we return |
| * from this function. Unfortunately we do not have timers available at |
| * this point to determine when we should report a Timeout. |
| * |
| * However, by using a large number for the poll loop we can assume |
| * that the polling operation will take longer than the expected time |
| * the HW needs to RESET. If the poll loop expires we can assume a |
| * Timeout. The drawback is that on a slow system (and even on a fast |
| * system) this can lead to _very_ long Timeout periods. |
| */ |
| XUsbPs_WriteReg(InstancePtr->Config.BaseAddress, |
| XUSBPS_CMD_OFFSET, XUSBPS_CMD_RST_MASK); |
| |
| |
| /* Wait for the RESET bit to be cleared by HW. */ |
| Timeout = XUSBPS_TIMEOUT_COUNTER; |
| while ((XUsbPs_ReadReg(InstancePtr->Config.BaseAddress, |
| XUSBPS_CMD_OFFSET) & |
| XUSBPS_CMD_RST_MASK) && --Timeout) { |
| /* NOP */ |
| } |
| |
| if (0 == Timeout) { |
| return XST_FAILURE; |
| } |
| |
| return XST_SUCCESS; |
| } |
| |
| /*****************************************************************************/ |
| /** |
| * USB Suspend |
| * |
| * In order to conserve power, USB devices automatically enter the suspended |
| * state when the device has observed no bus traffic for a specified period. |
| * When suspended, the USB device maintains any internal status, including its |
| * address and configuration. Attached devices must be prepared to suspend at |
| * any time they are powered, regardless of if they have been assigned a |
| * non-default address, are configured, or neither. Bus activity may cease due |
| * to the host entering a suspend mode of its own. In addition, a USB device |
| * shall also enter the suspended state when the hub port it is attached to is |
| * disabled. |
| * |
| * A USB device exits suspend mode when there is bus activity. A USB device may |
| * also request the host to exit suspend mode or selective suspend by using |
| * electrical signaling to indicate remote wakeup. The ability of a device to |
| * signal remote wakeup is optional. If the USB device is capable of remote |
| * wakeup signaling, the device must support the ability of the host to enable |
| * and disable this capability. When the device is reset, remote wakeup |
| * signaling must be disabled. |
| * |
| * @param InstancePtr is a pointer to XUsbPs instance of the controller. |
| * |
| * @return |
| * - XST_SUCCESS if the USB device has entered Suspend mode |
| * successfully |
| * - XST_FAILURE on any error |
| * |
| * @note None. |
| * |
| ******************************************************************************/ |
| int XUsbPs_Suspend(const XUsbPs *InstancePtr) |
| { |
| (void) InstancePtr; |
| |
| return XST_SUCCESS; |
| } |
| |
| |
| /*****************************************************************************/ |
| /** |
| * USB Resume |
| * |
| If the USB controller is suspended, its operation is resumed when any |
| * non-idle signaling is received on its upstream facing port. |
| * |
| * @param InstancePtr is a pointer to XUsbPs instance of the controller. |
| * |
| * @return |
| * - XST_SUCCESS if the USB device has Resumed successfully |
| * - XST_FAILURE on any error |
| * |
| * @note None. |
| * |
| ******************************************************************************/ |
| int XUsbPs_Resume(const XUsbPs *InstancePtr) |
| { |
| (void) InstancePtr; |
| return XST_SUCCESS; |
| } |
| |
| |
| /*****************************************************************************/ |
| /** |
| * USB Assert Resume |
| * |
| * @param InstancePtr is a pointer to XUsbPs instance of the controller. |
| * |
| * @return |
| * - XST_SUCCESS if the USB device has Resumed successfully |
| * - XST_FAILURE on any error |
| * |
| * @note None. |
| * |
| ******************************************************************************/ |
| |
| int XUsbPs_RequestHostResume(const XUsbPs *InstancePtr) |
| { |
| (void) InstancePtr; |
| return XST_SUCCESS; |
| } |
| |
| /****************************************************************************/ |
| /** |
| * This functions sets the controller's DEVICE address. It also sets the |
| * advance bit so the controller will wait for the next IN-ACK before the new |
| * address takes effect. |
| * |
| * @param InstancePtr is a pointer to XUsbPs instance of the controller. |
| * @param Address is the Address of the device. |
| * |
| * @return |
| * - XST_SUCCESS: Address set successfully. |
| * - XST_FAILURE: An error occured. |
| * - XST_INVALID_PARAM: Invalid parameter passed, e.g. address |
| * value too big. |
| * |
| * @note None. |
| * |
| *****************************************************************************/ |
| int XUsbPs_SetDeviceAddress(XUsbPs *InstancePtr, u8 Address) |
| { |
| Xil_AssertNonvoid(InstancePtr != NULL); |
| |
| /* Check address range validity. */ |
| if (Address > XUSBPS_DEVICEADDR_MAX) { |
| return XST_INVALID_PARAM; |
| } |
| |
| /* Set the address register with the Address value provided. Also set |
| * the Address Advance Bit. This will cause the address to be set only |
| * after an IN occured and has been ACKed on the endpoint. |
| */ |
| XUsbPs_WriteReg(InstancePtr->Config.BaseAddress, |
| XUSBPS_DEVICEADDR_OFFSET, |
| (Address << XUSBPS_DEVICEADDR_ADDR_SHIFT) | |
| XUSBPS_DEVICEADDR_DEVICEAADV_MASK); |
| |
| return XST_SUCCESS; |
| } |
| |
| /** @} */ |