2 ******************************************************************************
4 * @author MCD Application Team
6 * @date 09-November-2015
7 * @brief Peripheral Device interrupt subroutines
8 ******************************************************************************
11 * <h2><center>© 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
34 /** @defgroup USB_DCD_INT
35 * @brief This file contains the interrupt subroutines for the Device mode.
40 /** @defgroup USB_DCD_INT_Private_Defines
48 /** @defgroup USB_DCD_INT_Private_TypesDefinitions
57 /** @defgroup USB_DCD_INT_Private_Macros
65 /** @defgroup USB_DCD_INT_Private_Variables
73 /** @defgroup USB_DCD_INT_Private_FunctionPrototypes
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
);
104 /** @defgroup USB_DCD_INT_Private_Functions
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
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
- \
136 /* Inform upper layer: data ready */
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
);
153 * @brief USBD_OTG_EP1IN_ISR_Handler
154 * handles all USB Interrupts
155 * @param pdev: device instance
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
);
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);
202 * @brief STM32_USBF_OTG_ISR_Handler
203 * handles all USB Interrupts
204 * @param pdev: device instance
207 uint32_t USBD_OTG_ISR_Handler (USB_OTG_CORE_HANDLE
*pdev
)
209 USB_OTG_GINTSTS_TypeDef gintr_status
;
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 */
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 */
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
);
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
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 */
309 gintsts
.b
.sessreqintr
= 1;
310 USB_OTG_WRITE_REG32 (&pdev
->regs
.GREGS
->GINTSTS
, gintsts
.d32
);
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
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
);
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
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 */
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 */
369 gintsts
.b
.wkupintr
= 1;
370 USB_OTG_WRITE_REG32 (&pdev
->regs
.GREGS
->GINTSTS
, gintsts
.d32
);
375 * @brief USB_OTG_HandleUSBSuspend_ISR
376 * Indicates that SUSPEND state has been detected on the USB
377 * @param pdev: device instance
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 */
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 */
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
);
416 * @brief DCD_HandleInEP_ISR
417 * Indicates that an IN EP has a pending Interrupt
418 * @param pdev: device instance
421 static uint32_t DCD_HandleInEP_ISR(USB_OTG_CORE_HANDLE
*pdev
)
423 USB_OTG_DIEPINTn_TypeDef diepint
;
427 uint32_t fifoemptymsk
;
429 ep_intr
= USB_OTG_ReadDevAllInEPItr(pdev
);
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
);
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
);
482 * @brief DCD_HandleOutEP_ISR
483 * Indicates that an OUT EP has a pending Interrupt
484 * @param pdev: device instance
487 static uint32_t DCD_HandleOutEP_ISR(USB_OTG_CORE_HANDLE
*pdev
)
490 USB_OTG_DOEPINTn_TypeDef doepint
;
491 USB_OTG_DEPXFRSIZ_TypeDef deptsiz
;
496 /* Read in the device interrupt bits */
497 ep_intr
= USB_OTG_ReadDevAllOutEp_itr(pdev
);
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
- \
518 /* Inform upper layer: data ready */
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 */
543 USBD_DCD_INT_fops
->SetupStage(pdev
);
544 CLEAR_OUT_EP_INTR(epnum
, setup
);
554 * @brief DCD_HandleSof_ISR
555 * Handles the SOF Interrupts
556 * @param pdev: device instance
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 */
568 GINTSTS
.b
.sofintr
= 1;
569 USB_OTG_WRITE_REG32 (&pdev
->regs
.GREGS
->GINTSTS
, GINTSTS
.d32
);
575 * @brief DCD_HandleRxStatusQueueLevel_ISR
576 * Handles the Rx Status Queue Level Interrupt
577 * @param pdev: device instance
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
;
586 /* Disable the Rx Status Queue Level interrupt */
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
)
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
;
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
;
621 /* Enable the Rx Status Queue Level interrupt */
622 USB_OTG_MODIFY_REG32( &pdev
->regs
.GREGS
->GINTMSK
, 0, int_mask
.d32
);
628 * @brief DCD_WriteEmptyTxFifo
629 * check FIFO for the next packet to be loaded
630 * @param pdev: device instance
633 static uint32_t DCD_WriteEmptyTxFifo(USB_OTG_CORE_HANDLE
*pdev
, uint32_t epnum
)
635 USB_OTG_DTXFSTSn_TypeDef txstatus
;
640 uint32_t fifoemptymsk
;
642 ep
= &pdev
->dev
.in_ep
[epnum
];
644 len
= ep
->xfer_len
- ep
->xfer_count
;
646 if (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
&&
659 len
= ep
->xfer_len
- ep
->xfer_count
;
661 if (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
,
687 * @brief DCD_HandleUsbReset_ISR
688 * This interrupt occurs when a USB Reset is detected
689 * @param pdev: device instance
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
;
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 );
725 USB_OTG_WRITE_REG32( &pdev
->regs
.DREGS
->DAINTMSK
, daintmsk
.d32
);
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
);
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
);
742 /* Reset Device Address */
743 dcfg
.d32
= USB_OTG_READ_REG32( &pdev
->regs
.DREGS
->DCFG
);
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 */
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
);
762 * @brief DCD_HandleEnumDone_ISR
763 * Read the device status register and set the device speed
764 * @param pdev: device instance
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;
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 */
869 gintsts
.b
.enumdone
= 1;
870 USB_OTG_WRITE_REG32( &pdev
->regs
.GREGS
->GINTSTS
, gintsts
.d32
);
876 * @brief DCD_IsoINIncomplete_ISR
877 * handle the ISO IN incomplete interrupt
878 * @param pdev: device instance
881 static uint32_t DCD_IsoINIncomplete_ISR(USB_OTG_CORE_HANDLE
*pdev
)
883 USB_OTG_GINTSTS_TypeDef gintsts
;
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
);
897 * @brief DCD_IsoOUTIncomplete_ISR
898 * handle the ISO OUT incomplete interrupt
899 * @param pdev: device instance
902 static uint32_t DCD_IsoOUTIncomplete_ISR(USB_OTG_CORE_HANDLE
*pdev
)
904 USB_OTG_GINTSTS_TypeDef gintsts
;
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
);
916 * @brief DCD_ReadDevInEP
918 * @param pdev: device instance
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
;
943 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/