]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A9_Zynq_ZC702/RTOSDemo_bsp/ps7_cortexa9_0/libsrc/usbps_v2_3/src/xusbps.c
xTaskGenericNotify() now sets xYieldPending to pdTRUE even when the 'higher priority...
[freertos] / FreeRTOS / Demo / CORTEX_A9_Zynq_ZC702 / RTOSDemo_bsp / ps7_cortexa9_0 / libsrc / usbps_v2_3 / src / xusbps.c
1 /******************************************************************************
2 *
3 * Copyright (C) 2010 - 2015 Xilinx, Inc.  All rights reserved.
4 *
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:
11 *
12 * The above copyright notice and this permission notice shall be included in
13 * all copies or substantial portions of the Software.
14 *
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.
18 *
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
25 * SOFTWARE.
26 *
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.
30 *
31 ******************************************************************************/
32 /******************************************************************************/
33 /**
34  * @file xusbps.c
35 * @addtogroup usbps_v2_2
36 * @{
37  *
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
40  * driver.
41  *
42  * @note        None.
43  *
44  * <pre>
45  * MODIFICATION HISTORY:
46  *
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
51  * </pre>
52  ******************************************************************************/
53
54 /***************************** Include Files **********************************/
55 #include <stdio.h>
56 #include "xusbps.h"
57
58 /************************** Constant Definitions ******************************/
59
60 /**************************** Type Definitions ********************************/
61
62 /***************** Macros (Inline Functions) Definitions **********************/
63
64 /************************** Variable Definitions ******************************/
65
66 /************************** Function Prototypes *******************************/
67
68 /*****************************************************************************/
69 /**
70 *
71 * This function initializes a XUsbPs instance/driver.
72 *
73 * The initialization entails:
74 * - Initialize all members of the XUsbPs structure.
75 *
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
84 *               of the device.
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).
89 *
90 * @return
91 *               - XST_SUCCESS no errors occured.
92 *               - XST_FAILURE an error occured during initialization.
93 *
94 * @note
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
98 *               for details.
99 *
100 ******************************************************************************/
101 int XUsbPs_CfgInitialize(XUsbPs *InstancePtr,
102                           const XUsbPs_Config *ConfigPtr, u32 VirtBaseAddress)
103 {
104         Xil_AssertNonvoid(InstancePtr != NULL);
105         Xil_AssertNonvoid(ConfigPtr   != NULL);
106
107         /* Copy the config structure. */
108         InstancePtr->Config = *ConfigPtr;
109
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.
112          */
113         if (0 != VirtBaseAddress) {
114                 InstancePtr->Config.BaseAddress = VirtBaseAddress;
115         }
116
117         /* Initialize the XUsbPs structure to default values. */
118         InstancePtr->CurrentAltSetting  = XUSBPS_DEFAULT_ALT_SETTING;
119
120         InstancePtr->HandlerFunc        = NULL;
121
122         return XST_SUCCESS;
123 }
124
125 /*****************************************************************************/
126 /**
127 *
128 * This function performs device reset, device is stopped at the end.
129 *
130 * @param        InstancePtr is a pointer to XUsbPs instance of the controller.
131 *
132 * @return       None.
133 *
134 * @note         None.
135 *
136 ******************************************************************************/
137 void XUsbPs_DeviceReset(XUsbPs *InstancePtr)
138 {
139         int Timeout;
140
141         /* Clear all setup token semaphores by reading the
142          * XUSBPS_EPSTAT_OFFSET register and writing its value back to
143          * itself.
144          */
145         XUsbPs_WriteReg(InstancePtr->Config.BaseAddress, XUSBPS_EPSTAT_OFFSET,
146                 XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
147                         XUSBPS_EPSTAT_OFFSET));
148
149         /* Clear all the endpoint complete status bits by reading the
150          * XUSBPS_EPCOMPL_OFFSET register and writings its value back
151          * to itself.
152          */
153         XUsbPs_WriteReg(InstancePtr->Config.BaseAddress, XUSBPS_EPCOMPL_OFFSET,
154                 XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
155                         XUSBPS_EPCOMPL_OFFSET));
156
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.
160          *
161          * Avoid hanging here by using a Timeout counter...
162          */
163         Timeout = XUSBPS_TIMEOUT_COUNTER;
164         while ((XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
165                                 XUSBPS_EPPRIME_OFFSET) &
166                                 XUSBPS_EP_ALL_MASK) && --Timeout) {
167                 /* NOP */
168         }
169         XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
170                                 XUSBPS_EPFLUSH_OFFSET, 0xFFFFFFFF);
171
172         XUsbPs_Stop(InstancePtr);
173
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);
178
179         /* Wait for reset to finish, hardware clears the reset bit once done  */
180         Timeout = 1000000;
181         while((XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
182                                 XUSBPS_CMD_OFFSET) &
183                                 XUSBPS_CMD_RST_MASK) && --Timeout) {
184                 /* NOP */
185         }
186 }
187 /*****************************************************************************/
188 /**
189 *
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.
194 *
195 * @param        InstancePtr is a pointer to XUsbPs instance of the controller.
196 *
197 * @return
198 *               - XST_SUCCESS Reset operation completed successfully.
199 *               - XST_FAILURE Reset operation timed out.
200 *
201 * @note         None.
202 *
203 ******************************************************************************/
204 int XUsbPs_Reset(XUsbPs *InstancePtr)
205 {
206         int Timeout;
207
208         Xil_AssertNonvoid(InstancePtr != NULL);
209
210         /* Write a 1 to the RESET bit. The RESET bit is cleared by HW once the
211          * RESET is complete.
212          *
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.
216          *
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.
222          */
223         XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
224                                 XUSBPS_CMD_OFFSET, XUSBPS_CMD_RST_MASK);
225
226
227         /* Wait for the RESET bit to be cleared by HW. */
228         Timeout = XUSBPS_TIMEOUT_COUNTER;
229         while ((XUsbPs_ReadReg(InstancePtr->Config.BaseAddress,
230                                 XUSBPS_CMD_OFFSET) &
231                                 XUSBPS_CMD_RST_MASK) && --Timeout) {
232                 /* NOP */
233         }
234
235         if (0 == Timeout) {
236                 return XST_FAILURE;
237         }
238
239         return XST_SUCCESS;
240 }
241
242 /*****************************************************************************/
243 /**
244  * USB Suspend
245  *
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
254  * disabled.
255  *
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.
263  *
264  * @param       InstancePtr is a pointer to XUsbPs instance of the controller.
265  *
266  * @return
267  *              - XST_SUCCESS if the USB device has entered Suspend mode
268  *              successfully
269  *              - XST_FAILURE on any error
270  *
271  * @note        None.
272  *
273  ******************************************************************************/
274 int XUsbPs_Suspend(const XUsbPs *InstancePtr)
275 {
276         (void) InstancePtr;
277
278         return XST_SUCCESS;
279 }
280
281
282 /*****************************************************************************/
283 /**
284 * USB Resume
285 *
286  If the USB controller is suspended, its operation is resumed when any
287 * non-idle signaling is received on its upstream facing port.
288 *
289 * @param        InstancePtr is a pointer to XUsbPs instance of the controller.
290 *
291 * @return
292 *               - XST_SUCCESS if the USB device has Resumed successfully
293 *               - XST_FAILURE on any error
294 *
295 * @note         None.
296 *
297 ******************************************************************************/
298 int XUsbPs_Resume(const XUsbPs *InstancePtr)
299 {
300         (void) InstancePtr;
301         return XST_SUCCESS;
302 }
303
304
305 /*****************************************************************************/
306 /**
307 * USB Assert Resume
308 *
309 * @param        InstancePtr is a pointer to XUsbPs instance of the controller.
310 *
311 * @return
312 *               - XST_SUCCESS if the USB device has Resumed successfully
313 *               - XST_FAILURE on any error
314 *
315 * @note         None.
316 *
317 ******************************************************************************/
318
319 int XUsbPs_RequestHostResume(const XUsbPs *InstancePtr)
320 {
321         (void) InstancePtr;
322         return XST_SUCCESS;
323 }
324
325 /****************************************************************************/
326 /**
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.
330 *
331 * @param        InstancePtr is a pointer to XUsbPs instance of the controller.
332 * @param        Address is the Address of the device.
333 *
334 * @return
335 *               - XST_SUCCESS: Address set successfully.
336 *               - XST_FAILURE: An error occured.
337 *               - XST_INVALID_PARAM: Invalid parameter passed, e.g. address
338 *               value too big.
339 *
340 * @note         None.
341 *
342 *****************************************************************************/
343 int XUsbPs_SetDeviceAddress(XUsbPs *InstancePtr, u8 Address)
344 {
345         Xil_AssertNonvoid(InstancePtr != NULL);
346
347         /* Check address range validity. */
348         if (Address > XUSBPS_DEVICEADDR_MAX) {
349                 return XST_INVALID_PARAM;
350         }
351
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.
355          */
356         XUsbPs_WriteReg(InstancePtr->Config.BaseAddress,
357                                 XUSBPS_DEVICEADDR_OFFSET,
358                                 (Address << XUSBPS_DEVICEADDR_ADDR_SHIFT) |
359                                 XUSBPS_DEVICEADDR_DEVICEAADV_MASK);
360
361         return XST_SUCCESS;
362 }
363
364 /** @} */