]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_A53_64-bit_UltraScale_MPSoC/RTOSDemo_A53_bsp/psu_cortexa53_0/libsrc/usbpsu_v1_1/src/xusbpsu_intr.c
Update Zynq MPSoC hardware definition and BSP files to be those shipped with the...
[freertos] / FreeRTOS / Demo / CORTEX_A53_64-bit_UltraScale_MPSoC / RTOSDemo_A53_bsp / psu_cortexa53_0 / libsrc / usbpsu_v1_1 / src / xusbpsu_intr.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_intr.c
36 * @addtogroup usbpsu_v1_0
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 *
47 * </pre>
48 *
49 *****************************************************************************/
50
51 /***************************** Include Files ********************************/
52
53 #include "xusbpsu.h"
54
55 /************************** Constant Definitions *****************************/
56
57 /**************************** Type Definitions *******************************/
58
59 /***************** Macros (Inline Functions) Definitions *********************/
60
61 /************************** Function Prototypes ******************************/
62
63 /************************** Variable Definitions *****************************/
64
65 /****************************************************************************/
66 /**
67 * Endpoint interrupt handler.
68 *
69 * @param        InstancePtr is a pointer to the XUsbPsu instance.
70 * @param        Event is endpoint Event occured in the core.
71 *
72 * @return       None.
73 *
74 * @note         None.
75 *
76 *****************************************************************************/
77 void XUsbPsu_EpInterrupt(struct XUsbPsu *InstancePtr,
78                 const struct XUsbPsu_Event_Epevt *Event)
79 {
80         struct XUsbPsu_Ep *Ept;
81         u32 Epnum;
82
83         Epnum = Event->Epnumber;
84         Ept = &InstancePtr->eps[Epnum];
85
86         if ((Ept->EpStatus & XUSBPSU_EP_ENABLED) == (u32)0U) {
87                 return;
88         }
89
90         if ((Epnum == (u32)0) || (Epnum == (u32)1)) {
91                 XUsbPsu_Ep0Intr(InstancePtr, Event);
92                 return;
93         }
94
95         /* Handle other end point events */
96         switch (Event->Endpoint_Event) {
97                 case XUSBPSU_DEPEVT_XFERCOMPLETE:
98                         XUsbPsu_EpXferComplete(InstancePtr, Event);
99                         break;
100
101                 case XUSBPSU_DEPEVT_XFERNOTREADY:
102                         break;
103
104                 default:
105                         /* Made for Misra-C Compliance. */
106                         break;
107         }
108 }
109
110 /****************************************************************************/
111 /**
112 * Disconnect Interrupt handler.
113 *
114 * @param        InstancePtr is a pointer to the XUsbPsu instance.
115 *
116 * @return       None.
117 *
118 * @note         None.
119 *
120 *****************************************************************************/
121 void XUsbPsu_DisconnectIntr(struct XUsbPsu *InstancePtr)
122 {
123         u32 RegVal;
124
125         RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCTL);
126         RegVal &= ~XUSBPSU_DCTL_INITU1ENA;
127         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCTL, RegVal);
128
129         RegVal &= ~XUSBPSU_DCTL_INITU2ENA;
130         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCTL, RegVal);
131
132         InstancePtr->IsConfigDone = 0U;
133         InstancePtr->Speed = XUSBPSU_SPEED_UNKNOWN;
134 }
135
136 /****************************************************************************/
137 /**
138 * Reset Interrupt handler.
139 *
140 * @param        InstancePtr is a pointer to the XUsbPsu instance.
141 *
142 * @return       None.
143 *
144 * @note         None.
145 *
146 *****************************************************************************/
147 void XUsbPsu_ResetIntr(struct XUsbPsu *InstancePtr)
148 {
149         u32     RegVal;
150         u32     Index;
151
152         InstancePtr->State = XUSBPSU_STATE_DEFAULT;
153
154         RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DCTL);
155         RegVal &= ~XUSBPSU_DCTL_TSTCTRL_MASK;
156         XUsbPsu_WriteReg(InstancePtr, XUSBPSU_DCTL, RegVal);
157         InstancePtr->TestMode = 0U;
158
159         for (Index = 0U; Index < (InstancePtr->NumInEps + InstancePtr->NumOutEps);
160                         Index++)
161         {
162                 InstancePtr->eps[Index].EpStatus = 0U;
163         }
164
165         InstancePtr->IsConfigDone = 0U;
166
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);
171 }
172
173 /****************************************************************************/
174 /**
175 * Connection Done Interrupt handler.
176 *
177 * @param        InstancePtr is a pointer to the XUsbPsu instance.
178 *
179 * @return       None.
180 *
181 * @note         None.
182 *
183 *****************************************************************************/
184 void XUsbPsu_ConnDoneIntr(struct XUsbPsu *InstancePtr)
185 {
186         u32                     RegVal;
187         u16                     Size;
188         u8                      Speed;
189
190         RegVal = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_DSTS);
191         Speed = (u8)(RegVal & XUSBPSU_DSTS_CONNECTSPD);
192         InstancePtr->Speed = Speed;
193
194         switch (Speed) {
195         case XUSBPSU_DCFG_SUPERSPEED:
196 #ifdef XUSBPSU_DEBUG
197                 xil_printf("Super Speed\r\n");
198 #endif
199                 Size = 512U;
200                 InstancePtr->Speed = XUSBPSU_SPEED_SUPER;
201                 break;
202
203         case XUSBPSU_DCFG_HIGHSPEED:
204 #ifdef XUSBPSU_DEBUG
205                 xil_printf("High Speed\r\n");
206 #endif
207                 Size = 64U;
208                 InstancePtr->Speed = XUSBPSU_SPEED_HIGH;
209                 break;
210
211         case XUSBPSU_DCFG_FULLSPEED2:
212         case XUSBPSU_DCFG_FULLSPEED1:
213 #ifdef XUSBPSU_DEBUG
214                 xil_printf("Full Speed\r\n");
215 #endif
216                 Size = 64U;
217                 InstancePtr->Speed = XUSBPSU_SPEED_FULL;
218                 break;
219
220         case XUSBPSU_DCFG_LOWSPEED:
221 #ifdef XUSBPSU_DEBUG
222                 xil_printf("Low Speed\r\n");
223 #endif
224                 Size = 64U;
225                 InstancePtr->Speed = XUSBPSU_SPEED_LOW;
226                 break;
227         default :
228                 Size = 64U;
229                 break;
230         }
231
232         (void)XUsbPsu_EnableControlEp(InstancePtr, Size);
233         (void)XUsbPsu_RecvSetup(InstancePtr);
234 }
235
236 /****************************************************************************/
237 /**
238 * Link Status Change Interrupt handler.
239 *
240 * @param        InstancePtr is a pointer to the XUsbPsu instance.
241 * @param        EvtInfo is Event information.
242 *
243 * @return       None.
244 *
245 * @note         None.
246 *
247 *****************************************************************************/
248 void XUsbPsu_LinkStsChangeIntr(struct XUsbPsu *InstancePtr, u32 EvtInfo)
249 {
250         u32     State = EvtInfo & (u32)XUSBPSU_LINK_STATE_MASK;
251         InstancePtr->LinkState = (u8)State;
252 }
253
254 /****************************************************************************/
255 /**
256 * Interrupt handler for device specific events.
257 *
258 * @param        InstancePtr is a pointer to the XUsbPsu instance.
259 * @param        Event is the Device Event occured in core.
260 *
261 * @return       None.
262 *
263 * @note         None.
264 *
265 *****************************************************************************/
266 void XUsbPsu_DevInterrupt(struct XUsbPsu *InstancePtr,
267                 const struct XUsbPsu_Event_Devt *Event)
268 {
269
270         switch (Event->Type) {
271                 case XUSBPSU_DEVICE_EVENT_DISCONNECT:
272                         XUsbPsu_DisconnectIntr(InstancePtr);
273                         break;
274
275                 case XUSBPSU_DEVICE_EVENT_RESET:
276                         XUsbPsu_ResetIntr(InstancePtr);
277                         break;
278
279                 case XUSBPSU_DEVICE_EVENT_CONNECT_DONE:
280                         XUsbPsu_ConnDoneIntr(InstancePtr);
281                         break;
282
283                 case XUSBPSU_DEVICE_EVENT_WAKEUP:
284                         break;
285
286                 case XUSBPSU_DEVICE_EVENT_HIBER_REQ:
287                         break;
288
289                 case XUSBPSU_DEVICE_EVENT_LINK_STATUS_CHANGE:
290                         XUsbPsu_LinkStsChangeIntr(InstancePtr,
291                                         Event->Event_Info);
292                         break;
293
294                 case XUSBPSU_DEVICE_EVENT_EOPF:
295                         break;
296
297                 case XUSBPSU_DEVICE_EVENT_SOF:
298                         break;
299
300                 case XUSBPSU_DEVICE_EVENT_ERRATIC_ERROR:
301                         break;
302
303                 case XUSBPSU_DEVICE_EVENT_CMD_CMPL:
304                         break;
305
306                 case XUSBPSU_DEVICE_EVENT_OVERFLOW:
307                         break;
308
309                 default:
310                         /* Made for Misra-C Compliance. */
311                         break;
312         }
313 }
314
315 /****************************************************************************/
316 /**
317 * Processes an Event entry in Event Buffer.
318 *
319 * @param        InstancePtr is a pointer to the XUsbPsu instance.
320 * @param        Event is the Event entry.
321 *
322 * @return       None.
323 *
324 * @note         None.
325 *
326 *****************************************************************************/
327 void XUsbPsu_EventHandler(struct XUsbPsu *InstancePtr,
328                         const union XUsbPsu_Event *Event)
329 {
330
331         if (Event->Type.Is_DevEvt == 0U) {
332                 /* End point Specific Event */
333                 XUsbPsu_EpInterrupt(InstancePtr, &Event->Epevt);
334                 return;
335         }
336
337         switch (Event->Type.Type) {
338         case XUSBPSU_EVENT_TYPE_DEV:
339                 /* Device Specific Event */
340                 XUsbPsu_DevInterrupt(InstancePtr, &Event->Devt);
341                 break;
342         /* Carkit and I2C events not supported now */
343         default:
344                 /* Made for Misra-C Compliance. */
345                 break;
346         }
347 }
348
349 /****************************************************************************/
350 /**
351 * Processes events in an Event Buffer.
352 *
353 * @param        InstancePtr is a pointer to the XUsbPsu instance.
354 * @bus          Event buffer number.
355 *
356 * @return       None.
357 *
358 * @note         None.
359 *
360 *****************************************************************************/
361 void XUsbPsu_EventBufferHandler(struct XUsbPsu *InstancePtr)
362 {
363         struct XUsbPsu_EvtBuffer *Evt;
364         union XUsbPsu_Event Event = {0};
365
366         Evt = &InstancePtr->Evt;
367
368         Xil_DCacheInvalidateRange((INTPTR)Evt->BuffAddr,
369                               (u32)XUSBPSU_EVENT_BUFFERS_SIZE);
370
371         while (Evt->Count > 0) {
372                 Event.Raw = *(UINTPTR *)(Evt->BuffAddr + Evt->Offset);
373
374                 /*
375          * Process the event received
376          */
377         XUsbPsu_EventHandler(InstancePtr, &Event);
378
379                 Evt->Offset = (Evt->Offset + 4U) % XUSBPSU_EVENT_BUFFERS_SIZE;
380                 Evt->Count -= 4;
381                 XUsbPsu_WriteReg(InstancePtr, XUSBPSU_GEVNTCOUNT(0), 4U);
382         }
383
384         Evt->Flags &= ~XUSBPSU_EVENT_PENDING;
385 }
386
387 /****************************************************************************/
388 /**
389 * Main Interrupt Handler.
390 *
391 * @return       None.
392 *
393 * @note         None.
394 *
395 *****************************************************************************/
396 void XUsbPsu_IntrHandler(void *XUsbPsuInstancePtr)
397 {
398         struct XUsbPsu  *InstancePtr;
399         struct XUsbPsu_EvtBuffer *Evt;
400         u32 Count;
401         u32 RegVal;
402
403         InstancePtr = XUsbPsuInstancePtr;
404
405         Evt = &InstancePtr->Evt;
406
407         Count = XUsbPsu_ReadReg(InstancePtr, XUSBPSU_GEVNTCOUNT(0));
408         Count &= XUSBPSU_GEVNTCOUNT_MASK;
409         /*
410          * As per data book software should only process Events if Event count
411          * is greater than zero.
412          */
413         if (Count == 0U) {
414                 return;
415         }
416
417         Evt->Count = Count;
418         Evt->Flags |= XUSBPSU_EVENT_PENDING;
419
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);
424
425         /* Processes events in an Event Buffer */
426         XUsbPsu_EventBufferHandler(InstancePtr);
427
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);
432 }
433
434 /** @} */