diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml
index 756ab0991..c76e45a6b 100644
--- a/.github/workflows/push.yml
+++ b/.github/workflows/push.yml
@@ -25,7 +25,7 @@ jobs:
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        target: [esp32, esp32s2, esp32s3, esp32c2, esp32c3, esp32c6, esp32h2, esp32p4]
+        target: [esp32, esp32s2, esp32s3, esp32c2, esp32c3, esp32c6, esp32h2, esp32p4, esp32c5]
       fail-fast: false
     steps:
     - name: Checkout repository
diff --git a/components/arduino_tinyusb/patches/dcd_dwc2.patch b/components/arduino_tinyusb/patches/dcd_dwc2.patch
index 11c1c05c0..14e6975f0 100644
--- a/components/arduino_tinyusb/patches/dcd_dwc2.patch
+++ b/components/arduino_tinyusb/patches/dcd_dwc2.patch
@@ -19,11 +19,11 @@
    dwc2_regs_t* dwc2 = DWC2_REG(rhport);
    const uint8_t epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress);
 @@ -266,7 +277,18 @@
-     depctl.bm.set_data0_iso_even = 1;
+     depctl.set_data0_iso_even = 1;
    }
    if (dir == TUSB_DIR_IN) {
--    depctl.bm.tx_fifo_num = epnum;
-+    //depctl.bm.tx_fifo_num = epnum;
+-    depctl.tx_fifo_num = epnum;
++    //depctl.tx_fifo_num = epnum;
 +    uint8_t fifo_num = epnum;
 +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
 +    // Special Case for EP5, which is used by CDC but not actually called by the driver
@@ -34,7 +34,7 @@
 +      fifo_num = get_free_fifo();
 +    }
 +#endif
-+    depctl.bm.tx_fifo_num = fifo_num;
++    depctl.tx_fifo_num = fifo_num;
    }
  
    dwc2_dep_t* dep = &dwc2->ep[dir == TUSB_DIR_IN ? 0 : 1][epnum];
diff --git a/components/arduino_tinyusb/src/dcd_dwc2.c b/components/arduino_tinyusb/src/dcd_dwc2.c
index d6796641a..ea931ab90 100644
--- a/components/arduino_tinyusb/src/dcd_dwc2.c
+++ b/components/arduino_tinyusb/src/dcd_dwc2.c
@@ -41,12 +41,6 @@
 #include "device/dcd.h"
 #include "dwc2_common.h"
 
-#if TU_CHECK_MCU(OPT_MCU_GD32VF103)
-  #define DWC2_EP_COUNT(_dwc2)   DWC2_EP_MAX
-#else
-  #define DWC2_EP_COUNT(_dwc2)  ((_dwc2)->ghwcfg2_bm.num_dev_ep + 1)
-#endif
-
 //--------------------------------------------------------------------+
 // MACRO TYPEDEF CONSTANT ENUM
 //--------------------------------------------------------------------+
@@ -79,6 +73,16 @@ CFG_TUD_MEM_SECTION static struct {
   TUD_EPBUF_DEF(setup_packet, 8);
 } _dcd_usbbuf;
 
+TU_ATTR_ALWAYS_INLINE static inline uint8_t dwc2_ep_count(const dwc2_regs_t* dwc2) {
+  #if TU_CHECK_MCU(OPT_MCU_GD32VF103)
+  return DWC2_EP_MAX;
+  #else
+  const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2};
+  return ghwcfg2.num_dev_ep + 1;
+  #endif
+}
+
+
 //--------------------------------------------------------------------
 // DMA
 //--------------------------------------------------------------------
@@ -102,7 +106,8 @@ bool dcd_dcache_clean_invalidate(const void* addr, uint32_t data_size) {
 TU_ATTR_ALWAYS_INLINE static inline bool dma_device_enabled(const dwc2_regs_t* dwc2) {
   (void) dwc2;
   // Internal DMA only
-  return CFG_TUD_DWC2_DMA_ENABLE && dwc2->ghwcfg2_bm.arch == GHWCFG2_ARCH_INTERNAL_DMA;
+  const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2};
+  return CFG_TUD_DWC2_DMA_ENABLE && ghwcfg2.arch == GHWCFG2_ARCH_INTERNAL_DMA;
 }
 
 static void dma_setup_prepare(uint8_t rhport) {
@@ -261,20 +266,15 @@ static void edpt_activate(uint8_t rhport, const tusb_desc_endpoint_t* p_endpoint
   xfer->interval = p_endpoint_desc->bInterval;
 
   // Endpoint control
-  union {
-    uint32_t value;
-    dwc2_depctl_t bm;
-  } depctl;
-  depctl.value = 0;
-
-  depctl.bm.mps = xfer->max_size;
-  depctl.bm.active = 1;
-  depctl.bm.type = p_endpoint_desc->bmAttributes.xfer;
+  dwc2_depctl_t depctl = {.value = 0};
+  depctl.mps = xfer->max_size;
+  depctl.active = 1;
+  depctl.type = p_endpoint_desc->bmAttributes.xfer;
   if (p_endpoint_desc->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS) {
-    depctl.bm.set_data0_iso_even = 1;
+    depctl.set_data0_iso_even = 1;
   }
   if (dir == TUSB_DIR_IN) {
-    //depctl.bm.tx_fifo_num = epnum;
+    //depctl.tx_fifo_num = epnum;
     uint8_t fifo_num = epnum;
 #if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)
     // Special Case for EP5, which is used by CDC but not actually called by the driver
@@ -285,7 +285,7 @@ static void edpt_activate(uint8_t rhport, const tusb_desc_endpoint_t* p_endpoint
       fifo_num = get_free_fifo();
     }
 #endif
-    depctl.bm.tx_fifo_num = fifo_num;
+    depctl.tx_fifo_num = fifo_num;
   }
 
   dwc2_dep_t* dep = &dwc2->ep[dir == TUSB_DIR_IN ? 0 : 1][epnum];
@@ -365,31 +365,22 @@ static void edpt_schedule_packets(uint8_t rhport, const uint8_t epnum, const uin
   }
 
   // transfer size: A full OUT transfer (multiple packets, possibly) triggers XFRC.
-  union {
-    uint32_t value;
-    dwc2_ep_tsize_t bm;
-  } deptsiz;
-  deptsiz.value = 0;
-  deptsiz.bm.xfer_size =  total_bytes;
-  deptsiz.bm.packet_count = num_packets;
-
+  dwc2_ep_tsize_t deptsiz = {.value = 0};
+  deptsiz.xfer_size = total_bytes;
+  deptsiz.packet_count = num_packets;
   dep->tsiz = deptsiz.value;
 
   // control
-  union {
-    dwc2_depctl_t bm;
-    uint32_t value;
-  } depctl;
-  depctl.value = dep->ctl;
-
-  depctl.bm.clear_nak = 1;
-  depctl.bm.enable = 1;
-  if (depctl.bm.type == DEPCTL_EPTYPE_ISOCHRONOUS && xfer->interval == 1) {
-    const uint32_t odd_now = (dwc2->dsts_bm.frame_number & 1u);
+  dwc2_depctl_t depctl = {.value = dep->ctl};
+  depctl.clear_nak = 1;
+  depctl.enable = 1;
+  if (depctl.type == DEPCTL_EPTYPE_ISOCHRONOUS && xfer->interval == 1) {
+    const dwc2_dsts_t dsts = {.value = dwc2->dsts};
+    const uint32_t odd_now = dsts.frame_number & 1u;
     if (odd_now) {
-      depctl.bm.set_data0_iso_even = 1;
+      depctl.set_data0_iso_even = 1;
     } else {
-      depctl.bm.set_data1_iso_odd = 1;
+      depctl.set_data1_iso_odd = 1;
     }
   }
 
@@ -432,7 +423,8 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) {
 
     // XCVRDLY: transceiver delay between xcvr_sel and txvalid during device chirp is required
     // when using with some PHYs such as USB334x (USB3341, USB3343, USB3346, USB3347)
-    if (dwc2->ghwcfg2_bm.hs_phy_type == GHWCFG2_HSPHY_ULPI) {
+    const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2};
+    if (ghwcfg2.hs_phy_type == GHWCFG2_HSPHY_ULPI) {
       dcfg |= DCFG_XCVRDLY;
     }
   } else {
@@ -667,7 +659,7 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) {
 // 7.4.1 Initialization on USB Reset
 static void handle_bus_reset(uint8_t rhport) {
   dwc2_regs_t *dwc2 = DWC2_REG(rhport);
-  const uint8_t ep_count =  DWC2_EP_COUNT(dwc2);
+  const uint8_t ep_count =  dwc2_ep_count(dwc2);
 
   tu_memclr(xfer_status, sizeof(xfer_status));
 
@@ -697,7 +689,9 @@ static void handle_bus_reset(uint8_t rhport) {
   dfifo_device_init(rhport);
 
   // 5. Reset device address
-  dwc2->dcfg_bm.address = 0;
+  dwc2_dcfg_t dcfg = {.value = dwc2->dcfg};
+  dcfg.address = 0;
+  dwc2->dcfg = dcfg.value;
 
   // Fixed both control EP0 size to 64 bytes
   dwc2->epin[0].ctl &= ~(0x03 << DIEPCTL_MPSIZ_Pos);
@@ -717,8 +711,9 @@ static void handle_bus_reset(uint8_t rhport) {
 
 static void handle_enum_done(uint8_t rhport) {
   dwc2_regs_t *dwc2 = DWC2_REG(rhport);
+  const dwc2_dsts_t dsts = {.value = dwc2->dsts};
   tusb_speed_t speed;
-  switch (dwc2->dsts_bm.enum_speed) {
+  switch (dsts.enum_speed) {
     case DCFG_SPEED_HIGH:
       speed = TUSB_SPEED_HIGH;
     break;
@@ -763,12 +758,12 @@ static void handle_rxflvl_irq(uint8_t rhport) {
   const volatile uint32_t* rx_fifo = dwc2->fifo[0];
 
   // Pop control word off FIFO
-  const dwc2_grxstsp_t grxstsp_bm = dwc2->grxstsp_bm;
-  const uint8_t epnum = grxstsp_bm.ep_ch_num;
+  const dwc2_grxstsp_t grxstsp = {.value = dwc2->grxstsp};
+  const uint8_t epnum = grxstsp.ep_ch_num;
 
   dwc2_dep_t* epout = &dwc2->epout[epnum];
 
-  switch (grxstsp_bm.packet_status) {
+  switch (grxstsp.packet_status) {
     case GRXSTS_PKTSTS_GLOBAL_OUT_NAK:
       // Global OUT NAK: do nothing
       break;
@@ -790,7 +785,7 @@ static void handle_rxflvl_irq(uint8_t rhport) {
 
     case GRXSTS_PKTSTS_RX_DATA: {
       // Out packet received
-      const uint16_t byte_count = grxstsp_bm.byte_count;
+      const uint16_t byte_count = grxstsp.byte_count;
       xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT);
 
       if (byte_count) {
@@ -804,7 +799,8 @@ static void handle_rxflvl_irq(uint8_t rhport) {
 
         // short packet, minus remaining bytes (xfer_size)
         if (byte_count < xfer->max_size) {
-          xfer->total_len -= epout->tsiz_bm.xfer_size;
+          const dwc2_ep_tsize_t tsiz = {.value = epout->tsiz};
+          xfer->total_len -= tsiz.xfer_size;
           if (epnum == 0) {
             xfer->total_len -= _dcd_data.ep0_pending[TUSB_DIR_OUT];
             _dcd_data.ep0_pending[TUSB_DIR_OUT] = 0;
@@ -866,11 +862,13 @@ static void handle_epin_slave(uint8_t rhport, uint8_t epnum, dwc2_diepint_t diep
   // - 64 bytes or
   // - Half/Empty of TX FIFO size (configured by GAHBCFG.TXFELVL)
   if (diepint_bm.txfifo_empty && (dwc2->diepempmsk & (1 << epnum))) {
-    const uint16_t remain_packets = epin->tsiz_bm.packet_count;
+    dwc2_ep_tsize_t tsiz = {.value = epin->tsiz};
+    const uint16_t remain_packets = tsiz.packet_count;
 
     // Process every single packet (only whole packets can be written to fifo)
     for (uint16_t i = 0; i < remain_packets; i++) {
-      const uint16_t remain_bytes = (uint16_t) epin->tsiz_bm.xfer_size;
+      tsiz.value = epin->tsiz;
+      const uint16_t remain_bytes = (uint16_t) tsiz.xfer_size;
       const uint16_t xact_bytes = tu_min16(remain_bytes, xfer->max_size);
 
       // Check if dtxfsts has enough space available
@@ -889,7 +887,8 @@ static void handle_epin_slave(uint8_t rhport, uint8_t epnum, dwc2_diepint_t diep
     }
 
     // Turn off TXFE if all bytes are written.
-    if (epin->tsiz_bm.xfer_size == 0) {
+    tsiz.value = epin->tsiz;
+    if (tsiz.xfer_size == 0) {
       dwc2->diepempmsk &= ~(1 << epnum);
     }
   }
@@ -920,7 +919,8 @@ static void handle_epout_dma(uint8_t rhport, uint8_t epnum, dwc2_doepint_t doepi
         xfer_ctl_t* xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT);
 
         // determine actual received bytes
-        const uint16_t remain = epout->tsiz_bm.xfer_size;
+        const dwc2_ep_tsize_t tsiz = {.value = epout->tsiz};
+        const uint16_t remain = tsiz.xfer_size;
         xfer->total_len -= remain;
 
         // this is ZLP, so prepare EP0 for next setup
@@ -956,7 +956,7 @@ static void handle_epin_dma(uint8_t rhport, uint8_t epnum, dwc2_diepint_t diepin
 static void handle_ep_irq(uint8_t rhport, uint8_t dir) {
   dwc2_regs_t* dwc2 = DWC2_REG(rhport);
   const bool is_dma = dma_device_enabled(dwc2);
-  const uint8_t ep_count = DWC2_EP_COUNT(dwc2);
+  const uint8_t ep_count = dwc2_ep_count(dwc2);
   const uint8_t daint_offset = (dir == TUSB_DIR_IN) ? DAINT_IEPINT_Pos : DAINT_OEPINT_Pos;
   dwc2_dep_t* ep_base = &dwc2->ep[dir == TUSB_DIR_IN ? 0 : 1][0];
 
diff --git a/configs/builds.json b/configs/builds.json
index ddfb8e4f8..1e161c683 100644
--- a/configs/builds.json
+++ b/configs/builds.json
@@ -4,7 +4,7 @@
 			"file":"libspi_flash.a",
 			"src":"build/esp-idf/spi_flash/libspi_flash.a",
 			"out":"lib/libspi_flash.a",
-			"targets":["esp32","esp32c2","esp32c3","esp32s2","esp32s3","esp32c6","esp32h2","esp32p4"]
+			"targets":["esp32","esp32c2","esp32c3","esp32s2","esp32s3","esp32c6","esp32h2","esp32p4","esp32c5"]
 		},
 		{
 			"file":"libesp_psram.a",
@@ -44,6 +44,20 @@
 		}
 	],
 	"targets":[
+		{
+			"target": "esp32c5",
+			"features":["qio_ram"],
+			"idf_libs":["qio","80m"],
+			"bootloaders":[
+				["qio","80m"],
+				["dio","80m"],
+				["qio","40m"],
+				["dio","40m"]
+			],
+			"mem_variants":[
+				["dio","80m"]
+			]
+		},
 		{
 			"target": "esp32p4",
 			"features":["qio_ram"],
diff --git a/configs/defconfig.esp32c5 b/configs/defconfig.esp32c5
new file mode 100644
index 000000000..efb756f15
--- /dev/null
+++ b/configs/defconfig.esp32c5
@@ -0,0 +1,57 @@
+CONFIG_XTAL_FREQ_AUTO=y
+CONFIG_XTAL_FREQ=0
+CONFIG_SPIRAM_TRY_ALLOCATE_WIFI_LWIP=y
+CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y
+CONFIG_SPIRAM=y
+
+CONFIG_BT_ENABLED=y
+CONFIG_BT_BLE_BLUFI_ENABLE=y
+CONFIG_RTC_CLK_CAL_CYCLES=576
+# CONFIG_ESP_TASK_WDT_CHECK_IDLE_TASK_CPU0 is not set
+CONFIG_FREERTOS_IDLE_TASK_STACKSIZE=2304
+# This Enables RISCV LP for C6 - but it can't be used within Arduino at this time. 
+#CONFIG_ULP_COPROC_ENABLED=y
+#CONFIG_ULP_COPROC_LP_CORE=y
+#CONFIG_ULP_COPROC_RESERVE_MEM=4096
+
+#
+# OpenThread
+#
+CONFIG_OPENTHREAD_ENABLED=y
+# Border Router disabled
+# CONFIG_OPENTHREAD_BORDER_ROUTER=y
+# CONFIG_OPENTHREAD_RADIO_SPINEL_UART=y
+
+# DNS64 and NAT64 will be disabled for a while
+# OT IDF issue https://github.com/espressif/esp-idf/issues/15069
+# CONFIG_OPENTHREAD_DNS64_CLIENT=y
+
+# Radio for RPC
+# CONFIG_OPENTHREAD_RADIO=y 
+# CONFIG_OPENTHREAD_RADIO_NATIVE=y
+# CONFIG_OPENTHREAD_DIAG=n
+CONFIG_OPENTHREAD_COMMISSIONER=y
+CONFIG_OPENTHREAD_JOINER=y
+CONFIG_OPENTHREAD_CLI=y
+CONFIG_OPENTHREAD_SRP_CLIENT=y
+CONFIG_OPENTHREAD_DNS_CLIENT=y
+# Default dataset for quick start
+CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread-ESP"
+CONFIG_OPENTHREAD_MESH_LOCAL_PREFIX="fd00:db8:a0:0::/64"
+CONFIG_OPENTHREAD_NETWORK_CHANNEL=15
+CONFIG_OPENTHREAD_NETWORK_PANID=0x1234
+CONFIG_OPENTHREAD_NETWORK_EXTPANID="dead00beef00cafe"
+CONFIG_OPENTHREAD_NETWORK_MASTERKEY="00112233445566778899aabbccddeeff"
+CONFIG_OPENTHREAD_NETWORK_PSKC="104810e2315100afd6bc9215a6bfac53"
+# end of OpenThread
+
+# Matter shall use only WiFi
+CONFIG_ENABLE_MATTER_OVER_THREAD=n
+
+#
+# Zigbee
+#
+CONFIG_ZB_ENABLED=y
+CONFIG_ZB_ZED=y
+CONFIG_ZB_RADIO_NATIVE=y
+# end of Zigbee
diff --git a/main/idf_component.yml b/main/idf_component.yml
index 8c574bb08..67f5d539d 100644
--- a/main/idf_component.yml
+++ b/main/idf_component.yml
@@ -20,4 +20,4 @@ dependencies:
     version: "^1.4.0"
     require: public
     rules:
-      - if: "target not in [esp32c2, esp32h2, esp32p4]"
+      - if: "target not in [esp32c2, esp32h2, esp32p4, esp32c5]"
diff --git a/tools/config.sh b/tools/config.sh
index 79d4feef5..d180e7afc 100755
--- a/tools/config.sh
+++ b/tools/config.sh
@@ -6,11 +6,11 @@ if [ -z $IDF_PATH ]; then
 fi
 
 if [ -z $IDF_BRANCH ]; then
-    IDF_BRANCH="release/v5.4"
+    IDF_BRANCH="master"
 fi
 
 if [ -z $AR_PR_TARGET_BRANCH ]; then
-    AR_PR_TARGET_BRANCH="master"
+    AR_PR_TARGET_BRANCH="release/v3.3.x"
 fi
 
 if [ -z $IDF_TARGET ]; then
diff --git a/tools/gen_pioarduino_manifest.py b/tools/gen_pioarduino_manifest.py
index 9d2b99c19..2a76d6cd8 100644
--- a/tools/gen_pioarduino_manifest.py
+++ b/tools/gen_pioarduino_manifest.py
@@ -23,6 +23,9 @@ def convert_version(version_string):
     'v7.7.7' becomes '7.7.7'
     """
 
+    if version_string == 'heads/master':
+        return ".".join(("5", "5", "0")) #temporary
+
     regex_pattern = (
         r"v(?P<MAJOR>0|[1-9]\d*)\.(?P<MINOR>0|[1-9]\d*)\.*(?P<PATCH>0|[1-9]\d*)*"
     )