1 /**
2 ******************************************************************************
3 * @file usb_dcd_int.c
4 * @author MCD Application Team
5 * @version V2.0.0
6 * @date 22-July-2011
7 * @brief Peripheral Device interrupt subroutines
8 ******************************************************************************
9 * @attention
10 *
11 * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
12 * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
13 * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
14 * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
15 * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
16 * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
17 *
18 * <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
19 ******************************************************************************
20 */
21
22 #include "usb_conf.h"
23 #ifdef USE_DEVICE_MODE
24 /* Includes ------------------------------------------------------------------*/
25 #include "usb_dcd_int.h"
26 /** @addtogroup USB_OTG_DRIVER
27 * @{
28 */
29
30 /** @defgroup USB_DCD_INT
31 * @brief This file contains the interrupt subroutines for the Device mode.
32 * @{
33 */
34
35
36 /** @defgroup USB_DCD_INT_Private_Defines
37 * @{
38 */
39 /**
40 * @}
41 */
42
43
44 /** @defgroup USB_DCD_INT_Private_TypesDefinitions
45 * @{
46 */
47 /**
48 * @}
49 */
50
51
52
53 /** @defgroup USB_DCD_INT_Private_Macros
54 * @{
55 */
56 /**
57 * @}
58 */
59
60
61 /** @defgroup USB_DCD_INT_Private_Variables
62 * @{
63 */
64 /**
65 * @}
66 */
67
68
69 /** @defgroup USB_DCD_INT_Private_FunctionPrototypes
70 * @{
71 */
72 /* static functions */
73 static uint32_t DCD_ReadDevInEP (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum);
74
75 /* Interrupt Handlers */
76 static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev);
77 static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev);
78 static uint32_t DCD_HandleSof_ISR(USB_OTG_CORE_HANDLE *pdev);
79
80 static uint32_t DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev);
81 static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev , uint32_t epnum);
82
83 static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev);
84 static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev);
85 static uint32_t DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE *pdev);
86 static uint32_t DCD_HandleUSBSuspend_ISR(USB_OTG_CORE_HANDLE *pdev);
87
88 static uint32_t DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev);
89 static uint32_t DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev);
90 #ifdef VBUS_SENSING_ENABLED
91 static uint32_t DCD_SessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev);
92 static uint32_t DCD_OTG_ISR(USB_OTG_CORE_HANDLE *pdev);
93 #endif
94
95 /**
96 * @}
97 */
98
99
100 /** @defgroup USB_DCD_INT_Private_Functions
101 * @{
102 */
103
104
105 #ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
106 /**
107 * @brief USBD_OTG_EP1OUT_ISR_Handler
108 * handles all USB Interrupts
109 * @param pdev: device instance
110 * @retval status
111 */
USBD_OTG_EP1OUT_ISR_Handler(USB_OTG_CORE_HANDLE * pdev)112 uint32_t USBD_OTG_EP1OUT_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
113 {
114
115 USB_OTG_DOEPINTn_TypeDef doepint;
116 USB_OTG_DEPXFRSIZ_TypeDef deptsiz;
117
118 doepint.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[1]->DOEPINT);
119 doepint.d32&= USB_OTG_READ_REG32(&pdev->regs.DREGS->DOUTEP1MSK);
120
121 /* Transfer complete */
122 if ( doepint.b.xfercompl )
123 {
124 /* Clear the bit in DOEPINTn for this interrupt */
125 CLEAR_OUT_EP_INTR(1, xfercompl);
126 if (pdev->cfg.dma_enable == 1)
127 {
128 deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[1]->DOEPTSIZ));
129 /*ToDo : handle more than one single MPS size packet */
130 pdev->dev.out_ep[1].xfer_count = pdev->dev.out_ep[1].maxpacket - \
131 deptsiz.b.xfersize;
132 }
133 /* Inform upper layer: data ready */
134 /* RX COMPLETE */
135 USBD_DCD_INT_fops->DataOutStage(pdev , 1);
136
137 }
138
139 /* Endpoint disable */
140 if ( doepint.b.epdisabled )
141 {
142 /* Clear the bit in DOEPINTn for this interrupt */
143 CLEAR_OUT_EP_INTR(1, epdisabled);
144 }
145 /* AHB Error */
146 if ( doepint.b.ahberr )
147 {
148 CLEAR_OUT_EP_INTR(1, ahberr);
149 }
150 return 1;
151 }
152
153 /**
154 * @brief USBD_OTG_EP1IN_ISR_Handler
155 * handles all USB Interrupts
156 * @param pdev: device instance
157 * @retval status
158 */
USBD_OTG_EP1IN_ISR_Handler(USB_OTG_CORE_HANDLE * pdev)159 uint32_t USBD_OTG_EP1IN_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
160 {
161
162 USB_OTG_DIEPINTn_TypeDef diepint;
163 uint32_t fifoemptymsk, msk, emp;
164
165 msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DINEP1MSK);
166 emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK);
167 msk |= ((emp >> 1 ) & 0x1) << 7;
168 diepint.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[1]->DIEPINT) & msk;
169
170 if ( diepint.b.xfercompl )
171 {
172 fifoemptymsk = 0x1 << 1;
173 USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0);
174 CLEAR_IN_EP_INTR(1, xfercompl);
175 /* TX COMPLETE */
176 USBD_DCD_INT_fops->DataInStage(pdev , 1);
177 }
178 if ( diepint.b.ahberr )
179 {
180 CLEAR_IN_EP_INTR(1, ahberr);
181 }
182 if ( diepint.b.epdisabled )
183 {
184 CLEAR_IN_EP_INTR(1, epdisabled);
185 }
186 if ( diepint.b.timeout )
187 {
188 CLEAR_IN_EP_INTR(1, timeout);
189 }
190 if (diepint.b.intktxfemp)
191 {
192 CLEAR_IN_EP_INTR(1, intktxfemp);
193 }
194 if (diepint.b.intknepmis)
195 {
196 CLEAR_IN_EP_INTR(1, intknepmis);
197 }
198 if (diepint.b.inepnakeff)
199 {
200 CLEAR_IN_EP_INTR(1, inepnakeff);
201 }
202 if (diepint.b.emptyintr)
203 {
204 DCD_WriteEmptyTxFifo(pdev , 1);
205 CLEAR_IN_EP_INTR(1, emptyintr);
206 }
207 return 1;
208 }
209 #endif
210
211 /**
212 * @brief STM32_USBF_OTG_ISR_Handler
213 * handles all USB Interrupts
214 * @param pdev: device instance
215 * @retval status
216 */
USBD_OTG_ISR_Handler(USB_OTG_CORE_HANDLE * pdev)217 uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
218 {
219 USB_OTG_GINTSTS_TypeDef gintr_status;
220 uint32_t retval = 0;
221
222 if (USB_OTG_IsDeviceMode(pdev)) /* ensure that we are in device mode */
223 {
224 gintr_status.d32 = USB_OTG_ReadCoreItr(pdev);
225 if (!gintr_status.d32) /* avoid spurious interrupt */
226 {
227 return 0;
228 }
229
230 if (gintr_status.b.outepintr)
231 {
232 retval |= DCD_HandleOutEP_ISR(pdev);
233 }
234
235 if (gintr_status.b.inepint)
236 {
237 retval |= DCD_HandleInEP_ISR(pdev);
238 }
239
240 if (gintr_status.b.modemismatch)
241 {
242 USB_OTG_GINTSTS_TypeDef gintsts;
243
244 /* Clear interrupt */
245 gintsts.d32 = 0;
246 gintsts.b.modemismatch = 1;
247 USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
248 }
249
250 if (gintr_status.b.wkupintr)
251 {
252 retval |= DCD_HandleResume_ISR(pdev);
253 }
254
255 if (gintr_status.b.usbsuspend)
256 {
257 retval |= DCD_HandleUSBSuspend_ISR(pdev);
258 }
259 if (gintr_status.b.sofintr)
260 {
261 retval |= DCD_HandleSof_ISR(pdev);
262
263 }
264
265 if (gintr_status.b.rxstsqlvl)
266 {
267 retval |= DCD_HandleRxStatusQueueLevel_ISR(pdev);
268
269 }
270
271 if (gintr_status.b.usbreset)
272 {
273 retval |= DCD_HandleUsbReset_ISR(pdev);
274
275 }
276 if (gintr_status.b.enumdone)
277 {
278 retval |= DCD_HandleEnumDone_ISR(pdev);
279 }
280
281 if (gintr_status.b.incomplisoin)
282 {
283 retval |= DCD_IsoINIncomplete_ISR(pdev);
284 }
285
286 if (gintr_status.b.incomplisoout)
287 {
288 retval |= DCD_IsoOUTIncomplete_ISR(pdev);
289 }
290 #ifdef VBUS_SENSING_ENABLED
291 if (gintr_status.b.sessreqintr)
292 {
293 retval |= DCD_SessionRequest_ISR(pdev);
294 }
295
296 if (gintr_status.b.otgintr)
297 {
298 retval |= DCD_OTG_ISR(pdev);
299 }
300 #endif
301 }
302 return retval;
303 }
304
305 #ifdef VBUS_SENSING_ENABLED
306 /**
307 * @brief DCD_SessionRequest_ISR
308 * Indicates that the USB_OTG controller has detected a connection
309 * @param pdev: device instance
310 * @retval status
311 */
DCD_SessionRequest_ISR(USB_OTG_CORE_HANDLE * pdev)312 static uint32_t DCD_SessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev)
313 {
314 USB_OTG_GINTSTS_TypeDef gintsts;
315 USBD_DCD_INT_fops->DevConnected (pdev);
316
317 /* Clear interrupt */
318 gintsts.d32 = 0;
319 gintsts.b.sessreqintr = 1;
320 USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
321 return 1;
322 }
323
324 /**
325 * @brief DCD_OTG_ISR
326 * Indicates that the USB_OTG controller has detected an OTG event:
327 * used to detect the end of session i.e. disconnection
328 * @param pdev: device instance
329 * @retval status
330 */
DCD_OTG_ISR(USB_OTG_CORE_HANDLE * pdev)331 static uint32_t DCD_OTG_ISR(USB_OTG_CORE_HANDLE *pdev)
332 {
333
334 USB_OTG_GOTGINT_TypeDef gotgint;
335
336 gotgint.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGINT);
337
338 if (gotgint.b.sesenddet)
339 {
340 USBD_DCD_INT_fops->DevDisconnected (pdev);
341 }
342 /* Clear OTG interrupt */
343 USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GOTGINT, gotgint.d32);
344 return 1;
345 }
346 #endif
347 /**
348 * @brief DCD_HandleResume_ISR
349 * Indicates that the USB_OTG controller has detected a resume or
350 * remote Wake-up sequence
351 * @param pdev: device instance
352 * @retval status
353 */
DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE * pdev)354 static uint32_t DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE *pdev)
355 {
356 USB_OTG_GINTSTS_TypeDef gintsts;
357 USB_OTG_DCTL_TypeDef devctl;
358 USB_OTG_PCGCCTL_TypeDef power;
359
360 if(pdev->cfg.low_power)
361 {
362 /* un-gate USB Core clock */
363 power.d32 = USB_OTG_READ_REG32(pdev->regs.PCGCCTL);
364 power.b.gatehclk = 0;
365 power.b.stoppclk = 0;
366 USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32);
367 }
368
369 /* Clear the Remote Wake-up Signaling */
370 devctl.d32 = 0;
371 devctl.b.rmtwkupsig = 1;
372 USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, devctl.d32, 0);
373
374 /* Inform upper layer by the Resume Event */
375 USBD_DCD_INT_fops->Resume (pdev);
376
377 /* Clear interrupt */
378 gintsts.d32 = 0;
379 gintsts.b.wkupintr = 1;
380 USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
381 return 1;
382 }
383
384 /**
385 * @brief USB_OTG_HandleUSBSuspend_ISR
386 * Indicates that SUSPEND state has been detected on the USB
387 * @param pdev: device instance
388 * @retval status
389 */
DCD_HandleUSBSuspend_ISR(USB_OTG_CORE_HANDLE * pdev)390 static uint32_t DCD_HandleUSBSuspend_ISR(USB_OTG_CORE_HANDLE *pdev)
391 {
392 USB_OTG_GINTSTS_TypeDef gintsts;
393 USB_OTG_PCGCCTL_TypeDef power;
394 USB_OTG_DSTS_TypeDef dsts;
395
396 USBD_DCD_INT_fops->Suspend (pdev);
397
398 dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
399
400 /* Clear interrupt */
401 gintsts.d32 = 0;
402 gintsts.b.usbsuspend = 1;
403 USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
404
405 if((pdev->cfg.low_power) && (dsts.b.suspsts == 1))
406 {
407 /* switch-off the clocks */
408 power.d32 = 0;
409 power.b.stoppclk = 1;
410 USB_OTG_MODIFY_REG32(pdev->regs.PCGCCTL, 0, power.d32);
411
412 power.b.gatehclk = 1;
413 USB_OTG_MODIFY_REG32(pdev->regs.PCGCCTL, 0, power.d32);
414
415 /* Request to enter Sleep mode after exit from current ISR */
416 SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk);
417 }
418 return 1;
419 }
420
421 /**
422 * @brief DCD_HandleInEP_ISR
423 * Indicates that an IN EP has a pending Interrupt
424 * @param pdev: device instance
425 * @retval status
426 */
DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE * pdev)427 static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev)
428 {
429 USB_OTG_DIEPINTn_TypeDef diepint;
430
431 uint32_t ep_intr;
432 uint32_t epnum = 0;
433 uint32_t fifoemptymsk;
434 diepint.d32 = 0;
435 ep_intr = USB_OTG_ReadDevAllInEPItr(pdev);
436
437 while ( ep_intr )
438 {
439 if (ep_intr&0x1) /* In ITR */
440 {
441 diepint.d32 = DCD_ReadDevInEP(pdev , epnum); /* Get In ITR status */
442 if ( diepint.b.xfercompl )
443 {
444 fifoemptymsk = 0x1 << epnum;
445 USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0);
446 CLEAR_IN_EP_INTR(epnum, xfercompl);
447 /* TX COMPLETE */
448 USBD_DCD_INT_fops->DataInStage(pdev , epnum);
449
450 if (pdev->cfg.dma_enable == 1)
451 {
452 if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_IN))
453 {
454 /* prepare to rx more setup packets */
455 USB_OTG_EP0_OutStart(pdev);
456 }
457 }
458 }
459 if ( diepint.b.ahberr )
460 {
461 CLEAR_IN_EP_INTR(epnum, ahberr);
462 }
463 if ( diepint.b.timeout )
464 {
465 CLEAR_IN_EP_INTR(epnum, timeout);
466 }
467 if (diepint.b.intktxfemp)
468 {
469 CLEAR_IN_EP_INTR(epnum, intktxfemp);
470 }
471 if (diepint.b.intknepmis)
472 {
473 CLEAR_IN_EP_INTR(epnum, intknepmis);
474 }
475 if (diepint.b.inepnakeff)
476 {
477 CLEAR_IN_EP_INTR(epnum, inepnakeff);
478 }
479 if ( diepint.b.epdisabled )
480 {
481 CLEAR_IN_EP_INTR(epnum, epdisabled);
482 }
483 if (diepint.b.emptyintr)
484 {
485
486 DCD_WriteEmptyTxFifo(pdev , epnum);
487
488 CLEAR_IN_EP_INTR(epnum, emptyintr);
489 }
490 }
491 epnum++;
492 ep_intr >>= 1;
493 }
494
495 return 1;
496 }
497
498 /**
499 * @brief DCD_HandleOutEP_ISR
500 * Indicates that an OUT EP has a pending Interrupt
501 * @param pdev: device instance
502 * @retval status
503 */
DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE * pdev)504 static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev)
505 {
506 uint32_t ep_intr;
507 USB_OTG_DOEPINTn_TypeDef doepint;
508 USB_OTG_DEPXFRSIZ_TypeDef deptsiz;
509 uint32_t epnum = 0;
510
511 doepint.d32 = 0;
512
513 /* Read in the device interrupt bits */
514 ep_intr = USB_OTG_ReadDevAllOutEp_itr(pdev);
515
516 while ( ep_intr )
517 {
518 if (ep_intr&0x1)
519 {
520
521 doepint.d32 = USB_OTG_ReadDevOutEP_itr(pdev, epnum);
522
523 /* Transfer complete */
524 if ( doepint.b.xfercompl )
525 {
526 /* Clear the bit in DOEPINTn for this interrupt */
527 CLEAR_OUT_EP_INTR(epnum, xfercompl);
528 if (pdev->cfg.dma_enable == 1)
529 {
530 deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[epnum]->DOEPTSIZ));
531 /*ToDo : handle more than one single MPS size packet */
532 pdev->dev.out_ep[epnum].xfer_count = pdev->dev.out_ep[epnum].maxpacket - \
533 deptsiz.b.xfersize;
534 }
535 /* Inform upper layer: data ready */
536 /* RX COMPLETE */
537 USBD_DCD_INT_fops->DataOutStage(pdev , epnum);
538
539 if (pdev->cfg.dma_enable == 1)
540 {
541 if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_OUT))
542 {
543 /* prepare to rx more setup packets */
544 USB_OTG_EP0_OutStart(pdev);
545 }
546 }
547 }
548 /* Endpoint disable */
549 if ( doepint.b.epdisabled )
550 {
551 /* Clear the bit in DOEPINTn for this interrupt */
552 CLEAR_OUT_EP_INTR(epnum, epdisabled);
553 }
554 /* AHB Error */
555 if ( doepint.b.ahberr )
556 {
557 CLEAR_OUT_EP_INTR(epnum, ahberr);
558 }
559 /* Setup Phase Done (control EPs) */
560 if ( doepint.b.setup )
561 {
562
563 /* inform the upper layer that a setup packet is available */
564 /* SETUP COMPLETE */
565 USBD_DCD_INT_fops->SetupStage(pdev);
566 CLEAR_OUT_EP_INTR(epnum, setup);
567 }
568 }
569 epnum++;
570 ep_intr >>= 1;
571 }
572 return 1;
573 }
574
575 /**
576 * @brief DCD_HandleSof_ISR
577 * Handles the SOF Interrupts
578 * @param pdev: device instance
579 * @retval status
580 */
DCD_HandleSof_ISR(USB_OTG_CORE_HANDLE * pdev)581 static uint32_t DCD_HandleSof_ISR(USB_OTG_CORE_HANDLE *pdev)
582 {
583 USB_OTG_GINTSTS_TypeDef GINTSTS;
584
585
586 USBD_DCD_INT_fops->SOF(pdev);
587
588 /* Clear interrupt */
589 GINTSTS.d32 = 0;
590 GINTSTS.b.sofintr = 1;
591 USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, GINTSTS.d32);
592
593 return 1;
594 }
595
596 /**
597 * @brief DCD_HandleRxStatusQueueLevel_ISR
598 * Handles the Rx Status Queue Level Interrupt
599 * @param pdev: device instance
600 * @retval status
601 */
DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE * pdev)602 static uint32_t DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev)
603 {
604 USB_OTG_GINTMSK_TypeDef int_mask;
605 USB_OTG_DRXSTS_TypeDef status;
606 USB_OTG_EP *ep;
607
608 /* Disable the Rx Status Queue Level interrupt */
609 int_mask.d32 = 0;
610 int_mask.b.rxstsqlvl = 1;
611 USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, int_mask.d32, 0);
612
613 /* Get the Status from the top of the FIFO */
614 status.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRXSTSP );
615
616 ep = &pdev->dev.out_ep[status.b.epnum];
617
618 switch (status.b.pktsts)
619 {
620 case STS_GOUT_NAK:
621 break;
622 case STS_DATA_UPDT:
623 if (status.b.bcnt)
624 {
625 USB_OTG_ReadPacket(pdev,ep->xfer_buff, status.b.bcnt);
626 ep->xfer_buff += status.b.bcnt;
627 ep->xfer_count += status.b.bcnt;
628 }
629 break;
630 case STS_XFER_COMP:
631 break;
632 case STS_SETUP_COMP:
633 break;
634 case STS_SETUP_UPDT:
635 /* Copy the setup packet received in FIFO into the setup buffer in RAM */
636 USB_OTG_ReadPacket(pdev , pdev->dev.setup_packet, 8);
637 ep->xfer_count += status.b.bcnt;
638 break;
639 default:
640 break;
641 }
642
643 /* Enable the Rx Status Queue Level interrupt */
644 USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, int_mask.d32);
645
646 return 1;
647 }
648
649 /**
650 * @brief DCD_WriteEmptyTxFifo
651 * check FIFO for the next packet to be loaded
652 * @param pdev: device instance
653 * @retval status
654 */
DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE * pdev,uint32_t epnum)655 static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev, uint32_t epnum)
656 {
657 USB_OTG_DTXFSTSn_TypeDef txstatus;
658 USB_OTG_EP *ep;
659 uint32_t len = 0;
660 uint32_t len32b;
661 txstatus.d32 = 0;
662
663 ep = &pdev->dev.in_ep[epnum];
664
665 len = ep->xfer_len - ep->xfer_count;
666
667 if (len > ep->maxpacket)
668 {
669 len = ep->maxpacket;
670 }
671
672 len32b = (len + 3) / 4;
673 txstatus.d32 = USB_OTG_READ_REG32( &pdev->regs.INEP_REGS[epnum]->DTXFSTS);
674
675
676
677 while (txstatus.b.txfspcavail > len32b &&
678 ep->xfer_count < ep->xfer_len &&
679 ep->xfer_len != 0)
680 {
681 /* Write the FIFO */
682 len = ep->xfer_len - ep->xfer_count;
683
684 if (len > ep->maxpacket)
685 {
686 len = ep->maxpacket;
687 }
688 len32b = (len + 3) / 4;
689
690 USB_OTG_WritePacket (pdev , ep->xfer_buff, epnum, len);
691
692 ep->xfer_buff += len;
693 ep->xfer_count += len;
694
695 txstatus.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DTXFSTS);
696 }
697
698 return 1;
699 }
700
701 /**
702 * @brief DCD_HandleUsbReset_ISR
703 * This interrupt occurs when a USB Reset is detected
704 * @param pdev: device instance
705 * @retval status
706 */
DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE * pdev)707 static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev)
708 {
709 USB_OTG_DAINT_TypeDef daintmsk;
710 USB_OTG_DOEPMSK_TypeDef doepmsk;
711 USB_OTG_DIEPMSK_TypeDef diepmsk;
712 USB_OTG_DCFG_TypeDef dcfg;
713 USB_OTG_DCTL_TypeDef dctl;
714 USB_OTG_GINTSTS_TypeDef gintsts;
715 uint32_t i;
716
717 dctl.d32 = 0;
718 daintmsk.d32 = 0;
719 doepmsk.d32 = 0;
720 diepmsk.d32 = 0;
721 dcfg.d32 = 0;
722 gintsts.d32 = 0;
723
724 /* Clear the Remote Wake-up Signaling */
725 dctl.b.rmtwkupsig = 1;
726 USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, 0 );
727
728 /* Flush the Tx FIFO */
729 USB_OTG_FlushTxFifo(pdev , 0 );
730
731 for (i = 0; i < pdev->cfg.dev_endpoints ; i++)
732 {
733 USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF);
734 USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF);
735 }
736 USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF );
737
738 daintmsk.ep.in = 1;
739 daintmsk.ep.out = 1;
740 USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, daintmsk.d32 );
741
742 doepmsk.b.setup = 1;
743 doepmsk.b.xfercompl = 1;
744 doepmsk.b.ahberr = 1;
745 doepmsk.b.epdisabled = 1;
746 USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, doepmsk.d32 );
747 #ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
748 USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOUTEP1MSK, doepmsk.d32 );
749 #endif
750 diepmsk.b.xfercompl = 1;
751 diepmsk.b.timeout = 1;
752 diepmsk.b.epdisabled = 1;
753 diepmsk.b.ahberr = 1;
754 diepmsk.b.intknepmis = 1;
755 USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, diepmsk.d32 );
756 #ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
757 USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DINEP1MSK, diepmsk.d32 );
758 #endif
759 /* Reset Device Address */
760 dcfg.d32 = USB_OTG_READ_REG32( &pdev->regs.DREGS->DCFG);
761 dcfg.b.devaddr = 0;
762 USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DCFG, dcfg.d32);
763
764
765 /* setup EP0 to receive SETUP packets */
766 USB_OTG_EP0_OutStart(pdev);
767
768 /* Clear interrupt */
769 gintsts.d32 = 0;
770 gintsts.b.usbreset = 1;
771 USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
772
773 /*Reset internal state machine */
774 USBD_DCD_INT_fops->Reset(pdev);
775 return 1;
776 }
777
778 /**
779 * @brief DCD_HandleEnumDone_ISR
780 * Read the device status register and set the device speed
781 * @param pdev: device instance
782 * @retval status
783 */
DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE * pdev)784 static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev)
785 {
786 USB_OTG_GINTSTS_TypeDef gintsts;
787 USB_OTG_GUSBCFG_TypeDef gusbcfg;
788
789 USB_OTG_EP0Activate(pdev);
790
791 /* Set USB turn-around time based on device speed and PHY interface. */
792 gusbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);
793
794 /* Full or High speed */
795 if ( USB_OTG_GetDeviceSpeed(pdev) == USB_SPEED_HIGH)
796 {
797 pdev->cfg.speed = USB_OTG_SPEED_HIGH;
798 pdev->cfg.mps = USB_OTG_HS_MAX_PACKET_SIZE ;
799 gusbcfg.b.usbtrdtim = 9;
800 }
801 else
802 {
803 pdev->cfg.speed = USB_OTG_SPEED_FULL;
804 pdev->cfg.mps = USB_OTG_FS_MAX_PACKET_SIZE ;
805 gusbcfg.b.usbtrdtim = 5;
806 }
807
808 USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, gusbcfg.d32);
809
810 /* Clear interrupt */
811 gintsts.d32 = 0;
812 gintsts.b.enumdone = 1;
813 USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, gintsts.d32 );
814 return 1;
815 }
816
817
818 /**
819 * @brief DCD_IsoINIncomplete_ISR
820 * handle the ISO IN incomplete interrupt
821 * @param pdev: device instance
822 * @retval status
823 */
DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE * pdev)824 static uint32_t DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev)
825 {
826 USB_OTG_GINTSTS_TypeDef gintsts;
827
828 gintsts.d32 = 0;
829
830 USBD_DCD_INT_fops->IsoINIncomplete (pdev);
831
832 /* Clear interrupt */
833 gintsts.b.incomplisoin = 1;
834 USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
835
836 return 1;
837 }
838
839 /**
840 * @brief DCD_IsoOUTIncomplete_ISR
841 * handle the ISO OUT incomplete interrupt
842 * @param pdev: device instance
843 * @retval status
844 */
DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE * pdev)845 static uint32_t DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev)
846 {
847 USB_OTG_GINTSTS_TypeDef gintsts;
848
849 gintsts.d32 = 0;
850
851 USBD_DCD_INT_fops->IsoOUTIncomplete (pdev);
852
853 /* Clear interrupt */
854 gintsts.b.incomplisoout = 1;
855 USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
856 return 1;
857 }
858 /**
859 * @brief DCD_ReadDevInEP
860 * Reads ep flags
861 * @param pdev: device instance
862 * @retval status
863 */
DCD_ReadDevInEP(USB_OTG_CORE_HANDLE * pdev,uint8_t epnum)864 static uint32_t DCD_ReadDevInEP (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
865 {
866 uint32_t v, msk, emp;
867 msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPMSK);
868 emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK);
869 msk |= ((emp >> epnum) & 0x1) << 7;
870 v = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DIEPINT) & msk;
871 return v;
872 }
873
874
875
876 /**
877 * @}
878 */
879
880 /**
881 * @}
882 */
883
884 /**
885 * @}
886 */
887 #endif
888
889 /******************* (C) COPYRIGHT 2011 STMicroelectronics *****END OF FILE****/
890