From 14488409b784e3fa2803947e8b9a9beb52e55a5b Mon Sep 17 00:00:00 2001 From: Russ Butler Date: Fri, 26 Oct 2018 11:11:49 -0500 Subject: [PATCH] Ignore disabled Kinetis USB endpoint interrupts Ignore interrupts on disabled USB endpoints. This prevents handling interrupts when in the wrong state. Prior to this patch when running the serial test on a K64F the assert on line 908 of USBDevice.cpp would sometimes be triggered. This assert indicates that an endpoint 0 IN interrupt occurred before the device was ready. This occurs during the test_cdc_usb_reconnect test when the host sends a "Set Control Line State" USB request and the device acknowledges it just before USB is disconnected. --- usb/device/targets/TARGET_Freescale/USBPhy_Kinetis.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/usb/device/targets/TARGET_Freescale/USBPhy_Kinetis.cpp b/usb/device/targets/TARGET_Freescale/USBPhy_Kinetis.cpp index 16b0cd28569..07282bc400a 100644 --- a/usb/device/targets/TARGET_Freescale/USBPhy_Kinetis.cpp +++ b/usb/device/targets/TARGET_Freescale/USBPhy_Kinetis.cpp @@ -636,8 +636,11 @@ void USBPhyHw::process() uint32_t ev_odd = (USB0->STAT >> 2) & 0x01; int phy_ep = (num << 1) | dir; + bool tx_en = (USB0->ENDPOINT[PHY_TO_LOG(phy_ep)].ENDPT & USB_ENDPT_EPTXEN_MASK) ? true : false; + bool rx_en = (USB0->ENDPOINT[PHY_TO_LOG(phy_ep)].ENDPT & USB_ENDPT_EPRXEN_MASK) ? true : false; + // setup packet - if ((num == 0) && (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == SETUP_TOKEN)) { + if (tx_en && (num == 0) && (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == SETUP_TOKEN)) { setup_suspend = true; Data1 |= 0x02 | 0x01; // set DATA1 for TX and RX bdt[EP_BDT_IDX(0, TX, EVEN)].info &= ~BD_OWN_MASK; @@ -648,7 +651,7 @@ void USBPhyHw::process() } else { // OUT packet - if (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == OUT_TOKEN) { + if (rx_en && (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == OUT_TOKEN)) { if (num == 0) events->ep0_out(); else { @@ -658,7 +661,7 @@ void USBPhyHw::process() } // IN packet - if (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == IN_TOKEN) { + if (tx_en && (TOK_PID((EP_BDT_IDX(num, dir, ev_odd))) == IN_TOKEN)) { if (num == 0) { events->ep0_in(); if (set_addr == 1) {