@@ -648,6 +648,8 @@ void vk_dwcotg_dcd_irq(vk_dwcotg_dcd_t *dwcotg_dcd)
648648 int_status &= (int_msak | USB_OTG_DIEPINT_TXFE );
649649
650650 if (int_status & USB_OTG_DIEPINT_XFRC ) {
651+ // clear interrupt flag first, because operation afterwards will maybe trigger next interrupt
652+ in_regs [ep_idx ].diepint = USB_OTG_DIEPINT_XFRC ;
651653 if ((ep_idx == 0 ) && (dwcotg_dcd -> ctrl_transfer_state == DWCOTG_STATUS_STAGE )) {
652654 dwcotg_dcd -> ctrl_transfer_state = DWCOTG_SETUP_STAGE ;
653655 __vk_dwcotg_dcd_notify (dwcotg_dcd , USB_ON_STATUS , 0 );
@@ -658,7 +660,7 @@ void vk_dwcotg_dcd_irq(vk_dwcotg_dcd_t *dwcotg_dcd)
658660 } else if (trans -> zlp ) {
659661 // OTG Programmer's Guild, 8.4:
660662 // To transmit a few maximum-packet-size packets and a zero-length
661- // data packet at the end of thetransfer , the application must split
663+ // data packet at the end of the transfer , the application must split
662664 // the transfer in two parts. The first sends maximum-packet-sizedata
663665 // packets and the second sends the zero-length data packet alone.
664666 trans -> zlp = false;
@@ -667,7 +669,6 @@ void vk_dwcotg_dcd_irq(vk_dwcotg_dcd_t *dwcotg_dcd)
667669 __vk_dwcotg_dcd_notify (dwcotg_dcd , USB_ON_IN , ep_idx );
668670 }
669671 }
670- in_regs [ep_idx ].diepint = USB_OTG_DIEPINT_XFRC ;
671672 }
672673 if (int_status & USB_OTG_DIEPINT_EPDISD ) {
673674 in_regs [ep_idx ].diepint = USB_OTG_DIEPINT_EPDISD ;
@@ -679,8 +680,9 @@ void vk_dwcotg_dcd_irq(vk_dwcotg_dcd_t *dwcotg_dcd)
679680 in_regs [ep_idx ].diepint = USB_OTG_DIEPINT_INEPNE ;
680681 }
681682 if (int_status & USB_OTG_DIEPINT_TXFE ) {
682- __vk_dwcotg_dcd_ep_write ( dwcotg_dcd , ep_idx );
683+ // clear interrupt flag first, because operation afterwards will maybe trigger next interrupt
683684 in_regs [ep_idx ].diepint = USB_OTG_DIEPINT_TXFE ;
685+ __vk_dwcotg_dcd_ep_write (dwcotg_dcd , ep_idx );
684686 }
685687 }
686688 ep_int >>= 1 ;
@@ -696,11 +698,12 @@ void vk_dwcotg_dcd_irq(vk_dwcotg_dcd_t *dwcotg_dcd)
696698 while (ep_int ) {
697699 if (ep_int & 0x1 ) {
698700 uint_fast32_t int_status = out_regs [ep_idx ].doepint ;
699-
700701 int_status &= dev_global_regs -> doepmsk | USB_OTG_DOEPINT_STSPHSERCVD ;
701702
702703 // transfer complete interrupt
703704 if (int_status & USB_OTG_DOEPINT_XFRC ) {
705+ // clear interrupt flag first, because operation afterwards will maybe trigger next interrupt
706+ out_regs [ep_idx ].doepint = USB_OTG_DOEPINT_XFRC ;
704707 if ((ep_idx == 0 ) && (dwcotg_dcd -> ctrl_transfer_state == DWCOTG_STATUS_STAGE )) {
705708 if (!(int_status & USB_OTG_DOEPINT_STSPHSERCVD )) {
706709 dwcotg_dcd -> ctrl_transfer_state = DWCOTG_SETUP_STAGE ;
@@ -714,7 +717,6 @@ void vk_dwcotg_dcd_irq(vk_dwcotg_dcd_t *dwcotg_dcd)
714717 __vk_dwcotg_dcd_notify (dwcotg_dcd , USB_ON_OUT , ep_idx );
715718 }
716719 }
717- out_regs [ep_idx ].doepint = USB_OTG_DOEPINT_XFRC ;
718720 }
719721 // endpoint disable interrupt
720722 if (int_status & USB_OTG_DOEPINT_EPDISD ) {
0 commit comments