Updated and Validated
[betaflight.git] / lib / main / STM32_USB_OTG_Driver / src / usb_hcd_int.c
blob7366d155f01d583d87b96eed57a59ba520a09b79
1 /**
2 ******************************************************************************
3 * @file usb_hcd_int.c
4 * @author MCD Application Team
5 * @version V2.2.0
6 * @date 09-November-2015
7 * @brief Host driver 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_core.h"
30 #include "usb_defines.h"
31 #include "usb_hcd_int.h"
33 #if defined (__CC_ARM) /*!< ARM Compiler */
34 #pragma O0
35 #elif defined (__GNUC__) /*!< GNU Compiler */
36 #pragma GCC optimize ("O0")
37 #elif defined (__TASKING__) /*!< TASKING Compiler */
38 #pragma optimize=0
40 #endif /* __CC_ARM */
42 /** @addtogroup USB_OTG_DRIVER
43 * @{
46 /** @defgroup USB_HCD_INT
47 * @brief This file contains the interrupt subroutines for the Host mode.
48 * @{
52 /** @defgroup USB_HCD_INT_Private_Defines
53 * @{
54 */
55 /**
56 * @}
57 */
60 /** @defgroup USB_HCD_INT_Private_TypesDefinitions
61 * @{
62 */
63 /**
64 * @}
65 */
69 /** @defgroup USB_HCD_INT_Private_Macros
70 * @{
71 */
72 /**
73 * @}
74 */
77 /** @defgroup USB_HCD_INT_Private_Variables
78 * @{
79 */
80 /**
81 * @}
82 */
85 /** @defgroup USB_HCD_INT_Private_FunctionPrototypes
86 * @{
87 */
89 static uint32_t USB_OTG_USBH_handle_sof_ISR(USB_OTG_CORE_HANDLE *pdev);
90 static uint32_t USB_OTG_USBH_handle_port_ISR(USB_OTG_CORE_HANDLE *pdev);
91 static uint32_t USB_OTG_USBH_handle_hc_ISR (USB_OTG_CORE_HANDLE *pdev);
92 static uint32_t USB_OTG_USBH_handle_hc_n_In_ISR (USB_OTG_CORE_HANDLE *pdev ,
93 uint32_t num);
94 static uint32_t USB_OTG_USBH_handle_hc_n_Out_ISR (USB_OTG_CORE_HANDLE *pdev ,
95 uint32_t num);
96 static uint32_t USB_OTG_USBH_handle_rx_qlvl_ISR (USB_OTG_CORE_HANDLE *pdev);
97 static uint32_t USB_OTG_USBH_handle_nptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev);
98 static uint32_t USB_OTG_USBH_handle_ptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev);
99 static uint32_t USB_OTG_USBH_handle_Disconnect_ISR (USB_OTG_CORE_HANDLE *pdev);
100 static uint32_t USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR (USB_OTG_CORE_HANDLE *pdev);
103 * @}
107 /** @defgroup USB_HCD_INT_Private_Functions
108 * @{
112 * @brief HOST_Handle_ISR
113 * This function handles all USB Host Interrupts
114 * @param pdev: Selected device
115 * @retval status
118 uint32_t USBH_OTG_ISR_Handler (USB_OTG_CORE_HANDLE *pdev)
120 USB_OTG_GINTSTS_TypeDef gintsts;
121 uint32_t retval = 0;
123 gintsts.d32 = 0;
125 /* Check if HOST Mode */
126 if (USB_OTG_IsHostMode(pdev))
128 gintsts.d32 = USB_OTG_ReadCoreItr(pdev);
129 if (!gintsts.d32)
131 return 0;
134 if (gintsts.b.sofintr)
136 retval |= USB_OTG_USBH_handle_sof_ISR (pdev);
139 if (gintsts.b.rxstsqlvl)
141 retval |= USB_OTG_USBH_handle_rx_qlvl_ISR (pdev);
144 if (gintsts.b.nptxfempty)
146 retval |= USB_OTG_USBH_handle_nptxfempty_ISR (pdev);
149 if (gintsts.b.ptxfempty)
151 retval |= USB_OTG_USBH_handle_ptxfempty_ISR (pdev);
154 if (gintsts.b.hcintr)
156 retval |= USB_OTG_USBH_handle_hc_ISR (pdev);
159 if (gintsts.b.portintr)
161 retval |= USB_OTG_USBH_handle_port_ISR (pdev);
164 if (gintsts.b.disconnect)
166 retval |= USB_OTG_USBH_handle_Disconnect_ISR (pdev);
170 if (gintsts.b.incomplisoout)
172 retval |= USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR (pdev);
177 return retval;
181 * @brief USB_OTG_USBH_handle_hc_ISR
182 * This function indicates that one or more host channels has a pending
183 * @param pdev: Selected device
184 * @retval status
186 static uint32_t USB_OTG_USBH_handle_hc_ISR (USB_OTG_CORE_HANDLE *pdev)
188 USB_OTG_HAINT_TypeDef haint;
189 USB_OTG_HCCHAR_TypeDef hcchar;
190 uint32_t i = 0;
191 uint32_t retval = 0;
193 /* Clear appropriate bits in HCINTn to clear the interrupt bit in
194 * GINTSTS */
196 haint.d32 = USB_OTG_ReadHostAllChannels_intr(pdev);
198 for (i = 0; i < pdev->cfg.host_channels ; i++)
200 if (haint.b.chint & (1 << i))
202 hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[i]->HCCHAR);
204 if (hcchar.b.epdir)
206 retval |= USB_OTG_USBH_handle_hc_n_In_ISR (pdev, i);
208 else
210 retval |= USB_OTG_USBH_handle_hc_n_Out_ISR (pdev, i);
215 return retval;
219 * @brief USB_OTG_otg_hcd_handle_sof_intr
220 * Handles the start-of-frame interrupt in host mode.
221 * @param pdev: Selected device
222 * @retval status
224 static uint32_t USB_OTG_USBH_handle_sof_ISR (USB_OTG_CORE_HANDLE *pdev)
226 USB_OTG_GINTSTS_TypeDef gintsts;
227 gintsts.d32 = 0;
229 USBH_HCD_INT_fops->SOF(pdev);
231 /* Clear interrupt */
232 gintsts.b.sofintr = 1;
233 USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
235 return 1;
239 * @brief USB_OTG_USBH_handle_Disconnect_ISR
240 * Handles disconnect event.
241 * @param pdev: Selected device
242 * @retval status
244 static uint32_t USB_OTG_USBH_handle_Disconnect_ISR (USB_OTG_CORE_HANDLE *pdev)
246 USB_OTG_GINTSTS_TypeDef gintsts;
248 gintsts.d32 = 0;
250 USBH_HCD_INT_fops->DevDisconnected(pdev);
252 /* Clear interrupt */
253 gintsts.b.disconnect = 1;
254 USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
256 return 1;
258 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
259 #pragma optimize = none
260 #endif /* __CC_ARM */
262 * @brief USB_OTG_USBH_handle_nptxfempty_ISR
263 * Handles non periodic tx fifo empty.
264 * @param pdev: Selected device
265 * @retval status
267 static uint32_t USB_OTG_USBH_handle_nptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev)
269 USB_OTG_GINTMSK_TypeDef intmsk;
270 USB_OTG_HNPTXSTS_TypeDef hnptxsts;
271 uint16_t len_words , len;
273 hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS);
275 len_words = (pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_len + 3) / 4;
277 while ((hnptxsts.b.nptxfspcavail > len_words)&&
278 (pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_len != 0))
281 len = hnptxsts.b.nptxfspcavail * 4;
283 if (len > pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_len)
285 /* Last packet */
286 len = pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_len;
288 intmsk.d32 = 0;
289 intmsk.b.nptxfempty = 1;
290 USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0);
293 len_words = (pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_len + 3) / 4;
295 USB_OTG_WritePacket (pdev , pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_buff, hnptxsts.b.nptxqtop.chnum, len);
297 pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_buff += len;
298 pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_len -= len;
299 pdev->host.hc[hnptxsts.b.nptxqtop.chnum].xfer_count += len;
301 hnptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->HNPTXSTS);
304 return 1;
306 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
307 #pragma optimize = none
308 #endif /* __CC_ARM */
310 * @brief USB_OTG_USBH_handle_ptxfempty_ISR
311 * Handles periodic tx fifo empty
312 * @param pdev: Selected device
313 * @retval status
315 static uint32_t USB_OTG_USBH_handle_ptxfempty_ISR (USB_OTG_CORE_HANDLE *pdev)
317 USB_OTG_GINTMSK_TypeDef intmsk;
318 USB_OTG_HPTXSTS_TypeDef hptxsts;
319 uint16_t len_words , len;
321 hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS);
323 len_words = (pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len + 3) / 4;
325 while ((hptxsts.b.ptxfspcavail > len_words)&&
326 (pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len != 0))
329 len = hptxsts.b.ptxfspcavail * 4;
331 if (len > pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len)
333 len = pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len;
334 /* Last packet */
335 intmsk.d32 = 0;
336 intmsk.b.ptxfempty = 1;
337 USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0);
340 len_words = (pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len + 3) / 4;
342 USB_OTG_WritePacket (pdev , pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_buff, hptxsts.b.ptxqtop.chnum, len);
344 pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_buff += len;
345 pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_len -= len;
346 pdev->host.hc[hptxsts.b.ptxqtop.chnum].xfer_count += len;
348 hptxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HPTXSTS);
351 return 1;
355 * @brief USB_OTG_USBH_handle_port_ISR
356 * This function determines which interrupt conditions have occurred
357 * @param pdev: Selected device
358 * @retval status
360 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
361 #pragma optimize = none
362 #endif /* __CC_ARM */
363 static uint32_t USB_OTG_USBH_handle_port_ISR (USB_OTG_CORE_HANDLE *pdev)
365 USB_OTG_HPRT0_TypeDef hprt0;
366 USB_OTG_HPRT0_TypeDef hprt0_dup;
367 USB_OTG_HCFG_TypeDef hcfg;
368 uint32_t retval = 0;
369 USB_OTG_GINTMSK_TypeDef intmsk;
371 intmsk.d32 = 0;
372 hcfg.d32 = 0;
373 hprt0.d32 = 0;
374 hprt0_dup.d32 = 0;
376 hprt0.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0);
377 hprt0_dup.d32 = USB_OTG_READ_REG32(pdev->regs.HPRT0);
379 /* Clear the interrupt bits in GINTSTS */
381 hprt0_dup.b.prtena = 0;
382 hprt0_dup.b.prtconndet = 0;
383 hprt0_dup.b.prtenchng = 0;
384 hprt0_dup.b.prtovrcurrchng = 0;
386 /* Port Connect Detected */
387 if (hprt0.b.prtconndet)
389 hprt0_dup.b.prtconndet = 1;
390 USBH_HCD_INT_fops->DevConnected(pdev);
391 retval |= 1;
394 /* Port Enable Changed */
395 if (hprt0.b.prtenchng)
397 hprt0_dup.b.prtenchng = 1;
399 if (hprt0.b.prtena == 1)
401 if ((hprt0.b.prtspd == HPRT0_PRTSPD_LOW_SPEED) ||
402 (hprt0.b.prtspd == HPRT0_PRTSPD_FULL_SPEED))
404 hcfg.d32 = USB_OTG_READ_REG32(&pdev->regs.HREGS->HCFG);
406 if (hprt0.b.prtspd == HPRT0_PRTSPD_LOW_SPEED)
408 USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HFIR, 6000 );
409 if (hcfg.b.fslspclksel != HCFG_6_MHZ)
411 if(pdev->cfg.phy_itface == USB_OTG_EMBEDDED_PHY)
413 USB_OTG_InitFSLSPClkSel(pdev , HCFG_6_MHZ);
416 else
418 USB_OTG_WRITE_REG32(&pdev->regs.HREGS->HFIR, 48000 );
419 if (hcfg.b.fslspclksel != HCFG_48_MHZ)
421 USB_OTG_InitFSLSPClkSel(pdev ,HCFG_48_MHZ );
428 USBH_HCD_INT_fops->DevPortEnabled(pdev);
430 /*unmask disconnect interrupt */
431 intmsk.d32 = 0;
432 intmsk.b.disconnect = 1;
433 USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, intmsk.d32, intmsk.d32);
435 else
437 USBH_HCD_INT_fops->DevPortDisabled(pdev);
442 /* Overcurrent Change Interrupt */
443 if (hprt0.b.prtovrcurrchng)
445 hprt0_dup.b.prtovrcurrchng = 1;
446 retval |= 1;
449 /* Clear Port Interrupts */
450 USB_OTG_WRITE_REG32(pdev->regs.HPRT0, hprt0_dup.d32);
452 return retval;
454 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
455 #pragma optimize = none
456 #endif /* __CC_ARM */
458 * @brief USB_OTG_USBH_handle_hc_n_Out_ISR
459 * Handles interrupt for a specific Host Channel
460 * @param pdev: Selected device
461 * @param hc_num: Channel number
462 * @retval status
464 uint32_t USB_OTG_USBH_handle_hc_n_Out_ISR (USB_OTG_CORE_HANDLE *pdev , uint32_t num)
467 USB_OTG_HCINTn_TypeDef hcint;
468 USB_OTG_HCINTMSK_TypeDef hcintmsk;
469 USB_OTG_HC_REGS *hcreg;
470 USB_OTG_HCCHAR_TypeDef hcchar;
472 hcreg = pdev->regs.HC_REGS[num];
473 hcint.d32 = USB_OTG_READ_REG32(&hcreg->HCINT);
474 hcintmsk.d32 = USB_OTG_READ_REG32(&hcreg->HCINTMSK);
475 hcint.d32 = hcint.d32 & hcintmsk.d32;
477 hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCCHAR);
479 if (hcint.b.ahberr)
481 CLEAR_HC_INT(hcreg ,ahberr);
482 UNMASK_HOST_INT_CHH (num);
484 else if (hcint.b.ack)
486 CLEAR_HC_INT(hcreg , ack);
488 else if (hcint.b.frmovrun)
490 UNMASK_HOST_INT_CHH (num);
491 USB_OTG_HC_Halt(pdev, num);
492 CLEAR_HC_INT(hcreg ,frmovrun);
494 else if (hcint.b.xfercompl)
496 pdev->host.ErrCnt[num] = 0;
497 UNMASK_HOST_INT_CHH (num);
498 USB_OTG_HC_Halt(pdev, num);
499 CLEAR_HC_INT(hcreg , xfercompl);
500 pdev->host.HC_Status[num] = HC_XFRC;
503 else if (hcint.b.stall)
505 CLEAR_HC_INT(hcreg , stall);
506 UNMASK_HOST_INT_CHH (num);
507 USB_OTG_HC_Halt(pdev, num);
508 pdev->host.HC_Status[num] = HC_STALL;
511 else if (hcint.b.nak)
513 pdev->host.ErrCnt[num] = 0;
514 UNMASK_HOST_INT_CHH (num);
515 if (pdev->cfg.dma_enable == 0)
517 USB_OTG_HC_Halt(pdev, num);
519 CLEAR_HC_INT(hcreg , nak);
520 pdev->host.HC_Status[num] = HC_NAK;
523 else if (hcint.b.xacterr)
525 UNMASK_HOST_INT_CHH (num);
526 USB_OTG_HC_Halt(pdev, num);
527 pdev->host.HC_Status[num] = HC_XACTERR;
528 CLEAR_HC_INT(hcreg , xacterr);
530 else if (hcint.b.nyet)
532 pdev->host.ErrCnt[num] = 0;
533 UNMASK_HOST_INT_CHH (num);
534 if (pdev->cfg.dma_enable == 0)
536 USB_OTG_HC_Halt(pdev, num);
538 CLEAR_HC_INT(hcreg , nyet);
539 pdev->host.HC_Status[num] = HC_NYET;
541 else if (hcint.b.datatglerr)
543 UNMASK_HOST_INT_CHH (num);
544 USB_OTG_HC_Halt(pdev, num);
545 CLEAR_HC_INT(hcreg , nak);
546 pdev->host.HC_Status[num] = HC_DATATGLERR;
548 CLEAR_HC_INT(hcreg , datatglerr);
550 else if (hcint.b.chhltd)
552 MASK_HOST_INT_CHH (num);
554 if(pdev->host.HC_Status[num] == HC_XFRC)
556 pdev->host.URB_State[num] = URB_DONE;
558 if (hcchar.b.eptype == EP_TYPE_BULK)
560 pdev->host.hc[num].toggle_out ^= 1;
563 else if(pdev->host.HC_Status[num] == HC_NAK)
565 pdev->host.URB_State[num] = URB_NOTREADY;
567 else if(pdev->host.HC_Status[num] == HC_NYET)
569 if(pdev->host.hc[num].do_ping == 1)
571 USB_OTG_HC_DoPing(pdev, num);
573 pdev->host.URB_State[num] = URB_NOTREADY;
575 else if(pdev->host.HC_Status[num] == HC_STALL)
577 pdev->host.URB_State[num] = URB_STALL;
579 else if(pdev->host.HC_Status[num] == HC_XACTERR)
582 pdev->host.URB_State[num] = URB_ERROR;
585 CLEAR_HC_INT(hcreg , chhltd);
589 return 1;
591 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
592 #pragma optimize = none
593 #endif /* __CC_ARM */
595 * @brief USB_OTG_USBH_handle_hc_n_In_ISR
596 * Handles interrupt for a specific Host Channel
597 * @param pdev: Selected device
598 * @param hc_num: Channel number
599 * @retval status
601 uint32_t USB_OTG_USBH_handle_hc_n_In_ISR (USB_OTG_CORE_HANDLE *pdev , uint32_t num)
603 USB_OTG_HCINTn_TypeDef hcint;
604 USB_OTG_HCINTMSK_TypeDef hcintmsk;
605 USB_OTG_HCCHAR_TypeDef hcchar;
606 USB_OTG_HCTSIZn_TypeDef hctsiz;
607 USB_OTG_HC_REGS *hcreg;
609 hcreg = pdev->regs.HC_REGS[num];
610 hcint.d32 = USB_OTG_READ_REG32(&hcreg->HCINT);
611 hcintmsk.d32 = USB_OTG_READ_REG32(&hcreg->HCINTMSK);
612 hcint.d32 = hcint.d32 & hcintmsk.d32;
613 hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCCHAR);
614 hcintmsk.d32 = 0;
616 if (hcint.b.ahberr)
618 CLEAR_HC_INT(hcreg ,ahberr);
619 UNMASK_HOST_INT_CHH (num);
621 else if (hcint.b.ack)
623 CLEAR_HC_INT(hcreg ,ack);
626 else if (hcint.b.stall)
628 UNMASK_HOST_INT_CHH (num);
629 pdev->host.HC_Status[num] = HC_STALL;
630 CLEAR_HC_INT(hcreg , nak); /* Clear the NAK Condition */
631 CLEAR_HC_INT(hcreg , stall); /* Clear the STALL Condition */
632 hcint.b.nak = 0; /* NOTE: When there is a 'stall', reset also nak,
633 else, the pdev->host.HC_Status = HC_STALL
634 will be overwritten by 'nak' in code below */
635 USB_OTG_HC_Halt(pdev, num);
637 else if (hcint.b.datatglerr)
639 UNMASK_HOST_INT_CHH (num);
640 USB_OTG_HC_Halt(pdev, num);
641 CLEAR_HC_INT(hcreg , nak);
642 pdev->host.HC_Status[num] = HC_DATATGLERR;
643 CLEAR_HC_INT(hcreg , datatglerr);
646 if (hcint.b.frmovrun)
648 UNMASK_HOST_INT_CHH (num);
649 USB_OTG_HC_Halt(pdev, num);
650 CLEAR_HC_INT(hcreg ,frmovrun);
653 else if (hcint.b.xfercompl)
655 if (pdev->cfg.dma_enable == 1)
657 hctsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[num]->HCTSIZ);
658 pdev->host.XferCnt[num] = pdev->host.hc[num].xfer_len - hctsiz.b.xfersize;
661 pdev->host.HC_Status[num] = HC_XFRC;
662 pdev->host.ErrCnt [num]= 0;
663 CLEAR_HC_INT(hcreg , xfercompl);
665 if ((hcchar.b.eptype == EP_TYPE_CTRL)||
666 (hcchar.b.eptype == EP_TYPE_BULK))
668 UNMASK_HOST_INT_CHH (num);
669 USB_OTG_HC_Halt(pdev, num);
670 CLEAR_HC_INT(hcreg , nak);
671 pdev->host.hc[num].toggle_in ^= 1;
674 else if(hcchar.b.eptype == EP_TYPE_INTR)
676 hcchar.b.oddfrm = 1;
677 USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32);
678 pdev->host.URB_State[num] = URB_DONE;
681 else if (hcint.b.chhltd)
683 MASK_HOST_INT_CHH (num);
685 if(pdev->host.HC_Status[num] == HC_XFRC)
687 pdev->host.URB_State[num] = URB_DONE;
690 else if (pdev->host.HC_Status[num] == HC_STALL)
692 pdev->host.URB_State[num] = URB_STALL;
695 else if((pdev->host.HC_Status[num] == HC_XACTERR) ||
696 (pdev->host.HC_Status[num] == HC_DATATGLERR))
698 pdev->host.ErrCnt[num] = 0;
699 pdev->host.URB_State[num] = URB_ERROR;
702 else if(hcchar.b.eptype == EP_TYPE_INTR)
704 pdev->host.hc[num].toggle_in ^= 1;
707 CLEAR_HC_INT(hcreg , chhltd);
710 else if (hcint.b.xacterr)
712 UNMASK_HOST_INT_CHH (num);
713 pdev->host.HC_Status[num] = HC_XACTERR;
714 USB_OTG_HC_Halt(pdev, num);
715 CLEAR_HC_INT(hcreg , xacterr);
717 else if (hcint.b.nak)
719 if(hcchar.b.eptype == EP_TYPE_INTR)
721 UNMASK_HOST_INT_CHH (num);
722 if (pdev->cfg.dma_enable == 0)
724 USB_OTG_HC_Halt(pdev, num);
728 pdev->host.HC_Status[num] = HC_NAK;
729 CLEAR_HC_INT(hcreg , nak);
731 if ((hcchar.b.eptype == EP_TYPE_CTRL)||
732 (hcchar.b.eptype == EP_TYPE_BULK))
734 /* re-activate the channel */
735 hcchar.b.chen = 1;
736 hcchar.b.chdis = 0;
737 USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[num]->HCCHAR, hcchar.d32);
742 return 1;
747 * @brief USB_OTG_USBH_handle_rx_qlvl_ISR
748 * Handles the Rx Status Queue Level Interrupt
749 * @param pdev: Selected device
750 * @retval status
752 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
753 #pragma optimize = none
754 #endif /* __CC_ARM */
755 static uint32_t USB_OTG_USBH_handle_rx_qlvl_ISR (USB_OTG_CORE_HANDLE *pdev)
757 USB_OTG_GRXFSTS_TypeDef grxsts;
758 USB_OTG_GINTMSK_TypeDef intmsk;
759 USB_OTG_HCTSIZn_TypeDef hctsiz;
760 USB_OTG_HCCHAR_TypeDef hcchar;
761 __IO uint8_t channelnum =0;
762 uint32_t count;
764 /* Disable the Rx Status Queue Level interrupt */
765 intmsk.d32 = 0;
766 intmsk.b.rxstsqlvl = 1;
767 USB_OTG_MODIFY_REG32( &pdev->regs.GREGS->GINTMSK, intmsk.d32, 0);
769 grxsts.d32 = USB_OTG_READ_REG32(&pdev->regs.GREGS->GRXSTSP);
770 channelnum = grxsts.b.chnum;
771 hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[channelnum]->HCCHAR);
773 switch (grxsts.b.pktsts)
775 case GRXSTS_PKTSTS_IN:
776 /* Read the data into the host buffer. */
777 if ((grxsts.b.bcnt > 0) && (pdev->host.hc[channelnum].xfer_buff != (void *)0))
780 USB_OTG_ReadPacket(pdev, pdev->host.hc[channelnum].xfer_buff, grxsts.b.bcnt);
781 /*manage multiple Xfer */
782 pdev->host.hc[grxsts.b.chnum].xfer_buff += grxsts.b.bcnt;
783 pdev->host.hc[grxsts.b.chnum].xfer_count += grxsts.b.bcnt;
786 count = pdev->host.hc[channelnum].xfer_count;
787 pdev->host.XferCnt[channelnum] = count;
789 hctsiz.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[channelnum]->HCTSIZ);
790 if(hctsiz.b.pktcnt > 0)
792 /* re-activate the channel when more packets are expected */
793 hcchar.b.chen = 1;
794 hcchar.b.chdis = 0;
795 USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[channelnum]->HCCHAR, hcchar.d32);
798 break;
800 case GRXSTS_PKTSTS_IN_XFER_COMP:
802 case GRXSTS_PKTSTS_DATA_TOGGLE_ERR:
803 case GRXSTS_PKTSTS_CH_HALTED:
804 default:
805 break;
808 /* Enable the Rx Status Queue Level interrupt */
809 intmsk.b.rxstsqlvl = 1;
810 USB_OTG_MODIFY_REG32(&pdev->regs.GREGS->GINTMSK, 0, intmsk.d32);
811 return 1;
815 * @brief USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR
816 * Handles the incomplete Periodic transfer Interrupt
817 * @param pdev: Selected device
818 * @retval status
820 #if defined ( __ICCARM__ ) /*!< IAR Compiler */
821 #pragma optimize = none
822 #endif /* __CC_ARM */
823 static uint32_t USB_OTG_USBH_handle_IncompletePeriodicXfer_ISR (USB_OTG_CORE_HANDLE *pdev)
826 USB_OTG_GINTSTS_TypeDef gintsts;
827 USB_OTG_HCCHAR_TypeDef hcchar;
832 hcchar.d32 = USB_OTG_READ_REG32(&pdev->regs.HC_REGS[0]->HCCHAR);
833 hcchar.b.chen = 1;
834 hcchar.b.chdis = 1;
835 USB_OTG_WRITE_REG32(&pdev->regs.HC_REGS[0]->HCCHAR, hcchar.d32);
837 gintsts.d32 = 0;
838 /* Clear interrupt */
839 gintsts.b.incomplisoout = 1;
840 USB_OTG_WRITE_REG32(&pdev->regs.GREGS->GINTSTS, gintsts.d32);
842 return 1;
846 * @}
850 * @}
854 * @}
857 /************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/