Updated and Validated
[betaflight.git] / lib / main / STM32_USB_OTG_Driver / src / usb_dcd_int.c
blobfe05306b02a8f269e53a7f953ab92a5770976baa
1 /**
2 ******************************************************************************
3 * @file usb_dcd_int.c
4 * @author MCD Application Team
5 * @version V2.2.0
6 * @date 09-November-2015
7 * @brief Peripheral Device interrupt subroutines
8 ******************************************************************************
9 * @attention
11 * <h2><center>&copy; COPYRIGHT 2015 STMicroelectronics</center></h2>
13 * Licensed under MCD-ST Liberty SW License Agreement V2, (the "License");
14 * You may not use this file except in compliance with the License.
15 * You may obtain a copy of the License at:
17 * http://www.st.com/software_license_agreement_liberty_v2
19 * Unless required by applicable law or agreed to in writing, software
20 * distributed under the License is distributed on an "AS IS" BASIS,
21 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
22 * See the License for the specific language governing permissions and
23 * limitations under the License.
25 ******************************************************************************
28 /* Includes ------------------------------------------------------------------*/
29 #include "usb_dcd_int.h"
30 /** @addtogroup USB_OTG_DRIVER
31 * @{
34 /** @defgroup USB_DCD_INT
35 * @brief This file contains the interrupt subroutines for the Device mode.
36 * @{
40 /** @defgroup USB_DCD_INT_Private_Defines
41 * @{
42 */
43 /**
44 * @}
45 */
48 /** @defgroup USB_DCD_INT_Private_TypesDefinitions
49 * @{
50 */
51 /**
52 * @}
53 */
57 /** @defgroup USB_DCD_INT_Private_Macros
58 * @{
59 */
60 /**
61 * @}
62 */
65 /** @defgroup USB_DCD_INT_Private_Variables
66 * @{
67 */
68 /**
69 * @}
70 */
73 /** @defgroup USB_DCD_INT_Private_FunctionPrototypes
74 * @{
75 */
76 /* static functions */
77 static uint32_t DCD_ReadDevInEP (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum);
79 /* Interrupt Handlers */
80 static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev);
81 static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev);
82 static uint32_t DCD_HandleSof_ISR(USB_OTG_CORE_HANDLE *pdev);
84 static uint32_t DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev);
85 static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev , uint32_t epnum);
87 static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev);
88 static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev);
89 static uint32_t DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE *pdev);
90 static uint32_t DCD_HandleUSBSuspend_ISR(USB_OTG_CORE_HANDLE *pdev);
92 static uint32_t DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev);
93 static uint32_t DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev);
94 #ifdef VBUS_SENSING_ENABLED
95 static uint32_t DCD_SessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev);
96 static uint32_t DCD_OTG_ISR(USB_OTG_CORE_HANDLE *pdev);
97 #endif
99 /**
100 * @}
104 /** @defgroup USB_DCD_INT_Private_Functions
105 * @{
109 #ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
111 * @brief USBD_OTG_EP1OUT_ISR_Handler
112 * handles all USB Interrupts
113 * @param pdev: device instance
114 * @retval status
116 uint32_t USBD_OTG_EP1OUT_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
119 USB_OTG_DOEPINTn_TypeDef doepint;
120 USB_OTG_DEPXFRSIZ_TypeDef deptsiz;
122 doepint.d32 = USB_OTG_READ_REG32(&pdev->regs.OUTEP_REGS[1]->DOEPINT);
123 doepint.d32&= USB_OTG_READ_REG32(&pdev->regs.DREGS->DOUTEP1MSK);
125 /* Transfer complete */
126 if ( doepint.b.xfercompl )
128 /* Clear the bit in DOEPINTn for this interrupt */
129 CLEAR_OUT_EP_INTR(1, xfercompl);
130 if (pdev->cfg.dma_enable == 1)
132 deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[1]->DOEPTSIZ));
133 pdev->dev.out_ep[1].xfer_count = pdev->dev.out_ep[1].xfer_len- \
134 deptsiz.b.xfersize;
136 /* Inform upper layer: data ready */
137 /* RX COMPLETE */
138 USBD_DCD_INT_fops->DataOutStage(pdev , 1);
142 /* Endpoint disable */
143 if ( doepint.b.epdisabled )
145 /* Clear the bit in DOEPINTn for this interrupt */
146 CLEAR_OUT_EP_INTR(1, epdisabled);
149 return 1;
153 * @brief USBD_OTG_EP1IN_ISR_Handler
154 * handles all USB Interrupts
155 * @param pdev: device instance
156 * @retval status
158 uint32_t USBD_OTG_EP1IN_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
161 USB_OTG_DIEPINTn_TypeDef diepint;
162 uint32_t fifoemptymsk, msk, emp;
164 msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DINEP1MSK);
165 emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK);
166 msk |= ((emp >> 1 ) & 0x1) << 7;
167 diepint.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[1]->DIEPINT) & msk;
169 if ( diepint.b.xfercompl )
171 fifoemptymsk = 0x1 << 1;
172 USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0);
173 CLEAR_IN_EP_INTR(1, xfercompl);
174 /* TX COMPLETE */
175 USBD_DCD_INT_fops->DataInStage(pdev , 1);
177 if ( diepint.b.epdisabled )
179 CLEAR_IN_EP_INTR(1, epdisabled);
181 if ( diepint.b.timeout )
183 CLEAR_IN_EP_INTR(1, timeout);
185 if (diepint.b.intktxfemp)
187 CLEAR_IN_EP_INTR(1, intktxfemp);
189 if (diepint.b.inepnakeff)
191 CLEAR_IN_EP_INTR(1, inepnakeff);
193 if (diepint.b.emptyintr)
195 DCD_WriteEmptyTxFifo(pdev , 1);
197 return 1;
199 #endif
202 * @brief STM32_USBF_OTG_ISR_Handler
203 * handles all USB Interrupts
204 * @param pdev: device instance
205 * @retval status
207 uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
209 USB_OTG_GINTSTS_TypeDef gintr_status;
210 uint32_t retval = 0;
212 if (USB_OTG_IsDeviceMode(pdev)) /* ensure that we are in device mode */
214 gintr_status.d32 = USB_OTG_ReadCoreItr(pdev);
215 if (!gintr_status.d32) /* avoid spurious interrupt */
217 return 0;
220 if (gintr_status.b.outepintr)
222 retval |= DCD_HandleOutEP_ISR(pdev);
225 if (gintr_status.b.inepint)
227 retval |= DCD_HandleInEP_ISR(pdev);
230 if (gintr_status.b.modemismatch)
232 USB_OTG_GINTSTS_TypeDef gintsts;
234 /* Clear interrupt */
235 gintsts.d32 = 0;
236 gintsts.b.modemismatch = 1;
237 USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
240 if (gintr_status.b.wkupintr)
242 retval |= DCD_HandleResume_ISR(pdev);
245 if (gintr_status.b.usbsuspend)
247 retval |= DCD_HandleUSBSuspend_ISR(pdev);
249 if (gintr_status.b.sofintr)
251 retval |= DCD_HandleSof_ISR(pdev);
255 if (gintr_status.b.rxstsqlvl)
257 retval |= DCD_HandleRxStatusQueueLevel_ISR(pdev);
261 if (gintr_status.b.usbreset)
263 retval |= DCD_HandleUsbReset_ISR(pdev);
266 if (gintr_status.b.enumdone)
268 retval |= DCD_HandleEnumDone_ISR(pdev);
271 if (gintr_status.b.incomplisoin)
273 retval |= DCD_IsoINIncomplete_ISR(pdev);
276 if (gintr_status.b.incomplisoout)
278 retval |= DCD_IsoOUTIncomplete_ISR(pdev);
280 #ifdef VBUS_SENSING_ENABLED
281 if (gintr_status.b.sessreqintr)
283 retval |= DCD_SessionRequest_ISR(pdev);
286 if (gintr_status.b.otgintr)
288 retval |= DCD_OTG_ISR(pdev);
290 #endif
292 return retval;
295 #ifdef VBUS_SENSING_ENABLED
297 * @brief DCD_SessionRequest_ISR
298 * Indicates that the USB_OTG controller has detected a connection
299 * @param pdev: device instance
300 * @retval status
302 static uint32_t DCD_SessionRequest_ISR(USB_OTG_CORE_HANDLE *pdev)
304 USB_OTG_GINTSTS_TypeDef gintsts;
305 USBD_DCD_INT_fops->DevConnected (pdev);
307 /* Clear interrupt */
308 gintsts.d32 = 0;
309 gintsts.b.sessreqintr = 1;
310 USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
311 return 1;
315 * @brief DCD_OTG_ISR
316 * Indicates that the USB_OTG controller has detected an OTG event:
317 * used to detect the end of session i.e. disconnection
318 * @param pdev: device instance
319 * @retval status
321 static uint32_t DCD_OTG_ISR(USB_OTG_CORE_HANDLE *pdev)
324 USB_OTG_GOTGINT_TypeDef gotgint;
326 gotgint.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GOTGINT);
328 if (gotgint.b.sesenddet)
330 USBD_DCD_INT_fops->DevDisconnected (pdev);
332 /* Clear OTG interrupt */
333 USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GOTGINT, gotgint.d32);
334 return 1;
336 #endif
338 * @brief DCD_HandleResume_ISR
339 * Indicates that the USB_OTG controller has detected a resume or
340 * remote Wake-up sequence
341 * @param pdev: device instance
342 * @retval status
344 static uint32_t DCD_HandleResume_ISR(USB_OTG_CORE_HANDLE *pdev)
346 USB_OTG_GINTSTS_TypeDef gintsts;
347 USB_OTG_DCTL_TypeDef devctl;
348 USB_OTG_PCGCCTL_TypeDef power;
350 if(pdev->cfg.low_power)
352 /* un-gate USB Core clock */
353 power.d32 = USB_OTG_READ_REG32(pdev->regs.PCGCCTL);
354 power.b.gatehclk = 0;
355 power.b.stoppclk = 0;
356 USB_OTG_WRITE_REG32(pdev->regs.PCGCCTL, power.d32);
359 /* Clear the Remote Wake-up Signaling */
360 devctl.d32 = 0;
361 devctl.b.rmtwkupsig = 1;
362 USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, devctl.d32, 0);
364 /* Inform upper layer by the Resume Event */
365 USBD_DCD_INT_fops->Resume (pdev);
367 /* Clear interrupt */
368 gintsts.d32 = 0;
369 gintsts.b.wkupintr = 1;
370 USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
371 return 1;
375 * @brief USB_OTG_HandleUSBSuspend_ISR
376 * Indicates that SUSPEND state has been detected on the USB
377 * @param pdev: device instance
378 * @retval status
380 static uint32_t DCD_HandleUSBSuspend_ISR(USB_OTG_CORE_HANDLE *pdev)
382 USB_OTG_GINTSTS_TypeDef gintsts;
383 USB_OTG_PCGCCTL_TypeDef power;
384 USB_OTG_DSTS_TypeDef dsts;
385 __IO uint8_t prev_status = 0;
387 prev_status = pdev->dev.device_status;
388 USBD_DCD_INT_fops->Suspend (pdev);
390 dsts.d32 = USB_OTG_READ_REG32(&pdev->regs.DREGS->DSTS);
392 /* Clear interrupt */
393 gintsts.d32 = 0;
394 gintsts.b.usbsuspend = 1;
395 USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
397 if((pdev->cfg.low_power) && (dsts.b.suspsts == 1) &&
398 (pdev->dev.connection_status == 1) &&
399 (prev_status == USB_OTG_CONFIGURED))
401 /* switch-off the clocks */
402 power.d32 = 0;
403 power.b.stoppclk = 1;
404 USB_OTG_MODIFY_REG32(pdev->regs.PCGCCTL, 0, power.d32);
406 power.b.gatehclk = 1;
407 USB_OTG_MODIFY_REG32(pdev->regs.PCGCCTL, 0, power.d32);
409 /* Request to enter Sleep mode after exit from current ISR */
410 SCB->SCR |= (SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk);
412 return 1;
416 * @brief DCD_HandleInEP_ISR
417 * Indicates that an IN EP has a pending Interrupt
418 * @param pdev: device instance
419 * @retval status
421 static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE *pdev)
423 USB_OTG_DIEPINTn_TypeDef diepint;
425 uint32_t ep_intr;
426 uint32_t epnum = 0;
427 uint32_t fifoemptymsk;
428 diepint.d32 = 0;
429 ep_intr = USB_OTG_ReadDevAllInEPItr(pdev);
431 while ( ep_intr )
433 if ((ep_intr & 0x1) == 0x01) /* In ITR */
435 diepint.d32 = DCD_ReadDevInEP(pdev , epnum); /* Get In ITR status */
436 if ( diepint.b.xfercompl )
438 fifoemptymsk = 0x1 << epnum;
439 USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK, fifoemptymsk, 0);
440 CLEAR_IN_EP_INTR(epnum, xfercompl);
441 /* TX COMPLETE */
442 USBD_DCD_INT_fops->DataInStage(pdev , epnum);
444 if (pdev->cfg.dma_enable == 1)
446 if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_IN))
448 /* prepare to rx more setup packets */
449 USB_OTG_EP0_OutStart(pdev);
453 if ( diepint.b.timeout )
455 CLEAR_IN_EP_INTR(epnum, timeout);
457 if (diepint.b.intktxfemp)
459 CLEAR_IN_EP_INTR(epnum, intktxfemp);
461 if (diepint.b.inepnakeff)
463 CLEAR_IN_EP_INTR(epnum, inepnakeff);
465 if ( diepint.b.epdisabled )
467 CLEAR_IN_EP_INTR(epnum, epdisabled);
469 if (diepint.b.emptyintr)
471 DCD_WriteEmptyTxFifo(pdev , epnum);
474 epnum++;
475 ep_intr >>= 1;
478 return 1;
482 * @brief DCD_HandleOutEP_ISR
483 * Indicates that an OUT EP has a pending Interrupt
484 * @param pdev: device instance
485 * @retval status
487 static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE *pdev)
489 uint32_t ep_intr;
490 USB_OTG_DOEPINTn_TypeDef doepint;
491 USB_OTG_DEPXFRSIZ_TypeDef deptsiz;
492 uint32_t epnum = 0;
494 doepint.d32 = 0;
496 /* Read in the device interrupt bits */
497 ep_intr = USB_OTG_ReadDevAllOutEp_itr(pdev);
499 while ( ep_intr )
501 if (ep_intr&0x1)
504 doepint.d32 = USB_OTG_ReadDevOutEP_itr(pdev, epnum);
506 /* Transfer complete */
507 if ( doepint.b.xfercompl )
509 /* Clear the bit in DOEPINTn for this interrupt */
510 CLEAR_OUT_EP_INTR(epnum, xfercompl);
511 if (pdev->cfg.dma_enable == 1)
513 deptsiz.d32 = USB_OTG_READ_REG32(&(pdev->regs.OUTEP_REGS[epnum]->DOEPTSIZ));
514 /*ToDo : handle more than one single MPS size packet */
515 pdev->dev.out_ep[epnum].xfer_count = pdev->dev.out_ep[epnum].maxpacket - \
516 deptsiz.b.xfersize;
518 /* Inform upper layer: data ready */
519 /* RX COMPLETE */
520 USBD_DCD_INT_fops->DataOutStage(pdev , epnum);
522 if (pdev->cfg.dma_enable == 1)
524 if((epnum == 0) && (pdev->dev.device_state == USB_OTG_EP0_STATUS_OUT))
526 /* prepare to rx more setup packets */
527 USB_OTG_EP0_OutStart(pdev);
531 /* Endpoint disable */
532 if ( doepint.b.epdisabled )
534 /* Clear the bit in DOEPINTn for this interrupt */
535 CLEAR_OUT_EP_INTR(epnum, epdisabled);
537 /* Setup Phase Done (control EPs) */
538 if ( doepint.b.setup )
541 /* inform the upper layer that a setup packet is available */
542 /* SETUP COMPLETE */
543 USBD_DCD_INT_fops->SetupStage(pdev);
544 CLEAR_OUT_EP_INTR(epnum, setup);
547 epnum++;
548 ep_intr >>= 1;
550 return 1;
554 * @brief DCD_HandleSof_ISR
555 * Handles the SOF Interrupts
556 * @param pdev: device instance
557 * @retval status
559 static uint32_t DCD_HandleSof_ISR(USB_OTG_CORE_HANDLE *pdev)
561 USB_OTG_GINTSTS_TypeDef GINTSTS;
564 USBD_DCD_INT_fops->SOF(pdev);
566 /* Clear interrupt */
567 GINTSTS.d32 = 0;
568 GINTSTS.b.sofintr = 1;
569 USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, GINTSTS.d32);
571 return 1;
575 * @brief DCD_HandleRxStatusQueueLevel_ISR
576 * Handles the Rx Status Queue Level Interrupt
577 * @param pdev: device instance
578 * @retval status
580 static uint32_t DCD_HandleRxStatusQueueLevel_ISR(USB_OTG_CORE_HANDLE *pdev)
582 USB_OTG_GINTMSK_TypeDef int_mask;
583 USB_OTG_DRXSTS_TypeDef status;
584 USB_OTG_EP *ep;
586 /* Disable the Rx Status Queue Level interrupt */
587 int_mask.d32 = 0;
588 int_mask.b.rxstsqlvl = 1;
589 USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, int_mask.d32, 0);
591 /* Get the Status from the top of the FIFO */
592 status.d32 = USB_OTG_READ_REG32( &pdev->regs.GREGS->GRXSTSP );
594 ep = &pdev->dev.out_ep[status.b.epnum];
596 switch (status.b.pktsts)
598 case STS_GOUT_NAK:
599 break;
600 case STS_DATA_UPDT:
601 if (status.b.bcnt)
603 USB_OTG_ReadPacket(pdev,ep->xfer_buff, status.b.bcnt);
604 ep->xfer_buff += status.b.bcnt;
605 ep->xfer_count += status.b.bcnt;
607 break;
608 case STS_XFER_COMP:
609 break;
610 case STS_SETUP_COMP:
611 break;
612 case STS_SETUP_UPDT:
613 /* Copy the setup packet received in FIFO into the setup buffer in RAM */
614 USB_OTG_ReadPacket(pdev , pdev->dev.setup_packet, 8);
615 ep->xfer_count += status.b.bcnt;
616 break;
617 default:
618 break;
621 /* Enable the Rx Status Queue Level interrupt */
622 USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, 0, int_mask.d32);
624 return 1;
628 * @brief DCD_WriteEmptyTxFifo
629 * check FIFO for the next packet to be loaded
630 * @param pdev: device instance
631 * @retval status
633 static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE *pdev, uint32_t epnum)
635 USB_OTG_DTXFSTSn_TypeDef txstatus;
636 USB_OTG_EP *ep;
637 uint32_t len = 0;
638 uint32_t len32b;
639 txstatus.d32 = 0;
640 uint32_t fifoemptymsk;
642 ep = &pdev->dev.in_ep[epnum];
644 len = ep->xfer_len - ep->xfer_count;
646 if (len > ep->maxpacket)
648 len = ep->maxpacket;
651 len32b = (len + 3) / 4;
652 txstatus.d32 = USB_OTG_READ_REG32( &pdev->regs.INEP_REGS[epnum]->DTXFSTS);
654 while (txstatus.b.txfspcavail > len32b &&
655 ep->xfer_count < ep->xfer_len &&
656 ep->xfer_len != 0)
658 /* Write the FIFO */
659 len = ep->xfer_len - ep->xfer_count;
661 if (len > ep->maxpacket)
663 len = ep->maxpacket;
665 len32b = (len + 3) / 4;
667 USB_OTG_WritePacket (pdev , ep->xfer_buff, epnum, len);
669 ep->xfer_buff += len;
670 ep->xfer_count += len;
672 txstatus.d32 = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DTXFSTS);
674 /* Mask the TxFIFOEmpty interrupt */
675 if (ep->xfer_len == ep->xfer_count)
677 fifoemptymsk = 0x1 << ep->num;
678 USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DIEPEMPMSK,
679 fifoemptymsk, 0);
683 return 1;
687 * @brief DCD_HandleUsbReset_ISR
688 * This interrupt occurs when a USB Reset is detected
689 * @param pdev: device instance
690 * @retval status
692 static uint32_t DCD_HandleUsbReset_ISR(USB_OTG_CORE_HANDLE *pdev)
694 USB_OTG_DAINT_TypeDef daintmsk;
695 USB_OTG_DOEPMSK_TypeDef doepmsk;
696 USB_OTG_DIEPMSK_TypeDef diepmsk;
697 USB_OTG_DCFG_TypeDef dcfg;
698 USB_OTG_DCTL_TypeDef dctl;
699 USB_OTG_GINTSTS_TypeDef gintsts;
700 uint32_t i;
702 dctl.d32 = 0;
703 daintmsk.d32 = 0;
704 doepmsk.d32 = 0;
705 diepmsk.d32 = 0;
706 dcfg.d32 = 0;
707 gintsts.d32 = 0;
709 /* Clear the Remote Wake-up Signaling */
710 dctl.b.rmtwkupsig = 1;
711 USB_OTG_MODIFY_REG32(&pdev->regs.DREGS->DCTL, dctl.d32, 0 );
713 /* Flush the Tx FIFO */
714 USB_OTG_FlushTxFifo(pdev , 0 );
716 for (i = 0; i < pdev->cfg.dev_endpoints ; i++)
718 USB_OTG_WRITE_REG32( &pdev->regs.INEP_REGS[i]->DIEPINT, 0xFF);
719 USB_OTG_WRITE_REG32( &pdev->regs.OUTEP_REGS[i]->DOEPINT, 0xFF);
721 USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINT, 0xFFFFFFFF );
723 daintmsk.ep.in = 1;
724 daintmsk.ep.out = 1;
725 USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DAINTMSK, daintmsk.d32 );
727 doepmsk.b.setup = 1;
728 doepmsk.b.xfercompl = 1;
729 doepmsk.b.epdisabled = 1;
730 USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOEPMSK, doepmsk.d32 );
731 #ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
732 USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DOUTEP1MSK, doepmsk.d32 );
733 #endif
734 diepmsk.b.xfercompl = 1;
735 diepmsk.b.timeout = 1;
736 diepmsk.b.epdisabled = 1;
738 USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DIEPMSK, diepmsk.d32 );
739 #ifdef USB_OTG_HS_DEDICATED_EP1_ENABLED
740 USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DINEP1MSK, diepmsk.d32 );
741 #endif
742 /* Reset Device Address */
743 dcfg.d32 = USB_OTG_READ_REG32( &pdev->regs.DREGS->DCFG);
744 dcfg.b.devaddr = 0;
745 USB_OTG_WRITE_REG32( &pdev->regs.DREGS->DCFG, dcfg.d32);
748 /* setup EP0 to receive SETUP packets */
749 USB_OTG_EP0_OutStart(pdev);
751 /* Clear interrupt */
752 gintsts.d32 = 0;
753 gintsts.b.usbreset = 1;
754 USB_OTG_WRITE_REG32 (&pdev->regs.GREGS->GINTSTS, gintsts.d32);
756 /*Reset internal state machine */
757 USBD_DCD_INT_fops->Reset(pdev);
758 return 1;
762 * @brief DCD_HandleEnumDone_ISR
763 * Read the device status register and set the device speed
764 * @param pdev: device instance
765 * @retval status
767 static uint32_t DCD_HandleEnumDone_ISR(USB_OTG_CORE_HANDLE *pdev)
769 uint32_t hclk = 168000000;
771 USB_OTG_GINTSTS_TypeDef gintsts;
772 USB_OTG_GUSBCFG_TypeDef gusbcfg;
773 RCC_ClocksTypeDef RCC_Clocks;
774 USB_OTG_EP0Activate(pdev);
776 /* Get HCLK frequency */
777 RCC_GetClocksFreq(&RCC_Clocks);
778 hclk = RCC_Clocks.HCLK_Frequency;
780 /* Clear default TRDT value and Set USB turn-around time based on device speed and PHY interface. */
781 gusbcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GUSBCFG);
782 gusbcfg.b.usbtrdtim = 0;
783 USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, gusbcfg.d32);
785 /* Full or High speed */
786 if ( USB_OTG_GetDeviceSpeed(pdev) == USB_SPEED_HIGH)
788 pdev->cfg.speed = USB_OTG_SPEED_HIGH;
789 pdev->cfg.mps = USB_OTG_HS_MAX_PACKET_SIZE ;
791 /*USBTRD min For HS device*/
792 gusbcfg.b.usbtrdtim = 9;
794 else
796 pdev->cfg.speed = USB_OTG_SPEED_FULL;
797 pdev->cfg.mps = USB_OTG_FS_MAX_PACKET_SIZE ;
799 /* The USBTRD is configured according to the tables below, depending on AHB frequency
800 used by application. In the low AHB frequency range it is used to stretch enough the USB response
801 time to IN tokens, the USB turnaround time, so to compensate for the longer AHB read access
802 latency to the Data FIFO */
804 if((hclk >= 15000000)&&(hclk < 16000000))
806 /* hclk Clock Range between 15-16 MHz */
807 gusbcfg.b.usbtrdtim = 0xE;
810 else if((hclk >= 16000000)&&(hclk < 17100000))
812 /* hclk Clock Range between 16-17.1 MHz */
813 gusbcfg.b.usbtrdtim = 0xD;
816 else if((hclk >= 17100000)&&(hclk < 18400000))
818 /* hclk Clock Range between 17-18.4 MHz */
819 gusbcfg.b.usbtrdtim = 0xC;
822 else if((hclk >= 18400000)&&(hclk < 20000000))
824 /* hclk Clock Range between 18.4-20 MHz */
825 gusbcfg.b.usbtrdtim = 0xB;
828 else if((hclk >= 20000000)&&(hclk < 21800000))
830 /* hclk Clock Range between 20-21.8 MHz */
831 gusbcfg.b.usbtrdtim = 0xA;
834 else if((hclk >= 21800000)&&(hclk < 24000000))
836 /* hclk Clock Range between 21.8-24 MHz */
837 gusbcfg.b.usbtrdtim = 0x9;
840 else if((hclk >= 24000000)&&(hclk < 26600000))
842 /* hclk Clock Range between 24-26.6 MHz */
843 gusbcfg.b.usbtrdtim = 0x8;
846 else if((hclk >= 26600000)&&(hclk < 30000000))
848 /* hclk Clock Range between 26.6-30 MHz */
849 gusbcfg.b.usbtrdtim = 0x7;
852 else if((hclk >= 30000000)&&(hclk < 34300000))
854 /* hclk Clock Range between 30-34.3 MHz */
855 gusbcfg.b.usbtrdtim= 0x6;
858 else /* if(hclk >= 34300000) */
860 /* hclk Clock Range between 34.3-168 MHz */
861 gusbcfg.b.usbtrdtim = 0x5;
865 USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GUSBCFG, gusbcfg.d32);
867 /* Clear interrupt */
868 gintsts.d32 = 0;
869 gintsts.b.enumdone = 1;
870 USB_OTG_WRITE_REG32( &pdev->regs.GREGS->GINTSTS, gintsts.d32 );
871 return 1;
876 * @brief DCD_IsoINIncomplete_ISR
877 * handle the ISO IN incomplete interrupt
878 * @param pdev: device instance
879 * @retval status
881 static uint32_t DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev)
883 USB_OTG_GINTSTS_TypeDef gintsts;
885 gintsts.d32 = 0;
887 USBD_DCD_INT_fops->IsoINIncomplete (pdev);
889 /* Clear interrupt */
890 gintsts.b.incomplisoin = 1;
891 USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
893 return 1;
897 * @brief DCD_IsoOUTIncomplete_ISR
898 * handle the ISO OUT incomplete interrupt
899 * @param pdev: device instance
900 * @retval status
902 static uint32_t DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE *pdev)
904 USB_OTG_GINTSTS_TypeDef gintsts;
906 gintsts.d32 = 0;
908 USBD_DCD_INT_fops->IsoOUTIncomplete (pdev);
910 /* Clear interrupt */
911 gintsts.b.incomplisoout = 1;
912 USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
913 return 1;
916 * @brief DCD_ReadDevInEP
917 * Reads ep flags
918 * @param pdev: device instance
919 * @retval status
921 static uint32_t DCD_ReadDevInEP (USB_OTG_CORE_HANDLE *pdev, uint8_t epnum)
923 uint32_t v, msk, emp;
924 msk = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPMSK);
925 emp = USB_OTG_READ_REG32(&pdev->regs.DREGS->DIEPEMPMSK);
926 msk |= ((emp >> epnum) & 0x1) << 7;
927 v = USB_OTG_READ_REG32(&pdev->regs.INEP_REGS[epnum]->DIEPINT) & msk;
928 return v;
932 * @}
936 * @}
940 * @}
943 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/