Skip to content
This repository was archived by the owner on Nov 15, 2023. It is now read-only.

Commit b73f846

Browse files
committed
clear interrupt flag first, because operation afterwards will maybe trigger next interrupt
1 parent ecc671e commit b73f846

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

vsf/vsf/component/usb/driver/otg/dwcotg/vsf_dwcotg_dcd.c

+7-5
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)