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