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>&copy; 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