1 /******************************************************************************
3 * Copyright (C) 2010 - 2015 Xilinx, Inc. All rights reserved.
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
15 * Use of the Software is limited solely to applications:
16 * (a) running on a Xilinx device, or
17 * (b) that interact with a Xilinx device through a bus or interconnect.
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * XILINX BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
24 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
27 * Except as contained in this notice, the name of the Xilinx shall not be used
28 * in advertising or otherwise to promote the sale, use or other dealings in
29 * this Software without prior written authorization from Xilinx.
31 ******************************************************************************/
32 /******************************************************************************/
35 * @addtogroup usbps_v2_2
38 * The XUsbPs driver. Functions in this file are the minimum required
39 * functions for this driver. See xusbps.h for a detailed description of the
45 * MODIFICATION HISTORY:
47 * Ver Who Date Changes
48 * ----- ---- -------- --------------------------------------------------------
49 * 1.00a jz 10/10/10 First release
50 * 2.1 kpc 04/28/14 Removed ununsed functions
52 ******************************************************************************/
54 /***************************** Include Files **********************************/
58 /************************** Constant Definitions ******************************/
60 /**************************** Type Definitions ********************************/
62 /***************** Macros (Inline Functions) Definitions **********************/
64 /************************** Variable Definitions ******************************/
66 /************************** Function Prototypes *******************************/
68 /*****************************************************************************/
71 * This function initializes a XUsbPs instance/driver.
73 * The initialization entails:
74 * - Initialize all members of the XUsbPs structure.
76 * @param InstancePtr is a pointer to XUsbPs instance of the controller.
77 * @param ConfigPtr is a pointer to a XUsbPs_Config configuration
78 * structure. This structure will contain the requested
79 * configuration for the device. Typically, this is a local
80 * structure and the content of which will be copied into the
81 * configuration structure within XUsbPs.
82 * @param VirtBaseAddress is the base address of the device. For systems
83 * with virtual memory, this address must be the virtual address
85 * For systems that do not support virtual memory this address
86 * should be the physical address of the device. For backwards
87 * compatibilty NULL may be passed in systems that do not support
88 * virtual memory (deprecated).
91 * - XST_SUCCESS no errors occured.
92 * - XST_FAILURE an error occured during initialization.
95 * After calling XUsbPs_CfgInitialize() the controller
96 * IS NOT READY for use. Before the controller can be used its
97 * DEVICE parameters must be configured. See xusbps.h
100 ******************************************************************************/
101 int XUsbPs_CfgInitialize(XUsbPs *InstancePtr,
102 const XUsbPs_Config *ConfigPtr, u32 VirtBaseAddress)
104 Xil_AssertNonvoid(InstancePtr != NULL);
105 Xil_AssertNonvoid(ConfigPtr != NULL);
107 /* Copy the config structure. */
108 InstancePtr->Config = *ConfigPtr;
110 /* Check if the user provided a non-NULL base address. If so, we have
111 * to overwrite the base address in the configuration structure.
113 if (0 != VirtBaseAddress) {
114 InstancePtr->Config.BaseAddress = VirtBaseAddress;
117 /* Initialize the XUsbPs structure to default values. */
118 InstancePtr->CurrentAltSetting = XUSBPS_DEFAULT_ALT_SETTING;
120 InstancePtr->HandlerFunc = NULL;
125 /*****************************************************************************/
128 * This function performs device reset, device is stopped at the end.
130 * @param InstancePtr is a pointer to XUsbPs instance of the controller.
136 ******************************************************************************/
137 void XUsbPs_DeviceReset(XUsbPs *InstancePtr)
141 /* Clear all setup token semaphores by reading the
142 * XUSBPS_EPSTAT_OFFSET register and writing its value back to
145 XUsbPs_WriteReg(InstancePtr->Config.BaseAddress, XUSBPS_EPSTAT_OFFSET,
146 XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
147 XUSBPS_EPSTAT_OFFSET));
149 /* Clear all the endpoint complete status bits by reading the
150 * XUSBPS_EPCOMPL_OFFSET register and writings its value back
153 XUsbPs_WriteReg(InstancePtr->Config.BaseAddress, XUSBPS_EPCOMPL_OFFSET,
154 XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
155 XUSBPS_EPCOMPL_OFFSET));
157 /* Cancel all endpoint prime status by waiting until all bits
158 * in XUSBPS_EPPRIME_OFFSET are 0 and then writing 0xFFFFFFFF
159 * to XUSBPS_EPFLUSH_OFFSET.
161 * Avoid hanging here by using a Timeout counter...
163 Timeout = XUSBPS_TIMEOUT_COUNTER;
164 while ((XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
165 XUSBPS_EPPRIME_OFFSET) &
166 XUSBPS_EP_ALL_MASK) && --Timeout) {
169 XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
170 XUSBPS_EPFLUSH_OFFSET, 0xFFFFFFFF);
172 XUsbPs_Stop(InstancePtr);
174 /* Write to CR register for controller reset */
175 XUsbPs_WriteReg(InstancePtr->Config.BaseAddress, XUSBPS_CMD_OFFSET,
176 XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
177 XUSBPS_CMD_OFFSET) | XUSBPS_CMD_RST_MASK);
179 /* Wait for reset to finish, hardware clears the reset bit once done */
181 while((XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
183 XUSBPS_CMD_RST_MASK) && --Timeout) {
187 /*****************************************************************************/
190 * This function resets the USB device. All the configuration registers are
191 * reset to their default values. The function waits until the reset operation
192 * is complete or for a certain duration within which the reset operation is
193 * expected to be completed.
195 * @param InstancePtr is a pointer to XUsbPs instance of the controller.
198 * - XST_SUCCESS Reset operation completed successfully.
199 * - XST_FAILURE Reset operation timed out.
203 ******************************************************************************/
204 int XUsbPs_Reset(XUsbPs *InstancePtr)
208 Xil_AssertNonvoid(InstancePtr != NULL);
210 /* Write a 1 to the RESET bit. The RESET bit is cleared by HW once the
213 * We are going to wait for the RESET bit to clear before we return
214 * from this function. Unfortunately we do not have timers available at
215 * this point to determine when we should report a Timeout.
217 * However, by using a large number for the poll loop we can assume
218 * that the polling operation will take longer than the expected time
219 * the HW needs to RESET. If the poll loop expires we can assume a
220 * Timeout. The drawback is that on a slow system (and even on a fast
221 * system) this can lead to _very_ long Timeout periods.
223 XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
224 XUSBPS_CMD_OFFSET, XUSBPS_CMD_RST_MASK);
227 /* Wait for the RESET bit to be cleared by HW. */
228 Timeout = XUSBPS_TIMEOUT_COUNTER;
229 while ((XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
231 XUSBPS_CMD_RST_MASK) && --Timeout) {
242 /*****************************************************************************/
246 * In order to conserve power, USB devices automatically enter the suspended
247 * state when the device has observed no bus traffic for a specified period.
248 * When suspended, the USB device maintains any internal status, including its
249 * address and configuration. Attached devices must be prepared to suspend at
250 * any time they are powered, regardless of if they have been assigned a
251 * non-default address, are configured, or neither. Bus activity may cease due
252 * to the host entering a suspend mode of its own. In addition, a USB device
253 * shall also enter the suspended state when the hub port it is attached to is
256 * A USB device exits suspend mode when there is bus activity. A USB device may
257 * also request the host to exit suspend mode or selective suspend by using
258 * electrical signaling to indicate remote wakeup. The ability of a device to
259 * signal remote wakeup is optional. If the USB device is capable of remote
260 * wakeup signaling, the device must support the ability of the host to enable
261 * and disable this capability. When the device is reset, remote wakeup
262 * signaling must be disabled.
264 * @param InstancePtr is a pointer to XUsbPs instance of the controller.
267 * - XST_SUCCESS if the USB device has entered Suspend mode
269 * - XST_FAILURE on any error
273 ******************************************************************************/
274 int XUsbPs_Suspend(const XUsbPs *InstancePtr)
282 /*****************************************************************************/
286 If the USB controller is suspended, its operation is resumed when any
287 * non-idle signaling is received on its upstream facing port.
289 * @param InstancePtr is a pointer to XUsbPs instance of the controller.
292 * - XST_SUCCESS if the USB device has Resumed successfully
293 * - XST_FAILURE on any error
297 ******************************************************************************/
298 int XUsbPs_Resume(const XUsbPs *InstancePtr)
305 /*****************************************************************************/
309 * @param InstancePtr is a pointer to XUsbPs instance of the controller.
312 * - XST_SUCCESS if the USB device has Resumed successfully
313 * - XST_FAILURE on any error
317 ******************************************************************************/
319 int XUsbPs_RequestHostResume(const XUsbPs *InstancePtr)
325 /****************************************************************************/
327 * This functions sets the controller's DEVICE address. It also sets the
328 * advance bit so the controller will wait for the next IN-ACK before the new
329 * address takes effect.
331 * @param InstancePtr is a pointer to XUsbPs instance of the controller.
332 * @param Address is the Address of the device.
335 * - XST_SUCCESS: Address set successfully.
336 * - XST_FAILURE: An error occured.
337 * - XST_INVALID_PARAM: Invalid parameter passed, e.g. address
342 *****************************************************************************/
343 int XUsbPs_SetDeviceAddress(XUsbPs *InstancePtr, u8 Address)
345 Xil_AssertNonvoid(InstancePtr != NULL);
347 /* Check address range validity. */
348 if (Address > XUSBPS_DEVICEADDR_MAX) {
349 return XST_INVALID_PARAM;
352 /* Set the address register with the Address value provided. Also set
353 * the Address Advance Bit. This will cause the address to be set only
354 * after an IN occured and has been ACKed on the endpoint.
356 XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
357 XUSBPS_DEVICEADDR_OFFSET,
358 (Address << XUSBPS_DEVICEADDR_ADDR_SHIFT) |
359 XUSBPS_DEVICEADDR_DEVICEAADV_MASK);