Quellcode durchsuchen

add hpmicro patch

Signed-off-by: Jiading Xu <Jiading.Xu@hpmicro.com>
Jiading Xu vor 4 Jahren
Ursprung
Commit
83101e3d26

+ 5 - 1
rt-thread/SConscript

@@ -21,7 +21,11 @@ if GetDepend(["SOC_FAMILY_STM32"]):
 if GetDepend(["SOC_NRF52840"]):
     src += ["../src/portable/nordic/nrf5x/dcd_nrf5x.c",
             "bsp/nrf5x/drv_tinyusb.c"]
-    
+
+if GetDepend(["SOC_HPM6000"]):
+    src +=  ["bsp/hpmicro/drv_tinyusb.c",
+    		 "../src/portable/hpm/dcd_hpm.c"]            
+                
 # Device class
 if GetDepend(["PKG_TINYUSB_DEVICE_CDC"]):
     src += ["../src/class/cdc/cdc_device.c"]

+ 41 - 0
rt-thread/bsp/hpmicro/drv_tinyusb.c

@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2021 hpmicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+#include <tusb.h>
+#include "board.h"
+
+extern void tud_descriptor_set_serial(char *serial_number, uint8_t length);
+
+TU_ATTR_WEAK void generate_serial_number(void)
+{
+    char serial_number[32] = {"00001"};
+
+    tud_descriptor_set_serial(serial_number, sizeof(serial_number));
+}
+
+TU_ATTR_WEAK int tusb_board_init(void)
+{
+    generate_serial_number();
+
+    return 0;
+}
+
+TU_ATTR_WEAK void isr_usb0(void)
+{
+    rt_interrupt_enter();
+    dcd_int_handler(0);
+    rt_interrupt_leave();
+}
+SDK_DECLARE_EXT_ISR_M(IRQn_USB0, isr_usb0)
+
+TU_ATTR_WEAK void isr_usb1(void)
+{
+    rt_interrupt_enter();
+    dcd_int_handler(1);
+    rt_interrupt_leave();
+}
+SDK_DECLARE_EXT_ISR_M(IRQn_USB1, isr_usb1)

+ 21 - 0
src/class/hid/hid_device.c

@@ -80,6 +80,26 @@ bool tud_hid_n_ready(uint8_t instance)
   return tud_ready() && (ep_in != 0) && !usbd_edpt_busy(TUD_OPT_RHPORT, ep_in);
 }
 
+#if  (CFG_TUD_HID_EP_BUFSIZE >= 256)
+bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, uint16_t len)
+{
+  uint8_t const rhport = 0;
+  hidd_interface_t * p_hid = &_hidd_itf[instance];
+  TU_VERIFY( usbd_edpt_claim(rhport, p_hid->ep_in) );
+  if (report_id)
+  {
+    len = tu_min16(len, CFG_TUD_HID_EP_BUFSIZE-1);
+    p_hid->epin_buf[0] = report_id;
+    memcpy(p_hid->epin_buf+1, report, len);
+    len++;
+  }else
+  {
+    len = tu_min16(len, CFG_TUD_HID_EP_BUFSIZE);
+    memcpy(p_hid->epin_buf, report, len);
+  }
+  return usbd_edpt_xfer(TUD_OPT_RHPORT, p_hid->ep_in, p_hid->epin_buf, len);
+}
+#else
 bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, uint8_t len)
 {
   uint8_t const rhport = 0;
@@ -105,6 +125,7 @@ bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, u
 
   return usbd_edpt_xfer(TUD_OPT_RHPORT, p_hid->ep_in, p_hid->epin_buf, len);
 }
+#endif
 
 uint8_t tud_hid_n_interface_protocol(uint8_t instance)
 {

+ 41 - 3
src/class/hid/hid_device.h

@@ -62,7 +62,11 @@ uint8_t tud_hid_n_interface_protocol(uint8_t instance);
 uint8_t tud_hid_n_get_protocol(uint8_t instance);
 
 // Send report to host
-bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, uint8_t len);
+#if (CFG_TUD_HID_EP_BUFSIZE >= 256)
+    bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, uint16_t len);
+#else
+    bool tud_hid_n_report(uint8_t instance, uint8_t report_id, void const* report, uint8_t len);
+#endif
 
 // KEYBOARD: convenient helper to send keyboard report if application
 // use template layout report as defined by hid_keyboard_report_t
@@ -82,7 +86,11 @@ bool tud_hid_n_gamepad_report(uint8_t instance, uint8_t report_id, int8_t x, int
 static inline bool    tud_hid_ready(void);
 static inline uint8_t tud_hid_interface_protocol(void);
 static inline uint8_t tud_hid_get_protocol(void);
+#if  (CFG_TUD_HID_EP_BUFSIZE >= 256)
+    static inline bool tud_hid_report(uint8_t report_id, void const* report, uint16_t len);
+#else
 static inline bool    tud_hid_report(uint8_t report_id, void const* report, uint8_t len);
+#endif
 static inline bool    tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6]);
 static inline bool    tud_hid_mouse_report(uint8_t report_id, uint8_t buttons, int8_t x, int8_t y, int8_t vertical, int8_t horizontal);
 static inline bool    tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y, int8_t z, int8_t rz, int8_t rx, int8_t ry, uint8_t hat, uint32_t buttons);
@@ -137,10 +145,17 @@ static inline uint8_t tud_hid_get_protocol(void)
   return tud_hid_n_get_protocol(0);
 }
 
+#if  (CFG_TUD_HID_EP_BUFSIZE >= 256)
+static inline bool tud_hid_report(uint8_t report_id, void const* report, uint16_t len)
+{
+  return tud_hid_n_report(0, report_id, report, len);
+}
+#else
 static inline bool tud_hid_report(uint8_t report_id, void const* report, uint8_t len)
 {
   return tud_hid_n_report(0, report_id, report, len);
 }
+#endif
 
 static inline bool tud_hid_keyboard_report(uint8_t report_id, uint8_t modifier, uint8_t keycode[6])
 {
@@ -355,6 +370,29 @@ static inline bool  tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y
 // HID Generic Input & Output
 // - 1st parameter is report size (mandatory)
 // - 2nd parameter is report id HID_REPORT_ID(n) (optional)
+#if (CFG_TUSB_REPORT_ID_COUNT == 2)
+  #define TUD_HID_REPORT_DESC_GENERIC_INOUT(report_size, ...) \
+    HID_USAGE_PAGE_N ( HID_USAGE_PAGE_VENDOR, 2   ),\
+    HID_USAGE        ( 0x01                       ),\
+    HID_COLLECTION   ( HID_COLLECTION_APPLICATION ),\
+      GET_1ST_2ND_ARGS(__VA_ARGS__), \
+      /* Input */ \
+      HID_USAGE       ( 0x02                                   ),\
+      HID_LOGICAL_MIN ( 0x00                                   ),\
+      HID_LOGICAL_MAX ( 0xff                                   ),\
+      HID_REPORT_SIZE ( 8                                      ),\
+      HID_REPORT_COUNT_N( report_size, 2                       ),\
+      HID_INPUT       ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\
+      /* Output */ \
+      GET_3RD_4TH_ARGS(__VA_ARGS__), \
+      HID_USAGE       ( 0x03                                   ),\
+      HID_LOGICAL_MIN ( 0x00                                   ),\
+      HID_LOGICAL_MAX ( 0xff                                   ),\
+      HID_REPORT_SIZE ( 8                                      ),\
+      HID_REPORT_COUNT_N( report_size, 2                       ),\
+      HID_OUTPUT      ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ),\
+    HID_COLLECTION_END
+#elif (CFG_TUSB_REPORT_ID_COUNT < 2)
 #define TUD_HID_REPORT_DESC_GENERIC_INOUT(report_size, ...) \
     HID_USAGE_PAGE_N ( HID_USAGE_PAGE_VENDOR, 2   ),\
     HID_USAGE        ( 0x01                       ),\
@@ -375,8 +413,8 @@ static inline bool  tud_hid_gamepad_report(uint8_t report_id, int8_t x, int8_t y
       HID_REPORT_SIZE ( 8                                       ),\
       HID_REPORT_COUNT( report_size                             ),\
       HID_OUTPUT      ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE  ),\
-    HID_COLLECTION_END \
-
+    HID_COLLECTION_END
+#endif
 //--------------------------------------------------------------------+
 // Internal Class Driver API
 //--------------------------------------------------------------------+

+ 4 - 0
src/common/tusb_verify.h

@@ -101,8 +101,12 @@
  *------------------------------------------------------------------*/
 
 // Helper to implement optional parameter for TU_VERIFY Macro family
+#define GET_1ST_ARG(arg1, ...)                    arg1
+#define GET_2ND_ARG(arg1, arg2, ...)              arg2
 #define GET_3RD_ARG(arg1, arg2, arg3, ...)        arg3
 #define GET_4TH_ARG(arg1, arg2, arg3, arg4, ...)  arg4
+#define GET_1ST_2ND_ARGS(...)     GET_1ST_ARG(__VA_ARGS__), GET_2ND_ARG(__VA_ARGS__)
+#define GET_3RD_4TH_ARGS(...)     GET_3RD_ARG(__VA_ARGS__), GET_4TH_ARG(__VA_ARGS__)
 
 /*------------- Generator for TU_VERIFY and TU_VERIFY_HDLR -------------*/
 #define TU_VERIFY_DEFINE(_cond, _handler, _ret)  do            \

+ 6 - 0
src/device/dcd.h

@@ -53,6 +53,7 @@ typedef enum
   DCD_EVENT_INVALID = 0,
   DCD_EVENT_BUS_RESET,
   DCD_EVENT_UNPLUGGED,
+  DCD_EVENT_PLUGGED,
   DCD_EVENT_SOF,
   DCD_EVENT_SUSPEND, // TODO LPM Sleep L1 support
   DCD_EVENT_RESUME,
@@ -78,6 +79,11 @@ typedef struct TU_ATTR_ALIGNED(4)
       tusb_speed_t speed;
     } bus_reset;
 
+    // Plugged
+    struct {
+      tusb_speed_t speed;
+    } plugged;
+
     // SETUP_RECEIVED
     tusb_control_request_t setup_received;
 

+ 2 - 0
src/device/dcd_attr.h

@@ -212,6 +212,8 @@
 #elif TU_CHECK_MCU(OPT_MCU_F1C100S)
   #define DCD_ATTR_ENDPOINT_MAX   4
 
+#elif TU_CHECK_MCU(OPT_MCU_HPM)
+  #define DCD_ATTR_ENDPOINT_MAX   8
 #else
   #warning "DCD_ATTR_ENDPOINT_MAX is not defined for this MCU, default to 8"
   #define DCD_ATTR_ENDPOINT_MAX   8

+ 11 - 0
src/device/usbd.c

@@ -306,6 +306,7 @@ static char const* const _usbd_event_str[DCD_EVENT_COUNT] =
   "Invalid"        ,
   "Bus Reset"      ,
   "Unplugged"      ,
+  "Plugged"        ,
   "SOF"            ,
   "Suspend"        ,
   "Resume"         ,
@@ -357,6 +358,11 @@ tusb_speed_t tud_speed_get(void)
   return (tusb_speed_t) _usbd_dev.speed;
 }
 
+void tud_speed_set(tusb_speed_t speed)
+{
+    _usbd_dev.speed = speed;
+}
+
 bool tud_connected(void)
 {
   return _usbd_dev.connected;
@@ -521,6 +527,11 @@ void tud_task (void)
         if (tud_umount_cb) tud_umount_cb();
       break;
 
+      case DCD_EVENT_PLUGGED:
+        TU_LOG2(": %s Speed\r\n", _tusb_speed_str[event.plugged.speed]);
+        tud_speed_set(event.plugged.speed);
+      break;
+
       case DCD_EVENT_SETUP_RECEIVED:
         TU_LOG2_VAR(&event.setup_received);
         TU_LOG2("\r\n");

+ 3 - 0
src/device/usbd.h

@@ -56,6 +56,9 @@ extern void dcd_int_handler(uint8_t rhport);
 // Get current bus speed
 tusb_speed_t tud_speed_get(void);
 
+// Adjust endpoint's attributes matched with the current bus speed
+void tud_speed_set(tusb_speed_t speed);
+
 // Check if device is connected (may not mounted/configured yet)
 // True if just got out of Bus Reset and received the very first data from host
 bool tud_connected(void);

+ 290 - 0
src/portable/hpm/dcd_hpm.c

@@ -0,0 +1,290 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2019 Ha Thach (tinyusb.org)
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ *
+ * This file is part of the TinyUSB stack.
+ */
+
+/*
+ * Copyright (c) 2021 hpmicro
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ *
+ */
+
+/*---------------------------------------------------------------------*
+ * Include
+ *---------------------------------------------------------------------*/
+#include "tusb_option.h"
+
+#if TUSB_OPT_DEVICE_ENABLED && CFG_TUSB_MCU == OPT_MCU_HPM
+
+#include "board.h"
+#include "hpm_usb_device.h"
+#include "common/tusb_common.h"
+#include "device/dcd.h"
+
+/*---------------------------------------------------------------------*
+ * Macro Enum Declaration
+ *---------------------------------------------------------------------*/
+/* USBSTS, USBINTR */
+enum {
+    intr_usb         = HPM_BITSMASK(1, 0),
+    intr_error       = HPM_BITSMASK(1, 1),
+    intr_port_change = HPM_BITSMASK(1, 2),
+    intr_reset       = HPM_BITSMASK(1, 6),
+    intr_sof         = HPM_BITSMASK(1, 7),
+    intr_suspend     = HPM_BITSMASK(1, 8),
+    intr_nak         = HPM_BITSMASK(1, 16)
+};
+
+/*---------------------------------------------------------------------*
+ * Macro Typedef Declaration
+ *---------------------------------------------------------------------*/
+typedef struct {
+    USB_Type* regs;         /* register base*/
+    const uint32_t irqnum;  /* IRQ number */
+    const uint8_t ep_count; /* Max bi-directional Endpoints */
+} dcd_controller_t;
+
+/*---------------------------------------------------------------------*
+ * Variable Definitions
+ *---------------------------------------------------------------------*/
+static const dcd_controller_t _dcd_controller[] =
+{
+    { .regs = (USB_Type*) HPM_USB0_BASE, .irqnum = IRQn_USB0, .ep_count = USB_SOC_DCD_MAX_ENDPOINT_COUNT },
+    { .regs = (USB_Type*) HPM_USB1_BASE, .irqnum = IRQn_USB1, .ep_count = USB_SOC_DCD_MAX_ENDPOINT_COUNT }
+};
+
+ATTR_PLACE_AT_NONCACHEABLE static usb_device_handle_t usb_device_handle[USB_SOC_MAX_COUNT];
+
+ATTR_PLACE_AT_NONCACHEABLE_WITH_ALIGNMENT(USB_SOC_DCD_DATA_RAM_ADDRESS_ALIGNMENT) static dcd_data_t _dcd_data;
+
+/*---------------------------------------------------------------------*
+ * Device API
+ *---------------------------------------------------------------------*/
+
+/* USB bus reset */
+static void bus_reset(uint8_t rhport)
+{
+    usb_device_bus_reset(&usb_device_handle[rhport], CFG_TUD_ENDPOINT0_SIZE);
+}
+
+/* Initialize controller to device mode */
+void dcd_init(uint8_t rhport)
+{
+    uint32_t int_mask;
+
+    usb_device_handle[rhport].regs     = _dcd_controller[rhport].regs;
+    usb_device_handle[rhport].dcd_data =  &_dcd_data;
+
+    int_mask = (USB_USBINTR_UE_MASK | USB_USBINTR_UEE_MASK | USB_USBINTR_PCE_MASK | USB_USBINTR_URE_MASK
+
+    #if (defined(USB_DEVICE_CONFIG_LOW_POWER_MODE) && (USB_DEVICE_CONFIG_LOW_POWER_MODE > 0U))
+                    | USB_USBINTR_SLE_MASK
+    #endif /* USB_DEVICE_CONFIG_LOW_POWER_MODE */
+                    );
+
+    usb_device_init(&usb_device_handle[rhport], int_mask);
+}
+
+/* De-initialize controller */
+void dcd_deinit(uint8_t rhport)
+{
+    usb_device_deinit(&usb_device_handle[rhport]);
+}
+
+/* Enable device interrupt */
+void dcd_int_enable(uint8_t rhport)
+{
+    intc_m_enable_irq(_dcd_controller[rhport].irqnum);
+}
+
+/* Disable device interrupt */
+void dcd_int_disable(uint8_t rhport)
+{
+    intc_m_disable_irq(_dcd_controller[rhport].irqnum);
+}
+
+/* Receive Set Address request, mcu port must also include status IN response */
+void dcd_set_address(uint8_t rhport, uint8_t dev_addr)
+{
+    usb_device_set_address(&usb_device_handle[rhport], dev_addr);
+}
+
+/* Wake up host */
+void dcd_remote_wakeup(uint8_t rhport)
+{
+    usb_device_remote_wakeup(&usb_device_handle[rhport]);
+}
+
+/* Connect by enabling internal pull-up resistor on D+/D- */
+void dcd_connect(uint8_t rhport)
+{
+    usb_device_connect(&usb_device_handle[rhport]);
+}
+
+/* Disconnect by disabling internal pull-up resistor on D+/D- */
+void dcd_disconnect(uint8_t rhport)
+{
+    usb_device_disconnect(&usb_device_handle[rhport]);
+}
+
+/*---------------------------------------------------------------------*
+ * Endpoint API
+ *---------------------------------------------------------------------*/
+/* Configure endpoint's registers according to descriptor */
+bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc)
+{
+    usb_endpoint_config_t ep_cfg;
+
+    ep_cfg.xfer            = p_endpoint_desc->bmAttributes.xfer;
+    ep_cfg.ep_addr         = p_endpoint_desc->bEndpointAddress;
+    ep_cfg.max_packet_size = p_endpoint_desc->wMaxPacketSize;
+
+    return usb_device_edpt_open(&usb_device_handle[rhport], &ep_cfg);
+}
+
+/* Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack */
+bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
+{
+    return usb_device_edpt_xfer(&usb_device_handle[rhport], ep_addr, buffer, total_bytes);
+}
+
+/* Stall endpoint */
+void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr)
+{
+    usb_device_edpt_stall(&usb_device_handle[rhport], ep_addr);
+}
+
+/* clear stall, data toggle is also reset to DATA0 */
+void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr)
+{
+    usb_device_edpt_clear_stall(&usb_device_handle[rhport], ep_addr);
+}
+
+/* close a specified endpoint */
+void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr)
+{
+    usb_device_edpt_close(&usb_device_handle[rhport], ep_addr);
+}
+
+/* Close all non-control endpoints, cancel all pending transfers if any */
+void dcd_edpt_close_all(uint8_t rhport)
+{
+    usb_device_edpt_close_all(&usb_device_handle[rhport]);
+}
+/*---------------------------------------------------------------------*
+ * Internal API
+ *---------------------------------------------------------------------*/
+/* Index to bit position in register */
+static inline uint8_t ep_idx2bit(uint8_t ep_idx)
+{
+    return ep_idx / 2 + ((ep_idx % 2) ? 16 : 0);
+}
+
+/*---------------------------------------------------------------------*
+ * ISR
+ *---------------------------------------------------------------------*/
+void dcd_int_handler(uint8_t rhport)
+{
+    uint32_t int_status;
+    uint32_t speed;
+    usb_device_handle_t *handle = &usb_device_handle[rhport];
+
+    /* Acknowledge handled interrupt */
+    int_status = usb_device_status_flags(handle);
+    int_status &= usb_device_interrupts(handle);
+    usb_device_clear_status_flags(handle, int_status);
+
+    /* disabled interrupt sources */
+    if (int_status == 0) {
+        return;
+    }
+
+    if (int_status & intr_reset) {
+        bus_reset(rhport);
+        speed = usb_device_get_port_speed(handle);
+        dcd_event_bus_reset(rhport, (tusb_speed_t)speed, true);
+    }
+
+    if (int_status & intr_suspend) {
+         if (usb_device_get_suspend_status(handle)) {
+            /* Note: Host may delay more than 3 ms before and/or after bus reset before doing enumeration. */
+            if (usb_device_get_address(handle)) {
+                dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true);
+            }
+        }
+    }
+
+    if (int_status & intr_port_change) {
+        if (!usb_device_get_port_ccs(handle)) {
+            dcd_event_t event = {.rhport = rhport, .event_id = DCD_EVENT_UNPLUGGED};
+            dcd_event_handler(&event, true);
+        } else {
+            dcd_event_t event = {.rhport = rhport, .event_id = DCD_EVENT_PLUGGED};
+            if (usb_device_get_port_reset_status(handle) == 0) {
+                 uint32_t speed = usb_device_get_port_speed(handle);
+                 event.plugged.speed = speed;
+                 dcd_event_handler(&event, true);
+            }
+        }
+    }
+
+    if (int_status & intr_usb) {
+        uint32_t const edpt_complete = usb_device_get_edpt_complete_status(handle);
+        usb_device_clear_edpt_complete_status(handle, edpt_complete);
+
+        uint32_t edpt_setup_status = usb_device_get_setup_status(handle);
+        if (edpt_setup_status) {
+            /*------------- Set up Received -------------*/
+            usb_device_clear_setup_status(handle, edpt_setup_status);
+            dcd_qhd_t *qhd0 = usb_device_qhd_get(&usb_device_handle[rhport], 0);
+            dcd_event_setup_received(rhport, (uint8_t*) &qhd0->setup_request, true);
+        }
+
+        if (edpt_complete) {
+            for(uint8_t ep_idx = 0; ep_idx < USB_SOS_DCD_MAX_QHD_COUNT; ep_idx++) {
+                if (tu_bit_test(edpt_complete, ep_idx2bit(ep_idx))) {
+                    /* Failed QTD also get ENDPTCOMPLETE set */
+                    dcd_qtd_t *p_qtd = usb_device_qtd_get(&usb_device_handle[rhport], ep_idx);
+
+                    uint8_t result = p_qtd->halted ? XFER_RESULT_STALLED :
+                    (p_qtd->xact_err ||p_qtd->buffer_err) ? XFER_RESULT_FAILED : XFER_RESULT_SUCCESS;
+
+                    uint8_t const ep_addr = (ep_idx/2) | ( (ep_idx & 0x01) ? TUSB_DIR_IN_MASK : 0);
+                    /* only number of bytes in the IOC qtd */
+                    dcd_event_xfer_complete(rhport, ep_addr, p_qtd->expected_bytes - p_qtd->total_bytes, result, true);
+                }
+            }
+        }
+    }
+
+    if (int_status & intr_sof) {
+        dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true);
+    }
+
+    if (int_status & intr_nak) {}
+    if (int_status & intr_error) TU_ASSERT(false, );
+}
+
+#endif

+ 3 - 0
src/tusb_option.h

@@ -148,6 +148,9 @@
 // Allwinner
 #define OPT_MCU_F1C100S          2100 ///< Allwinner F1C100s family
 
+// HPMicro
+#define OPT_MCU_HPM              9000 ///< HPMicro HPM6000
+
 // Helper to check if configured MCU is one of listed
 // Apply _TU_CHECK_MCU with || as separator to list of input
 #define _TU_CHECK_MCU(_m)   (CFG_TUSB_MCU == _m)