@@ -648,6 +648,8 @@ void vk_dwcotg_dcd_irq(vk_dwcotg_dcd_t *dwcotg_dcd)
648
648
int_status &= (int_msak | USB_OTG_DIEPINT_TXFE );
649
649
650
650
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 ;
651
653
if ((ep_idx == 0 ) && (dwcotg_dcd -> ctrl_transfer_state == DWCOTG_STATUS_STAGE )) {
652
654
dwcotg_dcd -> ctrl_transfer_state = DWCOTG_SETUP_STAGE ;
653
655
__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)
658
660
} else if (trans -> zlp ) {
659
661
// OTG Programmer's Guild, 8.4:
660
662
// 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
662
664
// the transfer in two parts. The first sends maximum-packet-sizedata
663
665
// packets and the second sends the zero-length data packet alone.
664
666
trans -> zlp = false;
@@ -667,7 +669,6 @@ void vk_dwcotg_dcd_irq(vk_dwcotg_dcd_t *dwcotg_dcd)
667
669
__vk_dwcotg_dcd_notify (dwcotg_dcd , USB_ON_IN , ep_idx );
668
670
}
669
671
}
670
- in_regs [ep_idx ].diepint = USB_OTG_DIEPINT_XFRC ;
671
672
}
672
673
if (int_status & USB_OTG_DIEPINT_EPDISD ) {
673
674
in_regs [ep_idx ].diepint = USB_OTG_DIEPINT_EPDISD ;
@@ -679,8 +680,9 @@ void vk_dwcotg_dcd_irq(vk_dwcotg_dcd_t *dwcotg_dcd)
679
680
in_regs [ep_idx ].diepint = USB_OTG_DIEPINT_INEPNE ;
680
681
}
681
682
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
683
684
in_regs [ep_idx ].diepint = USB_OTG_DIEPINT_TXFE ;
685
+ __vk_dwcotg_dcd_ep_write (dwcotg_dcd , ep_idx );
684
686
}
685
687
}
686
688
ep_int >>= 1 ;
@@ -696,11 +698,12 @@ void vk_dwcotg_dcd_irq(vk_dwcotg_dcd_t *dwcotg_dcd)
696
698
while (ep_int ) {
697
699
if (ep_int & 0x1 ) {
698
700
uint_fast32_t int_status = out_regs [ep_idx ].doepint ;
699
-
700
701
int_status &= dev_global_regs -> doepmsk | USB_OTG_DOEPINT_STSPHSERCVD ;
701
702
702
703
// transfer complete interrupt
703
704
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 ;
704
707
if ((ep_idx == 0 ) && (dwcotg_dcd -> ctrl_transfer_state == DWCOTG_STATUS_STAGE )) {
705
708
if (!(int_status & USB_OTG_DOEPINT_STSPHSERCVD )) {
706
709
dwcotg_dcd -> ctrl_transfer_state = DWCOTG_SETUP_STAGE ;
@@ -714,7 +717,6 @@ void vk_dwcotg_dcd_irq(vk_dwcotg_dcd_t *dwcotg_dcd)
714
717
__vk_dwcotg_dcd_notify (dwcotg_dcd , USB_ON_OUT , ep_idx );
715
718
}
716
719
}
717
- out_regs [ep_idx ].doepint = USB_OTG_DOEPINT_XFRC ;
718
720
}
719
721
// endpoint disable interrupt
720
722
if (int_status & USB_OTG_DOEPINT_EPDISD ) {
0 commit comments