Explorar el Código

Merge remote-tracking branch 'hathach/master'

FrankTan hace 3 años
padre
commit
aeb2f92308
Se han modificado 93 ficheros con 1697 adiciones y 3270 borrados
  1. 4 0
      .github/ISSUE_TEMPLATE/config.yml
  2. 2 2
      .github/workflows/build_aarch64.yml
  3. 6 5
      .github/workflows/build_arm.yml
  4. 2 2
      .github/workflows/build_esp.yml
  5. 2 2
      .github/workflows/build_msp430.yml
  6. 2 2
      .github/workflows/build_renesas.yml
  7. 2 2
      .github/workflows/build_riscv.yml
  8. 1 1
      .github/workflows/trigger.yml
  9. 2 2
      docs/reference/index.rst
  10. 1 0
      docs/requirements.txt
  11. 9 5
      examples/device/cdc_msc_freertos/src/main.c
  12. 4 0
      examples/device/hid_boot_interface/src/tusb_config.h
  13. 3 1
      examples/device/hid_composite_freertos/src/main.c
  14. 2 0
      examples/device/net_lwip_webserver/src/lwipopts.h
  15. 2 2
      examples/device/uac2_headset/src/main.c
  16. 12 0
      examples/dual/CMakeLists.txt
  17. 1 1
      examples/dual/host_hid_to_device_cdc/CMakeLists.txt
  18. 0 0
      examples/dual/host_hid_to_device_cdc/Makefile
  19. 1 0
      examples/dual/host_hid_to_device_cdc/only.txt
  20. 98 117
      examples/dual/host_hid_to_device_cdc/src/main.c
  21. 3 9
      examples/dual/host_hid_to_device_cdc/src/tusb_config.h
  22. 0 1
      examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c
  23. 4 1
      examples/host/bare_api/CMakeLists.txt
  24. 4 1
      examples/host/cdc_msc_hid/CMakeLists.txt
  25. 7 0
      examples/host/cdc_msc_hid/src/tusb_config.h
  26. 4 1
      examples/host/hid_controller/CMakeLists.txt
  27. 1 1
      examples/rules.mk
  28. 4 1
      hw/bsp/imxrt/family.c
  29. 5 0
      hw/bsp/rp2040/family.c
  30. 98 39
      hw/bsp/rp2040/family.cmake
  31. 220 45
      src/class/audio/audio_device.c
  32. 63 1
      src/class/audio/audio_device.h
  33. 1 1
      src/class/hid/hid_host.c
  34. 10 6
      src/common/tusb_common.h
  35. 6 2
      src/common/tusb_debug.h
  36. 7 0
      src/common/tusb_mcu.h
  37. 8 9
      src/common/tusb_verify.h
  38. 43 4
      src/device/dcd.h
  39. 58 59
      src/device/usbd.c
  40. 17 2
      src/device/usbd.h
  41. 4 1
      src/device/usbd_pvt.h
  42. 47 4
      src/host/hcd.h
  43. 28 61
      src/host/usbh.c
  44. 14 5
      src/host/usbh.h
  45. 11 11
      src/osal/osal.h
  46. 29 16
      src/osal/osal_freertos.h
  47. 12 10
      src/osal/osal_mynewt.h
  48. 15 13
      src/osal/osal_none.h
  49. 23 21
      src/osal/osal_pico.h
  50. 15 13
      src/osal/osal_rtthread.h
  51. 14 14
      src/osal/osal_rtx4.h
  52. 7 0
      src/portable/bridgetek/ft9xx/dcd_ft9xx.c
  53. 0 1267
      src/portable/broadcom/synopsys/dcd_synopsys.c
  54. 0 1476
      src/portable/broadcom/synopsys/synopsys_common.h
  55. 8 0
      src/portable/chipidea/ci_hs/dcd_ci_hs.c
  56. 8 0
      src/portable/dialog/da146xx/dcd_da146xx.c
  57. 2 2
      src/portable/ehci/ehci.c
  58. 8 0
      src/portable/espressif/esp32sx/dcd_esp32sx.c
  59. 8 0
      src/portable/mentor/musb/dcd_musb.c
  60. 5 0
      src/portable/mentor/musb/hcd_musb.c
  61. 13 1
      src/portable/microchip/pic32mz/dcd_pic32mz.c
  62. 8 0
      src/portable/microchip/samd/dcd_samd.c
  63. 8 0
      src/portable/microchip/samg/dcd_samg.c
  64. 8 0
      src/portable/microchip/samx7x/dcd_samx7x.c
  65. 8 0
      src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c
  66. 8 0
      src/portable/nordic/nrf5x/dcd_nrf5x.c
  67. 8 0
      src/portable/nuvoton/nuc120/dcd_nuc120.c
  68. 8 0
      src/portable/nuvoton/nuc121/dcd_nuc121.c
  69. 8 0
      src/portable/nuvoton/nuc505/dcd_nuc505.c
  70. 8 0
      src/portable/nxp/khci/dcd_khci.c
  71. 8 0
      src/portable/nxp/lpc17_40/dcd_lpc17_40.c
  72. 8 0
      src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c
  73. 8 0
      src/portable/nxp/transdimension/dcd_transdimension.c
  74. 5 0
      src/portable/ohci/ohci.c
  75. 210 0
      src/portable/raspberrypi/pio_usb/dcd_pio_usb.c
  76. 217 0
      src/portable/raspberrypi/pio_usb/hcd_pio_usb.c
  77. 24 1
      src/portable/raspberrypi/rp2040/dcd_rp2040.c
  78. 14 4
      src/portable/raspberrypi/rp2040/hcd_rp2040.c
  79. 1 1
      src/portable/raspberrypi/rp2040/rp2040_usb.c
  80. 8 0
      src/portable/renesas/usba/dcd_usba.c
  81. 5 0
      src/portable/renesas/usba/hcd_usba.c
  82. 9 1
      src/portable/sony/cxd56/dcd_cxd56.c
  83. 8 0
      src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c
  84. 7 0
      src/portable/st/synopsys/dcd_synopsys.c
  85. 8 0
      src/portable/sunxi/dcd_sunxi_musb.c
  86. 34 4
      src/portable/synopsys/dwc2/dcd_dwc2.c
  87. 6 0
      src/portable/synopsys/dwc2/dwc2_stm32.h
  88. 8 0
      src/portable/template/dcd_template.c
  89. 8 0
      src/portable/ti/msp430x5xx/dcd_msp430x5xx.c
  90. 7 0
      src/portable/valentyusb/eptri/dcd_eptri.c
  91. 22 5
      src/tusb_option.h
  92. 5 6
      tools/build_board.py
  93. 5 6
      tools/build_family.py

+ 4 - 0
.github/ISSUE_TEMPLATE/config.yml

@@ -1,4 +1,8 @@
+blank_issues_enabled: false
 contact_links:
   - name: TinyUSB Discussion
     url: https://github.com/hathach/tinyusb/discussions
     about: If you have other questions or need help, post it here.
+  - name: TinyUSB Docs
+    url: https://docs.tinyusb.org/
+    about: Online documentation

+ 2 - 2
.github/workflows/build_aarch64.yml

@@ -24,13 +24,13 @@ jobs:
       uses: actions/setup-python@v2
 
     - name: Checkout TinyUSB
-      uses: actions/checkout@v2
+      uses: actions/checkout@v3
 
     - name: Checkout common submodules in lib
       run: git submodule update --init lib/FreeRTOS-Kernel lib/lwip lib/sct_neopixel
 
     - name: Checkout hathach/linkermap
-      uses: actions/checkout@v2
+      uses: actions/checkout@v3
       with:
          repository: hathach/linkermap
          path: linkermap

+ 6 - 5
.github/workflows/build_arm.yml

@@ -15,12 +15,12 @@ jobs:
     runs-on: ubuntu-latest
     steps:
     - name: Setup Ruby
-      uses: actions/setup-ruby@v1
+      uses: ruby/setup-ruby@v1
       with:
         ruby-version: '2.7'
 
     - name: Checkout TinyUSB
-      uses: actions/checkout@v2
+      uses: actions/checkout@v3
 
     - name: Unit Tests
       run: |
@@ -66,13 +66,13 @@ jobs:
       uses: actions/setup-python@v2
 
     - name: Checkout TinyUSB
-      uses: actions/checkout@v2
+      uses: actions/checkout@v3
 
     - name: Checkout common submodules in lib
       run: git submodule update --init lib/FreeRTOS-Kernel lib/lwip lib/sct_neopixel
 
     - name: Checkout hathach/linkermap
-      uses: actions/checkout@v2
+      uses: actions/checkout@v3
       with:
          repository: hathach/linkermap
          path: linkermap
@@ -82,6 +82,7 @@ jobs:
       run: |
         git clone --depth 1 -b develop https://github.com/raspberrypi/pico-sdk ~/pico-sdk
         echo >> $GITHUB_ENV PICO_SDK_PATH=~/pico-sdk
+        git submodule update --init hw/mcu/raspberry_pi/Pico-PIO-USB
 
     - name: Set Toolchain URL
       run: echo >> $GITHUB_ENV TOOLCHAIN_URL=https://github.com/xpack-dev-tools/arm-none-eabi-gcc-xpack/releases/download/v10.2.1-1.1/xpack-arm-none-eabi-gcc-10.2.1-1.1-linux-x64.tar.gz
@@ -135,7 +136,7 @@ jobs:
       uses: actions/setup-python@v2
 
     - name: Checkout TinyUSB
-      uses: actions/checkout@v2
+      uses: actions/checkout@v3
 
     - name: Checkout common submodules in lib
       run: git submodule update --init lib/FreeRTOS-Kernel lib/lwip

+ 2 - 2
.github/workflows/build_esp.yml

@@ -29,10 +29,10 @@ jobs:
       run: docker pull espressif/idf:latest
 
     - name: Checkout TinyUSB
-      uses: actions/checkout@v2
+      uses: actions/checkout@v3
 
     - name: Checkout hathach/linkermap
-      uses: actions/checkout@v2
+      uses: actions/checkout@v3
       with:
          repository: hathach/linkermap
          path: linkermap

+ 2 - 2
.github/workflows/build_msp430.yml

@@ -21,13 +21,13 @@ jobs:
       uses: actions/setup-python@v2
 
     - name: Checkout TinyUSB
-      uses: actions/checkout@v2
+      uses: actions/checkout@v3
 
     - name: Checkout common submodules in lib
       run: git submodule update --init lib/FreeRTOS-Kernel lib/lwip
 
     - name: Checkout hathach/linkermap
-      uses: actions/checkout@v2
+      uses: actions/checkout@v3
       with:
          repository: hathach/linkermap
          path: linkermap

+ 2 - 2
.github/workflows/build_renesas.yml

@@ -21,13 +21,13 @@ jobs:
       uses: actions/setup-python@v2
 
     - name: Checkout TinyUSB
-      uses: actions/checkout@v2
+      uses: actions/checkout@v3
 
     - name: Checkout common submodules in lib
       run: git submodule update --init lib/FreeRTOS-Kernel lib/lwip
 
     - name: Checkout hathach/linkermap
-      uses: actions/checkout@v2
+      uses: actions/checkout@v3
       with:
          repository: hathach/linkermap
          path: linkermap

+ 2 - 2
.github/workflows/build_riscv.yml

@@ -22,13 +22,13 @@ jobs:
       uses: actions/setup-python@v2
 
     - name: Checkout TinyUSB
-      uses: actions/checkout@v2
+      uses: actions/checkout@v3
 
     - name: Checkout common submodules in lib
       run: git submodule update --init lib/FreeRTOS-Kernel lib/lwip
 
     - name: Checkout hathach/linkermap
-      uses: actions/checkout@v2
+      uses: actions/checkout@v3
       with:
          repository: hathach/linkermap
          path: linkermap

+ 1 - 1
.github/workflows/trigger.yml

@@ -22,7 +22,7 @@ jobs:
     runs-on: ubuntu-latest
     steps:
     - name: Checkout code
-      uses: actions/checkout@v2
+      uses: actions/checkout@v3
 
     - name: Push to tinyusb_src
       run: |

+ 2 - 2
docs/reference/index.rst

@@ -25,7 +25,7 @@ Supports multiple device configurations by dynamically changing usb descriptors.
 -  Vendor-specific class support with generic In & Out endpoints. Can be used with MS OS 2.0 compatible descriptor to load winUSB driver without INF file.
 -  `WebUSB <https://github.com/WICG/webusb>`__ with vendor-specific class
 
-If you have special need, `usbd_app_driver_get_cb()` can be used to write your own class driver without modifying the stack. Here is how RPi team add their reset interface [raspberrypi/pico-sdk#197](https://github.com/raspberrypi/pico-sdk/pull/197)
+If you have special need, `usbd_app_driver_get_cb()` can be used to write your own class driver without modifying the stack. Here is how RPi team add their reset interface `raspberrypi/pico-sdk#197 <https://github.com/raspberrypi/pico-sdk/pull/197>`__
 
 Host Stack
 ==========
@@ -41,7 +41,7 @@ TinyUSB is completely thread-safe by pushing all ISR events into a central queue
 
 - **No OS**
 - **FreeRTOS**
-- **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its [own repo](https://github.com/hathach/mynewt-tinyusb-example)
+- **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its `own repo <https://github.com/hathach/mynewt-tinyusb-example>`__
 
 License
 =======

+ 1 - 0
docs/requirements.txt

@@ -1,3 +1,4 @@
 sphinx~=3.0
 furo>=2020.12.30.b24
 sphinx-autodoc-typehints>=1.10
+jinja2==3.0.3

+ 9 - 5
examples/device/cdc_msc_freertos/src/main.c

@@ -130,8 +130,11 @@ void usb_device_task(void* param)
   // RTOS forever loop
   while (1)
   {
-    // tinyusb device task
+    // put this thread to waiting state until there is new events
     tud_task();
+
+    // following code only run if tud_task() process at least 1 event
+    tud_cdc_write_flush();
   }
 }
 
@@ -181,7 +184,7 @@ void cdc_task(void* params)
     // if ( tud_cdc_connected() )
     {
       // There are data available
-      if ( tud_cdc_available() )
+      while ( tud_cdc_available() )
       {
         uint8_t buf[64];
 
@@ -194,12 +197,13 @@ void cdc_task(void* params)
         // for throughput test e.g
         //    $ dd if=/dev/zero of=/dev/ttyACM0 count=10000
         tud_cdc_write(buf, count);
-        tud_cdc_write_flush();
       }
+
+      tud_cdc_write_flush();
     }
 
-    // For ESP32-S2 this delay is essential to allow idle how to run and reset wdt
-    vTaskDelay(pdMS_TO_TICKS(10));
+    // For ESP32-Sx this delay is essential to allow idle how to run and reset watchdog
+    vTaskDelay(1);
   }
 }
 

+ 4 - 0
examples/device/hid_boot_interface/src/tusb_config.h

@@ -39,6 +39,10 @@
   #error CFG_TUSB_MCU must be defined
 #endif
 
+// Use raspberry pio-usb for device
+// #define CFG_TUD_RPI_PIO_USB     1
+// #define BOARD_DEVICE_RHPORT_NUM 1
+
 // RHPort number used for device can be defined by board.mk, default to port 0
 #ifndef BOARD_DEVICE_RHPORT_NUM
   #define BOARD_DEVICE_RHPORT_NUM     0

+ 3 - 1
examples/device/hid_composite_freertos/src/main.c

@@ -132,8 +132,10 @@ void usb_device_task(void* param)
   // RTOS forever loop
   while (1)
   {
-    // tinyusb device task
+    // put this thread to waiting state until there is new events
     tud_task();
+
+    // following code only run if tud_task() process at least 1 event
   }
 }
 

+ 2 - 0
examples/device/net_lwip_webserver/src/lwipopts.h

@@ -49,7 +49,9 @@
 
 #define TCP_MSS                         (1500 /*mtu*/ - 20 /*iphdr*/ - 20 /*tcphhr*/)
 #define TCP_SND_BUF                     (2 * TCP_MSS)
+#ifndef TCP_WND
 #define TCP_WND                         (TCP_MSS)
+#endif
 
 #define ETHARP_SUPPORT_STATIC_ENTRIES   1
 

+ 2 - 2
examples/device/uac2_headset/src/main.c

@@ -156,7 +156,7 @@ static bool tud_audio_clock_get_request(uint8_t rhport, audio_control_request_t
   {
     if (request->bRequest == AUDIO_CS_REQ_CUR)
     {
-      TU_LOG1("Clock get current freq %u\r\n", current_sample_rate);
+      TU_LOG1("Clock get current freq %lu\r\n", current_sample_rate);
 
       audio_control_cur_4_t curf = { tu_htole32(current_sample_rate) };
       return tud_audio_buffer_and_schedule_control_xfer(rhport, (tusb_control_request_t const *)request, &curf, sizeof(curf));
@@ -205,7 +205,7 @@ static bool tud_audio_clock_set_request(uint8_t rhport, audio_control_request_t
 
     current_sample_rate = ((audio_control_cur_4_t const *)buf)->bCur;
 
-    TU_LOG1("Clock set current freq: %d\r\n", current_sample_rate);
+    TU_LOG1("Clock set current freq: %ld\r\n", current_sample_rate);
 
     return true;
   }

+ 12 - 0
examples/dual/CMakeLists.txt

@@ -0,0 +1,12 @@
+cmake_minimum_required(VERSION 3.5)
+
+include(${CMAKE_CURRENT_SOURCE_DIR}/../../hw/bsp/family_support.cmake)
+
+project(tinyusb_dual_examples)
+family_initialize_project(tinyusb_dual_examples ${CMAKE_CURRENT_LIST_DIR})
+if (FAMILY STREQUAL "rp2040" AND NOT TARGET tinyusb_pico_pio_usb)
+    message("Skipping dual host/device mode examples as Pico-PIO-USB is not available")
+else()
+    # family_add_subdirectory will filter what to actually add based on selected FAMILY
+    family_add_subdirectory(host_hid_to_device_cdc)
+endif()

+ 1 - 1
examples/host/hid_to_cdc/CMakeLists.txt → examples/dual/host_hid_to_device_cdc/CMakeLists.txt

@@ -25,4 +25,4 @@ target_include_directories(${PROJECT} PUBLIC
 
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
-family_configure_device_example(${PROJECT})
+family_configure_dual_usb_example(${PROJECT})

+ 0 - 0
examples/host/hid_to_cdc/Makefile → examples/dual/host_hid_to_device_cdc/Makefile


+ 1 - 0
examples/host/hid_to_cdc/only.txt → examples/dual/host_hid_to_device_cdc/only.txt

@@ -1,2 +1,3 @@
 board:mimxrt1060_evk
 board:mimxrt1064_evk
+mcu:RP2040

+ 98 - 117
examples/host/hid_to_cdc/src/main.c → examples/dual/host_hid_to_device_cdc/src/main.c

@@ -23,10 +23,8 @@
  *
  */
 
-// This example runs both host and device concurrently. The USB host looks for
-// any HID device with reports that are 8 bytes long and then assumes they are
-// keyboard reports. It translates the keypresses of the reports to ASCII and
-// transmits it over CDC to the device's host.
+// This example runs both host and device concurrently. The USB host receive
+// reports from HID device and print it out over USB Device CDC interface.
 
 #include <stdlib.h>
 #include <stdio.h>
@@ -73,12 +71,14 @@ enum  {
 static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED;
 
 void led_blinking_task(void);
-void cdc_task(void);
 
 /*------------- MAIN -------------*/
 int main(void)
 {
   board_init();
+
+  printf("TinyUSB Host HID <-> Device CDC Example\r\n");
+
   tusb_init();
 
   while (1)
@@ -86,15 +86,13 @@ int main(void)
     tud_task(); // tinyusb device task
     tuh_task(); // tinyusb host task
     led_blinking_task();
-
-    cdc_task();
   }
 
   return 0;
 }
 
 //--------------------------------------------------------------------+
-// Device callbacks
+// Device CDC
 //--------------------------------------------------------------------+
 
 // Invoked when device is mounted
@@ -124,8 +122,20 @@ void tud_resume_cb(void)
   blink_interval_ms = BLINK_MOUNTED;
 }
 
+// Invoked when CDC interface received data from host
+void tud_cdc_rx_cb(uint8_t itf)
+{
+  (void) itf;
+
+  char buf[64];
+  uint32_t count = tud_cdc_read(buf, sizeof(buf));
+
+  // TODO control LED on keyboard of host stack
+  (void) count;
+}
+
 //--------------------------------------------------------------------+
-// Host callbacks
+// Host HID
 //--------------------------------------------------------------------+
 
 // Invoked when device with hid interface is mounted
@@ -137,169 +147,140 @@ void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_re
 {
   (void)desc_report;
   (void)desc_len;
+
+  // Interface protocol (hid_interface_protocol_enum_t)
+  const char* protocol_str[] = { "None", "Keyboard", "Mouse" };
+  uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance);
+
   uint16_t vid, pid;
   tuh_vid_pid_get(dev_addr, &vid, &pid);
 
-  printf("HID device address = %d, instance = %d is mounted\r\n", dev_addr, instance);
-  printf("VID = %04x, PID = %04x\r\n", vid, pid);
+  char tempbuf[256];
+  int count = sprintf(tempbuf, "[%04x:%04x][%u] HID Interface%u, Protocol = %s\r\n", vid, pid, dev_addr, instance, protocol_str[itf_protocol]);
+
+  tud_cdc_write(tempbuf, count);
+  tud_cdc_write_flush();
 
-  // Receive any report and treat it like a keyboard.
+  // Receive report from boot keyboard & mouse only
   // tuh_hid_report_received_cb() will be invoked when report is available
-  if ( !tuh_hid_receive_report(dev_addr, instance) )
+  if (itf_protocol == HID_ITF_PROTOCOL_KEYBOARD || itf_protocol == HID_ITF_PROTOCOL_MOUSE)
   {
-    printf("Error: cannot request to receive report\r\n");
+    if ( !tuh_hid_receive_report(dev_addr, instance) )
+    {
+      tud_cdc_write_str("Error: cannot request report\r\n");
+    }
   }
 }
 
 // Invoked when device with hid interface is un-mounted
 void tuh_hid_umount_cb(uint8_t dev_addr, uint8_t instance)
 {
-  printf("HID device address = %d, instance = %d is unmounted\r\n", dev_addr, instance);
+  char tempbuf[256];
+  int count = sprintf(tempbuf, "[%u] HID Interface%u is unmounted\r\n", dev_addr, instance);
+  tud_cdc_write(tempbuf, count);
+  tud_cdc_write_flush();
 }
 
-// keycodes from last report to check if key is holding or newly pressed
-uint8_t last_keycodes[6] = {0};
-
 // look up new key in previous keys
-static inline bool key_in_last_report(const uint8_t key_arr[6], uint8_t keycode)
+static inline bool find_key_in_report(hid_keyboard_report_t const *report, uint8_t keycode)
 {
   for(uint8_t i=0; i<6; i++)
   {
-    if (key_arr[i] == keycode) return true;
+    if (report->keycode[i] == keycode)  return true;
   }
 
   return false;
 }
 
-// Invoked when received report from device via interrupt endpoint
-void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len)
-{
-  if (len != 8)
-  {
-    char ch_num;
-
-    tud_cdc_write_str("incorrect report len: ");
-
-    if ( len > 10 )
-    {
-      ch_num = '0' + (len / 10);
-      tud_cdc_write(&ch_num, 1);
-      len = len % 10;
-    }
-
-    ch_num = '0' + len;
-    tud_cdc_write(&ch_num, 1);
-
-    tud_cdc_write_str("\r\n");
-    tud_cdc_write_flush();
 
-    // Don't request a new report for a wrong sized endpoint.
-    return;
-  }
-
-  uint8_t const modifiers = report[0];
+// convert hid keycode to ascii and print via usb device CDC (ignore non-printable)
+static void process_kbd_report(uint8_t dev_addr, hid_keyboard_report_t const *report)
+{
+  (void) dev_addr;
+  static hid_keyboard_report_t prev_report = { 0, 0, {0} }; // previous report to check key released
   bool flush = false;
 
-  for (int i = 2; i < 8; i++)
+  for(uint8_t i=0; i<6; i++)
   {
-    uint8_t keycode = report[i];
-
-    if (keycode)
+    uint8_t keycode = report->keycode[i];
+    if ( keycode )
     {
-      if ( key_in_last_report(last_keycodes, keycode) )
+      if ( find_key_in_report(&prev_report, keycode) )
       {
         // exist in previous report means the current key is holding
-        // do nothing
       }else
       {
         // not existed in previous report means the current key is pressed
-        // Only print keycodes 0 - 128.
-        if (keycode < 128)
+
+        // remap the key code for Colemak layout
+        #ifdef KEYBOARD_COLEMAK
+        uint8_t colemak_key_code = colemak[keycode];
+        if (colemak_key_code != 0) keycode = colemak_key_code;
+        #endif
+
+        bool const is_shift = report->modifier & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT);
+        uint8_t ch = keycode2ascii[keycode][is_shift ? 1 : 0];
+
+        if (ch)
         {
-          // remap the key code for Colemak layout so @tannewt can type.
-          #ifdef KEYBOARD_COLEMAK
-          uint8_t colemak_key_code = colemak[keycode];
-          if (colemak_key_code != 0) keycode = colemak_key_code;
-          #endif
-
-          bool const is_shift = modifiers & (KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT);
-          char c = keycode2ascii[keycode][is_shift ? 1 : 0];
-          if (c)
-          {
-            if (c == '\n') tud_cdc_write("\r", 1);
-            tud_cdc_write(&c, 1);
-            flush = true;
-          }
+          if (ch == '\n') tud_cdc_write("\r", 1);
+          tud_cdc_write(&ch, 1);
+          flush = true;
         }
       }
     }
+    // TODO example skips key released
   }
 
   if (flush) tud_cdc_write_flush();
 
-  // save current report
-  memcpy(last_keycodes, report+2, 6);
-
-  // continue to request to receive report
-  if ( !tuh_hid_receive_report(dev_addr, instance) )
-  {
-    printf("Error: cannot request to receive report\r\n");
-  }
+  prev_report = *report;
 }
 
+// send mouse report to usb device CDC
+static void process_mouse_report(uint8_t dev_addr, hid_mouse_report_t const * report)
+{
+  //------------- button state  -------------//
+  //uint8_t button_changed_mask = report->buttons ^ prev_report.buttons;
+  char l = report->buttons & MOUSE_BUTTON_LEFT   ? 'L' : '-';
+  char m = report->buttons & MOUSE_BUTTON_MIDDLE ? 'M' : '-';
+  char r = report->buttons & MOUSE_BUTTON_RIGHT  ? 'R' : '-';
 
+  char tempbuf[32];
+  int count = sprintf(tempbuf, "[%u] %c%c%c %d %d %d\r\n", dev_addr, l, m, r, report->x, report->y, report->wheel);
 
-//--------------------------------------------------------------------+
-// USB CDC
-//--------------------------------------------------------------------+
-void cdc_task(void)
-{
-  // connected() check for DTR bit
-  // Most but not all terminal client set this when making connection
-  // if ( tud_cdc_connected() )
-  {
-    // connected and there are data available
-    if ( tud_cdc_available() )
-    {
-      // read datas
-      char buf[64];
-      uint32_t count = tud_cdc_read(buf, sizeof(buf));
-      (void) count;
-
-      // Echo back
-      // Note: Skip echo by commenting out write() and write_flush()
-      // for throughput test e.g
-      //    $ dd if=/dev/zero of=/dev/ttyACM0 count=10000
-      tud_cdc_write(buf, count);
-      tud_cdc_write_flush();
-    }
-  }
+  tud_cdc_write(tempbuf, count);
+  tud_cdc_write_flush();
 }
 
-// Invoked when cdc when line state changed e.g connected/disconnected
-void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts)
+// Invoked when received report from device via interrupt endpoint
+void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* report, uint16_t len)
 {
-  (void) itf;
-  (void) rts;
+  (void) len;
+  uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance);
 
-  // TODO set some indicator
-  if ( dtr )
+  switch(itf_protocol)
   {
-    // Terminal connected
-  }else
-  {
-    // Terminal disconnected
+    case HID_ITF_PROTOCOL_KEYBOARD:
+      process_kbd_report(dev_addr, (hid_keyboard_report_t const*) report );
+    break;
+
+    case HID_ITF_PROTOCOL_MOUSE:
+      process_mouse_report(dev_addr, (hid_mouse_report_t const*) report );
+    break;
+
+    default: break;
   }
-}
 
-// Invoked when CDC interface received data from host
-void tud_cdc_rx_cb(uint8_t itf)
-{
-  (void) itf;
+  // continue to request to receive report
+  if ( !tuh_hid_receive_report(dev_addr, instance) )
+  {
+    tud_cdc_write_str("Error: cannot request report\r\n");
+  }
 }
 
 //--------------------------------------------------------------------+
-// BLINKING TASK
+// Blinking Task
 //--------------------------------------------------------------------+
 void led_blinking_task(void)
 {

+ 3 - 9
examples/host/hid_to_cdc/src/tusb_config.h → examples/dual/host_hid_to_device_cdc/src/tusb_config.h

@@ -49,6 +49,9 @@
   #define BOARD_HOST_RHPORT_NUM     1
 #endif
 
+// Use raspberry pio-usb for host
+#define CFG_TUH_RPI_PIO_USB            1
+
 // RHPort max operational speed can defined by board.mk
 // Default to Highspeed for MCU with internal HighSpeed PHY (can be port specific), otherwise FullSpeed
 #ifndef BOARD_DEVICE_RHPORT_SPEED
@@ -124,10 +127,6 @@
 
 //------------- CLASS -------------//
 #define CFG_TUD_CDC              1
-#define CFG_TUD_MSC              0
-#define CFG_TUD_HID              0
-#define CFG_TUD_MIDI             0
-#define CFG_TUD_VENDOR           0
 
 // CDC FIFO size of TX and RX
 #define CFG_TUD_CDC_RX_BUFSIZE   (TUD_OPT_HIGH_SPEED ? 512 : 64)
@@ -144,14 +143,9 @@
 #define CFG_TUH_ENUMERATION_BUFSIZE 256
 
 #define CFG_TUH_HUB                 1
-#define CFG_TUH_CDC                 0
-#define CFG_TUH_MSC                 0
-#define CFG_TUH_VENDOR              0
-
 // max device support (excluding hub device)
 #define CFG_TUH_DEVICE_MAX          (CFG_TUH_HUB ? 4 : 1) // hub typically has 4 ports
 
-//------------- HID -------------//
 #define CFG_TUH_HID                  4
 #define CFG_TUH_HID_EPIN_BUFSIZE    64
 #define CFG_TUH_HID_EPOUT_BUFSIZE   64

+ 0 - 1
examples/host/hid_to_cdc/src/usb_descriptors.c → examples/dual/host_hid_to_device_cdc/src/usb_descriptors.c

@@ -81,7 +81,6 @@ enum
 {
   ITF_NUM_CDC = 0,
   ITF_NUM_CDC_DATA,
-  ITF_NUM_MSC,
   ITF_NUM_TOTAL
 };
 

+ 4 - 1
examples/host/bare_api/CMakeLists.txt

@@ -24,4 +24,7 @@ target_include_directories(${PROJECT} PUBLIC
 
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
-family_configure_host_example(${PROJECT})
+family_configure_host_example(${PROJECT})
+
+# For rp2040, un-comment to enable pico-pio-usb
+# family_add_pico_pio_usb(${PROJECT})

+ 4 - 1
examples/host/cdc_msc_hid/CMakeLists.txt

@@ -26,4 +26,7 @@ target_include_directories(${PROJECT} PUBLIC
 
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
-family_configure_host_example(${PROJECT})
+family_configure_host_example(${PROJECT})
+
+# For rp2040, un-comment to enable pico-pio-usb
+# family_add_pico_pio_usb(${PROJECT})

+ 7 - 0
examples/host/cdc_msc_hid/src/tusb_config.h

@@ -39,8 +39,15 @@
   #error CFG_TUSB_MCU must be defined
 #endif
 
+// Use raspberry pio-usb for host
+// #define CFG_TUH_RPI_PIO_USB            1
+// #define CFG_TUH_RPI_PIO_USB            1
+
 #if CFG_TUSB_MCU == OPT_MCU_LPC43XX || CFG_TUSB_MCU == OPT_MCU_LPC18XX || CFG_TUSB_MCU == OPT_MCU_MIMXRT10XX
   #define CFG_TUSB_RHPORT0_MODE       (OPT_MODE_HOST | OPT_MODE_HIGH_SPEED)
+#elif defined(CFG_TUH_RPI_PIO_USB) && CFG_TUH_RPI_PIO_USB
+  // rp2040: port0 is native, port 1 for PIO-USB
+  #define CFG_TUSB_RHPORT1_MODE       OPT_MODE_HOST
 #else
   #define CFG_TUSB_RHPORT0_MODE       OPT_MODE_HOST
 #endif

+ 4 - 1
examples/host/hid_controller/CMakeLists.txt

@@ -25,4 +25,7 @@ target_include_directories(${PROJECT} PUBLIC
 
 # Configure compilation flags and libraries for the example... see the corresponding function
 # in hw/bsp/FAMILY/family.cmake for details.
-family_configure_host_example(${PROJECT})
+family_configure_host_example(${PROJECT})
+
+# For rp2040, un-comment to enable pico-pio-usb
+# family_add_pico_pio_usb(${PROJECT})

+ 1 - 1
examples/rules.mk

@@ -199,7 +199,7 @@ flash-xfel: $(BUILD)/$(PROJECT)-sunxi.bin
 PYOCD_OPTION ?=
 flash-pyocd: $(BUILD)/$(PROJECT).hex
 	pyocd flash -t $(PYOCD_TARGET) $(PYOCD_OPTION) $<
-	pyocd reset -t $(PYOCD_TARGET)
+	#pyocd reset -t $(PYOCD_TARGET)
 
 # Flash using openocd
 OPENOCD_OPTION ?=

+ 4 - 1
hw/bsp/imxrt/family.c

@@ -51,7 +51,10 @@ void board_init(void)
   SysTick_Config(SystemCoreClock / 1000);
 #elif CFG_TUSB_OS == OPT_OS_FREERTOS
   // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher )
-//  NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
+  NVIC_SetPriority(USB_OTG1_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
+#ifdef USB_OTG2_IRQn
+  NVIC_SetPriority(USB_OTG2_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY );
+#endif
 #endif
 
   // LED

+ 5 - 0
hw/bsp/rp2040/family.c

@@ -127,6 +127,11 @@ void board_init(void)
 #ifndef BUTTON_BOOTSEL
 #endif
 
+#if CFG_TUH_RPI_PIO_USB || CFG_TUD_RPI_PIO_USB
+  // Set the system clock to a multiple of 120mhz for bitbanging USB with pico-usb
+  set_sys_clock_khz(120000, true);
+#endif
+
 #if defined(UART_DEV) && defined(LIB_PICO_STDIO_UART)
   bi_decl(bi_2pins_with_func(UART_TX_PIN, UART_TX_PIN, GPIO_FUNC_UART));
   uart_inst = uart_get_instance(UART_DEV);

+ 98 - 39
hw/bsp/rp2040/family.cmake

@@ -23,9 +23,11 @@ if (NOT TARGET _rp2040_family_inclusion_marker)
 		set(PICO_TINYUSB_PATH ${TOP})
 	endif()
 
+	#------------------------------------
 	# Base config for both device and host; wrapped by SDK's tinyusb_common
+	#------------------------------------
 	add_library(tinyusb_common_base INTERFACE)
-	
+
 	target_sources(tinyusb_common_base INTERFACE
 			${TOP}/src/tusb.c
 			${TOP}/src/common/tusb_fifo.c
@@ -48,7 +50,7 @@ if (NOT TARGET _rp2040_family_inclusion_marker)
 	if (CMAKE_BUILD_TYPE STREQUAL "Debug")
 		message("Compiling TinyUSB with CFG_TUSB_DEBUG=1")
 		set(TINYUSB_DEBUG_LEVEL 1)
-	endif ()
+	endif()
 	
 	target_compile_definitions(tinyusb_common_base INTERFACE
 			CFG_TUSB_MCU=OPT_MCU_RP2040
@@ -56,7 +58,9 @@ if (NOT TARGET _rp2040_family_inclusion_marker)
 			CFG_TUSB_DEBUG=${TINYUSB_DEBUG_LEVEL}
 	)
 
+	#------------------------------------
 	# Base config for device mode; wrapped by SDK's tinyusb_device
+	#------------------------------------
 	add_library(tinyusb_device_base INTERFACE)
 	target_sources(tinyusb_device_base INTERFACE
 			${TOP}/src/portable/raspberrypi/rp2040/dcd_rp2040.c
@@ -77,7 +81,9 @@ if (NOT TARGET _rp2040_family_inclusion_marker)
 			${TOP}/src/class/video/video_device.c
 			)
 
+	#------------------------------------
 	# Base config for host mode; wrapped by SDK's tinyusb_host
+	#------------------------------------
 	add_library(tinyusb_host_base INTERFACE)
 	target_sources(tinyusb_host_base INTERFACE
 			${TOP}/src/portable/raspberrypi/rp2040/hcd_rp2040.c
@@ -90,18 +96,20 @@ if (NOT TARGET _rp2040_family_inclusion_marker)
 			${TOP}/src/class/vendor/vendor_host.c
 			)
 
-	# Sometimes have to do host specific actions in mostly
-	# common functions
+	# Sometimes have to do host specific actions in mostly common functions
 	target_compile_definitions(tinyusb_host_base INTERFACE
 			RP2040_USB_HOST_MODE=1
 	)
 
+	#------------------------------------
+	# BSP & Additions
+	#------------------------------------
 	add_library(tinyusb_bsp INTERFACE)
 	target_sources(tinyusb_bsp INTERFACE
 			${TOP}/hw/bsp/rp2040/family.c
 			)
-#	target_include_directories(tinyusb_bsp INTERFACE
-#			${TOP}/hw/bsp/rp2040)
+	#	target_include_directories(tinyusb_bsp INTERFACE
+	#			${TOP}/hw/bsp/rp2040)
 
 	# tinyusb_additions will hold our extra settings for examples
 	add_library(tinyusb_additions INTERFACE)
@@ -111,24 +119,28 @@ if (NOT TARGET _rp2040_family_inclusion_marker)
 	)
 
 	if(DEFINED LOG)
-	  target_compile_definitions(tinyusb_additions INTERFACE CFG_TUSB_DEBUG=${LOG} )
+		target_compile_definitions(tinyusb_additions INTERFACE CFG_TUSB_DEBUG=${LOG})
 	endif()
 
 	if(LOGGER STREQUAL "rtt")
-	  target_compile_definitions(tinyusb_additions INTERFACE
-		LOGGER_RTT
-		SEGGER_RTT_MODE_DEFAULT=SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL
-	  )
-
-	  target_sources(tinyusb_additions INTERFACE
-		${TOP}/lib/SEGGER_RTT/RTT/SEGGER_RTT.c
-	  )
-
-	  target_include_directories(tinyusb_additions INTERFACE
-		${TOP}/lib/SEGGER_RTT/RTT
-	  )
+		target_compile_definitions(tinyusb_additions INTERFACE
+				LOGGER_RTT
+				SEGGER_RTT_MODE_DEFAULT=SEGGER_RTT_MODE_BLOCK_IF_FIFO_FULL
+		)
+
+		target_sources(tinyusb_additions INTERFACE
+				${TOP}/lib/SEGGER_RTT/RTT/SEGGER_RTT.c
+		)
+
+		target_include_directories(tinyusb_additions INTERFACE
+				${TOP}/lib/SEGGER_RTT/RTT
+		)
 	endif()
 
+	#------------------------------------
+	# Functions
+	#------------------------------------
+
 	function(family_configure_target TARGET)
 		pico_add_extra_outputs(${TARGET})
 		pico_enable_stdio_uart(${TARGET} 1)
@@ -145,34 +157,81 @@ if (NOT TARGET _rp2040_family_inclusion_marker)
 		target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_host)
 	endfunction()
 
+	function(family_add_pico_pio_usb TARGET)
+		target_link_libraries(${TARGET} PUBLIC tinyusb_pico_pio_usb)
+	endfunction()
+
+	function(family_configure_dual_usb_example TARGET)
+		family_configure_target(${TARGET})
+		# require tinyusb_pico_pio_usb
+		target_link_libraries(${TARGET} PUBLIC pico_stdlib tinyusb_device tinyusb_host tinyusb_pico_pio_usb )
+	endfunction()
+
+	function(check_and_add_pico_pio_usb_support)
+		# check for pico_generate_pio_header (as depending on environment we may be called before SDK is
+		# initialized in which case it isn't available yet), and only do the initialization once
+		if (COMMAND pico_generate_pio_header AND NOT TARGET tinyusb_pico_pio_usb)
+			#------------------------------------
+			# PIO USB for both host and device
+			#------------------------------------
+
+			if (NOT DEFINED PICO_PIO_USB_PATH)
+				set(PICO_PIO_USB_PATH "${TOP}/hw/mcu/raspberry_pi/Pico-PIO-USB")
+			endif()
+
+			if (EXISTS ${PICO_PIO_USB_PATH}/src/pio_usb.c)
+				add_library(tinyusb_pico_pio_usb INTERFACE)
+				target_sources(tinyusb_device_base INTERFACE
+						${TOP}/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c
+						)
+				target_sources(tinyusb_host_base INTERFACE
+						${TOP}/src/portable/raspberrypi/pio_usb/hcd_pio_usb.c
+						)
+
+				target_sources(tinyusb_pico_pio_usb INTERFACE
+						${PICO_PIO_USB_PATH}/src/pio_usb.c
+						${PICO_PIO_USB_PATH}/src/pio_usb_host.c
+						${PICO_PIO_USB_PATH}/src/pio_usb_device.c
+						${PICO_PIO_USB_PATH}/src/usb_crc.c
+						)
+
+				target_include_directories(tinyusb_pico_pio_usb INTERFACE
+						${PICO_PIO_USB_PATH}/src
+						)
+
+				target_link_libraries(tinyusb_pico_pio_usb INTERFACE
+						hardware_dma
+						hardware_pio
+						pico_multicore
+						)
+
+				target_compile_definitions(tinyusb_pico_pio_usb INTERFACE
+						PIO_USB_USE_TINYUSB
+						)
+
+				pico_generate_pio_header(tinyusb_pico_pio_usb ${PICO_PIO_USB_PATH}/src/usb_tx.pio)
+				pico_generate_pio_header(tinyusb_pico_pio_usb ${PICO_PIO_USB_PATH}/src/usb_rx.pio)
+			endif()
+		endif()
+	endfunction()
+
+	# Try to add Pico-PIO_USB support now for the case where this file is included directly
+	# after Pico SDK initialization, but without using the family_ functions (as is the case
+	# when included by the SDK itself)
+	check_and_add_pico_pio_usb_support()
+
 	function(family_initialize_project PROJECT DIR)
 		# call the original version of this function from family_common.cmake
 		_family_initialize_project(${PROJECT} ${DIR})
 		enable_language(C CXX ASM)
 		pico_sdk_init()
+
+		# now re-check for adding Pico-PIO_USB support now SDK is definitely available
+		check_and_add_pico_pio_usb_support()
 	endfunction()
 
 	# This method must be called from the project scope to suppress known warnings in TinyUSB source files
 	function(suppress_tinyusb_warnings)
-		set_source_files_properties(
-				${PICO_TINYUSB_PATH}/src/tusb.c
-				PROPERTIES
-				COMPILE_FLAGS "-Wno-conversion")
-		set_source_files_properties(
-				${PICO_TINYUSB_PATH}/src/common/tusb_fifo.c
-				PROPERTIES
-				COMPILE_FLAGS "-Wno-conversion -Wno-cast-qual")
-		set_source_files_properties(
-				${PICO_TINYUSB_PATH}/src/device/usbd.c
-				PROPERTIES
-				COMPILE_FLAGS "-Wno-conversion -Wno-cast-qual -Wno-null-dereference")
-		set_source_files_properties(
-				${PICO_TINYUSB_PATH}/src/device/usbd_control.c
-				PROPERTIES
-				COMPILE_FLAGS "-Wno-conversion")
-		set_source_files_properties(
-				${PICO_TINYUSB_PATH}/src/class/cdc/cdc_device.c
-				PROPERTIES
-				COMPILE_FLAGS "-Wno-conversion")
+		# there are currently no warnings to suppress, however this function must still exist
 	endfunction()
 endif()

+ 220 - 45
src/class/audio/audio_device.c

@@ -305,9 +305,35 @@ typedef struct
 #endif
 
 #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
-  uint32_t fb_val;                                                              // Feedback value for asynchronous mode (in 16.16 format).
-#endif
+  struct {
+    uint32_t value;       // Feedback value for asynchronous mode (in 16.16 format).
+    uint32_t min_value;   // min value according to UAC2 FMT-2.0 section 2.3.1.1.
+    uint32_t max_value;   // max value according to UAC2 FMT-2.0 section 2.3.1.1.
+
+    uint8_t frame_shift;  // bInterval-1 in unit of frame (FS), micro-frame (HS)
+    uint8_t compute_method;
+
+    union {
+      uint8_t power_of_2; // pre-computed power of 2 shift
+      float float_const;  // pre-computed float constant
+
+      struct {
+        uint32_t sample_freq;
+        uint32_t mclk_freq;
+      }fixed;
+
+#if 0 // implement later
+      struct {
+        uint32_t nominal_value;
+        uint32_t threshold_bytes;
+      }fifo_count;
 #endif
+    }compute;
+
+  } feedback;
+#endif // CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
+
+#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT
 
 #if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_ENCODING
   tu_fifo_t ep_in_ff;
@@ -1039,7 +1065,7 @@ static uint16_t audiod_encode_type_I_pcm(uint8_t rhport, audiod_function_t* audi
 #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
 static inline bool audiod_fb_send(uint8_t rhport, audiod_function_t *audio)
 {
-  return usbd_edpt_xfer(rhport, audio->ep_fb, (uint8_t *) &audio->fb_val, 4);
+  return usbd_edpt_xfer(rhport, audio->ep_fb, (uint8_t *) &audio->feedback.value, 4);
 }
 #endif
 
@@ -1510,7 +1536,7 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
       tu_fifo_clear(&audio->tx_supp_ff[cnt]);
     }
 #endif
-    
+
     // Invoke callback - can be used to stop data sampling
     if (tud_audio_set_itf_close_EP_cb) TU_VERIFY(tud_audio_set_itf_close_EP_cb(rhport, p_request));
 
@@ -1543,7 +1569,8 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
     // Close corresponding feedback EP
 #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
     usbd_edpt_close(rhport, audio->ep_fb);
-    audio->ep_fb = 0;                           // Necessary?
+    audio->ep_fb = 0;
+    tu_memclr(&audio->feedback, sizeof(audio->feedback));
 #endif
   }
 #endif
@@ -1602,8 +1629,6 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
 #endif
 
 #endif
-            // Invoke callback - can be used to trigger data sampling if not already running
-            if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request));
 
             // Schedule first transmit if alternate interface is not zero i.e. streaming is disabled - in case no sample data is available a ZLP is loaded
             // It is necessary to trigger this here since the refill is done with an RX FIFO empty interrupt which can only trigger if something was in there
@@ -1635,16 +1660,6 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
 #endif
 #endif
 
-#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
-            // In case of asynchronous EP, call Cb after ep_fb is set
-            if ( !(desc_ep->bmAttributes.sync == 0x01 && audio->ep_fb == 0) )
-            {
-              if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request));
-            }
-#else
-            // Invoke callback
-            if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request));
-#endif
             // Prepare for incoming data
 #if USE_LINEAR_BUFFER_RX
             TU_VERIFY(usbd_edpt_xfer(rhport, audio->ep_out, audio->lin_buf_out, audio->ep_out_sz), false);
@@ -1657,12 +1672,10 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
           if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN && desc_ep->bmAttributes.usage == 1)   // Check if usage is explicit data feedback
           {
             audio->ep_fb = ep_addr;
+            audio->feedback.frame_shift = desc_ep->bInterval -1;
 
-            // Invoke callback after ep_out is set
-            if (audio->ep_out != 0)
-            {
-              if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request));
-            }
+            // Enable SOF interrupt if callback is implemented
+            if (tud_audio_feedback_interval_isr) usbd_sof_enable(rhport, true);
           }
 #endif
 #endif // CFG_TUD_AUDIO_ENABLE_EP_OUT
@@ -1674,6 +1687,49 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
 
       TU_VERIFY(foundEPs == nEps);
 
+      // Invoke one callback for a final set interface
+      if (tud_audio_set_itf_cb) TU_VERIFY(tud_audio_set_itf_cb(rhport, p_request));
+
+#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
+      // Prepare feedback computation if callback is available
+      if (tud_audio_feedback_params_cb)
+      {
+        audio_feedback_params_t fb_param;
+
+        tud_audio_feedback_params_cb(func_id, alt, &fb_param);
+        audio->feedback.compute_method = fb_param.method;
+
+        // Minimal/Maximum value in 16.16 format for full speed (1ms per frame) or high speed (125 us per frame)
+        uint32_t const frame_div  = (TUSB_SPEED_FULL == tud_speed_get()) ? 1000 : 8000;
+        audio->feedback.min_value = (fb_param.sample_freq/frame_div - 1) << 16;
+        audio->feedback.max_value = (fb_param.sample_freq/frame_div + 1) << 16;
+
+        switch(fb_param.method)
+        {
+          case AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED:
+          case AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT:
+          case AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2:
+            set_fb_params_freq(audio, fb_param.sample_freq, fb_param.frequency.mclk_freq);
+          break;
+
+          #if 0 // implement later
+          case AUDIO_FEEDBACK_METHOD_FIFO_COUNT:
+          {
+            uint64_t fb64 = ((uint64_t) fb_param.sample_freq) << 16;
+            audio->feedback.compute.fifo_count.nominal_value = (uint32_t) (fb64 / frame_div);
+            audio->feedback.compute.fifo_count.threshold_bytes = fb_param.fifo_count.threshold_bytes;
+
+            tud_audio_fb_set(audio->feedback.compute.fifo_count.nominal_value);
+          }
+          break;
+          #endif
+
+          // nothing to do
+          default: break;
+        }
+      }
+#endif
+
       // We are done - abort loop
       break;
     }
@@ -1682,6 +1738,20 @@ static bool audiod_set_interface(uint8_t rhport, tusb_control_request_t const *
     p_desc = tu_desc_next(p_desc);
   }
 
+#if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
+  // Disable SOF interrupt if no driver has any enabled feedback EP
+  bool disable = true;
+  for(uint8_t i=0; i < CFG_TUD_AUDIO; i++)
+  {
+    if (_audiod_fct[i].ep_fb != 0)
+    {
+      disable = false;
+      break;
+    }
+  }
+  if (disable) usbd_sof_enable(rhport, false);
+#endif
+
   tud_control_status(rhport, p_request);
 
   return true;
@@ -1898,14 +1968,14 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3
   (void) xferred_bytes;
 
   // Search for interface belonging to given end point address and proceed as required
-  uint8_t func_id;
-  for (func_id = 0; func_id < CFG_TUD_AUDIO; func_id++)
+  for (uint8_t func_id = 0; func_id < CFG_TUD_AUDIO; func_id++)
   {
+    audiod_function_t* audio = &_audiod_fct[func_id];
 
 #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
 
     // Data transmission of control interrupt finished
-    if (_audiod_fct[func_id].ep_int_ctr == ep_addr)
+    if (audio->ep_int_ctr == ep_addr)
     {
       // According to USB2 specification, maximum payload of interrupt EP is 8 bytes on low speed, 64 bytes on full speed, and 1024 bytes on high speed (but only if an alternate interface other than 0 is used - see specification p. 49)
       // In case there is nothing to send we have to return a NAK - this is taken care of by PHY ???
@@ -1922,7 +1992,7 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3
 #if CFG_TUD_AUDIO_ENABLE_EP_IN
 
     // Data transmission of audio packet finished
-    if (_audiod_fct[func_id].ep_in == ep_addr && _audiod_fct[func_id].alt_setting != 0)
+    if (audio->ep_in == ep_addr && audio->alt_setting != 0)
     {
       // USB 2.0, section 5.6.4, third paragraph, states "An isochronous endpoint must specify its required bus access period. However, an isochronous endpoint must be prepared to handle poll rates faster than the one specified."
       // That paragraph goes on to say "An isochronous IN endpoint must return a zero-length packet whenever data is requested at a faster interval than the specified interval and data is not available."
@@ -1933,7 +2003,7 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3
       // This is the only place where we can fill something into the EPs buffer!
 
       // Load new data
-      TU_VERIFY(audiod_tx_done_cb(rhport, &_audiod_fct[func_id]));
+      TU_VERIFY(audiod_tx_done_cb(rhport, audio));
 
       // Transmission of ZLP is done by audiod_tx_done_cb()
       return true;
@@ -1943,24 +2013,24 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3
 #if CFG_TUD_AUDIO_ENABLE_EP_OUT
 
     // New audio packet received
-    if (_audiod_fct[func_id].ep_out == ep_addr)
+    if (audio->ep_out == ep_addr)
     {
-      TU_VERIFY(audiod_rx_done_cb(rhport, &_audiod_fct[func_id], (uint16_t) xferred_bytes));
+      TU_VERIFY(audiod_rx_done_cb(rhport, audio, (uint16_t) xferred_bytes));
       return true;
     }
 
 
 #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
     // Transmission of feedback EP finished
-    if (_audiod_fct[func_id].ep_fb == ep_addr)
+    if (audio->ep_fb == ep_addr)
     {
-      if (tud_audio_fb_done_cb) TU_VERIFY(tud_audio_fb_done_cb(rhport));
+      if (tud_audio_fb_done_cb) tud_audio_fb_done_cb(func_id);
 
       // Schedule a transmit with the new value if EP is not busy 
-      if (!usbd_edpt_busy(rhport, _audiod_fct[func_id].ep_fb))
+      if (!usbd_edpt_busy(rhport, audio->ep_fb))
       {
         // Schedule next transmission - value is changed bytud_audio_n_fb_set() in the meantime or the old value gets sent
-        return audiod_fb_send(rhport, &_audiod_fct[func_id]);
+        return audiod_fb_send(rhport, audio);
       }
     }
 #endif
@@ -1970,6 +2040,111 @@ bool audiod_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3
   return false;
 }
 
+#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
+
+static bool set_fb_params_freq(audiod_function_t* audio, uint32_t sample_freq, uint32_t mclk_freq)
+{
+  // Check if frame interval is within sane limits
+  // The interval value n_frames was taken from the descriptors within audiod_set_interface()
+
+  // n_frames_min is ceil(2^10 * f_s / f_m) for full speed and ceil(2^13 * f_s / f_m) for high speed
+  // this lower limit ensures the measures feedback value has sufficient precision
+  uint32_t const k = (TUSB_SPEED_FULL == tud_speed_get()) ? 10 : 13;
+  uint32_t const n_frame = (1UL << audio->feedback.frame_shift);
+
+  if ( (((1UL << k) * sample_freq / mclk_freq) + 1) > n_frame )
+  {
+    TU_LOG1("  UAC2 feedback interval too small\r\n"); TU_BREAKPOINT(); return false;
+  }
+
+  // Check if parameters really allow for a power of two division
+  if ((mclk_freq % sample_freq) == 0 && tu_is_power_of_two(mclk_freq / sample_freq))
+  {
+    audio->feedback.compute_method     = AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2;
+    audio->feedback.compute.power_of_2 = 16 - audio->feedback.frame_shift - tu_log2(mclk_freq / sample_freq);
+  }
+  else if ( audio->feedback.compute_method == AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT)
+  {
+    audio->feedback.compute.float_const = (float)sample_freq / mclk_freq * (1UL << (16 - audio->feedback.frame_shift));
+  }
+  else
+  {
+    audio->feedback.compute.fixed.sample_freq = sample_freq;
+    audio->feedback.compute.fixed.mclk_freq = mclk_freq;
+  }
+
+  return true;
+}
+
+uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles)
+{
+  audiod_function_t* audio = &_audiod_fct[func_id];
+  uint32_t feedback;
+
+  switch (audio->feedback.compute_method)
+  {
+    case AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2:
+      feedback = (cycles << audio->feedback.compute.power_of_2);
+    break;
+
+    case AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT:
+      feedback = (uint32_t) ((float) cycles * audio->feedback.compute.float_const);
+    break;
+
+    case AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED:
+    {
+      uint64_t fb64 = (((uint64_t) cycles) * audio->feedback.compute.fixed.sample_freq) << (16 - audio->feedback.frame_shift);
+      feedback = (uint32_t) (fb64 / audio->feedback.compute.fixed.mclk_freq);
+    }
+    break;
+
+    default: return 0;
+  }
+
+  // For Windows: https://docs.microsoft.com/en-us/windows-hardware/drivers/audio/usb-2-0-audio-drivers
+  // The size of isochronous packets created by the device must be within the limits specified in FMT-2.0 section 2.3.1.1.
+  // This means that the deviation of actual packet size from nominal size must not exceed +/- one audio slot
+  // (audio slot = channel count samples).
+  if ( feedback > audio->feedback.max_value ) feedback = audio->feedback.max_value;
+  if ( feedback < audio->feedback.min_value ) feedback = audio->feedback.min_value;
+
+  tud_audio_n_fb_set(func_id, feedback);
+
+  return feedback;
+}
+#endif
+
+void audiod_sof_isr (uint8_t rhport, uint32_t frame_count)
+{
+  (void) rhport;
+  (void) frame_count;
+
+#if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
+  // Determine feedback value - The feedback method is described in 5.12.4.2 of the USB 2.0 spec
+  // Boiled down, the feedback value Ff = n_samples / (micro)frame.
+  // Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_m) frames need to be measured, where K = 10 for full speed and K = 13 for high speed, f_s is the sampling frequency e.g. 48 kHz and f_m is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is available and locked to f_s)
+  // The update interval in the (4.10.2.1) Feedback Endpoint Descriptor must be less or equal to 2^(K - P), where P = min( ceil(log2(f_m / f_s)), K)
+  // feedback = n_cycles / n_frames * f_s / f_m in 16.16 format, where n_cycles are the number of main clock cycles within fb_n_frames
+
+  // Iterate over audio functions and set feedback value
+  for(uint8_t i=0; i < CFG_TUD_AUDIO; i++)
+  {
+    audiod_function_t* audio = &_audiod_fct[i];
+
+    if (audio->ep_fb != 0)
+    {
+      // HS shift need to be adjusted since SOF event is generated for frame only
+      uint8_t const hs_adjust = (TUSB_SPEED_HIGH == tud_speed_get()) ? 3 : 0;
+      uint32_t const interval = 1UL << (audio->feedback.frame_shift - hs_adjust);
+      if ( 0 == (frame_count & (interval-1)) )
+      {
+        if(tud_audio_feedback_interval_isr) tud_audio_feedback_interval_isr(i, frame_count, audio->feedback.frame_shift);
+      }
+    }
+  }
+#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
+}
+
 bool tud_audio_buffer_and_schedule_control_xfer(uint8_t rhport, tusb_control_request_t const * p_request, void* data, uint16_t len)
 {
   // Handles only sending of data not receiving
@@ -2164,6 +2339,16 @@ static bool audiod_verify_ep_exists(uint8_t ep, uint8_t *func_id)
 // Currently, only AS interfaces with an EP (in or out) are supposed to be parsed for!
 static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const * p_desc, uint8_t const * p_desc_end, uint8_t const as_itf)
 {
+#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_EP_OUT
+  if (as_itf != audio->ep_in_as_intf_num && as_itf != audio->ep_out_as_intf_num) return;           // Abort, this interface has no EP, this driver does not support this currently
+#endif
+#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_EP_OUT
+  if (as_itf != audio->ep_in_as_intf_num) return;
+#endif
+#if !CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_EP_OUT
+  if (as_itf != audio->ep_out_as_intf_num) return;
+#endif
+
   p_desc = tu_desc_next(p_desc);    // Exclude standard AS interface descriptor of current alternate interface descriptor
 
   while (p_desc < p_desc_end)
@@ -2174,16 +2359,6 @@ static void audiod_parse_for_AS_params(audiod_function_t* audio, uint8_t const *
     // Look for a Class-Specific AS Interface Descriptor(4.9.2) to verify format type and format and also to get number of physical channels
     if (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE && tu_desc_subtype(p_desc) == AUDIO_CS_AS_INTERFACE_AS_GENERAL)
     {
-#if CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_EP_OUT
-      if (as_itf != audio->ep_in_as_intf_num && as_itf != audio->ep_out_as_intf_num) break;           // Abort loop, this interface has no EP, this driver does not support this currently
-#endif
-#if CFG_TUD_AUDIO_ENABLE_EP_IN && !CFG_TUD_AUDIO_ENABLE_EP_OUT
-      if (as_itf != audio->ep_in_as_intf_num) break;
-#endif
-#if !CFG_TUD_AUDIO_ENABLE_EP_IN && CFG_TUD_AUDIO_ENABLE_EP_OUT
-      if (as_itf != audio->ep_out_as_intf_num) break;
-#endif
-
 #if CFG_TUD_AUDIO_ENABLE_EP_IN
       if (as_itf == audio->ep_in_as_intf_num)
       {
@@ -2255,7 +2430,7 @@ bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback)
 #if CFG_TUD_AUDIO_ENABLE_FEEDBACK_FORMAT_CORRECTION
   if ( TUSB_SPEED_FULL == tud_speed_get() )
   {
-    uint8_t * fb = (uint8_t *) &_audiod_fct[func_id].fb_val;
+    uint8_t * fb = (uint8_t *) &_audiod_fct[func_id].feedback.value;
 
     // For FS format is 10.14
     *(fb++) = (feedback >> 2) & 0xFF;
@@ -2267,7 +2442,7 @@ bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback)
 #else
   {
     // Send value as-is, caller will choose the appropriate format
-    _audiod_fct[func_id].fb_val = feedback;
+    _audiod_fct[func_id].feedback.value = feedback;
   }
 #endif
 

+ 63 - 1
src/class/audio/audio_device.h

@@ -458,7 +458,14 @@ TU_ATTR_WEAK bool tud_audio_rx_done_post_read_cb(uint8_t rhport, uint16_t n_byte
 #endif
 
 #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
-TU_ATTR_WEAK bool tud_audio_fb_done_cb(uint8_t rhport);
+TU_ATTR_WEAK void tud_audio_fb_done_cb(uint8_t func_id);
+
+
+// determined by the user itself and set by use of tud_audio_n_fb_set(). The feedback value may be determined e.g. from some fill status of some FIFO buffer. Advantage: No ISR interrupt is enabled, hence the CPU need not to handle an ISR every 1ms or 125us and thus less CPU load, disadvantage: typically a larger FIFO is needed to compensate for jitter (e.g. 8 frames), i.e. a larger delay is introduced.
+
+// Feedback value is calculated within the audio driver by use of SOF interrupt. The driver needs information about the master clock f_m from which the audio sample frequency f_s is derived, f_s itself, and the cycle count of f_m at time of the SOF interrupt (e.g. by use of a hardware counter) - see tud_audio_set_fb_params(). Advantage: Reduced jitter in the feedback value computation, hence, the receive FIFO can be smaller (e.g. 2 frames) and thus a smaller delay is possible, disadvantage: higher CPU load due to SOF ISR handling every frame i.e. 1ms or 125us. This option is a great starting point to try the SOF ISR option but depending on your hardware setup (performance of the CPU) it might not work. If so, figure out why and use the next option. (The most critical point is the reading of the cycle counter value of f_m. It is read from within the SOF ISR - see: audiod_sof() -, hence, the ISR must has a high priority such that no software dependent "random" delay i.e. jitter is introduced).
+
+// Feedback value is determined by the user by use of SOF interrupt. The user may use tud_audio_sof_isr() which is called every SOF (of course only invoked when an alternate interface other than zero was set). The number of frames used to determine the feedback value for the currently active alternate setting can be get by tud_audio_get_fb_n_frames(). The feedback value must be set by use of tud_audio_n_fb_set().
 
 // This function is used to provide data rate feedback from an asynchronous sink. Feedback value will be sent at FB endpoint interval till it's changed.
 //
@@ -468,9 +475,61 @@ TU_ATTR_WEAK bool tud_audio_fb_done_cb(uint8_t rhport);
 //
 // Note that due to a bug in its USB Audio 2.0 driver, Windows currently requires 16.16 format for _all_ USB 2.0 devices. On Linux and macOS it seems the 
 // driver can work with either format. So a good compromise is to keep format correction disabled and stick to 16.16 format.
+
+// Feedback value can be determined from within the SOF ISR of the audio driver. This should reduce jitter. If the feature is used, the user can not set the feedback value.
+
+// Determine feedback value - The feedback method is described in 5.12.4.2 of the USB 2.0 spec
+// Boiled down, the feedback value Ff = n_samples / (micro)frame.
+// Since an accuracy of less than 1 Sample / second is desired, at least n_frames = ceil(2^K * f_s / f_m) frames need to be measured, where K = 10 for full speed and K = 13 for high speed, f_s is the sampling frequency e.g. 48 kHz and f_m is the cpu clock frequency e.g. 100 MHz (or any other master clock whose clock count is available and locked to f_s)
+// The update interval in the (4.10.2.1) Feedback Endpoint Descriptor must be less or equal to 2^(K - P), where P = min( ceil(log2(f_m / f_s)), K)
+// feedback = n_cycles / n_frames * f_s / f_m in 16.16 format, where n_cycles are the number of main clock cycles within fb_n_frames
+
 bool tud_audio_n_fb_set(uint8_t func_id, uint32_t feedback);
 static inline bool tud_audio_fb_set(uint32_t feedback);
+
+// Update feedback value with passed cycles since last time this update function is called.
+// Typically called within tud_audio_sof_isr(). Required tud_audio_feedback_params_cb() is implemented
+// This function will also call tud_audio_feedback_set()
+// return feedback value in 16.16 for reference (0 for error)
+uint32_t tud_audio_feedback_update(uint8_t func_id, uint32_t cycles);
+
+enum {
+  AUDIO_FEEDBACK_METHOD_DISABLED,
+  AUDIO_FEEDBACK_METHOD_FREQUENCY_FIXED,
+  AUDIO_FEEDBACK_METHOD_FREQUENCY_FLOAT,
+  AUDIO_FEEDBACK_METHOD_FREQUENCY_POWER_OF_2,
+
+  // impelemnt later
+  // AUDIO_FEEDBACK_METHOD_FIFO_COUNT
+};
+
+typedef struct {
+  uint8_t method;
+  uint32_t sample_freq;   //  sample frequency in Hz
+
+  union {
+    struct {
+      uint32_t mclk_freq; // Main clock frequency in Hz i.e. master clock to which sample clock is based on
+    }frequency;
+
+#if 0 // implement later
+    struct {
+      uint32_t threshold_bytes; // minimum number of bytes received to be considered as filled/ready
+    }fifo_count;
 #endif
+  };
+}audio_feedback_params_t;
+
+// Invoked when needed to set feedback parameters
+TU_ATTR_WEAK void tud_audio_feedback_params_cb(uint8_t func_id, uint8_t alt_itf, audio_feedback_params_t* feedback_param);
+
+// Callback in ISR context, invoked periodically according to feedback endpoint bInterval.
+// Could be used to compute and update feedback value
+// frame_number  : current SOF count
+// interval_shift: number of bit shift i.e log2(interval) from Feedback endpoint descriptor
+TU_ATTR_WEAK void tud_audio_feedback_interval_isr(uint8_t func_id, uint32_t frame_number, uint8_t interval_shift);
+
+#endif // CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
 
 #if CFG_TUD_AUDIO_INT_CTR_EPSIZE_IN
 TU_ATTR_WEAK bool tud_audio_int_ctr_done_cb(uint8_t rhport, uint16_t n_bytes_copied);
@@ -612,10 +671,12 @@ static inline uint16_t tud_audio_int_ctr_write(uint8_t const* buffer, uint16_t l
 #endif
 
 #if CFG_TUD_AUDIO_ENABLE_EP_OUT && CFG_TUD_AUDIO_ENABLE_FEEDBACK_EP
+
 static inline bool tud_audio_fb_set(uint32_t feedback)
 {
   return tud_audio_n_fb_set(0, feedback);
 }
+
 #endif
 
 //--------------------------------------------------------------------+
@@ -626,6 +687,7 @@ void     audiod_reset          (uint8_t rhport);
 uint16_t audiod_open           (uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len);
 bool     audiod_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
 bool     audiod_xfer_cb        (uint8_t rhport, uint8_t edpt_addr, xfer_result_t result, uint32_t xferred_bytes);
+void     audiod_sof_isr        (uint8_t rhport, uint32_t frame_count);
 
 #ifdef __cplusplus
 }

+ 1 - 1
src/class/hid/hid_host.c

@@ -329,7 +329,7 @@ bool hidh_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_interface_t const *de
 
   TU_VERIFY(TUSB_CLASS_HID == desc_itf->bInterfaceClass);
 
-  TU_LOG2("HID opening Interface %u (addr = %u)\r\n", desc_itf->bInterfaceNumber, dev_addr);
+  TU_LOG2("[%u] HID opening Interface %u\r\n", dev_addr, desc_itf->bInterfaceNumber);
 
   // len = interface + hid + n*endpoints
   uint16_t const drv_len = sizeof(tusb_desc_interface_t) + sizeof(tusb_hid_descriptor_hid_t) + desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t);

+ 10 - 6
src/common/tusb_common.h

@@ -134,12 +134,6 @@ TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_offset4k(uint32_t value) { retur
 //------------- Mathematics -------------//
 TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_div_ceil(uint32_t v, uint32_t d) { return (v + d -1)/d; }
 
-/// inclusive range checking TODO remove
-TU_ATTR_ALWAYS_INLINE static inline bool tu_within(uint32_t lower, uint32_t value, uint32_t upper)
-{
-  return (lower <= value) && (value <= upper);
-}
-
 // log2 of a value is its MSB's position
 // TODO use clz TODO remove
 static inline uint8_t tu_log2(uint32_t value)
@@ -149,6 +143,16 @@ static inline uint8_t tu_log2(uint32_t value)
   return result;
 }
 
+//static inline uint8_t tu_log2(uint32_t value)
+//{
+//   return sizeof(uint32_t) * CHAR_BIT - __builtin_clz(x) - 1;
+//}
+
+static inline bool tu_is_power_of_two(uint32_t value)
+{
+   return (value != 0) && ((value & (value - 1)) == 0);
+}
+
 //------------- Unaligned Access -------------//
 #if TUP_ARCH_STRICT_ALIGN
 

+ 6 - 2
src/common/tusb_debug.h

@@ -57,7 +57,7 @@ void tu_print_mem(void const *buf, uint32_t count, uint8_t indent);
   #define tu_printf    printf
 #endif
 
-static inline void tu_print_var(uint8_t const* buf, uint32_t bufsize)
+static inline void tu_print_arr(uint8_t const* buf, uint32_t bufsize)
 {
   for(uint32_t i=0; i<bufsize; i++) tu_printf("%02X ", buf[i]);
 }
@@ -65,6 +65,7 @@ static inline void tu_print_var(uint8_t const* buf, uint32_t bufsize)
 // Log with Level
 #define TU_LOG(n, ...)        TU_XSTRCAT(TU_LOG, n)(__VA_ARGS__)
 #define TU_LOG_MEM(n, ...)    TU_XSTRCAT3(TU_LOG, n, _MEM)(__VA_ARGS__)
+#define TU_LOG_ARR(n, ...)    TU_XSTRCAT3(TU_LOG, n, _ARR)(__VA_ARGS__)
 #define TU_LOG_VAR(n, ...)    TU_XSTRCAT3(TU_LOG, n, _VAR)(__VA_ARGS__)
 #define TU_LOG_INT(n, ...)    TU_XSTRCAT3(TU_LOG, n, _INT)(__VA_ARGS__)
 #define TU_LOG_HEX(n, ...)    TU_XSTRCAT3(TU_LOG, n, _HEX)(__VA_ARGS__)
@@ -74,7 +75,8 @@ static inline void tu_print_var(uint8_t const* buf, uint32_t bufsize)
 // Log Level 1: Error
 #define TU_LOG1               tu_printf
 #define TU_LOG1_MEM           tu_print_mem
-#define TU_LOG1_VAR(_x)       tu_print_var((uint8_t const*)(_x), sizeof(*(_x)))
+#define TU_LOG1_ARR(_x, _n)   tu_print_arr((uint8_t const*)(_x), _n)
+#define TU_LOG1_VAR(_x)       tu_print_arr((uint8_t const*)(_x), sizeof(*(_x)))
 #define TU_LOG1_INT(_x)       tu_printf(#_x " = %ld\r\n", (unsigned long) (_x) )
 #define TU_LOG1_HEX(_x)       tu_printf(#_x " = %lX\r\n", (unsigned long) (_x) )
 
@@ -82,6 +84,7 @@ static inline void tu_print_var(uint8_t const* buf, uint32_t bufsize)
 #if CFG_TUSB_DEBUG >= 2
   #define TU_LOG2             TU_LOG1
   #define TU_LOG2_MEM         TU_LOG1_MEM
+  #define TU_LOG2_ARR         TU_LOG1_ARR
   #define TU_LOG2_VAR         TU_LOG1_VAR
   #define TU_LOG2_INT         TU_LOG1_INT
   #define TU_LOG2_HEX         TU_LOG1_HEX
@@ -91,6 +94,7 @@ static inline void tu_print_var(uint8_t const* buf, uint32_t bufsize)
 #if CFG_TUSB_DEBUG >= 3
   #define TU_LOG3             TU_LOG1
   #define TU_LOG3_MEM         TU_LOG1_MEM
+  #define TU_LOG3_ARR         TU_LOG1_ARR
   #define TU_LOG3_VAR         TU_LOG1_VAR
   #define TU_LOG3_INT         TU_LOG1_INT
   #define TU_LOG3_HEX         TU_LOG1_HEX

+ 7 - 0
src/common/tusb_mcu.h

@@ -228,6 +228,8 @@
 #elif TU_CHECK_MCU(OPT_MCU_RP2040)
   #define TUP_DCD_ENDPOINT_MAX    16
 
+  #define TU_ATTR_FAST_FUNC   __attribute__((section(".time_critical.tinyusb")))
+
 //------------- Silabs -------------//
 #elif TU_CHECK_MCU(OPT_MCU_EFM32GG)
   #define TUP_USBIP_DWC2
@@ -287,4 +289,9 @@
   #define TUP_RHPORT_HIGHSPEED    0x00
 #endif
 
+// fast function, normally mean placing function in SRAM
+#ifndef TU_ATTR_FAST_FUNC
+  #define TU_ATTR_FAST_FUNC
+#endif
+
 #endif

+ 8 - 9
src/common/tusb_verify.h

@@ -90,6 +90,9 @@
 #elif defined(__riscv)
   #define TU_BREAKPOINT() do { __asm("ebreak\n"); } while(0)
 
+#elif defined(_mips)
+  #define TU_BREAKPOINT() do { __asm("sdbbp 0"); } while (0)
+
 #else
   #define TU_BREAKPOINT() do {} while (0)
 #endif
@@ -99,12 +102,8 @@
  *------------------------------------------------------------------*/
 
 // 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__)
+#define _GET_3RD_ARG(arg1, arg2, arg3, ...)        arg3
+#define _GET_4TH_ARG(arg1, arg2, arg3, arg4, ...)  arg4
 
 /*------------- Generator for TU_VERIFY and TU_VERIFY_HDLR -------------*/
 #define TU_VERIFY_DEFINE(_cond, _handler, _ret)  do            \
@@ -120,7 +119,7 @@
 #define TU_VERIFY_1ARGS(_cond)                         TU_VERIFY_DEFINE(_cond, , false)
 #define TU_VERIFY_2ARGS(_cond, _ret)                   TU_VERIFY_DEFINE(_cond, , _ret)
 
-#define TU_VERIFY(...)                   GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_2ARGS, TU_VERIFY_1ARGS, UNUSED)(__VA_ARGS__)
+#define TU_VERIFY(...)                   _GET_3RD_ARG(__VA_ARGS__, TU_VERIFY_2ARGS, TU_VERIFY_1ARGS, UNUSED)(__VA_ARGS__)
 
 
 /*------------------------------------------------------------------*/
@@ -131,7 +130,7 @@
 #define TU_VERIFY_HDLR_2ARGS(_cond, _handler)           TU_VERIFY_DEFINE(_cond, _handler, false)
 #define TU_VERIFY_HDLR_3ARGS(_cond, _handler, _ret)     TU_VERIFY_DEFINE(_cond, _handler, _ret)
 
-#define TU_VERIFY_HDLR(...)              GET_4TH_ARG(__VA_ARGS__, TU_VERIFY_HDLR_3ARGS, TU_VERIFY_HDLR_2ARGS,UNUSED)(__VA_ARGS__)
+#define TU_VERIFY_HDLR(...)              _GET_4TH_ARG(__VA_ARGS__, TU_VERIFY_HDLR_3ARGS, TU_VERIFY_HDLR_2ARGS,UNUSED)(__VA_ARGS__)
 
 /*------------------------------------------------------------------*/
 /* ASSERT
@@ -143,7 +142,7 @@
 #define ASSERT_2ARGS(_cond, _ret)      TU_VERIFY_DEFINE(_cond, _MESS_FAILED(); TU_BREAKPOINT(), _ret)
 
 #ifndef TU_ASSERT
-#define TU_ASSERT(...)             GET_3RD_ARG(__VA_ARGS__, ASSERT_2ARGS, ASSERT_1ARGS,UNUSED)(__VA_ARGS__)
+#define TU_ASSERT(...)             _GET_3RD_ARG(__VA_ARGS__, ASSERT_2ARGS, ASSERT_1ARGS,UNUSED)(__VA_ARGS__)
 #endif
 
 /*------------------------------------------------------------------*/

+ 43 - 4
src/device/dcd.h

@@ -78,6 +78,11 @@ typedef struct TU_ATTR_ALIGNED(4)
       tusb_speed_t speed;
     } bus_reset;
 
+    // SOF
+    struct {
+      uint32_t frame_count;
+    }sof;
+
     // Plugged
     struct {
       tusb_speed_t speed;
@@ -138,6 +143,9 @@ void dcd_connect(uint8_t rhport) TU_ATTR_WEAK;
 // Disconnect by disabling internal pull-up resistor on D+/D-
 void dcd_disconnect(uint8_t rhport) TU_ATTR_WEAK;
 
+// Enable/Disable Start-of-frame interrupt. Default is disabled
+void dcd_sof_enable(uint8_t rhport, bool en);
+
 //--------------------------------------------------------------------+
 // Endpoint API
 //--------------------------------------------------------------------+
@@ -180,16 +188,47 @@ void dcd_edpt_clear_stall     (uint8_t rhport, uint8_t ep_addr);
 extern void dcd_event_handler(dcd_event_t const * event, bool in_isr);
 
 // helper to send bus signal event
-extern void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr);
+TU_ATTR_ALWAYS_INLINE static inline void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr)
+{
+  dcd_event_t event = { .rhport = rhport, .event_id = eid };
+  dcd_event_handler(&event, in_isr);
+}
 
 // helper to send bus reset event
-extern void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr);
+TU_ATTR_ALWAYS_INLINE static inline  void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr)
+{
+  dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_BUS_RESET };
+  event.bus_reset.speed = speed;
+  dcd_event_handler(&event, in_isr);
+}
 
 // helper to send setup received
-extern void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr);
+TU_ATTR_ALWAYS_INLINE static inline void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr)
+{
+  dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SETUP_RECEIVED };
+  memcpy(&event.setup_received, setup, 8);
+
+  dcd_event_handler(&event, in_isr);
+}
 
 // helper to send transfer complete event
-extern void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr);
+TU_ATTR_ALWAYS_INLINE static inline void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr)
+{
+  dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_XFER_COMPLETE };
+
+  event.xfer_complete.ep_addr = ep_addr;
+  event.xfer_complete.len     = xferred_bytes;
+  event.xfer_complete.result  = result;
+
+  dcd_event_handler(&event, in_isr);
+}
+
+static inline void dcd_event_sof(uint8_t rhport, uint32_t frame_count, bool in_isr)
+{
+  dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SOF };
+  event.sof.frame_count = frame_count;
+  dcd_event_handler(&event, in_isr);
+}
 
 #ifdef __cplusplus
  }

+ 58 - 59
src/device/usbd.c

@@ -69,7 +69,7 @@ typedef struct
   volatile uint8_t cfg_num; // current active configuration (0x00 is not configured)
   uint8_t speed;
 
-  uint8_t itf2drv[16];                      // map interface number to driver (0xff is invalid)
+  uint8_t itf2drv[CFG_TUD_INTERFACE_MAX];   // map interface number to driver (0xff is invalid)
   uint8_t ep2drv[CFG_TUD_ENDPPOINT_MAX][2]; // map endpoint to driver ( 0xff is invalid ), can use only 4-bit each
 
   tu_edpt_state_t ep_status[CFG_TUD_ENDPPOINT_MAX][2];
@@ -98,7 +98,7 @@ static usbd_class_driver_t const _usbd_driver[] =
     .open             = cdcd_open,
     .control_xfer_cb  = cdcd_control_xfer_cb,
     .xfer_cb          = cdcd_xfer_cb,
-    .sof              = NULL
+    .sof_isr          = NULL
   },
   #endif
 
@@ -110,7 +110,7 @@ static usbd_class_driver_t const _usbd_driver[] =
     .open             = mscd_open,
     .control_xfer_cb  = mscd_control_xfer_cb,
     .xfer_cb          = mscd_xfer_cb,
-    .sof              = NULL
+    .sof_isr          = NULL
   },
   #endif
 
@@ -122,7 +122,7 @@ static usbd_class_driver_t const _usbd_driver[] =
     .open             = hidd_open,
     .control_xfer_cb  = hidd_control_xfer_cb,
     .xfer_cb          = hidd_xfer_cb,
-    .sof              = NULL
+    .sof_isr          = NULL
   },
   #endif
 
@@ -134,7 +134,7 @@ static usbd_class_driver_t const _usbd_driver[] =
     .open             = audiod_open,
     .control_xfer_cb  = audiod_control_xfer_cb,
     .xfer_cb          = audiod_xfer_cb,
-    .sof              = NULL
+    .sof_isr          = audiod_sof_isr
   },
   #endif
 
@@ -146,7 +146,7 @@ static usbd_class_driver_t const _usbd_driver[] =
     .open             = videod_open,
     .control_xfer_cb  = videod_control_xfer_cb,
     .xfer_cb          = videod_xfer_cb,
-    .sof              = NULL
+    .sof_isr          = NULL
   },
   #endif
 
@@ -158,7 +158,7 @@ static usbd_class_driver_t const _usbd_driver[] =
     .reset            = midid_reset,
     .control_xfer_cb  = midid_control_xfer_cb,
     .xfer_cb          = midid_xfer_cb,
-    .sof              = NULL
+    .sof_isr          = NULL
   },
   #endif
 
@@ -170,7 +170,7 @@ static usbd_class_driver_t const _usbd_driver[] =
     .open             = vendord_open,
     .control_xfer_cb  = tud_vendor_control_xfer_cb,
     .xfer_cb          = vendord_xfer_cb,
-    .sof              = NULL
+    .sof_isr          = NULL
   },
   #endif
 
@@ -182,7 +182,7 @@ static usbd_class_driver_t const _usbd_driver[] =
     .open             = usbtmcd_open_cb,
     .control_xfer_cb  = usbtmcd_control_xfer_cb,
     .xfer_cb          = usbtmcd_xfer_cb,
-    .sof              = NULL
+    .sof_isr          = NULL
   },
   #endif
 
@@ -194,7 +194,7 @@ static usbd_class_driver_t const _usbd_driver[] =
     .open             = dfu_rtd_open,
     .control_xfer_cb  = dfu_rtd_control_xfer_cb,
     .xfer_cb          = NULL,
-    .sof              = NULL
+    .sof_isr          = NULL
   },
   #endif
 
@@ -206,7 +206,7 @@ static usbd_class_driver_t const _usbd_driver[] =
     .open             = dfu_moded_open,
     .control_xfer_cb  = dfu_moded_control_xfer_cb,
     .xfer_cb          = NULL,
-    .sof              = NULL
+    .sof_isr          = NULL
   },
   #endif
 
@@ -218,7 +218,7 @@ static usbd_class_driver_t const _usbd_driver[] =
     .open             = netd_open,
     .control_xfer_cb  = netd_control_xfer_cb,
     .xfer_cb          = netd_xfer_cb,
-    .sof              = NULL,
+    .sof_isr              = NULL,
   },
   #endif
 
@@ -230,7 +230,7 @@ static usbd_class_driver_t const _usbd_driver[] =
     .open             = btd_open,
     .control_xfer_cb  = btd_control_xfer_cb,
     .xfer_cb          = btd_xfer_cb,
-    .sof              = NULL
+    .sof_isr          = NULL
   },
   #endif
 };
@@ -264,6 +264,8 @@ static inline usbd_class_driver_t const * get_driver(uint8_t drvid)
 // DCD Event
 //--------------------------------------------------------------------+
 
+//static tud_sof_isr_t _sof_isr = NULL;
+
 enum { RHPORT_INVALID = 0xFFu };
 static uint8_t _usbd_rhport = RHPORT_INVALID;
 
@@ -377,6 +379,12 @@ bool tud_connect(void)
   return true;
 }
 
+//void tud_sof_isr_set(tud_sof_isr_t sof_isr)
+//{
+//  _sof_isr = sof_isr;
+//  dcd_sof_enable(_usbd_rhport, _sof_isr != NULL);
+//}
+
 //--------------------------------------------------------------------+
 // USBD Task
 //--------------------------------------------------------------------+
@@ -419,11 +427,13 @@ bool tud_init (uint8_t rhport)
     driver->init();
   }
 
+  _usbd_rhport = rhport;
+  //_sof_isr = NULL;
+
   // Init device controller driver
   dcd_init(rhport);
   dcd_int_enable(rhport);
 
-  _usbd_rhport = rhport;
 
   return true;
 }
@@ -472,8 +482,10 @@ bool tud_task_event_ready(void)
     }
     @endcode
  */
-void tud_task (void)
+void tud_task_ext(uint32_t timeout_ms, bool in_isr)
 {
+  (void) in_isr; // not implemented yet
+
   // Skip if stack is not initialized
   if ( !tusb_inited() ) return;
 
@@ -481,8 +493,7 @@ void tud_task (void)
   while (1)
   {
     dcd_event_t event;
-
-    if ( !osal_queue_receive(_usbd_q, &event) ) return;
+    if ( !osal_queue_receive(_usbd_q, &event, timeout_ms) ) return;
 
 #if CFG_TUSB_DEBUG >= 2
     if (event.event_id == DCD_EVENT_SETUP_RECEIVED) TU_LOG2("\r\n"); // extra line for setup
@@ -586,24 +597,21 @@ void tud_task (void)
         }
       break;
 
-      case DCD_EVENT_SOF:
-        TU_LOG2("\r\n");
-        for ( uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++ )
-        {
-          usbd_class_driver_t const * driver = get_driver(i);
-          if ( driver->sof ) driver->sof(event.rhport);
-        }
-      break;
-
       case USBD_EVENT_FUNC_CALL:
         TU_LOG2("\r\n");
         if ( event.func_call.func ) event.func_call.func(event.func_call.param);
       break;
 
+      case DCD_EVENT_SOF:
       default:
         TU_BREAKPOINT();
       break;
     }
+
+#if CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO
+    // return if there is no more events, for application to run other background
+    if (osal_queue_empty(_usbd_q)) return;
+#endif
   }
 }
 
@@ -1076,7 +1084,7 @@ static bool process_get_descriptor(uint8_t rhport, tusb_control_request_t const
 //--------------------------------------------------------------------+
 // DCD Event Handler
 //--------------------------------------------------------------------+
-void dcd_event_handler(dcd_event_t const * event, bool in_isr)
+TU_ATTR_FAST_FUNC void dcd_event_handler(dcd_event_t const * event, bool in_isr)
 {
   switch (event->event_id)
   {
@@ -1110,14 +1118,30 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr)
     break;
 
     case DCD_EVENT_SOF:
+      // SOF driver handler in ISR context
+      for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++)
+      {
+        usbd_class_driver_t const * driver = get_driver(i);
+        if (driver->sof_isr)
+        {
+          driver->sof_isr(event->rhport, event->sof.frame_count);
+        }
+      }
+
+      // SOF user handler in ISR context
+      // if (_sof_isr) _sof_isr(event->sof.frame_count);
+
       // Some MCUs after running dcd_remote_wakeup() does not have way to detect the end of remote wakeup
       // which last 1-15 ms. DCD can use SOF as a clear indicator that bus is back to operational
       if ( _usbd_dev.suspended )
       {
         _usbd_dev.suspended = 0;
+
         dcd_event_t const event_resume = { .rhport = event->rhport, .event_id = DCD_EVENT_RESUME };
         osal_queue_send(_usbd_q, &event_resume, in_isr);
       }
+
+      // skip osal queue for SOF in usbd task
     break;
 
     default:
@@ -1126,38 +1150,6 @@ void dcd_event_handler(dcd_event_t const * event, bool in_isr)
   }
 }
 
-void dcd_event_bus_signal (uint8_t rhport, dcd_eventid_t eid, bool in_isr)
-{
-  dcd_event_t event = { .rhport = rhport, .event_id = eid };
-  dcd_event_handler(&event, in_isr);
-}
-
-void dcd_event_bus_reset (uint8_t rhport, tusb_speed_t speed, bool in_isr)
-{
-  dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_BUS_RESET };
-  event.bus_reset.speed = speed;
-  dcd_event_handler(&event, in_isr);
-}
-
-void dcd_event_setup_received(uint8_t rhport, uint8_t const * setup, bool in_isr)
-{
-  dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_SETUP_RECEIVED };
-  memcpy(&event.setup_received, setup, 8);
-
-  dcd_event_handler(&event, in_isr);
-}
-
-void dcd_event_xfer_complete (uint8_t rhport, uint8_t ep_addr, uint32_t xferred_bytes, uint8_t result, bool in_isr)
-{
-  dcd_event_t event = { .rhport = rhport, .event_id = DCD_EVENT_XFER_COMPLETE };
-
-  event.xfer_complete.ep_addr = ep_addr;
-  event.xfer_complete.len     = xferred_bytes;
-  event.xfer_complete.result  = result;
-
-  dcd_event_handler(&event, in_isr);
-}
-
 //--------------------------------------------------------------------+
 // USBD API For Class Driver
 //--------------------------------------------------------------------+
@@ -1394,4 +1386,11 @@ void usbd_edpt_close(uint8_t rhport, uint8_t ep_addr)
   return;
 }
 
+void usbd_sof_enable(uint8_t rhport, bool en)
+{
+  // TODO: Check needed if all drivers including the user sof_cb does not need an active SOF ISR any more.
+  // Only if all drivers switched off SOF calls the SOF interrupt may be disabled
+  dcd_sof_enable(rhport, en);
+}
+
 #endif

+ 17 - 2
src/device/usbd.h

@@ -33,6 +33,8 @@
 extern "C" {
 #endif
 
+// typedef void (*tud_sof_isr_t) (uint32_t frame_count);
+
 //--------------------------------------------------------------------+
 // Application API
 //--------------------------------------------------------------------+
@@ -43,10 +45,19 @@ bool tud_init (uint8_t rhport);
 // Check if device stack is already initialized
 bool tud_inited(void);
 
+// Task function should be called in main/rtos loop, extended version of tud_task()
+// - timeout_ms: millisecond to wait, zero = no wait, 0xFFFFFFFF = wait forever
+// - in_isr: if function is called in ISR
+void tud_task_ext(uint32_t timeout_ms, bool in_isr);
+
 // Task function should be called in main/rtos loop
-void tud_task (void);
+TU_ATTR_ALWAYS_INLINE static inline
+void tud_task (void)
+{
+  tud_task_ext(UINT32_MAX, false);
+}
 
-// Check if there is pending events need proccessing by tud_task()
+// Check if there is pending events need processing by tud_task()
 bool tud_task_event_ready(void);
 
 // Interrupt handler, name alias to DCD
@@ -87,6 +98,10 @@ bool tud_disconnect(void);
 // Return false on unsupported MCUs
 bool tud_connect(void);
 
+// Set Start-of-frame (1ms interval) IRQ handler
+// NULL means disabled, frame_count may not be supported on mcus
+// void tud_sof_isr_set(tud_sof_isr_t sof_isr);
+
 // Carry out Data and Status stage of control transfer
 // - If len = 0, it is equivalent to sending status only
 // - If len > wLength : it will be truncated

+ 4 - 1
src/device/usbd_pvt.h

@@ -48,7 +48,7 @@ typedef struct
   uint16_t (* open             ) (uint8_t rhport, tusb_desc_interface_t const * desc_intf, uint16_t max_len);
   bool     (* control_xfer_cb  ) (uint8_t rhport, uint8_t stage, tusb_control_request_t const * request);
   bool     (* xfer_cb          ) (uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes);
-  void     (* sof              ) (uint8_t rhport); /* optional */
+  void     (* sof_isr          ) (uint8_t rhport, uint32_t frame_count); // optional
 } usbd_class_driver_t;
 
 // Invoked when initializing device stack to get additional class drivers.
@@ -102,6 +102,9 @@ bool usbd_edpt_ready(uint8_t rhport, uint8_t ep_addr)
   return !usbd_edpt_busy(rhport, ep_addr) && !usbd_edpt_stalled(rhport, ep_addr);
 }
 
+// Enable SOF interrupt
+void usbd_sof_enable(uint8_t rhport, bool en);
+
 /*------------------------------------------------------------------*/
 /* Helper
  *------------------------------------------------------------------*/

+ 47 - 4
src/host/hcd.h

@@ -144,9 +144,16 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr);
 // Endpoints API
 //--------------------------------------------------------------------+
 
-bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]);
+// Open an endpoint
 bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc);
+
+// Submit a transfer, when complete hcd_event_xfer_complete() must be invoked
 bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen);
+
+// Submit a special transfer to send 8-byte Setup Packet, when complete hcd_event_xfer_complete() must be invoked
+bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]);
+
+// clear stall, data toggle is also reset to DATA0
 bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr);
 
 //--------------------------------------------------------------------+
@@ -164,13 +171,49 @@ extern void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t* devtree_i
 extern void hcd_event_handler(hcd_event_t const* event, bool in_isr);
 
 // Helper to send device attach event
-extern void hcd_event_device_attach(uint8_t rhport, bool in_isr);
+TU_ATTR_ALWAYS_INLINE static inline
+void hcd_event_device_attach(uint8_t rhport, bool in_isr)
+{
+  hcd_event_t event;
+  event.rhport              = rhport;
+  event.event_id            = HCD_EVENT_DEVICE_ATTACH;
+  event.connection.hub_addr = 0;
+  event.connection.hub_port = 0;
+  hcd_event_handler(&event, in_isr);
+}
 
 // Helper to send device removal event
-extern void hcd_event_device_remove(uint8_t rhport, bool in_isr);
+TU_ATTR_ALWAYS_INLINE static inline
+void hcd_event_device_remove(uint8_t rhport, bool in_isr)
+{
+  hcd_event_t event;
+  event.rhport              = rhport;
+  event.event_id            = HCD_EVENT_DEVICE_REMOVE;
+  event.connection.hub_addr = 0;
+  event.connection.hub_port = 0;
+
+  hcd_event_handler(&event, in_isr);
+}
 
 // Helper to send USB transfer event
-extern void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr);
+TU_ATTR_ALWAYS_INLINE static inline
+void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr)
+{
+  hcd_event_t event =
+  {
+    .rhport   = 0, // TODO correct rhport
+    .event_id = HCD_EVENT_XFER_COMPLETE,
+    .dev_addr = dev_addr,
+    .xfer_complete =
+    {
+      .ep_addr = ep_addr,
+      .result  = result,
+      .len     = xferred_bytes
+    }
+  };
+
+  hcd_event_handler(&event, in_isr);
+}
 
 #ifdef __cplusplus
  }

+ 28 - 61
src/host/usbh.c

@@ -392,8 +392,10 @@ bool tuh_init(uint8_t rhport)
     }
     @endcode
  */
-void tuh_task(void)
+void tuh_task_ext(uint32_t timeout_ms, bool in_isr)
 {
+  (void) in_isr; // not implemented yet
+
   // Skip if stack is not initialized
   if ( !tusb_inited() ) return;
 
@@ -401,14 +403,14 @@ void tuh_task(void)
   while (1)
   {
     hcd_event_t event;
-    if ( !osal_queue_receive(_usbh_q, &event) ) return;
+    if ( !osal_queue_receive(_usbh_q, &event, timeout_ms) ) return;
 
     switch (event.event_id)
     {
       case HCD_EVENT_DEVICE_ATTACH:
         // TODO due to the shared _usbh_ctrl_buf, we must complete enumerating
         // one device before enumerating another one.
-        TU_LOG2("USBH DEVICE ATTACH\r\n");
+        TU_LOG2("[%u:] USBH DEVICE ATTACH\r\n", event.rhport);
         enum_new_device(&event);
       break;
 
@@ -497,6 +499,11 @@ void tuh_task(void)
 
       default: break;
     }
+
+#if CFG_TUSB_OS != OPT_OS_NONE && CFG_TUSB_OS != OPT_OS_PICO
+    // return if there is no more events, for application to run other background
+    if (osal_queue_empty(_usbh_q)) return;
+#endif
   }
 }
 
@@ -543,12 +550,12 @@ bool tuh_control_xfer (tuh_xfer_t* xfer)
   const uint8_t rhport = usbh_get_rhport(daddr);
 
   TU_LOG2("[%u:%u] %s: ", rhport, daddr, xfer->setup->bRequest <= TUSB_REQ_SYNCH_FRAME ? tu_str_std_request[xfer->setup->bRequest] : "Unknown Request");
-  TU_LOG2_VAR(&xfer->setup);
+  TU_LOG2_VAR(xfer->setup);
   TU_LOG2("\r\n");
 
   if (xfer->complete_cb)
   {
-    TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t*) &_ctrl_xfer.request) );
+    TU_ASSERT( hcd_setup_send(rhport, daddr, (uint8_t const*) &_ctrl_xfer.request) );
   }else
   {
     // blocking if complete callback is not provided
@@ -623,7 +630,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result
 
   if (XFER_RESULT_SUCCESS != result)
   {
-    TU_LOG2("[%u:%u] Control %s\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED");
+    TU_LOG1("[%u:%u] Control %s\r\n", rhport, dev_addr, result == XFER_RESULT_STALLED ? "STALLED" : "FAILED");
 
     // terminate transfer if any stage failed
     _xfer_complete(dev_addr, result);
@@ -636,12 +643,13 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result
         {
           // DATA stage: initial data toggle is always 1
           _set_control_xfer_stage(CONTROL_STAGE_DATA);
-          return hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength);
+          TU_ASSERT( hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, request->bmRequestType_bit.direction), _ctrl_xfer.buffer, request->wLength) );
+          return true;
         }
         __attribute__((fallthrough));
 
       case CONTROL_STAGE_DATA:
-        if (xferred_bytes)
+        if (request->wLength)
         {
           TU_LOG2("[%u:%u] Control data:\r\n", rhport, dev_addr);
           TU_LOG2_MEM(_ctrl_xfer.buffer, xferred_bytes, 2);
@@ -651,7 +659,7 @@ static bool usbh_control_xfer_cb (uint8_t dev_addr, uint8_t ep_addr, xfer_result
 
         // ACK stage: toggle is always 1
         _set_control_xfer_stage(CONTROL_STAGE_ACK);
-        hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0);
+        TU_ASSERT( hcd_edpt_xfer(rhport, dev_addr, tu_edpt_addr(0, 1-request->bmRequestType_bit.direction), NULL, 0) );
       break;
 
       case CONTROL_STAGE_ACK:
@@ -791,7 +799,7 @@ bool usbh_edpt_xfer_with_callback(uint8_t dev_addr, uint8_t ep_addr, uint8_t * b
 
 static bool usbh_edpt_control_open(uint8_t dev_addr, uint8_t max_packet_size)
 {
-  TU_LOG2("Open EP0 with Size = %u (addr = %u)\r\n", max_packet_size, dev_addr);
+  TU_LOG2("[%u:%u] Open EP0 with Size = %u\r\n", usbh_get_rhport(dev_addr), dev_addr, max_packet_size);
 
   tusb_desc_endpoint_t ep0_desc =
   {
@@ -847,7 +855,7 @@ void hcd_devtree_get_info(uint8_t dev_addr, hcd_devtree_info_t* devtree_info)
   }
 }
 
-void hcd_event_handler(hcd_event_t const* event, bool in_isr)
+TU_ATTR_FAST_FUNC void hcd_event_handler(hcd_event_t const* event, bool in_isr)
 {
   switch (event->event_id)
   {
@@ -857,52 +865,6 @@ void hcd_event_handler(hcd_event_t const* event, bool in_isr)
   }
 }
 
-void hcd_event_xfer_complete(uint8_t dev_addr, uint8_t ep_addr, uint32_t xferred_bytes, xfer_result_t result, bool in_isr)
-{
-  hcd_event_t event =
-  {
-    .rhport   = 0, // TODO correct rhport
-    .event_id = HCD_EVENT_XFER_COMPLETE,
-    .dev_addr = dev_addr,
-    .xfer_complete =
-    {
-      .ep_addr = ep_addr,
-      .result  = result,
-      .len     = xferred_bytes
-    }
-  };
-
-  hcd_event_handler(&event, in_isr);
-}
-
-void hcd_event_device_attach(uint8_t rhport, bool in_isr)
-{
-  hcd_event_t event =
-  {
-    .rhport   = rhport,
-    .event_id = HCD_EVENT_DEVICE_ATTACH
-  };
-
-  event.connection.hub_addr = 0;
-  event.connection.hub_port = 0;
-
-  hcd_event_handler(&event, in_isr);
-}
-
-void hcd_event_device_remove(uint8_t hostid, bool in_isr)
-{
-  hcd_event_t event =
-  {
-    .rhport   = hostid,
-    .event_id = HCD_EVENT_DEVICE_REMOVE
-  };
-
-  event.connection.hub_addr = 0;
-  event.connection.hub_port = 0;
-
-  hcd_event_handler(&event, in_isr);
-}
-
 //--------------------------------------------------------------------+
 // Descriptors Async
 //--------------------------------------------------------------------+
@@ -1177,7 +1139,7 @@ enum {
   //ENUM_HUB_GET_STATUS_1,
   ENUM_HUB_CLEAR_RESET_1,
   ENUM_ADDR0_DEVICE_DESC,
-  ENUM_RESET_2,         // 2nd reset before set address
+  ENUM_RESET_2,         // 2nd reset before set address (not used)
   ENUM_HUB_GET_STATUS_2,
   ENUM_HUB_CLEAR_RESET_2,
   ENUM_SET_ADDR,
@@ -1265,15 +1227,17 @@ static void process_enumeration(tuh_xfer_t* xfer)
     }
     break;
 
+#if 0
     case ENUM_RESET_2:
+      // XXX note used by now, but may be needed for some devices !?
       // Reset device again before Set Address
-      TU_LOG2("Port reset \r\n");
+      TU_LOG2("Port reset2 \r\n");
       if (_dev0.hub_addr == 0)
       {
         // connected directly to roothub
         hcd_port_reset( _dev0.rhport );
         osal_task_delay(RESET_DELAY);
-
+        hcd_port_reset_end(_dev0.rhport);
         // TODO: fall through to SET ADDRESS, refactor later
       }
       #if CFG_TUH_HUB
@@ -1285,6 +1249,7 @@ static void process_enumeration(tuh_xfer_t* xfer)
       }
       #endif
       __attribute__((fallthrough));
+#endif
 
     case ENUM_SET_ADDR:
       enum_request_set_addr();
@@ -1298,7 +1263,7 @@ static void process_enumeration(tuh_xfer_t* xfer)
       TU_ASSERT(new_dev, );
       new_dev->addressed = 1;
 
-      // TODO close device 0, may not be needed
+      // Close device 0
       hcd_device_close(_dev0.rhport, 0);
 
       // open control pipe for new address
@@ -1389,7 +1354,9 @@ static bool enum_new_device(hcd_event_t* event)
   {
     // connected/disconnected directly with roothub
     // wait until device is stable TODO non blocking
+    hcd_port_reset(_dev0.rhport);
     osal_task_delay(RESET_DELAY);
+    hcd_port_reset_end( _dev0.rhport);
 
     // device unplugged while delaying
     if ( !hcd_port_connect_status(_dev0.rhport) ) return true;

+ 14 - 5
src/host/usbh.h

@@ -91,8 +91,17 @@ bool tuh_init(uint8_t rhport);
 // Check if host stack is already initialized
 bool tuh_inited(void);
 
+// Task function should be called in main/rtos loop, extended version of tuh_task()
+// - timeout_ms: millisecond to wait, zero = no wait, 0xFFFFFFFF = wait forever
+// - in_isr: if function is called in ISR
+void tuh_task_ext(uint32_t timeout_ms, bool in_isr);
+
 // Task function should be called in main/rtos loop
-void tuh_task(void);
+TU_ATTR_ALWAYS_INLINE static inline
+void tuh_task(void)
+{
+  tuh_task_ext(UINT32_MAX, false);
+}
 
 // Interrupt handler, name alias to HCD
 extern void hcd_int_handler(uint8_t rhport);
@@ -106,8 +115,8 @@ tusb_speed_t tuh_speed_get(uint8_t daddr);
 bool tuh_mounted(uint8_t daddr);
 
 // Check if device is suspended
-TU_ATTR_ALWAYS_INLINE
-static inline bool tuh_suspended(uint8_t daddr)
+TU_ATTR_ALWAYS_INLINE static inline
+bool tuh_suspended(uint8_t daddr)
 {
   // TODO implement suspend & resume on host
   (void) daddr;
@@ -115,8 +124,8 @@ static inline bool tuh_suspended(uint8_t daddr)
 }
 
 // Check if device is ready to communicate with
-TU_ATTR_ALWAYS_INLINE
-static inline bool tuh_ready(uint8_t daddr)
+TU_ATTR_ALWAYS_INLINE static inline
+bool tuh_ready(uint8_t daddr)
 {
   return tuh_mounted(daddr) && !tuh_suspended(daddr);
 }

+ 11 - 11
src/osal/osal.h

@@ -66,19 +66,19 @@ typedef void (*osal_task_func_t)( void * );
 // OSAL Porting API
 // Should be implemented as static inline function in osal_port.h header
 /*
-    static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef);
-    static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr);
-    static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec);
-    static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl); // TODO removed
+   osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef);
+   bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr);
+   bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec);
+   void osal_semaphore_reset(osal_semaphore_t sem_hdl); // TODO removed
 
-    static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef);
-    static inline bool osal_mutex_lock (osal_mutex_t sem_hdl, uint32_t msec);
-    static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl);
+   osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef);
+   bool osal_mutex_lock (osal_mutex_t sem_hdl, uint32_t msec);
+   bool osal_mutex_unlock(osal_mutex_t mutex_hdl);
 
-    static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef);
-    static inline bool osal_queue_receive(osal_queue_t qhdl, void* data);
-    static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr);
-    static inline bool osal_queue_empty(osal_queue_t qhdl);
+   osal_queue_t osal_queue_create(osal_queue_def_t* qdef);
+   bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec);
+   bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr);
+   bool osal_queue_empty(osal_queue_t qhdl);
 */
 //--------------------------------------------------------------------+
 

+ 29 - 16
src/osal/osal_freertos.h

@@ -37,10 +37,24 @@
 extern "C" {
 #endif
 
+TU_ATTR_ALWAYS_INLINE static inline uint32_t _osal_ms2tick(uint32_t msec)
+{
+  if (msec == OSAL_TIMEOUT_WAIT_FOREVER) return portMAX_DELAY;
+  if (msec == 0) return 0;
+
+  uint32_t ticks = pdMS_TO_TICKS(msec);
+
+  // configTICK_RATE_HZ is less than 1000 and 1 tick > 1 ms
+  // we still need to delay at least 1 tick
+  if (ticks == 0) ticks =1 ;
+
+  return ticks;
+}
+
 //--------------------------------------------------------------------+
 // TASK API
 //--------------------------------------------------------------------+
-static inline void osal_task_delay(uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec)
 {
   vTaskDelay( pdMS_TO_TICKS(msec) );
 }
@@ -51,12 +65,12 @@ static inline void osal_task_delay(uint32_t msec)
 typedef StaticSemaphore_t osal_semaphore_def_t;
 typedef SemaphoreHandle_t osal_semaphore_t;
 
-static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
 {
   return xSemaphoreCreateBinaryStatic(semdef);
 }
 
-static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
 {
   if ( !in_isr )
   {
@@ -78,13 +92,12 @@ static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
   }
 }
 
-static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec)
 {
-  uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? portMAX_DELAY : pdMS_TO_TICKS(msec);
-  return xSemaphoreTake(sem_hdl, ticks);
+  return xSemaphoreTake(sem_hdl, _osal_ms2tick(msec));
 }
 
-static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl)
+TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl)
 {
   xQueueReset(sem_hdl);
 }
@@ -95,17 +108,17 @@ static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl)
 typedef StaticSemaphore_t osal_mutex_def_t;
 typedef SemaphoreHandle_t osal_mutex_t;
 
-static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
 {
   return xSemaphoreCreateMutexStatic(mdef);
 }
 
-static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec)
 {
   return osal_semaphore_wait(mutex_hdl, msec);
 }
 
-static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
 {
   return xSemaphoreGive(mutex_hdl);
 }
@@ -114,7 +127,7 @@ static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
 // QUEUE API
 //--------------------------------------------------------------------+
 
-// role device/host is used by OS NONE for mutex (disable usb isr) only
+// _int_set is not used with an RTOS
 #define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \
   static _type _name##_##buf[_depth];\
   osal_queue_def_t _name = { .depth = _depth, .item_sz = sizeof(_type), .buf = _name##_##buf };
@@ -130,17 +143,17 @@ typedef struct
 
 typedef QueueHandle_t osal_queue_t;
 
-static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
 {
   return xQueueCreateStatic(qdef->depth, qdef->item_sz, (uint8_t*) qdef->buf, &qdef->sq);
 }
 
-static inline bool osal_queue_receive(osal_queue_t qhdl, void* data)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec)
 {
-  return xQueueReceive(qhdl, data, portMAX_DELAY);
+  return xQueueReceive(qhdl, data, _osal_ms2tick(msec));
 }
 
-static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr)
 {
   if ( !in_isr )
   {
@@ -162,7 +175,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in
   }
 }
 
-static inline bool osal_queue_empty(osal_queue_t qhdl)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl)
 {
   return uxQueueMessagesWaiting(qhdl) == 0;
 }

+ 12 - 10
src/osal/osal_mynewt.h

@@ -36,7 +36,7 @@
 //--------------------------------------------------------------------+
 // TASK API
 //--------------------------------------------------------------------+
-static inline void osal_task_delay(uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec)
 {
   os_time_delay( os_time_ms_to_ticks32(msec) );
 }
@@ -47,18 +47,18 @@ static inline void osal_task_delay(uint32_t msec)
 typedef struct os_sem  osal_semaphore_def_t;
 typedef struct os_sem* osal_semaphore_t;
 
-static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
 {
   return (os_sem_init(semdef, 0) == OS_OK) ? (osal_semaphore_t) semdef : NULL;
 }
 
-static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
 {
   (void) in_isr;
   return os_sem_release(sem_hdl) == OS_OK;
 }
 
-static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec)
 {
   uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? OS_TIMEOUT_NEVER : os_time_ms_to_ticks32(msec);
   return os_sem_pend(sem_hdl, ticks) == OS_OK;
@@ -75,18 +75,18 @@ static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl)
 typedef struct os_mutex osal_mutex_def_t;
 typedef struct os_mutex* osal_mutex_t;
 
-static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
 {
   return (os_mutex_init(mdef) == OS_OK) ? (osal_mutex_t) mdef : NULL;
 }
 
-static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec)
 {
   uint32_t const ticks = (msec == OSAL_TIMEOUT_WAIT_FOREVER) ? OS_TIMEOUT_NEVER : os_time_ms_to_ticks32(msec);
   return os_mutex_pend(mutex_hdl, ticks) == OS_OK;
 }
 
-static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
 {
   return os_mutex_release(mutex_hdl) == OS_OK;
 }
@@ -116,7 +116,7 @@ typedef struct
 
 typedef osal_queue_def_t* osal_queue_t;
 
-static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
 {
   if ( OS_OK != os_mempool_init(&qdef->mpool, qdef->depth, qdef->item_sz, qdef->buf, "usbd queue") ) return NULL;
   if ( OS_OK != os_mempool_init(&qdef->epool, qdef->depth, sizeof(struct os_event), qdef->evbuf, "usbd evqueue") ) return NULL;
@@ -125,8 +125,10 @@ static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
   return (osal_queue_t) qdef;
 }
 
-static inline bool osal_queue_receive(osal_queue_t qhdl, void* data)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec)
 {
+  (void) msec; // os_eventq_get() does not take timeout, always behave as msec = WAIT_FOREVER
+
   struct os_event* ev;
   ev = os_eventq_get(&qhdl->evq);
 
@@ -161,7 +163,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in
   return true;
 }
 
-static inline bool osal_queue_empty(osal_queue_t qhdl)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl)
 {
   return STAILQ_EMPTY(&qhdl->evq.evq_list);
 }

+ 15 - 13
src/osal/osal_none.h

@@ -46,13 +46,13 @@ typedef struct
 
 typedef osal_semaphore_def_t* osal_semaphore_t;
 
-static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
 {
   semdef->count = 0;
   return semdef;
 }
 
-static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
 {
   (void) in_isr;
   sem_hdl->count++;
@@ -60,7 +60,7 @@ static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
 }
 
 // TODO blocking for now
-static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec)
 {
   (void) msec;
 
@@ -70,7 +70,7 @@ static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec)
   return true;
 }
 
-static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl)
+TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl)
 {
   sem_hdl->count = 0;
 }
@@ -82,18 +82,18 @@ static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl)
 typedef osal_semaphore_def_t osal_mutex_def_t;
 typedef osal_semaphore_t osal_mutex_t;
 
-static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
 {
   mdef->count = 1;
   return mdef;
 }
 
-static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec)
 {
   return osal_semaphore_wait(mutex_hdl, msec);
 }
 
-static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
 {
   return osal_semaphore_post(mutex_hdl, false);
 }
@@ -120,27 +120,29 @@ typedef osal_queue_def_t* osal_queue_t;
   }
 
 // lock queue by disable USB interrupt
-static inline void _osal_q_lock(osal_queue_t qhdl)
+TU_ATTR_ALWAYS_INLINE static inline void _osal_q_lock(osal_queue_t qhdl)
 {
   // disable dcd/hcd interrupt
   qhdl->interrupt_set(false);
 }
 
 // unlock queue
-static inline void _osal_q_unlock(osal_queue_t qhdl)
+TU_ATTR_ALWAYS_INLINE static inline void _osal_q_unlock(osal_queue_t qhdl)
 {
   // enable dcd/hcd interrupt
   qhdl->interrupt_set(true);
 }
 
-static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
 {
   tu_fifo_clear(&qdef->ff);
   return (osal_queue_t) qdef;
 }
 
-static inline bool osal_queue_receive(osal_queue_t qhdl, void* data)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec)
 {
+  (void) msec; // not used, always behave as msec = 0
+
   _osal_q_lock(qhdl);
   bool success = tu_fifo_read(&qhdl->ff, data);
   _osal_q_unlock(qhdl);
@@ -148,7 +150,7 @@ static inline bool osal_queue_receive(osal_queue_t qhdl, void* data)
   return success;
 }
 
-static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr)
 {
   if (!in_isr) {
     _osal_q_lock(qhdl);
@@ -165,7 +167,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in
   return success;
 }
 
-static inline bool osal_queue_empty(osal_queue_t qhdl)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl)
 {
   // Skip queue lock/unlock since this function is primarily called
   // with interrupt disabled before going into low power mode

+ 23 - 21
src/osal/osal_pico.h

@@ -39,7 +39,7 @@
 //--------------------------------------------------------------------+
 // TASK API
 //--------------------------------------------------------------------+
-static inline void osal_task_delay(uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec)
 {
   sleep_ms(msec);
 }
@@ -49,25 +49,25 @@ static inline void osal_task_delay(uint32_t msec)
 //--------------------------------------------------------------------+
 typedef struct semaphore osal_semaphore_def_t, *osal_semaphore_t;
 
-static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t* semdef)
 {
   sem_init(semdef, 0, 255);
   return semdef;
 }
 
-static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr)
 {
   (void) in_isr;
   sem_release(sem_hdl);
   return true;
 }
 
-static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec)
 {
   return sem_acquire_timeout_ms(sem_hdl, msec);
 }
 
-static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl)
+TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl)
 {
   sem_reset(sem_hdl, 0);
 }
@@ -78,21 +78,21 @@ static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl)
 //--------------------------------------------------------------------+
 typedef struct mutex osal_mutex_def_t, *osal_mutex_t;
 
-static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
 {
-    mutex_init(mdef);
-    return mdef;
+  mutex_init(mdef);
+  return mdef;
 }
 
-static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec)
 {
-    return mutex_enter_timeout_ms(mutex_hdl, msec);
+  return mutex_enter_timeout_ms(mutex_hdl, msec);
 }
 
-static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
 {
-    mutex_exit(mutex_hdl);
-    return true;
+  mutex_exit(mutex_hdl);
+  return true;
 }
 
 //--------------------------------------------------------------------+
@@ -121,26 +121,28 @@ typedef osal_queue_def_t* osal_queue_t;
   }
 
 // lock queue by disable USB interrupt
-static inline void _osal_q_lock(osal_queue_t qhdl)
+TU_ATTR_ALWAYS_INLINE static inline void _osal_q_lock(osal_queue_t qhdl)
 {
-    critical_section_enter_blocking(&qhdl->critsec);
+  critical_section_enter_blocking(&qhdl->critsec);
 }
 
 // unlock queue
-static inline void _osal_q_unlock(osal_queue_t qhdl)
+TU_ATTR_ALWAYS_INLINE static inline void _osal_q_unlock(osal_queue_t qhdl)
 {
-    critical_section_exit(&qhdl->critsec);
+  critical_section_exit(&qhdl->critsec);
 }
 
-static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
 {
   critical_section_init(&qdef->critsec);
   tu_fifo_clear(&qdef->ff);
   return (osal_queue_t) qdef;
 }
 
-static inline bool osal_queue_receive(osal_queue_t qhdl, void* data)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec)
 {
+  (void) msec; // not used, always behave as msec = 0
+
   // TODO: revisit... docs say that mutexes are never used from IRQ context,
   //  however osal_queue_recieve may be. therefore my assumption is that
   //  the fifo mutex is not populated for queues used from an IRQ context
@@ -153,7 +155,7 @@ static inline bool osal_queue_receive(osal_queue_t qhdl, void* data)
   return success;
 }
 
-static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr)
 {
   // TODO: revisit... docs say that mutexes are never used from IRQ context,
   //  however osal_queue_recieve may be. therefore my assumption is that
@@ -170,7 +172,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in
   return success;
 }
 
-static inline bool osal_queue_empty(osal_queue_t qhdl)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl)
 {
   // TODO: revisit; whether this is true or not currently, tu_fifo_empty is a single
   //  volatile read.

+ 15 - 13
src/osal/osal_rtthread.h

@@ -37,7 +37,7 @@ extern "C" {
 //--------------------------------------------------------------------+
 // TASK API
 //--------------------------------------------------------------------+
-static inline void osal_task_delay(uint32_t msec) {
+TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) {
   rt_thread_mdelay(msec);
 }
 
@@ -47,22 +47,22 @@ static inline void osal_task_delay(uint32_t msec) {
 typedef struct rt_semaphore osal_semaphore_def_t;
 typedef rt_sem_t osal_semaphore_t;
 
-static inline osal_semaphore_t
+TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t
 osal_semaphore_create(osal_semaphore_def_t *semdef) {
     rt_sem_init(semdef, "tusb", 0, RT_IPC_FLAG_PRIO);
     return semdef;
 }
 
-static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) {
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) {
     (void) in_isr;
     return rt_sem_release(sem_hdl) == RT_EOK;
 }
 
-static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) {
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) {
     return rt_sem_take(sem_hdl, rt_tick_from_millisecond(msec)) == RT_EOK;
 }
 
-static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) {
+TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) {
     // TODO: implement
 }
 
@@ -72,16 +72,16 @@ static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) {
 typedef struct rt_mutex osal_mutex_def_t;
 typedef rt_mutex_t osal_mutex_t;
 
-static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t *mdef) {
+TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t *mdef) {
     rt_mutex_init(mdef, "tusb", RT_IPC_FLAG_PRIO);
     return mdef;
 }
 
-static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) {
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) {
     return rt_mutex_take(mutex_hdl, rt_tick_from_millisecond(msec)) == RT_EOK;
 }
 
-static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) {
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) {
     return rt_mutex_release(mutex_hdl) == RT_EOK;
 }
 
@@ -104,22 +104,24 @@ typedef struct {
 
 typedef rt_mq_t osal_queue_t;
 
-static inline osal_queue_t osal_queue_create(osal_queue_def_t *qdef) {
+TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t *qdef) {
     rt_mq_init(&(qdef->sq), "tusb", qdef->buf, qdef->item_sz,
                qdef->item_sz * qdef->depth, RT_IPC_FLAG_PRIO);
     return &(qdef->sq);
 }
 
-static inline bool osal_queue_receive(osal_queue_t qhdl, void *data) {
-    return rt_mq_recv(qhdl, data, qhdl->msg_size, RT_WAITING_FOREVER) == RT_EOK;
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void *data, uint32_t msec) {
+
+    rt_tick_t tick = rt_tick_from_millisecond((rt_int32_t) msec));
+    return rt_mq_recv(qhdl, data, qhdl->msg_size, tick) == RT_EOK;
 }
 
-static inline bool osal_queue_send(osal_queue_t qhdl, void const *data, bool in_isr) {
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const *data, bool in_isr) {
     (void) in_isr;
     return rt_mq_send(qhdl, (void *)data, qhdl->msg_size) == RT_EOK;
 }
 
-static inline bool osal_queue_empty(osal_queue_t qhdl) {
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) {
     return (qhdl->entry) == 0;
 }
 

+ 14 - 14
src/osal/osal_rtx4.h

@@ -37,7 +37,7 @@ extern "C" {
 //--------------------------------------------------------------------+
 // TASK API
 //--------------------------------------------------------------------+
-static inline void osal_task_delay(uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec)
 {
   uint16_t hi = msec >> 16;
   uint16_t lo = msec;
@@ -47,7 +47,7 @@ static inline void osal_task_delay(uint32_t msec)
   os_dly_wait(lo);
 }
 
-static inline uint16_t msec2wait(uint32_t msec) {
+TU_ATTR_ALWAYS_INLINE static inline uint16_t msec2wait(uint32_t msec) {
   if (msec == OSAL_TIMEOUT_WAIT_FOREVER)
     return 0xFFFF;
   else if (msec >= 0xFFFE)
@@ -62,12 +62,12 @@ static inline uint16_t msec2wait(uint32_t msec) {
 typedef OS_SEM osal_semaphore_def_t;
 typedef OS_ID osal_semaphore_t;
 
-static inline OS_ID osal_semaphore_create(osal_semaphore_def_t* semdef) {
+TU_ATTR_ALWAYS_INLINE static inline OS_ID osal_semaphore_create(osal_semaphore_def_t* semdef) {
   os_sem_init(semdef, 0);
   return semdef;
 }
 
-static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) {
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) {
   if ( !in_isr ) {
     os_sem_send(sem_hdl);
   } else {
@@ -76,11 +76,11 @@ static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) {
 	return true;
 }
 
-static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) {
+TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait (osal_semaphore_t sem_hdl, uint32_t msec) {
   return os_sem_wait(sem_hdl, msec2wait(msec)) != OS_R_TMO;
 }
 
-static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) {
+TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) {
   // TODO: implement
 }
 
@@ -90,18 +90,18 @@ static inline void osal_semaphore_reset(osal_semaphore_t const sem_hdl) {
 typedef OS_MUT osal_mutex_def_t;
 typedef OS_ID osal_mutex_t;
 
-static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t* mdef)
 {
   os_mut_init(mdef);
   return mdef;
 }
 
-static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock (osal_mutex_t mutex_hdl, uint32_t msec)
 {
   return os_mut_wait(mutex_hdl, msec2wait(msec)) != OS_R_TMO;
 }
 
-static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl)
 {
   return os_mut_release(mutex_hdl) == OS_R_OK;
 }
@@ -127,23 +127,23 @@ typedef struct
 
 typedef osal_queue_def_t* osal_queue_t;
 
-static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
+TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef)
 {
   os_mbx_init(qdef->mbox, (qdef->depth + 4) * 4);
   _init_box(qdef->pool, ((qdef->item_sz+3)/4)*(qdef->depth) + 3, qdef->item_sz);
   return qdef;
 }
 
-static inline bool osal_queue_receive(osal_queue_t qhdl, void* data)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec)
 {
   void* buf;
-  os_mbx_wait(qhdl->mbox, &buf, 0xFFFF);
+  os_mbx_wait(qhdl->mbox, &buf, msec2wait(msec));
   memcpy(data, buf, qhdl->item_sz);
   _free_box(qhdl->pool, buf);
   return true;
 }
 
-static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in_isr)
 {
   void* buf = _alloc_box(qhdl->pool);
   memcpy(buf, data, qhdl->item_sz);
@@ -158,7 +158,7 @@ static inline bool osal_queue_send(osal_queue_t qhdl, void const * data, bool in
   return true;
 }
 
-static inline bool osal_queue_empty(osal_queue_t qhdl)
+TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl)
 {
   return os_mbx_check(qhdl->mbox) == qhdl->depth;
 }

+ 7 - 0
src/portable/bridgetek/ft9xx/dcd_ft9xx.c

@@ -649,6 +649,13 @@ void dcd_disconnect(uint8_t rhport)
   _ft90x_phy_enable(false);
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
 
 //--------------------------------------------------------------------+
 // Endpoint API

+ 0 - 1267
src/portable/broadcom/synopsys/dcd_synopsys.c

@@ -1,1267 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2018 Scott Shawcroft, 2019 William D. Jones for Adafruit Industries
- * Copyright (c) 2019 Ha Thach (tinyusb.org)
- * Copyright (c) 2020 Jan Duempelmann
- * Copyright (c) 2020 Reinhard Panhuber
- *
- * 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.
- */
-
-#include "tusb_option.h"
-
-#if CFG_TUD_ENABLED &&         \
-    (CFG_TUSB_MCU == OPT_MCU_BCM2711 ) \
-
-
-#include "synopsys_common.h"
-
-#include "broadcom/interrupts.h"
-
-// Since TinyUSB doesn't use SOF for now, and this interrupt too often (1ms interval)
-// We disable SOF for now until needed later on
-#define USE_SOF     0
-
-// EP_MAX       : Max number of bi-directional endpoints including EP0
-// EP_FIFO_SIZE : Size of dedicated USB SRAM
-#if CFG_TUSB_MCU == OPT_MCU_BCM2711
-// #include "bcm2711.h"
-#define EP_MAX_FS       8
-#define EP_FIFO_SIZE_FS 4096
-#define EP_MAX_HS       8
-#define EP_FIFO_SIZE_HS 4096
-#else
-#error "Unsupported MCUs"
-#endif
-
-#define EP_MAX 8
-#define EP_FIFO_SIZE 4096
-
-// Info on values here: https://github.com/torvalds/linux/blob/79160a603bdb51916226caf4a6616cc4e1c58a58/Documentation/devicetree/bindings/usb/dwc2.yaml
-
-// From: https://github.com/raspberrypi/linux/blob/rpi-5.10.y/arch/arm/boot/dts/bcm283x.dtsi
-// usb: usb@7e980000 {
-//   compatible = "brcm,bcm2835-usb";
-//   reg = <0x7e980000 0x10000>;
-//   interrupts = <1 9>;
-//   #address-cells = <1>;
-//   #size-cells = <0>;
-//   clocks = <&clk_usb>;
-//   clock-names = "otg";
-//   phys = <&usbphy>;
-//   phy-names = "usb2-phy";
-// };
-
-// From: https://github.com/raspberrypi/linux/blob/rpi-5.10.y/arch/arm/boot/dts/bcm283x-rpi-usb-otg.dtsi
-// SPDX-License-Identifier: GPL-2.0
-// &usb {
-//   dr_mode = "otg";
-//   g-rx-fifo-size = <256>;
-//   g-np-tx-fifo-size = <32>;
-  
-//    * According to dwc2 the sum of all device EP
-//    * fifo sizes shouldn't exceed 3776 bytes.
-   
-//   g-tx-fifo-size = <256 256 512 512 512 768 768>;
-// };
-
-// From: https://github.com/raspberrypi/linux/blob/rpi-5.10.y/arch/arm/boot/dts/bcm2711-rpi.dtsi
-// &usb {
-//   /* Enable the FIQ support */
-//   reg = <0x7e980000 0x10000>,
-//         <0x7e00b200 0x200>;
-//   interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>,
-//          <GIC_SPI 40 IRQ_TYPE_LEVEL_HIGH>;
-//   status = "disabled";
-// };
-
-// From: https://github.com/raspberrypi/linux/blob/rpi-5.10.y/arch/arm/boot/dts/bcm2711.dtsi
-// &usb {
-//   interrupts = <GIC_SPI 73 IRQ_TYPE_LEVEL_HIGH>;
-// };
-
-// From: https://github.com/torvalds/linux/blob/1d597682d3e669ec7021aa33d088ed3d136a5149/drivers/usb/dwc2/params.c
-// static void dwc2_set_bcm_params(struct dwc2_hsotg *hsotg)
-// {
-//   struct dwc2_core_params *p = &hsotg->params;
-
-//   p->host_rx_fifo_size = 774;
-//   p->max_transfer_size = 65535;
-//   p->max_packet_count = 511;
-//   p->ahbcfg = 0x10;
-// }
-
-#include "device/dcd.h"
-
-TU_VERIFY_STATIC(sizeof(USB_OTG_GlobalTypeDef) == 0x140, "size is incorrect");
-
-//--------------------------------------------------------------------+
-// MACRO TYPEDEF CONSTANT ENUM
-//--------------------------------------------------------------------+
-
-#define RHPORT_REGS_BASE USB_OTG_GLOBAL_BASE
-
-#define GLOBAL_BASE(_port)     ((USB_OTG_GlobalTypeDef*) RHPORT_REGS_BASE)
-#define DEVICE_BASE(_port)     (USB_OTG_DeviceTypeDef *) (USB_OTG_DEVICE_BASE)
-#define OUT_EP_BASE(_port)     (USB_OTG_OUTEndpointTypeDef *) (RHPORT_REGS_BASE + USB_OTG_OUT_ENDPOINT_BASE)
-#define IN_EP_BASE(_port)      (USB_OTG_INEndpointTypeDef *) (RHPORT_REGS_BASE + USB_OTG_IN_ENDPOINT_BASE)
-#define FIFO_BASE(_port, _x)   ((volatile uint32_t *) (RHPORT_REGS_BASE + USB_OTG_FIFO_BASE + (_x) * USB_OTG_FIFO_SIZE))
-
-enum
-{
-  DCD_HIGH_SPEED        = 0, // Highspeed mode
-  DCD_FULL_SPEED_USE_HS = 1, // Full speed in Highspeed port (probably with internal PHY)
-  DCD_FULL_SPEED        = 3, // Full speed with internal PHY
-};
-
-static TU_ATTR_ALIGNED(4) uint32_t _setup_packet[2];
-
-typedef struct {
-  uint8_t * buffer;
-  tu_fifo_t * ff;
-  uint16_t total_len;
-  uint16_t max_size;
-  uint8_t interval;
-} xfer_ctl_t;
-
-typedef volatile uint32_t * usb_fifo_t;
-
-xfer_ctl_t xfer_status[EP_MAX][2];
-#define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir]
-
-// EP0 transfers are limited to 1 packet - larger sizes has to be split
-static uint16_t ep0_pending[2];                   // Index determines direction as tusb_dir_t type
-
-// TX FIFO RAM allocation so far in words - RX FIFO size is readily available from usb_otg->GRXFSIZ
-static uint16_t _allocated_fifo_words_tx;         // TX FIFO size in words (IN EPs)
-static bool _out_ep_closed;                       // Flag to check if RX FIFO size needs an update (reduce its size)
-
-// Calculate the RX FIFO size according to recommendations from reference manual
-static inline uint16_t calc_rx_ff_size(uint16_t ep_size)
-{
-  return 15 + 2*(ep_size/4) + 2*EP_MAX;
-}
-
-static void update_grxfsiz(uint8_t rhport)
-{
-  (void) rhport;
-
-  USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport);
-
-  // Determine largest EP size for RX FIFO
-  uint16_t max_epsize = 0;
-  for (uint8_t epnum = 0; epnum < EP_MAX; epnum++)
-  {
-    max_epsize = tu_max16(max_epsize, xfer_status[epnum][TUSB_DIR_OUT].max_size);
-  }
-
-  // Update size of RX FIFO
-  usb_otg->GRXFSIZ = calc_rx_ff_size(max_epsize);
-}
-
-// Setup the control endpoint 0.
-static void bus_reset(uint8_t rhport)
-{
-  (void) rhport;
-
-  USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport);
-  USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport);
-  USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport);
-  USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport);
-
-  tu_memclr(xfer_status, sizeof(xfer_status));
-  _out_ep_closed = false;
-
-  // clear device address
-  dev->DCFG &= ~USB_OTG_DCFG_DAD_Msk;
-
-  // 1. NAK for all OUT endpoints
-  for(uint8_t n = 0; n < EP_MAX; n++) {
-    out_ep[n].DOEPCTL |= USB_OTG_DOEPCTL_SNAK;
-  }
-
-  // 2. Un-mask interrupt bits
-  dev->DAINTMSK = (1 << USB_OTG_DAINTMSK_OEPM_Pos) | (1 << USB_OTG_DAINTMSK_IEPM_Pos);
-  dev->DOEPMSK = USB_OTG_DOEPMSK_STUPM | USB_OTG_DOEPMSK_XFRCM;
-  dev->DIEPMSK = USB_OTG_DIEPMSK_TOM | USB_OTG_DIEPMSK_XFRCM;
-
-  // "USB Data FIFOs" section in reference manual
-  // Peripheral FIFO architecture
-  //
-  // The FIFO is split up in a lower part where the RX FIFO is located and an upper part where the TX FIFOs start.
-  // We do this to allow the RX FIFO to grow dynamically which is possible since the free space is located
-  // between the RX and TX FIFOs. This is required by ISO OUT EPs which need a bigger FIFO than the standard
-  // configuration done below.
-  //
-  // Dynamically FIFO sizes are of interest only for ISO EPs since all others are usually not opened and closed.
-  // All EPs other than ISO are opened as soon as the driver starts up i.e. when the host sends a
-  // configure interface command. Hence, all IN EPs other the ISO will be located at the top. IN ISO EPs are usually
-  // opened when the host sends an additional command: setInterface. At this point in time
-  // the ISO EP will be located next to the free space and can change its size. In case more IN EPs change its size
-  // an additional memory
-  //
-  // --------------- 320 or 1024 ( 1280 or 4096 bytes )
-  // | IN FIFO 0   |
-  // --------------- (320 or 1024) - 16
-  // | IN FIFO 1   |
-  // --------------- (320 or 1024) - 16 - x
-  // |   . . . .   |
-  // --------------- (320 or 1024) - 16 - x - y - ... - z
-  // | IN FIFO MAX |
-  // ---------------
-  // |    FREE     |
-  // --------------- GRXFSIZ
-  // | OUT FIFO    |
-  // | ( Shared )  |
-  // --------------- 0
-  //
-  // According to "FIFO RAM allocation" section in RM, FIFO RAM are allocated as follows (each word 32-bits):
-  // - Each EP IN needs at least max packet size, 16 words is sufficient for EP0 IN
-  //
-  // - All EP OUT shared a unique OUT FIFO which uses
-  //   - 13 for setup packets + control words (up to 3 setup packets).
-  //   - 1 for global NAK (not required/used here).
-  //   - Largest-EPsize / 4 + 1. ( FS: 64 bytes, HS: 512 bytes). Recommended is  "2 x (Largest-EPsize/4) + 1"
-  //   - 2 for each used OUT endpoint
-  //
-  //   Therefore GRXFSIZ = 13 + 1 + 1 + 2 x (Largest-EPsize/4) + 2 x EPOUTnum
-  //   - FullSpeed (64 Bytes ): GRXFSIZ = 15 + 2 x  16 + 2 x EP_MAX = 47  + 2 x EP_MAX
-  //   - Highspeed (512 bytes): GRXFSIZ = 15 + 2 x 128 + 2 x EP_MAX = 271 + 2 x EP_MAX
-  //
-  //   NOTE: Largest-EPsize & EPOUTnum is actual used endpoints in configuration. Since DCD has no knowledge
-  //   of the overall picture yet. We will use the worst scenario: largest possible + EP_MAX
-  //
-  //   For Isochronous, largest EP size can be 1023/1024 for FS/HS respectively. In addition if multiple ISO
-  //   are enabled at least "2 x (Largest-EPsize/4) + 1" are recommended.  Maybe provide a macro for application to
-  //   overwrite this.
-
-  #if TUD_OPT_HIGH_SPEED
-  usb_otg->GRXFSIZ = calc_rx_ff_size(512);
-  #else
-  usb_otg->GRXFSIZ = calc_rx_ff_size(64);
-  #endif
-
-  _allocated_fifo_words_tx = 16;
-
-  // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word )
-  usb_otg->DIEPTXF0_HNPTXFSIZ = (16 << USB_OTG_TX0FD_Pos) | (EP_FIFO_SIZE/4 - _allocated_fifo_words_tx);
-
-  // Fixed control EP0 size to 64 bytes
-  in_ep[0].DIEPCTL &= ~(0x03 << USB_OTG_DIEPCTL_MPSIZ_Pos);
-  xfer_status[0][TUSB_DIR_OUT].max_size = xfer_status[0][TUSB_DIR_IN].max_size = 64;
-
-  out_ep[0].DOEPTSIZ |= (3 << USB_OTG_DOEPTSIZ_STUPCNT_Pos);
-
-  usb_otg->GINTMSK |= USB_OTG_GINTMSK_OEPINT | USB_OTG_GINTMSK_IEPINT;
-}
-
-// Set turn-around timeout according to link speed
-extern uint32_t SystemCoreClock;
-static void set_turnaround(USB_OTG_GlobalTypeDef * usb_otg, tusb_speed_t speed)
-{
-  usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_TRDT;
-
-  if ( speed == TUSB_SPEED_HIGH )
-  {
-    // Use fixed 0x09 for Highspeed
-    usb_otg->GUSBCFG |= (0x09 << USB_OTG_GUSBCFG_TRDT_Pos);
-  }
-  else
-  {
-    // Turnaround timeout depends on the MCU clock
-    uint32_t turnaround;
-
-    if ( SystemCoreClock >= 32000000U )
-      turnaround = 0x6U;
-    else if ( SystemCoreClock >= 27500000U )
-      turnaround = 0x7U;
-    else if ( SystemCoreClock >= 24000000U )
-      turnaround = 0x8U;
-    else if ( SystemCoreClock >= 21800000U )
-      turnaround = 0x9U;
-    else if ( SystemCoreClock >= 20000000U )
-      turnaround = 0xAU;
-    else if ( SystemCoreClock >= 18500000U )
-      turnaround = 0xBU;
-    else if ( SystemCoreClock >= 17200000U )
-      turnaround = 0xCU;
-    else if ( SystemCoreClock >= 16000000U )
-      turnaround = 0xDU;
-    else if ( SystemCoreClock >= 15000000U )
-      turnaround = 0xEU;
-    else
-      turnaround = 0xFU;
-
-    // Fullspeed depends on MCU clocks, but we will use 0x06 for 32+ Mhz
-    usb_otg->GUSBCFG |= (turnaround << USB_OTG_GUSBCFG_TRDT_Pos);
-  }
-}
-
-static tusb_speed_t get_speed(uint8_t rhport)
-{
-  (void) rhport;
-  USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport);
-  uint32_t const enum_spd = (dev->DSTS & USB_OTG_DSTS_ENUMSPD_Msk) >> USB_OTG_DSTS_ENUMSPD_Pos;
-  return (enum_spd == DCD_HIGH_SPEED) ? TUSB_SPEED_HIGH : TUSB_SPEED_FULL;
-}
-
-static void set_speed(uint8_t rhport, tusb_speed_t speed)
-{
-  uint32_t bitvalue;
-
-  if ( rhport == 1 )
-  {
-    bitvalue = ((TUSB_SPEED_HIGH == speed) ? DCD_HIGH_SPEED : DCD_FULL_SPEED_USE_HS);
-  }
-  else
-  {
-    bitvalue = DCD_FULL_SPEED;
-  }
-
-  USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport);
-
-  // Clear and set speed bits
-  dev->DCFG &= ~(3 << USB_OTG_DCFG_DSPD_Pos);
-  dev->DCFG |= (bitvalue << USB_OTG_DCFG_DSPD_Pos);
-}
-
-#if 0
-// From CM4IO xtal to usb hub, may not be correct
-#define HSE_VALUE 24000000
-
-static bool USB_HS_PHYCInit(void)
-{
-  USB_HS_PHYC_GlobalTypeDef *usb_hs_phyc = (USB_HS_PHYC_GlobalTypeDef*) USB_HS_PHYC_CONTROLLER_BASE;
-
-  // Enable LDO
-  usb_hs_phyc->USB_HS_PHYC_LDO |= USB_HS_PHYC_LDO_ENABLE;
-
-  // Wait until LDO ready
-  while ( 0 == (usb_hs_phyc->USB_HS_PHYC_LDO & USB_HS_PHYC_LDO_STATUS) ) {}
-
-  uint32_t phyc_pll = 0;
-
-  // TODO Try to get HSE_VALUE from registers instead of depending CFLAGS
-  switch ( HSE_VALUE )
-  {
-    case 12000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12MHZ   ; break;
-    case 12500000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_12_5MHZ ; break;
-    case 16000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_16MHZ   ; break;
-    case 24000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_24MHZ   ; break;
-    case 25000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_25MHZ   ; break;
-    case 32000000: phyc_pll = USB_HS_PHYC_PLL1_PLLSEL_Msk     ; break; // Value not defined in header
-    default:
-      TU_ASSERT(0);
-  }
-  usb_hs_phyc->USB_HS_PHYC_PLL = phyc_pll;
-
-  // Control the tuning interface of the High Speed PHY
-  // Use magic value (USB_HS_PHYC_TUNE_VALUE) from ST driver
-  usb_hs_phyc->USB_HS_PHYC_TUNE |= 0x00000F13U;
-
-  // Enable PLL internal PHY
-  usb_hs_phyc->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN;
-
-  // Original ST code has 2 ms delay for PLL stabilization.
-  // Primitive test shows that more than 10 USB un/replug cycle showed no error with enumeration
-
-  return true;
-}
-#endif
-
-static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t const dir, uint16_t const num_packets, uint16_t total_bytes)
-{
-  (void) rhport;
-
-  USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport);
-  USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport);
-  USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport);
-
-  // EP0 is limited to one packet each xfer
-  // We use multiple transaction of xfer->max_size length to get a whole transfer done
-  if(epnum == 0) {
-    xfer_ctl_t * const xfer = XFER_CTL_BASE(epnum, dir);
-    total_bytes = tu_min16(ep0_pending[dir], xfer->max_size);
-    ep0_pending[dir] -= total_bytes;
-  }
-
-  // IN and OUT endpoint xfers are interrupt-driven, we just schedule them here.
-  if(dir == TUSB_DIR_IN) {
-    // A full IN transfer (multiple packets, possibly) triggers XFRC.
-    in_ep[epnum].DIEPTSIZ = (num_packets << USB_OTG_DIEPTSIZ_PKTCNT_Pos) |
-        ((total_bytes << USB_OTG_DIEPTSIZ_XFRSIZ_Pos) & USB_OTG_DIEPTSIZ_XFRSIZ_Msk);
-
-    in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_EPENA | USB_OTG_DIEPCTL_CNAK;
-    // For ISO endpoint set correct odd/even bit for next frame.
-    if ((in_ep[epnum].DIEPCTL & USB_OTG_DIEPCTL_EPTYP) == USB_OTG_DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1)
-    {
-      // Take odd/even bit from frame counter.
-      uint32_t const odd_frame_now = (dev->DSTS & (1u << USB_OTG_DSTS_FNSOF_Pos));
-      in_ep[epnum].DIEPCTL |= (odd_frame_now ? USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Msk : USB_OTG_DIEPCTL_SODDFRM_Msk);
-    }
-    // Enable fifo empty interrupt only if there are something to put in the fifo.
-    if(total_bytes != 0) {
-      dev->DIEPEMPMSK |= (1 << epnum);
-    }
-  } else {
-    // A full OUT transfer (multiple packets, possibly) triggers XFRC.
-    out_ep[epnum].DOEPTSIZ &= ~(USB_OTG_DOEPTSIZ_PKTCNT_Msk | USB_OTG_DOEPTSIZ_XFRSIZ);
-    out_ep[epnum].DOEPTSIZ |= (num_packets << USB_OTG_DOEPTSIZ_PKTCNT_Pos) |
-        ((total_bytes << USB_OTG_DOEPTSIZ_XFRSIZ_Pos) & USB_OTG_DOEPTSIZ_XFRSIZ_Msk);
-
-    out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_EPENA | USB_OTG_DOEPCTL_CNAK;
-    if ((out_ep[epnum].DOEPCTL & USB_OTG_DOEPCTL_EPTYP) == USB_OTG_DOEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1)
-    {
-      // Take odd/even bit from frame counter.
-      uint32_t const odd_frame_now = (dev->DSTS & (1u << USB_OTG_DSTS_FNSOF_Pos));
-      out_ep[epnum].DOEPCTL |= (odd_frame_now ? USB_OTG_DOEPCTL_SD0PID_SEVNFRM_Msk : USB_OTG_DOEPCTL_SODDFRM_Msk);
-    }
-  }
-}
-
-/*------------------------------------------------------------------*/
-/* Controller API
- *------------------------------------------------------------------*/
-
-TU_ATTR_UNUSED
-static void reset_core(USB_OTG_GlobalTypeDef * usb_otg) {
-  while ((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0) {}
-
-  TU_LOG(2, "    resetting\r\n");
-  usb_otg->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
-  TU_LOG(2, "    waiting\r\n");
-  while ((usb_otg->GRSTCTL & (USB_OTG_GRSTCTL_AHBIDL | USB_OTG_GRSTCTL_CSRST)) != USB_OTG_GRSTCTL_AHBIDL) {}
-  TU_LOG(2, "    reset done\r\n");
-}
-
-void dcd_init (uint8_t rhport)
-{
-  printf("test done\r\n");
-  // Programming model begins in the last section of the chapter on the USB
-  // peripheral in each Reference Manual.
-  TU_LOG(2, "    dcd_init\r\n");
-
-  TU_LOG2("Test 123\r\n");
-
-  USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport);
-
-#if 1
-  // No VBUS sense
-  usb_otg->GCCFG &= ~(1UL << 21); // USB_OTG_GCCFG_VBDEN
-
-  // B-peripheral session valid override enable
-  usb_otg->GOTGCTL |= (1UL << 6); // USB_OTG_GOTGCTL_BVALOEN
-  usb_otg->GOTGCTL |= (1UL << 7); // USB_OTG_GOTGCTL_BVALOVAL
-
-  // Force device mode
-  usb_otg->GUSBCFG &= ~USB_OTG_GUSBCFG_FHMOD;
-  usb_otg->GUSBCFG |= USB_OTG_GUSBCFG_FDMOD;
-
-  // deactivate internal PHY
-  usb_otg->GCCFG &= ~USB_OTG_GCCFG_PWRDWN;
-
-  // Init The UTMI Interface
-  usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_PHYSEL);
-
-  // Select default internal VBUS Indicator and Drive for ULPI
-  usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIEVBUSD | USB_OTG_GUSBCFG_ULPIEVBUSI);
-
-  // Select UTMI Interface
-  usb_otg->GUSBCFG &= ~(1UL << 4); // USB_OTG_GUSBCFG_ULPI_UTMI_SEL
-  usb_otg->GCCFG |= (1UL << 32);   // USB_OTG_GCCFG_PHYHSEN
-
-  // Enables control of a High Speed USB PHY
-  //USB_HS_PHYCInit();
-
-  // Reset core after selecting PHY
-  // Wait AHB IDLE, reset then wait until it is cleared
-//  while ((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_AHBIDL) == 0U) {}
-//  usb_otg->GRSTCTL |= USB_OTG_GRSTCTL_CSRST;
-//  while ((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_CSRST) == USB_OTG_GRSTCTL_CSRST) {}
-
-  reset_core(usb_otg);
-
-  // Restart PHY clock
-  *((volatile uint32_t *)(RHPORT_REGS_BASE + USB_OTG_PCGCCTL_BASE)) = 0;
-
-#else
-
-  // ReadBackReg(&Core->Usb);
-  // Core->Usb.UlpiDriveExternalVbus = 0;
-  // Core->Usb.TsDlinePulseEnable = 0;
-  // WriteThroughReg(&Core->Usb);
-
-  // This sequence is modeled after: https://github.com/Chadderz121/csud/blob/e13b9355d043a9cdd384b335060f1bc0416df61e/source/hcd/dwc/designware20.c#L689
-  usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_TSDPS | USB_OTG_GUSBCFG_ULPIEVBUSD);
-  reset_core(usb_otg);
-
-  //   Core->Usb.ModeSelect = UTMI;
-  //   LOG_DEBUG("HCD: Interface: UTMI+.\n");
-  //   Core->Usb.PhyInterface = false;
-
-  //   HcdReset();
-  TU_LOG2("init phy\r\n");
-  usb_otg->GUSBCFG |= (1 << 4); // bit four sets UTMI+ mode
-  usb_otg->GUSBCFG &= ~(1 << 3); // bit three disables phy interface
-  reset_core(usb_otg);
-
-  //   LOG_DEBUG("HCD: ULPI FSLS configuration: disabled.\n");
-  //   Core->Usb.UlpiFsls = false;
-  //   Core->Usb.ulpi_clk_sus_m = false;
-  usb_otg->GUSBCFG &= ~(USB_OTG_GUSBCFG_ULPIFSLS | USB_OTG_GUSBCFG_ULPICSM);
-
-  // LOG_DEBUG("HCD: DMA configuration: enabled.\n");
-  // Core->Ahb.DmaEnable = true;
-  // Core->Ahb.DmaRemainderMode = Incremental;
-  usb_otg->GAHBCFG &= ~(1 << 23); // Remainder mode
-  usb_otg->GAHBCFG |= USB_OTG_GAHBCFG_DMAEN;
-
-  //   LOG_DEBUG("HCD: HNP/SRP configuration: HNP, SRP.\n");
-  //   Core->Usb.HnpCapable = true;
-  //   Core->Usb.SrpCapable = true;
-  usb_otg->GUSBCFG |= USB_OTG_GUSBCFG_SRPCAP | USB_OTG_GUSBCFG_HNPCAP;
-
-#endif
-
-  // Clear all interrupts
-  usb_otg->GINTSTS |= usb_otg->GINTSTS;
-
-  // Required as part of core initialization.
-  // TODO: How should mode mismatch be handled? It will cause
-  // the core to stop working/require reset.
-  usb_otg->GINTMSK |= USB_OTG_GINTMSK_OTGINT | USB_OTG_GINTMSK_MMISM;
-
-  USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport);
-
-  // If USB host misbehaves during status portion of control xfer
-  // (non zero-length packet), send STALL back and discard.
-  dev->DCFG |=  USB_OTG_DCFG_NZLSOHSK;
-
-  set_speed(rhport, TUSB_SPEED_HIGH);
-
-  // TODO internal phy (full speed)
-  usb_otg->GCCFG |= USB_OTG_GCCFG_PWRDWN;
-
-  usb_otg->GINTMSK |= USB_OTG_GINTMSK_USBRST   | USB_OTG_GINTMSK_ENUMDNEM |
-      USB_OTG_GINTMSK_USBSUSPM | USB_OTG_GINTMSK_WUIM     |
-      USB_OTG_GINTMSK_RXFLVLM  | (USE_SOF ? USB_OTG_GINTMSK_SOFM : 0);
-
-  // Enable global interrupt
-  usb_otg->GAHBCFG |= USB_OTG_GAHBCFG_GINT;
-
-  dcd_connect(rhport);
-}
-
-void dcd_int_enable (uint8_t rhport)
-{
-  (void) rhport;
-  BP_EnableIRQ(USB_IRQn);
-}
-
-void dcd_int_disable (uint8_t rhport)
-{
-  (void) rhport;
-  BP_DisableIRQ(USB_IRQn);
-}
-
-void dcd_set_address (uint8_t rhport, uint8_t dev_addr)
-{
-  USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport);
-  dev->DCFG = (dev->DCFG & ~USB_OTG_DCFG_DAD_Msk) | (dev_addr << USB_OTG_DCFG_DAD_Pos);
-
-  // Response with status after changing device address
-  dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0);
-}
-
-static void remote_wakeup_delay(void)
-{
-  // try to delay for 1 ms
-  uint32_t count = SystemCoreClock / 1000;
-  while ( count-- )
-  {
-    // __NOP();
-  }
-}
-
-void dcd_remote_wakeup(uint8_t rhport)
-{
-  (void) rhport;
-
-  USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport);
-  USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport);
-
-  // set remote wakeup
-  dev->DCTL |= USB_OTG_DCTL_RWUSIG;
-
-  // enable SOF to detect bus resume
-  usb_otg->GINTSTS = USB_OTG_GINTSTS_SOF;
-  usb_otg->GINTMSK |= USB_OTG_GINTMSK_SOFM;
-
-  // Per specs: remote wakeup signal bit must be clear within 1-15ms
-  remote_wakeup_delay();
-
-  dev->DCTL &= ~USB_OTG_DCTL_RWUSIG;
-}
-
-void dcd_connect(uint8_t rhport)
-{
-  (void) rhport;
-  USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport);
-  dev->DCTL &= ~USB_OTG_DCTL_SDIS;
-}
-
-void dcd_disconnect(uint8_t rhport)
-{
-  (void) rhport;
-  USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport);
-  dev->DCTL |= USB_OTG_DCTL_SDIS;
-}
-
-
-/*------------------------------------------------------------------*/
-/* DCD Endpoint port
- *------------------------------------------------------------------*/
-
-bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt)
-{
-  (void) rhport;
-
-  USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport);
-  USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport);
-  USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport);
-  USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport);
-
-  uint8_t const epnum = tu_edpt_number(desc_edpt->bEndpointAddress);
-  uint8_t const dir   = tu_edpt_dir(desc_edpt->bEndpointAddress);
-
-  TU_ASSERT(epnum < EP_MAX);
-
-  xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
-  xfer->max_size = tu_edpt_packet_size(desc_edpt);
-  xfer->interval = desc_edpt->bInterval;
-
-  uint16_t const fifo_size = (xfer->max_size + 3) / 4; // Round up to next full word
-
-  if(dir == TUSB_DIR_OUT)
-  {
-    // Calculate required size of RX FIFO
-    uint16_t const sz = calc_rx_ff_size(4*fifo_size);
-
-    // If size_rx needs to be extended check if possible and if so enlarge it
-    if (usb_otg->GRXFSIZ < sz)
-    {
-      TU_ASSERT(sz + _allocated_fifo_words_tx <= EP_FIFO_SIZE/4);
-
-      // Enlarge RX FIFO
-      usb_otg->GRXFSIZ = sz;
-    }
-
-    out_ep[epnum].DOEPCTL |= (1 << USB_OTG_DOEPCTL_USBAEP_Pos)        |
-        (desc_edpt->bmAttributes.xfer << USB_OTG_DOEPCTL_EPTYP_Pos)   |
-        (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? USB_OTG_DOEPCTL_SD0PID_SEVNFRM : 0) |
-        (xfer->max_size << USB_OTG_DOEPCTL_MPSIZ_Pos);
-
-    dev->DAINTMSK |= (1 << (USB_OTG_DAINTMSK_OEPM_Pos + epnum));
-  }
-  else
-  {
-    // "USB Data FIFOs" section in reference manual
-    // Peripheral FIFO architecture
-    //
-    // --------------- 320 or 1024 ( 1280 or 4096 bytes )
-    // | IN FIFO 0   |
-    // --------------- (320 or 1024) - 16
-    // | IN FIFO 1   |
-    // --------------- (320 or 1024) - 16 - x
-    // |   . . . .   |
-    // --------------- (320 or 1024) - 16 - x - y - ... - z
-    // | IN FIFO MAX |
-    // ---------------
-    // |    FREE     |
-    // --------------- GRXFSIZ
-    // | OUT FIFO    |
-    // | ( Shared )  |
-    // --------------- 0
-    //
-    // In FIFO is allocated by following rules:
-    // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n".
-
-    // Check if free space is available
-    TU_ASSERT(_allocated_fifo_words_tx + fifo_size + usb_otg->GRXFSIZ <= EP_FIFO_SIZE/4);
-
-    _allocated_fifo_words_tx += fifo_size;
-
-    TU_LOG(2, "    Allocated %u bytes at offset %u", fifo_size*4, EP_FIFO_SIZE-_allocated_fifo_words_tx*4);
-
-    // DIEPTXF starts at FIFO #1.
-    // Both TXFD and TXSA are in unit of 32-bit words.
-    usb_otg->DIEPTXF[epnum - 1] = (fifo_size << USB_OTG_DIEPTXF_INEPTXFD_Pos) | (EP_FIFO_SIZE/4 - _allocated_fifo_words_tx);
-
-    in_ep[epnum].DIEPCTL |= (1 << USB_OTG_DIEPCTL_USBAEP_Pos) |
-        (epnum << USB_OTG_DIEPCTL_TXFNUM_Pos) |
-        (desc_edpt->bmAttributes.xfer << USB_OTG_DIEPCTL_EPTYP_Pos) |
-        (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? USB_OTG_DIEPCTL_SD0PID_SEVNFRM : 0) |
-        (xfer->max_size << USB_OTG_DIEPCTL_MPSIZ_Pos);
-
-    dev->DAINTMSK |= (1 << (USB_OTG_DAINTMSK_IEPM_Pos + epnum));
-  }
-
-  return true;
-}
-
-// Close all non-control endpoints, cancel all pending transfers if any.
-void dcd_edpt_close_all (uint8_t rhport)
-{
-  (void) rhport;
-
-//  USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport);
-  USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport);
-  USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport);
-  USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport);
-
-  // Disable non-control interrupt
-  dev->DAINTMSK = (1 << USB_OTG_DAINTMSK_OEPM_Pos) | (1 << USB_OTG_DAINTMSK_IEPM_Pos);
-
-  for(uint8_t n = 1; n < EP_MAX; n++)
-  {
-    // disable OUT endpoint
-    out_ep[n].DOEPCTL = 0;
-    xfer_status[n][TUSB_DIR_OUT].max_size = 0;
-
-    // disable IN endpoint
-    in_ep[n].DIEPCTL = 0;
-    xfer_status[n][TUSB_DIR_IN].max_size = 0;
-  }
-
-  // reset allocated fifo IN
-  _allocated_fifo_words_tx = 16;
-}
-
-bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes)
-{
-  uint8_t const epnum = tu_edpt_number(ep_addr);
-  uint8_t const dir   = tu_edpt_dir(ep_addr);
-
-  xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
-  xfer->buffer      = buffer;
-  xfer->ff          = NULL;
-  xfer->total_len   = total_bytes;
-
-  // EP0 can only handle one packet
-  if(epnum == 0) {
-    ep0_pending[dir] = total_bytes;
-    // Schedule the first transaction for EP0 transfer
-    edpt_schedule_packets(rhport, epnum, dir, 1, ep0_pending[dir]);
-    return true;
-  }
-
-  uint16_t num_packets = (total_bytes / xfer->max_size);
-  uint16_t const short_packet_size = total_bytes % xfer->max_size;
-
-  // Zero-size packet is special case.
-  if(short_packet_size > 0 || (total_bytes == 0)) {
-    num_packets++;
-  }
-
-  // Schedule packets to be sent within interrupt
-  edpt_schedule_packets(rhport, epnum, dir, num_packets, total_bytes);
-
-  return true;
-}
-
-// The number of bytes has to be given explicitly to allow more flexible control of how many
-// bytes should be written and second to keep the return value free to give back a boolean
-// success message. If total_bytes is too big, the FIFO will copy only what is available
-// into the USB buffer!
-bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
-{
-  // USB buffers always work in bytes so to avoid unnecessary divisions we demand item_size = 1
-  TU_ASSERT(ff->item_size == 1);
-
-  uint8_t const epnum = tu_edpt_number(ep_addr);
-  uint8_t const dir   = tu_edpt_dir(ep_addr);
-
-  xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, dir);
-  xfer->buffer      = NULL;
-  xfer->ff          = ff;
-  xfer->total_len   = total_bytes;
-
-  uint16_t num_packets = (total_bytes / xfer->max_size);
-  uint16_t const short_packet_size = total_bytes % xfer->max_size;
-
-  // Zero-size packet is special case.
-  if(short_packet_size > 0 || (total_bytes == 0)) num_packets++;
-
-  // Schedule packets to be sent within interrupt
-  edpt_schedule_packets(rhport, epnum, dir, num_packets, total_bytes);
-
-  return true;
-}
-
-static void dcd_edpt_disable (uint8_t rhport, uint8_t ep_addr, bool stall)
-{
-  (void) rhport;
-
-  USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport);
-  USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport);
-  USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport);
-  USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport);
-
-  uint8_t const epnum = tu_edpt_number(ep_addr);
-  uint8_t const dir   = tu_edpt_dir(ep_addr);
-
-  if(dir == TUSB_DIR_IN) {
-    // Only disable currently enabled non-control endpoint
-    if ( (epnum == 0) || !(in_ep[epnum].DIEPCTL & USB_OTG_DIEPCTL_EPENA) ){
-      in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_SNAK | (stall ? USB_OTG_DIEPCTL_STALL : 0);
-    } else {
-      // Stop transmitting packets and NAK IN xfers.
-      in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_SNAK;
-      while((in_ep[epnum].DIEPINT & USB_OTG_DIEPINT_INEPNE) == 0);
-
-      // Disable the endpoint.
-      in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_EPDIS | (stall ? USB_OTG_DIEPCTL_STALL : 0);
-      while((in_ep[epnum].DIEPINT & USB_OTG_DIEPINT_EPDISD_Msk) == 0);
-      in_ep[epnum].DIEPINT = USB_OTG_DIEPINT_EPDISD;
-    }
-
-    // Flush the FIFO, and wait until we have confirmed it cleared.
-    usb_otg->GRSTCTL |= (epnum << USB_OTG_GRSTCTL_TXFNUM_Pos);
-    usb_otg->GRSTCTL |= USB_OTG_GRSTCTL_TXFFLSH;
-    while((usb_otg->GRSTCTL & USB_OTG_GRSTCTL_TXFFLSH_Msk) != 0);
-  } else {
-    // Only disable currently enabled non-control endpoint
-    if ( (epnum == 0) || !(out_ep[epnum].DOEPCTL & USB_OTG_DOEPCTL_EPENA) ){
-      out_ep[epnum].DOEPCTL |= stall ? USB_OTG_DOEPCTL_STALL : 0;
-    } else {
-      // Asserting GONAK is required to STALL an OUT endpoint.
-      // Simpler to use polling here, we don't use the "B"OUTNAKEFF interrupt
-      // anyway, and it can't be cleared by user code. If this while loop never
-      // finishes, we have bigger problems than just the stack.
-      dev->DCTL |= USB_OTG_DCTL_SGONAK;
-      while((usb_otg->GINTSTS & USB_OTG_GINTSTS_BOUTNAKEFF_Msk) == 0);
-
-      // Ditto here- disable the endpoint.
-      out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_EPDIS | (stall ? USB_OTG_DOEPCTL_STALL : 0);
-      while((out_ep[epnum].DOEPINT & USB_OTG_DOEPINT_EPDISD_Msk) == 0);
-      out_ep[epnum].DOEPINT = USB_OTG_DOEPINT_EPDISD;
-
-      // Allow other OUT endpoints to keep receiving.
-      dev->DCTL |= USB_OTG_DCTL_CGONAK;
-    }
-  }
-}
-
-/**
- * Close an endpoint.
- */
-void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr)
-{
-  USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport);
-
-  uint8_t const epnum = tu_edpt_number(ep_addr);
-  uint8_t const dir   = tu_edpt_dir(ep_addr);
-
-  dcd_edpt_disable(rhport, ep_addr, false);
-
-  // Update max_size
-  xfer_status[epnum][dir].max_size = 0;  // max_size = 0 marks a disabled EP - required for changing FIFO allocation
-
-  if (dir == TUSB_DIR_IN)
-  {
-    uint16_t const fifo_size = (usb_otg->DIEPTXF[epnum - 1] & USB_OTG_DIEPTXF_INEPTXFD_Msk) >> USB_OTG_DIEPTXF_INEPTXFD_Pos;
-    uint16_t const fifo_start = (usb_otg->DIEPTXF[epnum - 1] & USB_OTG_DIEPTXF_INEPTXSA_Msk) >> USB_OTG_DIEPTXF_INEPTXSA_Pos;
-    // For now only the last opened endpoint can be closed without fuss.
-    TU_ASSERT(fifo_start == EP_FIFO_SIZE/4 - _allocated_fifo_words_tx,);
-    _allocated_fifo_words_tx -= fifo_size;
-  }
-  else
-  {
-    _out_ep_closed = true;     // Set flag such that RX FIFO gets reduced in size once RX FIFO is empty
-  }
-}
-
-void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
-{
-  dcd_edpt_disable(rhport, ep_addr, true);
-}
-
-void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
-{
-  (void) rhport;
-
-  USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport);
-  USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport);
-
-  uint8_t const epnum = tu_edpt_number(ep_addr);
-  uint8_t const dir   = tu_edpt_dir(ep_addr);
-
-  // Clear stall and reset data toggle
-  if(dir == TUSB_DIR_IN) {
-    in_ep[epnum].DIEPCTL &= ~USB_OTG_DIEPCTL_STALL;
-    in_ep[epnum].DIEPCTL |= USB_OTG_DIEPCTL_SD0PID_SEVNFRM;
-  } else {
-    out_ep[epnum].DOEPCTL &= ~USB_OTG_DOEPCTL_STALL;
-    out_ep[epnum].DOEPCTL |= USB_OTG_DOEPCTL_SD0PID_SEVNFRM;
-  }
-}
-
-/*------------------------------------------------------------------*/
-
-// Read a single data packet from receive FIFO
-static void read_fifo_packet(uint8_t rhport, uint8_t * dst, uint16_t len)
-{
-  (void) rhport;
-
-  usb_fifo_t rx_fifo = FIFO_BASE(rhport, 0);
-
-  // Reading full available 32 bit words from fifo
-  uint16_t full_words = len >> 2;
-  for(uint16_t i = 0; i < full_words; i++) {
-    uint32_t tmp = *rx_fifo;
-    dst[0] = tmp & 0x000000FF;
-    dst[1] = (tmp & 0x0000FF00) >> 8;
-    dst[2] = (tmp & 0x00FF0000) >> 16;
-    dst[3] = (tmp & 0xFF000000) >> 24;
-    dst += 4;
-  }
-
-  // Read the remaining 1-3 bytes from fifo
-  uint8_t bytes_rem = len & 0x03;
-  if(bytes_rem != 0) {
-    uint32_t tmp = *rx_fifo;
-    dst[0] = tmp & 0x000000FF;
-    if(bytes_rem > 1) {
-      dst[1] = (tmp & 0x0000FF00) >> 8;
-    }
-    if(bytes_rem > 2) {
-      dst[2] = (tmp & 0x00FF0000) >> 16;
-    }
-  }
-}
-
-// Write a single data packet to EPIN FIFO
-static void write_fifo_packet(uint8_t rhport, uint8_t fifo_num, uint8_t * src, uint16_t len)
-{
-  (void) rhport;
-
-  usb_fifo_t tx_fifo = FIFO_BASE(rhport, fifo_num);
-
-  // Pushing full available 32 bit words to fifo
-  uint16_t full_words = len >> 2;
-  for(uint16_t i = 0; i < full_words; i++){
-    *tx_fifo = (src[3] << 24) | (src[2] << 16) | (src[1] << 8) | src[0];
-    src += 4;
-  }
-
-  // Write the remaining 1-3 bytes into fifo
-  uint8_t bytes_rem = len & 0x03;
-  if(bytes_rem){
-    uint32_t tmp_word = 0;
-    tmp_word |= src[0];
-    if(bytes_rem > 1){
-      tmp_word |= src[1] << 8;
-    }
-    if(bytes_rem > 2){
-      tmp_word |= src[2] << 16;
-    }
-    *tx_fifo = tmp_word;
-  }
-}
-
-static void handle_rxflvl_ints(uint8_t rhport, USB_OTG_OUTEndpointTypeDef * out_ep) {
-  USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport);
-  usb_fifo_t rx_fifo = FIFO_BASE(rhport, 0);
-
-  // Pop control word off FIFO
-  uint32_t ctl_word = usb_otg->GRXSTSP;
-  uint8_t pktsts = (ctl_word & USB_OTG_GRXSTSP_PKTSTS_Msk) >> USB_OTG_GRXSTSP_PKTSTS_Pos;
-  uint8_t epnum = (ctl_word &  USB_OTG_GRXSTSP_EPNUM_Msk) >>  USB_OTG_GRXSTSP_EPNUM_Pos;
-  uint16_t bcnt = (ctl_word & USB_OTG_GRXSTSP_BCNT_Msk) >> USB_OTG_GRXSTSP_BCNT_Pos;
-
-  switch(pktsts) {
-    case 0x01: // Global OUT NAK (Interrupt)
-      break;
-
-    case 0x02: // Out packet recvd
-    {
-      xfer_ctl_t * xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT);
-
-      // Read packet off RxFIFO
-      if (xfer->ff)
-      {
-        // Ring buffer
-        tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void *)(uintptr_t) rx_fifo, bcnt);
-      }
-      else
-      {
-        // Linear buffer
-        read_fifo_packet(rhport, xfer->buffer, bcnt);
-
-        // Increment pointer to xfer data
-        xfer->buffer += bcnt;
-      }
-
-      // Truncate transfer length in case of short packet
-      if(bcnt < xfer->max_size) {
-        xfer->total_len -= (out_ep[epnum].DOEPTSIZ & USB_OTG_DOEPTSIZ_XFRSIZ_Msk) >> USB_OTG_DOEPTSIZ_XFRSIZ_Pos;
-        if(epnum == 0) {
-          xfer->total_len -= ep0_pending[TUSB_DIR_OUT];
-          ep0_pending[TUSB_DIR_OUT] = 0;
-        }
-      }
-    }
-    break;
-
-    case 0x03: // Out packet done (Interrupt)
-      break;
-
-    case 0x04: // Setup packet done (Interrupt)
-      out_ep[epnum].DOEPTSIZ |= (3 << USB_OTG_DOEPTSIZ_STUPCNT_Pos);
-      break;
-
-    case 0x06: // Setup packet recvd
-      // We can receive up to three setup packets in succession, but
-      // only the last one is valid.
-      _setup_packet[0] = (* rx_fifo);
-      _setup_packet[1] = (* rx_fifo);
-      break;
-
-    default: // Invalid
-      TU_BREAKPOINT();
-      break;
-  }
-}
-
-static void handle_epout_ints(uint8_t rhport, USB_OTG_DeviceTypeDef * dev, USB_OTG_OUTEndpointTypeDef * out_ep) {
-  // DAINT for a given EP clears when DOEPINTx is cleared.
-  // OEPINT will be cleared when DAINT's out bits are cleared.
-  for(uint8_t n = 0; n < EP_MAX; n++) {
-    xfer_ctl_t * xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT);
-
-    if(dev->DAINT & (1 << (USB_OTG_DAINT_OEPINT_Pos + n))) {
-      // SETUP packet Setup Phase done.
-      if(out_ep[n].DOEPINT & USB_OTG_DOEPINT_STUP) {
-        out_ep[n].DOEPINT =  USB_OTG_DOEPINT_STUP;
-        dcd_event_setup_received(rhport, (uint8_t*) &_setup_packet[0], true);
-      }
-
-      // OUT XFER complete
-      if(out_ep[n].DOEPINT & USB_OTG_DOEPINT_XFRC) {
-        out_ep[n].DOEPINT = USB_OTG_DOEPINT_XFRC;
-
-        // EP0 can only handle one packet
-        if((n == 0) && ep0_pending[TUSB_DIR_OUT]) {
-          // Schedule another packet to be received.
-          edpt_schedule_packets(rhport, n, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]);
-        } else {
-          dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true);
-        }
-      }
-    }
-  }
-}
-
-static void handle_epin_ints(uint8_t rhport, USB_OTG_DeviceTypeDef * dev, USB_OTG_INEndpointTypeDef * in_ep) {
-  // DAINT for a given EP clears when DIEPINTx is cleared.
-  // IEPINT will be cleared when DAINT's out bits are cleared.
-  for ( uint8_t n = 0; n < EP_MAX; n++ )
-  {
-    xfer_ctl_t *xfer = XFER_CTL_BASE(n, TUSB_DIR_IN);
-
-    if ( dev->DAINT & (1 << (USB_OTG_DAINT_IEPINT_Pos + n)) )
-    {
-      // IN XFER complete (entire xfer).
-      if ( in_ep[n].DIEPINT & USB_OTG_DIEPINT_XFRC )
-      {
-        in_ep[n].DIEPINT = USB_OTG_DIEPINT_XFRC;
-
-        // EP0 can only handle one packet
-        if((n == 0) && ep0_pending[TUSB_DIR_IN]) {
-          // Schedule another packet to be transmitted.
-          edpt_schedule_packets(rhport, n, TUSB_DIR_IN, 1, ep0_pending[TUSB_DIR_IN]);
-        } else {
-          dcd_event_xfer_complete(rhport, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true);
-        }
-      }
-
-      // XFER FIFO empty
-      if ( (in_ep[n].DIEPINT & USB_OTG_DIEPINT_TXFE) && (dev->DIEPEMPMSK & (1 << n)) )
-      {
-        // DIEPINT's TXFE bit is read-only, software cannot clear it.
-        // It will only be cleared by hardware when written bytes is more than
-        // - 64 bytes or
-        // - Half of TX FIFO size (configured by DIEPTXF)
-
-        uint16_t remaining_packets = (in_ep[n].DIEPTSIZ & USB_OTG_DIEPTSIZ_PKTCNT_Msk) >> USB_OTG_DIEPTSIZ_PKTCNT_Pos;
-
-        // Process every single packet (only whole packets can be written to fifo)
-        for(uint16_t i = 0; i < remaining_packets; i++)
-        {
-          uint16_t const remaining_bytes = (in_ep[n].DIEPTSIZ & USB_OTG_DIEPTSIZ_XFRSIZ_Msk) >> USB_OTG_DIEPTSIZ_XFRSIZ_Pos;
-
-          // Packet can not be larger than ep max size
-          uint16_t const packet_size = tu_min16(remaining_bytes, xfer->max_size);
-
-          // It's only possible to write full packets into FIFO. Therefore DTXFSTS register of current
-          // EP has to be checked if the buffer can take another WHOLE packet
-          if(packet_size > ((in_ep[n].DTXFSTS & USB_OTG_DTXFSTS_INEPTFSAV_Msk) << 2)) break;
-
-          // Push packet to Tx-FIFO
-          if (xfer->ff)
-          {
-            usb_fifo_t tx_fifo = FIFO_BASE(rhport, n);
-            tu_fifo_read_n_const_addr_full_words(xfer->ff, (void *)(uintptr_t) tx_fifo, packet_size);
-          }
-          else
-          {
-            write_fifo_packet(rhport, n, xfer->buffer, packet_size);
-
-            // Increment pointer to xfer data
-            xfer->buffer += packet_size;
-          }
-        }
-
-        // Turn off TXFE if all bytes are written.
-        if (((in_ep[n].DIEPTSIZ & USB_OTG_DIEPTSIZ_XFRSIZ_Msk) >> USB_OTG_DIEPTSIZ_XFRSIZ_Pos) == 0)
-        {
-          dev->DIEPEMPMSK &= ~(1 << n);
-        }
-      }
-    }
-  }
-}
-
-void dcd_int_handler(uint8_t rhport)
-{
-  USB_OTG_GlobalTypeDef * usb_otg = GLOBAL_BASE(rhport);
-  USB_OTG_DeviceTypeDef * dev = DEVICE_BASE(rhport);
-  USB_OTG_OUTEndpointTypeDef * out_ep = OUT_EP_BASE(rhport);
-  USB_OTG_INEndpointTypeDef * in_ep = IN_EP_BASE(rhport);
-
-  uint32_t const int_status = usb_otg->GINTSTS & usb_otg->GINTMSK;
-
-  if(int_status & USB_OTG_GINTSTS_USBRST)
-  {
-    // USBRST is start of reset.
-    usb_otg->GINTSTS = USB_OTG_GINTSTS_USBRST;
-    bus_reset(rhport);
-  }
-
-  if(int_status & USB_OTG_GINTSTS_ENUMDNE)
-  {
-    // ENUMDNE is the end of reset where speed of the link is detected
-
-    usb_otg->GINTSTS = USB_OTG_GINTSTS_ENUMDNE;
-
-    tusb_speed_t const speed = get_speed(rhport);
-
-    set_turnaround(usb_otg, speed);
-    dcd_event_bus_reset(rhport, speed, true);
-  }
-
-  if(int_status & USB_OTG_GINTSTS_USBSUSP)
-  {
-    usb_otg->GINTSTS = USB_OTG_GINTSTS_USBSUSP;
-    dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true);
-  }
-
-  if(int_status & USB_OTG_GINTSTS_WKUINT)
-  {
-    usb_otg->GINTSTS = USB_OTG_GINTSTS_WKUINT;
-    dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true);
-  }
-
-  // TODO check USB_OTG_GINTSTS_DISCINT for disconnect detection
-  // if(int_status & USB_OTG_GINTSTS_DISCINT)
-
-  if(int_status & USB_OTG_GINTSTS_OTGINT)
-  {
-    // OTG INT bit is read-only
-    uint32_t const otg_int = usb_otg->GOTGINT;
-
-    if (otg_int & USB_OTG_GOTGINT_SEDET)
-    {
-      dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true);
-    }
-
-    usb_otg->GOTGINT = otg_int;
-  }
-
-  if(int_status & USB_OTG_GINTSTS_SOF)
-  {
-    usb_otg->GINTSTS = USB_OTG_GINTSTS_SOF;
-
-    // Disable SOF interrupt since currently only used for remote wakeup detection
-    usb_otg->GINTMSK &= ~USB_OTG_GINTMSK_SOFM;
-
-    dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true);
-  }
-
-  // RxFIFO non-empty interrupt handling.
-  if(int_status & USB_OTG_GINTSTS_RXFLVL)
-  {
-    // RXFLVL bit is read-only
-
-    // Mask out RXFLVL while reading data from FIFO
-    usb_otg->GINTMSK &= ~USB_OTG_GINTMSK_RXFLVLM;
-
-    // Loop until all available packets were handled
-    do
-    {
-      handle_rxflvl_ints(rhport, out_ep);
-    } while(usb_otg->GINTSTS & USB_OTG_GINTSTS_RXFLVL);
-
-    // Manage RX FIFO size
-    if (_out_ep_closed)
-    {
-      update_grxfsiz(rhport);
-
-      // Disable flag
-      _out_ep_closed = false;
-    }
-
-    usb_otg->GINTMSK |= USB_OTG_GINTMSK_RXFLVLM;
-  }
-
-  // OUT endpoint interrupt handling.
-  if(int_status & USB_OTG_GINTSTS_OEPINT)
-  {
-    // OEPINT is read-only
-    handle_epout_ints(rhport, dev, out_ep);
-  }
-
-  // IN endpoint interrupt handling.
-  if(int_status & USB_OTG_GINTSTS_IEPINT)
-  {
-    // IEPINT bit read-only
-    handle_epin_ints(rhport, dev, in_ep);
-  }
-
-  //  // Check for Incomplete isochronous IN transfer
-  //  if(int_status & USB_OTG_GINTSTS_IISOIXFR) {
-  //    printf("      IISOIXFR!\r\n");
-  ////    TU_LOG2("      IISOIXFR!\r\n");
-  //  }
-}
-
-#endif

+ 0 - 1476
src/portable/broadcom/synopsys/synopsys_common.h

@@ -1,1476 +0,0 @@
-/**
-  ******************************************************************************
-  * @file    synopsys_common.h
-  * @author  MCD Application Team
-  * @brief   CMSIS Cortex-M3 Device USB OTG peripheral Header File. 
-  *          This file contains the USB OTG peripheral register's definitions, bits 
-  *          definitions and memory mapping for STM32F1xx devices.
-  *            
-  *          This file contains:
-  *           - Data structures and the address mapping for the USB OTG peripheral
-  *           - The Peripheral's registers declarations and bits definition
-  *           - Macros to access the peripheral's registers hardware
-  *  
-  ******************************************************************************
-  * @attention
-  *
-  * <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
-  * All rights reserved.</center></h2>
-  *
-  * This software component is licensed by ST under BSD 3-Clause license,
-  * the "License"; You may not use this file except in compliance with the
-  * License. You may obtain a copy of the License at:
-  *                        opensource.org/licenses/BSD-3-Clause
-  *
-  ******************************************************************************
-  */
-
-#include "stdint.h"
-
-#pragma once
-
-#ifdef __cplusplus
-  #define   __I   volatile
-#else
-  #define   __I   volatile const
-#endif
-#define     __O   volatile
-#define     __IO  volatile
-#define     __IM  volatile const
-#define     __OM  volatile
-#define     __IOM volatile
-
-/** 
-  * @brief __USB_OTG_Core_register
-  */
-
-typedef struct
-{
-  __IO uint32_t GOTGCTL;              /*!<  USB_OTG Control and Status Register       Address offset: 000h */
-  __IO uint32_t GOTGINT;              /*!<  USB_OTG Interrupt Register                Address offset: 004h */
-  __IO uint32_t GAHBCFG;              /*!<  Core AHB Configuration Register           Address offset: 008h */
-  __IO uint32_t GUSBCFG;              /*!<  Core USB Configuration Register           Address offset: 00Ch */
-  __IO uint32_t GRSTCTL;              /*!<  Core Reset Register                       Address offset: 010h */
-  __IO uint32_t GINTSTS;              /*!<  Core Interrupt Register                   Address offset: 014h */
-  __IO uint32_t GINTMSK;              /*!<  Core Interrupt Mask Register              Address offset: 018h */
-  __IO uint32_t GRXSTSR;              /*!<  Receive Sts Q Read Register               Address offset: 01Ch */
-  __IO uint32_t GRXSTSP;              /*!<  Receive Sts Q Read & POP Register         Address offset: 020h */
-  __IO uint32_t GRXFSIZ;              /*!< Receive FIFO Size Register                 Address offset: 024h */
-  __IO uint32_t DIEPTXF0_HNPTXFSIZ;   /*!<  EP0 / Non Periodic Tx FIFO Size Register  Address offset: 028h */
-  __IO uint32_t HNPTXSTS;             /*!<  Non Periodic Tx FIFO/Queue Sts reg        Address offset: 02Ch */
-  uint32_t Reserved30[2];             /*!< Reserved 030h*/
-  __IO uint32_t GCCFG;                /*!< General Purpose IO Register                Address offset: 038h */
-  __IO uint32_t CID;                  /*!< User ID Register                             03Ch */
-  __IO uint32_t GSNPSID;              /* USB_OTG core ID                                040h*/
-  __IO uint32_t GHWCFG1;              /* User HW config1                                044h*/
-  __IO uint32_t GHWCFG2;              /* User HW config2                                048h*/
-  __IO uint32_t GHWCFG3;              /*!< User HW config3                              04Ch */
-  uint32_t  Reserved6;                /*!< Reserved                                     050h */
-  __IO uint32_t GLPMCFG;              /*!< LPM Register                                 054h */
-  __IO uint32_t GPWRDN;               /*!< Power Down Register                          058h */
-  __IO uint32_t GDFIFOCFG;            /*!< DFIFO Software Config Register               05Ch */
-   __IO uint32_t GADPCTL;             /*!< ADP Timer, Control and Status Register       60Ch */
-    uint32_t  Reserved43[39];         /*!< Reserved                                058h-0FFh */
-  __IO uint32_t HPTXFSIZ;             /*!< Host Periodic Tx FIFO Size Reg             Address offset: 100h */
-  __IO uint32_t DIEPTXF[0x0F];        /*!< dev Periodic Transmit FIFO                 Address offset: 0x104 */
-} USB_OTG_GlobalTypeDef;
-
-
-
-/** 
-  * @brief __device_Registers
-  */
-
-typedef struct 
-{
-  __IO uint32_t DCFG;                 /*!< dev Configuration Register                 Address offset: 800h*/
-  __IO uint32_t DCTL;                 /*!< dev Control Register                       Address offset: 804h*/
-  __IO uint32_t DSTS;                 /*!< dev Status Register (RO)                   Address offset: 808h*/
-  uint32_t Reserved0C;                /*!< Reserved 80Ch*/
-  __IO uint32_t DIEPMSK;              /*!< dev IN Endpoint Mask                       Address offset: 810h*/
-  __IO uint32_t DOEPMSK;              /*!< dev OUT Endpoint Mask                      Address offset: 814h*/
-  __IO uint32_t DAINT;                /*!< dev All Endpoints Itr Reg                  Address offset: 818h*/
-  __IO uint32_t DAINTMSK;             /*!< dev All Endpoints Itr Mask                 Address offset: 81Ch*/
-  uint32_t  Reserved20;               /*!< Reserved 820h*/
-  uint32_t Reserved9;                 /*!< Reserved 824h*/
-  __IO uint32_t DVBUSDIS;             /*!< dev VBUS discharge Register                Address offset: 828h*/
-  __IO uint32_t DVBUSPULSE;           /*!< dev VBUS Pulse Register                    Address offset: 82Ch*/
-  __IO uint32_t DTHRCTL;              /*!< dev thr                                    Address offset: 830h*/
-  __IO uint32_t DIEPEMPMSK;           /*!< dev empty msk                              Address offset: 834h*/
-  __IO uint32_t DEACHINT;             /*!< dedicated EP interrupt                     Address offset: 838h*/
-  __IO uint32_t DEACHMSK;             /*!< dedicated EP msk                           Address offset: 83Ch*/  
-  uint32_t Reserved40;                /*!< dedicated EP mask                          Address offset: 840h*/
-  __IO uint32_t DINEP1MSK;            /*!< dedicated EP mask                          Address offset: 844h*/
-  uint32_t  Reserved44[15];           /*!< Reserved 844-87Ch*/
-  __IO uint32_t DOUTEP1MSK;           /*!< dedicated EP msk                           Address offset: 884h*/
-} USB_OTG_DeviceTypeDef;
-
-/** 
-  * @brief __IN_Endpoint-Specific_Register
-  */
-
-typedef struct 
-{
-  __IO uint32_t DIEPCTL;              /*!< dev IN Endpoint Control Reg                900h + (ep_num * 20h) + 00h*/
-  uint32_t Reserved04;                /*!< Reserved                                   900h + (ep_num * 20h) + 04h*/
-  __IO uint32_t DIEPINT;              /*!< dev IN Endpoint Itr Reg                    900h + (ep_num * 20h) + 08h*/
-  uint32_t Reserved0C;                /*!< Reserved                                   900h + (ep_num * 20h) + 0Ch*/
-  __IO uint32_t DIEPTSIZ;             /*!< IN Endpoint Txfer Size                     900h + (ep_num * 20h) + 10h*/
-  __IO uint32_t DIEPDMA;              /*!< IN Endpoint DMA Address Reg                900h + (ep_num * 20h) + 14h*/
-  __IO uint32_t DTXFSTS;              /*!< IN Endpoint Tx FIFO Status Reg             900h + (ep_num * 20h) + 18h*/
-  uint32_t Reserved18;                /*!< Reserved                                   900h+(ep_num*20h)+1Ch-900h+ (ep_num * 20h) + 1Ch*/
-} USB_OTG_INEndpointTypeDef;
-
-/** 
-  * @brief __OUT_Endpoint-Specific_Registers
-  */
-
-typedef struct 
-{
-  __IO uint32_t DOEPCTL;              /*!< dev OUT Endpoint Control Reg               B00h + (ep_num * 20h) + 00h*/
-  uint32_t Reserved04;                /*!< Reserved                                   B00h + (ep_num * 20h) + 04h*/
-  __IO uint32_t DOEPINT;              /*!< dev OUT Endpoint Itr Reg                   B00h + (ep_num * 20h) + 08h*/
-  uint32_t Reserved0C;                /*!< Reserved                                   B00h + (ep_num * 20h) + 0Ch*/
-  __IO uint32_t DOEPTSIZ;             /*!< dev OUT Endpoint Txfer Size                B00h + (ep_num * 20h) + 10h*/
-  __IO uint32_t DOEPDMA;              /*!< dev OUT Endpoint DMA Address               B00h + (ep_num * 20h) + 14h*/
-  uint32_t Reserved18[2];             /*!< Reserved                                   B00h + (ep_num * 20h) + 18h - B00h + (ep_num * 20h) + 1Ch*/
-} USB_OTG_OUTEndpointTypeDef;
-
-/** 
-  * @brief __Host_Mode_Register_Structures
-  */
-
-typedef struct 
-{
-  __IO uint32_t HCFG;                 /*!< Host Configuration Register    400h*/
-  __IO uint32_t HFIR;                 /*!< Host Frame Interval Register   404h*/
-  __IO uint32_t HFNUM;                /*!< Host Frame Nbr/Frame Remaining 408h*/
-  uint32_t Reserved40C;               /*!< Reserved                       40Ch*/
-  __IO uint32_t HPTXSTS;              /*!< Host Periodic Tx FIFO/ Queue Status 410h*/
-  __IO uint32_t HAINT;                /*!< Host All Channels Interrupt Register 414h*/
-  __IO uint32_t HAINTMSK;             /*!< Host All Channels Interrupt Mask 418h*/
-} USB_OTG_HostTypeDef;
-
-/** 
-  * @brief __Host_Channel_Specific_Registers
-  */
-
-typedef struct
-{
-  __IO uint32_t HCCHAR;
-  __IO uint32_t HCSPLT;
-  __IO uint32_t HCINT;
-  __IO uint32_t HCINTMSK;
-  __IO uint32_t HCTSIZ;
-  __IO uint32_t HCDMA;
-  uint32_t Reserved[2];
-} USB_OTG_HostChannelTypeDef;
-
-/*!< USB registers base address */
-#define USB_OTG_FS_PERIPH_BASE               0x50000000UL
-
-// #define USB_OTG_GLOBAL_BASE                  0x00000000UL
-// #define USB_OTG_DEVICE_BASE                  0x00000800UL
-#define USB_OTG_IN_ENDPOINT_BASE             0x00000900UL
-#define USB_OTG_OUT_ENDPOINT_BASE            0x00000B00UL
-#define USB_OTG_EP_REG_SIZE                  0x00000020UL
-// #define USB_OTG_HOST_BASE                    0x00000400UL
-#define USB_OTG_HOST_PORT_BASE               0x00000440UL
-#define USB_OTG_HOST_CHANNEL_BASE            0x00000500UL
-#define USB_OTG_HOST_CHANNEL_SIZE            0x00000020UL
-#define USB_OTG_PCGCCTL_BASE                 0x00000E00UL
-#define USB_OTG_FIFO_BASE                    0x00001000UL
-#define USB_OTG_FIFO_SIZE                    0x00001000UL
-
-/******************************************************************************/
-/*                                                                            */
-/*                                 USB_OTG                                    */
-/*                                                                            */
-/******************************************************************************/
-/********************  Bit definition for USB_OTG_GOTGCTL register  ***********/
-#define USB_OTG_GOTGCTL_SRQSCS_Pos              (0U)                           
-#define USB_OTG_GOTGCTL_SRQSCS_Msk              (0x1UL << USB_OTG_GOTGCTL_SRQSCS_Pos) /*!< 0x00000001 */
-#define USB_OTG_GOTGCTL_SRQSCS                  USB_OTG_GOTGCTL_SRQSCS_Msk     /*!< Session request success */
-#define USB_OTG_GOTGCTL_SRQ_Pos                 (1U)                           
-#define USB_OTG_GOTGCTL_SRQ_Msk                 (0x1UL << USB_OTG_GOTGCTL_SRQ_Pos) /*!< 0x00000002 */
-#define USB_OTG_GOTGCTL_SRQ                     USB_OTG_GOTGCTL_SRQ_Msk        /*!< Session request */
-#define USB_OTG_GOTGCTL_HNGSCS_Pos              (8U)                           
-#define USB_OTG_GOTGCTL_HNGSCS_Msk              (0x1UL << USB_OTG_GOTGCTL_HNGSCS_Pos) /*!< 0x00000100 */
-#define USB_OTG_GOTGCTL_HNGSCS                   USB_OTG_GOTGCTL_HNGSCS_Msk    /*!< Host set HNP enable */
-#define USB_OTG_GOTGCTL_HNPRQ_Pos               (9U)                           
-#define USB_OTG_GOTGCTL_HNPRQ_Msk               (0x1UL << USB_OTG_GOTGCTL_HNPRQ_Pos) /*!< 0x00000200 */
-#define USB_OTG_GOTGCTL_HNPRQ                   USB_OTG_GOTGCTL_HNPRQ_Msk      /*!< HNP request */
-#define USB_OTG_GOTGCTL_HSHNPEN_Pos             (10U)                          
-#define USB_OTG_GOTGCTL_HSHNPEN_Msk             (0x1UL << USB_OTG_GOTGCTL_HSHNPEN_Pos) /*!< 0x00000400 */
-#define USB_OTG_GOTGCTL_HSHNPEN                 USB_OTG_GOTGCTL_HSHNPEN_Msk    /*!< Host set HNP enable */
-#define USB_OTG_GOTGCTL_DHNPEN_Pos              (11U)                          
-#define USB_OTG_GOTGCTL_DHNPEN_Msk              (0x1UL << USB_OTG_GOTGCTL_DHNPEN_Pos) /*!< 0x00000800 */
-#define USB_OTG_GOTGCTL_DHNPEN                  USB_OTG_GOTGCTL_DHNPEN_Msk     /*!< Device HNP enabled */
-#define USB_OTG_GOTGCTL_CIDSTS_Pos              (16U)                          
-#define USB_OTG_GOTGCTL_CIDSTS_Msk              (0x1UL << USB_OTG_GOTGCTL_CIDSTS_Pos) /*!< 0x00010000 */
-#define USB_OTG_GOTGCTL_CIDSTS                  USB_OTG_GOTGCTL_CIDSTS_Msk     /*!< Connector ID status */
-#define USB_OTG_GOTGCTL_DBCT_Pos                (17U)                          
-#define USB_OTG_GOTGCTL_DBCT_Msk                (0x1UL << USB_OTG_GOTGCTL_DBCT_Pos) /*!< 0x00020000 */
-#define USB_OTG_GOTGCTL_DBCT                    USB_OTG_GOTGCTL_DBCT_Msk       /*!< Long/short debounce time */
-#define USB_OTG_GOTGCTL_ASVLD_Pos               (18U)                          
-#define USB_OTG_GOTGCTL_ASVLD_Msk               (0x1UL << USB_OTG_GOTGCTL_ASVLD_Pos) /*!< 0x00040000 */
-#define USB_OTG_GOTGCTL_ASVLD                   USB_OTG_GOTGCTL_ASVLD_Msk      /*!< A-session valid */
-#define USB_OTG_GOTGCTL_BSVLD_Pos               (19U)                          
-#define USB_OTG_GOTGCTL_BSVLD_Msk               (0x1UL << USB_OTG_GOTGCTL_BSVLD_Pos) /*!< 0x00080000 */
-#define USB_OTG_GOTGCTL_BSVLD                   USB_OTG_GOTGCTL_BSVLD_Msk      /*!< B-session valid */
-
-/********************  Bit definition for USB_OTG_HCFG register  ********************/
-
-#define USB_OTG_HCFG_FSLSPCS_Pos                (0U)                           
-#define USB_OTG_HCFG_FSLSPCS_Msk                (0x3UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000003 */
-#define USB_OTG_HCFG_FSLSPCS                    USB_OTG_HCFG_FSLSPCS_Msk       /*!< FS/LS PHY clock select */
-#define USB_OTG_HCFG_FSLSPCS_0                  (0x1UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000001 */
-#define USB_OTG_HCFG_FSLSPCS_1                  (0x2UL << USB_OTG_HCFG_FSLSPCS_Pos) /*!< 0x00000002 */
-#define USB_OTG_HCFG_FSLSS_Pos                  (2U)                           
-#define USB_OTG_HCFG_FSLSS_Msk                  (0x1UL << USB_OTG_HCFG_FSLSS_Pos) /*!< 0x00000004 */
-#define USB_OTG_HCFG_FSLSS                      USB_OTG_HCFG_FSLSS_Msk         /*!< FS- and LS-only support */
-
-/********************  Bit definition for USB_OTG_DCFG register  ********************/
-
-#define USB_OTG_DCFG_DSPD_Pos                   (0U)                           
-#define USB_OTG_DCFG_DSPD_Msk                   (0x3UL << USB_OTG_DCFG_DSPD_Pos) /*!< 0x00000003 */
-#define USB_OTG_DCFG_DSPD                       USB_OTG_DCFG_DSPD_Msk          /*!< Device speed */
-#define USB_OTG_DCFG_DSPD_0                     (0x1UL << USB_OTG_DCFG_DSPD_Pos) /*!< 0x00000001 */
-#define USB_OTG_DCFG_DSPD_1                     (0x2UL << USB_OTG_DCFG_DSPD_Pos) /*!< 0x00000002 */
-#define USB_OTG_DCFG_NZLSOHSK_Pos               (2U)                           
-#define USB_OTG_DCFG_NZLSOHSK_Msk               (0x1UL << USB_OTG_DCFG_NZLSOHSK_Pos) /*!< 0x00000004 */
-#define USB_OTG_DCFG_NZLSOHSK                   USB_OTG_DCFG_NZLSOHSK_Msk      /*!< Nonzero-length status OUT handshake */
-
-#define USB_OTG_DCFG_DAD_Pos                    (4U)                           
-#define USB_OTG_DCFG_DAD_Msk                    (0x7FUL << USB_OTG_DCFG_DAD_Pos) /*!< 0x000007F0 */
-#define USB_OTG_DCFG_DAD                        USB_OTG_DCFG_DAD_Msk           /*!< Device address */
-#define USB_OTG_DCFG_DAD_0                      (0x01UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000010 */
-#define USB_OTG_DCFG_DAD_1                      (0x02UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000020 */
-#define USB_OTG_DCFG_DAD_2                      (0x04UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000040 */
-#define USB_OTG_DCFG_DAD_3                      (0x08UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000080 */
-#define USB_OTG_DCFG_DAD_4                      (0x10UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000100 */
-#define USB_OTG_DCFG_DAD_5                      (0x20UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000200 */
-#define USB_OTG_DCFG_DAD_6                      (0x40UL << USB_OTG_DCFG_DAD_Pos) /*!< 0x00000400 */
-
-#define USB_OTG_DCFG_PFIVL_Pos                  (11U)                          
-#define USB_OTG_DCFG_PFIVL_Msk                  (0x3UL << USB_OTG_DCFG_PFIVL_Pos) /*!< 0x00001800 */
-#define USB_OTG_DCFG_PFIVL                      USB_OTG_DCFG_PFIVL_Msk         /*!< Periodic (micro)frame interval */
-#define USB_OTG_DCFG_PFIVL_0                    (0x1UL << USB_OTG_DCFG_PFIVL_Pos) /*!< 0x00000800 */
-#define USB_OTG_DCFG_PFIVL_1                    (0x2UL << USB_OTG_DCFG_PFIVL_Pos) /*!< 0x00001000 */
-
-#define USB_OTG_DCFG_PERSCHIVL_Pos              (24U)                          
-#define USB_OTG_DCFG_PERSCHIVL_Msk              (0x3UL << USB_OTG_DCFG_PERSCHIVL_Pos) /*!< 0x03000000 */
-#define USB_OTG_DCFG_PERSCHIVL                  USB_OTG_DCFG_PERSCHIVL_Msk     /*!< Periodic scheduling interval */
-#define USB_OTG_DCFG_PERSCHIVL_0                (0x1UL << USB_OTG_DCFG_PERSCHIVL_Pos) /*!< 0x01000000 */
-#define USB_OTG_DCFG_PERSCHIVL_1                (0x2UL << USB_OTG_DCFG_PERSCHIVL_Pos) /*!< 0x02000000 */
-
-/********************  Bit definition for USB_OTG_PCGCR register  ********************/
-#define USB_OTG_PCGCR_STPPCLK_Pos               (0U)                           
-#define USB_OTG_PCGCR_STPPCLK_Msk               (0x1UL << USB_OTG_PCGCR_STPPCLK_Pos) /*!< 0x00000001 */
-#define USB_OTG_PCGCR_STPPCLK                   USB_OTG_PCGCR_STPPCLK_Msk      /*!< Stop PHY clock */
-#define USB_OTG_PCGCR_GATEHCLK_Pos              (1U)                           
-#define USB_OTG_PCGCR_GATEHCLK_Msk              (0x1UL << USB_OTG_PCGCR_GATEHCLK_Pos) /*!< 0x00000002 */
-#define USB_OTG_PCGCR_GATEHCLK                  USB_OTG_PCGCR_GATEHCLK_Msk     /*!< Gate HCLK */
-#define USB_OTG_PCGCR_PHYSUSP_Pos               (4U)                           
-#define USB_OTG_PCGCR_PHYSUSP_Msk               (0x1UL << USB_OTG_PCGCR_PHYSUSP_Pos) /*!< 0x00000010 */
-#define USB_OTG_PCGCR_PHYSUSP                   USB_OTG_PCGCR_PHYSUSP_Msk      /*!< PHY suspended */
-
-/********************  Bit definition for USB_OTG_GOTGINT register  ********************/
-#define USB_OTG_GOTGINT_SEDET_Pos               (2U)                           
-#define USB_OTG_GOTGINT_SEDET_Msk               (0x1UL << USB_OTG_GOTGINT_SEDET_Pos) /*!< 0x00000004 */
-#define USB_OTG_GOTGINT_SEDET                   USB_OTG_GOTGINT_SEDET_Msk      /*!< Session end detected */
-#define USB_OTG_GOTGINT_SRSSCHG_Pos             (8U)                           
-#define USB_OTG_GOTGINT_SRSSCHG_Msk             (0x1UL << USB_OTG_GOTGINT_SRSSCHG_Pos) /*!< 0x00000100 */
-#define USB_OTG_GOTGINT_SRSSCHG                 USB_OTG_GOTGINT_SRSSCHG_Msk    /*!< Session request success status change */
-#define USB_OTG_GOTGINT_HNSSCHG_Pos             (9U)                           
-#define USB_OTG_GOTGINT_HNSSCHG_Msk             (0x1UL << USB_OTG_GOTGINT_HNSSCHG_Pos) /*!< 0x00000200 */
-#define USB_OTG_GOTGINT_HNSSCHG                 USB_OTG_GOTGINT_HNSSCHG_Msk    /*!< Host negotiation success status change */
-#define USB_OTG_GOTGINT_HNGDET_Pos              (17U)                          
-#define USB_OTG_GOTGINT_HNGDET_Msk              (0x1UL << USB_OTG_GOTGINT_HNGDET_Pos) /*!< 0x00020000 */
-#define USB_OTG_GOTGINT_HNGDET                  USB_OTG_GOTGINT_HNGDET_Msk     /*!< Host negotiation detected */
-#define USB_OTG_GOTGINT_ADTOCHG_Pos             (18U)                          
-#define USB_OTG_GOTGINT_ADTOCHG_Msk             (0x1UL << USB_OTG_GOTGINT_ADTOCHG_Pos) /*!< 0x00040000 */
-#define USB_OTG_GOTGINT_ADTOCHG                 USB_OTG_GOTGINT_ADTOCHG_Msk    /*!< A-device timeout change */
-#define USB_OTG_GOTGINT_DBCDNE_Pos              (19U)                          
-#define USB_OTG_GOTGINT_DBCDNE_Msk              (0x1UL << USB_OTG_GOTGINT_DBCDNE_Pos) /*!< 0x00080000 */
-#define USB_OTG_GOTGINT_DBCDNE                  USB_OTG_GOTGINT_DBCDNE_Msk     /*!< Debounce done */
-
-/********************  Bit definition for USB_OTG_DCTL register  ********************/
-#define USB_OTG_DCTL_RWUSIG_Pos                 (0U)                           
-#define USB_OTG_DCTL_RWUSIG_Msk                 (0x1UL << USB_OTG_DCTL_RWUSIG_Pos) /*!< 0x00000001 */
-#define USB_OTG_DCTL_RWUSIG                     USB_OTG_DCTL_RWUSIG_Msk        /*!< Remote wakeup signaling */
-#define USB_OTG_DCTL_SDIS_Pos                   (1U)                           
-#define USB_OTG_DCTL_SDIS_Msk                   (0x1UL << USB_OTG_DCTL_SDIS_Pos) /*!< 0x00000002 */
-#define USB_OTG_DCTL_SDIS                       USB_OTG_DCTL_SDIS_Msk          /*!< Soft disconnect */
-#define USB_OTG_DCTL_GINSTS_Pos                 (2U)                           
-#define USB_OTG_DCTL_GINSTS_Msk                 (0x1UL << USB_OTG_DCTL_GINSTS_Pos) /*!< 0x00000004 */
-#define USB_OTG_DCTL_GINSTS                     USB_OTG_DCTL_GINSTS_Msk        /*!< Global IN NAK status */
-#define USB_OTG_DCTL_GONSTS_Pos                 (3U)                           
-#define USB_OTG_DCTL_GONSTS_Msk                 (0x1UL << USB_OTG_DCTL_GONSTS_Pos) /*!< 0x00000008 */
-#define USB_OTG_DCTL_GONSTS                     USB_OTG_DCTL_GONSTS_Msk        /*!< Global OUT NAK status */
-
-#define USB_OTG_DCTL_TCTL_Pos                   (4U)                           
-#define USB_OTG_DCTL_TCTL_Msk                   (0x7UL << USB_OTG_DCTL_TCTL_Pos) /*!< 0x00000070 */
-#define USB_OTG_DCTL_TCTL                       USB_OTG_DCTL_TCTL_Msk          /*!< Test control */
-#define USB_OTG_DCTL_TCTL_0                     (0x1UL << USB_OTG_DCTL_TCTL_Pos) /*!< 0x00000010 */
-#define USB_OTG_DCTL_TCTL_1                     (0x2UL << USB_OTG_DCTL_TCTL_Pos) /*!< 0x00000020 */
-#define USB_OTG_DCTL_TCTL_2                     (0x4UL << USB_OTG_DCTL_TCTL_Pos) /*!< 0x00000040 */
-#define USB_OTG_DCTL_SGINAK_Pos                 (7U)                           
-#define USB_OTG_DCTL_SGINAK_Msk                 (0x1UL << USB_OTG_DCTL_SGINAK_Pos) /*!< 0x00000080 */
-#define USB_OTG_DCTL_SGINAK                     USB_OTG_DCTL_SGINAK_Msk        /*!< Set global IN NAK */
-#define USB_OTG_DCTL_CGINAK_Pos                 (8U)                           
-#define USB_OTG_DCTL_CGINAK_Msk                 (0x1UL << USB_OTG_DCTL_CGINAK_Pos) /*!< 0x00000100 */
-#define USB_OTG_DCTL_CGINAK                     USB_OTG_DCTL_CGINAK_Msk        /*!< Clear global IN NAK */
-#define USB_OTG_DCTL_SGONAK_Pos                 (9U)                           
-#define USB_OTG_DCTL_SGONAK_Msk                 (0x1UL << USB_OTG_DCTL_SGONAK_Pos) /*!< 0x00000200 */
-#define USB_OTG_DCTL_SGONAK                     USB_OTG_DCTL_SGONAK_Msk        /*!< Set global OUT NAK */
-#define USB_OTG_DCTL_CGONAK_Pos                 (10U)                          
-#define USB_OTG_DCTL_CGONAK_Msk                 (0x1UL << USB_OTG_DCTL_CGONAK_Pos) /*!< 0x00000400 */
-#define USB_OTG_DCTL_CGONAK                     USB_OTG_DCTL_CGONAK_Msk        /*!< Clear global OUT NAK */
-#define USB_OTG_DCTL_POPRGDNE_Pos               (11U)                          
-#define USB_OTG_DCTL_POPRGDNE_Msk               (0x1UL << USB_OTG_DCTL_POPRGDNE_Pos) /*!< 0x00000800 */
-#define USB_OTG_DCTL_POPRGDNE                   USB_OTG_DCTL_POPRGDNE_Msk      /*!< Power-on programming done */
-
-/********************  Bit definition for USB_OTG_HFIR register  ********************/
-#define USB_OTG_HFIR_FRIVL_Pos                  (0U)                           
-#define USB_OTG_HFIR_FRIVL_Msk                  (0xFFFFUL << USB_OTG_HFIR_FRIVL_Pos) /*!< 0x0000FFFF */
-#define USB_OTG_HFIR_FRIVL                      USB_OTG_HFIR_FRIVL_Msk         /*!< Frame interval */
-
-/********************  Bit definition for USB_OTG_HFNUM register  ********************/
-#define USB_OTG_HFNUM_FRNUM_Pos                 (0U)                           
-#define USB_OTG_HFNUM_FRNUM_Msk                 (0xFFFFUL << USB_OTG_HFNUM_FRNUM_Pos) /*!< 0x0000FFFF */
-#define USB_OTG_HFNUM_FRNUM                     USB_OTG_HFNUM_FRNUM_Msk        /*!< Frame number */
-#define USB_OTG_HFNUM_FTREM_Pos                 (16U)                          
-#define USB_OTG_HFNUM_FTREM_Msk                 (0xFFFFUL << USB_OTG_HFNUM_FTREM_Pos) /*!< 0xFFFF0000 */
-#define USB_OTG_HFNUM_FTREM                     USB_OTG_HFNUM_FTREM_Msk        /*!< Frame time remaining */
-
-/********************  Bit definition for USB_OTG_DSTS register  ********************/
-#define USB_OTG_DSTS_SUSPSTS_Pos                (0U)                           
-#define USB_OTG_DSTS_SUSPSTS_Msk                (0x1UL << USB_OTG_DSTS_SUSPSTS_Pos) /*!< 0x00000001 */
-#define USB_OTG_DSTS_SUSPSTS                    USB_OTG_DSTS_SUSPSTS_Msk       /*!< Suspend status */
-
-#define USB_OTG_DSTS_ENUMSPD_Pos                (1U)                           
-#define USB_OTG_DSTS_ENUMSPD_Msk                (0x3UL << USB_OTG_DSTS_ENUMSPD_Pos) /*!< 0x00000006 */
-#define USB_OTG_DSTS_ENUMSPD                    USB_OTG_DSTS_ENUMSPD_Msk       /*!< Enumerated speed */
-#define USB_OTG_DSTS_ENUMSPD_0                  (0x1UL << USB_OTG_DSTS_ENUMSPD_Pos) /*!< 0x00000002 */
-#define USB_OTG_DSTS_ENUMSPD_1                  (0x2UL << USB_OTG_DSTS_ENUMSPD_Pos) /*!< 0x00000004 */
-#define USB_OTG_DSTS_EERR_Pos                   (3U)                           
-#define USB_OTG_DSTS_EERR_Msk                   (0x1UL << USB_OTG_DSTS_EERR_Pos) /*!< 0x00000008 */
-#define USB_OTG_DSTS_EERR                       USB_OTG_DSTS_EERR_Msk          /*!< Erratic error */
-#define USB_OTG_DSTS_FNSOF_Pos                  (8U)                           
-#define USB_OTG_DSTS_FNSOF_Msk                  (0x3FFFUL << USB_OTG_DSTS_FNSOF_Pos) /*!< 0x003FFF00 */
-#define USB_OTG_DSTS_FNSOF                      USB_OTG_DSTS_FNSOF_Msk         /*!< Frame number of the received SOF */
-
-/********************  Bit definition for USB_OTG_GAHBCFG register  ********************/
-#define USB_OTG_GAHBCFG_GINT_Pos                (0U)                           
-#define USB_OTG_GAHBCFG_GINT_Msk                (0x1UL << USB_OTG_GAHBCFG_GINT_Pos) /*!< 0x00000001 */
-#define USB_OTG_GAHBCFG_GINT                    USB_OTG_GAHBCFG_GINT_Msk       /*!< Global interrupt mask */
-#define USB_OTG_GAHBCFG_HBSTLEN_Pos             (1U)                           
-#define USB_OTG_GAHBCFG_HBSTLEN_Msk             (0xFUL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< 0x0000001E */
-#define USB_OTG_GAHBCFG_HBSTLEN                 USB_OTG_GAHBCFG_HBSTLEN_Msk    /*!< Burst length/type */
-#define USB_OTG_GAHBCFG_HBSTLEN_0                (0x0UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< Single */
-#define USB_OTG_GAHBCFG_HBSTLEN_1                (0x1UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< INCR */
-#define USB_OTG_GAHBCFG_HBSTLEN_2                (0x3UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< INCR4 */
-#define USB_OTG_GAHBCFG_HBSTLEN_3                (0x5UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< INCR8 */
-#define USB_OTG_GAHBCFG_HBSTLEN_4                (0x7UL << USB_OTG_GAHBCFG_HBSTLEN_Pos) /*!< INCR16 */
-#define USB_OTG_GAHBCFG_DMAEN_Pos               (5U)                           
-#define USB_OTG_GAHBCFG_DMAEN_Msk               (0x1UL << USB_OTG_GAHBCFG_DMAEN_Pos) /*!< 0x00000020 */
-#define USB_OTG_GAHBCFG_DMAEN                   USB_OTG_GAHBCFG_DMAEN_Msk      /*!< DMA enable */
-#define USB_OTG_GAHBCFG_TXFELVL_Pos             (7U)                           
-#define USB_OTG_GAHBCFG_TXFELVL_Msk             (0x1UL << USB_OTG_GAHBCFG_TXFELVL_Pos) /*!< 0x00000080 */
-#define USB_OTG_GAHBCFG_TXFELVL                 USB_OTG_GAHBCFG_TXFELVL_Msk    /*!< TxFIFO empty level */
-#define USB_OTG_GAHBCFG_PTXFELVL_Pos            (8U)                           
-#define USB_OTG_GAHBCFG_PTXFELVL_Msk            (0x1UL << USB_OTG_GAHBCFG_PTXFELVL_Pos) /*!< 0x00000100 */
-#define USB_OTG_GAHBCFG_PTXFELVL                USB_OTG_GAHBCFG_PTXFELVL_Msk   /*!< Periodic TxFIFO empty level */
-
-/********************  Bit definition for USB_OTG_GUSBCFG register  ********************/
-
-#define USB_OTG_GUSBCFG_TOCAL_Pos               (0U)                           
-#define USB_OTG_GUSBCFG_TOCAL_Msk               (0x7UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000007 */
-#define USB_OTG_GUSBCFG_TOCAL                   USB_OTG_GUSBCFG_TOCAL_Msk      /*!< FS timeout calibration */
-#define USB_OTG_GUSBCFG_TOCAL_0                 (0x1UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000001 */
-#define USB_OTG_GUSBCFG_TOCAL_1                 (0x2UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000002 */
-#define USB_OTG_GUSBCFG_TOCAL_2                 (0x4UL << USB_OTG_GUSBCFG_TOCAL_Pos) /*!< 0x00000004 */
-#define USB_OTG_GUSBCFG_PHYSEL_Pos              (6U)                           
-#define USB_OTG_GUSBCFG_PHYSEL_Msk              (0x1UL << USB_OTG_GUSBCFG_PHYSEL_Pos) /*!< 0x00000040 */
-#define USB_OTG_GUSBCFG_PHYSEL                  USB_OTG_GUSBCFG_PHYSEL_Msk     /*!< USB 2.0 high-speed ULPI PHY or USB 1.1 full-speed serial transceiver select */
-#define USB_OTG_GUSBCFG_SRPCAP_Pos              (8U)                           
-#define USB_OTG_GUSBCFG_SRPCAP_Msk              (0x1UL << USB_OTG_GUSBCFG_SRPCAP_Pos) /*!< 0x00000100 */
-#define USB_OTG_GUSBCFG_SRPCAP                  USB_OTG_GUSBCFG_SRPCAP_Msk     /*!< SRP-capable */
-#define USB_OTG_GUSBCFG_HNPCAP_Pos              (9U)                           
-#define USB_OTG_GUSBCFG_HNPCAP_Msk              (0x1UL << USB_OTG_GUSBCFG_HNPCAP_Pos) /*!< 0x00000200 */
-#define USB_OTG_GUSBCFG_HNPCAP                  USB_OTG_GUSBCFG_HNPCAP_Msk     /*!< HNP-capable */
-#define USB_OTG_GUSBCFG_TRDT_Pos                (10U)                          
-#define USB_OTG_GUSBCFG_TRDT_Msk                (0xFUL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00003C00 */
-#define USB_OTG_GUSBCFG_TRDT                    USB_OTG_GUSBCFG_TRDT_Msk       /*!< USB turnaround time */
-#define USB_OTG_GUSBCFG_TRDT_0                  (0x1UL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00000400 */
-#define USB_OTG_GUSBCFG_TRDT_1                  (0x2UL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00000800 */
-#define USB_OTG_GUSBCFG_TRDT_2                  (0x4UL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00001000 */
-#define USB_OTG_GUSBCFG_TRDT_3                  (0x8UL << USB_OTG_GUSBCFG_TRDT_Pos) /*!< 0x00002000 */
-#define USB_OTG_GUSBCFG_PHYLPCS_Pos             (15U)                          
-#define USB_OTG_GUSBCFG_PHYLPCS_Msk             (0x1UL << USB_OTG_GUSBCFG_PHYLPCS_Pos) /*!< 0x00008000 */
-#define USB_OTG_GUSBCFG_PHYLPCS                 USB_OTG_GUSBCFG_PHYLPCS_Msk    /*!< PHY Low-power clock select */
-#define USB_OTG_GUSBCFG_ULPIFSLS_Pos            (17U)                          
-#define USB_OTG_GUSBCFG_ULPIFSLS_Msk            (0x1UL << USB_OTG_GUSBCFG_ULPIFSLS_Pos) /*!< 0x00020000 */
-#define USB_OTG_GUSBCFG_ULPIFSLS                USB_OTG_GUSBCFG_ULPIFSLS_Msk   /*!< ULPI FS/LS select */
-#define USB_OTG_GUSBCFG_ULPIAR_Pos              (18U)                          
-#define USB_OTG_GUSBCFG_ULPIAR_Msk              (0x1UL << USB_OTG_GUSBCFG_ULPIAR_Pos) /*!< 0x00040000 */
-#define USB_OTG_GUSBCFG_ULPIAR                  USB_OTG_GUSBCFG_ULPIAR_Msk     /*!< ULPI Auto-resume */
-#define USB_OTG_GUSBCFG_ULPICSM_Pos             (19U)                          
-#define USB_OTG_GUSBCFG_ULPICSM_Msk             (0x1UL << USB_OTG_GUSBCFG_ULPICSM_Pos) /*!< 0x00080000 */
-#define USB_OTG_GUSBCFG_ULPICSM                 USB_OTG_GUSBCFG_ULPICSM_Msk    /*!< ULPI Clock SuspendM */
-#define USB_OTG_GUSBCFG_ULPIEVBUSD_Pos          (20U)                          
-#define USB_OTG_GUSBCFG_ULPIEVBUSD_Msk          (0x1UL << USB_OTG_GUSBCFG_ULPIEVBUSD_Pos) /*!< 0x00100000 */
-#define USB_OTG_GUSBCFG_ULPIEVBUSD              USB_OTG_GUSBCFG_ULPIEVBUSD_Msk /*!< ULPI External VBUS Drive */
-#define USB_OTG_GUSBCFG_ULPIEVBUSI_Pos          (21U)                          
-#define USB_OTG_GUSBCFG_ULPIEVBUSI_Msk          (0x1UL << USB_OTG_GUSBCFG_ULPIEVBUSI_Pos) /*!< 0x00200000 */
-#define USB_OTG_GUSBCFG_ULPIEVBUSI              USB_OTG_GUSBCFG_ULPIEVBUSI_Msk /*!< ULPI external VBUS indicator */
-#define USB_OTG_GUSBCFG_TSDPS_Pos               (22U)                          
-#define USB_OTG_GUSBCFG_TSDPS_Msk               (0x1UL << USB_OTG_GUSBCFG_TSDPS_Pos) /*!< 0x00400000 */
-#define USB_OTG_GUSBCFG_TSDPS                   USB_OTG_GUSBCFG_TSDPS_Msk      /*!< TermSel DLine pulsing selection */
-#define USB_OTG_GUSBCFG_PCCI_Pos                (23U)                          
-#define USB_OTG_GUSBCFG_PCCI_Msk                (0x1UL << USB_OTG_GUSBCFG_PCCI_Pos) /*!< 0x00800000 */
-#define USB_OTG_GUSBCFG_PCCI                    USB_OTG_GUSBCFG_PCCI_Msk       /*!< Indicator complement */
-#define USB_OTG_GUSBCFG_PTCI_Pos                (24U)                          
-#define USB_OTG_GUSBCFG_PTCI_Msk                (0x1UL << USB_OTG_GUSBCFG_PTCI_Pos) /*!< 0x01000000 */
-#define USB_OTG_GUSBCFG_PTCI                    USB_OTG_GUSBCFG_PTCI_Msk       /*!< Indicator pass through */
-#define USB_OTG_GUSBCFG_ULPIIPD_Pos             (25U)                          
-#define USB_OTG_GUSBCFG_ULPIIPD_Msk             (0x1UL << USB_OTG_GUSBCFG_ULPIIPD_Pos) /*!< 0x02000000 */
-#define USB_OTG_GUSBCFG_ULPIIPD                 USB_OTG_GUSBCFG_ULPIIPD_Msk    /*!< ULPI interface protect disable */
-#define USB_OTG_GUSBCFG_FHMOD_Pos               (29U)                          
-#define USB_OTG_GUSBCFG_FHMOD_Msk               (0x1UL << USB_OTG_GUSBCFG_FHMOD_Pos) /*!< 0x20000000 */
-#define USB_OTG_GUSBCFG_FHMOD                   USB_OTG_GUSBCFG_FHMOD_Msk      /*!< Forced host mode */
-#define USB_OTG_GUSBCFG_FDMOD_Pos               (30U)                          
-#define USB_OTG_GUSBCFG_FDMOD_Msk               (0x1UL << USB_OTG_GUSBCFG_FDMOD_Pos) /*!< 0x40000000 */
-#define USB_OTG_GUSBCFG_FDMOD                   USB_OTG_GUSBCFG_FDMOD_Msk      /*!< Forced peripheral mode */
-#define USB_OTG_GUSBCFG_CTXPKT_Pos              (31U)                          
-#define USB_OTG_GUSBCFG_CTXPKT_Msk              (0x1UL << USB_OTG_GUSBCFG_CTXPKT_Pos) /*!< 0x80000000 */
-#define USB_OTG_GUSBCFG_CTXPKT                  USB_OTG_GUSBCFG_CTXPKT_Msk     /*!< Corrupt Tx packet */
-
-/********************  Bit definition for USB_OTG_GRSTCTL register  ********************/
-#define USB_OTG_GRSTCTL_CSRST_Pos               (0U)                           
-#define USB_OTG_GRSTCTL_CSRST_Msk               (0x1UL << USB_OTG_GRSTCTL_CSRST_Pos) /*!< 0x00000001 */
-#define USB_OTG_GRSTCTL_CSRST                   USB_OTG_GRSTCTL_CSRST_Msk      /*!< Core soft reset */
-#define USB_OTG_GRSTCTL_HSRST_Pos               (1U)                           
-#define USB_OTG_GRSTCTL_HSRST_Msk               (0x1UL << USB_OTG_GRSTCTL_HSRST_Pos) /*!< 0x00000002 */
-#define USB_OTG_GRSTCTL_HSRST                   USB_OTG_GRSTCTL_HSRST_Msk      /*!< HCLK soft reset */
-#define USB_OTG_GRSTCTL_FCRST_Pos               (2U)                           
-#define USB_OTG_GRSTCTL_FCRST_Msk               (0x1UL << USB_OTG_GRSTCTL_FCRST_Pos) /*!< 0x00000004 */
-#define USB_OTG_GRSTCTL_FCRST                   USB_OTG_GRSTCTL_FCRST_Msk      /*!< Host frame counter reset */
-#define USB_OTG_GRSTCTL_RXFFLSH_Pos             (4U)                           
-#define USB_OTG_GRSTCTL_RXFFLSH_Msk             (0x1UL << USB_OTG_GRSTCTL_RXFFLSH_Pos) /*!< 0x00000010 */
-#define USB_OTG_GRSTCTL_RXFFLSH                 USB_OTG_GRSTCTL_RXFFLSH_Msk    /*!< RxFIFO flush */
-#define USB_OTG_GRSTCTL_TXFFLSH_Pos             (5U)                           
-#define USB_OTG_GRSTCTL_TXFFLSH_Msk             (0x1UL << USB_OTG_GRSTCTL_TXFFLSH_Pos) /*!< 0x00000020 */
-#define USB_OTG_GRSTCTL_TXFFLSH                 USB_OTG_GRSTCTL_TXFFLSH_Msk    /*!< TxFIFO flush */
-
-
-#define USB_OTG_GRSTCTL_TXFNUM_Pos              (6U)                           
-#define USB_OTG_GRSTCTL_TXFNUM_Msk              (0x1FUL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x000007C0 */
-#define USB_OTG_GRSTCTL_TXFNUM                  USB_OTG_GRSTCTL_TXFNUM_Msk     /*!< TxFIFO number */
-#define USB_OTG_GRSTCTL_TXFNUM_0                (0x01UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000040 */
-#define USB_OTG_GRSTCTL_TXFNUM_1                (0x02UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000080 */
-#define USB_OTG_GRSTCTL_TXFNUM_2                (0x04UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000100 */
-#define USB_OTG_GRSTCTL_TXFNUM_3                (0x08UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000200 */
-#define USB_OTG_GRSTCTL_TXFNUM_4                (0x10UL << USB_OTG_GRSTCTL_TXFNUM_Pos) /*!< 0x00000400 */
-#define USB_OTG_GRSTCTL_DMAREQ_Pos              (30U)                          
-#define USB_OTG_GRSTCTL_DMAREQ_Msk              (0x1UL << USB_OTG_GRSTCTL_DMAREQ_Pos) /*!< 0x40000000 */
-#define USB_OTG_GRSTCTL_DMAREQ                  USB_OTG_GRSTCTL_DMAREQ_Msk     /*!< DMA request signal */
-#define USB_OTG_GRSTCTL_AHBIDL_Pos              (31U)                          
-#define USB_OTG_GRSTCTL_AHBIDL_Msk              (0x1UL << USB_OTG_GRSTCTL_AHBIDL_Pos) /*!< 0x80000000 */
-#define USB_OTG_GRSTCTL_AHBIDL                  USB_OTG_GRSTCTL_AHBIDL_Msk     /*!< AHB master idle */
-
-/********************  Bit definition for USB_OTG_DIEPMSK register  ********************/
-#define USB_OTG_DIEPMSK_XFRCM_Pos               (0U)                           
-#define USB_OTG_DIEPMSK_XFRCM_Msk               (0x1UL << USB_OTG_DIEPMSK_XFRCM_Pos) /*!< 0x00000001 */
-#define USB_OTG_DIEPMSK_XFRCM                   USB_OTG_DIEPMSK_XFRCM_Msk      /*!< Transfer completed interrupt mask */
-#define USB_OTG_DIEPMSK_EPDM_Pos                (1U)                           
-#define USB_OTG_DIEPMSK_EPDM_Msk                (0x1UL << USB_OTG_DIEPMSK_EPDM_Pos) /*!< 0x00000002 */
-#define USB_OTG_DIEPMSK_EPDM                    USB_OTG_DIEPMSK_EPDM_Msk       /*!< Endpoint disabled interrupt mask */
-#define USB_OTG_DIEPMSK_TOM_Pos                 (3U)                           
-#define USB_OTG_DIEPMSK_TOM_Msk                 (0x1UL << USB_OTG_DIEPMSK_TOM_Pos) /*!< 0x00000008 */
-#define USB_OTG_DIEPMSK_TOM                     USB_OTG_DIEPMSK_TOM_Msk        /*!< Timeout condition mask (nonisochronous endpoints) */
-#define USB_OTG_DIEPMSK_ITTXFEMSK_Pos           (4U)                           
-#define USB_OTG_DIEPMSK_ITTXFEMSK_Msk           (0x1UL << USB_OTG_DIEPMSK_ITTXFEMSK_Pos) /*!< 0x00000010 */
-#define USB_OTG_DIEPMSK_ITTXFEMSK               USB_OTG_DIEPMSK_ITTXFEMSK_Msk  /*!< IN token received when TxFIFO empty mask */
-#define USB_OTG_DIEPMSK_INEPNMM_Pos             (5U)                           
-#define USB_OTG_DIEPMSK_INEPNMM_Msk             (0x1UL << USB_OTG_DIEPMSK_INEPNMM_Pos) /*!< 0x00000020 */
-#define USB_OTG_DIEPMSK_INEPNMM                 USB_OTG_DIEPMSK_INEPNMM_Msk    /*!< IN token received with EP mismatch mask */
-#define USB_OTG_DIEPMSK_INEPNEM_Pos             (6U)                           
-#define USB_OTG_DIEPMSK_INEPNEM_Msk             (0x1UL << USB_OTG_DIEPMSK_INEPNEM_Pos) /*!< 0x00000040 */
-#define USB_OTG_DIEPMSK_INEPNEM                 USB_OTG_DIEPMSK_INEPNEM_Msk    /*!< IN endpoint NAK effective mask */
-#define USB_OTG_DIEPMSK_TXFURM_Pos              (8U)                           
-#define USB_OTG_DIEPMSK_TXFURM_Msk              (0x1UL << USB_OTG_DIEPMSK_TXFURM_Pos) /*!< 0x00000100 */
-#define USB_OTG_DIEPMSK_TXFURM                  USB_OTG_DIEPMSK_TXFURM_Msk     /*!< FIFO underrun mask */
-#define USB_OTG_DIEPMSK_BIM_Pos                 (9U)                           
-#define USB_OTG_DIEPMSK_BIM_Msk                 (0x1UL << USB_OTG_DIEPMSK_BIM_Pos) /*!< 0x00000200 */
-#define USB_OTG_DIEPMSK_BIM                     USB_OTG_DIEPMSK_BIM_Msk        /*!< BNA interrupt mask */
-
-/********************  Bit definition for USB_OTG_HPTXSTS register  ********************/
-#define USB_OTG_HPTXSTS_PTXFSAVL_Pos            (0U)                           
-#define USB_OTG_HPTXSTS_PTXFSAVL_Msk            (0xFFFFUL << USB_OTG_HPTXSTS_PTXFSAVL_Pos) /*!< 0x0000FFFF */
-#define USB_OTG_HPTXSTS_PTXFSAVL                USB_OTG_HPTXSTS_PTXFSAVL_Msk   /*!< Periodic transmit data FIFO space available */
-#define USB_OTG_HPTXSTS_PTXQSAV_Pos             (16U)                          
-#define USB_OTG_HPTXSTS_PTXQSAV_Msk             (0xFFUL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00FF0000 */
-#define USB_OTG_HPTXSTS_PTXQSAV                 USB_OTG_HPTXSTS_PTXQSAV_Msk    /*!< Periodic transmit request queue space available */
-#define USB_OTG_HPTXSTS_PTXQSAV_0               (0x01UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00010000 */
-#define USB_OTG_HPTXSTS_PTXQSAV_1               (0x02UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00020000 */
-#define USB_OTG_HPTXSTS_PTXQSAV_2               (0x04UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00040000 */
-#define USB_OTG_HPTXSTS_PTXQSAV_3               (0x08UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00080000 */
-#define USB_OTG_HPTXSTS_PTXQSAV_4               (0x10UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00100000 */
-#define USB_OTG_HPTXSTS_PTXQSAV_5               (0x20UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00200000 */
-#define USB_OTG_HPTXSTS_PTXQSAV_6               (0x40UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00400000 */
-#define USB_OTG_HPTXSTS_PTXQSAV_7               (0x80UL << USB_OTG_HPTXSTS_PTXQSAV_Pos) /*!< 0x00800000 */
-
-#define USB_OTG_HPTXSTS_PTXQTOP_Pos             (24U)                          
-#define USB_OTG_HPTXSTS_PTXQTOP_Msk             (0xFFUL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0xFF000000 */
-#define USB_OTG_HPTXSTS_PTXQTOP                 USB_OTG_HPTXSTS_PTXQTOP_Msk    /*!< Top of the periodic transmit request queue */
-#define USB_OTG_HPTXSTS_PTXQTOP_0               (0x01UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x01000000 */
-#define USB_OTG_HPTXSTS_PTXQTOP_1               (0x02UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x02000000 */
-#define USB_OTG_HPTXSTS_PTXQTOP_2               (0x04UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x04000000 */
-#define USB_OTG_HPTXSTS_PTXQTOP_3               (0x08UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x08000000 */
-#define USB_OTG_HPTXSTS_PTXQTOP_4               (0x10UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x10000000 */
-#define USB_OTG_HPTXSTS_PTXQTOP_5               (0x20UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x20000000 */
-#define USB_OTG_HPTXSTS_PTXQTOP_6               (0x40UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x40000000 */
-#define USB_OTG_HPTXSTS_PTXQTOP_7               (0x80UL << USB_OTG_HPTXSTS_PTXQTOP_Pos) /*!< 0x80000000 */
-
-/********************  Bit definition for USB_OTG_HAINT register  ********************/
-#define USB_OTG_HAINT_HAINT_Pos                 (0U)                           
-#define USB_OTG_HAINT_HAINT_Msk                 (0xFFFFUL << USB_OTG_HAINT_HAINT_Pos) /*!< 0x0000FFFF */
-#define USB_OTG_HAINT_HAINT                     USB_OTG_HAINT_HAINT_Msk        /*!< Channel interrupts */
-
-/********************  Bit definition for USB_OTG_DOEPMSK register  ********************/
-#define USB_OTG_DOEPMSK_XFRCM_Pos               (0U)                           
-#define USB_OTG_DOEPMSK_XFRCM_Msk               (0x1UL << USB_OTG_DOEPMSK_XFRCM_Pos) /*!< 0x00000001 */
-#define USB_OTG_DOEPMSK_XFRCM                   USB_OTG_DOEPMSK_XFRCM_Msk      /*!< Transfer completed interrupt mask */
-#define USB_OTG_DOEPMSK_EPDM_Pos                (1U)                           
-#define USB_OTG_DOEPMSK_EPDM_Msk                (0x1UL << USB_OTG_DOEPMSK_EPDM_Pos) /*!< 0x00000002 */
-#define USB_OTG_DOEPMSK_EPDM                    USB_OTG_DOEPMSK_EPDM_Msk       /*!< Endpoint disabled interrupt mask */
-#define USB_OTG_DOEPMSK_AHBERRM_Pos              (2U)
-#define USB_OTG_DOEPMSK_AHBERRM_Msk              (0x1UL << USB_OTG_DOEPMSK_AHBERRM_Pos) /*!< 0x00000004 */
-#define USB_OTG_DOEPMSK_AHBERRM                  USB_OTG_DOEPMSK_AHBERRM_Msk   /*!< OUT transaction AHB Error interrupt mask       */
-#define USB_OTG_DOEPMSK_STUPM_Pos               (3U)                           
-#define USB_OTG_DOEPMSK_STUPM_Msk               (0x1UL << USB_OTG_DOEPMSK_STUPM_Pos) /*!< 0x00000008 */
-#define USB_OTG_DOEPMSK_STUPM                   USB_OTG_DOEPMSK_STUPM_Msk      /*!< SETUP phase done mask */
-#define USB_OTG_DOEPMSK_OTEPDM_Pos              (4U)                           
-#define USB_OTG_DOEPMSK_OTEPDM_Msk              (0x1UL << USB_OTG_DOEPMSK_OTEPDM_Pos) /*!< 0x00000010 */
-#define USB_OTG_DOEPMSK_OTEPDM                  USB_OTG_DOEPMSK_OTEPDM_Msk     /*!< OUT token received when endpoint disabled mask */
-#define USB_OTG_DOEPMSK_OTEPSPRM_Pos             (5U)                          
-#define USB_OTG_DOEPMSK_OTEPSPRM_Msk             (0x1UL << USB_OTG_DOEPMSK_OTEPSPRM_Pos) /*!< 0x00000020 */
-#define USB_OTG_DOEPMSK_OTEPSPRM                 USB_OTG_DOEPMSK_OTEPSPRM_Msk  /*!< Status Phase Received mask                     */
-#define USB_OTG_DOEPMSK_B2BSTUP_Pos             (6U)                           
-#define USB_OTG_DOEPMSK_B2BSTUP_Msk             (0x1UL << USB_OTG_DOEPMSK_B2BSTUP_Pos) /*!< 0x00000040 */
-#define USB_OTG_DOEPMSK_B2BSTUP                 USB_OTG_DOEPMSK_B2BSTUP_Msk    /*!< Back-to-back SETUP packets received mask */
-#define USB_OTG_DOEPMSK_OPEM_Pos                (8U)                           
-#define USB_OTG_DOEPMSK_OPEM_Msk                (0x1UL << USB_OTG_DOEPMSK_OPEM_Pos) /*!< 0x00000100 */
-#define USB_OTG_DOEPMSK_OPEM                    USB_OTG_DOEPMSK_OPEM_Msk       /*!< OUT packet error mask */
-#define USB_OTG_DOEPMSK_BOIM_Pos                (9U)                           
-#define USB_OTG_DOEPMSK_BOIM_Msk                (0x1UL << USB_OTG_DOEPMSK_BOIM_Pos) /*!< 0x00000200 */
-#define USB_OTG_DOEPMSK_BOIM                    USB_OTG_DOEPMSK_BOIM_Msk       /*!< BNA interrupt mask */
-#define USB_OTG_DOEPMSK_BERRM_Pos                (12U)
-#define USB_OTG_DOEPMSK_BERRM_Msk                (0x1UL << USB_OTG_DOEPMSK_BERRM_Pos) /*!< 0x00001000 */
-#define USB_OTG_DOEPMSK_BERRM                    USB_OTG_DOEPMSK_BERRM_Msk      /*!< Babble error interrupt mask                   */
-#define USB_OTG_DOEPMSK_NAKM_Pos                 (13U)
-#define USB_OTG_DOEPMSK_NAKM_Msk                 (0x1UL << USB_OTG_DOEPMSK_NAKM_Pos) /*!< 0x00002000 */
-#define USB_OTG_DOEPMSK_NAKM                     USB_OTG_DOEPMSK_NAKM_Msk      /*!< OUT Packet NAK interrupt mask                  */
-#define USB_OTG_DOEPMSK_NYETM_Pos                (14U)
-#define USB_OTG_DOEPMSK_NYETM_Msk                (0x1UL << USB_OTG_DOEPMSK_NYETM_Pos) /*!< 0x00004000 */
-#define USB_OTG_DOEPMSK_NYETM                    USB_OTG_DOEPMSK_NYETM_Msk     /*!< NYET interrupt mask                            */
-/********************  Bit definition for USB_OTG_GINTSTS register  ********************/
-#define USB_OTG_GINTSTS_CMOD_Pos                (0U)                           
-#define USB_OTG_GINTSTS_CMOD_Msk                (0x1UL << USB_OTG_GINTSTS_CMOD_Pos) /*!< 0x00000001 */
-#define USB_OTG_GINTSTS_CMOD                    USB_OTG_GINTSTS_CMOD_Msk       /*!< Current mode of operation */
-#define USB_OTG_GINTSTS_MMIS_Pos                (1U)                           
-#define USB_OTG_GINTSTS_MMIS_Msk                (0x1UL << USB_OTG_GINTSTS_MMIS_Pos) /*!< 0x00000002 */
-#define USB_OTG_GINTSTS_MMIS                    USB_OTG_GINTSTS_MMIS_Msk       /*!< Mode mismatch interrupt */
-#define USB_OTG_GINTSTS_OTGINT_Pos              (2U)                           
-#define USB_OTG_GINTSTS_OTGINT_Msk              (0x1UL << USB_OTG_GINTSTS_OTGINT_Pos) /*!< 0x00000004 */
-#define USB_OTG_GINTSTS_OTGINT                  USB_OTG_GINTSTS_OTGINT_Msk     /*!< OTG interrupt */
-#define USB_OTG_GINTSTS_SOF_Pos                 (3U)                           
-#define USB_OTG_GINTSTS_SOF_Msk                 (0x1UL << USB_OTG_GINTSTS_SOF_Pos) /*!< 0x00000008 */
-#define USB_OTG_GINTSTS_SOF                     USB_OTG_GINTSTS_SOF_Msk        /*!< Start of frame */
-#define USB_OTG_GINTSTS_RXFLVL_Pos              (4U)                           
-#define USB_OTG_GINTSTS_RXFLVL_Msk              (0x1UL << USB_OTG_GINTSTS_RXFLVL_Pos) /*!< 0x00000010 */
-#define USB_OTG_GINTSTS_RXFLVL                  USB_OTG_GINTSTS_RXFLVL_Msk     /*!< RxFIFO nonempty */
-#define USB_OTG_GINTSTS_NPTXFE_Pos              (5U)                           
-#define USB_OTG_GINTSTS_NPTXFE_Msk              (0x1UL << USB_OTG_GINTSTS_NPTXFE_Pos) /*!< 0x00000020 */
-#define USB_OTG_GINTSTS_NPTXFE                  USB_OTG_GINTSTS_NPTXFE_Msk     /*!< Nonperiodic TxFIFO empty */
-#define USB_OTG_GINTSTS_GINAKEFF_Pos            (6U)                           
-#define USB_OTG_GINTSTS_GINAKEFF_Msk            (0x1UL << USB_OTG_GINTSTS_GINAKEFF_Pos) /*!< 0x00000040 */
-#define USB_OTG_GINTSTS_GINAKEFF                USB_OTG_GINTSTS_GINAKEFF_Msk   /*!< Global IN nonperiodic NAK effective */
-#define USB_OTG_GINTSTS_BOUTNAKEFF_Pos          (7U)                           
-#define USB_OTG_GINTSTS_BOUTNAKEFF_Msk          (0x1UL << USB_OTG_GINTSTS_BOUTNAKEFF_Pos) /*!< 0x00000080 */
-#define USB_OTG_GINTSTS_BOUTNAKEFF              USB_OTG_GINTSTS_BOUTNAKEFF_Msk /*!< Global OUT NAK effective */
-#define USB_OTG_GINTSTS_ESUSP_Pos               (10U)                          
-#define USB_OTG_GINTSTS_ESUSP_Msk               (0x1UL << USB_OTG_GINTSTS_ESUSP_Pos) /*!< 0x00000400 */
-#define USB_OTG_GINTSTS_ESUSP                   USB_OTG_GINTSTS_ESUSP_Msk      /*!< Early suspend */
-#define USB_OTG_GINTSTS_USBSUSP_Pos             (11U)                          
-#define USB_OTG_GINTSTS_USBSUSP_Msk             (0x1UL << USB_OTG_GINTSTS_USBSUSP_Pos) /*!< 0x00000800 */
-#define USB_OTG_GINTSTS_USBSUSP                 USB_OTG_GINTSTS_USBSUSP_Msk    /*!< USB suspend */
-#define USB_OTG_GINTSTS_USBRST_Pos              (12U)                          
-#define USB_OTG_GINTSTS_USBRST_Msk              (0x1UL << USB_OTG_GINTSTS_USBRST_Pos) /*!< 0x00001000 */
-#define USB_OTG_GINTSTS_USBRST                  USB_OTG_GINTSTS_USBRST_Msk     /*!< USB reset */
-#define USB_OTG_GINTSTS_ENUMDNE_Pos             (13U)                          
-#define USB_OTG_GINTSTS_ENUMDNE_Msk             (0x1UL << USB_OTG_GINTSTS_ENUMDNE_Pos) /*!< 0x00002000 */
-#define USB_OTG_GINTSTS_ENUMDNE                 USB_OTG_GINTSTS_ENUMDNE_Msk    /*!< Enumeration done */
-#define USB_OTG_GINTSTS_ISOODRP_Pos             (14U)                          
-#define USB_OTG_GINTSTS_ISOODRP_Msk             (0x1UL << USB_OTG_GINTSTS_ISOODRP_Pos) /*!< 0x00004000 */
-#define USB_OTG_GINTSTS_ISOODRP                 USB_OTG_GINTSTS_ISOODRP_Msk    /*!< Isochronous OUT packet dropped interrupt */
-#define USB_OTG_GINTSTS_EOPF_Pos                (15U)                          
-#define USB_OTG_GINTSTS_EOPF_Msk                (0x1UL << USB_OTG_GINTSTS_EOPF_Pos) /*!< 0x00008000 */
-#define USB_OTG_GINTSTS_EOPF                    USB_OTG_GINTSTS_EOPF_Msk       /*!< End of periodic frame interrupt */
-#define USB_OTG_GINTSTS_IEPINT_Pos              (18U)                          
-#define USB_OTG_GINTSTS_IEPINT_Msk              (0x1UL << USB_OTG_GINTSTS_IEPINT_Pos) /*!< 0x00040000 */
-#define USB_OTG_GINTSTS_IEPINT                  USB_OTG_GINTSTS_IEPINT_Msk     /*!< IN endpoint interrupt */
-#define USB_OTG_GINTSTS_OEPINT_Pos              (19U)                          
-#define USB_OTG_GINTSTS_OEPINT_Msk              (0x1UL << USB_OTG_GINTSTS_OEPINT_Pos) /*!< 0x00080000 */
-#define USB_OTG_GINTSTS_OEPINT                  USB_OTG_GINTSTS_OEPINT_Msk     /*!< OUT endpoint interrupt */
-#define USB_OTG_GINTSTS_IISOIXFR_Pos            (20U)                          
-#define USB_OTG_GINTSTS_IISOIXFR_Msk            (0x1UL << USB_OTG_GINTSTS_IISOIXFR_Pos) /*!< 0x00100000 */
-#define USB_OTG_GINTSTS_IISOIXFR                USB_OTG_GINTSTS_IISOIXFR_Msk   /*!< Incomplete isochronous IN transfer */
-#define USB_OTG_GINTSTS_PXFR_INCOMPISOOUT_Pos   (21U)                          
-#define USB_OTG_GINTSTS_PXFR_INCOMPISOOUT_Msk   (0x1UL << USB_OTG_GINTSTS_PXFR_INCOMPISOOUT_Pos) /*!< 0x00200000 */
-#define USB_OTG_GINTSTS_PXFR_INCOMPISOOUT       USB_OTG_GINTSTS_PXFR_INCOMPISOOUT_Msk /*!< Incomplete periodic transfer */
-#define USB_OTG_GINTSTS_DATAFSUSP_Pos           (22U)                          
-#define USB_OTG_GINTSTS_DATAFSUSP_Msk           (0x1UL << USB_OTG_GINTSTS_DATAFSUSP_Pos) /*!< 0x00400000 */
-#define USB_OTG_GINTSTS_DATAFSUSP               USB_OTG_GINTSTS_DATAFSUSP_Msk  /*!< Data fetch suspended */
-#define USB_OTG_GINTSTS_HPRTINT_Pos             (24U)                          
-#define USB_OTG_GINTSTS_HPRTINT_Msk             (0x1UL << USB_OTG_GINTSTS_HPRTINT_Pos) /*!< 0x01000000 */
-#define USB_OTG_GINTSTS_HPRTINT                 USB_OTG_GINTSTS_HPRTINT_Msk    /*!< Host port interrupt */
-#define USB_OTG_GINTSTS_HCINT_Pos               (25U)                          
-#define USB_OTG_GINTSTS_HCINT_Msk               (0x1UL << USB_OTG_GINTSTS_HCINT_Pos) /*!< 0x02000000 */
-#define USB_OTG_GINTSTS_HCINT                   USB_OTG_GINTSTS_HCINT_Msk      /*!< Host channels interrupt */
-#define USB_OTG_GINTSTS_PTXFE_Pos               (26U)                          
-#define USB_OTG_GINTSTS_PTXFE_Msk               (0x1UL << USB_OTG_GINTSTS_PTXFE_Pos) /*!< 0x04000000 */
-#define USB_OTG_GINTSTS_PTXFE                   USB_OTG_GINTSTS_PTXFE_Msk      /*!< Periodic TxFIFO empty */
-#define USB_OTG_GINTSTS_CIDSCHG_Pos             (28U)                          
-#define USB_OTG_GINTSTS_CIDSCHG_Msk             (0x1UL << USB_OTG_GINTSTS_CIDSCHG_Pos) /*!< 0x10000000 */
-#define USB_OTG_GINTSTS_CIDSCHG                 USB_OTG_GINTSTS_CIDSCHG_Msk    /*!< Connector ID status change */
-#define USB_OTG_GINTSTS_DISCINT_Pos             (29U)                          
-#define USB_OTG_GINTSTS_DISCINT_Msk             (0x1UL << USB_OTG_GINTSTS_DISCINT_Pos) /*!< 0x20000000 */
-#define USB_OTG_GINTSTS_DISCINT                 USB_OTG_GINTSTS_DISCINT_Msk    /*!< Disconnect detected interrupt */
-#define USB_OTG_GINTSTS_SRQINT_Pos              (30U)                          
-#define USB_OTG_GINTSTS_SRQINT_Msk              (0x1UL << USB_OTG_GINTSTS_SRQINT_Pos) /*!< 0x40000000 */
-#define USB_OTG_GINTSTS_SRQINT                  USB_OTG_GINTSTS_SRQINT_Msk     /*!< Session request/new session detected interrupt */
-#define USB_OTG_GINTSTS_WKUINT_Pos              (31U)                          
-#define USB_OTG_GINTSTS_WKUINT_Msk              (0x1UL << USB_OTG_GINTSTS_WKUINT_Pos) /*!< 0x80000000 */
-#define USB_OTG_GINTSTS_WKUINT                  USB_OTG_GINTSTS_WKUINT_Msk     /*!< Resume/remote wakeup detected interrupt */
-
-/********************  Bit definition for USB_OTG_GINTMSK register  ********************/
-#define USB_OTG_GINTMSK_MMISM_Pos               (1U)                           
-#define USB_OTG_GINTMSK_MMISM_Msk               (0x1UL << USB_OTG_GINTMSK_MMISM_Pos) /*!< 0x00000002 */
-#define USB_OTG_GINTMSK_MMISM                   USB_OTG_GINTMSK_MMISM_Msk      /*!< Mode mismatch interrupt mask */
-#define USB_OTG_GINTMSK_OTGINT_Pos              (2U)                           
-#define USB_OTG_GINTMSK_OTGINT_Msk              (0x1UL << USB_OTG_GINTMSK_OTGINT_Pos) /*!< 0x00000004 */
-#define USB_OTG_GINTMSK_OTGINT                  USB_OTG_GINTMSK_OTGINT_Msk     /*!< OTG interrupt mask */
-#define USB_OTG_GINTMSK_SOFM_Pos                (3U)                           
-#define USB_OTG_GINTMSK_SOFM_Msk                (0x1UL << USB_OTG_GINTMSK_SOFM_Pos) /*!< 0x00000008 */
-#define USB_OTG_GINTMSK_SOFM                    USB_OTG_GINTMSK_SOFM_Msk       /*!< Start of frame mask */
-#define USB_OTG_GINTMSK_RXFLVLM_Pos             (4U)                           
-#define USB_OTG_GINTMSK_RXFLVLM_Msk             (0x1UL << USB_OTG_GINTMSK_RXFLVLM_Pos) /*!< 0x00000010 */
-#define USB_OTG_GINTMSK_RXFLVLM                 USB_OTG_GINTMSK_RXFLVLM_Msk    /*!< Receive FIFO nonempty mask */
-#define USB_OTG_GINTMSK_NPTXFEM_Pos             (5U)                           
-#define USB_OTG_GINTMSK_NPTXFEM_Msk             (0x1UL << USB_OTG_GINTMSK_NPTXFEM_Pos) /*!< 0x00000020 */
-#define USB_OTG_GINTMSK_NPTXFEM                 USB_OTG_GINTMSK_NPTXFEM_Msk    /*!< Nonperiodic TxFIFO empty mask */
-#define USB_OTG_GINTMSK_GINAKEFFM_Pos           (6U)                           
-#define USB_OTG_GINTMSK_GINAKEFFM_Msk           (0x1UL << USB_OTG_GINTMSK_GINAKEFFM_Pos) /*!< 0x00000040 */
-#define USB_OTG_GINTMSK_GINAKEFFM               USB_OTG_GINTMSK_GINAKEFFM_Msk  /*!< Global nonperiodic IN NAK effective mask */
-#define USB_OTG_GINTMSK_GONAKEFFM_Pos           (7U)                           
-#define USB_OTG_GINTMSK_GONAKEFFM_Msk           (0x1UL << USB_OTG_GINTMSK_GONAKEFFM_Pos) /*!< 0x00000080 */
-#define USB_OTG_GINTMSK_GONAKEFFM               USB_OTG_GINTMSK_GONAKEFFM_Msk  /*!< Global OUT NAK effective mask */
-#define USB_OTG_GINTMSK_ESUSPM_Pos              (10U)                          
-#define USB_OTG_GINTMSK_ESUSPM_Msk              (0x1UL << USB_OTG_GINTMSK_ESUSPM_Pos) /*!< 0x00000400 */
-#define USB_OTG_GINTMSK_ESUSPM                  USB_OTG_GINTMSK_ESUSPM_Msk     /*!< Early suspend mask */
-#define USB_OTG_GINTMSK_USBSUSPM_Pos            (11U)                          
-#define USB_OTG_GINTMSK_USBSUSPM_Msk            (0x1UL << USB_OTG_GINTMSK_USBSUSPM_Pos) /*!< 0x00000800 */
-#define USB_OTG_GINTMSK_USBSUSPM                USB_OTG_GINTMSK_USBSUSPM_Msk   /*!< USB suspend mask */
-#define USB_OTG_GINTMSK_USBRST_Pos              (12U)                          
-#define USB_OTG_GINTMSK_USBRST_Msk              (0x1UL << USB_OTG_GINTMSK_USBRST_Pos) /*!< 0x00001000 */
-#define USB_OTG_GINTMSK_USBRST                  USB_OTG_GINTMSK_USBRST_Msk     /*!< USB reset mask */
-#define USB_OTG_GINTMSK_ENUMDNEM_Pos            (13U)                          
-#define USB_OTG_GINTMSK_ENUMDNEM_Msk            (0x1UL << USB_OTG_GINTMSK_ENUMDNEM_Pos) /*!< 0x00002000 */
-#define USB_OTG_GINTMSK_ENUMDNEM                USB_OTG_GINTMSK_ENUMDNEM_Msk   /*!< Enumeration done mask */
-#define USB_OTG_GINTMSK_ISOODRPM_Pos            (14U)                          
-#define USB_OTG_GINTMSK_ISOODRPM_Msk            (0x1UL << USB_OTG_GINTMSK_ISOODRPM_Pos) /*!< 0x00004000 */
-#define USB_OTG_GINTMSK_ISOODRPM                USB_OTG_GINTMSK_ISOODRPM_Msk   /*!< Isochronous OUT packet dropped interrupt mask */
-#define USB_OTG_GINTMSK_EOPFM_Pos               (15U)                          
-#define USB_OTG_GINTMSK_EOPFM_Msk               (0x1UL << USB_OTG_GINTMSK_EOPFM_Pos) /*!< 0x00008000 */
-#define USB_OTG_GINTMSK_EOPFM                   USB_OTG_GINTMSK_EOPFM_Msk      /*!< End of periodic frame interrupt mask */
-#define USB_OTG_GINTMSK_EPMISM_Pos              (17U)                          
-#define USB_OTG_GINTMSK_EPMISM_Msk              (0x1UL << USB_OTG_GINTMSK_EPMISM_Pos) /*!< 0x00020000 */
-#define USB_OTG_GINTMSK_EPMISM                  USB_OTG_GINTMSK_EPMISM_Msk     /*!< Endpoint mismatch interrupt mask */
-#define USB_OTG_GINTMSK_IEPINT_Pos              (18U)                          
-#define USB_OTG_GINTMSK_IEPINT_Msk              (0x1UL << USB_OTG_GINTMSK_IEPINT_Pos) /*!< 0x00040000 */
-#define USB_OTG_GINTMSK_IEPINT                  USB_OTG_GINTMSK_IEPINT_Msk     /*!< IN endpoints interrupt mask */
-#define USB_OTG_GINTMSK_OEPINT_Pos              (19U)                          
-#define USB_OTG_GINTMSK_OEPINT_Msk              (0x1UL << USB_OTG_GINTMSK_OEPINT_Pos) /*!< 0x00080000 */
-#define USB_OTG_GINTMSK_OEPINT                  USB_OTG_GINTMSK_OEPINT_Msk     /*!< OUT endpoints interrupt mask */
-#define USB_OTG_GINTMSK_IISOIXFRM_Pos           (20U)                          
-#define USB_OTG_GINTMSK_IISOIXFRM_Msk           (0x1UL << USB_OTG_GINTMSK_IISOIXFRM_Pos) /*!< 0x00100000 */
-#define USB_OTG_GINTMSK_IISOIXFRM               USB_OTG_GINTMSK_IISOIXFRM_Msk  /*!< Incomplete isochronous IN transfer mask */
-#define USB_OTG_GINTMSK_PXFRM_IISOOXFRM_Pos     (21U)                          
-#define USB_OTG_GINTMSK_PXFRM_IISOOXFRM_Msk     (0x1UL << USB_OTG_GINTMSK_PXFRM_IISOOXFRM_Pos) /*!< 0x00200000 */
-#define USB_OTG_GINTMSK_PXFRM_IISOOXFRM         USB_OTG_GINTMSK_PXFRM_IISOOXFRM_Msk /*!< Incomplete periodic transfer mask */
-#define USB_OTG_GINTMSK_FSUSPM_Pos              (22U)                          
-#define USB_OTG_GINTMSK_FSUSPM_Msk              (0x1UL << USB_OTG_GINTMSK_FSUSPM_Pos) /*!< 0x00400000 */
-#define USB_OTG_GINTMSK_FSUSPM                  USB_OTG_GINTMSK_FSUSPM_Msk     /*!< Data fetch suspended mask */
-#define USB_OTG_GINTMSK_PRTIM_Pos               (24U)                          
-#define USB_OTG_GINTMSK_PRTIM_Msk               (0x1UL << USB_OTG_GINTMSK_PRTIM_Pos) /*!< 0x01000000 */
-#define USB_OTG_GINTMSK_PRTIM                   USB_OTG_GINTMSK_PRTIM_Msk      /*!< Host port interrupt mask */
-#define USB_OTG_GINTMSK_HCIM_Pos                (25U)                          
-#define USB_OTG_GINTMSK_HCIM_Msk                (0x1UL << USB_OTG_GINTMSK_HCIM_Pos) /*!< 0x02000000 */
-#define USB_OTG_GINTMSK_HCIM                    USB_OTG_GINTMSK_HCIM_Msk       /*!< Host channels interrupt mask */
-#define USB_OTG_GINTMSK_PTXFEM_Pos              (26U)                          
-#define USB_OTG_GINTMSK_PTXFEM_Msk              (0x1UL << USB_OTG_GINTMSK_PTXFEM_Pos) /*!< 0x04000000 */
-#define USB_OTG_GINTMSK_PTXFEM                  USB_OTG_GINTMSK_PTXFEM_Msk     /*!< Periodic TxFIFO empty mask */
-#define USB_OTG_GINTMSK_CIDSCHGM_Pos            (28U)                          
-#define USB_OTG_GINTMSK_CIDSCHGM_Msk            (0x1UL << USB_OTG_GINTMSK_CIDSCHGM_Pos) /*!< 0x10000000 */
-#define USB_OTG_GINTMSK_CIDSCHGM                USB_OTG_GINTMSK_CIDSCHGM_Msk   /*!< Connector ID status change mask */
-#define USB_OTG_GINTMSK_DISCINT_Pos             (29U)                          
-#define USB_OTG_GINTMSK_DISCINT_Msk             (0x1UL << USB_OTG_GINTMSK_DISCINT_Pos) /*!< 0x20000000 */
-#define USB_OTG_GINTMSK_DISCINT                 USB_OTG_GINTMSK_DISCINT_Msk    /*!< Disconnect detected interrupt mask */
-#define USB_OTG_GINTMSK_SRQIM_Pos               (30U)                          
-#define USB_OTG_GINTMSK_SRQIM_Msk               (0x1UL << USB_OTG_GINTMSK_SRQIM_Pos) /*!< 0x40000000 */
-#define USB_OTG_GINTMSK_SRQIM                   USB_OTG_GINTMSK_SRQIM_Msk      /*!< Session request/new session detected interrupt mask */
-#define USB_OTG_GINTMSK_WUIM_Pos                (31U)                          
-#define USB_OTG_GINTMSK_WUIM_Msk                (0x1UL << USB_OTG_GINTMSK_WUIM_Pos) /*!< 0x80000000 */
-#define USB_OTG_GINTMSK_WUIM                    USB_OTG_GINTMSK_WUIM_Msk       /*!< Resume/remote wakeup detected interrupt mask */
-
-/********************  Bit definition for USB_OTG_DAINT register  ********************/
-#define USB_OTG_DAINT_IEPINT_Pos                (0U)                           
-#define USB_OTG_DAINT_IEPINT_Msk                (0xFFFFUL << USB_OTG_DAINT_IEPINT_Pos) /*!< 0x0000FFFF */
-#define USB_OTG_DAINT_IEPINT                    USB_OTG_DAINT_IEPINT_Msk       /*!< IN endpoint interrupt bits */
-#define USB_OTG_DAINT_OEPINT_Pos                (16U)                          
-#define USB_OTG_DAINT_OEPINT_Msk                (0xFFFFUL << USB_OTG_DAINT_OEPINT_Pos) /*!< 0xFFFF0000 */
-#define USB_OTG_DAINT_OEPINT                    USB_OTG_DAINT_OEPINT_Msk       /*!< OUT endpoint interrupt bits */
-
-/********************  Bit definition for USB_OTG_HAINTMSK register  ********************/
-#define USB_OTG_HAINTMSK_HAINTM_Pos             (0U)                           
-#define USB_OTG_HAINTMSK_HAINTM_Msk             (0xFFFFUL << USB_OTG_HAINTMSK_HAINTM_Pos) /*!< 0x0000FFFF */
-#define USB_OTG_HAINTMSK_HAINTM                 USB_OTG_HAINTMSK_HAINTM_Msk    /*!< Channel interrupt mask */
-
-/********************  Bit definition for USB_OTG_GRXSTSP register  ********************/
-#define USB_OTG_GRXSTSP_EPNUM_Pos               (0U)                           
-#define USB_OTG_GRXSTSP_EPNUM_Msk               (0xFUL << USB_OTG_GRXSTSP_EPNUM_Pos) /*!< 0x0000000F */
-#define USB_OTG_GRXSTSP_EPNUM                   USB_OTG_GRXSTSP_EPNUM_Msk      /*!< IN EP interrupt mask bits */
-#define USB_OTG_GRXSTSP_BCNT_Pos                (4U)                           
-#define USB_OTG_GRXSTSP_BCNT_Msk                (0x7FFUL << USB_OTG_GRXSTSP_BCNT_Pos) /*!< 0x00007FF0 */
-#define USB_OTG_GRXSTSP_BCNT                    USB_OTG_GRXSTSP_BCNT_Msk       /*!< OUT EP interrupt mask bits */
-#define USB_OTG_GRXSTSP_DPID_Pos                (15U)                          
-#define USB_OTG_GRXSTSP_DPID_Msk                (0x3UL << USB_OTG_GRXSTSP_DPID_Pos) /*!< 0x00018000 */
-#define USB_OTG_GRXSTSP_DPID                    USB_OTG_GRXSTSP_DPID_Msk       /*!< OUT EP interrupt mask bits */
-#define USB_OTG_GRXSTSP_PKTSTS_Pos              (17U)                          
-#define USB_OTG_GRXSTSP_PKTSTS_Msk              (0xFUL << USB_OTG_GRXSTSP_PKTSTS_Pos) /*!< 0x001E0000 */
-#define USB_OTG_GRXSTSP_PKTSTS                  USB_OTG_GRXSTSP_PKTSTS_Msk     /*!< OUT EP interrupt mask bits */
-
-/********************  Bit definition for USB_OTG_DAINTMSK register  ********************/
-#define USB_OTG_DAINTMSK_IEPM_Pos               (0U)                           
-#define USB_OTG_DAINTMSK_IEPM_Msk               (0xFFFFUL << USB_OTG_DAINTMSK_IEPM_Pos) /*!< 0x0000FFFF */
-#define USB_OTG_DAINTMSK_IEPM                   USB_OTG_DAINTMSK_IEPM_Msk      /*!< IN EP interrupt mask bits */
-#define USB_OTG_DAINTMSK_OEPM_Pos               (16U)                          
-#define USB_OTG_DAINTMSK_OEPM_Msk               (0xFFFFUL << USB_OTG_DAINTMSK_OEPM_Pos) /*!< 0xFFFF0000 */
-#define USB_OTG_DAINTMSK_OEPM                   USB_OTG_DAINTMSK_OEPM_Msk      /*!< OUT EP interrupt mask bits */
-
-/********************  Bit definition for USB_OTG_GRXFSIZ register  ********************/
-#define USB_OTG_GRXFSIZ_RXFD_Pos                (0U)                           
-#define USB_OTG_GRXFSIZ_RXFD_Msk                (0xFFFFUL << USB_OTG_GRXFSIZ_RXFD_Pos) /*!< 0x0000FFFF */
-#define USB_OTG_GRXFSIZ_RXFD                    USB_OTG_GRXFSIZ_RXFD_Msk       /*!< RxFIFO depth */
-
-/********************  Bit definition for USB_OTG_DVBUSDIS register  ********************/
-#define USB_OTG_DVBUSDIS_VBUSDT_Pos             (0U)                           
-#define USB_OTG_DVBUSDIS_VBUSDT_Msk             (0xFFFFUL << USB_OTG_DVBUSDIS_VBUSDT_Pos) /*!< 0x0000FFFF */
-#define USB_OTG_DVBUSDIS_VBUSDT                 USB_OTG_DVBUSDIS_VBUSDT_Msk    /*!< Device VBUS discharge time */
-
-/********************  Bit definition for OTG register  ********************/
-#define USB_OTG_NPTXFSA_Pos                     (0U)                           
-#define USB_OTG_NPTXFSA_Msk                     (0xFFFFUL << USB_OTG_NPTXFSA_Pos) /*!< 0x0000FFFF */
-#define USB_OTG_NPTXFSA                         USB_OTG_NPTXFSA_Msk            /*!< Nonperiodic transmit RAM start address */
-#define USB_OTG_NPTXFD_Pos                      (16U)                          
-#define USB_OTG_NPTXFD_Msk                      (0xFFFFUL << USB_OTG_NPTXFD_Pos) /*!< 0xFFFF0000 */
-#define USB_OTG_NPTXFD                          USB_OTG_NPTXFD_Msk             /*!< Nonperiodic TxFIFO depth */
-#define USB_OTG_TX0FSA_Pos                      (0U)                           
-#define USB_OTG_TX0FSA_Msk                      (0xFFFFUL << USB_OTG_TX0FSA_Pos) /*!< 0x0000FFFF */
-#define USB_OTG_TX0FSA                          USB_OTG_TX0FSA_Msk             /*!< Endpoint 0 transmit RAM start address */
-#define USB_OTG_TX0FD_Pos                       (16U)                          
-#define USB_OTG_TX0FD_Msk                       (0xFFFFUL << USB_OTG_TX0FD_Pos) /*!< 0xFFFF0000 */
-#define USB_OTG_TX0FD                           USB_OTG_TX0FD_Msk              /*!< Endpoint 0 TxFIFO depth */
-
-/********************  Bit definition for USB_OTG_DVBUSPULSE register  ********************/
-#define USB_OTG_DVBUSPULSE_DVBUSP_Pos           (0U)                           
-#define USB_OTG_DVBUSPULSE_DVBUSP_Msk           (0xFFFUL << USB_OTG_DVBUSPULSE_DVBUSP_Pos) /*!< 0x00000FFF */
-#define USB_OTG_DVBUSPULSE_DVBUSP               USB_OTG_DVBUSPULSE_DVBUSP_Msk  /*!< Device VBUS pulsing time */
-
-/********************  Bit definition for USB_OTG_GNPTXSTS register  ********************/
-#define USB_OTG_GNPTXSTS_NPTXFSAV_Pos           (0U)                           
-#define USB_OTG_GNPTXSTS_NPTXFSAV_Msk           (0xFFFFUL << USB_OTG_GNPTXSTS_NPTXFSAV_Pos) /*!< 0x0000FFFF */
-#define USB_OTG_GNPTXSTS_NPTXFSAV               USB_OTG_GNPTXSTS_NPTXFSAV_Msk  /*!< Nonperiodic TxFIFO space available */
-
-#define USB_OTG_GNPTXSTS_NPTQXSAV_Pos           (16U)                          
-#define USB_OTG_GNPTXSTS_NPTQXSAV_Msk           (0xFFUL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00FF0000 */
-#define USB_OTG_GNPTXSTS_NPTQXSAV               USB_OTG_GNPTXSTS_NPTQXSAV_Msk  /*!< Nonperiodic transmit request queue space available */
-#define USB_OTG_GNPTXSTS_NPTQXSAV_0             (0x01UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00010000 */
-#define USB_OTG_GNPTXSTS_NPTQXSAV_1             (0x02UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00020000 */
-#define USB_OTG_GNPTXSTS_NPTQXSAV_2             (0x04UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00040000 */
-#define USB_OTG_GNPTXSTS_NPTQXSAV_3             (0x08UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00080000 */
-#define USB_OTG_GNPTXSTS_NPTQXSAV_4             (0x10UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00100000 */
-#define USB_OTG_GNPTXSTS_NPTQXSAV_5             (0x20UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00200000 */
-#define USB_OTG_GNPTXSTS_NPTQXSAV_6             (0x40UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00400000 */
-#define USB_OTG_GNPTXSTS_NPTQXSAV_7             (0x80UL << USB_OTG_GNPTXSTS_NPTQXSAV_Pos) /*!< 0x00800000 */
-
-#define USB_OTG_GNPTXSTS_NPTXQTOP_Pos           (24U)                          
-#define USB_OTG_GNPTXSTS_NPTXQTOP_Msk           (0x7FUL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x7F000000 */
-#define USB_OTG_GNPTXSTS_NPTXQTOP               USB_OTG_GNPTXSTS_NPTXQTOP_Msk  /*!< Top of the nonperiodic transmit request queue */
-#define USB_OTG_GNPTXSTS_NPTXQTOP_0             (0x01UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x01000000 */
-#define USB_OTG_GNPTXSTS_NPTXQTOP_1             (0x02UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x02000000 */
-#define USB_OTG_GNPTXSTS_NPTXQTOP_2             (0x04UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x04000000 */
-#define USB_OTG_GNPTXSTS_NPTXQTOP_3             (0x08UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x08000000 */
-#define USB_OTG_GNPTXSTS_NPTXQTOP_4             (0x10UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x10000000 */
-#define USB_OTG_GNPTXSTS_NPTXQTOP_5             (0x20UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x20000000 */
-#define USB_OTG_GNPTXSTS_NPTXQTOP_6             (0x40UL << USB_OTG_GNPTXSTS_NPTXQTOP_Pos) /*!< 0x40000000 */
-
-/********************  Bit definition for USB_OTG_DTHRCTL register  ********************/
-#define USB_OTG_DTHRCTL_NONISOTHREN_Pos         (0U)                           
-#define USB_OTG_DTHRCTL_NONISOTHREN_Msk         (0x1UL << USB_OTG_DTHRCTL_NONISOTHREN_Pos) /*!< 0x00000001 */
-#define USB_OTG_DTHRCTL_NONISOTHREN             USB_OTG_DTHRCTL_NONISOTHREN_Msk /*!< Nonisochronous IN endpoints threshold enable */
-#define USB_OTG_DTHRCTL_ISOTHREN_Pos            (1U)                           
-#define USB_OTG_DTHRCTL_ISOTHREN_Msk            (0x1UL << USB_OTG_DTHRCTL_ISOTHREN_Pos) /*!< 0x00000002 */
-#define USB_OTG_DTHRCTL_ISOTHREN                USB_OTG_DTHRCTL_ISOTHREN_Msk   /*!< ISO IN endpoint threshold enable */
-
-#define USB_OTG_DTHRCTL_TXTHRLEN_Pos            (2U)                           
-#define USB_OTG_DTHRCTL_TXTHRLEN_Msk            (0x1FFUL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x000007FC */
-#define USB_OTG_DTHRCTL_TXTHRLEN                USB_OTG_DTHRCTL_TXTHRLEN_Msk   /*!< Transmit threshold length */
-#define USB_OTG_DTHRCTL_TXTHRLEN_0              (0x001UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000004 */
-#define USB_OTG_DTHRCTL_TXTHRLEN_1              (0x002UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000008 */
-#define USB_OTG_DTHRCTL_TXTHRLEN_2              (0x004UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000010 */
-#define USB_OTG_DTHRCTL_TXTHRLEN_3              (0x008UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000020 */
-#define USB_OTG_DTHRCTL_TXTHRLEN_4              (0x010UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000040 */
-#define USB_OTG_DTHRCTL_TXTHRLEN_5              (0x020UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000080 */
-#define USB_OTG_DTHRCTL_TXTHRLEN_6              (0x040UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000100 */
-#define USB_OTG_DTHRCTL_TXTHRLEN_7              (0x080UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000200 */
-#define USB_OTG_DTHRCTL_TXTHRLEN_8              (0x100UL << USB_OTG_DTHRCTL_TXTHRLEN_Pos) /*!< 0x00000400 */
-#define USB_OTG_DTHRCTL_RXTHREN_Pos             (16U)                          
-#define USB_OTG_DTHRCTL_RXTHREN_Msk             (0x1UL << USB_OTG_DTHRCTL_RXTHREN_Pos) /*!< 0x00010000 */
-#define USB_OTG_DTHRCTL_RXTHREN                 USB_OTG_DTHRCTL_RXTHREN_Msk    /*!< Receive threshold enable */
-
-#define USB_OTG_DTHRCTL_RXTHRLEN_Pos            (17U)                          
-#define USB_OTG_DTHRCTL_RXTHRLEN_Msk            (0x1FFUL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x03FE0000 */
-#define USB_OTG_DTHRCTL_RXTHRLEN                USB_OTG_DTHRCTL_RXTHRLEN_Msk   /*!< Receive threshold length */
-#define USB_OTG_DTHRCTL_RXTHRLEN_0              (0x001UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00020000 */
-#define USB_OTG_DTHRCTL_RXTHRLEN_1              (0x002UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00040000 */
-#define USB_OTG_DTHRCTL_RXTHRLEN_2              (0x004UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00080000 */
-#define USB_OTG_DTHRCTL_RXTHRLEN_3              (0x008UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00100000 */
-#define USB_OTG_DTHRCTL_RXTHRLEN_4              (0x010UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00200000 */
-#define USB_OTG_DTHRCTL_RXTHRLEN_5              (0x020UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00400000 */
-#define USB_OTG_DTHRCTL_RXTHRLEN_6              (0x040UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x00800000 */
-#define USB_OTG_DTHRCTL_RXTHRLEN_7              (0x080UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x01000000 */
-#define USB_OTG_DTHRCTL_RXTHRLEN_8              (0x100UL << USB_OTG_DTHRCTL_RXTHRLEN_Pos) /*!< 0x02000000 */
-#define USB_OTG_DTHRCTL_ARPEN_Pos               (27U)                          
-#define USB_OTG_DTHRCTL_ARPEN_Msk               (0x1UL << USB_OTG_DTHRCTL_ARPEN_Pos) /*!< 0x08000000 */
-#define USB_OTG_DTHRCTL_ARPEN                   USB_OTG_DTHRCTL_ARPEN_Msk      /*!< Arbiter parking enable */
-
-/********************  Bit definition for USB_OTG_DIEPEMPMSK register  ********************/
-#define USB_OTG_DIEPEMPMSK_INEPTXFEM_Pos        (0U)                           
-#define USB_OTG_DIEPEMPMSK_INEPTXFEM_Msk        (0xFFFFUL << USB_OTG_DIEPEMPMSK_INEPTXFEM_Pos) /*!< 0x0000FFFF */
-#define USB_OTG_DIEPEMPMSK_INEPTXFEM            USB_OTG_DIEPEMPMSK_INEPTXFEM_Msk /*!< IN EP Tx FIFO empty interrupt mask bits */
-
-/********************  Bit definition for USB_OTG_DEACHINT register  ********************/
-#define USB_OTG_DEACHINT_IEP1INT_Pos            (1U)                           
-#define USB_OTG_DEACHINT_IEP1INT_Msk            (0x1UL << USB_OTG_DEACHINT_IEP1INT_Pos) /*!< 0x00000002 */
-#define USB_OTG_DEACHINT_IEP1INT                USB_OTG_DEACHINT_IEP1INT_Msk   /*!< IN endpoint 1interrupt bit */
-#define USB_OTG_DEACHINT_OEP1INT_Pos            (17U)                          
-#define USB_OTG_DEACHINT_OEP1INT_Msk            (0x1UL << USB_OTG_DEACHINT_OEP1INT_Pos) /*!< 0x00020000 */
-#define USB_OTG_DEACHINT_OEP1INT                USB_OTG_DEACHINT_OEP1INT_Msk   /*!< OUT endpoint 1 interrupt bit */
-
-/********************  Bit definition for USB_OTG_GCCFG register  ********************/
-#define USB_OTG_GCCFG_PWRDWN_Pos                (16U)                          
-#define USB_OTG_GCCFG_PWRDWN_Msk                (0x1UL << USB_OTG_GCCFG_PWRDWN_Pos) /*!< 0x00010000 */
-#define USB_OTG_GCCFG_PWRDWN                    USB_OTG_GCCFG_PWRDWN_Msk       /*!< Power down */
-#define USB_OTG_GCCFG_VBUSASEN_Pos              (18U)                          
-#define USB_OTG_GCCFG_VBUSASEN_Msk              (0x1UL << USB_OTG_GCCFG_VBUSASEN_Pos) /*!< 0x00040000 */
-#define USB_OTG_GCCFG_VBUSASEN                  USB_OTG_GCCFG_VBUSASEN_Msk     /*!< Enable the VBUS sensing device */
-#define USB_OTG_GCCFG_VBUSBSEN_Pos              (19U)                          
-#define USB_OTG_GCCFG_VBUSBSEN_Msk              (0x1UL << USB_OTG_GCCFG_VBUSBSEN_Pos) /*!< 0x00080000 */
-#define USB_OTG_GCCFG_VBUSBSEN                  USB_OTG_GCCFG_VBUSBSEN_Msk     /*!< Enable the VBUS sensing device */
-#define USB_OTG_GCCFG_SOFOUTEN_Pos              (20U)                          
-#define USB_OTG_GCCFG_SOFOUTEN_Msk              (0x1UL << USB_OTG_GCCFG_SOFOUTEN_Pos) /*!< 0x00100000 */
-#define USB_OTG_GCCFG_SOFOUTEN                  USB_OTG_GCCFG_SOFOUTEN_Msk     /*!< SOF output enable */
-
-/********************  Bit definition for USB_OTG_DEACHINTMSK register  ********************/
-#define USB_OTG_DEACHINTMSK_IEP1INTM_Pos        (1U)                           
-#define USB_OTG_DEACHINTMSK_IEP1INTM_Msk        (0x1UL << USB_OTG_DEACHINTMSK_IEP1INTM_Pos) /*!< 0x00000002 */
-#define USB_OTG_DEACHINTMSK_IEP1INTM            USB_OTG_DEACHINTMSK_IEP1INTM_Msk /*!< IN Endpoint 1 interrupt mask bit */
-#define USB_OTG_DEACHINTMSK_OEP1INTM_Pos        (17U)                          
-#define USB_OTG_DEACHINTMSK_OEP1INTM_Msk        (0x1UL << USB_OTG_DEACHINTMSK_OEP1INTM_Pos) /*!< 0x00020000 */
-#define USB_OTG_DEACHINTMSK_OEP1INTM            USB_OTG_DEACHINTMSK_OEP1INTM_Msk /*!< OUT Endpoint 1 interrupt mask bit */
-
-/********************  Bit definition for USB_OTG_CID register  ********************/
-#define USB_OTG_CID_PRODUCT_ID_Pos              (0U)                           
-#define USB_OTG_CID_PRODUCT_ID_Msk              (0xFFFFFFFFUL << USB_OTG_CID_PRODUCT_ID_Pos) /*!< 0xFFFFFFFF */
-#define USB_OTG_CID_PRODUCT_ID                  USB_OTG_CID_PRODUCT_ID_Msk     /*!< Product ID field */
-
-/********************  Bit definition for USB_OTG_DIEPEACHMSK1 register  ********************/
-#define USB_OTG_DIEPEACHMSK1_XFRCM_Pos          (0U)                           
-#define USB_OTG_DIEPEACHMSK1_XFRCM_Msk          (0x1UL << USB_OTG_DIEPEACHMSK1_XFRCM_Pos) /*!< 0x00000001 */
-#define USB_OTG_DIEPEACHMSK1_XFRCM              USB_OTG_DIEPEACHMSK1_XFRCM_Msk /*!< Transfer completed interrupt mask */
-#define USB_OTG_DIEPEACHMSK1_EPDM_Pos           (1U)                           
-#define USB_OTG_DIEPEACHMSK1_EPDM_Msk           (0x1UL << USB_OTG_DIEPEACHMSK1_EPDM_Pos) /*!< 0x00000002 */
-#define USB_OTG_DIEPEACHMSK1_EPDM               USB_OTG_DIEPEACHMSK1_EPDM_Msk  /*!< Endpoint disabled interrupt mask */
-#define USB_OTG_DIEPEACHMSK1_TOM_Pos            (3U)                           
-#define USB_OTG_DIEPEACHMSK1_TOM_Msk            (0x1UL << USB_OTG_DIEPEACHMSK1_TOM_Pos) /*!< 0x00000008 */
-#define USB_OTG_DIEPEACHMSK1_TOM                USB_OTG_DIEPEACHMSK1_TOM_Msk   /*!< Timeout condition mask (nonisochronous endpoints) */
-#define USB_OTG_DIEPEACHMSK1_ITTXFEMSK_Pos      (4U)                           
-#define USB_OTG_DIEPEACHMSK1_ITTXFEMSK_Msk      (0x1UL << USB_OTG_DIEPEACHMSK1_ITTXFEMSK_Pos) /*!< 0x00000010 */
-#define USB_OTG_DIEPEACHMSK1_ITTXFEMSK          USB_OTG_DIEPEACHMSK1_ITTXFEMSK_Msk /*!< IN token received when TxFIFO empty mask */
-#define USB_OTG_DIEPEACHMSK1_INEPNMM_Pos        (5U)                           
-#define USB_OTG_DIEPEACHMSK1_INEPNMM_Msk        (0x1UL << USB_OTG_DIEPEACHMSK1_INEPNMM_Pos) /*!< 0x00000020 */
-#define USB_OTG_DIEPEACHMSK1_INEPNMM            USB_OTG_DIEPEACHMSK1_INEPNMM_Msk /*!< IN token received with EP mismatch mask */
-#define USB_OTG_DIEPEACHMSK1_INEPNEM_Pos        (6U)                           
-#define USB_OTG_DIEPEACHMSK1_INEPNEM_Msk        (0x1UL << USB_OTG_DIEPEACHMSK1_INEPNEM_Pos) /*!< 0x00000040 */
-#define USB_OTG_DIEPEACHMSK1_INEPNEM            USB_OTG_DIEPEACHMSK1_INEPNEM_Msk /*!< IN endpoint NAK effective mask */
-#define USB_OTG_DIEPEACHMSK1_TXFURM_Pos         (8U)                           
-#define USB_OTG_DIEPEACHMSK1_TXFURM_Msk         (0x1UL << USB_OTG_DIEPEACHMSK1_TXFURM_Pos) /*!< 0x00000100 */
-#define USB_OTG_DIEPEACHMSK1_TXFURM             USB_OTG_DIEPEACHMSK1_TXFURM_Msk /*!< FIFO underrun mask */
-#define USB_OTG_DIEPEACHMSK1_BIM_Pos            (9U)                           
-#define USB_OTG_DIEPEACHMSK1_BIM_Msk            (0x1UL << USB_OTG_DIEPEACHMSK1_BIM_Pos) /*!< 0x00000200 */
-#define USB_OTG_DIEPEACHMSK1_BIM                USB_OTG_DIEPEACHMSK1_BIM_Msk   /*!< BNA interrupt mask */
-#define USB_OTG_DIEPEACHMSK1_NAKM_Pos           (13U)                          
-#define USB_OTG_DIEPEACHMSK1_NAKM_Msk           (0x1UL << USB_OTG_DIEPEACHMSK1_NAKM_Pos) /*!< 0x00002000 */
-#define USB_OTG_DIEPEACHMSK1_NAKM               USB_OTG_DIEPEACHMSK1_NAKM_Msk  /*!< NAK interrupt mask */
-
-/********************  Bit definition for USB_OTG_HPRT register  ********************/
-#define USB_OTG_HPRT_PCSTS_Pos                  (0U)                           
-#define USB_OTG_HPRT_PCSTS_Msk                  (0x1UL << USB_OTG_HPRT_PCSTS_Pos) /*!< 0x00000001 */
-#define USB_OTG_HPRT_PCSTS                      USB_OTG_HPRT_PCSTS_Msk         /*!< Port connect status */
-#define USB_OTG_HPRT_PCDET_Pos                  (1U)                           
-#define USB_OTG_HPRT_PCDET_Msk                  (0x1UL << USB_OTG_HPRT_PCDET_Pos) /*!< 0x00000002 */
-#define USB_OTG_HPRT_PCDET                      USB_OTG_HPRT_PCDET_Msk         /*!< Port connect detected */
-#define USB_OTG_HPRT_PENA_Pos                   (2U)                           
-#define USB_OTG_HPRT_PENA_Msk                   (0x1UL << USB_OTG_HPRT_PENA_Pos) /*!< 0x00000004 */
-#define USB_OTG_HPRT_PENA                       USB_OTG_HPRT_PENA_Msk          /*!< Port enable */
-#define USB_OTG_HPRT_PENCHNG_Pos                (3U)                           
-#define USB_OTG_HPRT_PENCHNG_Msk                (0x1UL << USB_OTG_HPRT_PENCHNG_Pos) /*!< 0x00000008 */
-#define USB_OTG_HPRT_PENCHNG                    USB_OTG_HPRT_PENCHNG_Msk       /*!< Port enable/disable change */
-#define USB_OTG_HPRT_POCA_Pos                   (4U)                           
-#define USB_OTG_HPRT_POCA_Msk                   (0x1UL << USB_OTG_HPRT_POCA_Pos) /*!< 0x00000010 */
-#define USB_OTG_HPRT_POCA                       USB_OTG_HPRT_POCA_Msk          /*!< Port overcurrent active */
-#define USB_OTG_HPRT_POCCHNG_Pos                (5U)                           
-#define USB_OTG_HPRT_POCCHNG_Msk                (0x1UL << USB_OTG_HPRT_POCCHNG_Pos) /*!< 0x00000020 */
-#define USB_OTG_HPRT_POCCHNG                    USB_OTG_HPRT_POCCHNG_Msk       /*!< Port overcurrent change */
-#define USB_OTG_HPRT_PRES_Pos                   (6U)                           
-#define USB_OTG_HPRT_PRES_Msk                   (0x1UL << USB_OTG_HPRT_PRES_Pos) /*!< 0x00000040 */
-#define USB_OTG_HPRT_PRES                       USB_OTG_HPRT_PRES_Msk          /*!< Port resume */
-#define USB_OTG_HPRT_PSUSP_Pos                  (7U)                           
-#define USB_OTG_HPRT_PSUSP_Msk                  (0x1UL << USB_OTG_HPRT_PSUSP_Pos) /*!< 0x00000080 */
-#define USB_OTG_HPRT_PSUSP                      USB_OTG_HPRT_PSUSP_Msk         /*!< Port suspend */
-#define USB_OTG_HPRT_PRST_Pos                   (8U)                           
-#define USB_OTG_HPRT_PRST_Msk                   (0x1UL << USB_OTG_HPRT_PRST_Pos) /*!< 0x00000100 */
-#define USB_OTG_HPRT_PRST                       USB_OTG_HPRT_PRST_Msk          /*!< Port reset */
-
-#define USB_OTG_HPRT_PLSTS_Pos                  (10U)                          
-#define USB_OTG_HPRT_PLSTS_Msk                  (0x3UL << USB_OTG_HPRT_PLSTS_Pos) /*!< 0x00000C00 */
-#define USB_OTG_HPRT_PLSTS                      USB_OTG_HPRT_PLSTS_Msk         /*!< Port line status */
-#define USB_OTG_HPRT_PLSTS_0                    (0x1UL << USB_OTG_HPRT_PLSTS_Pos) /*!< 0x00000400 */
-#define USB_OTG_HPRT_PLSTS_1                    (0x2UL << USB_OTG_HPRT_PLSTS_Pos) /*!< 0x00000800 */
-#define USB_OTG_HPRT_PPWR_Pos                   (12U)                          
-#define USB_OTG_HPRT_PPWR_Msk                   (0x1UL << USB_OTG_HPRT_PPWR_Pos) /*!< 0x00001000 */
-#define USB_OTG_HPRT_PPWR                       USB_OTG_HPRT_PPWR_Msk          /*!< Port power */
-
-#define USB_OTG_HPRT_PTCTL_Pos                  (13U)                          
-#define USB_OTG_HPRT_PTCTL_Msk                  (0xFUL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x0001E000 */
-#define USB_OTG_HPRT_PTCTL                      USB_OTG_HPRT_PTCTL_Msk         /*!< Port test control */
-#define USB_OTG_HPRT_PTCTL_0                    (0x1UL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x00002000 */
-#define USB_OTG_HPRT_PTCTL_1                    (0x2UL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x00004000 */
-#define USB_OTG_HPRT_PTCTL_2                    (0x4UL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x00008000 */
-#define USB_OTG_HPRT_PTCTL_3                    (0x8UL << USB_OTG_HPRT_PTCTL_Pos) /*!< 0x00010000 */
-
-#define USB_OTG_HPRT_PSPD_Pos                   (17U)                          
-#define USB_OTG_HPRT_PSPD_Msk                   (0x3UL << USB_OTG_HPRT_PSPD_Pos) /*!< 0x00060000 */
-#define USB_OTG_HPRT_PSPD                       USB_OTG_HPRT_PSPD_Msk          /*!< Port speed */
-#define USB_OTG_HPRT_PSPD_0                     (0x1UL << USB_OTG_HPRT_PSPD_Pos) /*!< 0x00020000 */
-#define USB_OTG_HPRT_PSPD_1                     (0x2UL << USB_OTG_HPRT_PSPD_Pos) /*!< 0x00040000 */
-
-/********************  Bit definition for USB_OTG_DOEPEACHMSK1 register  ********************/
-#define USB_OTG_DOEPEACHMSK1_XFRCM_Pos          (0U)                           
-#define USB_OTG_DOEPEACHMSK1_XFRCM_Msk          (0x1UL << USB_OTG_DOEPEACHMSK1_XFRCM_Pos) /*!< 0x00000001 */
-#define USB_OTG_DOEPEACHMSK1_XFRCM              USB_OTG_DOEPEACHMSK1_XFRCM_Msk /*!< Transfer completed interrupt mask */
-#define USB_OTG_DOEPEACHMSK1_EPDM_Pos           (1U)                           
-#define USB_OTG_DOEPEACHMSK1_EPDM_Msk           (0x1UL << USB_OTG_DOEPEACHMSK1_EPDM_Pos) /*!< 0x00000002 */
-#define USB_OTG_DOEPEACHMSK1_EPDM               USB_OTG_DOEPEACHMSK1_EPDM_Msk  /*!< Endpoint disabled interrupt mask */
-#define USB_OTG_DOEPEACHMSK1_TOM_Pos            (3U)                           
-#define USB_OTG_DOEPEACHMSK1_TOM_Msk            (0x1UL << USB_OTG_DOEPEACHMSK1_TOM_Pos) /*!< 0x00000008 */
-#define USB_OTG_DOEPEACHMSK1_TOM                USB_OTG_DOEPEACHMSK1_TOM_Msk   /*!< Timeout condition mask */
-#define USB_OTG_DOEPEACHMSK1_ITTXFEMSK_Pos      (4U)                           
-#define USB_OTG_DOEPEACHMSK1_ITTXFEMSK_Msk      (0x1UL << USB_OTG_DOEPEACHMSK1_ITTXFEMSK_Pos) /*!< 0x00000010 */
-#define USB_OTG_DOEPEACHMSK1_ITTXFEMSK          USB_OTG_DOEPEACHMSK1_ITTXFEMSK_Msk /*!< IN token received when TxFIFO empty mask */
-#define USB_OTG_DOEPEACHMSK1_INEPNMM_Pos        (5U)                           
-#define USB_OTG_DOEPEACHMSK1_INEPNMM_Msk        (0x1UL << USB_OTG_DOEPEACHMSK1_INEPNMM_Pos) /*!< 0x00000020 */
-#define USB_OTG_DOEPEACHMSK1_INEPNMM            USB_OTG_DOEPEACHMSK1_INEPNMM_Msk /*!< IN token received with EP mismatch mask */
-#define USB_OTG_DOEPEACHMSK1_INEPNEM_Pos        (6U)                           
-#define USB_OTG_DOEPEACHMSK1_INEPNEM_Msk        (0x1UL << USB_OTG_DOEPEACHMSK1_INEPNEM_Pos) /*!< 0x00000040 */
-#define USB_OTG_DOEPEACHMSK1_INEPNEM            USB_OTG_DOEPEACHMSK1_INEPNEM_Msk /*!< IN endpoint NAK effective mask */
-#define USB_OTG_DOEPEACHMSK1_TXFURM_Pos         (8U)                           
-#define USB_OTG_DOEPEACHMSK1_TXFURM_Msk         (0x1UL << USB_OTG_DOEPEACHMSK1_TXFURM_Pos) /*!< 0x00000100 */
-#define USB_OTG_DOEPEACHMSK1_TXFURM             USB_OTG_DOEPEACHMSK1_TXFURM_Msk /*!< OUT packet error mask */
-#define USB_OTG_DOEPEACHMSK1_BIM_Pos            (9U)                           
-#define USB_OTG_DOEPEACHMSK1_BIM_Msk            (0x1UL << USB_OTG_DOEPEACHMSK1_BIM_Pos) /*!< 0x00000200 */
-#define USB_OTG_DOEPEACHMSK1_BIM                USB_OTG_DOEPEACHMSK1_BIM_Msk   /*!< BNA interrupt mask */
-#define USB_OTG_DOEPEACHMSK1_BERRM_Pos          (12U)                          
-#define USB_OTG_DOEPEACHMSK1_BERRM_Msk          (0x1UL << USB_OTG_DOEPEACHMSK1_BERRM_Pos) /*!< 0x00001000 */
-#define USB_OTG_DOEPEACHMSK1_BERRM              USB_OTG_DOEPEACHMSK1_BERRM_Msk /*!< Bubble error interrupt mask */
-#define USB_OTG_DOEPEACHMSK1_NAKM_Pos           (13U)                          
-#define USB_OTG_DOEPEACHMSK1_NAKM_Msk           (0x1UL << USB_OTG_DOEPEACHMSK1_NAKM_Pos) /*!< 0x00002000 */
-#define USB_OTG_DOEPEACHMSK1_NAKM               USB_OTG_DOEPEACHMSK1_NAKM_Msk  /*!< NAK interrupt mask */
-#define USB_OTG_DOEPEACHMSK1_NYETM_Pos          (14U)                          
-#define USB_OTG_DOEPEACHMSK1_NYETM_Msk          (0x1UL << USB_OTG_DOEPEACHMSK1_NYETM_Pos) /*!< 0x00004000 */
-#define USB_OTG_DOEPEACHMSK1_NYETM              USB_OTG_DOEPEACHMSK1_NYETM_Msk /*!< NYET interrupt mask */
-
-/********************  Bit definition for USB_OTG_HPTXFSIZ register  ********************/
-#define USB_OTG_HPTXFSIZ_PTXSA_Pos              (0U)                           
-#define USB_OTG_HPTXFSIZ_PTXSA_Msk              (0xFFFFUL << USB_OTG_HPTXFSIZ_PTXSA_Pos) /*!< 0x0000FFFF */
-#define USB_OTG_HPTXFSIZ_PTXSA                  USB_OTG_HPTXFSIZ_PTXSA_Msk     /*!< Host periodic TxFIFO start address */
-#define USB_OTG_HPTXFSIZ_PTXFD_Pos              (16U)                          
-#define USB_OTG_HPTXFSIZ_PTXFD_Msk              (0xFFFFUL << USB_OTG_HPTXFSIZ_PTXFD_Pos) /*!< 0xFFFF0000 */
-#define USB_OTG_HPTXFSIZ_PTXFD                  USB_OTG_HPTXFSIZ_PTXFD_Msk     /*!< Host periodic TxFIFO depth */
-
-/********************  Bit definition for USB_OTG_DIEPCTL register  ********************/
-#define USB_OTG_DIEPCTL_MPSIZ_Pos               (0U)                           
-#define USB_OTG_DIEPCTL_MPSIZ_Msk               (0x7FFUL << USB_OTG_DIEPCTL_MPSIZ_Pos) /*!< 0x000007FF */
-#define USB_OTG_DIEPCTL_MPSIZ                   USB_OTG_DIEPCTL_MPSIZ_Msk      /*!< Maximum packet size */
-#define USB_OTG_DIEPCTL_USBAEP_Pos              (15U)                          
-#define USB_OTG_DIEPCTL_USBAEP_Msk              (0x1UL << USB_OTG_DIEPCTL_USBAEP_Pos) /*!< 0x00008000 */
-#define USB_OTG_DIEPCTL_USBAEP                  USB_OTG_DIEPCTL_USBAEP_Msk     /*!< USB active endpoint */
-#define USB_OTG_DIEPCTL_EONUM_DPID_Pos          (16U)                          
-#define USB_OTG_DIEPCTL_EONUM_DPID_Msk          (0x1UL << USB_OTG_DIEPCTL_EONUM_DPID_Pos) /*!< 0x00010000 */
-#define USB_OTG_DIEPCTL_EONUM_DPID              USB_OTG_DIEPCTL_EONUM_DPID_Msk /*!< Even/odd frame */
-#define USB_OTG_DIEPCTL_NAKSTS_Pos              (17U)                          
-#define USB_OTG_DIEPCTL_NAKSTS_Msk              (0x1UL << USB_OTG_DIEPCTL_NAKSTS_Pos) /*!< 0x00020000 */
-#define USB_OTG_DIEPCTL_NAKSTS                  USB_OTG_DIEPCTL_NAKSTS_Msk     /*!< NAK status */
-
-#define USB_OTG_DIEPCTL_EPTYP_Pos               (18U)                          
-#define USB_OTG_DIEPCTL_EPTYP_Msk               (0x3UL << USB_OTG_DIEPCTL_EPTYP_Pos) /*!< 0x000C0000 */
-#define USB_OTG_DIEPCTL_EPTYP                   USB_OTG_DIEPCTL_EPTYP_Msk      /*!< Endpoint type */
-#define USB_OTG_DIEPCTL_EPTYP_0                 (0x1UL << USB_OTG_DIEPCTL_EPTYP_Pos) /*!< 0x00040000 */
-#define USB_OTG_DIEPCTL_EPTYP_1                 (0x2UL << USB_OTG_DIEPCTL_EPTYP_Pos) /*!< 0x00080000 */
-#define USB_OTG_DIEPCTL_STALL_Pos               (21U)                          
-#define USB_OTG_DIEPCTL_STALL_Msk               (0x1UL << USB_OTG_DIEPCTL_STALL_Pos) /*!< 0x00200000 */
-#define USB_OTG_DIEPCTL_STALL                   USB_OTG_DIEPCTL_STALL_Msk      /*!< STALL handshake */
-
-#define USB_OTG_DIEPCTL_TXFNUM_Pos              (22U)                          
-#define USB_OTG_DIEPCTL_TXFNUM_Msk              (0xFUL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x03C00000 */
-#define USB_OTG_DIEPCTL_TXFNUM                  USB_OTG_DIEPCTL_TXFNUM_Msk     /*!< TxFIFO number */
-#define USB_OTG_DIEPCTL_TXFNUM_0                (0x1UL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x00400000 */
-#define USB_OTG_DIEPCTL_TXFNUM_1                (0x2UL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x00800000 */
-#define USB_OTG_DIEPCTL_TXFNUM_2                (0x4UL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x01000000 */
-#define USB_OTG_DIEPCTL_TXFNUM_3                (0x8UL << USB_OTG_DIEPCTL_TXFNUM_Pos) /*!< 0x02000000 */
-#define USB_OTG_DIEPCTL_CNAK_Pos                (26U)                          
-#define USB_OTG_DIEPCTL_CNAK_Msk                (0x1UL << USB_OTG_DIEPCTL_CNAK_Pos) /*!< 0x04000000 */
-#define USB_OTG_DIEPCTL_CNAK                    USB_OTG_DIEPCTL_CNAK_Msk       /*!< Clear NAK */
-#define USB_OTG_DIEPCTL_SNAK_Pos                (27U)                          
-#define USB_OTG_DIEPCTL_SNAK_Msk                (0x1UL << USB_OTG_DIEPCTL_SNAK_Pos) /*!< 0x08000000 */
-#define USB_OTG_DIEPCTL_SNAK                    USB_OTG_DIEPCTL_SNAK_Msk       /*!< Set NAK */
-#define USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Pos      (28U)                          
-#define USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Msk      (0x1UL << USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Pos) /*!< 0x10000000 */
-#define USB_OTG_DIEPCTL_SD0PID_SEVNFRM          USB_OTG_DIEPCTL_SD0PID_SEVNFRM_Msk /*!< Set DATA0 PID */
-#define USB_OTG_DIEPCTL_SODDFRM_Pos             (29U)                          
-#define USB_OTG_DIEPCTL_SODDFRM_Msk             (0x1UL << USB_OTG_DIEPCTL_SODDFRM_Pos) /*!< 0x20000000 */
-#define USB_OTG_DIEPCTL_SODDFRM                 USB_OTG_DIEPCTL_SODDFRM_Msk    /*!< Set odd frame */
-#define USB_OTG_DIEPCTL_EPDIS_Pos               (30U)                          
-#define USB_OTG_DIEPCTL_EPDIS_Msk               (0x1UL << USB_OTG_DIEPCTL_EPDIS_Pos) /*!< 0x40000000 */
-#define USB_OTG_DIEPCTL_EPDIS                   USB_OTG_DIEPCTL_EPDIS_Msk      /*!< Endpoint disable */
-#define USB_OTG_DIEPCTL_EPENA_Pos               (31U)                          
-#define USB_OTG_DIEPCTL_EPENA_Msk               (0x1UL << USB_OTG_DIEPCTL_EPENA_Pos) /*!< 0x80000000 */
-#define USB_OTG_DIEPCTL_EPENA                   USB_OTG_DIEPCTL_EPENA_Msk      /*!< Endpoint enable */
-
-/********************  Bit definition for USB_OTG_HCCHAR register  ********************/
-#define USB_OTG_HCCHAR_MPSIZ_Pos                (0U)                           
-#define USB_OTG_HCCHAR_MPSIZ_Msk                (0x7FFUL << USB_OTG_HCCHAR_MPSIZ_Pos) /*!< 0x000007FF */
-#define USB_OTG_HCCHAR_MPSIZ                    USB_OTG_HCCHAR_MPSIZ_Msk       /*!< Maximum packet size */
-
-#define USB_OTG_HCCHAR_EPNUM_Pos                (11U)                          
-#define USB_OTG_HCCHAR_EPNUM_Msk                (0xFUL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00007800 */
-#define USB_OTG_HCCHAR_EPNUM                    USB_OTG_HCCHAR_EPNUM_Msk       /*!< Endpoint number */
-#define USB_OTG_HCCHAR_EPNUM_0                  (0x1UL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00000800 */
-#define USB_OTG_HCCHAR_EPNUM_1                  (0x2UL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00001000 */
-#define USB_OTG_HCCHAR_EPNUM_2                  (0x4UL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00002000 */
-#define USB_OTG_HCCHAR_EPNUM_3                  (0x8UL << USB_OTG_HCCHAR_EPNUM_Pos) /*!< 0x00004000 */
-#define USB_OTG_HCCHAR_EPDIR_Pos                (15U)                          
-#define USB_OTG_HCCHAR_EPDIR_Msk                (0x1UL << USB_OTG_HCCHAR_EPDIR_Pos) /*!< 0x00008000 */
-#define USB_OTG_HCCHAR_EPDIR                    USB_OTG_HCCHAR_EPDIR_Msk       /*!< Endpoint direction */
-#define USB_OTG_HCCHAR_LSDEV_Pos                (17U)                          
-#define USB_OTG_HCCHAR_LSDEV_Msk                (0x1UL << USB_OTG_HCCHAR_LSDEV_Pos) /*!< 0x00020000 */
-#define USB_OTG_HCCHAR_LSDEV                    USB_OTG_HCCHAR_LSDEV_Msk       /*!< Low-speed device */
-
-#define USB_OTG_HCCHAR_EPTYP_Pos                (18U)                          
-#define USB_OTG_HCCHAR_EPTYP_Msk                (0x3UL << USB_OTG_HCCHAR_EPTYP_Pos) /*!< 0x000C0000 */
-#define USB_OTG_HCCHAR_EPTYP                    USB_OTG_HCCHAR_EPTYP_Msk       /*!< Endpoint type */
-#define USB_OTG_HCCHAR_EPTYP_0                  (0x1UL << USB_OTG_HCCHAR_EPTYP_Pos) /*!< 0x00040000 */
-#define USB_OTG_HCCHAR_EPTYP_1                  (0x2UL << USB_OTG_HCCHAR_EPTYP_Pos) /*!< 0x00080000 */
-                                      
-#define USB_OTG_HCCHAR_MC_Pos                   (20U)                          
-#define USB_OTG_HCCHAR_MC_Msk                   (0x3UL << USB_OTG_HCCHAR_MC_Pos) /*!< 0x00300000 */
-#define USB_OTG_HCCHAR_MC                       USB_OTG_HCCHAR_MC_Msk          /*!< Multi Count (MC) / Error Count (EC) */
-#define USB_OTG_HCCHAR_MC_0                     (0x1UL << USB_OTG_HCCHAR_MC_Pos) /*!< 0x00100000 */
-#define USB_OTG_HCCHAR_MC_1                     (0x2UL << USB_OTG_HCCHAR_MC_Pos) /*!< 0x00200000 */
-
-#define USB_OTG_HCCHAR_DAD_Pos                  (22U)                          
-#define USB_OTG_HCCHAR_DAD_Msk                  (0x7FUL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x1FC00000 */
-#define USB_OTG_HCCHAR_DAD                      USB_OTG_HCCHAR_DAD_Msk         /*!< Device address */
-#define USB_OTG_HCCHAR_DAD_0                    (0x01UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x00400000 */
-#define USB_OTG_HCCHAR_DAD_1                    (0x02UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x00800000 */
-#define USB_OTG_HCCHAR_DAD_2                    (0x04UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x01000000 */
-#define USB_OTG_HCCHAR_DAD_3                    (0x08UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x02000000 */
-#define USB_OTG_HCCHAR_DAD_4                    (0x10UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x04000000 */
-#define USB_OTG_HCCHAR_DAD_5                    (0x20UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x08000000 */
-#define USB_OTG_HCCHAR_DAD_6                    (0x40UL << USB_OTG_HCCHAR_DAD_Pos) /*!< 0x10000000 */
-#define USB_OTG_HCCHAR_ODDFRM_Pos               (29U)                          
-#define USB_OTG_HCCHAR_ODDFRM_Msk               (0x1UL << USB_OTG_HCCHAR_ODDFRM_Pos) /*!< 0x20000000 */
-#define USB_OTG_HCCHAR_ODDFRM                   USB_OTG_HCCHAR_ODDFRM_Msk      /*!< Odd frame */
-#define USB_OTG_HCCHAR_CHDIS_Pos                (30U)                          
-#define USB_OTG_HCCHAR_CHDIS_Msk                (0x1UL << USB_OTG_HCCHAR_CHDIS_Pos) /*!< 0x40000000 */
-#define USB_OTG_HCCHAR_CHDIS                    USB_OTG_HCCHAR_CHDIS_Msk       /*!< Channel disable */
-#define USB_OTG_HCCHAR_CHENA_Pos                (31U)                          
-#define USB_OTG_HCCHAR_CHENA_Msk                (0x1UL << USB_OTG_HCCHAR_CHENA_Pos) /*!< 0x80000000 */
-#define USB_OTG_HCCHAR_CHENA                    USB_OTG_HCCHAR_CHENA_Msk       /*!< Channel enable */
-
-/********************  Bit definition for USB_OTG_HCSPLT register  ********************/
-
-#define USB_OTG_HCSPLT_PRTADDR_Pos              (0U)                           
-#define USB_OTG_HCSPLT_PRTADDR_Msk              (0x7FUL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x0000007F */
-#define USB_OTG_HCSPLT_PRTADDR                  USB_OTG_HCSPLT_PRTADDR_Msk     /*!< Port address */
-#define USB_OTG_HCSPLT_PRTADDR_0                (0x01UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000001 */
-#define USB_OTG_HCSPLT_PRTADDR_1                (0x02UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000002 */
-#define USB_OTG_HCSPLT_PRTADDR_2                (0x04UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000004 */
-#define USB_OTG_HCSPLT_PRTADDR_3                (0x08UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000008 */
-#define USB_OTG_HCSPLT_PRTADDR_4                (0x10UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000010 */
-#define USB_OTG_HCSPLT_PRTADDR_5                (0x20UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000020 */
-#define USB_OTG_HCSPLT_PRTADDR_6                (0x40UL << USB_OTG_HCSPLT_PRTADDR_Pos) /*!< 0x00000040 */
-
-#define USB_OTG_HCSPLT_HUBADDR_Pos              (7U)                           
-#define USB_OTG_HCSPLT_HUBADDR_Msk              (0x7FUL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00003F80 */
-#define USB_OTG_HCSPLT_HUBADDR                  USB_OTG_HCSPLT_HUBADDR_Msk     /*!< Hub address */
-#define USB_OTG_HCSPLT_HUBADDR_0                (0x01UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000080 */
-#define USB_OTG_HCSPLT_HUBADDR_1                (0x02UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000100 */
-#define USB_OTG_HCSPLT_HUBADDR_2                (0x04UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000200 */
-#define USB_OTG_HCSPLT_HUBADDR_3                (0x08UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000400 */
-#define USB_OTG_HCSPLT_HUBADDR_4                (0x10UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00000800 */
-#define USB_OTG_HCSPLT_HUBADDR_5                (0x20UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00001000 */
-#define USB_OTG_HCSPLT_HUBADDR_6                (0x40UL << USB_OTG_HCSPLT_HUBADDR_Pos) /*!< 0x00002000 */
-
-#define USB_OTG_HCSPLT_XACTPOS_Pos              (14U)                          
-#define USB_OTG_HCSPLT_XACTPOS_Msk              (0x3UL << USB_OTG_HCSPLT_XACTPOS_Pos) /*!< 0x0000C000 */
-#define USB_OTG_HCSPLT_XACTPOS                  USB_OTG_HCSPLT_XACTPOS_Msk     /*!< XACTPOS */
-#define USB_OTG_HCSPLT_XACTPOS_0                (0x1UL << USB_OTG_HCSPLT_XACTPOS_Pos) /*!< 0x00004000 */
-#define USB_OTG_HCSPLT_XACTPOS_1                (0x2UL << USB_OTG_HCSPLT_XACTPOS_Pos) /*!< 0x00008000 */
-#define USB_OTG_HCSPLT_COMPLSPLT_Pos            (16U)                          
-#define USB_OTG_HCSPLT_COMPLSPLT_Msk            (0x1UL << USB_OTG_HCSPLT_COMPLSPLT_Pos) /*!< 0x00010000 */
-#define USB_OTG_HCSPLT_COMPLSPLT                USB_OTG_HCSPLT_COMPLSPLT_Msk   /*!< Do complete split */
-#define USB_OTG_HCSPLT_SPLITEN_Pos              (31U)                          
-#define USB_OTG_HCSPLT_SPLITEN_Msk              (0x1UL << USB_OTG_HCSPLT_SPLITEN_Pos) /*!< 0x80000000 */
-#define USB_OTG_HCSPLT_SPLITEN                  USB_OTG_HCSPLT_SPLITEN_Msk     /*!< Split enable */
-
-/********************  Bit definition for USB_OTG_HCINT register  ********************/
-#define USB_OTG_HCINT_XFRC_Pos                  (0U)                           
-#define USB_OTG_HCINT_XFRC_Msk                  (0x1UL << USB_OTG_HCINT_XFRC_Pos) /*!< 0x00000001 */
-#define USB_OTG_HCINT_XFRC                      USB_OTG_HCINT_XFRC_Msk         /*!< Transfer completed */
-#define USB_OTG_HCINT_CHH_Pos                   (1U)                           
-#define USB_OTG_HCINT_CHH_Msk                   (0x1UL << USB_OTG_HCINT_CHH_Pos) /*!< 0x00000002 */
-#define USB_OTG_HCINT_CHH                       USB_OTG_HCINT_CHH_Msk          /*!< Channel halted */
-#define USB_OTG_HCINT_AHBERR_Pos                (2U)                           
-#define USB_OTG_HCINT_AHBERR_Msk                (0x1UL << USB_OTG_HCINT_AHBERR_Pos) /*!< 0x00000004 */
-#define USB_OTG_HCINT_AHBERR                    USB_OTG_HCINT_AHBERR_Msk       /*!< AHB error */
-#define USB_OTG_HCINT_STALL_Pos                 (3U)                           
-#define USB_OTG_HCINT_STALL_Msk                 (0x1UL << USB_OTG_HCINT_STALL_Pos) /*!< 0x00000008 */
-#define USB_OTG_HCINT_STALL                     USB_OTG_HCINT_STALL_Msk        /*!< STALL response received interrupt */
-#define USB_OTG_HCINT_NAK_Pos                   (4U)                           
-#define USB_OTG_HCINT_NAK_Msk                   (0x1UL << USB_OTG_HCINT_NAK_Pos) /*!< 0x00000010 */
-#define USB_OTG_HCINT_NAK                       USB_OTG_HCINT_NAK_Msk          /*!< NAK response received interrupt */
-#define USB_OTG_HCINT_ACK_Pos                   (5U)                           
-#define USB_OTG_HCINT_ACK_Msk                   (0x1UL << USB_OTG_HCINT_ACK_Pos) /*!< 0x00000020 */
-#define USB_OTG_HCINT_ACK                       USB_OTG_HCINT_ACK_Msk          /*!< ACK response received/transmitted interrupt */
-#define USB_OTG_HCINT_NYET_Pos                  (6U)                           
-#define USB_OTG_HCINT_NYET_Msk                  (0x1UL << USB_OTG_HCINT_NYET_Pos) /*!< 0x00000040 */
-#define USB_OTG_HCINT_NYET                      USB_OTG_HCINT_NYET_Msk         /*!< Response received interrupt */
-#define USB_OTG_HCINT_TXERR_Pos                 (7U)                           
-#define USB_OTG_HCINT_TXERR_Msk                 (0x1UL << USB_OTG_HCINT_TXERR_Pos) /*!< 0x00000080 */
-#define USB_OTG_HCINT_TXERR                     USB_OTG_HCINT_TXERR_Msk        /*!< Transaction error */
-#define USB_OTG_HCINT_BBERR_Pos                 (8U)                           
-#define USB_OTG_HCINT_BBERR_Msk                 (0x1UL << USB_OTG_HCINT_BBERR_Pos) /*!< 0x00000100 */
-#define USB_OTG_HCINT_BBERR                     USB_OTG_HCINT_BBERR_Msk        /*!< Babble error */
-#define USB_OTG_HCINT_FRMOR_Pos                 (9U)                           
-#define USB_OTG_HCINT_FRMOR_Msk                 (0x1UL << USB_OTG_HCINT_FRMOR_Pos) /*!< 0x00000200 */
-#define USB_OTG_HCINT_FRMOR                     USB_OTG_HCINT_FRMOR_Msk        /*!< Frame overrun */
-#define USB_OTG_HCINT_DTERR_Pos                 (10U)                          
-#define USB_OTG_HCINT_DTERR_Msk                 (0x1UL << USB_OTG_HCINT_DTERR_Pos) /*!< 0x00000400 */
-#define USB_OTG_HCINT_DTERR                     USB_OTG_HCINT_DTERR_Msk        /*!< Data toggle error */
-
-/********************  Bit definition for USB_OTG_DIEPINT register  ********************/
-#define USB_OTG_DIEPINT_XFRC_Pos                (0U)                           
-#define USB_OTG_DIEPINT_XFRC_Msk                (0x1UL << USB_OTG_DIEPINT_XFRC_Pos) /*!< 0x00000001 */
-#define USB_OTG_DIEPINT_XFRC                    USB_OTG_DIEPINT_XFRC_Msk       /*!< Transfer completed interrupt */
-#define USB_OTG_DIEPINT_EPDISD_Pos              (1U)                           
-#define USB_OTG_DIEPINT_EPDISD_Msk              (0x1UL << USB_OTG_DIEPINT_EPDISD_Pos) /*!< 0x00000002 */
-#define USB_OTG_DIEPINT_EPDISD                  USB_OTG_DIEPINT_EPDISD_Msk     /*!< Endpoint disabled interrupt */
-#define USB_OTG_DIEPINT_AHBERR_Pos               (2U)
-#define USB_OTG_DIEPINT_AHBERR_Msk               (0x1UL << USB_OTG_DIEPINT_AHBERR_Pos) /*!< 0x00000004 */
-#define USB_OTG_DIEPINT_AHBERR                   USB_OTG_DIEPINT_AHBERR_Msk   /*!< AHB Error (AHBErr) during an IN transaction */
-#define USB_OTG_DIEPINT_TOC_Pos                 (3U)                           
-#define USB_OTG_DIEPINT_TOC_Msk                 (0x1UL << USB_OTG_DIEPINT_TOC_Pos) /*!< 0x00000008 */
-#define USB_OTG_DIEPINT_TOC                     USB_OTG_DIEPINT_TOC_Msk        /*!< Timeout condition */
-#define USB_OTG_DIEPINT_ITTXFE_Pos              (4U)                           
-#define USB_OTG_DIEPINT_ITTXFE_Msk              (0x1UL << USB_OTG_DIEPINT_ITTXFE_Pos) /*!< 0x00000010 */
-#define USB_OTG_DIEPINT_ITTXFE                  USB_OTG_DIEPINT_ITTXFE_Msk     /*!< IN token received when TxFIFO is empty */
-#define USB_OTG_DIEPINT_INEPNM_Pos               (5U)
-#define USB_OTG_DIEPINT_INEPNM_Msk               (0x1UL << USB_OTG_DIEPINT_INEPNM_Pos) /*!< 0x00000004 */
-#define USB_OTG_DIEPINT_INEPNM                   USB_OTG_DIEPINT_INEPNM_Msk   /*!< IN token received with EP mismatch */
-#define USB_OTG_DIEPINT_INEPNE_Pos              (6U)                           
-#define USB_OTG_DIEPINT_INEPNE_Msk              (0x1UL << USB_OTG_DIEPINT_INEPNE_Pos) /*!< 0x00000040 */
-#define USB_OTG_DIEPINT_INEPNE                  USB_OTG_DIEPINT_INEPNE_Msk     /*!< IN endpoint NAK effective */
-#define USB_OTG_DIEPINT_TXFE_Pos                (7U)                           
-#define USB_OTG_DIEPINT_TXFE_Msk                (0x1UL << USB_OTG_DIEPINT_TXFE_Pos) /*!< 0x00000080 */
-#define USB_OTG_DIEPINT_TXFE                    USB_OTG_DIEPINT_TXFE_Msk       /*!< Transmit FIFO empty */
-#define USB_OTG_DIEPINT_TXFIFOUDRN_Pos          (8U)                           
-#define USB_OTG_DIEPINT_TXFIFOUDRN_Msk          (0x1UL << USB_OTG_DIEPINT_TXFIFOUDRN_Pos) /*!< 0x00000100 */
-#define USB_OTG_DIEPINT_TXFIFOUDRN              USB_OTG_DIEPINT_TXFIFOUDRN_Msk /*!< Transmit Fifo Underrun */
-#define USB_OTG_DIEPINT_BNA_Pos                 (9U)                           
-#define USB_OTG_DIEPINT_BNA_Msk                 (0x1UL << USB_OTG_DIEPINT_BNA_Pos) /*!< 0x00000200 */
-#define USB_OTG_DIEPINT_BNA                     USB_OTG_DIEPINT_BNA_Msk        /*!< Buffer not available interrupt */
-#define USB_OTG_DIEPINT_PKTDRPSTS_Pos           (11U)                          
-#define USB_OTG_DIEPINT_PKTDRPSTS_Msk           (0x1UL << USB_OTG_DIEPINT_PKTDRPSTS_Pos) /*!< 0x00000800 */
-#define USB_OTG_DIEPINT_PKTDRPSTS               USB_OTG_DIEPINT_PKTDRPSTS_Msk  /*!< Packet dropped status */
-#define USB_OTG_DIEPINT_BERR_Pos                (12U)                          
-#define USB_OTG_DIEPINT_BERR_Msk                (0x1UL << USB_OTG_DIEPINT_BERR_Pos) /*!< 0x00001000 */
-#define USB_OTG_DIEPINT_BERR                    USB_OTG_DIEPINT_BERR_Msk       /*!< Babble error interrupt */
-#define USB_OTG_DIEPINT_NAK_Pos                 (13U)                          
-#define USB_OTG_DIEPINT_NAK_Msk                 (0x1UL << USB_OTG_DIEPINT_NAK_Pos) /*!< 0x00002000 */
-#define USB_OTG_DIEPINT_NAK                     USB_OTG_DIEPINT_NAK_Msk        /*!< NAK interrupt */
-
-/********************  Bit definition for USB_OTG_HCINTMSK register  ********************/
-#define USB_OTG_HCINTMSK_XFRCM_Pos              (0U)                           
-#define USB_OTG_HCINTMSK_XFRCM_Msk              (0x1UL << USB_OTG_HCINTMSK_XFRCM_Pos) /*!< 0x00000001 */
-#define USB_OTG_HCINTMSK_XFRCM                  USB_OTG_HCINTMSK_XFRCM_Msk     /*!< Transfer completed mask */
-#define USB_OTG_HCINTMSK_CHHM_Pos               (1U)                           
-#define USB_OTG_HCINTMSK_CHHM_Msk               (0x1UL << USB_OTG_HCINTMSK_CHHM_Pos) /*!< 0x00000002 */
-#define USB_OTG_HCINTMSK_CHHM                   USB_OTG_HCINTMSK_CHHM_Msk      /*!< Channel halted mask */
-#define USB_OTG_HCINTMSK_AHBERR_Pos             (2U)                           
-#define USB_OTG_HCINTMSK_AHBERR_Msk             (0x1UL << USB_OTG_HCINTMSK_AHBERR_Pos) /*!< 0x00000004 */
-#define USB_OTG_HCINTMSK_AHBERR                 USB_OTG_HCINTMSK_AHBERR_Msk    /*!< AHB error */
-#define USB_OTG_HCINTMSK_STALLM_Pos             (3U)                           
-#define USB_OTG_HCINTMSK_STALLM_Msk             (0x1UL << USB_OTG_HCINTMSK_STALLM_Pos) /*!< 0x00000008 */
-#define USB_OTG_HCINTMSK_STALLM                 USB_OTG_HCINTMSK_STALLM_Msk    /*!< STALL response received interrupt mask */
-#define USB_OTG_HCINTMSK_NAKM_Pos               (4U)                           
-#define USB_OTG_HCINTMSK_NAKM_Msk               (0x1UL << USB_OTG_HCINTMSK_NAKM_Pos) /*!< 0x00000010 */
-#define USB_OTG_HCINTMSK_NAKM                   USB_OTG_HCINTMSK_NAKM_Msk      /*!< NAK response received interrupt mask */
-#define USB_OTG_HCINTMSK_ACKM_Pos               (5U)                           
-#define USB_OTG_HCINTMSK_ACKM_Msk               (0x1UL << USB_OTG_HCINTMSK_ACKM_Pos) /*!< 0x00000020 */
-#define USB_OTG_HCINTMSK_ACKM                   USB_OTG_HCINTMSK_ACKM_Msk      /*!< ACK response received/transmitted interrupt mask */
-#define USB_OTG_HCINTMSK_NYET_Pos               (6U)                           
-#define USB_OTG_HCINTMSK_NYET_Msk               (0x1UL << USB_OTG_HCINTMSK_NYET_Pos) /*!< 0x00000040 */
-#define USB_OTG_HCINTMSK_NYET                   USB_OTG_HCINTMSK_NYET_Msk      /*!< response received interrupt mask */
-#define USB_OTG_HCINTMSK_TXERRM_Pos             (7U)                           
-#define USB_OTG_HCINTMSK_TXERRM_Msk             (0x1UL << USB_OTG_HCINTMSK_TXERRM_Pos) /*!< 0x00000080 */
-#define USB_OTG_HCINTMSK_TXERRM                 USB_OTG_HCINTMSK_TXERRM_Msk    /*!< Transaction error mask */
-#define USB_OTG_HCINTMSK_BBERRM_Pos             (8U)                           
-#define USB_OTG_HCINTMSK_BBERRM_Msk             (0x1UL << USB_OTG_HCINTMSK_BBERRM_Pos) /*!< 0x00000100 */
-#define USB_OTG_HCINTMSK_BBERRM                 USB_OTG_HCINTMSK_BBERRM_Msk    /*!< Babble error mask */
-#define USB_OTG_HCINTMSK_FRMORM_Pos             (9U)                           
-#define USB_OTG_HCINTMSK_FRMORM_Msk             (0x1UL << USB_OTG_HCINTMSK_FRMORM_Pos) /*!< 0x00000200 */
-#define USB_OTG_HCINTMSK_FRMORM                 USB_OTG_HCINTMSK_FRMORM_Msk    /*!< Frame overrun mask */
-#define USB_OTG_HCINTMSK_DTERRM_Pos             (10U)                          
-#define USB_OTG_HCINTMSK_DTERRM_Msk             (0x1UL << USB_OTG_HCINTMSK_DTERRM_Pos) /*!< 0x00000400 */
-#define USB_OTG_HCINTMSK_DTERRM                 USB_OTG_HCINTMSK_DTERRM_Msk    /*!< Data toggle error mask */
-
-/********************  Bit definition for USB_OTG_DIEPTSIZ register  ********************/
-
-#define USB_OTG_DIEPTSIZ_XFRSIZ_Pos             (0U)                           
-#define USB_OTG_DIEPTSIZ_XFRSIZ_Msk             (0x7FFFFUL << USB_OTG_DIEPTSIZ_XFRSIZ_Pos) /*!< 0x0007FFFF */
-#define USB_OTG_DIEPTSIZ_XFRSIZ                 USB_OTG_DIEPTSIZ_XFRSIZ_Msk    /*!< Transfer size */
-#define USB_OTG_DIEPTSIZ_PKTCNT_Pos             (19U)                          
-#define USB_OTG_DIEPTSIZ_PKTCNT_Msk             (0x3FFUL << USB_OTG_DIEPTSIZ_PKTCNT_Pos) /*!< 0x1FF80000 */
-#define USB_OTG_DIEPTSIZ_PKTCNT                 USB_OTG_DIEPTSIZ_PKTCNT_Msk    /*!< Packet count */
-#define USB_OTG_DIEPTSIZ_MULCNT_Pos             (29U)                          
-#define USB_OTG_DIEPTSIZ_MULCNT_Msk             (0x3UL << USB_OTG_DIEPTSIZ_MULCNT_Pos) /*!< 0x60000000 */
-#define USB_OTG_DIEPTSIZ_MULCNT                 USB_OTG_DIEPTSIZ_MULCNT_Msk    /*!< Packet count */
-/********************  Bit definition for USB_OTG_HCTSIZ register  ********************/
-#define USB_OTG_HCTSIZ_XFRSIZ_Pos               (0U)                           
-#define USB_OTG_HCTSIZ_XFRSIZ_Msk               (0x7FFFFUL << USB_OTG_HCTSIZ_XFRSIZ_Pos) /*!< 0x0007FFFF */
-#define USB_OTG_HCTSIZ_XFRSIZ                   USB_OTG_HCTSIZ_XFRSIZ_Msk      /*!< Transfer size */
-#define USB_OTG_HCTSIZ_PKTCNT_Pos               (19U)                          
-#define USB_OTG_HCTSIZ_PKTCNT_Msk               (0x3FFUL << USB_OTG_HCTSIZ_PKTCNT_Pos) /*!< 0x1FF80000 */
-#define USB_OTG_HCTSIZ_PKTCNT                   USB_OTG_HCTSIZ_PKTCNT_Msk      /*!< Packet count */
-#define USB_OTG_HCTSIZ_DOPING_Pos               (31U)                          
-#define USB_OTG_HCTSIZ_DOPING_Msk               (0x1UL << USB_OTG_HCTSIZ_DOPING_Pos) /*!< 0x80000000 */
-#define USB_OTG_HCTSIZ_DOPING                   USB_OTG_HCTSIZ_DOPING_Msk      /*!< Do PING */
-#define USB_OTG_HCTSIZ_DPID_Pos                 (29U)                          
-#define USB_OTG_HCTSIZ_DPID_Msk                 (0x3UL << USB_OTG_HCTSIZ_DPID_Pos) /*!< 0x60000000 */
-#define USB_OTG_HCTSIZ_DPID                     USB_OTG_HCTSIZ_DPID_Msk        /*!< Data PID */
-#define USB_OTG_HCTSIZ_DPID_0                   (0x1UL << USB_OTG_HCTSIZ_DPID_Pos) /*!< 0x20000000 */
-#define USB_OTG_HCTSIZ_DPID_1                   (0x2UL << USB_OTG_HCTSIZ_DPID_Pos) /*!< 0x40000000 */
-
-/********************  Bit definition for USB_OTG_DIEPDMA register  ********************/
-#define USB_OTG_DIEPDMA_DMAADDR_Pos             (0U)                           
-#define USB_OTG_DIEPDMA_DMAADDR_Msk             (0xFFFFFFFFUL << USB_OTG_DIEPDMA_DMAADDR_Pos) /*!< 0xFFFFFFFF */
-#define USB_OTG_DIEPDMA_DMAADDR                 USB_OTG_DIEPDMA_DMAADDR_Msk    /*!< DMA address */
-
-/********************  Bit definition for USB_OTG_HCDMA register  ********************/
-#define USB_OTG_HCDMA_DMAADDR_Pos               (0U)                           
-#define USB_OTG_HCDMA_DMAADDR_Msk               (0xFFFFFFFFUL << USB_OTG_HCDMA_DMAADDR_Pos) /*!< 0xFFFFFFFF */
-#define USB_OTG_HCDMA_DMAADDR                   USB_OTG_HCDMA_DMAADDR_Msk      /*!< DMA address */
-
-/********************  Bit definition for USB_OTG_DTXFSTS register  ********************/
-#define USB_OTG_DTXFSTS_INEPTFSAV_Pos           (0U)                           
-#define USB_OTG_DTXFSTS_INEPTFSAV_Msk           (0xFFFFUL << USB_OTG_DTXFSTS_INEPTFSAV_Pos) /*!< 0x0000FFFF */
-#define USB_OTG_DTXFSTS_INEPTFSAV                USB_OTG_DTXFSTS_INEPTFSAV_Msk /*!< IN endpoint TxFIFO space available */
-
-/********************  Bit definition for USB_OTG_DIEPTXF register  ********************/
-#define USB_OTG_DIEPTXF_INEPTXSA_Pos            (0U)                           
-#define USB_OTG_DIEPTXF_INEPTXSA_Msk            (0xFFFFUL << USB_OTG_DIEPTXF_INEPTXSA_Pos) /*!< 0x0000FFFF */
-#define USB_OTG_DIEPTXF_INEPTXSA                USB_OTG_DIEPTXF_INEPTXSA_Msk   /*!< IN endpoint FIFOx transmit RAM start address */
-#define USB_OTG_DIEPTXF_INEPTXFD_Pos            (16U)                          
-#define USB_OTG_DIEPTXF_INEPTXFD_Msk            (0xFFFFUL << USB_OTG_DIEPTXF_INEPTXFD_Pos) /*!< 0xFFFF0000 */
-#define USB_OTG_DIEPTXF_INEPTXFD                USB_OTG_DIEPTXF_INEPTXFD_Msk   /*!< IN endpoint TxFIFO depth */
-
-/********************  Bit definition for USB_OTG_DOEPCTL register  ********************/
-
-#define USB_OTG_DOEPCTL_MPSIZ_Pos               (0U)                           
-#define USB_OTG_DOEPCTL_MPSIZ_Msk               (0x7FFUL << USB_OTG_DOEPCTL_MPSIZ_Pos) /*!< 0x000007FF */
-#define USB_OTG_DOEPCTL_MPSIZ                    USB_OTG_DOEPCTL_MPSIZ_Msk     /*!< Maximum packet size */          /*!<Bit 1 */
-#define USB_OTG_DOEPCTL_USBAEP_Pos              (15U)                          
-#define USB_OTG_DOEPCTL_USBAEP_Msk              (0x1UL << USB_OTG_DOEPCTL_USBAEP_Pos) /*!< 0x00008000 */
-#define USB_OTG_DOEPCTL_USBAEP                  USB_OTG_DOEPCTL_USBAEP_Msk     /*!< USB active endpoint */
-#define USB_OTG_DOEPCTL_NAKSTS_Pos              (17U)                          
-#define USB_OTG_DOEPCTL_NAKSTS_Msk              (0x1UL << USB_OTG_DOEPCTL_NAKSTS_Pos) /*!< 0x00020000 */
-#define USB_OTG_DOEPCTL_NAKSTS                  USB_OTG_DOEPCTL_NAKSTS_Msk     /*!< NAK status */
-#define USB_OTG_DOEPCTL_SD0PID_SEVNFRM_Pos      (28U)                          
-#define USB_OTG_DOEPCTL_SD0PID_SEVNFRM_Msk      (0x1UL << USB_OTG_DOEPCTL_SD0PID_SEVNFRM_Pos) /*!< 0x10000000 */
-#define USB_OTG_DOEPCTL_SD0PID_SEVNFRM          USB_OTG_DOEPCTL_SD0PID_SEVNFRM_Msk /*!< Set DATA0 PID */
-#define USB_OTG_DOEPCTL_SODDFRM_Pos             (29U)                          
-#define USB_OTG_DOEPCTL_SODDFRM_Msk             (0x1UL << USB_OTG_DOEPCTL_SODDFRM_Pos) /*!< 0x20000000 */
-#define USB_OTG_DOEPCTL_SODDFRM                 USB_OTG_DOEPCTL_SODDFRM_Msk    /*!< Set odd frame */
-#define USB_OTG_DOEPCTL_EPTYP_Pos               (18U)                          
-#define USB_OTG_DOEPCTL_EPTYP_Msk               (0x3UL << USB_OTG_DOEPCTL_EPTYP_Pos) /*!< 0x000C0000 */
-#define USB_OTG_DOEPCTL_EPTYP                   USB_OTG_DOEPCTL_EPTYP_Msk      /*!< Endpoint type */
-#define USB_OTG_DOEPCTL_EPTYP_0                 (0x1UL << USB_OTG_DOEPCTL_EPTYP_Pos) /*!< 0x00040000 */
-#define USB_OTG_DOEPCTL_EPTYP_1                 (0x2UL << USB_OTG_DOEPCTL_EPTYP_Pos) /*!< 0x00080000 */
-#define USB_OTG_DOEPCTL_SNPM_Pos                (20U)                          
-#define USB_OTG_DOEPCTL_SNPM_Msk                (0x1UL << USB_OTG_DOEPCTL_SNPM_Pos) /*!< 0x00100000 */
-#define USB_OTG_DOEPCTL_SNPM                    USB_OTG_DOEPCTL_SNPM_Msk       /*!< Snoop mode */
-#define USB_OTG_DOEPCTL_STALL_Pos               (21U)                          
-#define USB_OTG_DOEPCTL_STALL_Msk               (0x1UL << USB_OTG_DOEPCTL_STALL_Pos) /*!< 0x00200000 */
-#define USB_OTG_DOEPCTL_STALL                   USB_OTG_DOEPCTL_STALL_Msk      /*!< STALL handshake */
-#define USB_OTG_DOEPCTL_CNAK_Pos                (26U)                          
-#define USB_OTG_DOEPCTL_CNAK_Msk                (0x1UL << USB_OTG_DOEPCTL_CNAK_Pos) /*!< 0x04000000 */
-#define USB_OTG_DOEPCTL_CNAK                    USB_OTG_DOEPCTL_CNAK_Msk       /*!< Clear NAK */
-#define USB_OTG_DOEPCTL_SNAK_Pos                (27U)                          
-#define USB_OTG_DOEPCTL_SNAK_Msk                (0x1UL << USB_OTG_DOEPCTL_SNAK_Pos) /*!< 0x08000000 */
-#define USB_OTG_DOEPCTL_SNAK                    USB_OTG_DOEPCTL_SNAK_Msk       /*!< Set NAK */
-#define USB_OTG_DOEPCTL_EPDIS_Pos               (30U)                          
-#define USB_OTG_DOEPCTL_EPDIS_Msk               (0x1UL << USB_OTG_DOEPCTL_EPDIS_Pos) /*!< 0x40000000 */
-#define USB_OTG_DOEPCTL_EPDIS                   USB_OTG_DOEPCTL_EPDIS_Msk      /*!< Endpoint disable */
-#define USB_OTG_DOEPCTL_EPENA_Pos               (31U)                          
-#define USB_OTG_DOEPCTL_EPENA_Msk               (0x1UL << USB_OTG_DOEPCTL_EPENA_Pos) /*!< 0x80000000 */
-#define USB_OTG_DOEPCTL_EPENA                   USB_OTG_DOEPCTL_EPENA_Msk      /*!< Endpoint enable */
-
-/********************  Bit definition for USB_OTG_DOEPINT register  ********************/
-#define USB_OTG_DOEPINT_XFRC_Pos                (0U)                           
-#define USB_OTG_DOEPINT_XFRC_Msk                (0x1UL << USB_OTG_DOEPINT_XFRC_Pos) /*!< 0x00000001 */
-#define USB_OTG_DOEPINT_XFRC                    USB_OTG_DOEPINT_XFRC_Msk       /*!< Transfer completed interrupt */
-#define USB_OTG_DOEPINT_EPDISD_Pos              (1U)                           
-#define USB_OTG_DOEPINT_EPDISD_Msk              (0x1UL << USB_OTG_DOEPINT_EPDISD_Pos) /*!< 0x00000002 */
-#define USB_OTG_DOEPINT_EPDISD                  USB_OTG_DOEPINT_EPDISD_Msk     /*!< Endpoint disabled interrupt */
-#define USB_OTG_DOEPINT_AHBERR_Pos               (2U)
-#define USB_OTG_DOEPINT_AHBERR_Msk               (0x1UL << USB_OTG_DOEPINT_AHBERR_Pos) /*!< 0x00000004 */
-#define USB_OTG_DOEPINT_AHBERR                   USB_OTG_DOEPINT_AHBERR_Msk   /*!< AHB Error (AHBErr) during an OUT transaction */
-#define USB_OTG_DOEPINT_STUP_Pos                (3U)                           
-#define USB_OTG_DOEPINT_STUP_Msk                (0x1UL << USB_OTG_DOEPINT_STUP_Pos) /*!< 0x00000008 */
-#define USB_OTG_DOEPINT_STUP                    USB_OTG_DOEPINT_STUP_Msk       /*!< SETUP phase done */
-#define USB_OTG_DOEPINT_OTEPDIS_Pos             (4U)                           
-#define USB_OTG_DOEPINT_OTEPDIS_Msk             (0x1UL << USB_OTG_DOEPINT_OTEPDIS_Pos) /*!< 0x00000010 */
-#define USB_OTG_DOEPINT_OTEPDIS                 USB_OTG_DOEPINT_OTEPDIS_Msk    /*!< OUT token received when endpoint disabled */
-#define USB_OTG_DOEPINT_OTEPSPR_Pos              (5U)                          
-#define USB_OTG_DOEPINT_OTEPSPR_Msk              (0x1UL << USB_OTG_DOEPINT_OTEPSPR_Pos) /*!< 0x00000020 */
-#define USB_OTG_DOEPINT_OTEPSPR                  USB_OTG_DOEPINT_OTEPSPR_Msk   /*!< Status Phase Received For Control Write */
-#define USB_OTG_DOEPINT_B2BSTUP_Pos             (6U)                           
-#define USB_OTG_DOEPINT_B2BSTUP_Msk             (0x1UL << USB_OTG_DOEPINT_B2BSTUP_Pos) /*!< 0x00000040 */
-#define USB_OTG_DOEPINT_B2BSTUP                 USB_OTG_DOEPINT_B2BSTUP_Msk    /*!< Back-to-back SETUP packets received */
-#define USB_OTG_DOEPINT_OUTPKTERR_Pos            (8U)
-#define USB_OTG_DOEPINT_OUTPKTERR_Msk            (0x1UL << USB_OTG_DOEPINT_OUTPKTERR_Pos) /*!< 0x00000100 */
-#define USB_OTG_DOEPINT_OUTPKTERR                USB_OTG_DOEPINT_OUTPKTERR_Msk   /*!< OUT packet error */
-#define USB_OTG_DOEPINT_NAK_Pos                  (13U)
-#define USB_OTG_DOEPINT_NAK_Msk                  (0x1UL << USB_OTG_DOEPINT_NAK_Pos) /*!< 0x00002000 */
-#define USB_OTG_DOEPINT_NAK                      USB_OTG_DOEPINT_NAK_Msk   /*!< NAK Packet is transmitted by the device */
-#define USB_OTG_DOEPINT_NYET_Pos                (14U)                          
-#define USB_OTG_DOEPINT_NYET_Msk                (0x1UL << USB_OTG_DOEPINT_NYET_Pos) /*!< 0x00004000 */
-#define USB_OTG_DOEPINT_NYET                    USB_OTG_DOEPINT_NYET_Msk       /*!< NYET interrupt */
-#define USB_OTG_DOEPINT_STPKTRX_Pos              (15U)
-#define USB_OTG_DOEPINT_STPKTRX_Msk              (0x1UL << USB_OTG_DOEPINT_STPKTRX_Pos) /*!< 0x00008000 */
-#define USB_OTG_DOEPINT_STPKTRX                  USB_OTG_DOEPINT_STPKTRX_Msk   /*!< Setup Packet Received */
-/********************  Bit definition for USB_OTG_DOEPTSIZ register  ********************/
-
-#define USB_OTG_DOEPTSIZ_XFRSIZ_Pos             (0U)                           
-#define USB_OTG_DOEPTSIZ_XFRSIZ_Msk             (0x7FFFFUL << USB_OTG_DOEPTSIZ_XFRSIZ_Pos) /*!< 0x0007FFFF */
-#define USB_OTG_DOEPTSIZ_XFRSIZ                 USB_OTG_DOEPTSIZ_XFRSIZ_Msk    /*!< Transfer size */
-#define USB_OTG_DOEPTSIZ_PKTCNT_Pos             (19U)                          
-#define USB_OTG_DOEPTSIZ_PKTCNT_Msk             (0x3FFUL << USB_OTG_DOEPTSIZ_PKTCNT_Pos) /*!< 0x1FF80000 */
-#define USB_OTG_DOEPTSIZ_PKTCNT                 USB_OTG_DOEPTSIZ_PKTCNT_Msk    /*!< Packet count */
-
-#define USB_OTG_DOEPTSIZ_STUPCNT_Pos            (29U)                          
-#define USB_OTG_DOEPTSIZ_STUPCNT_Msk            (0x3UL << USB_OTG_DOEPTSIZ_STUPCNT_Pos) /*!< 0x60000000 */
-#define USB_OTG_DOEPTSIZ_STUPCNT                USB_OTG_DOEPTSIZ_STUPCNT_Msk   /*!< SETUP packet count */
-#define USB_OTG_DOEPTSIZ_STUPCNT_0              (0x1UL << USB_OTG_DOEPTSIZ_STUPCNT_Pos) /*!< 0x20000000 */
-#define USB_OTG_DOEPTSIZ_STUPCNT_1              (0x2UL << USB_OTG_DOEPTSIZ_STUPCNT_Pos) /*!< 0x40000000 */
-
-/********************  Bit definition for PCGCCTL register  ********************/
-#define USB_OTG_PCGCCTL_STOPCLK_Pos             (0U)                           
-#define USB_OTG_PCGCCTL_STOPCLK_Msk             (0x1UL << USB_OTG_PCGCCTL_STOPCLK_Pos) /*!< 0x00000001 */
-#define USB_OTG_PCGCCTL_STOPCLK                 USB_OTG_PCGCCTL_STOPCLK_Msk    /*!< SETUP packet count */
-#define USB_OTG_PCGCCTL_GATECLK_Pos             (1U)                           
-#define USB_OTG_PCGCCTL_GATECLK_Msk             (0x1UL << USB_OTG_PCGCCTL_GATECLK_Pos) /*!< 0x00000002 */
-#define USB_OTG_PCGCCTL_GATECLK                 USB_OTG_PCGCCTL_GATECLK_Msk    /*!<Bit 0 */
-#define USB_OTG_PCGCCTL_PHYSUSP_Pos             (4U)                           
-#define USB_OTG_PCGCCTL_PHYSUSP_Msk             (0x1UL << USB_OTG_PCGCCTL_PHYSUSP_Pos) /*!< 0x00000010 */
-#define USB_OTG_PCGCCTL_PHYSUSP                 USB_OTG_PCGCCTL_PHYSUSP_Msk    /*!<Bit 1 */
-
-/* Legacy define */
-/********************  Bit definition for OTG register  ********************/
-#define USB_OTG_CHNUM_Pos                       (0U)                           
-#define USB_OTG_CHNUM_Msk                       (0xFUL << USB_OTG_CHNUM_Pos)    /*!< 0x0000000F */
-#define USB_OTG_CHNUM                           USB_OTG_CHNUM_Msk              /*!< Channel number */
-#define USB_OTG_CHNUM_0                         (0x1UL << USB_OTG_CHNUM_Pos)    /*!< 0x00000001 */
-#define USB_OTG_CHNUM_1                         (0x2UL << USB_OTG_CHNUM_Pos)    /*!< 0x00000002 */
-#define USB_OTG_CHNUM_2                         (0x4UL << USB_OTG_CHNUM_Pos)    /*!< 0x00000004 */
-#define USB_OTG_CHNUM_3                         (0x8UL << USB_OTG_CHNUM_Pos)    /*!< 0x00000008 */
-#define USB_OTG_BCNT_Pos                        (4U)                           
-#define USB_OTG_BCNT_Msk                        (0x7FFUL << USB_OTG_BCNT_Pos)   /*!< 0x00007FF0 */
-#define USB_OTG_BCNT                            USB_OTG_BCNT_Msk               /*!< Byte count */
-
-#define USB_OTG_DPID_Pos                        (15U)                          
-#define USB_OTG_DPID_Msk                        (0x3UL << USB_OTG_DPID_Pos)     /*!< 0x00018000 */
-#define USB_OTG_DPID                            USB_OTG_DPID_Msk               /*!< Data PID */
-#define USB_OTG_DPID_0                          (0x1UL << USB_OTG_DPID_Pos)     /*!< 0x00008000 */
-#define USB_OTG_DPID_1                          (0x2UL << USB_OTG_DPID_Pos)     /*!< 0x00010000 */
-
-#define USB_OTG_PKTSTS_Pos                      (17U)                          
-#define USB_OTG_PKTSTS_Msk                      (0xFUL << USB_OTG_PKTSTS_Pos)   /*!< 0x001E0000 */
-#define USB_OTG_PKTSTS                          USB_OTG_PKTSTS_Msk             /*!< Packet status */
-#define USB_OTG_PKTSTS_0                        (0x1UL << USB_OTG_PKTSTS_Pos)   /*!< 0x00020000 */
-#define USB_OTG_PKTSTS_1                        (0x2UL << USB_OTG_PKTSTS_Pos)   /*!< 0x00040000 */
-#define USB_OTG_PKTSTS_2                        (0x4UL << USB_OTG_PKTSTS_Pos)   /*!< 0x00080000 */
-#define USB_OTG_PKTSTS_3                        (0x8UL << USB_OTG_PKTSTS_Pos)   /*!< 0x00100000 */
-
-#define USB_OTG_EPNUM_Pos                       (0U)                           
-#define USB_OTG_EPNUM_Msk                       (0xFUL << USB_OTG_EPNUM_Pos)    /*!< 0x0000000F */
-#define USB_OTG_EPNUM                           USB_OTG_EPNUM_Msk              /*!< Endpoint number */
-#define USB_OTG_EPNUM_0                         (0x1UL << USB_OTG_EPNUM_Pos)    /*!< 0x00000001 */
-#define USB_OTG_EPNUM_1                         (0x2UL << USB_OTG_EPNUM_Pos)    /*!< 0x00000002 */
-#define USB_OTG_EPNUM_2                         (0x4UL << USB_OTG_EPNUM_Pos)    /*!< 0x00000004 */
-#define USB_OTG_EPNUM_3                         (0x8UL << USB_OTG_EPNUM_Pos)    /*!< 0x00000008 */
-
-#define USB_OTG_FRMNUM_Pos                      (21U)                          
-#define USB_OTG_FRMNUM_Msk                      (0xFUL << USB_OTG_FRMNUM_Pos)   /*!< 0x01E00000 */
-#define USB_OTG_FRMNUM                          USB_OTG_FRMNUM_Msk             /*!< Frame number */
-#define USB_OTG_FRMNUM_0                        (0x1UL << USB_OTG_FRMNUM_Pos)   /*!< 0x00200000 */
-#define USB_OTG_FRMNUM_1                        (0x2UL << USB_OTG_FRMNUM_Pos)   /*!< 0x00400000 */
-#define USB_OTG_FRMNUM_2                        (0x4UL << USB_OTG_FRMNUM_Pos)   /*!< 0x00800000 */
-#define USB_OTG_FRMNUM_3                        (0x8UL << USB_OTG_FRMNUM_Pos)   /*!< 0x01000000 */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 8 - 0
src/portable/chipidea/ci_hs/dcd_ci_hs.c

@@ -266,6 +266,14 @@ void dcd_disconnect(uint8_t rhport)
   dcd_reg->USBCMD &= ~USBCMD_RUN_STOP;
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 //--------------------------------------------------------------------+
 // HELPER
 //--------------------------------------------------------------------+

+ 8 - 0
src/portable/dialog/da146xx/dcd_da146xx.c

@@ -882,6 +882,14 @@ void dcd_disconnect(uint8_t rhport)
   REG_CLR_BIT(USB_MCTRL_REG, USB_NAT);
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void)
 {
   return (SCB->ICSR & SCB_ICSR_VECTACTIVE_Msk) != 0;

+ 2 - 2
src/portable/ehci/ehci.c

@@ -163,15 +163,15 @@ void hcd_port_reset(uint8_t rhport)
   regs->portsc = portsc;
 }
 
-#if 0
 void hcd_port_reset_end(uint8_t rhport)
 {
   (void) rhport;
 
+#if 0
   ehci_registers_t* regs = ehci_data.regs;
   regs->portsc_bm.port_reset = 0;
-}
 #endif
+}
 
 bool hcd_port_connect_status(uint8_t rhport)
 {

+ 8 - 0
src/portable/espressif/esp32sx/dcd_esp32sx.c

@@ -240,6 +240,14 @@ void dcd_disconnect(uint8_t rhport)
   USB0.dctl |= USB_SFTDISCON_M;
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 /*------------------------------------------------------------------*/
 /* DCD Endpoint port
  *------------------------------------------------------------------*/

+ 8 - 0
src/portable/mentor/musb/dcd_musb.c

@@ -648,6 +648,14 @@ void dcd_disconnect(uint8_t rhport)
   USB0->POWER &= ~USB_POWER_SOFTCONN;
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 //--------------------------------------------------------------------+
 // Endpoint API
 //--------------------------------------------------------------------+

+ 5 - 0
src/portable/mentor/musb/hcd_musb.c

@@ -617,6 +617,11 @@ void hcd_port_reset(uint8_t rhport)
   _hcd.need_reset = false;
 }
 
+void hcd_port_reset_end(uint8_t rhport)
+{
+  (void) rhport;
+}
+
 tusb_speed_t hcd_port_speed_get(uint8_t rhport)
 {
   (void)rhport;

+ 13 - 1
src/portable/microchip/pic32mz/dcd_pic32mz.c

@@ -186,6 +186,14 @@ void dcd_disconnect(uint8_t rhport)
   USB_REGS->POWERbits.SOFTCONN = 1;
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 TU_ATTR_ALWAYS_INLINE static inline bool is_in_isr(void)
 {
   return (_CP0_GET_STATUS() & (_CP0_STATUS_EXL_MASK | _CP0_STATUS_IPL_MASK)) != 0;
@@ -530,6 +538,7 @@ static void ep0_handle_rx(void)
 
   transferred = rx_fifo_read(0, xfer->buffer + xfer->transferred);
   xfer->transferred += transferred;
+  TU_ASSERT(xfer->transferred <= xfer->total_len,);
   if (transferred < xfer->max_packet_size || xfer->transferred == xfer->total_len)
   {
     ep0_set_stage(EP0_STAGE_DATA_OUT_COMPLETE);
@@ -560,8 +569,10 @@ static void epn_handle_rx_int(uint8_t epnum)
     transferred = rx_fifo_read(epnum, xfer->buffer + xfer->transferred);
     USB_REGS->EPCSR[epnum].RXCSRL_HOSTbits.RXPKTRDY = 0;
     xfer->transferred += transferred;
+    TU_ASSERT(xfer->transferred <= xfer->total_len,);
     if (transferred < xfer->max_packet_size || xfer->transferred == xfer->total_len)
     {
+      USB_REGS->INTRRXEbits.w &= ~(1u << epnum);
       xfer_complete(xfer, XFER_RESULT_SUCCESS, true);
     }
   }
@@ -579,6 +590,7 @@ static void epn_handle_tx_int(uint8_t epnum)
   else
   {
     xfer->transferred += xfer->last_packet_size;
+    TU_ASSERT(xfer->transferred <= xfer->total_len,);
     if (xfer->last_packet_size < xfer->max_packet_size || xfer->transferred == xfer->total_len)
     {
       xfer->last_packet_size = 0;
@@ -689,7 +701,7 @@ void dcd_int_handler(uint8_t rhport)
   int i;
   uint8_t mask;
   __USBCSR2bits_t csr2_bits;
-  uint16_t rxints = USB_REGS->INTRRX;
+  uint16_t rxints = USB_REGS->INTRRX & USB_REGS->INTRRXEbits.w;
   uint16_t txints = USB_REGS->INTRTX;
   csr2_bits = USBCSR2bits;
   (void) rhport;

+ 8 - 0
src/portable/microchip/samd/dcd_samd.c

@@ -180,6 +180,14 @@ void dcd_connect(uint8_t rhport)
    USB->DEVICE.CTRLB.reg &= ~USB_DEVICE_CTRLB_DETACH;
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 /*------------------------------------------------------------------*/
 /* DCD Endpoint port
  *------------------------------------------------------------------*/

+ 8 - 0
src/portable/microchip/samg/dcd_samg.c

@@ -210,6 +210,14 @@ void dcd_disconnect(uint8_t rhport)
   UDP->UDP_TXVC = UDP_TXVC_TXVDIS_Msk;
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 //--------------------------------------------------------------------+
 // Endpoint API
 //--------------------------------------------------------------------+

+ 8 - 0
src/portable/microchip/samx7x/dcd_samx7x.c

@@ -191,6 +191,14 @@ void dcd_disconnect(uint8_t rhport)
   USB_REG->DEVCTRL &=~(DEVCTRL_ADDEN | DEVCTRL_UADD);
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 static tusb_speed_t get_speed(void)
 {
   switch (USB_REG->SR & SR_SPEED) {

+ 8 - 0
src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c

@@ -305,6 +305,14 @@ void dcd_disconnect(uint8_t rhport)
   USB_OTG_FS->CTL      = 0;
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 //--------------------------------------------------------------------+
 // Endpoint API
 //--------------------------------------------------------------------+

+ 8 - 0
src/portable/nordic/nrf5x/dcd_nrf5x.c

@@ -307,6 +307,14 @@ void dcd_connect(uint8_t rhport)
   NRF_USBD->USBPULLUP = 1;
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 //--------------------------------------------------------------------+
 // Endpoint API
 //--------------------------------------------------------------------+

+ 8 - 0
src/portable/nuvoton/nuc120/dcd_nuc120.c

@@ -497,4 +497,12 @@ void dcd_connect(uint8_t rhport)
   usb_attach();
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 #endif

+ 8 - 0
src/portable/nuvoton/nuc121/dcd_nuc121.c

@@ -551,4 +551,12 @@ void dcd_connect(uint8_t rhport)
   usb_attach();
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 #endif

+ 8 - 0
src/portable/nuvoton/nuc505/dcd_nuc505.c

@@ -720,4 +720,12 @@ void dcd_connect(uint8_t rhport)
   usb_attach();
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 #endif

+ 8 - 0
src/portable/nxp/khci/dcd_khci.c

@@ -328,6 +328,14 @@ void dcd_disconnect(uint8_t rhport)
   KHCI->CONTROL &= ~USB_CONTROL_DPPULLUPNONOTG_MASK;
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 //--------------------------------------------------------------------+
 // Endpoint API
 //--------------------------------------------------------------------+

+ 8 - 0
src/portable/nxp/lpc17_40/dcd_lpc17_40.c

@@ -228,6 +228,14 @@ void dcd_disconnect(uint8_t rhport)
   sie_write(SIE_CMDCODE_DEVICE_STATUS, 1, 0);
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 //--------------------------------------------------------------------+
 // CONTROL HELPER
 //--------------------------------------------------------------------+

+ 8 - 0
src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c

@@ -277,6 +277,14 @@ void dcd_disconnect(uint8_t rhport)
   dcd_reg->DEVCMDSTAT &= ~CMDSTAT_DEVICE_CONNECT_MASK;
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 //--------------------------------------------------------------------+
 // DCD Endpoint Port
 //--------------------------------------------------------------------+

+ 8 - 0
src/portable/nxp/transdimension/dcd_transdimension.c

@@ -294,6 +294,14 @@ void dcd_disconnect(uint8_t rhport)
   dcd_reg->USBCMD &= ~USBCMD_RUN_STOP;
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 //--------------------------------------------------------------------+
 // HELPER
 //--------------------------------------------------------------------+

+ 5 - 0
src/portable/ohci/ohci.c

@@ -216,6 +216,11 @@ void hcd_port_reset(uint8_t hostid)
   OHCI_REG->rhport_status[0] = RHPORT_PORT_RESET_STATUS_MASK;
 }
 
+void hcd_port_reset_end(uint8_t rhport)
+{
+  (void) rhport;
+}
+
 bool hcd_port_connect_status(uint8_t hostid)
 {
   (void) hostid;

+ 210 - 0
src/portable/raspberrypi/pio_usb/dcd_pio_usb.c

@@ -0,0 +1,210 @@
+/* 
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2018, hathach (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.
+ */
+
+#include "tusb_option.h"
+
+#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && CFG_TUD_RPI_PIO_USB
+
+#include "pico.h"
+#include "pio_usb.h"
+#include "pio_usb_ll.h"
+
+#include "device/dcd.h"
+
+//--------------------------------------------------------------------+
+// MACRO TYPEDEF CONSTANT ENUM DECLARATION
+//--------------------------------------------------------------------+
+
+#define RHPORT_OFFSET     1
+#define RHPORT_PIO(_x)    ((_x)-RHPORT_OFFSET)
+
+//-------------  -------------//
+static usb_device_t *usb_device = NULL;
+static usb_descriptor_buffers_t desc;
+
+/*------------------------------------------------------------------*/
+/* Device API
+ *------------------------------------------------------------------*/
+
+// Initialize controller to device mode
+void dcd_init (uint8_t rhport)
+{
+  (void) rhport;
+
+  static pio_usb_configuration_t config = PIO_USB_DEFAULT_CONFIG;
+  usb_device = pio_usb_device_init(&config, &desc);
+}
+
+// Enable device interrupt
+void dcd_int_enable (uint8_t rhport)
+{
+  (void) rhport;
+}
+
+// Disable device interrupt
+void dcd_int_disable (uint8_t rhport)
+{
+  (void) rhport;
+}
+
+// Receive Set Address request, mcu port must also include status IN response
+void dcd_set_address (uint8_t rhport, uint8_t dev_addr)
+{
+  // must be called before queuing status
+  pio_usb_device_set_address(dev_addr);
+  dcd_edpt_xfer(rhport, 0x80, NULL, 0);
+}
+
+// Wake up host
+void dcd_remote_wakeup (uint8_t rhport)
+{
+  (void) rhport;
+}
+
+// Connect by enabling internal pull-up resistor on D+/D-
+void dcd_connect(uint8_t rhport)
+{
+  (void) rhport;
+}
+
+// Disconnect by disabling internal pull-up resistor on D+/D-
+void dcd_disconnect(uint8_t rhport)
+{
+  (void) rhport;
+}
+
+//--------------------------------------------------------------------+
+// Endpoint API
+//--------------------------------------------------------------------+
+
+// Configure endpoint's registers according to descriptor
+bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_ep)
+{
+  (void) rhport;
+  return pio_usb_device_endpoint_open((uint8_t const*) desc_ep);
+}
+
+void dcd_edpt_close_all (uint8_t rhport)
+{
+  (void) rhport;
+}
+
+// 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)
+{
+  (void) rhport;
+  endpoint_t *ep = pio_usb_device_get_endpoint_by_address(ep_addr);
+  return pio_usb_ll_transfer_start(ep, buffer, total_bytes);
+}
+
+// Submit a transfer where is managed by FIFO, When complete dcd_event_xfer_complete() is invoked to notify the stack - optional, however, must be listed in usbd.c
+//bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes)
+//{
+//  (void) rhport;
+//  (void) ep_addr;
+//  (void) ff;
+//  (void) total_bytes;
+//  return false;
+//}
+
+// Stall endpoint
+void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr)
+{
+  (void) rhport;
+  endpoint_t *ep = pio_usb_device_get_endpoint_by_address(ep_addr);
+  ep->has_transfer = false;
+  ep->stalled = true;
+}
+
+// clear stall, data toggle is also reset to DATA0
+void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr)
+{
+  (void) rhport;
+  endpoint_t *ep = pio_usb_device_get_endpoint_by_address(ep_addr);
+  ep->data_id = 0;
+  ep->stalled = false;
+}
+
+//--------------------------------------------------------------------+
+//
+//--------------------------------------------------------------------+
+
+static void __no_inline_not_in_flash_func(handle_endpoint_irq)(uint8_t tu_rhport, xfer_result_t result, volatile uint32_t* ep_reg)
+{
+  const uint32_t ep_all = *ep_reg;
+
+  for(uint8_t ep_idx = 0; ep_idx < PIO_USB_EP_POOL_CNT; ep_idx++)
+  {
+    uint32_t const mask = (1u << ep_idx);
+
+    if (ep_all & mask)
+    {
+      endpoint_t* ep = PIO_USB_ENDPOINT(ep_idx);
+      dcd_event_xfer_complete(tu_rhport, ep->ep_num, ep->actual_len, result, true);
+    }
+  }
+
+  // clear all
+  (*ep_reg) &= ~ep_all;
+}
+
+// IRQ Handler
+void __no_inline_not_in_flash_func(pio_usb_device_irq_handler)(uint8_t root_id)
+{
+  uint8_t const tu_rhport = root_id + 1;
+  root_port_t* rport = PIO_USB_ROOT_PORT(root_id);
+  uint32_t const ints = rport->ints;
+
+  if (ints & PIO_USB_INTS_RESET_END_BITS)
+  {
+    dcd_event_bus_reset(tu_rhport, TUSB_SPEED_FULL, true);
+  }
+
+  if (ints & PIO_USB_INTS_SETUP_REQ_BITS)
+  {
+    dcd_event_setup_received(tu_rhport, rport->setup_packet, true);
+  }
+
+  if ( ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS )
+  {
+    handle_endpoint_irq(tu_rhport, XFER_RESULT_SUCCESS, &rport->ep_complete);
+  }
+
+  if ( ints & PIO_USB_INTS_ENDPOINT_STALLED_BITS )
+  {
+    handle_endpoint_irq(tu_rhport, XFER_RESULT_STALLED, &rport->ep_stalled);
+  }
+
+  if ( ints & PIO_USB_INTS_ENDPOINT_ERROR_BITS )
+  {
+    handle_endpoint_irq(tu_rhport, XFER_RESULT_FAILED, &rport->ep_error);
+  }
+
+  // clear all
+  rport->ints &= ~ints;
+}
+
+#endif

+ 217 - 0
src/portable/raspberrypi/pio_usb/hcd_pio_usb.c

@@ -0,0 +1,217 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2021 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.
+ */
+
+#include "tusb_option.h"
+
+#if CFG_TUH_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && CFG_TUH_RPI_PIO_USB
+
+#include "pico.h"
+#include "pio_usb.h"
+#include "pio_usb_ll.h"
+
+//--------------------------------------------------------------------+
+// INCLUDE
+//--------------------------------------------------------------------+
+#include "osal/osal.h"
+
+#include "host/hcd.h"
+#include "host/usbh.h"
+
+#define RHPORT_OFFSET     1
+#define RHPORT_PIO(_x)    ((_x)-RHPORT_OFFSET)
+
+static pio_usb_configuration_t pio_host_config = PIO_USB_DEFAULT_CONFIG;
+
+//--------------------------------------------------------------------+
+// HCD API
+//--------------------------------------------------------------------+
+bool hcd_init(uint8_t rhport)
+{
+  (void) rhport;
+
+  // To run USB SOF interrupt in core1, call this init in core1
+  pio_usb_host_init(&pio_host_config);
+
+  return true;
+}
+
+void hcd_port_reset(uint8_t rhport)
+{
+  uint8_t const pio_rhport = RHPORT_PIO(rhport);
+  pio_usb_host_port_reset_start(pio_rhport);
+}
+
+void hcd_port_reset_end(uint8_t rhport)
+{
+  uint8_t const pio_rhport = RHPORT_PIO(rhport);
+  pio_usb_host_port_reset_end(pio_rhport);
+}
+
+bool hcd_port_connect_status(uint8_t rhport)
+{
+  uint8_t const pio_rhport = RHPORT_PIO(rhport);
+
+  root_port_t *root = PIO_USB_ROOT_PORT(pio_rhport);
+  port_pin_status_t line_state = pio_usb_bus_get_line_state(root);
+
+  return line_state != PORT_PIN_SE0;
+}
+
+tusb_speed_t hcd_port_speed_get(uint8_t rhport)
+{
+  // TODO determine link speed
+  uint8_t const pio_rhport = RHPORT_PIO(rhport);
+  return PIO_USB_ROOT_PORT(pio_rhport)->is_fullspeed ? TUSB_SPEED_FULL : TUSB_SPEED_LOW;
+}
+
+// Close all opened endpoint belong to this device
+void hcd_device_close(uint8_t rhport, uint8_t dev_addr)
+{
+  uint8_t const pio_rhport = RHPORT_PIO(rhport);
+  pio_usb_host_close_device(pio_rhport, dev_addr);
+}
+
+uint32_t hcd_frame_number(uint8_t rhport)
+{
+  (void) rhport;
+  return 0;
+}
+
+void hcd_int_enable(uint8_t rhport)
+{
+  (void) rhport;
+}
+
+void hcd_int_disable(uint8_t rhport)
+{
+  (void) rhport;
+}
+
+//--------------------------------------------------------------------+
+// Endpoint API
+//--------------------------------------------------------------------+
+
+bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * desc_ep)
+{
+  hcd_devtree_info_t dev_tree;
+  hcd_devtree_get_info(dev_addr, &dev_tree);
+  bool const need_pre = (dev_tree.hub_addr && dev_tree.speed == TUSB_SPEED_LOW);
+
+  uint8_t const pio_rhport = RHPORT_PIO(rhport);
+  return pio_usb_host_endpoint_open(pio_rhport, dev_addr, (uint8_t const*) desc_ep, need_pre);
+}
+
+bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t * buffer, uint16_t buflen)
+{
+  uint8_t const pio_rhport = RHPORT_PIO(rhport);
+  return pio_usb_host_endpoint_transfer(pio_rhport, dev_addr, ep_addr, buffer, buflen);
+}
+
+bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8])
+{
+  uint8_t const pio_rhport = RHPORT_PIO(rhport);
+  return pio_usb_host_send_setup(pio_rhport, dev_addr, setup_packet);
+}
+
+//bool hcd_edpt_busy(uint8_t dev_addr, uint8_t ep_addr)
+//{
+//    // EPX is shared, so multiple device addresses and endpoint addresses share that
+//    // so if any transfer is active on epx, we are busy. Interrupt endpoints have their own
+//    // EPX so ep->active will only be busy if there is a pending transfer on that interrupt endpoint
+//    // on that device
+//    pico_trace("hcd_edpt_busy dev addr %d ep_addr 0x%x\n", dev_addr, ep_addr);
+//    struct hw_endpoint *ep = get_dev_ep(dev_addr, ep_addr);
+//    assert(ep);
+//    bool busy = ep->active;
+//    pico_trace("busy == %d\n", busy);
+//    return busy;
+//}
+
+bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr)
+{
+  (void) dev_addr;
+  (void) ep_addr;
+
+  return true;
+}
+
+static void __no_inline_not_in_flash_func(handle_endpoint_irq)(root_port_t* rport, xfer_result_t result, volatile uint32_t* ep_reg)
+{
+  (void) rport;
+  const uint32_t ep_all = *ep_reg;
+
+  for(uint8_t ep_idx = 0; ep_idx < PIO_USB_EP_POOL_CNT; ep_idx++)
+  {
+    uint32_t const mask = (1u << ep_idx);
+
+    if (ep_all & mask)
+    {
+      endpoint_t* ep = PIO_USB_ENDPOINT(ep_idx);
+      hcd_event_xfer_complete(ep->dev_addr, ep->ep_num, ep->actual_len, result, true);
+    }
+  }
+
+  // clear all
+  (*ep_reg) &= ~ep_all;
+}
+
+// IRQ Handler
+void __no_inline_not_in_flash_func(pio_usb_host_irq_handler)(uint8_t root_id)
+{
+  uint8_t const tu_rhport = root_id + 1;
+  root_port_t* rport = PIO_USB_ROOT_PORT(root_id);
+  uint32_t const ints = rport->ints;
+
+  if ( ints & PIO_USB_INTS_CONNECT_BITS )
+  {
+    hcd_event_device_attach(tu_rhport, true);
+  }
+
+  if ( ints & PIO_USB_INTS_DISCONNECT_BITS )
+  {
+    hcd_event_device_remove(tu_rhport, true);
+  }
+
+  if ( ints & PIO_USB_INTS_ENDPOINT_COMPLETE_BITS )
+  {
+    handle_endpoint_irq(rport, XFER_RESULT_SUCCESS, &rport->ep_complete);
+  }
+
+  if ( ints & PIO_USB_INTS_ENDPOINT_STALLED_BITS )
+  {
+    handle_endpoint_irq(rport, XFER_RESULT_STALLED, &rport->ep_stalled);
+  }
+
+  if ( ints & PIO_USB_INTS_ENDPOINT_ERROR_BITS )
+  {
+    handle_endpoint_irq(rport, XFER_RESULT_FAILED, &rport->ep_error);
+  }
+
+  // clear all
+  rport->ints &= ~ints;
+}
+
+#endif

+ 24 - 1
src/portable/raspberrypi/rp2040/dcd_rp2040.c

@@ -26,7 +26,7 @@
 
 #include "tusb_option.h"
 
-#if CFG_TUD_ENABLED && CFG_TUSB_MCU == OPT_MCU_RP2040
+#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && !CFG_TUD_RPI_PIO_USB
 
 #include "pico.h"
 #include "rp2040_usb.h"
@@ -247,6 +247,12 @@ static void dcd_rp2040_irq(void)
     uint32_t const status = usb_hw->ints;
     uint32_t handled = 0;
 
+    if (status & USB_INTF_DEV_SOF_BITS)
+    {
+      handled |= USB_INTF_DEV_SOF_BITS;
+      dcd_event_sof(0, usb_hw->sof_rd & USB_SOF_RD_BITS, true);
+    }
+
     // xfer events are handled before setup req. So if a transfer completes immediately
     // before closing the EP, the events will be delivered in same order.
     if (status & USB_INTS_BUFF_STATUS_BITS)
@@ -424,6 +430,23 @@ void dcd_connect(__unused uint8_t rhport)
   usb_hw_set->sie_ctrl = USB_SIE_CTRL_PULLUP_EN_BITS;
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+
+  uint32_t inte = usb_hw->inte;
+
+  if (en)
+  {
+    inte |= USB_INTS_DEV_SOF_BITS;
+  }else
+  {
+    inte &= ~USB_INTS_DEV_SOF_BITS;
+  }
+
+  usb_hw->inte = inte;
+}
+
 /*------------------------------------------------------------------*/
 /* DCD Endpoint port
  *------------------------------------------------------------------*/

+ 14 - 4
src/portable/raspberrypi/rp2040/hcd_rp2040.c

@@ -27,7 +27,7 @@
 
 #include "tusb_option.h"
 
-#if CFG_TUH_ENABLED && CFG_TUSB_MCU == OPT_MCU_RP2040
+#if CFG_TUH_ENABLED && (CFG_TUSB_MCU == OPT_MCU_RP2040) && !CFG_TUH_RPI_PIO_USB
 
 #include "pico.h"
 #include "rp2040_usb.h"
@@ -40,7 +40,8 @@
 #include "host/hcd.h"
 #include "host/usbh.h"
 
-#define ROOT_PORT 0
+// port 0 is native USB port, other is counted as software PIO
+#define RHPORT_NATIVE 0
 
 //--------------------------------------------------------------------+
 // Low level rp2040 controller functions
@@ -185,11 +186,11 @@ static void hcd_rp2040_irq(void)
         
         if (dev_speed())
         {
-            hcd_event_device_attach(ROOT_PORT, true);
+            hcd_event_device_attach(RHPORT_NATIVE, true);
         }
         else
         {
-            hcd_event_device_remove(ROOT_PORT, true);
+            hcd_event_device_remove(RHPORT_NATIVE, true);
         }
 
         // Clear speed change interrupt
@@ -388,6 +389,11 @@ void hcd_port_reset(uint8_t rhport)
     // TODO: Nothing to do here yet. Perhaps need to reset some state?
 }
 
+void hcd_port_reset_end(uint8_t rhport)
+{
+  (void) rhport;
+}
+
 bool hcd_port_connect_status(uint8_t rhport)
 {
     pico_trace("hcd_port_connect_status\n");
@@ -531,7 +537,11 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet
     (void) rhport;
 
     // Copy data into setup packet buffer
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Warray-bounds"
+#pragma GCC diagnostic ignored "-Wstringop-overflow"
     memcpy((void*)&usbh_dpram->setup_packet[0], setup_packet, 8);
+#pragma GCC diagnostic pop
 
     // Configure EP0 struct with setup info for the trans complete
     struct hw_endpoint *ep = _hw_endpoint_allocate(0);

+ 1 - 1
src/portable/raspberrypi/rp2040/rp2040_usb.c

@@ -58,9 +58,9 @@ void rp2040_usb_init(void)
   unreset_block_wait(RESETS_RESET_USBCTRL_BITS);
 
   // Clear any previous state just in case
-  // TODO Suppress warning array-bounds with gcc11
 #pragma GCC diagnostic push
 #pragma GCC diagnostic ignored "-Warray-bounds"
+#pragma GCC diagnostic ignored "-Wstringop-overflow"
   memset(usb_hw, 0, sizeof(*usb_hw));
   memset(usb_dpram, 0, sizeof(*usb_dpram));
 #pragma GCC diagnostic pop

+ 8 - 0
src/portable/renesas/usba/dcd_usba.c

@@ -687,6 +687,14 @@ void dcd_disconnect(uint8_t rhport)
   USB0.SYSCFG.BIT.DPRPU = 0;
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 //--------------------------------------------------------------------+
 // Endpoint API
 //--------------------------------------------------------------------+

+ 5 - 0
src/portable/renesas/usba/hcd_usba.c

@@ -620,6 +620,11 @@ void hcd_port_reset(uint8_t rhport)
   _hcd.need_reset = false;
 }
 
+void hcd_port_reset_end(uint8_t rhport)
+{
+  (void) rhport;
+}
+
 tusb_speed_t hcd_port_speed_get(uint8_t rhport)
 {
   (void)rhport;

+ 9 - 1
src/portable/sony/cxd56/dcd_cxd56.c

@@ -247,6 +247,14 @@ void dcd_disconnect(uint8_t rhport)
   DEV_DISCONNECT(usbdev);
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 //--------------------------------------------------------------------+
 // Endpoint API
 //--------------------------------------------------------------------+
@@ -363,7 +371,7 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t to
 
     if (usbdcd_driver.setup_processed)
     {
-      if (osal_queue_receive(usbdcd_driver.setup_queue, &ctrl))
+      if (osal_queue_receive(usbdcd_driver.setup_queue, &ctrl, 100))
       {
         usbdcd_driver.setup_processed = false;
         dcd_event_setup_received(0, (uint8_t *)&ctrl, false);

+ 8 - 0
src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c

@@ -287,6 +287,14 @@ void dcd_connect(uint8_t rhport)
 }
 #endif
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 // Enable device interrupt
 void dcd_int_enable (uint8_t rhport)
 {

+ 7 - 0
src/portable/st/synopsys/dcd_synopsys.c

@@ -602,6 +602,13 @@ void dcd_disconnect(uint8_t rhport)
   dev->DCTL |= USB_OTG_DCTL_SDIS;
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
 
 /*------------------------------------------------------------------*/
 /* DCD Endpoint port

+ 8 - 0
src/portable/sunxi/dcd_sunxi_musb.c

@@ -909,6 +909,14 @@ void dcd_disconnect(uint8_t rhport)
   USBC_REG_clear_bit_b(USBC_BP_POWER_D_SOFT_CONNECT, USBC_REG_PCTL(USBC0_BASE));
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 void dcd_int_enable(uint8_t rhport)
 {
   (void)rhport;

+ 34 - 4
src/portable/synopsys/dwc2/dcd_dwc2.c

@@ -93,6 +93,9 @@ static uint16_t ep0_pending[2];                   // Index determines direction
 static uint16_t _allocated_fifo_words_tx;         // TX FIFO size in words (IN EPs)
 static bool     _out_ep_closed;                   // Flag to check if RX FIFO size needs an update (reduce its size)
 
+// SOF enabling flag - required for SOF to not get disabled in ISR when SOF was enabled by
+static bool _sof_en;
+
 // Calculate the RX FIFO size according to recommendations from reference manual
 static inline uint16_t calc_rx_ff_size(uint16_t ep_size)
 {
@@ -126,6 +129,8 @@ static void bus_reset(uint8_t rhport)
   tu_memclr(xfer_status, sizeof(xfer_status));
   _out_ep_closed = false;
 
+  _sof_en = false;
+
   // clear device address
   dwc2->dcfg &= ~DCFG_DAD_Msk;
 
@@ -588,6 +593,24 @@ void dcd_disconnect(uint8_t rhport)
   dwc2->dctl |= DCTL_SDIS;
 }
 
+// Be advised: audio, video and possibly other iso-ep classes use dcd_sof_enable() to enable/disable its corresponding ISR on purpose!
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  dwc2_regs_t * dwc2 = DWC2_REG(rhport);
+
+  _sof_en = en;
+
+  if (en)
+  {
+    dwc2->gintsts = GINTSTS_SOF;
+    dwc2->gintmsk |= GINTMSK_SOFM;
+  }
+  else
+  {
+    dwc2->gintmsk &= ~GINTMSK_SOFM;
+  }
+}
 
 /*------------------------------------------------------------------*/
 /* DCD Endpoint port
@@ -796,8 +819,7 @@ static void dcd_edpt_disable (uint8_t rhport, uint8_t ep_addr, bool stall)
     }
 
     // Flush the FIFO, and wait until we have confirmed it cleared.
-    dwc2->grstctl |= (epnum << GRSTCTL_TXFNUM_Pos);
-    dwc2->grstctl |= GRSTCTL_TXFFLSH;
+    dwc2->grstctl = ((epnum << GRSTCTL_TXFNUM_Pos) | GRSTCTL_TXFFLSH);
     while ( (dwc2->grstctl & GRSTCTL_TXFFLSH_Msk) != 0 ) {}
   }
   else
@@ -1251,8 +1273,16 @@ void dcd_int_handler(uint8_t rhport)
   {
     dwc2->gotgint = GINTSTS_SOF;
 
-    // Disable SOF interrupt since currently only used for remote wakeup detection
-    dwc2->gintmsk &= ~GINTMSK_SOFM;
+    if (_sof_en)
+    {
+      uint32_t frame = (dwc2->dsts & (DSTS_FNSOF)) >> 8;
+      dcd_event_sof(rhport, frame, true);
+    }
+    else
+    {
+      // Disable SOF interrupt if SOF was not explicitly enabled. SOF was used for remote wakeup detection
+      dwc2->gintmsk &= ~GINTMSK_SOFM;
+    }
 
     dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true);
   }

+ 6 - 0
src/portable/synopsys/dwc2/dwc2_stm32.h

@@ -56,6 +56,12 @@
   #define EP_FIFO_SIZE_FS 4096
   #define EP_MAX_HS       9
   #define EP_FIFO_SIZE_HS 4096
+  #if (! defined USB2_OTG_FS)
+    // H7 with only 1 USB port: H72x / H73x / H7Ax / H7Bx
+    // USB_OTG_FS_PERIPH_BASE and OTG_FS_IRQn not defined
+    #define USB_OTG_FS_PERIPH_BASE  USB1_OTG_HS_PERIPH_BASE
+    #define OTG_FS_IRQn             OTG_HS_IRQn
+  #endif
 
 #elif CFG_TUSB_MCU == OPT_MCU_STM32F7
   #include "stm32f7xx.h"

+ 8 - 0
src/portable/template/dcd_template.c

@@ -82,6 +82,14 @@ void dcd_disconnect(uint8_t rhport)
   (void) rhport;
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 //--------------------------------------------------------------------+
 // Endpoint API
 //--------------------------------------------------------------------+

+ 8 - 0
src/portable/ti/msp430x5xx/dcd_msp430x5xx.c

@@ -222,6 +222,14 @@ void dcd_disconnect(uint8_t rhport)
   dcd_int_enable(rhport);
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
+
 /*------------------------------------------------------------------*/
 /* DCD Endpoint port
  *------------------------------------------------------------------*/

+ 7 - 0
src/portable/valentyusb/eptri/dcd_eptri.c

@@ -401,6 +401,13 @@ void dcd_disconnect(uint8_t rhport)
   usb_pullup_out_write(0);
 }
 
+void dcd_sof_enable(uint8_t rhport, bool en)
+{
+  (void) rhport;
+  (void) en;
+
+  // TODO implement later
+}
 
 //--------------------------------------------------------------------+
 // DCD Endpoint Port

+ 22 - 5
src/tusb_option.h

@@ -27,6 +27,9 @@
 #ifndef _TUSB_OPTION_H_
 #define _TUSB_OPTION_H_
 
+// To avoid GCC compiler warnings when -pedantic option is used (strict ISO C)
+typedef int make_iso_compilers_happy ;
+
 #include "common/tusb_compiler.h"
 
 #define TUSB_VERSION_MAJOR     0
@@ -242,7 +245,7 @@
   #define TUH_OPT_RHPORT   -1
 #endif
 
-#define CFG_TUH_ENABLED     ( TUH_RHPORT_MODE & OPT_MODE_HOST )
+#define CFG_TUH_ENABLED     (TUH_RHPORT_MODE & OPT_MODE_HOST)
 
 // For backward compatible
 #define TUSB_OPT_DEVICE_ENABLED CFG_TUD_ENABLED
@@ -261,7 +264,7 @@
 
 
 //--------------------------------------------------------------------+
-// COMMON OPTIONS
+// Common Options (Default)
 //--------------------------------------------------------------------+
 
 // Debug enable to print out error message
@@ -289,16 +292,20 @@
 #endif
 
 // mutex is only needed for RTOS TODO also required with multiple core MCUs
-#define TUSB_OPT_MUTEX    (CFG_TUSB_OS != OPT_OS_NONE)
+#define TUSB_OPT_MUTEX      (CFG_TUSB_OS != OPT_OS_NONE)
 
 //--------------------------------------------------------------------
-// DEVICE OPTIONS
+// Device Options (Default)
 //--------------------------------------------------------------------
 
 #ifndef CFG_TUD_ENDPOINT0_SIZE
   #define CFG_TUD_ENDPOINT0_SIZE  64
 #endif
 
+#ifndef CFG_TUD_INTERFACE_MAX
+  #define CFG_TUD_INTERFACE_MAX   16
+#endif
+
 #ifndef CFG_TUD_CDC
   #define CFG_TUD_CDC             0
 #endif
@@ -357,7 +364,7 @@
 #endif
 
 //--------------------------------------------------------------------
-// HOST OPTIONS
+// Host Options (Default)
 //--------------------------------------------------------------------
 #if CFG_TUH_ENABLED
   #ifndef CFG_TUH_DEVICE_MAX
@@ -399,6 +406,16 @@
 #define CFG_TUH_API_EDPT_XFER 0
 #endif
 
+// Enable PIO-USB software host controller
+#ifndef CFG_TUH_RPI_PIO_USB
+#define CFG_TUH_RPI_PIO_USB 0
+#endif
+
+#ifndef CFG_TUD_RPI_PIO_USB
+#define CFG_TUD_RPI_PIO_USB 0
+#endif
+
+
 //------------------------------------------------------------------
 // Configuration Validation
 //------------------------------------------------------------------

+ 5 - 6
tools/build_board.py

@@ -28,12 +28,11 @@ def filter_with_input(mylist):
 
 # If examples are not specified in arguments, build all
 all_examples = []
-for entry in os.scandir("examples/device"):
-    if entry.is_dir():
-        all_examples.append("device/" + entry.name)
-for entry in os.scandir("examples/host"):
-    if entry.is_dir():
-        all_examples.append("host/" + entry.name)
+for dir1 in os.scandir("examples"):
+    if dir1.is_dir():
+        for entry in os.scandir(dir1.path):
+            if entry.is_dir():
+                all_examples.append(dir1.name + '/' + entry.name)
 filter_with_input(all_examples)
 all_examples.sort()
 

+ 5 - 6
tools/build_family.py

@@ -28,12 +28,11 @@ def filter_with_input(mylist):
 
 # If examples are not specified in arguments, build all
 all_examples = []
-for entry in os.scandir("examples/device"):
-    if entry.is_dir():
-        all_examples.append("device/" + entry.name)
-for entry in os.scandir("examples/host"):
-    if entry.is_dir():
-        all_examples.append("host/" + entry.name)
+for dir1 in os.scandir("examples"):
+    if dir1.is_dir():
+        for entry in os.scandir(dir1.path):
+            if entry.is_dir():
+                all_examples.append(dir1.name + '/' + entry.name)
 filter_with_input(all_examples)
 all_examples.sort()