diff --git a/.idea/cmake.xml b/.idea/cmake.xml
index 37cd73c65..d4ad3a748 100644
--- a/.idea/cmake.xml
+++ b/.idea/cmake.xml
@@ -9,35 +9,21 @@
       <configuration PROFILE_NAME="feather_rp2040" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=pico_sdk -DPICO_BOARD=adafruit_feather_rp2040 -DLOG=1" />
       <configuration PROFILE_NAME="feather_rp2040_max3421" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_rp2040_max3421 -DLOG=1" />
       <configuration PROFILE_NAME="metro_rp2040" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=pico_sdk -DPICO_BOARD=adafruit_metro_rp2040 -DLOG=1 -DMAX3421_HOST=1" />
-      <configuration PROFILE_NAME="feather esp32s2" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_feather_esp32s2 -DMAX3421_HOST=1 -DLOG=1">
+      <configuration PROFILE_NAME="adafruit_feather_esp32_v2" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_feather_esp32_v2 -DMAX3421_HOST=1 -DLOG=1">
         <ADDITIONAL_GENERATION_ENVIRONMENT>
           <envs>
             <env name="ESPBAUD" value="1500000" />
           </envs>
         </ADDITIONAL_GENERATION_ENVIRONMENT>
       </configuration>
-      <configuration PROFILE_NAME="metro esp32s2" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_metro_esp32s2 -DMAX3421_HOST=1 -DLOG=1">
+      <configuration PROFILE_NAME="adafruit_feather_esp32s2" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_feather_esp32s2 -DMAX3421_HOST=1 -DLOG=1">
         <ADDITIONAL_GENERATION_ENVIRONMENT>
           <envs>
             <env name="ESPBAUD" value="1500000" />
           </envs>
         </ADDITIONAL_GENERATION_ENVIRONMENT>
       </configuration>
-      <configuration PROFILE_NAME="kaluga" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=espressif_kaluga_1 -DMAX3421_HOST=1 -DLOG=1">
-        <ADDITIONAL_GENERATION_ENVIRONMENT>
-          <envs>
-            <env name="ESPBAUD" value="1500000" />
-          </envs>
-        </ADDITIONAL_GENERATION_ENVIRONMENT>
-      </configuration>
-      <configuration PROFILE_NAME="feather esp32s3" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_feather_esp32s3 -DMAX3421_HOST=1 -DLOG=1">
-        <ADDITIONAL_GENERATION_ENVIRONMENT>
-          <envs>
-            <env name="ESPBAUD" value="1500000" />
-          </envs>
-        </ADDITIONAL_GENERATION_ENVIRONMENT>
-      </configuration>
-      <configuration PROFILE_NAME="espressif_s3_devkitc" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=espressif_s3_devkitc -DLOG=1">
+      <configuration PROFILE_NAME="adafruit_feather_esp32s3" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_feather_esp32s3 -DMAX3421_HOST=1 -DLOG=1">
         <ADDITIONAL_GENERATION_ENVIRONMENT>
           <envs>
             <env name="ESPBAUD" value="1500000" />
@@ -51,7 +37,21 @@
           </envs>
         </ADDITIONAL_GENERATION_ENVIRONMENT>
       </configuration>
-      <configuration PROFILE_NAME="adafruit_feather_esp32_v2" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=adafruit_feather_esp32_v2 -DMAX3421_HOST=1 -DLOG=1">
+      <configuration PROFILE_NAME="espressif_kaluga_1" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=espressif_kaluga_1 -DMAX3421_HOST=1 -DLOG=1">
+        <ADDITIONAL_GENERATION_ENVIRONMENT>
+          <envs>
+            <env name="ESPBAUD" value="1500000" />
+          </envs>
+        </ADDITIONAL_GENERATION_ENVIRONMENT>
+      </configuration>
+      <configuration PROFILE_NAME="espressif_s3_devkitc" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=espressif_s3_devkitc -DLOG=1">
+        <ADDITIONAL_GENERATION_ENVIRONMENT>
+          <envs>
+            <env name="ESPBAUD" value="1500000" />
+          </envs>
+        </ADDITIONAL_GENERATION_ENVIRONMENT>
+      </configuration>
+      <configuration PROFILE_NAME="espressif_p4_function_ev" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=espressif_p4_function_ev">
         <ADDITIONAL_GENERATION_ENVIRONMENT>
           <envs>
             <env name="ESPBAUD" value="1500000" />
@@ -65,19 +65,15 @@
           </envs>
         </ADDITIONAL_GENERATION_ENVIRONMENT>
       </configuration>
-      <configuration PROFILE_NAME="espressif_p4_function_ev" ENABLED="false" TOOLCHAIN_NAME="ESP-IDF" GENERATION_OPTIONS="-DBOARD=espressif_p4_function_ev -DLOG=1">
-        <ADDITIONAL_GENERATION_ENVIRONMENT>
-          <envs>
-            <env name="ESPBAUD" value="1500000" />
-          </envs>
-        </ADDITIONAL_GENERATION_ENVIRONMENT>
-      </configuration>
       <configuration PROFILE_NAME="feather_m0_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_m0_express -DLOG=1 -DLOGGER=RTT -DMAX3421_HOST=1" />
       <configuration PROFILE_NAME="metro_m0_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m0_express -DLOG=1 -DLOGGER=RTT -DMAX3421_HOST=1" />
+      <configuration PROFILE_NAME="samd11_xplained" ENABLED="false" CONFIG_NAME="MinSizeRel" GENERATION_OPTIONS="-DBOARD=samd11_xplained" />
+      <configuration PROFILE_NAME="atsaml21_xpro" ENABLED="false" GENERATION_OPTIONS="-DBOARD=atsaml21_xpro" />
       <configuration PROFILE_NAME="feather_m4_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_m4_express -DLOG=1 -DLOGGER=RTT -DMAX3421_HOST=1" />
       <configuration PROFILE_NAME="metro_m4_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=metro_m4_express -DLOG=1 -DLOGGER=RTT -DMAX3421_HOST=1" />
       <configuration PROFILE_NAME="itsybitsy_m4" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=itsybitsy_m4" />
       <configuration PROFILE_NAME="same54_xplained" ENABLED="false" GENERATION_OPTIONS="-DBOARD=same54_xplained -DLOG=1 -DLOGGER=RTT" />
+      <configuration PROFILE_NAME="samg55_xplained" ENABLED="false" GENERATION_OPTIONS="-DBOARD=samg55_xplained" />
       <configuration PROFILE_NAME="feather_nrf52840_express" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=feather_nrf52840_express -DLOG=1 -DLOGGER=RTT -DMAX3421_HOST=1" />
       <configuration PROFILE_NAME="pca10056" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=pca10056 -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
       <configuration PROFILE_NAME="pca10095" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=pca10095 -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
@@ -86,33 +82,22 @@
       <configuration PROFILE_NAME="rt1010 evk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mimxrt1010_evk -DLOG=1 -DLOGGER=RTT" />
       <configuration PROFILE_NAME="rt1060 evk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mimxrt1060_evk -DLOG=1 -DLOGGER=RTT" />
       <configuration PROFILE_NAME="rt1170 evkb" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mimxrt1170_evkb -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
-      <configuration PROFILE_NAME="lpcxpresso1769" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso1769 -DLOG=1 -DLOGGER=RTT" />
-      <configuration PROFILE_NAME="mcb1800" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mcb1800 -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
-      <configuration PROFILE_NAME="ea4088 quickstart" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ea4088_quickstart -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
-      <configuration PROFILE_NAME="ea4357" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ea4357 -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
-      <configuration PROFILE_NAME="lpc5414" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso54114 -DLOG=1 -DLOGGER=RTT" />
-      <configuration PROFILE_NAME="lpc54628" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso54628 -DLOG=1 -DLOGGER=RTT" />
-      <configuration PROFILE_NAME="lpc55s69" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso55s69 -DLOG=1 -DLOGGER=RTT" />
-      <configuration PROFILE_NAME="mcxn947brk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mcxn947brk -DLOG=1 -DLOGGER=RTT" />
-      <configuration PROFILE_NAME="frdm_mcxa153" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_mcxa153 -DLOG=1 -DLOGGER=RTT" />
-      <configuration PROFILE_NAME="frdm_kl25z" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_kl25z -DLOG=1 -DLOGGER=RTT" />
-      <configuration PROFILE_NAME="frdm_k32l2a4s" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_k32l2a4s" />
-      <configuration PROFILE_NAME="frdm_k64f" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_k64f -DLOG=1 -DLOGGER=RTT" />
       <configuration PROFILE_NAME="stm32f072disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f072disco -DLOG=0 -DLOGGER=RTT" />
       <configuration PROFILE_NAME="stm32f103_mini_2" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f103_mini_2 -DLOG=1 -DLOGGGER=RTT" />
       <configuration PROFILE_NAME="stm32f103ze_iar" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f103ze_iar -DLOG=1 -DLOGGGER=RTT" />
       <configuration PROFILE_NAME="stm32f207nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f207nucleo -DLOG=1 -DLOGGER=RTT" />
       <configuration PROFILE_NAME="stm32f303disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f303disco -DLOG=0 -DLOGGER=RTT" />
-      <configuration PROFILE_NAME="stm32f411disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f411disco -DLOG=1 -DLOGGER=RTT" />
-      <configuration PROFILE_NAME="stm32f769disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f769disco -DLOG=1 -DLOGGER=RTT" />
+      <configuration PROFILE_NAME="stm32f411disco" ENABLED="true" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f411disco -DLOG=1 -DLOGGER=RTT" />
+      <configuration PROFILE_NAME="stm32f412disco" ENABLED="true" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f412disco -DLOG=1 -DLOGGER=RTT" />
+      <configuration PROFILE_NAME="stm32f769disco" ENABLED="true" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32f769disco -DLOG=1 -DLOGGER=RTT" />
       <configuration PROFILE_NAME="stm32g0b1nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32g0b1nucleo" />
       <configuration PROFILE_NAME="stm32g474nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32g474nucleo" />
       <configuration PROFILE_NAME="b_g474e_dpow1" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=b_g474e_dpow1 -DLOG=1 -DLOGGER=RTT" />
       <configuration PROFILE_NAME="stm32h563nucleo" ENABLED="false" GENERATION_OPTIONS="-DBOARD=stm32h563nucleo -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
-      <configuration PROFILE_NAME="stm32h743eval" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32h743eval -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
+      <configuration PROFILE_NAME="stm32h743eval" ENABLED="true" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32h743eval -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
       <configuration PROFILE_NAME="stm32h743nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32h743nucleo -DLOG=1" />
       <configuration PROFILE_NAME="stm32l0538disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32l0538disco -DLOG=0 -DLOGGER=RTT" />
-      <configuration PROFILE_NAME="stm32l476disco" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32l476disco" />
+      <configuration PROFILE_NAME="stm32l476disco" ENABLED="true" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32l476disco -DLOG=1 -DLOGGER=RTT" />
       <configuration PROFILE_NAME="stm32u575nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32u575nucleo -DLOG=1 -DLOGGER=RTT" />
       <configuration PROFILE_NAME="stm32u5a5nucleo" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=stm32u5a5nucleo -DLOG=1 -DLOGGER=RTT" />
       <configuration PROFILE_NAME="stm32wb55nucleo" ENABLED="false" GENERATION_OPTIONS="-DBOARD=stm32wb55nucleo" />
@@ -124,22 +109,31 @@
       <configuration PROFILE_NAME="uno_r4" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=uno_r4 -DLOG=4 -DLOGGER=RTT" />
       <configuration PROFILE_NAME="portenta_c33" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=portenta_c33 -DLOG=1" />
       <configuration PROFILE_NAME="raspberrypi_zero" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberrypi_zero -DLOG=1" />
-      <configuration PROFILE_NAME="raspberrypi_cm4" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberrypi_cm4 -DLOG=1" />
       <configuration PROFILE_NAME="raspberrypi_zero2" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberrypi_zero2 -DLOG=1" />
+      <configuration PROFILE_NAME="raspberrypi_cm4" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=raspberrypi_cm4 -DLOG=1" />
       <configuration PROFILE_NAME="lpcxpresso11u37" ENABLED="false" GENERATION_OPTIONS="-DBOARD=lpcxpresso11u37" />
       <configuration PROFILE_NAME="lpcxpresso11u68" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso11u68 -DLOG=1 -DLOGGER=RTT" />
       <configuration PROFILE_NAME="lpcxpresso1347" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso1347 -DLOG=1 -DLOGGER=RTT" />
       <configuration PROFILE_NAME="lpcxpresso1549" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso1549 -DLOG=1 -DLOGGER=RTT" />
+      <configuration PROFILE_NAME="lpcxpresso1769" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso1769 -DLOG=1 -DLOGGER=RTT" />
+      <configuration PROFILE_NAME="mcb1800" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mcb1800 -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
+      <configuration PROFILE_NAME="ea4088 quickstart" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ea4088_quickstart -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
+      <configuration PROFILE_NAME="ea4357" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=ea4357 -DLOG=1 -DLOGGER=RTT -DTRACE_ETM=1" />
       <configuration PROFILE_NAME="lpcxpresso51u68" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso51u68 -DLOG=1 -DLOGGER=RTT" />
-      <configuration PROFILE_NAME="atsaml21_xpro" ENABLED="false" GENERATION_OPTIONS="-DBOARD=atsaml21_xpro" />
-      <configuration PROFILE_NAME="samd11_xplained" ENABLED="false" CONFIG_NAME="MinSizeRel" GENERATION_OPTIONS="-DBOARD=samd11_xplained" />
+      <configuration PROFILE_NAME="lpc5414" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso54114 -DLOG=1 -DLOGGER=RTT" />
+      <configuration PROFILE_NAME="lpc54628" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso54628 -DLOG=1 -DLOGGER=RTT" />
+      <configuration PROFILE_NAME="lpc55s69" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=lpcxpresso55s69 -DLOG=1 -DLOGGER=RTT" />
+      <configuration PROFILE_NAME="mcxn947brk" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=mcxn947brk -DLOG=1 -DLOGGER=RTT" />
+      <configuration PROFILE_NAME="frdm_mcxa153" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_mcxa153 -DLOG=1 -DLOGGER=RTT" />
+      <configuration PROFILE_NAME="frdm_kl25z" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_kl25z -DLOG=1 -DLOGGER=RTT" />
+      <configuration PROFILE_NAME="frdm_k32l2a4s" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_k32l2a4s" />
+      <configuration PROFILE_NAME="frdm_k64f" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=frdm_k64f -DLOG=1 -DLOGGER=RTT" />
       <configuration PROFILE_NAME="msp430f5529" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=msp_exp430f5529lp" />
       <configuration PROFILE_NAME="msp_exp432e401y" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=msp_exp432e401y -DLOG=1" />
       <configuration PROFILE_NAME="ek_tm4c123gxl" ENABLED="false" CONFIG_NAME="MinSizeRel" GENERATION_OPTIONS="-DBOARD=ek_tm4c123gxl -DLOG=1" />
       <configuration PROFILE_NAME="xmc4500_relax" ENABLED="false" GENERATION_OPTIONS="-DBOARD=xmc4500_relax -DLOG=1 -DLOGGER=RTT" />
       <configuration PROFILE_NAME="f1c100s" ENABLED="false" GENERATION_OPTIONS="-DBOARD=f1c100s" />
       <configuration PROFILE_NAME="mm32f327x_mb39" ENABLED="false" GENERATION_OPTIONS="-DBOARD=mm32f327x_mb39" />
-      <configuration PROFILE_NAME="samg55_xplained" ENABLED="false" GENERATION_OPTIONS="-DBOARD=samg55_xplained" />
       <configuration PROFILE_NAME="fomu" ENABLED="false" GENERATION_OPTIONS="-DBOARD=fomu" />
       <configuration PROFILE_NAME="sipeed_longan_nano" ENABLED="false" GENERATION_OPTIONS="-DBOARD=sipeed_longan_nano" />
       <configuration PROFILE_NAME="nanoch32v203" ENABLED="false" CONFIG_NAME="Debug" GENERATION_OPTIONS="-DBOARD=nanoch32v203" />
diff --git a/hw/bsp/stm32h7/boards/stm32h743eval/board.cmake b/hw/bsp/stm32h7/boards/stm32h743eval/board.cmake
index a28aa87bd..6d7a97741 100644
--- a/hw/bsp/stm32h7/boards/stm32h743eval/board.cmake
+++ b/hw/bsp/stm32h7/boards/stm32h743eval/board.cmake
@@ -1,5 +1,6 @@
 set(MCU_VARIANT stm32h743xx)
 set(JLINK_DEVICE stm32h743xi)
+# set(JLINK_OPTION "-USB jtrace")
 
 set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/${MCU_VARIANT}_flash.ld)
 
diff --git a/hw/bsp/stm32l4/boards/stm32l476disco/board.cmake b/hw/bsp/stm32l4/boards/stm32l476disco/board.cmake
index 4ade0a5c9..fd1c931c2 100644
--- a/hw/bsp/stm32l4/boards/stm32l476disco/board.cmake
+++ b/hw/bsp/stm32l4/boards/stm32l476disco/board.cmake
@@ -1,6 +1,6 @@
 set(MCU_VARIANT stm32l476xx)
 set(JLINK_DEVICE stm32l476vg)
-
+# set(JLINK_OPTION "-USB 000777632258")
 set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/STM32L476VGTx_FLASH.ld)
 
 function(update_board TARGET)
diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c
index 210ce1bba..99cf3fdaa 100644
--- a/src/portable/synopsys/dwc2/dcd_dwc2.c
+++ b/src/portable/synopsys/dwc2/dcd_dwc2.c
@@ -327,53 +327,49 @@ static void edpt_activate(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoin
   xfer->interval = p_endpoint_desc->bInterval;
 
   // USBAEP, EPTYP, SD0PID_SEVNFRM, MPSIZ are the same for IN and OUT endpoints.
-  uint32_t const dxepctl = (1 << DOEPCTL_USBAEP_Pos) |
-                           (p_endpoint_desc->bmAttributes.xfer << DOEPCTL_EPTYP_Pos) |
-                           (p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DOEPCTL_SD0PID_SEVNFRM : 0) |
-                           (xfer->max_size << DOEPCTL_MPSIZ_Pos);
-
-  if (dir == TUSB_DIR_OUT) {
-    dwc2->epout[epnum].doepctl = dxepctl;
-    dwc2->daintmsk |= TU_BIT(DAINTMSK_OEPM_Pos + epnum);
-  } else {
-    dwc2->epin[epnum].diepctl = dxepctl | (epnum << DIEPCTL_TXFNUM_Pos);
-    dwc2->daintmsk |= TU_BIT(DAINTMSK_IEPM_Pos + epnum);
+  uint32_t epctl = (1 << DOEPCTL_USBAEP_Pos) |
+                   (p_endpoint_desc->bmAttributes.xfer << DOEPCTL_EPTYP_Pos) |
+                   (p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? DOEPCTL_SD0PID_SEVNFRM : 0) |
+                   (xfer->max_size << DOEPCTL_MPSIZ_Pos);
+  if (dir == TUSB_DIR_IN) {
+    epctl |= (epnum << DIEPCTL_TXFNUM_Pos);
   }
+
+  dwc2_dep_t* dep = &dwc2->ep[1 - dir][epnum];
+  dep->ctl = epctl;
+  dwc2->daintmsk |= TU_BIT(epnum + DAINT_SHIFT(dir));
 }
 
 static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) {
   (void) rhport;
 
   dwc2_regs_t* dwc2 = DWC2_REG(rhport);
-  uint8_t const epnum = tu_edpt_number(ep_addr);
-  uint8_t const dir = tu_edpt_dir(ep_addr);
+  const uint8_t epnum = tu_edpt_number(ep_addr);
+  const uint8_t dir = tu_edpt_dir(ep_addr);
+  dwc2_dep_t* dep = &dwc2->ep[1 - dir][epnum];
 
   if (dir == TUSB_DIR_IN) {
-    dwc2_epin_t* epin = dwc2->epin;
-
     // Only disable currently enabled non-control endpoint
-    if ((epnum == 0) || !(epin[epnum].diepctl & DIEPCTL_EPENA)) {
-      epin[epnum].diepctl |= DIEPCTL_SNAK | (stall ? DIEPCTL_STALL : 0);
+    if ((epnum == 0) || !(dep->diepctl & DIEPCTL_EPENA)) {
+      dep->diepctl |= DIEPCTL_SNAK | (stall ? DIEPCTL_STALL : 0);
     } else {
       // Stop transmitting packets and NAK IN xfers.
-      epin[epnum].diepctl |= DIEPCTL_SNAK;
-      while ((epin[epnum].diepint & DIEPINT_INEPNE) == 0) {}
+      dep->diepctl |= DIEPCTL_SNAK;
+      while ((dep->diepint & DIEPINT_INEPNE) == 0) {}
 
       // Disable the endpoint.
-      epin[epnum].diepctl |= DIEPCTL_EPDIS | (stall ? DIEPCTL_STALL : 0);
-      while ((epin[epnum].diepint & DIEPINT_EPDISD_Msk) == 0) {}
+      dep->diepctl |= DIEPCTL_EPDIS | (stall ? DIEPCTL_STALL : 0);
+      while ((dep->diepint & DIEPINT_EPDISD_Msk) == 0) {}
 
-      epin[epnum].diepint = DIEPINT_EPDISD;
+      dep->diepint = DIEPINT_EPDISD;
     }
 
     // Flush the FIFO, and wait until we have confirmed it cleared.
     dfifo_flush_tx(dwc2, epnum);
   } else {
-    dwc2_epout_t* epout = dwc2->epout;
-
     // Only disable currently enabled non-control endpoint
-    if ((epnum == 0) || !(epout[epnum].doepctl & DOEPCTL_EPENA)) {
-      epout[epnum].doepctl |= stall ? DOEPCTL_STALL : 0;
+    if ((epnum == 0) || !(dep->doepctl & DOEPCTL_EPENA)) {
+      dep->doepctl |= stall ? 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
@@ -382,11 +378,11 @@ static void edpt_disable(uint8_t rhport, uint8_t ep_addr, bool stall) {
       dwc2->dctl |= DCTL_SGONAK;
       while ((dwc2->gintsts & GINTSTS_BOUTNAKEFF_Msk) == 0) {}
 
-      // Ditto here- disable the endpoint.
-      epout[epnum].doepctl |= DOEPCTL_EPDIS | (stall ? DOEPCTL_STALL : 0);
-      while ((epout[epnum].doepint & DOEPINT_EPDISD_Msk) == 0) {}
+      // Ditto here disable the endpoint.
+      dep->doepctl |= DOEPCTL_EPDIS | (stall ? DOEPCTL_STALL : 0);
+      while ((dep->doepint & DOEPINT_EPDISD_Msk) == 0) {}
 
-      epout[epnum].doepint = DOEPINT_EPDISD;
+      dep->doepint = DOEPINT_EPDISD;
 
       // Allow other OUT endpoints to keep receiving.
       dwc2->dctl |= DCTL_CGONAK;
@@ -430,7 +426,7 @@ static void bus_reset(uint8_t rhport) {
 
   dfifo_init(rhport);
 
-  // Fixed control EP0 size to 64 bytes
+  // Fixed both control EP0 size to 64 bytes
   dwc2->epin[0].diepctl &= ~(0x03 << DIEPCTL_MPSIZ_Pos);
   dwc2->epout[0].doepctl &= ~(0x03 << DOEPCTL_MPSIZ_Pos);
 
@@ -461,33 +457,33 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c
   }
 
   // IN and OUT endpoint xfers are interrupt-driven, we just schedule them here.
-  if (dir == TUSB_DIR_IN) {
-    dwc2_epin_t* epin = dwc2->epin;
+  const uint8_t is_epout = 1 - dir;
+  dwc2_dep_t* dep = &dwc2->ep[is_epout][epnum];
 
+  if (dir == TUSB_DIR_IN) {
     // A full IN transfer (multiple packets, possibly) triggers XFRC.
-    epin[epnum].dieptsiz = (num_packets << DIEPTSIZ_PKTCNT_Pos) |
+    dep->dieptsiz = (num_packets << DIEPTSIZ_PKTCNT_Pos) |
                            ((total_bytes << DIEPTSIZ_XFRSIZ_Pos) & DIEPTSIZ_XFRSIZ_Msk);
 
     if(dma_enabled(dwc2)) {
-      epin[epnum].diepdma = (uintptr_t)xfer->buffer;
+      dep->diepdma = (uintptr_t)xfer->buffer;
 
       // For ISO endpoint set correct odd/even bit for next frame.
-      if ((epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) {
+      if ((dep->diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) {
         // Take odd/even bit from frame counter.
         uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos));
-        epin[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk);
+        dep->diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk);
       }
 
-      epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK;
+      dep->diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK;
     } else {
-
-      epin[epnum].diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK;
+      dep->diepctl |= DIEPCTL_EPENA | DIEPCTL_CNAK;
 
       // For ISO endpoint set correct odd/even bit for next frame.
-      if ((epin[epnum].diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) {
+      if ((dep->diepctl & DIEPCTL_EPTYP) == DIEPCTL_EPTYP_0 && (XFER_CTL_BASE(epnum, dir))->interval == 1) {
         // Take odd/even bit from frame counter.
         uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos));
-        epin[epnum].diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk);
+        dep->diepctl |= (odd_frame_now ? DIEPCTL_SD0PID_SEVNFRM_Msk : DIEPCTL_SODDFRM_Msk);
       }
       // Enable fifo empty interrupt only if there are something to put in the fifo.
       if (total_bytes != 0) {
@@ -495,25 +491,23 @@ static void edpt_schedule_packets(uint8_t rhport, uint8_t const epnum, uint8_t c
       }
     }
   } else {
-    dwc2_epout_t* epout = dwc2->epout;
-
     // A full OUT transfer (multiple packets, possibly) triggers XFRC.
-    epout[epnum].doeptsiz &= ~(DOEPTSIZ_PKTCNT_Msk | DOEPTSIZ_XFRSIZ);
-    epout[epnum].doeptsiz |= (num_packets << DOEPTSIZ_PKTCNT_Pos) |
+    dep->doeptsiz &= ~(DOEPTSIZ_PKTCNT_Msk | DOEPTSIZ_XFRSIZ);
+    dep->doeptsiz |= (num_packets << DOEPTSIZ_PKTCNT_Pos) |
                              ((total_bytes << DOEPTSIZ_XFRSIZ_Pos) & DOEPTSIZ_XFRSIZ_Msk);
 
-    if ((epout[epnum].doepctl & DOEPCTL_EPTYP) == DOEPCTL_EPTYP_0 &&
+    if ((dep->doepctl & DOEPCTL_EPTYP) == DOEPCTL_EPTYP_0 &&
         XFER_CTL_BASE(epnum, dir)->interval == 1) {
       // Take odd/even bit from frame counter.
       uint32_t const odd_frame_now = (dwc2->dsts & (1u << DSTS_FNSOF_Pos));
-      epout[epnum].doepctl |= (odd_frame_now ? DOEPCTL_SD0PID_SEVNFRM_Msk : DOEPCTL_SODDFRM_Msk);
+      dep->doepctl |= (odd_frame_now ? DOEPCTL_SD0PID_SEVNFRM_Msk : DOEPCTL_SODDFRM_Msk);
     }
 
     if(dma_enabled(dwc2)) {
-      epout[epnum].doepdma = (uintptr_t)xfer->buffer;
+      dep->doepdma = (uintptr_t)xfer->buffer;
     }
 
-    epout[epnum].doepctl |= DOEPCTL_EPENA | DOEPCTL_CNAK;
+    dep->doepctl |= DOEPCTL_EPENA | DOEPCTL_CNAK;
   }
 }
 
@@ -837,17 +831,13 @@ void dcd_edpt_close_all(uint8_t rhport) {
   dwc2->daintmsk = (1 << DAINTMSK_OEPM_Pos) | (1 << DAINTMSK_IEPM_Pos);
 
   for (uint8_t n = 1; n < ep_count; n++) {
-    // disable OUT endpoint
-    if (dwc2->epout[n].doepctl & DOEPCTL_EPENA) {
-      dwc2->epout[n].doepctl |= DOEPCTL_SNAK | DOEPCTL_EPDIS;
+    for (uint8_t d = 0; d < 2; d++) {
+      dwc2_dep_t* dep = &dwc2->ep[d][n];
+      if (dep->ctl & EPCTL_EPENA) {
+        dep->ctl |= EPCTL_SNAK | EPCTL_EPDIS;
+      }
+      xfer_status[n][1-d].max_size = 0;
     }
-    xfer_status[n][TUSB_DIR_OUT].max_size = 0;
-
-    // disable IN endpoint
-    if (dwc2->epin[n].diepctl & DIEPCTL_EPENA) {
-      dwc2->epin[n].diepctl |= DIEPCTL_SNAK | DIEPCTL_EPDIS;
-    }
-    xfer_status[n][TUSB_DIR_IN].max_size = 0;
   }
 
   dfifo_flush_tx(dwc2, 0x10); // all tx fifo
@@ -937,21 +927,14 @@ void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) {
 }
 
 void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {
-  (void) rhport;
-
   dwc2_regs_t* dwc2 = DWC2_REG(rhport);
-
   uint8_t const epnum = tu_edpt_number(ep_addr);
   uint8_t const dir = tu_edpt_dir(ep_addr);
+  dwc2_dep_t* dep = &dwc2->ep[1 - dir][epnum];
 
   // Clear stall and reset data toggle
-  if (dir == TUSB_DIR_IN) {
-    dwc2->epin[epnum].diepctl &= ~DIEPCTL_STALL;
-    dwc2->epin[epnum].diepctl |= DIEPCTL_SD0PID_SEVNFRM;
-  } else {
-    dwc2->epout[epnum].doepctl &= ~DOEPCTL_STALL;
-    dwc2->epout[epnum].doepctl |= DOEPCTL_SD0PID_SEVNFRM;
-  }
+  dep->ctl &= ~EPCTL_STALL;;
+  dep->ctl |= EPCTL_SD0PID_SEVNFRM;
 }
 
 //--------------------------------------------------------------------
@@ -963,10 +946,10 @@ static void handle_rxflvl_irq(uint8_t rhport) {
   volatile uint32_t const* rx_fifo = dwc2->fifo[0];
 
   // Pop control word off FIFO
-  uint32_t const ctl_word = dwc2->grxstsp;
-  uint8_t const pktsts = (ctl_word & GRXSTSP_PKTSTS_Msk) >> GRXSTSP_PKTSTS_Pos;
-  uint8_t const epnum = (ctl_word & GRXSTSP_EPNUM_Msk) >> GRXSTSP_EPNUM_Pos;
-  uint16_t const bcnt = (ctl_word & GRXSTSP_BCNT_Msk) >> GRXSTSP_BCNT_Pos;
+  uint32_t const grxstsp = dwc2->grxstsp;
+  uint8_t const pktsts = (grxstsp & GRXSTSP_PKTSTS_Msk) >> GRXSTSP_PKTSTS_Pos;
+  uint8_t const epnum = (grxstsp & GRXSTSP_EPNUM_Msk) >> GRXSTSP_EPNUM_Pos;
+  uint16_t const bcnt = (grxstsp & GRXSTSP_BCNT_Msk) >> GRXSTSP_BCNT_Pos;
 
   dwc2_epout_t* epout = &dwc2->epout[epnum];
 
@@ -1024,20 +1007,16 @@ static void handle_rxflvl_irq(uint8_t rhport) {
           ep0_pending[TUSB_DIR_OUT] = 0;
         }
       }
+      break;
     }
-      break;
 
-      // Out packet done (Interrupt)
     case GRXSTS_PKTSTS_OUTDONE:
-      // Occurred on STM32L47 with dwc2 version 3.10a but not found on other version like 2.80a or 3.30a
-      // May (or not) be 3.10a specific feature/bug or depending on MCU configuration
-      // XFRC complete is additionally generated when
-      // - setup packet is received
-      // - complete the data stage of control write is complete
-      // It will be handled in handle_epout_irq()
+      /* Out packet done (Interrupt)
+         After this entry is popped from the receive FIFO, the controller asserts a Transfer Completed interrupt on
+         the specified OUT endpoint which will be handled by handle_epout_irq() */
       break;
 
-    default:    // Invalid
+    default:
       TU_BREAKPOINT();
       break;
   }
@@ -1049,73 +1028,73 @@ static void handle_epout_irq(uint8_t rhport) {
 
   // 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_count; n++) {
-    if (dwc2->daint & TU_BIT(DAINT_OEPINT_Pos + n)) {
-      dwc2_epout_t* epout = &dwc2->epout[n];
-
-      uint32_t const doepint = epout->doepint;
-
+  for (uint8_t epnum = 0; epnum < ep_count; epnum++) {
+    if (dwc2->daint & TU_BIT(DAINT_OEPINT_Pos + epnum)) {
+      dwc2_epout_t* epout = &dwc2->epout[epnum];
+      const uint32_t doepint = epout->doepint;
       TU_ASSERT((epout->doepint & DOEPINT_AHBERR) == 0, );
 
       // OUT XFER complete
-      if (epout->doepint & DOEPINT_XFRC) {
+      if (doepint & DOEPINT_XFRC) {
         epout->doepint = DOEPINT_XFRC;
 
-        xfer_ctl_t* xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT);
+        xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT);
 
         if(dma_enabled(dwc2)) {
-          if (doepint & DOEPINT_STUP) {
+          if (doepint & DOEPINT_SETUP) {
             // STPKTRX is only available for version from 3_00a
-            if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) {
-              epout->doepint = DOEPINT_STPKTRX;
+            if ((doepint & DOEPINT_DMA_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) {
+              epout->doepint = DOEPINT_DMA_STPKTRX;
             }
-          } else if (doepint & DOEPINT_OTEPSPR) {
-            epout->doepint = DOEPINT_OTEPSPR;
+          } else if (doepint & DOEPINT_STSPHSRX) {
+            epout->doepint = DOEPINT_STSPHSRX;
           } else {
-            if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) {
-              epout->doepint = DOEPINT_STPKTRX;
+            if ((doepint & DOEPINT_DMA_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) {
+              epout->doepint = DOEPINT_DMA_STPKTRX;
             } else {
               // EP0 can only handle one packet
-              if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) {
+              if ((epnum == 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]);
+                edpt_schedule_packets(rhport, epnum, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]);
               } else {
                 // Fix packet length
                 uint16_t remain = (epout->doeptsiz & DOEPTSIZ_XFRSIZ_Msk) >> DOEPTSIZ_XFRSIZ_Pos;
                 xfer->total_len -= remain;
                 // this is ZLP, so prepare EP0 for next setup
-                if(n == 0 && xfer->total_len == 0) {
+                if(epnum == 0 && xfer->total_len == 0) {
                   dma_setup_prepare(rhport);
                 }
 
-                dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true);
+                dcd_event_xfer_complete(rhport, epnum, xfer->total_len, XFER_RESULT_SUCCESS, true);
               }
             }
           }
         } else {
-          if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) {
-            epout->doepint = DOEPINT_STPKTRX;
+          // DMA_STPKTRX should only be set in Buffer DMA Mode. However, STM32L476 (slave-only) with v3.10a
+          // incorrectly set this along with SETUP bit. This may (or not) be STM32L476 or 3.10a specific bug
+          if ((doepint & DOEPINT_DMA_STPKTRX) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) {
+            epout->doepint = DOEPINT_DMA_STPKTRX;
           } else {
-            if ((doepint & DOEPINT_OTEPSPR) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) {
-              epout->doepint = DOEPINT_OTEPSPR;
+            if ((doepint & DOEPINT_STSPHSRX) && (dwc2->gsnpsid == DWC2_CORE_REV_3_10a)) {
+              epout->doepint = DOEPINT_STSPHSRX;
             }
 
             // EP0 can only handle one packet
-            if ((n == 0) && ep0_pending[TUSB_DIR_OUT]) {
+            if ((epnum == 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]);
+              edpt_schedule_packets(rhport, epnum, TUSB_DIR_OUT, 1, ep0_pending[TUSB_DIR_OUT]);
             } else {
-              dcd_event_xfer_complete(rhport, n, xfer->total_len, XFER_RESULT_SUCCESS, true);
+              dcd_event_xfer_complete(rhport, epnum, xfer->total_len, XFER_RESULT_SUCCESS, true);
             }
           }
         }
       }
 
       // SETUP packet Setup Phase done.
-      if (doepint & DOEPINT_STUP) {
-        epout->doepint = DOEPINT_STUP;
-        if ((doepint & DOEPINT_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) {
-          epout->doepint = DOEPINT_STPKTRX;
+      if (doepint & DOEPINT_SETUP) {
+        epout->doepint = DOEPINT_SETUP;
+        if ((doepint & DOEPINT_DMA_STPKTRX) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) {
+          epout->doepint = DOEPINT_DMA_STPKTRX;
         }
         if(dma_enabled(dwc2) && (dwc2->gsnpsid > DWC2_CORE_REV_3_00a)) {
           dma_setup_prepare(rhport);
@@ -1195,6 +1174,29 @@ static void handle_epin_irq(uint8_t rhport) {
   }
 }
 
+/* Interrupt Hierarchy
+
+   DxEPMSK.XferComplMsk     DxEPINTn.XferCompl
+         |                       |
+         +---------- AND --------+
+                      |
+     DAINT.xEPnInt            DAINTMSK.xEPnMsk
+         |                       |
+         +---------- AND --------+
+                      |
+    GINTSTS.xEPInt         GINTMSK.xEPIntMsk
+         |                       |
+         +---------- AND --------+
+                      |
+             GAHBCFG.GblIntrMsk
+                      |
+                    IRQn
+
+  Note: when OTG_MULTI_PROC_INTRPT = 1, Device Each endpoint interrupt deachint/deachmsk/diepeachmsk/doepeachmsk
+  are combined to generate dedicated interrupt line for each endpoint.
+ */
+
+
 void dcd_int_handler(uint8_t rhport) {
   dwc2_regs_t* dwc2 = DWC2_REG(rhport);
 
@@ -1276,8 +1278,8 @@ void dcd_int_handler(uint8_t rhport) {
     // Mask out RXFLVL while reading data from FIFO
     dwc2->gintmsk &= ~GINTMSK_RXFLVLM;
 
-    // Loop until all available packets were handled
     do {
+      // Loop until all available packets were handled
       handle_rxflvl_irq(rhport);
     } while(dwc2->gintsts & GINTSTS_RXFLVL);
 
diff --git a/src/portable/synopsys/dwc2/dwc2_info.md b/src/portable/synopsys/dwc2/dwc2_info.md
index cd8a57ec3..5c7e5e688 100644
--- a/src/portable/synopsys/dwc2/dwc2_info.md
+++ b/src/portable/synopsys/dwc2/dwc2_info.md
@@ -8,13 +8,13 @@
 | - op_mode                  | HNP SRP         | HNP SRP      | HNP SRP       | HNP SRP      | HNP SRP              | HNP SRP          | HNP SRP          | HNP SRP      | HNP SRP      | HNP SRP      | HNP SRP      | HNP SRP      | noHNP noSRP  | HNP SRP        | HNP SRP      |
 | - arch                     | DMA internal    | DMA internal | DMA internal  | DMA internal | Slave only           | DMA internal     | Slave only       | Slave only   | DMA internal | DMA internal | DMA internal | Slave only   | DMA internal | Slave only     | DMA internal |
 | - p2p (hub support)        | 0               | 0            | 1             | 0            | 1                    | 0                | 1                | 1            | 0            | 0            | 0            | 1            | 0            | 0              | 1            |
-| - hs_phy_type              | UTMI+           | N/A          | N/A           | UTMI+/ULPI   | N/A                  | ULPI             | N/A              | N/A          | UTMI+/ULPI   | ULPI         | ULPI         | N/A          | UTMI+        | N/A            | N/A          |
-| - fs_phy_type              | Dedicated       | Dedicated    | Dedicated     | Shared ULPI  | Dedicated            | Dedicated        | Dedicated        | Dedicated    | Dedicated    | Dedicated    | Dedicated    | Dedicated    | N/A          | N/A            | Dedicated    |
+| - hs_phy_type              | UTMI+           | n/a          | n/a           | UTMI+/ULPI   | n/a                  | ULPI             | n/a              | n/a          | UTMI+/ULPI   | ULPI         | ULPI         | n/a          | UTMI+        | n/a            | n/a          |
+| - fs_phy_type              | Dedicated       | Dedicated    | Dedicated     | Shared ULPI  | Dedicated            | Dedicated        | Dedicated        | Dedicated    | Dedicated    | Dedicated    | Dedicated    | Dedicated    | n/a          | n/a            | Dedicated    |
 | - num_dev_ep               | 7               | 6            | 6             | 15           | 3                    | 5                | 5                | 5            | 8            | 8            | 8            | 5            | 8            | 0              | 6            |
 | - num_host_ch              | 7               | 13           | 7             | 15           | 7                    | 11               | 11               | 11           | 15           | 15           | 15           | 11           | 15           | 0              | 13           |
 | - period_channel_support   | 1               | 1            | 1             | 1            | 1                    | 1                | 1                | 1            | 1            | 1            | 1            | 1            | 1            | 0              | 1            |
 | - enable_dynamic_fifo      | 1               | 1            | 1             | 1            | 1                    | 1                | 1                | 1            | 1            | 1            | 1            | 1            | 1            | 0              | 1            |
-| - mul_cpu_int              | 0               | 0            | 0             | 1            | 1                    | 1                | 1                | 1            | 1            | 1            | 1            | 1            | 0            | 0              | 0            |
+| - mul_proc_intrpt          | 0               | 0            | 0             | 1            | 1                    | 1                | 1                | 1            | 1            | 1            | 1            | 1            | 0            | 0              | 0            |
 | - reserved21               | 0               | 0            | 0             | 0            | 0                    | 0                | 0                | 0            | 0            | 0            | 0            | 0            | 0            | 0              | 0            |
 | - nptx_q_depth             | 2               | 2            | 1             | 1            | 2                    | 2                | 2                | 2            | 2            | 2            | 2            | 2            | 2            | 0              | 2            |
 | - ptx_q_depth              | 2               | 2            | 2             | 1            | 2                    | 2                | 2                | 2            | 2            | 2            | 2            | 2            | 2            | 0              | 2            |
diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py
index 62437cfde..ac32eb585 100755
--- a/src/portable/synopsys/dwc2/dwc2_info.py
+++ b/src/portable/synopsys/dwc2/dwc2_info.py
@@ -50,7 +50,7 @@ class GHWCFG2(ctypes.LittleEndianStructure):
         ("num_host_ch", ctypes.c_uint32, 4),
         ("period_channel_support", ctypes.c_uint32, 1),
         ("enable_dynamic_fifo", ctypes.c_uint32, 1),
-        ("mul_cpu_int", ctypes.c_uint32, 1),
+        ("mul_proc_intrpt", ctypes.c_uint32, 1),
         ("reserved21", ctypes.c_uint32, 1),
         ("nptx_q_depth", ctypes.c_uint32, 2),
         ("ptx_q_depth", ctypes.c_uint32, 2),
@@ -119,13 +119,13 @@ GHWCFG2_field = {
         2: "DMA internal"
     },
     'hs_phy_type': {
-        0: "N/A",
+        0: "n/a",
         1: "UTMI+",
         2: "ULPI",
         3: "UTMI+/ULPI"
     },
     'fs_phy_type': {
-        0: "N/A",
+        0: "n/a",
         1: "Dedicated",
         2: "Shared UTMI+",
         3: "Shared ULPI"
diff --git a/src/portable/synopsys/dwc2/dwc2_type.h b/src/portable/synopsys/dwc2/dwc2_type.h
index ac88dd24d..d5a51fb09 100644
--- a/src/portable/synopsys/dwc2/dwc2_type.h
+++ b/src/portable/synopsys/dwc2/dwc2_type.h
@@ -250,7 +250,7 @@ typedef struct TU_ATTR_PACKED {
   uint32_t num_host_ch            : 4; // 14..17 Number of host channel (excluding control)
   uint32_t period_channel_support : 1; // 18 Support Periodic OUT Host Channel
   uint32_t enable_dynamic_fifo    : 1; // 19 Dynamic FIFO Sizing Enabled
-  uint32_t mul_cpu_int            : 1; // 20 Multi-Processor Interrupt Enabled
+  uint32_t mul_proc_intrpt        : 1; // 20 Multi-Processor Interrupt enabled (OTG_MULTI_PROC_INTRPT)
   uint32_t reserved21             : 1; // 21 reserved
   uint32_t nptx_q_depth           : 2; // 22..23 Non-periodic request queue depth: 0 = 2.  1 = 4, 2 = 8
   uint32_t ptx_q_depth            : 2; // 24..25 Host periodic request queue depth: 0 = 2.  1 = 4, 2 = 8
@@ -336,6 +336,32 @@ typedef struct {
            uint32_t reserved18[2];    // B18..B1C
 } dwc2_epout_t;
 
+typedef struct {
+  union {
+    volatile uint32_t diepctl;
+    volatile uint32_t doepctl;
+    volatile uint32_t ctl;
+  };
+  uint32_t rsv04;
+  union {
+    volatile uint32_t diepint;
+    volatile uint32_t doepint;
+  };
+  uint32_t rsv0c;
+  union {
+    volatile uint32_t dieptsiz;
+    volatile uint32_t doeptsiz;
+  };
+  union {
+    volatile uint32_t diepdma;
+    volatile uint32_t doepdma;
+  };
+  volatile uint32_t dtxfsts;
+  uint32_t rsv1c;
+}dwc2_dep_t;
+
+TU_VERIFY_STATIC(sizeof(dwc2_dep_t) == 0x20, "incorrect size");
+
 //--------------------------------------------------------------------
 // CSR Register Map
 //--------------------------------------------------------------------
@@ -418,16 +444,24 @@ typedef struct {
     volatile uint32_t dvbuspulse;       // 82C Device VBUS Pulsing Time
     volatile uint32_t dthrctl;          // 830 Device threshold Control
     volatile uint32_t diepempmsk;       // 834 Device IN Endpoint FIFO Empty Interrupt Mask
+
+    // Device Each Endpoint (IN/OUT) Interrupt/Mask for generating dedicated EP interrupt line
+    // require OTG_MULTI_PROC_INTRPT=1
     volatile uint32_t deachint;         // 838 Device Each Endpoint Interrupt
-    volatile uint32_t deachmsk;         // 83C Device Each Endpoint Interrupt msk
+    volatile uint32_t deachmsk;         // 83C Device Each Endpoint Interrupt mask
     volatile uint32_t diepeachmsk[16];  // 840..87C Device Each IN Endpoint mask
     volatile uint32_t doepeachmsk[16];  // 880..8BF Device Each OUT Endpoint mask
              uint32_t reserved8c0[16];  // 8C0..8FF
 
     //------------- Device Endpoint -------------//
-    dwc2_epin_t       epin[16];         // 900..AFF  IN Endpoints
-    dwc2_epout_t      epout[16];        // B00..CFF  OUT Endpoints
-             uint32_t reservedd00[64];  // D00..DFF
+    union {
+      dwc2_dep_t ep[2][16];            // 0: IN, 1 OUT
+      struct {
+        dwc2_epin_t  epin[16];         // 900..AFF  IN Endpoints
+        dwc2_epout_t epout[16];        // B00..CFF  OUT Endpoints
+      };
+    };
+    uint32_t reservedd00[64];  // D00..DFF
 
     //------------- Power Clock -------------//
     volatile uint32_t pcgctl;           // E00 Power and Clock Gating Control
@@ -1094,6 +1128,8 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo   ) == 0x1000, "incorrect size");
 #define DAINTMSK_OEPM_Msk                (0xFFFFUL << DAINTMSK_OEPM_Pos)          // 0xFFFF0000
 #define DAINTMSK_OEPM                    DAINTMSK_OEPM_Msk                        // OUT EP interrupt mask bits
 
+#define DAINT_SHIFT(_dir)            ((_dir == TUSB_DIR_IN) ? 0 : 16)
+
 #if 0
 /********************  Bit definition for OTG register  ********************/
 #define CHNUM_Pos                        (0U)
@@ -1803,6 +1839,45 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo   ) == 0x1000, "incorrect size");
 #define DIEPTXF_INEPTXFD_Msk             (0xFFFFUL << DIEPTXF_INEPTXFD_Pos)       // 0xFFFF0000
 #define DIEPTXF_INEPTXFD                 DIEPTXF_INEPTXFD_Msk                     // IN endpoint TxFIFO depth
 
+
+/********************  Bit definition for Common EPCTL register  ********************/
+#define EPCTL_MPSIZ_Pos                (0U)
+#define EPCTL_MPSIZ_Msk                (0x7FFUL << EPCTL_MPSIZ_Pos)           // 0x000007FF
+#define EPCTL_MPSIZ                    EPCTL_MPSIZ_Msk                        // Maximum packet size          //Bit 1
+#define EPCTL_USBAEP_Pos               (15U)
+#define EPCTL_USBAEP_Msk               (0x1UL << EPCTL_USBAEP_Pos)            // 0x00008000
+#define EPCTL_USBAEP                   EPCTL_USBAEP_Msk                       // USB active endpoint
+#define EPCTL_NAKSTS_Pos               (17U)
+#define EPCTL_NAKSTS_Msk               (0x1UL << EPCTL_NAKSTS_Pos)            // 0x00020000
+#define EPCTL_NAKSTS                   EPCTL_NAKSTS_Msk                       // NAK status
+#define EPCTL_EPTYP_Pos                (18U)
+#define EPCTL_EPTYP_Msk                (0x3UL << EPCTL_EPTYP_Pos)             // 0x000C0000
+#define EPCTL_EPTYP                    EPCTL_EPTYP_Msk                        // Endpoint type
+#define EPCTL_EPTYP_0                  (0x1UL << EPCTL_EPTYP_Pos)             // 0x00040000
+#define EPCTL_EPTYP_1                  (0x2UL << EPCTL_EPTYP_Pos)             // 0x00080000
+#define EPCTL_SNPM                     EPCTL_SNPM_Msk                         // Snoop mode
+#define EPCTL_STALL_Pos                (21U)
+#define EPCTL_STALL_Msk                (0x1UL << EPCTL_STALL_Pos)             // 0x00200000
+#define EPCTL_STALL                    EPCTL_STALL_Msk                        // STALL handshake
+#define EPCTL_CNAK_Pos                 (26U)
+#define EPCTL_CNAK_Msk                 (0x1UL << EPCTL_CNAK_Pos)              // 0x04000000
+#define EPCTL_CNAK                     EPCTL_CNAK_Msk                         // Clear NAK
+#define EPCTL_SNAK_Pos                 (27U)
+#define EPCTL_SNAK_Msk                 (0x1UL << EPCTL_SNAK_Pos)              // 0x08000000
+#define EPCTL_SNAK                     EPCTL_SNAK_Msk                         // Set NAK
+#define EPCTL_SD0PID_SEVNFRM_Pos       (28U)
+#define EPCTL_SD0PID_SEVNFRM_Msk       (0x1UL << EPCTL_SD0PID_SEVNFRM_Pos)    // 0x10000000
+#define EPCTL_SD0PID_SEVNFRM           EPCTL_SD0PID_SEVNFRM_Msk               // Set DATA0 PID
+#define EPCTL_SODDFRM_Pos              (29U)
+#define EPCTL_SODDFRM_Msk              (0x1UL << EPCTL_SODDFRM_Pos)           // 0x20000000
+#define EPCTL_SODDFRM                  EPCTL_SODDFRM_Msk                      // Set odd frame
+#define EPCTL_EPDIS_Pos                (30U)
+#define EPCTL_EPDIS_Msk                (0x1UL << EPCTL_EPDIS_Pos)             // 0x40000000
+#define EPCTL_EPDIS                    EPCTL_EPDIS_Msk                        // Endpoint disable
+#define EPCTL_EPENA_Pos                (31U)
+#define EPCTL_EPENA_Msk                (0x1UL << EPCTL_EPENA_Pos)             // 0x80000000
+#define EPCTL_EPENA                    EPCTL_EPENA_Msk                        // Endpoint enable
+
 /********************  Bit definition for DOEPCTL register  ********************/
 #define DOEPCTL_MPSIZ_Pos                (0U)
 #define DOEPCTL_MPSIZ_Msk                (0x7FFUL << DOEPCTL_MPSIZ_Pos)           // 0x000007FF
@@ -1853,15 +1928,19 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo   ) == 0x1000, "incorrect size");
 #define DOEPINT_AHBERR_Pos               (2U)
 #define DOEPINT_AHBERR_Msk               (0x1UL << DOEPINT_AHBERR_Pos)            // 0x00000004
 #define DOEPINT_AHBERR                   DOEPINT_AHBERR_Msk                       // AHB Error (AHBErr) during an OUT transaction
-#define DOEPINT_STUP_Pos                 (3U)
-#define DOEPINT_STUP_Msk                 (0x1UL << DOEPINT_STUP_Pos)              // 0x00000008
-#define DOEPINT_STUP                     DOEPINT_STUP_Msk                         // SETUP phase done
+
+#define DOEPINT_SETUP_Pos                (3U)
+#define DOEPINT_SETUP_Msk                (0x1UL << DOEPINT_SETUP_Pos)             // 0x00000008
+#define DOEPINT_SETUP                    DOEPINT_SETUP_Msk                        // SETUP phase done
+
 #define DOEPINT_OTEPDIS_Pos              (4U)
 #define DOEPINT_OTEPDIS_Msk              (0x1UL << DOEPINT_OTEPDIS_Pos)           // 0x00000010
 #define DOEPINT_OTEPDIS                  DOEPINT_OTEPDIS_Msk                      // OUT token received when endpoint disabled
-#define DOEPINT_OTEPSPR_Pos              (5U)
-#define DOEPINT_OTEPSPR_Msk              (0x1UL << DOEPINT_OTEPSPR_Pos)           // 0x00000020
-#define DOEPINT_OTEPSPR                  DOEPINT_OTEPSPR_Msk                      // Status Phase Received For Control Write
+
+#define DOEPINT_STSPHSRX_Pos             (5U)
+#define DOEPINT_STSPHSRX_Msk             (0x1UL << DOEPINT_STSPHSRX_Pos)          // 0x00000020
+#define DOEPINT_STSPHSRX                  DOEPINT_STSPHSRX_Msk                    // Status Phase Received For Control Write
+
 #define DOEPINT_B2BSTUP_Pos              (6U)
 #define DOEPINT_B2BSTUP_Msk              (0x1UL << DOEPINT_B2BSTUP_Pos)           // 0x00000040
 #define DOEPINT_B2BSTUP                  DOEPINT_B2BSTUP_Msk                      // Back-to-back SETUP packets received
@@ -1874,9 +1953,10 @@ TU_VERIFY_STATIC(offsetof(dwc2_regs_t, fifo   ) == 0x1000, "incorrect size");
 #define DOEPINT_NYET_Pos                 (14U)
 #define DOEPINT_NYET_Msk                 (0x1UL << DOEPINT_NYET_Pos)              // 0x00004000
 #define DOEPINT_NYET                     DOEPINT_NYET_Msk                         // NYET interrupt
-#define DOEPINT_STPKTRX_Pos              (15U)
-#define DOEPINT_STPKTRX_Msk              (0x1UL << DOEPINT_STPKTRX_Pos)           // 0x00008000
-#define DOEPINT_STPKTRX                  DOEPINT_STPKTRX_Msk                      // Setup Packet Received
+
+#define DOEPINT_DMA_STPKTRX_Pos          (15U)
+#define DOEPINT_DMA_STPKTRX_Msk          (0x1UL << DOEPINT_DMA_STPKTRX_Pos)       // 0x00008000
+#define DOEPINT_DMA_STPKTRX              DOEPINT_DMA_STPKTRX_Msk                  // Setup Packet Received in Buffer DMA Mode
 
 /********************  Bit definition for DOEPTSIZ register  ********************/
 #define DOEPTSIZ_XFRSIZ_Pos              (0U)