From 468df713fcffef56c9d4c0e98a49923483c3197b 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 16b0cd2856..07282bc400 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) {