1 /******************************************************************************
3 * Copyright (C) 2016 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 * @file xusbpsu_intr.c
36 * @addtogroup usbpsu_v1_0
41 * MODIFICATION HISTORY:
43 * Ver Who Date Changes
44 * ----- ---- -------- -------------------------------------------------------
45 * 1.0 sg 06/06/16 First release
49 *****************************************************************************/
51 /***************************** Include Files ********************************/
55 /************************** Constant Definitions *****************************/
57 /**************************** Type Definitions *******************************/
59 /***************** Macros (Inline Functions) Definitions *********************/
61 /************************** Function Prototypes ******************************/
63 /************************** Variable Definitions *****************************/
65 /****************************************************************************/
67 * Endpoint interrupt handler.
69 * @param InstancePtr is a pointer to the XUsbPsu instance.
70 * @param Event is endpoint Event occured in the core.
76 *****************************************************************************/
77 void XUsbPsu_EpInterrupt(struct XUsbPsu *InstancePtr,
78 const struct XUsbPsu_Event_Epevt *Event)
80 struct XUsbPsu_Ep *Ept;
83 Epnum = Event->Epnumber;
84 Ept = &InstancePtr->eps[Epnum];
86 if ((Ept->EpStatus & XUSBPSU_EP_ENABLED) == (u32)0U) {
90 if ((Epnum == (u32)0) || (Epnum == (u32)1)) {
91 XUsbPsu_Ep0Intr(InstancePtr, Event);
95 /* Handle other end point events */
96 switch (Event->Endpoint_Event) {
97 case XUSBPSU_DEPEVT_XFERCOMPLETE:
98 XUsbPsu_EpXferComplete(InstancePtr, Event);
101 case XUSBPSU_DEPEVT_XFERNOTREADY:
105 /* Made for Misra-C Compliance. */
110 /****************************************************************************/
112 * Disconnect Interrupt handler.
114 * @param InstancePtr is a pointer to the XUsbPsu instance.
120 *****************************************************************************/
121 void XUsbPsu_DisconnectIntr(struct XUsbPsu *InstancePtr)
125 RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCTL);
126 RegVal &= ~XUSBPSU_DCTL_INITU1ENA;
127 XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCTL, RegVal);
129 RegVal &= ~XUSBPSU_DCTL_INITU2ENA;
130 XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCTL, RegVal);
132 InstancePtr->IsConfigDone = 0U;
133 InstancePtr->Speed = XUSBPSU_SPEED_UNKNOWN;
136 /****************************************************************************/
138 * Reset Interrupt handler.
140 * @param InstancePtr is a pointer to the XUsbPsu instance.
146 *****************************************************************************/
147 void XUsbPsu_ResetIntr(struct XUsbPsu *InstancePtr)
152 InstancePtr->State = XUSBPSU_STATE_DEFAULT;
154 RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCTL);
155 RegVal &= ~XUSBPSU_DCTL_TSTCTRL_MASK;
156 XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCTL, RegVal);
157 InstancePtr->TestMode = 0U;
159 for (Index = 0U; Index < (InstancePtr->NumInEps + InstancePtr->NumOutEps);
162 InstancePtr->eps[Index].EpStatus = 0U;
165 InstancePtr->IsConfigDone = 0U;
167 /* Reset device address to zero */
168 RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCFG);
169 RegVal &= ~(XUSBPSU_DCFG_DEVADDR_MASK);
170 XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCFG, RegVal);
173 /****************************************************************************/
175 * Connection Done Interrupt handler.
177 * @param InstancePtr is a pointer to the XUsbPsu instance.
183 *****************************************************************************/
184 void XUsbPsu_ConnDoneIntr(struct XUsbPsu *InstancePtr)
190 RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DSTS);
191 Speed = (u8)(RegVal & XUSBPSU_DSTS_CONNECTSPD);
192 InstancePtr->Speed = Speed;
195 case XUSBPSU_DCFG_SUPERSPEED:
197 xil_printf("Super Speed\r\n");
200 InstancePtr->Speed = XUSBPSU_SPEED_SUPER;
203 case XUSBPSU_DCFG_HIGHSPEED:
205 xil_printf("High Speed\r\n");
208 InstancePtr->Speed = XUSBPSU_SPEED_HIGH;
211 case XUSBPSU_DCFG_FULLSPEED2:
212 case XUSBPSU_DCFG_FULLSPEED1:
214 xil_printf("Full Speed\r\n");
217 InstancePtr->Speed = XUSBPSU_SPEED_FULL;
220 case XUSBPSU_DCFG_LOWSPEED:
222 xil_printf("Low Speed\r\n");
225 InstancePtr->Speed = XUSBPSU_SPEED_LOW;
232 (void)XUsbPsu_EnableControlEp(InstancePtr, Size);
233 (void)XUsbPsu_RecvSetup(InstancePtr);
236 /****************************************************************************/
238 * Link Status Change Interrupt handler.
240 * @param InstancePtr is a pointer to the XUsbPsu instance.
241 * @param EvtInfo is Event information.
247 *****************************************************************************/
248 void XUsbPsu_LinkStsChangeIntr(struct XUsbPsu *InstancePtr, u32 EvtInfo)
250 u32 State = EvtInfo & (u32)XUSBPSU_LINK_STATE_MASK;
251 InstancePtr->LinkState = (u8)State;
254 /****************************************************************************/
256 * Interrupt handler for device specific events.
258 * @param InstancePtr is a pointer to the XUsbPsu instance.
259 * @param Event is the Device Event occured in core.
265 *****************************************************************************/
266 void XUsbPsu_DevInterrupt(struct XUsbPsu *InstancePtr,
267 const struct XUsbPsu_Event_Devt *Event)
270 switch (Event->Type) {
271 case XUSBPSU_DEVICE_EVENT_DISCONNECT:
272 XUsbPsu_DisconnectIntr(InstancePtr);
275 case XUSBPSU_DEVICE_EVENT_RESET:
276 XUsbPsu_ResetIntr(InstancePtr);
279 case XUSBPSU_DEVICE_EVENT_CONNECT_DONE:
280 XUsbPsu_ConnDoneIntr(InstancePtr);
283 case XUSBPSU_DEVICE_EVENT_WAKEUP:
286 case XUSBPSU_DEVICE_EVENT_HIBER_REQ:
289 case XUSBPSU_DEVICE_EVENT_LINK_STATUS_CHANGE:
290 XUsbPsu_LinkStsChangeIntr(InstancePtr,
294 case XUSBPSU_DEVICE_EVENT_EOPF:
297 case XUSBPSU_DEVICE_EVENT_SOF:
300 case XUSBPSU_DEVICE_EVENT_ERRATIC_ERROR:
303 case XUSBPSU_DEVICE_EVENT_CMD_CMPL:
306 case XUSBPSU_DEVICE_EVENT_OVERFLOW:
310 /* Made for Misra-C Compliance. */
315 /****************************************************************************/
317 * Processes an Event entry in Event Buffer.
319 * @param InstancePtr is a pointer to the XUsbPsu instance.
320 * @param Event is the Event entry.
326 *****************************************************************************/
327 void XUsbPsu_EventHandler(struct XUsbPsu *InstancePtr,
328 const union XUsbPsu_Event *Event)
331 if (Event->Type.Is_DevEvt == 0U) {
332 /* End point Specific Event */
333 XUsbPsu_EpInterrupt(InstancePtr, &Event->Epevt);
337 switch (Event->Type.Type) {
338 case XUSBPSU_EVENT_TYPE_DEV:
339 /* Device Specific Event */
340 XUsbPsu_DevInterrupt(InstancePtr, &Event->Devt);
342 /* Carkit and I2C events not supported now */
344 /* Made for Misra-C Compliance. */
349 /****************************************************************************/
351 * Processes events in an Event Buffer.
353 * @param InstancePtr is a pointer to the XUsbPsu instance.
354 * @bus Event buffer number.
360 *****************************************************************************/
361 void XUsbPsu_EventBufferHandler(struct XUsbPsu *InstancePtr)
363 struct XUsbPsu_EvtBuffer *Evt;
364 union XUsbPsu_Event Event = {0};
366 Evt = &InstancePtr->Evt;
368 Xil_DCacheInvalidateRange((INTPTR)Evt->BuffAddr,
369 (u32)XUSBPSU_EVENT_BUFFERS_SIZE);
371 while (Evt->Count > 0) {
372 Event.Raw = *(UINTPTR *)(Evt->BuffAddr + Evt->Offset);
375 * Process the event received
377 XUsbPsu_EventHandler(InstancePtr, &Event);
379 Evt->Offset = (Evt->Offset + 4U) % XUSBPSU_EVENT_BUFFERS_SIZE;
381 XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GEVNTCOUNT(0), 4U);
384 Evt->Flags &= ~XUSBPSU_EVENT_PENDING;
387 /****************************************************************************/
389 * Main Interrupt Handler.
395 *****************************************************************************/
396 void XUsbPsu_IntrHandler(void *XUsbPsuInstancePtr)
398 struct XUsbPsu *InstancePtr;
399 struct XUsbPsu_EvtBuffer *Evt;
403 InstancePtr = XUsbPsuInstancePtr;
405 Evt = &InstancePtr->Evt;
407 Count = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_GEVNTCOUNT(0));
408 Count &= XUSBPSU_GEVNTCOUNT_MASK;
410 * As per data book software should only process Events if Event count
411 * is greater than zero.
418 Evt->Flags |= XUSBPSU_EVENT_PENDING;
420 /* Mask event interrupt */
421 RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_GEVNTSIZ(0));
422 RegVal |= XUSBPSU_GEVNTSIZ_INTMASK;
423 XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GEVNTSIZ(0), RegVal);
425 /* Processes events in an Event Buffer */
426 XUsbPsu_EventBufferHandler(InstancePtr);
428 /* Unmask event interrupt */
429 RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_GEVNTSIZ(0));
430 RegVal &= ~XUSBPSU_GEVNTSIZ_INTMASK;
431 XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GEVNTSIZ(0), RegVal);