]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A53_64-bit_UltraScale_MPSoC/RTOSDemo_A53_bsp/psu_cortexa53_0/libsrc/usbpsu_v1_4/src/xusbpsu_endpoint.c
Update Zynq, MPSoc Cortex-A53 and MPSoc Cortex-R5 demo projects to build with the...
[freertos] / FreeRTOS / Demo / CORTEX_A53_64-bit_UltraScale_MPSoC / RTOSDemo_A53_bsp / psu_cortexa53_0 / libsrc / usbpsu_v1_4 / src / xusbpsu_endpoint.c
1 /******************************************************************************
2 *
3 * Copyright (C) 2016 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 *
35 * @file xusbpsu_endpoint.c
36 * @addtogroup usbpsu_v1_3
37 * @{
38 *
39 *
40 * <pre>
41 * MODIFICATION HISTORY:
42 *
43 * Ver   Who  Date     Changes
44 * ----- ---- -------- -------------------------------------------------------
45 * 1.0   sg  06/06/16 First release
46 * 1.3   vak 04/03/17 Added CCI support for USB
47 * 1.4   bk  12/01/18 Modify USBPSU driver code to fit USB common example code
48 *                      for all USB IPs
49 *       myk 12/01/18 Added hibernation support for device mode
50 * </pre>
51 *
52 *****************************************************************************/
53
54 /***************************** Include Files *********************************/
55 #include "xusbpsu_endpoint.h"
56
57 /************************** Constant Definitions *****************************/
58
59 /**************************** Type Definitions *******************************/
60
61 /***************** Macros (Inline Functions) Definitions *********************/
62
63 /************************** Function Prototypes ******************************/
64
65 /************************** Variable Definitions *****************************/
66
67 /****************************************************************************/
68 /**
69 * Returns zeroed parameters to be used by Endpoint commands
70 *
71 * @param        InstancePtr is a pointer to the XUsbPsu instance.
72 *
73 * @return       Zeroed Params structure pointer.
74 *
75 * @note         None.
76 *
77 *****************************************************************************/
78 struct XUsbPsu_EpParams *XUsbPsu_GetEpParams(struct XUsbPsu *InstancePtr)
79 {
80         if (InstancePtr == NULL) {
81                 return NULL;
82         }
83
84         InstancePtr->EpParams.Param0 = 0x00U;
85         InstancePtr->EpParams.Param1 = 0x00U;
86         InstancePtr->EpParams.Param2 = 0x00U;
87
88         return &InstancePtr->EpParams;
89 }
90
91 /****************************************************************************/
92 /**
93 * Returns Transfer Index assigned by Core for an Endpoint transfer.
94 *
95 * @param        InstancePtr is a pointer to the XUsbPsu instance.
96 * @param        UsbEpNum is USB endpoint number.
97 * @param        Dir is direction of endpoint - XUSBPSU_EP_DIR_IN/XUSBPSU_EP_DIR_OUT
98 *
99 * @return       Transfer Resource Index.
100 *
101 * @note         None.
102 *
103 *****************************************************************************/
104 u32 XUsbPsu_EpGetTransferIndex(struct XUsbPsu *InstancePtr, u8 UsbEpNum,
105                                                                 u8 Dir)
106 {
107         u8 PhyEpNum;
108         u32 ResourceIndex;
109
110         Xil_AssertNonvoid(InstancePtr != NULL);
111         Xil_AssertNonvoid(UsbEpNum <= (u8)16U);
112         Xil_AssertNonvoid((Dir == XUSBPSU_EP_DIR_IN) ||
113                                                 (Dir == XUSBPSU_EP_DIR_OUT));
114
115         PhyEpNum = (u8)PhysicalEp(UsbEpNum, Dir);
116         ResourceIndex = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DEPCMD(PhyEpNum));
117
118         return (u32)XUSBPSU_DEPCMD_GET_RSC_IDX(ResourceIndex);
119 }
120
121 /****************************************************************************/
122 /**
123 * Sends Endpoint command to Endpoint.
124 *
125 * @param        InstancePtr is a pointer to the XUsbPsu instance.
126 * @param        UsbEpNum is USB endpoint number.
127 * @param        Dir is direction of endpoint
128 *                       - XUSBPSU_EP_DIR_IN/ XUSBPSU_EP_DIR_OUT.
129 * @param        Cmd is Endpoint command.
130 * @param        Params is Endpoint command parameters.
131 *
132 * @return       XST_SUCCESS else XST_FAILURE.
133 *
134 * @note         None.
135 *
136 *****************************************************************************/
137 s32 XUsbPsu_SendEpCmd(struct XUsbPsu *InstancePtr, u8 UsbEpNum, u8 Dir,
138                                           u32 Cmd, struct XUsbPsu_EpParams *Params)
139 {
140         u32     PhyEpNum;
141
142         Xil_AssertNonvoid(InstancePtr != NULL);
143         Xil_AssertNonvoid(UsbEpNum <= (u8)16U);
144         Xil_AssertNonvoid((Dir == XUSBPSU_EP_DIR_IN) ||
145                                           (Dir == XUSBPSU_EP_DIR_OUT));
146
147         PhyEpNum = PhysicalEp(UsbEpNum, Dir);
148
149         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DEPCMDPAR0(PhyEpNum),
150                                          Params->Param0);
151         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DEPCMDPAR1(PhyEpNum),
152                                          Params->Param1);
153         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DEPCMDPAR2(PhyEpNum),
154                                          Params->Param2);
155
156         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DEPCMD(PhyEpNum),
157                         Cmd | XUSBPSU_DEPCMD_CMDACT);
158
159         if (XUsbPsu_Wait_Clear_Timeout(InstancePtr, XUSBPSU_DEPCMD(PhyEpNum),
160                         XUSBPSU_DEPCMD_CMDACT, 500U) == (s32)XST_FAILURE) {
161                 return XST_FAILURE;
162         }
163
164         return XST_SUCCESS;
165 }
166
167 /****************************************************************************/
168 /**
169 * Sends Start New Configuration command to Endpoint.
170 *
171 * @param        InstancePtr is a pointer to the XUsbPsu instance.
172 * @param        UsbEpNum is USB endpoint number.
173 * @param        Dir is direction of endpoint
174 *                       - XUSBPSU_EP_DIR_IN/ XUSBPSU_EP_DIR_OUT.
175 *
176 * @return       XST_SUCCESS else XST_FAILURE.
177 *
178 * @note
179 *                       As per data book this command should be issued by software
180 *                       under these conditions:
181 *                               1. After power-on-reset with XferRscIdx=0 before starting
182 *                                  to configure Physical Endpoints 0 and 1.
183 *                               2. With XferRscIdx=2 before starting to configure
184 *                                  Physical Endpoints > 1
185 *                               3. This command should always be issued to
186 *                                  Endpoint 0 (DEPCMD0).
187 *
188 *****************************************************************************/
189 s32 XUsbPsu_StartEpConfig(struct XUsbPsu *InstancePtr, u32 UsbEpNum, u8 Dir)
190 {
191         struct XUsbPsu_EpParams *Params;
192         u32     Cmd;
193         u8 PhyEpNum;
194
195         Xil_AssertNonvoid(InstancePtr != NULL);
196         Xil_AssertNonvoid(UsbEpNum <= (u32)16U);
197         Xil_AssertNonvoid((Dir == XUSBPSU_EP_DIR_IN) ||
198                                           (Dir == XUSBPSU_EP_DIR_OUT));
199
200         PhyEpNum = (u8)PhysicalEp(UsbEpNum, (u32)Dir);
201         Params =  XUsbPsu_GetEpParams(InstancePtr);
202         Xil_AssertNonvoid(Params != NULL);
203
204         if (PhyEpNum != 1U) {
205                 Cmd = XUSBPSU_DEPCMD_DEPSTARTCFG;
206                 /* XferRscIdx == 0 for EP0 and 2 for the remaining */
207                 if (PhyEpNum > 1U) {
208                         if (InstancePtr->IsConfigDone != 0U) {
209                                 return XST_SUCCESS;
210                         }
211                         InstancePtr->IsConfigDone = 1U;
212                         Cmd |= XUSBPSU_DEPCMD_PARAM(2);
213                 }
214
215                 return XUsbPsu_SendEpCmd(InstancePtr, 0U, XUSBPSU_EP_DIR_OUT,
216                                                                  Cmd, Params);
217         }
218
219         return XST_SUCCESS;
220 }
221
222 /****************************************************************************/
223 /**
224 * Sends Set Endpoint Configuration command to Endpoint.
225 *
226 * @param        InstancePtr is a pointer to the XUsbPsu instance.
227 * @param        UsbEpNum is USB endpoint number.
228 * @param        Dir is direction of endpoint - XUSBPSU_EP_DIR_IN/XUSBPSU_EP_DIR_OUT.
229 * @param        Size is size of Endpoint size.
230 * @param        Type is Endpoint type Control/Bulk/Interrupt/Isoc.
231 * @param        Restore should be true if saved state should be restored;
232 *                       typically this would be false
233 *
234 * @return       XST_SUCCESS else XST_FAILURE.
235 *
236 * @note         None.
237 *
238 *****************************************************************************/
239 s32 XUsbPsu_SetEpConfig(struct XUsbPsu *InstancePtr, u8 UsbEpNum, u8 Dir,
240                                                 u16 Size, u8 Type, u8 Restore)
241 {
242         struct XUsbPsu_Ep *Ept;
243         struct XUsbPsu_EpParams *Params;
244         u8 PhyEpNum;
245
246         Xil_AssertNonvoid(InstancePtr != NULL);
247         Xil_AssertNonvoid(UsbEpNum <= (u8)16U);
248         Xil_AssertNonvoid((Dir == XUSBPSU_EP_DIR_IN) ||
249                                                 (Dir == XUSBPSU_EP_DIR_OUT));
250         Xil_AssertNonvoid((Size >= 64U) && (Size <= 1024U));
251
252         Params = XUsbPsu_GetEpParams(InstancePtr);
253         Xil_AssertNonvoid(Params != NULL);
254
255         PhyEpNum = PhysicalEp(UsbEpNum , Dir);
256         Ept = &InstancePtr->eps[PhyEpNum];
257
258         Params->Param0 = XUSBPSU_DEPCFG_EP_TYPE(Type)
259                 | XUSBPSU_DEPCFG_MAX_PACKET_SIZE(Size);
260
261         /*
262          * Set burst size to 1 as recommended
263          */
264         if (InstancePtr->AppData->Speed == XUSBPSU_SPEED_SUPER) {
265                 Params->Param0 |= XUSBPSU_DEPCFG_BURST_SIZE(1);
266         }
267
268         Params->Param1 = XUSBPSU_DEPCFG_XFER_COMPLETE_EN
269                 | XUSBPSU_DEPCFG_XFER_NOT_READY_EN;
270
271         if (Restore) {
272                 Params->Param0 |= XUSBPSU_DEPCFG_ACTION_RESTORE;
273                 Params->Param2 = Ept->EpSavedState;
274         }
275
276         /*
277          * We are doing 1:1 mapping for endpoints, meaning
278          * Physical Endpoints 2 maps to Logical Endpoint 2 and
279          * so on. We consider the direction bit as part of the physical
280          * endpoint number. So USB endpoint 0x81 is 0x03.
281          */
282         Params->Param1 |= XUSBPSU_DEPCFG_EP_NUMBER(PhyEpNum);
283
284         if (Dir != XUSBPSU_EP_DIR_OUT) {
285                  Params->Param0 |= XUSBPSU_DEPCFG_FIFO_NUMBER((u32)PhyEpNum >> 1);
286         }
287
288         if (Ept->Type == XUSBPSU_ENDPOINT_XFER_ISOC) {
289                 Params->Param1 |= XUSBPSU_DEPCFG_BINTERVAL_M1(Ept->Interval - 1);
290                 Params->Param1 |= XUSBPSU_DEPCFG_XFER_IN_PROGRESS_EN;
291         }
292
293         return XUsbPsu_SendEpCmd(InstancePtr, UsbEpNum, Dir,
294                                                          XUSBPSU_DEPCMD_SETEPCONFIG, Params);
295 }
296
297 /****************************************************************************/
298 /**
299 * Sends Set Transfer Resource command to Endpoint.
300 *
301 * @param        InstancePtr is a pointer to the XUsbPsu instance.
302 * @param        UsbEpNum is USB endpoint number.
303 * @param        Dir is direction of endpoint - XUSBPSU_EP_DIR_IN/
304 *                                                                                       XUSBPSU_EP_DIR_OUT.
305 *
306 * @return       XST_SUCCESS else XST_FAILURE.
307 *
308 * @note         None.
309 *
310 *****************************************************************************/
311 s32 XUsbPsu_SetXferResource(struct XUsbPsu *InstancePtr, u8 UsbEpNum, u8 Dir)
312 {
313         struct XUsbPsu_EpParams *Params;
314
315
316         Xil_AssertNonvoid(InstancePtr != NULL);
317         Xil_AssertNonvoid(UsbEpNum <= (u8)16U);
318         Xil_AssertNonvoid((Dir == XUSBPSU_EP_DIR_IN) ||
319                                                 (Dir == XUSBPSU_EP_DIR_OUT));
320
321         Params = XUsbPsu_GetEpParams(InstancePtr);
322         Xil_AssertNonvoid(Params != NULL);
323
324         Params->Param0 = XUSBPSU_DEPXFERCFG_NUM_XFER_RES(1);
325
326         return XUsbPsu_SendEpCmd(InstancePtr, UsbEpNum, Dir,
327                                                          XUSBPSU_DEPCMD_SETTRANSFRESOURCE, Params);
328 }
329
330 /****************************************************************************/
331 /**
332 * Enables Endpoint for sending/receiving data.
333 *
334 * @param        InstancePtr is a pointer to the XUsbPsu instance.
335 * @param        UsbEpNum is USB endpoint number.
336 * @param        Dir is direction of endpoint - XUSBPSU_EP_DIR_IN/XUSBPSU_EP_DIR_OUT.
337 * @param        Maxsize is size of Endpoint size.
338 * @param        Type is Endpoint type Control/Bulk/Interrupt/Isoc.
339 * @param        Restore should be true if saved state should be restored;
340 *                       typically this would be false
341 *
342 * @return       XST_SUCCESS else XST_FAILURE.
343 *
344 * @note         None.
345 *
346 ****************************************************************************/
347 s32 XUsbPsu_EpEnable(struct XUsbPsu *InstancePtr, u8 UsbEpNum, u8 Dir,
348                         u16 Maxsize, u8 Type, u8 Restore)
349 {
350         struct XUsbPsu_Ep *Ept;
351         struct XUsbPsu_Trb *TrbStHw, *TrbLink;
352         u32 RegVal;
353         s32 Ret = (s32)XST_FAILURE;
354         u32 PhyEpNum;
355
356         Xil_AssertNonvoid(InstancePtr != NULL);
357         Xil_AssertNonvoid(UsbEpNum <= (u8)16U);
358         Xil_AssertNonvoid((Dir == XUSBPSU_EP_DIR_IN) ||
359                                           (Dir == XUSBPSU_EP_DIR_OUT));
360         Xil_AssertNonvoid((Maxsize >= 64U) && (Maxsize <= 1024U));
361
362         PhyEpNum = PhysicalEp(UsbEpNum , Dir);
363         Ept = &InstancePtr->eps[PhyEpNum];
364
365         Ept->UsbEpNum   = UsbEpNum;
366         Ept->Direction  = Dir;
367         Ept->Type       = Type;
368         Ept->MaxSize    = Maxsize;
369         Ept->PhyEpNum   = (u8)PhyEpNum;
370         Ept->CurUf      = 0;
371         if (!InstancePtr->IsHibernated) {
372                 Ept->TrbEnqueue = 0;
373                 Ept->TrbDequeue = 0;
374         }
375
376         if (((Ept->EpStatus & XUSBPSU_EP_ENABLED) == 0U)
377                         || (InstancePtr->IsHibernated)) {
378                 Ret = XUsbPsu_StartEpConfig(InstancePtr, UsbEpNum, Dir);
379                 if (Ret != 0) {
380                         return Ret;
381                 }
382         }
383
384         Ret = XUsbPsu_SetEpConfig(InstancePtr, UsbEpNum, Dir, Maxsize,
385                                         Type, Restore);
386         if (Ret != 0) {
387                 return Ret;
388         }
389
390         if (((Ept->EpStatus & XUSBPSU_EP_ENABLED) == 0U)
391                         || (InstancePtr->IsHibernated)) {
392                 Ret = XUsbPsu_SetXferResource(InstancePtr, UsbEpNum, Dir);
393                 if (Ret != 0) {
394                         return Ret;
395                 }
396
397                 Ept->EpStatus |= XUSBPSU_EP_ENABLED;
398
399                 RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DALEPENA);
400                 RegVal |= XUSBPSU_DALEPENA_EP(Ept->PhyEpNum);
401                 XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DALEPENA, RegVal);
402
403                 /* Following code is only applicable for ISO XFER */
404                 TrbStHw = &Ept->EpTrb[0];
405
406                 /* Link TRB. The HWO bit is never reset */
407                 TrbLink = &Ept->EpTrb[NO_OF_TRB_PER_EP];
408                 memset(TrbLink, 0x00, sizeof(struct XUsbPsu_Trb));
409
410                 TrbLink->BufferPtrLow = (UINTPTR)TrbStHw;
411                 TrbLink->BufferPtrHigh = ((UINTPTR)TrbStHw >> 16) >> 16;
412                 TrbLink->Ctrl |= XUSBPSU_TRBCTL_LINK_TRB;
413                 TrbLink->Ctrl |= XUSBPSU_TRB_CTRL_HWO;
414         }
415
416         return XST_SUCCESS;
417 }
418
419 /****************************************************************************/
420 /**
421 * Disables Endpoint.
422 *
423 * @param        InstancePtr is a pointer to the XUsbPsu instance.
424 * @param        UsbEpNum is USB endpoint number.
425 * @param        Dir is direction of endpoint
426 *                       - XUSBPSU_EP_DIR_IN/XUSBPSU_EP_DIR_OUT.
427 *
428 * @return       XST_SUCCESS else XST_FAILURE.
429 *
430 * @note         None.
431 *
432 ****************************************************************************/
433 s32 XUsbPsu_EpDisable(struct XUsbPsu *InstancePtr, u8 UsbEpNum, u8 Dir)
434 {
435         u32     RegVal;
436         u8      PhyEpNum;
437         struct XUsbPsu_Ep *Ept;
438
439         Xil_AssertNonvoid(InstancePtr != NULL);
440         Xil_AssertNonvoid(UsbEpNum <= (u8)16U);
441         Xil_AssertNonvoid((Dir == XUSBPSU_EP_DIR_IN) ||
442                                                 (Dir == XUSBPSU_EP_DIR_OUT));
443
444         PhyEpNum = PhysicalEp(UsbEpNum , Dir);
445         Ept = &InstancePtr->eps[PhyEpNum];
446
447         /* make sure HW endpoint isn't stalled */
448         if (Ept->EpStatus & XUSBPSU_EP_STALL)
449                 XUsbPsu_EpClearStall(InstancePtr, Ept->UsbEpNum, Ept->Direction);
450
451         RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DALEPENA);
452         RegVal &= ~XUSBPSU_DALEPENA_EP(PhyEpNum);
453         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DALEPENA, RegVal);
454
455         Ept->Type = 0U;
456         Ept->EpStatus = 0U;
457         Ept->MaxSize = 0U;
458         Ept->TrbEnqueue = 0U;
459         Ept->TrbDequeue = 0U;
460
461         return XST_SUCCESS;
462 }
463
464 /****************************************************************************/
465 /**
466 * Enables USB Control Endpoint i.e., EP0OUT and EP0IN of Core.
467 *
468 * @param        InstancePtr is a pointer to the XUsbPsu instance.
469 * @param        Size is control endpoint size.
470 *
471 * @return       XST_SUCCESS else XST_FAILURE.
472 *
473 * @note         None.
474 *
475 ****************************************************************************/
476 s32 XUsbPsu_EnableControlEp(struct XUsbPsu *InstancePtr, u16 Size)
477 {
478         s32 RetVal;
479
480         Xil_AssertNonvoid(InstancePtr != NULL);
481         Xil_AssertNonvoid((Size >= 64U) && (Size <= 512U));
482
483         RetVal = XUsbPsu_EpEnable(InstancePtr, 0U, XUSBPSU_EP_DIR_OUT, Size,
484                                 XUSBPSU_ENDPOINT_XFER_CONTROL, FALSE);
485         if (RetVal != 0) {
486                 return XST_FAILURE;
487         }
488
489         RetVal = XUsbPsu_EpEnable(InstancePtr, 0U, XUSBPSU_EP_DIR_IN, Size,
490                                 XUSBPSU_ENDPOINT_XFER_CONTROL, FALSE);
491         if (RetVal != 0) {
492                 return XST_FAILURE;
493         }
494
495         return XST_SUCCESS;
496 }
497
498 /****************************************************************************/
499 /**
500 * Initializes Endpoints. All OUT endpoints are even numbered and all IN
501 * endpoints are odd numbered. EP0 is for Control OUT and EP1 is for
502 * Control IN.
503 *
504 * @param        InstancePtr is a pointer to the XUsbPsu instance.
505 *
506 * @return       None.
507 *
508 * @note         None.
509 *
510 ****************************************************************************/
511 void XUsbPsu_InitializeEps(struct XUsbPsu *InstancePtr)
512 {
513         u8  i;
514         u8 Epnum;
515
516         Xil_AssertVoid(InstancePtr != NULL);
517
518         for (i = 0U; i < InstancePtr->NumOutEps; i++) {
519                 Epnum = (i << 1U) | XUSBPSU_EP_DIR_OUT;
520                 InstancePtr->eps[Epnum].PhyEpNum = Epnum;
521                 InstancePtr->eps[Epnum].Direction = XUSBPSU_EP_DIR_OUT;
522                 InstancePtr->eps[Epnum].ResourceIndex = 0;
523         }
524         for (i = 0U; i < InstancePtr->NumInEps; i++) {
525                 Epnum = (i << 1U) | XUSBPSU_EP_DIR_IN;
526                 InstancePtr->eps[Epnum].PhyEpNum = Epnum;
527                 InstancePtr->eps[Epnum].Direction = XUSBPSU_EP_DIR_IN;
528                 InstancePtr->eps[Epnum].ResourceIndex = 0;
529         }
530 }
531
532 /****************************************************************************/
533 /**
534 * Stops transfer on Endpoint.
535 *
536 * @param        InstancePtr is a pointer to the XUsbPsu instance.
537 * @param        UsbEpNum is USB endpoint number.
538 * @param        Dir is direction of endpoint - XUSBPSU_EP_DIR_IN/XUSBPSU_EP_DIR_OUT.
539 * @Force        Force flag to stop/pause transfer.
540 *
541 * @return       None.
542 *
543 * @note         None.
544 *
545 ****************************************************************************/
546 void XUsbPsu_StopTransfer(struct XUsbPsu *InstancePtr, u8 UsbEpNum,
547                         u8 Dir, u8 Force)
548 {
549         struct XUsbPsu_Ep *Ept;
550         struct XUsbPsu_EpParams *Params;
551         u8 PhyEpNum;
552         u32 Cmd;
553
554         Xil_AssertVoid(InstancePtr != NULL);
555         Xil_AssertVoid(UsbEpNum <= (u8)16U);
556         Xil_AssertVoid((Dir == XUSBPSU_EP_DIR_IN) || (Dir == XUSBPSU_EP_DIR_OUT));
557
558         PhyEpNum = PhysicalEp(UsbEpNum, Dir);
559         Params = XUsbPsu_GetEpParams(InstancePtr);
560         Xil_AssertVoid(Params != NULL);
561
562         Ept = &InstancePtr->eps[PhyEpNum];
563
564         if (Ept->ResourceIndex == 0U) {
565                 return;
566         }
567
568         /*
569          * - Issue EndTransfer WITH CMDIOC bit set
570          * - Wait 100us
571          */
572         Cmd = XUSBPSU_DEPCMD_ENDTRANSFER;
573         Cmd |= Force ? XUSBPSU_DEPCMD_HIPRI_FORCERM : 0;
574         Cmd |= XUSBPSU_DEPCMD_CMDIOC;
575         Cmd |= XUSBPSU_DEPCMD_PARAM(Ept->ResourceIndex);
576         (void)XUsbPsu_SendEpCmd(InstancePtr, Ept->UsbEpNum, Ept->Direction,
577                                                         Cmd, Params);
578         if (Force)
579                 Ept->ResourceIndex = 0U;
580         Ept->EpStatus &= ~XUSBPSU_EP_BUSY;
581         XUsbSleep(100U);
582 }
583
584 /****************************************************************************/
585 /**
586 * Query endpoint state and save it in EpSavedState
587 *
588 * @param        InstancePtr is a pointer to the XUsbPsu instance.
589 * @param        Ept is a pointer to the XUsbPsu pointer structure.
590 *
591 * @return       None.
592 *
593 * @note         None.
594 *
595 ****************************************************************************/
596 void XUsbPsu_SaveEndpointState(struct XUsbPsu *InstancePtr, struct XUsbPsu_Ep *Ept)
597 {
598        struct XUsbPsu_EpParams *Params = XUsbPsu_GetEpParams(InstancePtr);
599        XUsbPsu_SendEpCmd(InstancePtr, Ept->UsbEpNum, Ept->Direction,
600                        XUSBPSU_DEPCMD_GETEPSTATE, Params);
601        Ept->EpSavedState = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DEPCMDPAR2(Ept->PhyEpNum));
602 }
603
604 /****************************************************************************/
605 /**
606 * Clears Stall on all endpoints.
607 *
608 * @param        InstancePtr is a pointer to the XUsbPsu instance.
609 *
610 * @return       None.
611 *
612 * @note         None.
613 *
614 ****************************************************************************/
615 void XUsbPsu_ClearStalls(struct XUsbPsu *InstancePtr)
616 {
617         struct XUsbPsu_EpParams *Params;
618         u32 Epnum;
619         struct XUsbPsu_Ep *Ept;
620
621         Xil_AssertVoid(InstancePtr != NULL);
622
623         Params = XUsbPsu_GetEpParams(InstancePtr);
624         Xil_AssertVoid(Params != NULL);
625
626         for (Epnum = 1U; Epnum < XUSBPSU_ENDPOINTS_NUM; Epnum++) {
627
628                 Ept = &InstancePtr->eps[Epnum];
629                 if (Ept == NULL) {
630                         continue;
631                 }
632
633                 if ((Ept->EpStatus & XUSBPSU_EP_STALL) == 0U) {
634                         continue;
635                 }
636
637                 Ept->EpStatus &= ~XUSBPSU_EP_STALL;
638
639                 (void)XUsbPsu_SendEpCmd(InstancePtr, Ept->UsbEpNum,
640                                                   Ept->Direction, XUSBPSU_DEPCMD_CLEARSTALL,
641                                                   Params);
642         }
643 }
644
645 /****************************************************************************/
646 /**
647 * Initiates DMA to send data on endpoint to Host.
648 *
649 * @param        InstancePtr is a pointer to the XUsbPsu instance.
650 * @param        UsbEp is USB endpoint number.
651 * @param        BufferPtr is pointer to data.
652 * @param        BufferLen is length of data buffer.
653 *
654 * @return       XST_SUCCESS else XST_FAILURE
655 *
656 * @note         None.
657 *
658 *****************************************************************************/
659 s32 XUsbPsu_EpBufferSend(struct XUsbPsu *InstancePtr, u8 UsbEp,
660                                                  u8 *BufferPtr, u32 BufferLen)
661 {
662         u8      PhyEpNum;
663         u32     cmd;
664         s32     RetVal;
665         struct XUsbPsu_Trb      *TrbPtr;
666         struct XUsbPsu_Ep *Ept;
667         struct XUsbPsu_EpParams *Params;
668
669         Xil_AssertNonvoid(InstancePtr != NULL);
670         Xil_AssertNonvoid(UsbEp <= (u8)16U);
671         Xil_AssertNonvoid(BufferPtr != NULL);
672
673         PhyEpNum = PhysicalEp(UsbEp, XUSBPSU_EP_DIR_IN);
674         if (PhyEpNum == 1U) {
675                 RetVal = XUsbPsu_Ep0Send(InstancePtr, BufferPtr, BufferLen);
676                 return RetVal;
677         }
678
679         Ept = &InstancePtr->eps[PhyEpNum];
680
681         if (Ept->Direction != XUSBPSU_EP_DIR_IN) {
682                 return XST_FAILURE;
683         }
684
685         Ept->RequestedBytes = BufferLen;
686         Ept->BytesTxed = 0U;
687         Ept->BufferPtr = BufferPtr;
688
689         TrbPtr = &Ept->EpTrb[Ept->TrbEnqueue];
690         Xil_AssertNonvoid(TrbPtr != NULL);
691
692         Ept->TrbEnqueue++;
693         if (Ept->TrbEnqueue == NO_OF_TRB_PER_EP)
694                 Ept->TrbEnqueue = 0;
695         TrbPtr->BufferPtrLow  = (UINTPTR)BufferPtr;
696         TrbPtr->BufferPtrHigh  = ((UINTPTR)BufferPtr >> 16) >> 16;
697         TrbPtr->Size = BufferLen & XUSBPSU_TRB_SIZE_MASK;
698
699         switch (Ept->Type) {
700         case XUSBPSU_ENDPOINT_XFER_ISOC:
701                 /*
702                  *  According to DWC3 datasheet, XUSBPSU_TRBCTL_ISOCHRONOUS and
703                  *  XUSBPSU_TRBCTL_CHN fields are only set when request has
704                  *  scattered list so these fields are not set over here.
705                  */
706                 TrbPtr->Ctrl = (XUSBPSU_TRBCTL_ISOCHRONOUS_FIRST
707                                 | XUSBPSU_TRB_CTRL_CSP);
708
709                 break;
710         case XUSBPSU_ENDPOINT_XFER_INT:
711         case XUSBPSU_ENDPOINT_XFER_BULK:
712                 TrbPtr->Ctrl = (XUSBPSU_TRBCTL_NORMAL
713                                 | XUSBPSU_TRB_CTRL_LST);
714
715                 break;
716         }
717
718         TrbPtr->Ctrl |= (XUSBPSU_TRB_CTRL_HWO
719                         | XUSBPSU_TRB_CTRL_IOC
720                         | XUSBPSU_TRB_CTRL_ISP_IMI);
721
722         if (InstancePtr->ConfigPtr->IsCacheCoherent == 0) {
723                 Xil_DCacheFlushRange((INTPTR)TrbPtr, sizeof(struct XUsbPsu_Trb));
724                 Xil_DCacheFlushRange((INTPTR)BufferPtr, BufferLen);
725         }
726
727         Params = XUsbPsu_GetEpParams(InstancePtr);
728         Xil_AssertNonvoid(Params != NULL);
729         Params->Param0 = 0U;
730         Params->Param1 = (UINTPTR)TrbPtr;
731
732         if (Ept->EpStatus & XUSBPSU_EP_BUSY) {
733                 cmd = XUSBPSU_DEPCMD_UPDATETRANSFER;
734                 cmd |= XUSBPSU_DEPCMD_PARAM(Ept->ResourceIndex);
735         } else {
736                 if (Ept->Type == XUSBPSU_ENDPOINT_XFER_ISOC) {
737                         BufferPtr += BufferLen;
738                         struct XUsbPsu_Trb      *TrbTempNext;
739                         TrbTempNext = &Ept->EpTrb[Ept->TrbEnqueue];
740                         Xil_AssertNonvoid(TrbTempNext != NULL);
741
742                         Ept->TrbEnqueue++;
743                         if (Ept->TrbEnqueue == NO_OF_TRB_PER_EP)
744                                 Ept->TrbEnqueue = 0;
745                         TrbTempNext->BufferPtrLow  = (UINTPTR)BufferPtr;
746                         TrbTempNext->BufferPtrHigh  = ((UINTPTR)BufferPtr >> 16) >> 16;
747                         TrbTempNext->Size = BufferLen & XUSBPSU_TRB_SIZE_MASK;
748
749                         TrbTempNext->Ctrl = (XUSBPSU_TRBCTL_ISOCHRONOUS_FIRST
750                                         | XUSBPSU_TRB_CTRL_CSP
751                                         | XUSBPSU_TRB_CTRL_HWO
752                                         | XUSBPSU_TRB_CTRL_IOC
753                                         | XUSBPSU_TRB_CTRL_ISP_IMI);
754
755                         if (InstancePtr->ConfigPtr->IsCacheCoherent == 0) {
756                                 Xil_DCacheFlushRange((INTPTR)TrbTempNext,
757                                                                                 sizeof(struct XUsbPsu_Trb));
758                                 Xil_DCacheFlushRange((INTPTR)BufferPtr, BufferLen);
759                         }
760
761                 }
762
763                 cmd = XUSBPSU_DEPCMD_STARTTRANSFER;
764                 cmd |= XUSBPSU_DEPCMD_PARAM(Ept->CurUf);
765         }
766
767         RetVal = XUsbPsu_SendEpCmd(InstancePtr, UsbEp, Ept->Direction,
768                                                                 cmd, Params);
769         if (RetVal != XST_SUCCESS) {
770                 return XST_FAILURE;
771         }
772
773         if (!(Ept->EpStatus & XUSBPSU_EP_BUSY)) {
774                 Ept->ResourceIndex = (u8)XUsbPsu_EpGetTransferIndex(InstancePtr,
775                                 Ept->UsbEpNum,
776                                 Ept->Direction);
777
778                 Ept->EpStatus |= XUSBPSU_EP_BUSY;
779         }
780
781         return XST_SUCCESS;
782 }
783
784 /****************************************************************************/
785 /**
786 * Initiates DMA to receive data on Endpoint from Host.
787 *
788 * @param        InstancePtr is a pointer to the XUsbPsu instance.
789 * @param        UsbEp is USB endpoint number.
790 * @param        BufferPtr is pointer to data.
791 * @param        Length is length of data to be received.
792 *
793 * @return       XST_SUCCESS else XST_FAILURE
794 *
795 * @note         None.
796 *
797 *****************************************************************************/
798 s32 XUsbPsu_EpBufferRecv(struct XUsbPsu *InstancePtr, u8 UsbEp,
799                                                  u8 *BufferPtr, u32 Length)
800 {
801         u8      PhyEpNum;
802         u32     cmd;
803         u32     Size;
804         s32     RetVal;
805         struct XUsbPsu_Trb      *TrbPtr;
806         struct XUsbPsu_Ep *Ept;
807         struct XUsbPsu_EpParams *Params;
808
809         Xil_AssertNonvoid(InstancePtr != NULL);
810         Xil_AssertNonvoid(UsbEp <= (u8)16U);
811         Xil_AssertNonvoid(BufferPtr != NULL);
812
813         PhyEpNum = PhysicalEp(UsbEp, XUSBPSU_EP_DIR_OUT);
814         if (PhyEpNum == 0U) {
815                 RetVal = XUsbPsu_Ep0Recv(InstancePtr, BufferPtr, Length);
816                 return RetVal;
817         }
818
819         Ept = &InstancePtr->eps[PhyEpNum];
820
821         if (Ept->Direction != XUSBPSU_EP_DIR_OUT) {
822                 return XST_FAILURE;
823         }
824
825         Ept->RequestedBytes = Length;
826         Size = Length;
827         Ept->BytesTxed = 0U;
828         Ept->BufferPtr = BufferPtr;
829
830         /*
831          * 8.2.5 - An OUT transfer size (Total TRB buffer allocation)
832          * must be a multiple of MaxPacketSize even if software is expecting a
833          * fixed non-multiple of MaxPacketSize transfer from the Host.
834          */
835         if (!IS_ALIGNED(Length, Ept->MaxSize)) {
836                 Size = (u32)roundup(Length, Ept->MaxSize);
837                 Ept->UnalignedTx = 1U;
838         }
839
840         TrbPtr = &Ept->EpTrb[Ept->TrbEnqueue];
841         Xil_AssertNonvoid(TrbPtr != NULL);
842
843         Ept->TrbEnqueue++;
844         if (Ept->TrbEnqueue == NO_OF_TRB_PER_EP)
845                 Ept->TrbEnqueue = 0;
846
847         TrbPtr->BufferPtrLow  = (UINTPTR)BufferPtr;
848         TrbPtr->BufferPtrHigh = ((UINTPTR)BufferPtr >> 16) >> 16;
849         TrbPtr->Size = Size;
850
851         switch (Ept->Type) {
852         case XUSBPSU_ENDPOINT_XFER_ISOC:
853                 /*
854                  *  According to Linux driver, XUSBPSU_TRBCTL_ISOCHRONOUS and
855                  *  XUSBPSU_TRBCTL_CHN fields are only set when request has
856                  *  scattered list so these fields are not set over here.
857                  */
858                 TrbPtr->Ctrl = (XUSBPSU_TRBCTL_ISOCHRONOUS_FIRST
859                                 | XUSBPSU_TRB_CTRL_CSP);
860
861                 break;
862         case XUSBPSU_ENDPOINT_XFER_INT:
863         case XUSBPSU_ENDPOINT_XFER_BULK:
864                 TrbPtr->Ctrl = (XUSBPSU_TRBCTL_NORMAL
865                                 | XUSBPSU_TRB_CTRL_LST);
866
867                 break;
868         }
869
870         TrbPtr->Ctrl |= (XUSBPSU_TRB_CTRL_HWO
871                         | XUSBPSU_TRB_CTRL_IOC
872                         | XUSBPSU_TRB_CTRL_ISP_IMI);
873
874
875         if (InstancePtr->ConfigPtr->IsCacheCoherent == 0) {
876                 Xil_DCacheFlushRange((INTPTR)TrbPtr, sizeof(struct XUsbPsu_Trb));
877                 Xil_DCacheInvalidateRange((INTPTR)BufferPtr, Length);
878         }
879
880         Params = XUsbPsu_GetEpParams(InstancePtr);
881         Xil_AssertNonvoid(Params != NULL);
882         Params->Param0 = 0U;
883         Params->Param1 = (UINTPTR)TrbPtr;
884
885         if (Ept->EpStatus & XUSBPSU_EP_BUSY) {
886                 cmd = XUSBPSU_DEPCMD_UPDATETRANSFER;
887                 cmd |= XUSBPSU_DEPCMD_PARAM(Ept->ResourceIndex);
888         } else {
889                 if (Ept->Type == XUSBPSU_ENDPOINT_XFER_ISOC) {
890                         BufferPtr += Length;
891                         struct XUsbPsu_Trb      *TrbTempNext;
892                         TrbTempNext = &Ept->EpTrb[Ept->TrbEnqueue];
893                         Xil_AssertNonvoid(TrbTempNext != NULL);
894
895                         Ept->TrbEnqueue++;
896                         if (Ept->TrbEnqueue == NO_OF_TRB_PER_EP)
897                                 Ept->TrbEnqueue = 0;
898                         TrbTempNext->BufferPtrLow  = (UINTPTR)BufferPtr;
899                         TrbTempNext->BufferPtrHigh  = ((UINTPTR)BufferPtr >> 16) >> 16;
900                         TrbTempNext->Size = Length & XUSBPSU_TRB_SIZE_MASK;
901
902                         TrbTempNext->Ctrl = (XUSBPSU_TRBCTL_ISOCHRONOUS_FIRST
903                                         | XUSBPSU_TRB_CTRL_CSP
904                                         | XUSBPSU_TRB_CTRL_HWO
905                                         | XUSBPSU_TRB_CTRL_IOC
906                                         | XUSBPSU_TRB_CTRL_ISP_IMI);
907
908                         if (InstancePtr->ConfigPtr->IsCacheCoherent == 0) {
909                                 Xil_DCacheFlushRange((INTPTR)TrbTempNext,
910                                                                                 sizeof(struct XUsbPsu_Trb));
911                                 Xil_DCacheFlushRange((INTPTR)BufferPtr, Length);
912                         }
913
914                 }
915
916                 cmd = XUSBPSU_DEPCMD_STARTTRANSFER;
917                 cmd |= XUSBPSU_DEPCMD_PARAM(Ept->CurUf);
918         }
919
920         RetVal = XUsbPsu_SendEpCmd(InstancePtr, UsbEp, Ept->Direction,
921                                                                 cmd, Params);
922         if (RetVal != XST_SUCCESS) {
923                 return XST_FAILURE;
924         }
925
926         if (!(Ept->EpStatus & XUSBPSU_EP_BUSY)) {
927                 Ept->ResourceIndex = (u8)XUsbPsu_EpGetTransferIndex(InstancePtr,
928                                 Ept->UsbEpNum,
929                                 Ept->Direction);
930
931                 Ept->EpStatus |= XUSBPSU_EP_BUSY;
932         }
933
934         return XST_SUCCESS;
935 }
936
937 /****************************************************************************/
938 /**
939 * Stalls an Endpoint.
940 *
941 * @param        InstancePtr is a pointer to the XUsbPsu instance.
942 * @param        Epnum is USB endpoint number.
943 * @param        Dir     is direction.
944 *
945 * @return       None.
946 *
947 * @note         None.
948 *
949 *****************************************************************************/
950 void XUsbPsu_EpSetStall(struct XUsbPsu *InstancePtr, u8 Epnum, u8 Dir)
951 {
952         u8      PhyEpNum;
953         struct XUsbPsu_Ep *Ept = NULL;
954         struct XUsbPsu_EpParams *Params;
955
956         Xil_AssertVoid(InstancePtr != NULL);
957         Xil_AssertVoid(Epnum <= (u8)16U);
958         Xil_AssertVoid((Dir == XUSBPSU_EP_DIR_IN) || (Dir == XUSBPSU_EP_DIR_OUT));
959
960         PhyEpNum = PhysicalEp(Epnum, Dir);
961         Ept = &InstancePtr->eps[PhyEpNum];
962
963         Params = XUsbPsu_GetEpParams(InstancePtr);
964         Xil_AssertVoid(Params != NULL);
965
966         (void)XUsbPsu_SendEpCmd(InstancePtr, Ept->UsbEpNum, Ept->Direction,
967                                                         XUSBPSU_DEPCMD_SETSTALL, Params);
968
969         Ept->EpStatus |= XUSBPSU_EP_STALL;
970 }
971
972 /****************************************************************************/
973 /**
974 * Clears Stall on an Endpoint.
975 *
976 * @param        InstancePtr is a pointer to the XUsbPsu instance.
977 * @param        EpNum is USB endpoint number.
978 * @param        Dir     is direction.
979 *
980 * @return       None.
981 *
982 * @note         None.
983 *
984 *****************************************************************************/
985 void XUsbPsu_EpClearStall(struct XUsbPsu *InstancePtr, u8 Epnum, u8 Dir)
986 {
987         u8      PhyEpNum;
988         struct XUsbPsu_Ep *Ept = NULL;
989         struct XUsbPsu_EpParams *Params;
990
991         Xil_AssertVoid(InstancePtr != NULL);
992         Xil_AssertVoid(Epnum <= (u8)16U);
993         Xil_AssertVoid((Dir == XUSBPSU_EP_DIR_IN) || (Dir == XUSBPSU_EP_DIR_OUT));
994
995         PhyEpNum = PhysicalEp(Epnum, Dir);
996         Ept = &InstancePtr->eps[PhyEpNum];
997
998         Params = XUsbPsu_GetEpParams(InstancePtr);
999         Xil_AssertVoid(Params != NULL);
1000
1001         (void)XUsbPsu_SendEpCmd(InstancePtr, Ept->UsbEpNum, Ept->Direction,
1002                                                         XUSBPSU_DEPCMD_CLEARSTALL, Params);
1003
1004         Ept->EpStatus &= ~XUSBPSU_EP_STALL;
1005 }
1006
1007 /****************************************************************************/
1008 /**
1009 * Sets an user handler to be called after data is sent/received by an Endpoint
1010 *
1011 * @param        InstancePtr is a pointer to the XUsbPsu instance.
1012 * @param        EpNum is USB endpoint number.
1013 * @param        Dir is direction of endpoint - XUSBPSU_EP_DIR_IN/XUSBPSU_EP_DIR_OUT.
1014 * @param        Handler is user handler to be called.
1015 *
1016 * @return       None.
1017 *
1018 * @note         None.
1019 *
1020 *****************************************************************************/
1021 void XUsbPsu_SetEpHandler(struct XUsbPsu *InstancePtr, u8 Epnum,
1022                         u8 Dir, void (*Handler)(void *, u32, u32))
1023 {
1024         u8 PhyEpNum;
1025         struct XUsbPsu_Ep *Ept;
1026
1027         Xil_AssertVoid(InstancePtr != NULL);
1028         Xil_AssertVoid(Epnum <= (u8)16U);
1029         Xil_AssertVoid((Dir == XUSBPSU_EP_DIR_IN) || (Dir == XUSBPSU_EP_DIR_OUT));
1030
1031         PhyEpNum = PhysicalEp(Epnum, Dir);
1032         Ept = &InstancePtr->eps[PhyEpNum];
1033         Ept->Handler = Handler;
1034 }
1035
1036 /****************************************************************************/
1037 /**
1038 * Returns status of endpoint - Stalled or not
1039 *
1040 * @param        InstancePtr is a pointer to the XUsbPsu instance.
1041 * @param        EpNum is USB endpoint number.
1042 * @param        Dir is direction of endpoint - XUSBPSU_EP_DIR_IN/XUSBPSU_EP_DIR_OUT.
1043 *
1044 * @return
1045 *                       1 - if stalled
1046 *                       0 - if not stalled
1047 *
1048 * @note         None.
1049 *
1050 *****************************************************************************/
1051 s32 XUsbPsu_IsEpStalled(struct XUsbPsu *InstancePtr, u8 Epnum, u8 Dir)
1052 {
1053         u8 PhyEpNum;
1054         struct XUsbPsu_Ep *Ept;
1055
1056         Xil_AssertNonvoid(InstancePtr != NULL);
1057         Xil_AssertNonvoid(Epnum <= (u8)16U);
1058         Xil_AssertNonvoid((Dir == XUSBPSU_EP_DIR_IN) || (Dir == XUSBPSU_EP_DIR_OUT));
1059
1060         PhyEpNum = PhysicalEp(Epnum, Dir);
1061         Ept = &InstancePtr->eps[PhyEpNum];
1062
1063         return (s32)(!!(Ept->EpStatus & XUSBPSU_EP_STALL));
1064 }
1065
1066 /****************************************************************************/
1067 /**
1068 * Checks the Data Phase and calls user Endpoint handler.
1069 *
1070 * @param        InstancePtr is a pointer to the XUsbPsu instance.
1071 * @param        Event is a pointer to the Endpoint event occured in core.
1072 *
1073 * @return       None.
1074 *
1075 * @note         None.
1076 *
1077 *****************************************************************************/
1078 void XUsbPsu_EpXferComplete(struct XUsbPsu *InstancePtr,
1079                                                         const struct XUsbPsu_Event_Epevt *Event)
1080 {
1081         struct XUsbPsu_Ep       *Ept;
1082         struct XUsbPsu_Trb      *TrbPtr;
1083         u32     Length;
1084         u32     Epnum;
1085         u8      Dir;
1086
1087         Xil_AssertVoid(InstancePtr != NULL);
1088         Xil_AssertVoid(Event != NULL);
1089
1090         Epnum = Event->Epnumber;
1091         Ept = &InstancePtr->eps[Epnum];
1092         Dir = Ept->Direction;
1093         TrbPtr = &Ept->EpTrb[Ept->TrbDequeue];
1094         Xil_AssertVoid(TrbPtr != NULL);
1095
1096         Ept->TrbDequeue++;
1097         if (Ept->TrbDequeue == NO_OF_TRB_PER_EP)
1098                 Ept->TrbDequeue = 0;
1099
1100         if (InstancePtr->ConfigPtr->IsCacheCoherent == 0)
1101                 Xil_DCacheInvalidateRange((INTPTR)TrbPtr, sizeof(struct XUsbPsu_Trb));
1102
1103         if (Event->Endpoint_Event == XUSBPSU_DEPEVT_XFERCOMPLETE) {
1104                 Ept->EpStatus &= ~(XUSBPSU_EP_BUSY);
1105                 Ept->ResourceIndex = 0;
1106         }
1107
1108         Length = TrbPtr->Size & XUSBPSU_TRB_SIZE_MASK;
1109
1110         if (Length == 0U) {
1111                 Ept->BytesTxed = Ept->RequestedBytes;
1112         } else {
1113                 if (Dir == XUSBPSU_EP_DIR_IN) {
1114                         Ept->BytesTxed = Ept->RequestedBytes - Length;
1115                 } else if (Dir == XUSBPSU_EP_DIR_OUT) {
1116                         if (Ept->UnalignedTx == 1U) {
1117                                 Ept->BytesTxed = (u32)roundup(Ept->RequestedBytes,
1118                                                                                                 Ept->MaxSize);
1119                                 Ept->BytesTxed -= Length;
1120                                 Ept->UnalignedTx = 0U;
1121                         } else {
1122                                 /*
1123                                  * Get the actual number of bytes transmitted
1124                                  * by host
1125                                  */
1126                                 Ept->BytesTxed = Ept->RequestedBytes - Length;
1127                         }
1128                 }
1129         }
1130
1131         if (Dir == XUSBPSU_EP_DIR_OUT) {
1132                 /* Invalidate Cache */
1133                 if (InstancePtr->ConfigPtr->IsCacheCoherent == 0)
1134                         Xil_DCacheInvalidateRange((INTPTR)Ept->BufferPtr, Ept->BytesTxed);
1135         }
1136
1137         if (Ept->Handler != NULL) {
1138                 Ept->Handler(InstancePtr->AppData, Ept->RequestedBytes, Ept->BytesTxed);
1139         }
1140 }
1141
1142 /****************************************************************************/
1143 /**
1144 * For Isochronous transfer, get the microframe time and calls respective Endpoint
1145 * handler.
1146 *
1147 * @param        InstancePtr is a pointer to the XUsbPsu instance.
1148 * @param        Event is a pointer to the Endpoint event occurred in core.
1149 *
1150 * @return       None.
1151 *
1152 * @note         None.
1153 *
1154 *****************************************************************************/
1155 void XUsbPsu_EpXferNotReady(struct XUsbPsu *InstancePtr,
1156                                                         const struct XUsbPsu_Event_Epevt *Event)
1157 {
1158         struct XUsbPsu_Ep       *Ept;
1159         u32     Epnum;
1160         u32 CurUf, Mask;
1161
1162         Xil_AssertVoid(InstancePtr != NULL);
1163         Xil_AssertVoid(Event != NULL);
1164
1165         Epnum = Event->Epnumber;
1166         Ept = &InstancePtr->eps[Epnum];
1167
1168         if (Ept->Type == XUSBPSU_ENDPOINT_XFER_ISOC) {
1169                 Mask = ~(1 << (Ept->Interval - 1));
1170                 CurUf = Event->Parameters & Mask;
1171                 Ept->CurUf = CurUf + (Ept->Interval * 4);
1172                 if (Ept->Handler != NULL) {
1173                         Ept->Handler(InstancePtr->AppData, 0, 0);
1174                 }
1175         }
1176 }
1177 /** @} */