From 4f4ba3b16d9bcb98a1cb51cb6030f0be4dfd7513 Mon Sep 17 00:00:00 2001 From: Niklas Hauser Date: Sat, 17 May 2025 17:35:45 +0200 Subject: [stm32] Wait until the PHYC PLL is stable --- src/portable/synopsys/dwc2/dwc2_stm32.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index c11c1eb05..0bbad55f5 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -222,6 +222,10 @@ static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { // Enable PLL internal PHY USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN; + + // Wait ~2ms until the PLL is ready (there's no RDY bit to query) + uint32_t count = (SystemCoreClock / 1000) * 2; + while (count--) __NOP(); #else #endif -- cgit v1.3.1 From 4ae433fa6ef451cccb2b09aa3748978b46aade5f Mon Sep 17 00:00:00 2001 From: milek7 Date: Wed, 25 Jun 2025 03:35:40 +0200 Subject: stm32_fsdev: Allow configuring single-buffered isochronous endpoints. Controlled by the embedder defining CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP in tusb_config.h. If hardware does have SBUF_ISO bit it will use only one half of endpoint pair register. --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 47 ++++++++++++++++++++++----- src/portable/st/stm32_fsdev/fsdev_ch32.h | 5 +++ src/portable/st/stm32_fsdev/fsdev_stm32.h | 38 ++++++++++++++++++++++ 3 files changed, 82 insertions(+), 8 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index ef58957bb..ad733b16a 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -331,8 +331,13 @@ static void handle_ctr_rx(uint32_t ep_id) { xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, TUSB_DIR_OUT); uint8_t buf_id; - if (is_iso) { - buf_id = (ep_reg & USB_EP_DTOG_RX) ? 0 : 1; // ISO are double buffered +#if FSDEV_USE_SBUF_ISO == 0 + bool const dbl_buf = is_iso; +#else + bool const dbl_buf = false; +#endif + if (dbl_buf) { + buf_id = (ep_reg & USB_EP_DTOG_RX) ? 0 : 1; } else { buf_id = BTABLE_BUF_RX; } @@ -527,10 +532,16 @@ static uint8_t dcd_ep_alloc(uint8_t ep_addr, uint8_t ep_type) return i; } +#if FSDEV_USE_SBUF_ISO == 0 + bool const dbl_buf = ep_type == TUSB_XFER_ISOCHRONOUS; +#else + bool const dbl_buf = false; +#endif + // If EP of current direction is not allocated - // Except for ISO endpoint, both direction should be free + // For double-buffered mode both directions needs to be free if (!ep_alloc_status[i].allocated[dir] && - (ep_type != TUSB_XFER_ISOCHRONOUS || !ep_alloc_status[i].allocated[dir ^ 1])) { + (!dbl_buf || !ep_alloc_status[i].allocated[dir ^ 1])) { // Check if EP number is the same if (ep_alloc_status[i].ep_num == 0xFF || ep_alloc_status[i].ep_num == epnum) { // One EP pair has to be the same type @@ -652,9 +663,7 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet uint8_t const dir = tu_edpt_dir(ep_addr); uint8_t const ep_idx = dcd_ep_alloc(ep_addr, TUSB_XFER_ISOCHRONOUS); - /* Create a packet memory buffer area. Enable double buffering for devices with 2048 bytes PMA, - for smaller devices double buffering occupy too much space. */ -#if FSDEV_PMA_SIZE > 1024u +#if CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP != 0 uint32_t pma_addr = dcd_pma_alloc(largest_packet_size, true); uint16_t pma_addr2 = pma_addr >> 16; #else @@ -662,8 +671,12 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet uint16_t pma_addr2 = pma_addr; #endif +#if FSDEV_USE_SBUF_ISO == 0 btable_set_addr(ep_idx, 0, pma_addr); btable_set_addr(ep_idx, 1, pma_addr2); +#else + btable_set_addr(ep_idx, dir == TUSB_DIR_IN ? BTABLE_BUF_TX : BTABLE_BUF_RX, pma_addr); +#endif xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, dir); xfer->ep_idx = ep_idx; @@ -684,10 +697,23 @@ bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const *desc_ep) uint32_t ep_reg = ep_read(ep_idx) & ~USB_EPREG_MASK; ep_reg |= tu_edpt_number(ep_addr) | USB_EP_ISOCHRONOUS | USB_EP_CTR_TX | USB_EP_CTR_RX; +#if FSDEV_USE_SBUF_ISO != 0 + ep_reg |= USB_EP_KIND; + + ep_change_status(&ep_reg, dir, EP_STAT_DISABLED); + ep_change_dtog(&ep_reg, dir, 0); + + if (dir == TUSB_DIR_IN) { + ep_reg &= ~(USB_EPRX_STAT | USB_EP_DTOG_RX); + } else { + ep_reg &= ~(USB_EPTX_STAT | USB_EP_DTOG_TX); + } +#else ep_change_status(&ep_reg, TUSB_DIR_IN, EP_STAT_DISABLED); ep_change_status(&ep_reg, TUSB_DIR_OUT, EP_STAT_DISABLED); ep_change_dtog(&ep_reg, dir, 0); ep_change_dtog(&ep_reg, (tusb_dir_t)(1 - dir), 1); +#endif ep_write(ep_idx, ep_reg, true); @@ -702,7 +728,12 @@ static void dcd_transmit_packet(xfer_ctl_t *xfer, uint16_t ep_ix) { bool const is_iso = ep_is_iso(ep_reg); uint8_t buf_id; - if (is_iso) { +#if FSDEV_USE_SBUF_ISO == 0 + bool const dbl_buf = is_iso; +#else + bool const dbl_buf = false; +#endif + if (dbl_buf) { buf_id = (ep_reg & USB_EP_DTOG_TX) ? 1 : 0; } else { buf_id = BTABLE_BUF_TX; diff --git a/src/portable/st/stm32_fsdev/fsdev_ch32.h b/src/portable/st/stm32_fsdev/fsdev_ch32.h index 518197c47..ceebb6dab 100644 --- a/src/portable/st/stm32_fsdev/fsdev_ch32.h +++ b/src/portable/st/stm32_fsdev/fsdev_ch32.h @@ -54,9 +54,14 @@ #endif #define FSDEV_PMA_SIZE (512u) +#define FSDEV_USE_SBUF_ISO 0 #define FSDEV_REG_BASE (APB1PERIPH_BASE + 0x00005C00UL) #define FSDEV_PMA_BASE (APB1PERIPH_BASE + 0x00006000UL) +#ifndef CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP + #define CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP 0 +#endif + /**************************** ISTR interrupt events *************************/ #define USB_ISTR_CTR ((uint16_t)0x8000U) /*!< Correct TRansfer (clear-only bit) */ #define USB_ISTR_PMAOVR ((uint16_t)0x4000U) /*!< DMA OVeR/underrun (clear-only bit) */ diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index ccf31e035..770baa05a 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -36,6 +36,7 @@ #include "stm32f0xx.h" #define FSDEV_PMA_SIZE (1024u) #define FSDEV_REG_BASE USB_BASE + #define FSDEV_HAS_SBUF_ISO 0 // F0x2 models are crystal-less // All have internal D+ pull-up // 070RB: 2 x 16 bits/word memory LPM Support, BCD Support @@ -44,6 +45,7 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32F1 #include "stm32f1xx.h" #define FSDEV_PMA_SIZE (512u) + #define FSDEV_HAS_SBUF_ISO 0 // NO internal Pull-ups // *B, and *C: 2 x 16 bits/word @@ -55,6 +57,7 @@ defined(STM32F373xC) #include "stm32f3xx.h" #define FSDEV_PMA_SIZE (512u) + #define FSDEV_HAS_SBUF_ISO 0 // NO internal Pull-ups // *B, and *C: 1 x 16 bits/word // PMA dedicated to USB (no sharing with CAN) @@ -64,6 +67,7 @@ defined(STM32F303xD) || defined(STM32F303xE) #include "stm32f3xx.h" #define FSDEV_PMA_SIZE (1024u) + #define FSDEV_HAS_SBUF_ISO 0 // NO internal Pull-ups // *6, *8, *D, and *E: 2 x 16 bits/word LPM Support // When CAN clock is enabled, USB can use first 768 bytes ONLY. @@ -71,18 +75,22 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32L0 #include "stm32l0xx.h" #define FSDEV_PMA_SIZE (1024u) + #define FSDEV_HAS_SBUF_ISO 0 #elif CFG_TUSB_MCU == OPT_MCU_STM32L1 #include "stm32l1xx.h" #define FSDEV_PMA_SIZE (512u) + #define FSDEV_HAS_SBUF_ISO 0 #elif CFG_TUSB_MCU == OPT_MCU_STM32G4 #include "stm32g4xx.h" #define FSDEV_PMA_SIZE (1024u) + #define FSDEV_HAS_SBUF_ISO 0 #elif CFG_TUSB_MCU == OPT_MCU_STM32G0 #include "stm32g0xx.h" #define FSDEV_PMA_SIZE (2048u) + #define FSDEV_HAS_SBUF_ISO 1 #define USB USB_DRD_FS #define USB_EP_CTR_RX USB_EP_VTRX @@ -107,6 +115,7 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32C0 #include "stm32c0xx.h" #define FSDEV_PMA_SIZE (2048u) + #define FSDEV_HAS_SBUF_ISO 1 #define USB USB_DRD_FS #define USB_EP_CTR_RX USB_CHEP_VTRX #define USB_EP_CTR_TX USB_CHEP_VTTX @@ -121,6 +130,7 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32H5 #include "stm32h5xx.h" #define FSDEV_PMA_SIZE (2048u) + #define FSDEV_HAS_SBUF_ISO 1 #define USB USB_DRD_FS #define USB_EP_CTR_RX USB_EP_VTRX @@ -145,16 +155,19 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32WB #include "stm32wbxx.h" #define FSDEV_PMA_SIZE (1024u) + #define FSDEV_HAS_SBUF_ISO 0 /* ST provided header has incorrect value of USB_PMAADDR */ #define FSDEV_PMA_BASE USB1_PMAADDR #elif CFG_TUSB_MCU == OPT_MCU_STM32L4 #include "stm32l4xx.h" #define FSDEV_PMA_SIZE (1024u) + #define FSDEV_HAS_SBUF_ISO 0 #elif CFG_TUSB_MCU == OPT_MCU_STM32L5 #include "stm32l5xx.h" #define FSDEV_PMA_SIZE (1024u) + #define FSDEV_HAS_SBUF_ISO 0 #ifndef USB_PMAADDR #define USB_PMAADDR (USB_BASE + (USB_PMAADDR_NS - USB_BASE_NS)) @@ -163,6 +176,7 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 #include "stm32u5xx.h" #define FSDEV_PMA_SIZE (2048u) + #define FSDEV_HAS_SBUF_ISO 1 #define USB USB_DRD_FS #define USB_EP_CTR_RX USB_EP_VTRX @@ -187,6 +201,7 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32U0 #include "stm32u0xx.h" #define FSDEV_PMA_SIZE (2048u) + #define FSDEV_HAS_SBUF_ISO 1 #define USB USB_DRD_FS #define USB_EP_CTR_RX USB_EP_VTRX @@ -248,6 +263,29 @@ #define USB_ISTR_ALL_EVENTS (USB_ISTR_PMAOVR | USB_ISTR_ERR | USB_ISTR_WKUP | USB_ISTR_SUSP | \ USB_ISTR_RESET | USB_ISTR_SOF | USB_ISTR_ESOF | USB_ISTR_L1REQ_FORCED ) +#ifndef FSDEV_HAS_SBUF_ISO + #error "FSDEV_HAS_SBUF_ISO not defined" +#endif + +#ifndef CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP + // Defaults to double-buffered isochronous endpoints on devices with >1KB PMA + #if FSDEV_PMA_SIZE > 1024u + #define CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP 1 + #else + #define CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP 0 + #endif +#endif + +#if FSDEV_HAS_SBUF_ISO != 0 && CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP == 0 + // If hardware has SBUF_ISO bit single-buffered endpoints consume only + // one half of endpoint pair register. + #define FSDEV_USE_SBUF_ISO 1 +#else + // Otherwise it consumes entire endpoint pair but we can at least save + // memory by configuring the same buffer twice. + #define FSDEV_USE_SBUF_ISO 0 +#endif + //--------------------------------------------------------------------+ // //--------------------------------------------------------------------+ -- cgit v1.3.1 From 5b9908a39ba089dfd56b3a23475be5d9691d13e8 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 7 Aug 2025 14:20:40 +0700 Subject: update at32f405 dwc2 info and phy width selection --- src/portable/synopsys/dwc2/dwc2_common.c | 24 +++---- src/portable/synopsys/dwc2/dwc2_info.md | 116 +++++++++++++++---------------- src/portable/synopsys/dwc2/dwc2_info.py | 2 + 3 files changed, 72 insertions(+), 70 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c index b001f343d..70876a64c 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.c +++ b/src/portable/synopsys/dwc2/dwc2_common.c @@ -92,6 +92,14 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2}; const dwc2_ghwcfg4_t ghwcfg4 = {.value = dwc2->ghwcfg4}; + uint8_t phy_width; + if (CFG_TUSB_MCU != OPT_MCU_AT32F402_405 && // at32f402_405 does not support 16-bit + ghwcfg4.phy_data_width) { + phy_width = 16; // 16-bit PHY interface if supported + } else { + phy_width = 8; // 8-bit PHY interface + } + // De-select FS PHY gusbcfg &= ~GUSBCFG_PHYSEL; @@ -119,12 +127,10 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { gusbcfg &= ~GUSBCFG_ULPI_UTMI_SEL; // Set 16-bit interface if supported - if (ghwcfg4.phy_data_width) { - #if CFG_TUSB_MCU != OPT_MCU_AT32F402_405 // at32f402_405 does not actually support 16-bit - gusbcfg |= GUSBCFG_PHYIF16; // 16 bit - #endif + if (phy_width == 16) { + gusbcfg |= GUSBCFG_PHYIF16; } else { - gusbcfg &= ~GUSBCFG_PHYIF16; // 8 bit + gusbcfg &= ~GUSBCFG_PHYIF16; } } @@ -141,13 +147,7 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { // - 9 if using 8-bit PHY interface // - 5 if using 16-bit PHY interface gusbcfg &= ~GUSBCFG_TRDT_Msk; - -#if CFG_TUSB_MCU == OPT_MCU_AT32F402_405 // at32f402_405 does not actually support 16-bit - gusbcfg |= 9u << GUSBCFG_TRDT_Pos; -#else - gusbcfg |= (dwc2->ghwcfg4_bm.phy_data_width ? 5u : 9u) << GUSBCFG_TRDT_Pos; -#endif - + gusbcfg |= (phy_width == 16 ? 5u : 9u) << GUSBCFG_TRDT_Pos; dwc2->gusbcfg = gusbcfg; // MCU specific PHY update post reset diff --git a/src/portable/synopsys/dwc2/dwc2_info.md b/src/portable/synopsys/dwc2/dwc2_info.md index 595c89b75..00685e7ad 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.md +++ b/src/portable/synopsys/dwc2/dwc2_info.md @@ -1,58 +1,58 @@ -| | BCM2711 (Pi4) | EFM32GG | ESP32-S2/S3 | ESP32-P4 | ST F207/F407/411/429 FS | ST F407/429 HS | ST F412/76x FS | ST F723/L4P5 FS | ST F723 HS | ST F76x HS | ST H743/H750 | ST L476 FS | ST U5A5/H7RS/N6 HS | XMC4500 | GD32VF103 | -|:---------------------------|:----------------|:-------------|:--------------|:-------------|:--------------------------|:-----------------|:-----------------|:------------------|:-------------|:-------------|:---------------|:-------------|:---------------------|:-------------|:------------| -| GUID | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00AEC000 | 0x00001000 | -| GSNPSID | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54320A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x4F54292A | 0x00000000 | -| - specs version | 2.80a | 3.30a | 4.00a | 4.00a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.20a | 3.30a | 3.10a | 4.11a | 2.92a | 0.00W | -| GHWCFG1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | -| GHWCFG2 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x215FFFD0 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x228F5930 | 0x00000000 | -| - 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 | DMA internal | Slave only | -| - single_point | hub | hub | n/a | hub | n/a | hub | n/a | n/a | hub | hub | hub | n/a | hub | n/a | hub | -| - 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 | Dedicated | n/a | -| - num_dev_ep | 7 | 6 | 6 | 15 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 6 | 0 | -| - num_host_ch | 7 | 13 | 7 | 15 | 7 | 11 | 11 | 11 | 15 | 15 | 15 | 11 | 15 | 13 | 0 | -| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 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 | 8 | 8 | 4 | 4 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 2 | -| - ptx_q_depth | 8 | 8 | 8 | 4 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 2 | -| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | -| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| GHWCFG3 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x03805EB5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x027A01E5 | 0x00000000 | -| - xfer_size_width | 8 | 8 | 5 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 5 | 0 | -| - packet_size_width | 6 | 6 | 3 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | -| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - i2c_enable | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | -| - vendor_ctrl_itf | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | -| - optional_feature_removed | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - synch_reset | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - otg_adp_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - battery_charger_support | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | -| - dfifo_depth | 4080 | 498 | 200 | 896 | 512 | 1012 | 512 | 512 | 1006 | 1006 | 952 | 512 | 952 | 634 | 0 | -| GHWCFG4 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0xDFF1A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0xDBF08030 | 0x00000000 | -| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - partial_powerdown | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - enhanced_lpm_support | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - phy_data_width | 8 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8 bit | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8 bit | 8/16 bit | 8 bit | 8/16 bit | 8 bit | -| - ctrl_ep_num | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - iddg_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - vbus_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | -| - a_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | -| - b_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | -| - session_end_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | -| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - num_dev_in_eps | 7 | 6 | 4 | 7 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 6 | 0 | -| - dma_desc_enable | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | -| - dma_desc_dynamic | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | +| | AT32 F405 FS | AT32 F405 HS | BCM2711 (Pi4) | EFM32GG | ESP32-S2/S3 | ESP32-P4 | ST F207/F407/411/429 FS | ST F407/429 HS | ST F412/76x FS | ST F723/L4P5 FS | ST F723 HS | ST F76x HS | ST H743/H750 | ST L476 FS | ST U5A5/H7RS/N6 HS | XMC4500 | GD32VF103 | +|:---------------------------|:---------------|:---------------|:----------------|:-------------|:--------------|:-------------|:--------------------------|:-----------------|:-----------------|:------------------|:-------------|:-------------|:---------------|:-------------|:---------------------|:-------------|:------------| +| GUID | 0x00002000 | 0x00000000 | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00AEC000 | 0x00001000 | +| GSNPSID | 0x4F54400A | 0x4F54400A | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54320A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x4F54292A | 0x00000000 | +| - specs version | 4.00a | 4.00a | 2.80a | 3.30a | 4.00a | 4.00a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.20a | 3.30a | 3.10a | 4.11a | 2.92a | 0.00W | +| GHWCFG1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | +| GHWCFG2 | 0x228FDD00 | 0x229FDDD0 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x215FFFD0 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x228F5930 | 0x00000000 | +| - 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 | HNP SRP | HNP SRP | noHNP noSRP | HNP SRP | HNP SRP | +| - arch | Slave only | DMA internal | 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 | DMA internal | Slave only | +| - single_point | hub | hub | hub | hub | n/a | hub | n/a | hub | n/a | n/a | hub | hub | hub | n/a | hub | n/a | hub | +| - hs_phy_type | n/a | UTMI+/ULPI | 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 | Dedicated | Dedicated | Shared ULPI | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | n/a | Dedicated | n/a | +| - num_dev_ep | 7 | 7 | 7 | 6 | 6 | 15 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 6 | 0 | +| - num_host_ch | 15 | 15 | 7 | 13 | 7 | 15 | 7 | 11 | 11 | 11 | 15 | 15 | 15 | 11 | 15 | 13 | 0 | +| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - mul_proc_intrpt | 0 | 1 | 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 | 0 | 0 | +| - nptx_q_depth | 8 | 8 | 8 | 8 | 4 | 4 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 2 | +| - ptx_q_depth | 8 | 8 | 8 | 8 | 8 | 4 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 2 | +| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | +| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| GHWCFG3 | 0x020004E8 | 0x03F006E8 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x03805EB5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x027A01E5 | 0x00000000 | +| - xfer_size_width | 8 | 8 | 8 | 8 | 5 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 5 | 0 | +| - packet_size_width | 6 | 6 | 6 | 6 | 3 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | +| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - i2c_enable | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | +| - vendor_ctrl_itf | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | +| - optional_feature_removed | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - synch_reset | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - otg_adp_support | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - battery_charger_support | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | +| - dfifo_depth | 512 | 1008 | 4080 | 498 | 200 | 896 | 512 | 1012 | 512 | 512 | 1006 | 1006 | 952 | 512 | 952 | 634 | 0 | +| GHWCFG4 | 0x1FF0A020 | 0x1FF0A020 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0xDFF1A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0xDBF08030 | 0x00000000 | +| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - partial_powerdown | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - enhanced_lpm_support | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - phy_data_width | 8/16 bit | 8/16 bit | 8 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8 bit | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8 bit | 8/16 bit | 8 bit | 8/16 bit | 8 bit | +| - ctrl_ep_num | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - iddg_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - vbus_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | +| - a_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | +| - b_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | +| - session_end_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | +| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - num_dev_in_eps | 7 | 7 | 7 | 6 | 4 | 7 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 6 | 0 | +| - dma_desc_enable | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | +| - dma_desc_dynamic | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py index 3b1993cc5..bc5ad9a7b 100755 --- a/src/portable/synopsys/dwc2/dwc2_info.py +++ b/src/portable/synopsys/dwc2/dwc2_info.py @@ -9,6 +9,8 @@ import pandas as pd # Note: FS is FullSpeed, HS is HighSpeed dwc2_reg_list = ['GUID', 'GSNPSID', 'GHWCFG1', 'GHWCFG2', 'GHWCFG3', 'GHWCFG4'] dwc2_reg_value = { + 'AT32 F405 FS': [0x00002000, 0x4F54400A, 0x00000000, 0x228FDD00, 0x020004E8, 0x1FF0A020], + 'AT32 F405 HS': [0x00000000, 0x4F54400A, 0x00000000, 0x229FDDD0, 0x03F006E8, 0x1FF0A020], 'BCM2711 (Pi4)': [0x2708A000, 0x4F54280A, 0, 0x228DDD50, 0xFF000E8, 0x1FF00020], 'EFM32GG': [0, 0x4F54330A, 0, 0x228F5910, 0x01F204E8, 0x1BF08030], 'ESP32-S2/S3': [0, 0x4F54400A, 0, 0x224DD930, 0x0C804B5, 0xD3F0A030], -- cgit v1.3.1 From bd9dd75da8718dfd56b2e91b658f81613ed1bf3a Mon Sep 17 00:00:00 2001 From: Mitsumine Suzu <60875431+verylowfreq@users.noreply.github.com> Date: Sun, 24 Aug 2025 16:26:08 +0900 Subject: Small cleanups. --- src/portable/wch/hcd_ch32_usbfs.c | 25 ++++++++----------------- 1 file changed, 8 insertions(+), 17 deletions(-) (limited to 'src/portable') diff --git a/src/portable/wch/hcd_ch32_usbfs.c b/src/portable/wch/hcd_ch32_usbfs.c index d176f40c5..fc52597c2 100644 --- a/src/portable/wch/hcd_ch32_usbfs.c +++ b/src/portable/wch/hcd_ch32_usbfs.c @@ -120,9 +120,6 @@ static usb_edpt_t *get_empty_record_slot(void) { static usb_edpt_t *add_edpt_record(uint8_t dev_addr, uint8_t ep_addr, uint16_t max_packet_size, uint8_t xfer_type) { usb_edpt_t *slot = get_empty_record_slot(); - if (slot == NULL) { - PANIC("add_edpt_record(0x%02x, 0x%02x, ...) no slot for new record\r\n", dev_addr, ep_addr); - } TU_ASSERT(slot != NULL, NULL); slot->dev_addr = dev_addr; @@ -412,10 +409,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { } else { LOG_CH32_USBFSH("USB_PID_OUT continue...\r\n"); usb_current_xfer_info.buffer += tx_len; - uint16_t copylen = USBFS_TX_BUF_LEN; - if (copylen > usb_current_xfer_info.bufferlen) { - copylen = usb_current_xfer_info.bufferlen; - } + uint16_t copylen = TU_MIN(edpt_info->max_packet_size, usb_current_xfer_info.bufferlen); memcpy(USBFS_TX_Buf, usb_current_xfer_info.buffer, copylen); hardware_start_xfer(USB_PID_OUT, ep_addr, edpt_info->data_toggle); return; @@ -445,7 +439,10 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { } } default: { - PANIC("Unknown PID: 0x%02x\n", request_pid); + LOG_CH32_USBFSH("hcd_int_handler() L%d: unexpected response PID: 0x%02x\r\n", __LINE__, response_pid); + usb_current_xfer_info.is_busy = false; + hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true); + return; } } } else { @@ -474,7 +471,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true); return; } else { - LOG_CH32_USBFSH("In USBHD_IRQHandler, unexpected response PID: 0x%02x\r\n", response_pid); + LOG_CH32_USBFSH("hcd_int_handler() L%d: unexpected response PID: 0x%02x\r\n", __LINE__, response_pid); usb_current_xfer_info.is_busy = false; hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true); return; @@ -519,9 +516,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *b usb_current_xfer_info.is_busy = true; usb_edpt_t *edpt_info = get_edpt_record(dev_addr, ep_addr); - if (edpt_info == NULL) { - PANIC("get_edpt_record() returned NULL in hcd_edpt_xfer()\r\n"); - } + TU_ASSERT(edpt_info != NULL); hardware_set_port_address_speed(dev_addr); @@ -537,10 +532,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *b return hardware_start_xfer(USB_PID_IN, ep_addr, edpt_info->data_toggle); } else { LOG_CH32_USBFSH("hcd_edpt_xfer(): WRITE, dev_addr=0x%02x, ep_addr=0x%02x, len=%d\r\n", dev_addr, ep_addr, buflen); - uint16_t copylen = USBFS_TX_BUF_LEN; - if (copylen > buflen) { - copylen = buflen; - } + uint16_t copylen = TU_MIN(edpt_info->max_packet_size, buflen); USBOTG_H_FS->HOST_TX_LEN = copylen; memcpy(USBFS_TX_Buf, buffer, copylen); return hardware_start_xfer(USB_PID_OUT, ep_addr, edpt_info->data_toggle); @@ -596,7 +588,6 @@ bool hcd_edpt_clear_stall(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr) { (void) rhport; (void) dev_addr; LOG_CH32_USBFSH("hcd_edpt_clear_stall(rhport=%d, dev_addr=0x%02x, ep_addr=0x%02x)\r\n", rhport, dev_addr, ep_addr); - // PANIC("\r\install\r\n"); uint8_t edpt_num = tu_edpt_number(ep_addr); uint8_t setup_request_clear_stall[8] = { 0x02, 0x01, 0x00, 0x00, edpt_num, 0x00, 0x00, 0x00 -- cgit v1.3.1 From 522a34ee28bcee6674ccd91973cb87869be98909 Mon Sep 17 00:00:00 2001 From: Mitsumine Suzu <60875431+verylowfreq@users.noreply.github.com> Date: Sun, 24 Aug 2025 16:28:32 +0900 Subject: Insert small delay for LowSpeed device --- src/portable/wch/hcd_ch32_usbfs.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) (limited to 'src/portable') diff --git a/src/portable/wch/hcd_ch32_usbfs.c b/src/portable/wch/hcd_ch32_usbfs.c index fc52597c2..38bb0ed59 100644 --- a/src/portable/wch/hcd_ch32_usbfs.c +++ b/src/portable/wch/hcd_ch32_usbfs.c @@ -55,18 +55,18 @@ TU_ATTR_ALIGNED(4) static uint8_t USBFS_TX_Buf[USBFS_TX_BUF_LEN]; #define LOG_CH32_USBFSH(...) TU_LOG3(__VA_ARGS__) // Busywait for delay microseconds/nanoseconds -// static void loopdelay(uint32_t count) -// { -// volatile uint32_t c = count / 3; -// if (c == 0) { return; } -// // while (c-- != 0); -// asm volatile( -// "1: \n" // loop label -// " addi %0, %0, -1 \n" // c-- -// " bne %0, zero, 1b \n" // if (c != 0) goto loop -// : "+r"(c) // c is input/output operand -// ); -// } +static void loopdelay(uint32_t count) +{ + volatile uint32_t c = count / 3; + if (c == 0) { return; } + // while (c-- != 0); + asm volatile( + "1: \n" // loop label + " addi %0, %0, -1 \n" // c-- + " bne %0, zero, 1b \n" // if (c != 0) goto loop + : "+r"(c) // c is input/output operand + ); +} // Endpoint status @@ -194,10 +194,13 @@ static bool hardware_start_xfer(uint8_t pid, uint8_t ep_addr, uint8_t data_toggl : "(other)", pid, ep_addr, data_toggle); - // if (pid == USB_PID_IN) - // { // FIXME: long delay needed (at release build) about 30msec - // loopdelay(SystemCoreClock / 1000 * 30); - // } + //WORKAROUND: For LowSpeed device, insert small delay + bool is_lowspeed_device = tuh_speed_get(usb_current_xfer_info.dev_addr) == TUSB_SPEED_LOW; + if (is_lowspeed_device) { + //NOTE: worked -> SystemCoreClock / 1000000 * 50, 25 + // NOT worked -> 20 and less (at 144MHz internal clock) + loopdelay(SystemCoreClock / 1000000 * 40); + } uint8_t pid_edpt = (pid << 4) | (tu_edpt_number(ep_addr) & 0x0f); USBOTG_H_FS->HOST_TX_CTRL = (data_toggle != 0) ? USBFS_UH_T_TOG : 0; -- cgit v1.3.1 From a3bb7a90b3478f43d448443140b68c3473331f93 Mon Sep 17 00:00:00 2001 From: Mitsumine Suzu <60875431+verylowfreq@users.noreply.github.com> Date: Sun, 24 Aug 2025 16:46:12 +0900 Subject: Improve retry operation at NAK response. --- src/portable/wch/hcd_ch32_usbfs.c | 76 +++++++++++++++++++++++++++++++++------ 1 file changed, 66 insertions(+), 10 deletions(-) (limited to 'src/portable') diff --git a/src/portable/wch/hcd_ch32_usbfs.c b/src/portable/wch/hcd_ch32_usbfs.c index 38bb0ed59..449908658 100644 --- a/src/portable/wch/hcd_ch32_usbfs.c +++ b/src/portable/wch/hcd_ch32_usbfs.c @@ -28,6 +28,8 @@ #if CFG_TUH_ENABLED && defined(TUP_USBIP_WCH_USBFS) && defined(CFG_TUH_WCH_USBIP_USBFS) && CFG_TUH_WCH_USBIP_USBFS +#include + #include "host/hcd.h" #include "host/usbh.h" #include "host/usbh_pvt.h" @@ -95,6 +97,7 @@ typedef struct usb_current_xfer_st { uint8_t *buffer; uint16_t bufferlen; uint16_t xferred_len; + bool nak_pending; } usb_current_xfer_t; static volatile usb_current_xfer_t usb_current_xfer_info = {}; @@ -351,6 +354,34 @@ void hcd_int_disable(uint8_t rhport) { interrupt_enabled = false; } +typedef struct { + uint8_t rhport; + uint8_t dev_addr; + uint8_t ep_addr; + uint16_t buflen; + uint8_t* buf; +} xfer_retry_param_t; + +static void xfer_retry(void* _params) { + LOG_CH32_USBFSH("xfer_retry()\r\n"); + xfer_retry_param_t* params = (xfer_retry_param_t*)_params; + if (usb_current_xfer_info.nak_pending) { + usb_current_xfer_info.nak_pending = false; + + uint8_t dev_addr = params->dev_addr; + uint8_t ep_addr = params->ep_addr; + uint16_t buflen = params->buflen; + uint8_t* buf = params->buf; + free(params); + + usb_edpt_t* edpt_info = get_edpt_record(dev_addr, ep_addr); + if (edpt_info) { + hcd_edpt_xfer(0, dev_addr, ep_addr, buf, buflen); + } + } +} + + void hcd_int_handler(uint8_t rhport, bool in_isr) { (void) rhport; (void) in_isr; @@ -407,7 +438,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { if (usb_current_xfer_info.bufferlen == 0) { LOG_CH32_USBFSH("USB_PID_%s completed %d bytes\r\n", request_pid == USB_PID_OUT ? "OUT" : "SETUP", usb_current_xfer_info.xferred_len); usb_current_xfer_info.is_busy = false; - hcd_event_xfer_complete(dev_addr, ep_addr, usb_current_xfer_info.xferred_len, XFER_RESULT_SUCCESS, true); + hcd_event_xfer_complete(dev_addr, ep_addr, usb_current_xfer_info.xferred_len, XFER_RESULT_SUCCESS, in_isr); return; } else { LOG_CH32_USBFSH("USB_PID_OUT continue...\r\n"); @@ -432,7 +463,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { // USB device sent all data. LOG_CH32_USBFSH("USB_PID_IN completed\r\n"); usb_current_xfer_info.is_busy = false; - hcd_event_xfer_complete(dev_addr, ep_addr, xferred_len, XFER_RESULT_SUCCESS, true); + hcd_event_xfer_complete(dev_addr, ep_addr, xferred_len, XFER_RESULT_SUCCESS, in_isr); return; } else { // USB device may send more data. @@ -444,7 +475,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { default: { LOG_CH32_USBFSH("hcd_int_handler() L%d: unexpected response PID: 0x%02x\r\n", __LINE__, response_pid); usb_current_xfer_info.is_busy = false; - hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true); + hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, in_isr); return; } } @@ -458,25 +489,46 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { } else if (response_pid == USB_PID_NAK) { LOG_CH32_USBFSH("NAK reposense\r\n"); uint32_t elapsed_time = board_millis() - usb_current_xfer_info.start_ms; + (void)elapsed_time; if (edpt_info->xfer_type == TUSB_XFER_INTERRUPT) { usb_current_xfer_info.is_busy = false; - hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_SUCCESS, true); - } else if (elapsed_time > USB_XFER_TIMEOUT_MILLIS) { - usb_current_xfer_info.is_busy = false; - hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true); + hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_SUCCESS, in_isr); + } else { - hardware_start_xfer(request_pid, ep_addr, edpt_info->data_toggle); + usb_current_xfer_info.is_busy = false; + usb_current_xfer_info.nak_pending = true; + + xfer_retry_param_t* param_buf = malloc(sizeof(xfer_retry_param_t)); + xfer_retry_param_t param = { + .rhport = 0, + .dev_addr = dev_addr, + .ep_addr = ep_addr, + .buflen = usb_current_xfer_info.bufferlen, + .buf = usb_current_xfer_info.buffer + }; + memcpy(param_buf, ¶m, sizeof(xfer_retry_param_t)); + + hcd_event_t event = { + .rhport = rhport, + .dev_addr = dev_addr, + .event_id = USBH_EVENT_FUNC_CALL, + .func_call = { + .func = xfer_retry, + .param = param_buf + } + }; + hcd_event_handler(&event, in_isr); } return; } else if (response_pid == USB_PID_DATA0 || response_pid == USB_PID_DATA1) { LOG_CH32_USBFSH("Data toggle mismatched and DATA0/1 (not STALL). RX_LEN=%d\r\n", USBOTG_H_FS->RX_LEN); usb_current_xfer_info.is_busy = false; - hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true); + hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, in_isr); return; } else { LOG_CH32_USBFSH("hcd_int_handler() L%d: unexpected response PID: 0x%02x\r\n", __LINE__, response_pid); usb_current_xfer_info.is_busy = false; - hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, true); + hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_FAILED, in_isr); return; } } @@ -495,6 +547,8 @@ bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const uint8_t xfer_type = ep_desc->bmAttributes.xfer; LOG_CH32_USBFSH("hcd_edpt_open(rhport=%d, dev_addr=0x%02x, %p) EndpointAdderss=0x%02x,maxPacketSize=%d,xfer_type=%d\r\n", rhport, dev_addr, ep_desc, ep_addr, max_packet_size, xfer_type); + while (usb_current_xfer_info.is_busy) { } + if (ep_num == 0x00) { TU_ASSERT(get_or_add_edpt_record(dev_addr, 0x00, max_packet_size, xfer_type) != NULL, false); TU_ASSERT(get_or_add_edpt_record(dev_addr, 0x80, max_packet_size, xfer_type) != NULL, false); @@ -529,6 +583,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *b usb_current_xfer_info.bufferlen = buflen; usb_current_xfer_info.start_ms = board_millis(); usb_current_xfer_info.xferred_len = 0; + usb_current_xfer_info.nak_pending = false; if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { LOG_CH32_USBFSH("hcd_edpt_xfer(): READ, dev_addr=0x%02x, ep_addr=0x%02x, len=%d\r\n", dev_addr, ep_addr, buflen); @@ -581,6 +636,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet usb_current_xfer_info.buffer = USBFS_TX_Buf; usb_current_xfer_info.bufferlen = setup_packet_datalen; usb_current_xfer_info.xferred_len = 0; + usb_current_xfer_info.nak_pending = false; hardware_start_xfer(USB_PID_SETUP, 0, 0); -- cgit v1.3.1 From 6f2b5fc4952e0fc730466a8756ce6427c33ce2b7 Mon Sep 17 00:00:00 2001 From: Mitsumine Suzu <60875431+verylowfreq@users.noreply.github.com> Date: Sun, 24 Aug 2025 23:52:52 +0900 Subject: Remove dynamic memory allocation --- src/portable/wch/hcd_ch32_usbfs.c | 46 ++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 25 deletions(-) (limited to 'src/portable') diff --git a/src/portable/wch/hcd_ch32_usbfs.c b/src/portable/wch/hcd_ch32_usbfs.c index 449908658..ff34ae17a 100644 --- a/src/portable/wch/hcd_ch32_usbfs.c +++ b/src/portable/wch/hcd_ch32_usbfs.c @@ -84,6 +84,10 @@ typedef struct usb_edpt { // Data toggle (0 or not 0) for DATA0/1 uint8_t data_toggle; + + bool is_nak_pending; + uint16_t buflen; + uint8_t* buf; } usb_edpt_t; static usb_edpt_t usb_edpt_list[CFG_TUH_DEVICE_MAX * 6] = {}; @@ -130,6 +134,9 @@ static usb_edpt_t *add_edpt_record(uint8_t dev_addr, uint8_t ep_addr, uint16_t m slot->max_packet_size = max_packet_size; slot->xfer_type = xfer_type; slot->data_toggle = 0; + slot->is_nak_pending = false; + slot->buflen = 0; + slot->buf = NULL; slot->configured = true; @@ -354,28 +361,22 @@ void hcd_int_disable(uint8_t rhport) { interrupt_enabled = false; } -typedef struct { - uint8_t rhport; - uint8_t dev_addr; - uint8_t ep_addr; - uint16_t buflen; - uint8_t* buf; -} xfer_retry_param_t; static void xfer_retry(void* _params) { LOG_CH32_USBFSH("xfer_retry()\r\n"); - xfer_retry_param_t* params = (xfer_retry_param_t*)_params; + usb_edpt_t* edpt_info = (usb_edpt_t*)_params; if (usb_current_xfer_info.nak_pending) { usb_current_xfer_info.nak_pending = false; + edpt_info->is_nak_pending = false; - uint8_t dev_addr = params->dev_addr; - uint8_t ep_addr = params->ep_addr; - uint16_t buflen = params->buflen; - uint8_t* buf = params->buf; - free(params); + uint8_t dev_addr = edpt_info->dev_addr; + uint8_t ep_addr = edpt_info->ep_addr; + uint16_t buflen = edpt_info->buflen; + uint8_t* buf = edpt_info->buf; - usb_edpt_t* edpt_info = get_edpt_record(dev_addr, ep_addr); - if (edpt_info) { + // Check connectivity + usb_edpt_t* edpt_info_current = get_edpt_record(dev_addr, ep_addr); + if (edpt_info_current) { hcd_edpt_xfer(0, dev_addr, ep_addr, buf, buflen); } } @@ -498,15 +499,10 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { usb_current_xfer_info.is_busy = false; usb_current_xfer_info.nak_pending = true; - xfer_retry_param_t* param_buf = malloc(sizeof(xfer_retry_param_t)); - xfer_retry_param_t param = { - .rhport = 0, - .dev_addr = dev_addr, - .ep_addr = ep_addr, - .buflen = usb_current_xfer_info.bufferlen, - .buf = usb_current_xfer_info.buffer - }; - memcpy(param_buf, ¶m, sizeof(xfer_retry_param_t)); + + edpt_info->is_nak_pending = true; + edpt_info->buflen = usb_current_xfer_info.bufferlen; + edpt_info->buf = usb_current_xfer_info.buffer; hcd_event_t event = { .rhport = rhport, @@ -514,7 +510,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { .event_id = USBH_EVENT_FUNC_CALL, .func_call = { .func = xfer_retry, - .param = param_buf + .param = edpt_info } }; hcd_event_handler(&event, in_isr); -- cgit v1.3.1 From 38f41f5fa28943086cd36653e0914fd59cb7ed03 Mon Sep 17 00:00:00 2001 From: Tomas Rezucha Date: Thu, 28 Aug 2025 15:35:55 +0200 Subject: fix(dcd/dwc2): Fix reset procedure for versions >=4.20a --- src/portable/synopsys/dwc2/dwc2_common.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c index b001f343d..9b8333ad2 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.c +++ b/src/portable/synopsys/dwc2/dwc2_common.c @@ -1,7 +1,7 @@ /* * The MIT License (MIT) * - * Copyright (c) 2024 Ha Thach (tinyusb.org) + * Copyright (c) 2024-2025 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 @@ -45,11 +45,14 @@ // //-------------------------------------------------------------------- static void reset_core(dwc2_regs_t* dwc2) { + // load gsnpsid (it is not readable after reset is asserted) + uint32_t gsnpsid = dwc2->gsnpsid; + // reset core dwc2->grstctl |= GRSTCTL_CSRST; - if ((dwc2->gsnpsid & DWC2_CORE_REV_MASK) < (DWC2_CORE_REV_4_20a & DWC2_CORE_REV_MASK)) { - // prior v42.0 CSRST is self-clearing + if ((gsnpsid & DWC2_CORE_REV_MASK) < (DWC2_CORE_REV_4_20a & DWC2_CORE_REV_MASK)) { + // prior v4.20a CSRST is self-clearing while (dwc2->grstctl & GRSTCTL_CSRST) {} } else { // From v4.20a CSRST bit is write only, CSRT_DONE (w1c) is introduced for checking. -- cgit v1.3.1 From f5d04833bb5841930476cc666193f2f362aef228 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 3 Sep 2025 13:30:20 +0700 Subject: use tusb_time_millis_api() instead of board_millis() make loopdelay() always inline --- src/portable/wch/hcd_ch32_usbfs.c | 28 +++++++++++++--------------- 1 file changed, 13 insertions(+), 15 deletions(-) (limited to 'src/portable') diff --git a/src/portable/wch/hcd_ch32_usbfs.c b/src/portable/wch/hcd_ch32_usbfs.c index ff34ae17a..200136906 100644 --- a/src/portable/wch/hcd_ch32_usbfs.c +++ b/src/portable/wch/hcd_ch32_usbfs.c @@ -57,20 +57,18 @@ TU_ATTR_ALIGNED(4) static uint8_t USBFS_TX_Buf[USBFS_TX_BUF_LEN]; #define LOG_CH32_USBFSH(...) TU_LOG3(__VA_ARGS__) // Busywait for delay microseconds/nanoseconds -static void loopdelay(uint32_t count) -{ - volatile uint32_t c = count / 3; - if (c == 0) { return; } - // while (c-- != 0); - asm volatile( - "1: \n" // loop label - " addi %0, %0, -1 \n" // c-- - " bne %0, zero, 1b \n" // if (c != 0) goto loop - : "+r"(c) // c is input/output operand +TU_ATTR_ALWAYS_INLINE static inline void loopdelay(uint32_t count) { + volatile uint32_t c = count / 3; + if (c == 0) { return; } + // while (c-- != 0); + asm volatile( + "1: \n" // loop label + " addi %0, %0, -1 \n" // c-- + " bne %0, zero, 1b \n" // if (c != 0) goto loop + : "+r"(c) // c is input/output operand ); } - // Endpoint status typedef struct usb_edpt { // Is this a valid struct @@ -346,7 +344,7 @@ void hcd_device_close(uint8_t rhport, uint8_t dev_addr) { uint32_t hcd_frame_number(uint8_t rhport) { (void) rhport; - return board_millis(); + return tusb_time_millis_api(); } void hcd_int_enable(uint8_t rhport) { @@ -489,7 +487,7 @@ void hcd_int_handler(uint8_t rhport, bool in_isr) { return; } else if (response_pid == USB_PID_NAK) { LOG_CH32_USBFSH("NAK reposense\r\n"); - uint32_t elapsed_time = board_millis() - usb_current_xfer_info.start_ms; + uint32_t elapsed_time = tusb_time_millis_api() - usb_current_xfer_info.start_ms; (void)elapsed_time; if (edpt_info->xfer_type == TUSB_XFER_INTERRUPT) { usb_current_xfer_info.is_busy = false; @@ -577,7 +575,7 @@ bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *b usb_current_xfer_info.ep_addr = ep_addr; usb_current_xfer_info.buffer = buffer; usb_current_xfer_info.bufferlen = buflen; - usb_current_xfer_info.start_ms = board_millis(); + usb_current_xfer_info.start_ms = tusb_time_millis_api(); usb_current_xfer_info.xferred_len = 0; usb_current_xfer_info.nak_pending = false; @@ -628,7 +626,7 @@ bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet uint8_t ep_addr = (setup_packet[0] & 0x80) ? 0x80 : 0x00; usb_current_xfer_info.dev_addr = dev_addr; usb_current_xfer_info.ep_addr = ep_addr; - usb_current_xfer_info.start_ms = board_millis(); + usb_current_xfer_info.start_ms = tusb_time_millis_api(); usb_current_xfer_info.buffer = USBFS_TX_Buf; usb_current_xfer_info.bufferlen = setup_packet_datalen; usb_current_xfer_info.xferred_len = 0; -- cgit v1.3.1 From c5a390950f8616f42917bc6ecd8c8e528cdda49e Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 3 Sep 2025 17:20:54 +0700 Subject: add at32f415 dwc2 info --- src/portable/synopsys/dwc2/dwc2_info.md | 116 ++++++++++++++++---------------- src/portable/synopsys/dwc2/dwc2_info.py | 1 + 2 files changed, 59 insertions(+), 58 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dwc2_info.md b/src/portable/synopsys/dwc2/dwc2_info.md index 00685e7ad..e6b7820bc 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.md +++ b/src/portable/synopsys/dwc2/dwc2_info.md @@ -1,58 +1,58 @@ -| | AT32 F405 FS | AT32 F405 HS | BCM2711 (Pi4) | EFM32GG | ESP32-S2/S3 | ESP32-P4 | ST F207/F407/411/429 FS | ST F407/429 HS | ST F412/76x FS | ST F723/L4P5 FS | ST F723 HS | ST F76x HS | ST H743/H750 | ST L476 FS | ST U5A5/H7RS/N6 HS | XMC4500 | GD32VF103 | -|:---------------------------|:---------------|:---------------|:----------------|:-------------|:--------------|:-------------|:--------------------------|:-----------------|:-----------------|:------------------|:-------------|:-------------|:---------------|:-------------|:---------------------|:-------------|:------------| -| GUID | 0x00002000 | 0x00000000 | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00AEC000 | 0x00001000 | -| GSNPSID | 0x4F54400A | 0x4F54400A | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54320A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x4F54292A | 0x00000000 | -| - specs version | 4.00a | 4.00a | 2.80a | 3.30a | 4.00a | 4.00a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.20a | 3.30a | 3.10a | 4.11a | 2.92a | 0.00W | -| GHWCFG1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | -| GHWCFG2 | 0x228FDD00 | 0x229FDDD0 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x215FFFD0 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x228F5930 | 0x00000000 | -| - 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 | HNP SRP | HNP SRP | noHNP noSRP | HNP SRP | HNP SRP | -| - arch | Slave only | DMA internal | 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 | DMA internal | Slave only | -| - single_point | hub | hub | hub | hub | n/a | hub | n/a | hub | n/a | n/a | hub | hub | hub | n/a | hub | n/a | hub | -| - hs_phy_type | n/a | UTMI+/ULPI | 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 | Dedicated | Dedicated | Shared ULPI | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | n/a | Dedicated | n/a | -| - num_dev_ep | 7 | 7 | 7 | 6 | 6 | 15 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 6 | 0 | -| - num_host_ch | 15 | 15 | 7 | 13 | 7 | 15 | 7 | 11 | 11 | 11 | 15 | 15 | 15 | 11 | 15 | 13 | 0 | -| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - mul_proc_intrpt | 0 | 1 | 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 | 0 | 0 | -| - nptx_q_depth | 8 | 8 | 8 | 8 | 4 | 4 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 2 | -| - ptx_q_depth | 8 | 8 | 8 | 8 | 8 | 4 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 2 | -| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | -| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| GHWCFG3 | 0x020004E8 | 0x03F006E8 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x03805EB5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x027A01E5 | 0x00000000 | -| - xfer_size_width | 8 | 8 | 8 | 8 | 5 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 5 | 0 | -| - packet_size_width | 6 | 6 | 6 | 6 | 3 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | -| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - i2c_enable | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | -| - vendor_ctrl_itf | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | -| - optional_feature_removed | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - synch_reset | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - otg_adp_support | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - battery_charger_support | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | -| - dfifo_depth | 512 | 1008 | 4080 | 498 | 200 | 896 | 512 | 1012 | 512 | 512 | 1006 | 1006 | 952 | 512 | 952 | 634 | 0 | -| GHWCFG4 | 0x1FF0A020 | 0x1FF0A020 | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0xDFF1A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0xDBF08030 | 0x00000000 | -| - num_dev_period_in_ep | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - partial_powerdown | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - ahb_freq_min | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - enhanced_lpm_support | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - phy_data_width | 8/16 bit | 8/16 bit | 8 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8 bit | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8 bit | 8/16 bit | 8 bit | 8/16 bit | 8 bit | -| - ctrl_ep_num | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - iddg_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - vbus_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | -| - a_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | -| - b_valid_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | -| - session_end_filter | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | -| - dedicated_fifos | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - num_dev_in_eps | 7 | 7 | 7 | 6 | 4 | 7 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 6 | 0 | -| - dma_desc_enable | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | -| - dma_desc_dynamic | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | +| | AT32 F405 FS | AT32 F405 HS | AT32 F415 | BCM2711 (Pi4) | EFM32GG | ESP32-S2/S3 | ESP32-P4 | ST F207/F407/411/429 FS | ST F407/429 HS | ST F412/76x FS | ST F723/L4P5 FS | ST F723 HS | ST F76x HS | ST H743/H750 | ST L476 FS | ST U5A5/H7RS/N6 HS | XMC4500 | GD32VF103 | +|:---------------------------|:---------------|:---------------|:------------|:----------------|:-------------|:--------------|:-------------|:--------------------------|:-----------------|:-----------------|:------------------|:-------------|:-------------|:---------------|:-------------|:---------------------|:-------------|:------------| +| GUID | 0x00002000 | 0x00000000 | 0x00001000 | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00AEC000 | 0x00001000 | +| GSNPSID | 0x4F54400A | 0x4F54400A | 0x4F54400A | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54320A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x4F54292A | 0x00000000 | +| - specs version | 4.00a | 4.00a | 4.00a | 2.80a | 3.30a | 4.00a | 4.00a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.20a | 3.30a | 3.10a | 4.11a | 2.92a | 0.00W | +| GHWCFG1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | +| GHWCFG2 | 0x228FDD00 | 0x229FDDD0 | 0x228DCD00 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x215FFFD0 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x228F5930 | 0x00000000 | +| - 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 | HNP SRP | HNP SRP | HNP SRP | noHNP noSRP | HNP SRP | HNP SRP | +| - arch | Slave only | DMA internal | Slave only | 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 | DMA internal | Slave only | +| - single_point | hub | hub | hub | hub | hub | n/a | hub | n/a | hub | n/a | n/a | hub | hub | hub | n/a | hub | n/a | hub | +| - hs_phy_type | n/a | UTMI+/ULPI | n/a | 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 | Dedicated | Dedicated | Dedicated | Shared ULPI | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | n/a | Dedicated | n/a | +| - num_dev_ep | 7 | 7 | 3 | 7 | 6 | 6 | 15 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 6 | 0 | +| - num_host_ch | 15 | 15 | 7 | 7 | 13 | 7 | 15 | 7 | 11 | 11 | 11 | 15 | 15 | 15 | 11 | 15 | 13 | 0 | +| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - mul_proc_intrpt | 0 | 1 | 0 | 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 | 0 | 0 | 0 | +| - nptx_q_depth | 8 | 8 | 8 | 8 | 8 | 4 | 4 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 2 | +| - ptx_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 4 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 2 | +| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | +| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| GHWCFG3 | 0x020004E8 | 0x03F006E8 | 0x020004E8 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x03805EB5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x027A01E5 | 0x00000000 | +| - xfer_size_width | 8 | 8 | 8 | 8 | 8 | 5 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 5 | 0 | +| - packet_size_width | 6 | 6 | 6 | 6 | 6 | 3 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | +| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - i2c_enable | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | +| - vendor_ctrl_itf | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | +| - optional_feature_removed | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - synch_reset | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - otg_adp_support | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - battery_charger_support | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | +| - dfifo_depth | 512 | 1008 | 512 | 4080 | 498 | 200 | 896 | 512 | 1012 | 512 | 512 | 1006 | 1006 | 952 | 512 | 952 | 634 | 0 | +| GHWCFG4 | 0x1FF0A020 | 0x1FF0A020 | 0x0000000F | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0xDFF1A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0xDBF08030 | 0x00000000 | +| - num_dev_period_in_ep | 0 | 0 | 15 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - partial_powerdown | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - ahb_freq_min | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - enhanced_lpm_support | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - phy_data_width | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8 bit | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8 bit | 8/16 bit | 8 bit | 8/16 bit | 8 bit | +| - ctrl_ep_num | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - iddg_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - vbus_valid_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | +| - a_valid_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | +| - b_valid_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | +| - session_end_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | +| - dedicated_fifos | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - num_dev_in_eps | 7 | 7 | 0 | 7 | 6 | 4 | 7 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 6 | 0 | +| - dma_desc_enable | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | +| - dma_desc_dynamic | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py index bc5ad9a7b..a90150632 100755 --- a/src/portable/synopsys/dwc2/dwc2_info.py +++ b/src/portable/synopsys/dwc2/dwc2_info.py @@ -11,6 +11,7 @@ dwc2_reg_list = ['GUID', 'GSNPSID', 'GHWCFG1', 'GHWCFG2', 'GHWCFG3', 'GHWCFG4'] dwc2_reg_value = { 'AT32 F405 FS': [0x00002000, 0x4F54400A, 0x00000000, 0x228FDD00, 0x020004E8, 0x1FF0A020], 'AT32 F405 HS': [0x00000000, 0x4F54400A, 0x00000000, 0x229FDDD0, 0x03F006E8, 0x1FF0A020], + 'AT32 F415': [0x00001000, 0x4F54400A, 0x00000000, 0x228DCD00, 0x020004E8, 0x0F], 'BCM2711 (Pi4)': [0x2708A000, 0x4F54280A, 0, 0x228DDD50, 0xFF000E8, 0x1FF00020], 'EFM32GG': [0, 0x4F54330A, 0, 0x228F5910, 0x01F204E8, 0x1BF08030], 'ESP32-S2/S3': [0, 0x4F54400A, 0, 0x224DD930, 0x0C804B5, 0xD3F0A030], -- cgit v1.3.1 From d70d4043dcccb1628424c39c231ed1f95fb52f8e Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 10 Sep 2025 16:59:26 +0700 Subject: use tusb_time_delay_ms_api for delay, also move tusb_time api to common.h --- src/common/tusb_common.h | 8 +++++++- src/portable/synopsys/dwc2/dwc2_stm32.h | 3 +-- src/tusb.h | 10 ---------- 3 files changed, 8 insertions(+), 13 deletions(-) (limited to 'src/portable') diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 0351a3d8f..b5bdb76e3 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -78,10 +78,16 @@ #include "tusb_debug.h" //--------------------------------------------------------------------+ -// Optional API implemented by application if needed +// API implemented by application if needed // TODO move to a more obvious place/file //--------------------------------------------------------------------+ +// Get current milliseconds, required by some port/configuration without RTOS +extern uint32_t tusb_time_millis_api(void); + +// Delay in milliseconds, use tusb_time_millis_api() by default. required by some port/configuration with no RTOS +extern void tusb_time_delay_ms_api(uint32_t ms); + // flush data cache TU_ATTR_WEAK extern void tusb_app_dcache_flush(uintptr_t addr, uint32_t data_size); diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 0bbad55f5..14d95184e 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -224,8 +224,7 @@ static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN; // Wait ~2ms until the PLL is ready (there's no RDY bit to query) - uint32_t count = (SystemCoreClock / 1000) * 2; - while (count--) __NOP(); + tusb_time_delay_ms_api(2); #else #endif diff --git a/src/tusb.h b/src/tusb.h index dfba21ddf..88815def1 100644 --- a/src/tusb.h +++ b/src/tusb.h @@ -169,16 +169,6 @@ void tusb_int_handler(uint8_t rhport, bool in_isr); #endif -//--------------------------------------------------------------------+ -// API Implemented by user -//--------------------------------------------------------------------+ - -// Get current milliseconds, required by some port/configuration without RTOS -uint32_t tusb_time_millis_api(void); - -// Delay in milliseconds, use tusb_time_millis_api() by default. required by some port/configuration with no RTOS -void tusb_time_delay_ms_api(uint32_t ms); - #ifdef __cplusplus } #endif -- cgit v1.3.1 From 19f67ffc22bcf9a59125b0f992bf6e8ee9819eec Mon Sep 17 00:00:00 2001 From: Dalton Caron Date: Tue, 9 Sep 2025 14:09:26 -0700 Subject: Initial STM32WBARI eval support Clean up includes definitions Remove wait that is not required Remove redundant settings Clean up clock configuration to look like other modules Remove MSP_Init that is not required Clean up driver code dhcp: Fix DHCP_OFFER/DHCP_ACK destinaton. In RFC 2131, the destination of DHCP OFFER/ACK is defined in Section 4.1. Fix the destination error by following the rule of RFC 2131. TODO: We implement all rule but the last one. ARP table is required to associate client's macaddr. Currently, fallback to broadcast. Signed-off-by: Elwin Huang Fix compile error. Fix goto indentation Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Fix osal_spin_unlock for mynewt Mynewt version for osal_spin_unlock() called OS_ENTER_CRITICAL instead of OS_EXIT_CRITICAL. Signed-off-by: Jerzy Kasenberg Add ESP32-C5 and ESP32-C61 definitions fix(dcd/dwc2): Fix reset procedure for versions >=4.20a Fix STM32L4 GPIOD clock enable for variants without GPIOD Add weact blackpill support Add to boards.rst file Fix file Small cleanups. Insert small delay for LowSpeed device Improve retry operation at NAK response. Remove dynamic memory allocation use tusb_time_millis_api() instead of board_millis() make loopdelay() always inline update at32f405 dwc2 info and phy width selection add at32f415 dwc2 info add some consumer page configs remove duplicated enum Initial plan Fix obsolete cnt assignment in _tu_fifo_peek() overflow check Co-authored-by: hathach <249515+hathach@users.noreply.github.com> Initial plan Update STM32 CMSIS dependencies to fix HSITRIM register bug Co-authored-by: hathach <249515+hathach@users.noreply.github.com> Remove accidentally committed dependency directories Co-authored-by: hathach <249515+hathach@users.noreply.github.com> Update all STM32 HAL driver dependencies to latest versions Co-authored-by: hathach <249515+hathach@users.noreply.github.com> fix linker h745 issue with clang fix linker h745 issue with clang Update all STM32 CMSIS device dependencies to latest versions Co-authored-by: hathach <249515+hathach@users.noreply.github.com> update pio-usb Create comprehensive GitHub Copilot instructions and fix pre-commit configuration for TinyUSB (#3234) * Initial plan * Create comprehensive GitHub Copilot instructions for TinyUSB Co-authored-by: hathach <249515+hathach@users.noreply.github.com> * Remove accidentally committed dependencies, use tools/get_deps.py instead Co-authored-by: hathach <249515+hathach@users.noreply.github.com> * Fix .gitignore: ignore vendor/ directory not ceedling script Co-authored-by: hathach <249515+hathach@users.noreply.github.com> * Revert .gitignore changes and add README_processed.rst Co-authored-by: hathach <249515+hathach@users.noreply.github.com> * Remove README_processed.rst and revert ceedling file permissions Co-authored-by: hathach <249515+hathach@users.noreply.github.com> * Changes before error encountered Co-authored-by: hathach <249515+hathach@users.noreply.github.com> * Remove redundant manual validation step, keep only pre-commit and build validation Co-authored-by: hathach <249515+hathach@users.noreply.github.com> * fix pre-commit --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: hathach <249515+hathach@users.noreply.github.com> modified the bsp files of at32 to make them work better the family name error of at32 has been corrected fix pre-commit STM32N6570-DK board is added. Build with DEBUG=1 (make BOARD=stm32n6570dk DEBUG=1 all), otherwise it does not work for now. Tested with examples/device/cdc_dual_ports --- docs/reference/boards.rst | 1 + docs/reference/dependencies.rst | 1 + hw/bsp/stm32wba/FreeRTOSConfig/FreeRTOSConfig.h | 153 +++++++++ hw/bsp/stm32wba/boards/stm32wba_eval/board.cmake | 10 + hw/bsp/stm32wba/boards/stm32wba_eval/board.h | 136 ++++++++ hw/bsp/stm32wba/boards/stm32wba_eval/board.mk | 6 + .../stm32wba_eval/include/stm32wbaxx_hal_conf.h | 368 +++++++++++++++++++++ hw/bsp/stm32wba/family.c | 233 +++++++++++++ hw/bsp/stm32wba/family.mk | 59 ++++ hw/bsp/stm32wba/stm32wbaxx_hal_conf.h | 367 ++++++++++++++++++++ src/common/tusb_mcu.h | 6 + src/portable/st/stm32_fsdev/fsdev_stm32.h | 8 + src/portable/synopsys/dwc2/dwc2_common.c | 5 + src/portable/synopsys/dwc2/dwc2_stm32.h | 23 +- src/tusb_option.h | 1 + tools/get_deps.py | 6 + 16 files changed, 1381 insertions(+), 2 deletions(-) create mode 100644 hw/bsp/stm32wba/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/stm32wba/boards/stm32wba_eval/board.cmake create mode 100644 hw/bsp/stm32wba/boards/stm32wba_eval/board.h create mode 100644 hw/bsp/stm32wba/boards/stm32wba_eval/board.mk create mode 100644 hw/bsp/stm32wba/boards/stm32wba_eval/include/stm32wbaxx_hal_conf.h create mode 100644 hw/bsp/stm32wba/family.c create mode 100644 hw/bsp/stm32wba/family.mk create mode 100644 hw/bsp/stm32wba/stm32wbaxx_hal_conf.h (limited to 'src/portable') diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index 71dca8e94..a930f485b 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -303,6 +303,7 @@ stm32u575eval STM32 U575 Eval stm32u5 https://www.s stm32u575nucleo STM32 U575 Nucleo stm32u5 https://www.st.com/en/evaluation-tools/nucleo-u575zi-q.html stm32u5a5nucleo STM32 U5a5 Nucleo stm32u5 https://www.st.com/en/evaluation-tools/nucleo-u5a5zj-q.html stm32wb55nucleo STM32 P-NUCLEO-WB55 stm32wb https://www.st.com/en/evaluation-tools/p-nucleo-wb55.html +stm32wba65nucleo STM32 NUCLEO-WBA65RI stm32wba https://www.st.com/en/evaluation-tools/nucleo-wba65ri.html =================== ================================= ========= ================================================================= ====== Sunxi diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index d75139aae..8a65eee86 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -71,6 +71,7 @@ hw/mcu/st/stm32l5xx_hal_driver https://github.com/STMicroelectronics/ hw/mcu/st/stm32n6xx_hal_driver https://github.com/STMicroelectronics/stm32n6xx-hal-driver.git 49f9989d10cf6817d4b07ac01848956b46bd0fd6 stm32n6 hw/mcu/st/stm32u5xx_hal_driver https://github.com/STMicroelectronics/stm32u5xx_hal_driver.git 4d93097a67928e9377e655ddd14622adc31b9770 stm32u5 hw/mcu/st/stm32wbxx_hal_driver https://github.com/STMicroelectronics/stm32wbxx_hal_driver.git 2c5f06638be516c1b772f768456ba637f077bac8 stm32wb +hw/mcu/st/stm32wbaxx_hal_driver https://github.com/STMicroelectronics/stm32wbaxx-hal-driver.git 9442fbb71f855ff2e64fbf662b7726beba511a24 stm32wba hw/mcu/ti https://github.com/hathach/ti_driver.git 143ed6cc20a7615d042b03b21e070197d473e6e5 msp430 msp432e4 tm4c hw/mcu/wch/ch32f20x https://github.com/openwch/ch32f20x.git 77c4095087e5ed2c548ec9058e655d0b8757663b ch32f20x hw/mcu/wch/ch32v103 https://github.com/openwch/ch32v103.git 7578cae0b21f86dd053a1f781b2fc6ab99d0ec17 ch32v10x diff --git a/hw/bsp/stm32wba/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32wba/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..471d56aec --- /dev/null +++ b/hw/bsp/stm32wba/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,153 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "stm32wbaxx.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#if defined(__ARM_FP) && __ARM_FP >= 4 + #define configENABLE_FPU 1 +#else + #define configENABLE_FPU 0 +#endif +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 4 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1< + +#include "stm32wbaxx_hal.h" +#include "bsp/board_api.h" +#include "board.h" + + //--------------------------------------------------------------------+ + // MACRO TYPEDEF CONSTANT ENUM + //--------------------------------------------------------------------+ +#ifndef CFG_BOARD_UART_BAUDRATE +#define CFG_BOARD_UART_BAUDRATE 115200 +#endif + +#ifndef USART_TIMEOUT_TICKS +#define USART_TIMEOUT_TICKS 1000 +#endif + +static UART_HandleTypeDef uart_handle; + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB_OTG_HS_IRQHandler( void ) +{ + tud_int_handler( 0 ); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +static void board_gpio_configuration( void ) +{ + GPIO_InitTypeDef gpio_init = { 0 }; + + USART_GPIO_CLK_EN(); + USART_CLK_EN(); + + // Configure USART TX pin + gpio_init.Pin = USART_TX_PIN; + gpio_init.Mode = GPIO_MODE_AF_PP; + gpio_init.Pull = GPIO_NOPULL; + gpio_init.Speed = GPIO_SPEED_FREQ_HIGH; + gpio_init.Alternate = USART_GPIO_AF; + HAL_GPIO_Init( USART_TX_GPIO_PORT, &gpio_init ); + + // Configure USART RX pin + gpio_init.Pin = USART_RX_PIN; + gpio_init.Mode = GPIO_MODE_AF_PP; + gpio_init.Pull = GPIO_PULLUP; + gpio_init.Speed = GPIO_SPEED_FREQ_HIGH; + gpio_init.Alternate = USART_GPIO_AF; + HAL_GPIO_Init( USART_RX_GPIO_PORT, &gpio_init ); + + // Configure the LED + LED_CLK_EN(); + gpio_init.Pin = LED_PIN; + gpio_init.Mode = GPIO_MODE_OUTPUT_PP; + gpio_init.Pull = GPIO_PULLUP; + gpio_init.Speed = GPIO_SPEED_FREQ_LOW; + gpio_init.Alternate = 0; + HAL_GPIO_Init( LED_PORT, &gpio_init ); + + // Default LED state is off + board_led_write( false ); + + // Configure the button + BUTTON_CLK_EN(); + gpio_init.Pin = BUTTON_PIN; + gpio_init.Mode = GPIO_MODE_INPUT; + gpio_init.Pull = GPIO_PULLUP; + gpio_init.Speed = GPIO_SPEED_FREQ_LOW; + gpio_init.Alternate = 0; + HAL_GPIO_Init( BUTTON_PORT, &gpio_init ); + + // Configure USB DM and DP pins. This is optional, and maintained only for user guidance. + gpio_init.Pin = (GPIO_PIN_7 | GPIO_PIN_6); + gpio_init.Mode = GPIO_MODE_INPUT; + gpio_init.Pull = GPIO_NOPULL; + gpio_init.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init( GPIOD, &gpio_init ); +} + +static void board_uart_configuration( void ) +{ + uart_handle = ( UART_HandleTypeDef ) { + .Instance = USART_DEV, + .Init.BaudRate = CFG_BOARD_UART_BAUDRATE, + .Init.WordLength = UART_WORDLENGTH_8B, + .Init.StopBits = UART_STOPBITS_1, + .Init.Parity = UART_PARITY_NONE, + .Init.HwFlowCtl = UART_HWCONTROL_NONE, + .Init.Mode = UART_MODE_TX_RX, + .Init.OverSampling = UART_OVERSAMPLING_16 + }; + HAL_UART_Init( &uart_handle ); +} + +void board_init( void ) +{ + board_system_clock_config(); + board_gpio_configuration(); + board_uart_configuration(); + +#ifdef USB_OTG_HS + // STM32WBA65/64/62 only has 1 USB HS port + + #if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config( SystemCoreClock / 1000 ); + #elif CFG_TUSB_OS == OPT_OS_FREERTOS + // Explicitly disable systick to prevent its ISR runs before scheduler start + SysTick->CTRL &= ~1U; + + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority( OTG_HS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); + #endif + + // USB clock enable + __HAL_RCC_USB_OTG_HS_CLK_ENABLE(); + __HAL_RCC_USB_OTG_HS_PHY_CLK_ENABLE(); + + // See the reference manual section 11.4.7 for the USB OTG powering sequence + + // Remove the VDDUSB power isolation + PWR->SVMCR |= PWR_SVMCR_USV; + + // Enable VDD11USB supply by clearing VDD11USBDIS to 0 + PWR->VOSR &= ~PWR_VOSR_VDD11USBDIS; + + // Enable USB OTG internal power by setting USBPWREN to 1 + PWR->VOSR |= PWR_VOSR_USBPWREN; + + // Wait for VDD11USB supply to be ready in VDD11USBRDY = 1 + while ((PWR->VOSR & PWR_VOSR_VDD11USBRDY) == 0) {} + + // Enable USB OTG booster by setting USBBOOSTEN to 1 + PWR->VOSR |= PWR_VOSR_USBBOOSTEN; + + // Wait for USB OTG booster to be ready in USBBOOSTRDY = 1 + while ((PWR->VOSR & PWR_VOSR_USBBOOSTRDY) == 0) {} + + // Enable USB power on Pwrctrl CR2 register + PWR->SVMCR |= PWR_SVMCR_USV; + + // Set the reference clock selection (must match the clock source) + SYSCFG->OTGHSPHYCR &= ~SYSCFG_OTGHSPHYCR_CLKSEL; + SYSCFG->OTGHSPHYCR |= SYSCFG_OTGHSPHYCR_CLKSEL_0 | SYSCFG_OTGHSPHYCR_CLKSEL_1 | + SYSCFG_OTGHSPHYCR_CLKSEL_3; // 32MHz clock + + // Configuring the SYSCFG registers OTG_HS PHY + SYSCFG->OTGHSPHYCR |= SYSCFG_OTGHSPHYCR_EN; + + // Disable VBUS sense (B device) + USB_OTG_HS->GCCFG &= ~USB_OTG_GCCFG_VBDEN; + + // B-peripheral session valid override enable + USB_OTG_HS->GCCFG |= USB_OTG_GCCFG_VBVALEXTOEN; + USB_OTG_HS->GCCFG |= USB_OTG_GCCFG_VBVALOVAL; +#endif // USB_OTG_FS +} + +void board_led_write( bool state ) +{ + HAL_GPIO_WritePin( LED_PORT, LED_PIN, state ? LED_STATE_ON : ( 1 - LED_STATE_ON ) ); +} + +uint32_t board_button_read( void ) +{ + return HAL_GPIO_ReadPin( BUTTON_PORT, BUTTON_PIN ) == BUTTON_STATE_ACTIVE; +} + +int board_uart_read( uint8_t *buf, int len ) +{ + ( void ) buf; + ( void ) len; + return 0; +} + +int board_uart_write( void const *buf, int len ) +{ + ( void ) HAL_UART_Transmit( &uart_handle, ( const uint8_t * ) buf, len, USART_TIMEOUT_TICKS ); + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler( void ) +{ + HAL_IncTick(); + system_ticks++; +} + +uint32_t board_millis( void ) +{ + return system_ticks; +} +#endif + +void HardFault_Handler( void ) +{ + asm( "bkpt 1" ); +} + +// Required by __libc_init_array in startup code if we are compiling using -nostdlib/-nostartfiles. +void _init( void ); +void _init( void ) +{ } diff --git a/hw/bsp/stm32wba/family.mk b/hw/bsp/stm32wba/family.mk new file mode 100644 index 000000000..ca6459ab2 --- /dev/null +++ b/hw/bsp/stm32wba/family.mk @@ -0,0 +1,59 @@ +UF2_FAMILY_ID = 0x70d16657 +ST_FAMILY = wba + +ST_PREFIX = stm32${ST_FAMILY}xx +ST_CMSIS = hw/mcu/st/cmsis_device_$(ST_FAMILY) +ST_HAL_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx_hal_driver + +include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= cortex-m33 + +CFLAGS += \ + -DCFG_TUSB_MCU=OPT_MCU_STM32WBA + +CFLAGS_GCC += \ + -flto \ + -nostdlib -nostartfiles \ + -Wno-error=cast-align -Wno-unused-parameter + +LDFLAGS_GCC += -specs=nosys.specs -specs=nano.specs -Wl,--gc-sections + +SRC_C += \ + src/portable/synopsys/dwc2/dcd_dwc2.c \ + src/portable/synopsys/dwc2/hcd_dwc2.c \ + src/portable/synopsys/dwc2/dwc2_common.c \ + $(ST_CMSIS)/Source/Templates/system_${ST_PREFIX}.c \ + $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal.c \ + $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_cortex.c \ + $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_icache.c \ + $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_pwr.c \ + $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_pwr_ex.c \ + $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_rcc.c \ + $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_rcc_ex.c \ + $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_uart.c \ + $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_gpio.c \ + $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_pcd.c \ + $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal_pcd_ex.c \ + $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_ll_usb.c \ + $(ST_HAL_DRIVER)/Src/${ST_PREFIX}_hal.c + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/$(BOARD_PATH)/include \ + $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_HAL_DRIVER)/Inc + +# STM32WBA HAL uses uppercase MCU_VARIANT (excluding the x's) for linking and lowercase MCU_VARIANT for startup. +UPPERCASE_MCU_VARIANT = $(shell echo $(MCU_VARIANT) | sed 's/\([^x]\)/\U\1/g') + +# Startup - Manually specify lowercase version for startup file +SRC_S_GCC += $(ST_CMSIS)/Source/Templates/gcc/startup_$(MCU_VARIANT).s +SRC_S_IAR += $(ST_CMSIS)/Source/Templates/iar/startup_$(MCU_VARIANT).s + +# Linker +LD_FILE_GCC ?= ${ST_CMSIS}/Source/Templates/gcc/linker/${UPPERCASE_MCU_VARIANT}_FLASH_ns.ld +LD_FILE_IAR ?= $(ST_CMSIS)/Source/Templates/iar/linker/$(MCU_VARIANT)_flash_cm33.icf + +# flash target using on-board stlink +flash: flash-stlink \ No newline at end of file diff --git a/hw/bsp/stm32wba/stm32wbaxx_hal_conf.h b/hw/bsp/stm32wba/stm32wbaxx_hal_conf.h new file mode 100644 index 000000000..f4e49f341 --- /dev/null +++ b/hw/bsp/stm32wba/stm32wbaxx_hal_conf.h @@ -0,0 +1,367 @@ +/** + ****************************************************************************** + * @file stm32wbaxx_hal_conf_template.h + * @author MCD Application Team + * @brief HAL configuration template file. + * This file should be copied to the application folder and renamed + * to stm32wbaxx_hal_conf.h. + ****************************************************************************** + * @attention + * + * Copyright (c) 2022 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the LICENSE file + * in the root directory of this software component. + * If no LICENSE file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32WBAxx_HAL_CONF_H +#define STM32WBAxx_HAL_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +// #define HAL_ADC_MODULE_ENABLED +// #define HAL_COMP_MODULE_ENABLED +#define HAL_CORTEX_MODULE_ENABLED +// #define HAL_CRC_MODULE_ENABLED +// #define HAL_CRYP_MODULE_ENABLED +#define HAL_DMA_MODULE_ENABLED +#define HAL_EXTI_MODULE_ENABLED +#define HAL_FLASH_MODULE_ENABLED +#define HAL_GPIO_MODULE_ENABLED +#define HAL_GTZC_MODULE_ENABLED +#define HAL_HASH_MODULE_ENABLED +#define HAL_HCD_MODULE_ENABLED +#define HAL_HSEM_MODULE_ENABLED +// #define HAL_I2C_MODULE_ENABLED +#define HAL_ICACHE_MODULE_ENABLED +// #define HAL_IRDA_MODULE_ENABLED +// #define HAL_IWDG_MODULE_ENABLED +// #define HAL_LPTIM_MODULE_ENABLED +#define HAL_PCD_MODULE_ENABLED +// #define HAL_PKA_MODULE_ENABLED +#define HAL_PWR_MODULE_ENABLED +#define HAL_RAMCFG_MODULE_ENABLED +#define HAL_RCC_MODULE_ENABLED +// #define HAL_RNG_MODULE_ENABLED +// #define HAL_RTC_MODULE_ENABLED +// #define HAL_SAI_MODULE_ENABLED +// #define HAL_SMARTCARD_MODULE_ENABLED +// #define HAL_SMBUS_MODULE_ENABLED +#define HAL_SPI_MODULE_ENABLED +#define HAL_TIM_MODULE_ENABLED +// #define HAL_TSC_MODULE_ENABLED +#define HAL_UART_MODULE_ENABLED +#define HAL_USART_MODULE_ENABLED +// #define HAL_WWDG_MODULE_ENABLED +// #define HAL_XSPI_MODULE_ENABLED + +/* ########################## Oscillator Values adaptation ####################*/ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) +#define HSE_VALUE 32000000UL /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) +#define HSE_STARTUP_TIMEOUT 100UL /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) +#define HSI_VALUE 16000000UL /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) +#define LSI_VALUE 32000UL /*!< LSI Typical Value in Hz*/ +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations in voltage + and temperature.*/ + +#if defined (RCC_LSI2_SUPPORT) +#if !defined (LSI2_VALUE) +#define LSI2_VALUE 32000UL /*!< LSI2 Typical Value in Hz*/ +#endif /* LSI2_VALUE */ +#endif + +/** + * @brief External Low Speed oscillator (LSE) value. + * This value is used by the UART, RTC HAL module to compute the system frequency + */ +#if !defined (LSE_VALUE) +#define LSE_VALUE 32768UL /*!< Value of the External oscillator in Hz*/ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) +#define LSE_STARTUP_TIMEOUT 5000UL /*!< Time out for LSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for SAI1 peripheral + * This value is used by the RCC HAL module to compute the SAI1 & SAI2 clock source + * frequency. + */ +#if !defined (EXTERNAL_SAI1_CLOCK_VALUE) +#define EXTERNAL_SAI1_CLOCK_VALUE 48000UL /*!< Value of the SAI1 External clock source in Hz*/ +#endif /* EXTERNAL_SAI1_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE 3300UL /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY ((1UL<<__NVIC_PRIO_BITS) - 1UL) /*!< tick interrupt priority (lowest by default) */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U /*!< Enable prefetch */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Register callback feature configuration ############### */ +/** + * @brief Set below the peripheral configuration to "1U" to add the support + * of HAL callback registration/unregistration feature for the HAL + * driver(s). This allows user application to provide specific callback + * functions thanks to HAL_PPP_RegisterCallback() rather than overwriting + * the default weak callback functions (see each stm32wbaxx_hal_ppp.h file + * for possible callback identifiers defined in HAL_PPP_CallbackIDTypeDef + * for each PPP peripheral). + */ +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U /* COMP register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_IWDG_REGISTER_CALLBACKS 0U /* IWDG register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_PKA_REGISTER_CALLBACKS 0U /* PKA register callback disabled */ +#define USE_HAL_RAMCFG_REGISTER_CALLBACKS 0U /* RAMCFG register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_TSC_REGISTER_CALLBACKS 0U /* TSC register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ +#define USE_HAL_XSPI_REGISTER_CALLBACKS 0U /* XSPI register callback disabled */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver + * Activated: CRC code is present inside driver + * Deactivated: CRC code cleaned from driver + */ +#define USE_SPI_CRC 1U + +/* ################## CRYP peripheral configuration ########################## */ + +#define USE_HAL_CRYP_SUSPEND_RESUME 0U + +/* ################## HASH peripheral configuration ########################## */ + +#define USE_HAL_HASH_SUSPEND_RESUME 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ +#ifdef HAL_DMA_MODULE_ENABLED +#include "stm32wbaxx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_RCC_MODULE_ENABLED +#include "stm32wbaxx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED +#include "stm32wbaxx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_COMP_MODULE_ENABLED +#include "stm32wbaxx_hal_comp.h" +#endif /* HAL_COMP_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED +#include "stm32wbaxx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED +#include "stm32wbaxx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED +#include "stm32wbaxx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED +#include "stm32wbaxx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED +#include "stm32wbaxx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED +#include "stm32wbaxx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_GTZC_MODULE_ENABLED +#include "stm32wbaxx_hal_gtzc.h" +#endif /* HAL_GTZC_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED +#include "stm32wbaxx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED +#include "stm32wbaxx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_HSEM_MODULE_ENABLED +#include "stm32wbaxx_hal_hsem.h" +#endif /* HAL_HSEM_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED +#include "stm32wbaxx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_ICACHE_MODULE_ENABLED +#include "stm32wbaxx_hal_icache.h" +#endif /* HAL_ICACHE_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED +#include "stm32wbaxx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED +#include "stm32wbaxx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED +#include "stm32wbaxx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED +#include "stm32wbaxx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_PKA_MODULE_ENABLED +#include "stm32wbaxx_hal_pka.h" +#endif /* HAL_PKA_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED +#include "stm32wbaxx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RAMCFG_MODULE_ENABLED +#include "stm32wbaxx_hal_ramcfg.h" +#endif /* HAL_RAMCFG_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED +#include "stm32wbaxx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED +#include "stm32wbaxx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED +#include "stm32wbaxx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED +#include "stm32wbaxx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED +#include "stm32wbaxx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED +#include "stm32wbaxx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED +#include "stm32wbaxx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_TSC_MODULE_ENABLED +#include "stm32wbaxx_hal_tsc.h" +#endif /* HAL_TSC_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED +#include "stm32wbaxx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED +#include "stm32wbaxx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED +#include "stm32wbaxx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_XSPI_MODULE_ENABLED +#include "stm32wbaxx_hal_xspi.h" +#endif /* HAL_XSPI_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr: If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ +#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ +void assert_failed(uint8_t *file, uint32_t line); +#else +#define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + +#ifdef __cplusplus +} +#endif + +#endif /* STM32WBAxx_HAL_CONF_H */ diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 3ffc2d1a4..7722ca1e6 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -295,6 +295,12 @@ #define TUP_USBIP_FSDEV_STM32 #define TUP_DCD_ENDPOINT_MAX 8 +#elif TU_CHECK_MCU(OPT_MCU_STM32WBA) + #define TUP_USBIP_DWC2 + #define TUP_USBIP_DWC2_STM32 + #define TUP_DCD_ENDPOINT_MAX 9 + #define TUP_RHPORT_HIGHSPEED 1 + #elif TU_CHECK_MCU(OPT_MCU_STM32U5) #if defined (STM32U535xx) || defined (STM32U545xx) #define TUP_USBIP_FSDEV diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index ccf31e035..01baf50ae 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -148,6 +148,12 @@ /* ST provided header has incorrect value of USB_PMAADDR */ #define FSDEV_PMA_BASE USB1_PMAADDR +#elif defined(STM32WBA62xx) || defined(STM32WBA64xx) || defined(STM32WBA65xx) + // Available only on STM32WBA62/64/65xx devices + #include "stm32wbaxx.h" + #define FSDEV_PMA_SIZE (2048u) + #define USB USB_DRD_FS + #elif CFG_TUSB_MCU == OPT_MCU_STM32L4 #include "stm32l4xx.h" #define FSDEV_PMA_SIZE (1024u) @@ -289,6 +295,8 @@ static const IRQn_Type fsdev_irq[] = { USB_LP_IRQn, #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 USB_IRQn, + #elif CFG_TUSB_MCU == OPT_MCU_STM32WBA + USB_OTG_HS_IRQn, #elif CFG_TUSB_MCU == OPT_MCU_STM32U0 USB_DRD_FS_IRQn, #else diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c index d7d157149..f81cfceda 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.c +++ b/src/portable/synopsys/dwc2/dwc2_common.c @@ -49,6 +49,11 @@ static void reset_core(dwc2_regs_t* dwc2) { uint32_t gsnpsid = dwc2->gsnpsid; // reset core + + // On the STM32WBA peripheral, the device seems to get stuck in reset unless + // this shadow register is utilized. + uint32_t gsnpsid = dwc2->gsnpsid; + dwc2->grstctl |= GRSTCTL_CSRST; if ((gsnpsid & DWC2_CORE_REV_MASK) < (DWC2_CORE_REV_4_20a & DWC2_CORE_REV_MASK)) { diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index 672891561..ca5ce5a7c 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -113,6 +113,22 @@ extern "C" { #define EP_MAX_HS 9 #define EP_FIFO_SIZE_HS 4096 #endif + +#elif CFG_TUSB_MCU == OPT_MCU_STM32WBA + #if defined(STM32WBA62xx) + #include "stm32wba62xx.h" + #elif defined(STM32WBA64xx) + #include "stm32wba64xx.h" + #elif defined(STM32WBA65xx) + #include "stm32wba65xx.h" + #else + #error "The selected STM32WBA series chip does not support OTG USB HS" + #endif + + #define USB_OTG_HS_PERIPH_BASE USB_OTG_HS_BASE_NS + #define OTG_HS_IRQn USB_OTG_HS_IRQn + #define EP_MAX_HS 9 + #define EP_FIFO_SIZE_HS 4096 #else #error "Unsupported MCUs" #endif @@ -166,6 +182,7 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_remote_wakeup_delay(void) { // MCU specific PHY init, called BEFORE core reset // - dwc2 3.30a (H5) use USB_HS_PHYC // - dwc2 4.11a (U5) use femtoPHY +// - dwc2 x.xxx (WBA) use USB_OTG_HS static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { if (hs_phy_type == GHWCFG2_HSPHY_NOT_SUPPORTED) { // Enable on-chip FS PHY @@ -194,11 +211,10 @@ static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { #endif } else { -#if CFG_TUSB_MCU != OPT_MCU_STM32U5 +#if CFG_TUSB_MCU != OPT_MCU_STM32U5 && CFG_TUSB_MCU != OPT_MCU_STM32WBA // Disable FS PHY, TODO on U5A5 (dwc2 4.11a) 16th bit is 'Host CDP behavior enable' dwc2->stm32_gccfg &= ~STM32_GCCFG_PWRDWN; #endif - // Enable on-chip HS PHY if (hs_phy_type == GHWCFG2_HSPHY_UTMI || hs_phy_type == GHWCFG2_HSPHY_UTMI_ULPI) { #ifdef USB_HS_PHYC @@ -233,11 +249,14 @@ static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { // Enable PLL internal PHY USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN; +<<<<<<< HEAD // Wait ~2ms until the PLL is ready (there's no RDY bit to query) tusb_time_delay_ms_api(2); #else +======= +>>>>>>> 246a92c65 (It worksgit status!) #endif } } diff --git a/src/tusb_option.h b/src/tusb_option.h index 1533bb209..b2dd5fcb2 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -95,6 +95,7 @@ #define OPT_MCU_STM32H7RS 317 ///< ST F7RS #define OPT_MCU_STM32C0 318 ///< ST C0 #define OPT_MCU_STM32N6 319 ///< ST N6 +#define OPT_MCU_STM32WBA 320 ///< ST WBA // Sony #define OPT_MCU_CXD56 400 ///< SONY CXD56 diff --git a/tools/get_deps.py b/tools/get_deps.py index 36b4d2d59..37d541785 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -130,6 +130,9 @@ deps_optional = { 'hw/mcu/st/cmsis_device_wb': ['https://github.com/STMicroelectronics/cmsis_device_wb.git', 'cda2cb9fc4a5232ab18efece0bb06b0b60910083', 'stm32wb'], + 'hw/mcu/st/cmsis_device_wba': ['https://github.com/STMicroelectronics/cmsis-device-wba', + '647d8522e5fd15049e9a1cc30ed19d85e5911eaf', + 'stm32wba'], 'hw/mcu/st/stm32-mfxstm32l152': ['https://github.com/STMicroelectronics/stm32-mfxstm32l152.git', '7f4389efee9c6a655b55e5df3fceef5586b35f9b', 'stm32h7'], @@ -193,6 +196,9 @@ deps_optional = { 'hw/mcu/st/stm32wbxx_hal_driver': ['https://github.com/STMicroelectronics/stm32wbxx_hal_driver.git', 'd60dd46996876506f1d2e9abd6b1cc110c8004cd', 'stm32wb'], + 'hw/mcu/st/stm32wbaxx_hal_driver': ['https://github.com/STMicroelectronics/stm32wbaxx_hal_driver.git', + '9442fbb71f855ff2e64fbf662b7726beba511a24', + 'stm32wba'], 'hw/mcu/ti': ['https://github.com/hathach/ti_driver.git', '143ed6cc20a7615d042b03b21e070197d473e6e5', 'msp430 msp432e4 tm4c'], -- cgit v1.3.1 From 48f6b95bd8b0c3d33832f289b02b53da410d5ef9 Mon Sep 17 00:00:00 2001 From: Dalton Caron Date: Tue, 9 Sep 2025 15:41:12 -0700 Subject: Incorporate upstream changes to dwc2_common.c --- src/portable/synopsys/dwc2/dwc2_common.c | 29 ++++++++++++----------------- 1 file changed, 12 insertions(+), 17 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c index f81cfceda..9b8333ad2 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.c +++ b/src/portable/synopsys/dwc2/dwc2_common.c @@ -49,11 +49,6 @@ static void reset_core(dwc2_regs_t* dwc2) { uint32_t gsnpsid = dwc2->gsnpsid; // reset core - - // On the STM32WBA peripheral, the device seems to get stuck in reset unless - // this shadow register is utilized. - uint32_t gsnpsid = dwc2->gsnpsid; - dwc2->grstctl |= GRSTCTL_CSRST; if ((gsnpsid & DWC2_CORE_REV_MASK) < (DWC2_CORE_REV_4_20a & DWC2_CORE_REV_MASK)) { @@ -100,14 +95,6 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2}; const dwc2_ghwcfg4_t ghwcfg4 = {.value = dwc2->ghwcfg4}; - uint8_t phy_width; - if (CFG_TUSB_MCU != OPT_MCU_AT32F402_405 && // at32f402_405 does not support 16-bit - ghwcfg4.phy_data_width) { - phy_width = 16; // 16-bit PHY interface if supported - } else { - phy_width = 8; // 8-bit PHY interface - } - // De-select FS PHY gusbcfg &= ~GUSBCFG_PHYSEL; @@ -135,10 +122,12 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { gusbcfg &= ~GUSBCFG_ULPI_UTMI_SEL; // Set 16-bit interface if supported - if (phy_width == 16) { - gusbcfg |= GUSBCFG_PHYIF16; + if (ghwcfg4.phy_data_width) { + #if CFG_TUSB_MCU != OPT_MCU_AT32F402_405 // at32f402_405 does not actually support 16-bit + gusbcfg |= GUSBCFG_PHYIF16; // 16 bit + #endif } else { - gusbcfg &= ~GUSBCFG_PHYIF16; + gusbcfg &= ~GUSBCFG_PHYIF16; // 8 bit } } @@ -155,7 +144,13 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { // - 9 if using 8-bit PHY interface // - 5 if using 16-bit PHY interface gusbcfg &= ~GUSBCFG_TRDT_Msk; - gusbcfg |= (phy_width == 16 ? 5u : 9u) << GUSBCFG_TRDT_Pos; + +#if CFG_TUSB_MCU == OPT_MCU_AT32F402_405 // at32f402_405 does not actually support 16-bit + gusbcfg |= 9u << GUSBCFG_TRDT_Pos; +#else + gusbcfg |= (dwc2->ghwcfg4_bm.phy_data_width ? 5u : 9u) << GUSBCFG_TRDT_Pos; +#endif + dwc2->gusbcfg = gusbcfg; // MCU specific PHY update post reset -- cgit v1.3.1 From c9527bc0964dcd883df7ec485e2d71333ed780c0 Mon Sep 17 00:00:00 2001 From: Dalton Caron Date: Wed, 10 Sep 2025 11:14:52 -0700 Subject: Bring up to date with master --- src/portable/synopsys/dwc2/dwc2_stm32.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dwc2_stm32.h b/src/portable/synopsys/dwc2/dwc2_stm32.h index ca5ce5a7c..08950ccc0 100644 --- a/src/portable/synopsys/dwc2/dwc2_stm32.h +++ b/src/portable/synopsys/dwc2/dwc2_stm32.h @@ -249,14 +249,11 @@ static inline void dwc2_phy_init(dwc2_regs_t* dwc2, uint8_t hs_phy_type) { // Enable PLL internal PHY USB_HS_PHYC->USB_HS_PHYC_PLL |= USB_HS_PHYC_PLL_PLLEN; -<<<<<<< HEAD // Wait ~2ms until the PLL is ready (there's no RDY bit to query) tusb_time_delay_ms_api(2); #else -======= ->>>>>>> 246a92c65 (It worksgit status!) #endif } } -- cgit v1.3.1 From 5e661eac8809f3bfdafd357d00013d94b71b4000 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 11 Sep 2025 10:57:02 +0700 Subject: Revert "Incorporate upstream changes to dwc2_common.c" This reverts commit 48f6b95bd8b0c3d33832f289b02b53da410d5ef9. also revert gsnpsid shadown since it is already in the upstream --- src/portable/synopsys/dwc2/dwc2_common.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c index 9b8333ad2..d7d157149 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.c +++ b/src/portable/synopsys/dwc2/dwc2_common.c @@ -95,6 +95,14 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { const dwc2_ghwcfg2_t ghwcfg2 = {.value = dwc2->ghwcfg2}; const dwc2_ghwcfg4_t ghwcfg4 = {.value = dwc2->ghwcfg4}; + uint8_t phy_width; + if (CFG_TUSB_MCU != OPT_MCU_AT32F402_405 && // at32f402_405 does not support 16-bit + ghwcfg4.phy_data_width) { + phy_width = 16; // 16-bit PHY interface if supported + } else { + phy_width = 8; // 8-bit PHY interface + } + // De-select FS PHY gusbcfg &= ~GUSBCFG_PHYSEL; @@ -122,12 +130,10 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { gusbcfg &= ~GUSBCFG_ULPI_UTMI_SEL; // Set 16-bit interface if supported - if (ghwcfg4.phy_data_width) { - #if CFG_TUSB_MCU != OPT_MCU_AT32F402_405 // at32f402_405 does not actually support 16-bit - gusbcfg |= GUSBCFG_PHYIF16; // 16 bit - #endif + if (phy_width == 16) { + gusbcfg |= GUSBCFG_PHYIF16; } else { - gusbcfg &= ~GUSBCFG_PHYIF16; // 8 bit + gusbcfg &= ~GUSBCFG_PHYIF16; } } @@ -144,13 +150,7 @@ static void phy_hs_init(dwc2_regs_t* dwc2) { // - 9 if using 8-bit PHY interface // - 5 if using 16-bit PHY interface gusbcfg &= ~GUSBCFG_TRDT_Msk; - -#if CFG_TUSB_MCU == OPT_MCU_AT32F402_405 // at32f402_405 does not actually support 16-bit - gusbcfg |= 9u << GUSBCFG_TRDT_Pos; -#else - gusbcfg |= (dwc2->ghwcfg4_bm.phy_data_width ? 5u : 9u) << GUSBCFG_TRDT_Pos; -#endif - + gusbcfg |= (phy_width == 16 ? 5u : 9u) << GUSBCFG_TRDT_Pos; dwc2->gusbcfg = gusbcfg; // MCU specific PHY update post reset -- cgit v1.3.1 From af7310b925c031d23ba490e8f70965f345da1a4d Mon Sep 17 00:00:00 2001 From: Dalton Caron Date: Thu, 11 Sep 2025 09:13:54 -0700 Subject: Revert fsdev_stm32.h changes --- src/portable/st/stm32_fsdev/fsdev_stm32.h | 8 -------- 1 file changed, 8 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index 01baf50ae..ccf31e035 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -148,12 +148,6 @@ /* ST provided header has incorrect value of USB_PMAADDR */ #define FSDEV_PMA_BASE USB1_PMAADDR -#elif defined(STM32WBA62xx) || defined(STM32WBA64xx) || defined(STM32WBA65xx) - // Available only on STM32WBA62/64/65xx devices - #include "stm32wbaxx.h" - #define FSDEV_PMA_SIZE (2048u) - #define USB USB_DRD_FS - #elif CFG_TUSB_MCU == OPT_MCU_STM32L4 #include "stm32l4xx.h" #define FSDEV_PMA_SIZE (1024u) @@ -295,8 +289,6 @@ static const IRQn_Type fsdev_irq[] = { USB_LP_IRQn, #elif CFG_TUSB_MCU == OPT_MCU_STM32U5 USB_IRQn, - #elif CFG_TUSB_MCU == OPT_MCU_STM32WBA - USB_OTG_HS_IRQn, #elif CFG_TUSB_MCU == OPT_MCU_STM32U0 USB_DRD_FS_IRQn, #else -- cgit v1.3.1 From 5755afa690f242988c02932068339ad5ffc4404e Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 12 Sep 2025 11:39:41 +0200 Subject: Fix some IAR warnings Signed-off-by: HiFiPhile --- src/class/hid/hid_host.c | 3 ++- src/host/usbh.c | 29 +++++++++++++++-------------- src/portable/ehci/ehci.c | 5 +++-- 3 files changed, 20 insertions(+), 17 deletions(-) (limited to 'src/portable') diff --git a/src/class/hid/hid_host.c b/src/class/hid/hid_host.c index 56fccdd22..a44c83433 100644 --- a/src/class/hid/hid_host.c +++ b/src/class/hid/hid_host.c @@ -519,7 +519,8 @@ bool hidh_open(uint8_t rhport, uint8_t daddr, tusb_desc_interface_t const* desc_ // Assume bNumDescriptors = 1 p_hid->report_desc_type = desc_hid->bReportType; - p_hid->report_desc_len = tu_unaligned_read16(&desc_hid->wReportLength); + // Use offsetof to avoid pointer to the odd/misaligned address + p_hid->report_desc_len = tu_unaligned_read16((uint8_t const*)desc_hid + offsetof(tusb_hid_descriptor_hid_t, wReportLength)); // Per HID Specs: default is Report protocol, though we will force Boot protocol when set_config p_hid->protocol_mode = _hidh_default_protocol; diff --git a/src/host/usbh.c b/src/host/usbh.c index ce83977c5..1c63ac712 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -400,7 +400,7 @@ bool tuh_descriptor_get_device_local(uint8_t daddr, tusb_desc_device_t* desc_dev tusb_speed_t tuh_speed_get(uint8_t daddr) { tuh_bus_info_t bus_info; tuh_bus_info_get(daddr, &bus_info); - return bus_info.speed; + return (tusb_speed_t)bus_info.speed; } bool tuh_rhport_is_active(uint8_t rhport) { @@ -651,7 +651,7 @@ void tuh_task_ext(uint32_t timeout_ms, bool in_isr) { tuh_xfer_t xfer = { .daddr = event.dev_addr, .ep_addr = ep_addr, - .result = event.xfer_complete.result, + .result = (xfer_result_t)event.xfer_complete.result, .actual_len = event.xfer_complete.len, .buflen = 0, // not available .buffer = NULL, // not available @@ -832,18 +832,19 @@ static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t } TU_ATTR_FALLTHROUGH; - case CONTROL_STAGE_DATA: - if (request->wLength) { - TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, daddr); - TU_LOG_MEM_USBH(ctrl_info->buffer, xferred_bytes, 2); - } - ctrl_info->actual_len = (uint16_t) xferred_bytes; - - // ACK stage: toggle is always 1 - _control_set_xfer_stage(CONTROL_STAGE_ACK); - const uint8_t ep_status = tu_edpt_addr(0, 1 - request->bmRequestType_bit.direction); - TU_ASSERT(hcd_edpt_xfer(rhport, daddr, ep_status, NULL, 0)); - break; + case CONTROL_STAGE_DATA: { + if (request->wLength) { + TU_LOG_USBH("[%u:%u] Control data:\r\n", rhport, daddr); + TU_LOG_MEM_USBH(ctrl_info->buffer, xferred_bytes, 2); + } + ctrl_info->actual_len = (uint16_t) xferred_bytes; + + // ACK stage: toggle is always 1 + _control_set_xfer_stage(CONTROL_STAGE_ACK); + const uint8_t ep_status = tu_edpt_addr(0, 1 - request->bmRequestType_bit.direction); + TU_ASSERT(hcd_edpt_xfer(rhport, daddr, ep_status, NULL, 0)); + break; + } case CONTROL_STAGE_ACK: { // Abort all pending transfers if SET_CONFIGURATION request diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index da9f49d29..b372fe635 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -184,7 +184,8 @@ static void ehci_enable_schedule(ehci_registers_t* regs, bool is_period) { //--------------------------------------------------------------------+ uint32_t hcd_frame_number(uint8_t rhport) { (void) rhport; - return (ehci_data.uframe_number + ehci_data.regs->frame_index) >> 3; + uint32_t uframe = ehci_data.regs->frame_index; + return (ehci_data.uframe_number + uframe) >> 3; } void hcd_port_reset(uint8_t rhport) { @@ -896,7 +897,7 @@ static void qhd_init(ehci_qhd_t *p_qhd, uint8_t dev_addr, tusb_desc_endpoint_t c p_qhd->used = 1; p_qhd->removing = 0; p_qhd->attached_qtd = NULL; - p_qhd->pid = tu_edpt_dir(ep_desc->bEndpointAddress) ? EHCI_PID_IN : EHCI_PID_OUT; // PID for TD under this endpoint + p_qhd->pid = tu_edpt_dir(ep_desc->bEndpointAddress) == TUSB_DIR_IN ? EHCI_PID_IN : EHCI_PID_OUT; // PID for TD under this endpoint //------------- active, but no TD list -------------// p_qhd->qtd_overlay.halted = 0; -- cgit v1.3.1 From 4db2bdad07f55b03df8c40928a2b56536fa823e3 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 12 Sep 2025 14:08:54 +0200 Subject: echi: fix NXP USBPHY disconnection detection Signed-off-by: HiFiPhile --- src/portable/ehci/ehci.c | 60 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 52 insertions(+), 8 deletions(-) (limited to 'src/portable') diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index b372fe635..76b0142b2 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -38,6 +38,11 @@ #include "ehci_api.h" #include "ehci.h" +// NXP specific fixes +#if TU_CHECK_MCU(OPT_MCU_MIMXRT1XXX, OPT_MCU_LPC55, OPT_MCU_MCXN9) +#include "fsl_device_registers.h" +#endif + //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ @@ -179,6 +184,36 @@ static void ehci_enable_schedule(ehci_registers_t* regs, bool is_period) { } } +#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) +static void nxp_usbphy_disconn_detector_set(uint8_t port, bool enable) { + // unify naming convention +#if !defined(USBPHY1) && defined(USBPHY) + #define USBPHY1 USBPHY +#endif + + if (port == 0) { + if (enable) { + USBPHY1->CTRL_SET = USBPHY_CTRL_ENHOSTDISCONDETECT_MASK; + } else { + USBPHY1->CTRL_CLR = USBPHY_CTRL_ENHOSTDISCONDETECT_MASK; + } + } +#if FSL_FEATURE_SOC_USBPHY_COUNT > 1U + else if (port == 1) { + if (enable) { + USBPHY2->CTRL_SET = USBPHY_CTRL_ENHOSTDISCONDETECT_MASK; + } else { + USBPHY2->CTRL_CLR = USBPHY_CTRL_ENHOSTDISCONDETECT_MASK; + } + } +#endif + +#if !defined(USBPHY1) && defined(USBPHY) + #undef USBPHY1 +#endif +} +#endif + //--------------------------------------------------------------------+ // HCD API //--------------------------------------------------------------------+ @@ -213,16 +248,21 @@ void hcd_port_reset_end(uint8_t rhport) { (void) rhport; ehci_registers_t* regs = ehci_data.regs; - // skip if reset is already complete - if (!regs->portsc_bm.port_reset) { - return; - } + // stop reset only if is not complete yet + if (regs->portsc_bm.port_reset) { + // mask out all change bits since they are Write 1 to clear + uint32_t portsc = regs->portsc & ~EHCI_PORTSC_MASK_W1C; + portsc &= ~EHCI_PORTSC_MASK_PORT_RESET; - // mask out all change bits since they are Write 1 to clear - uint32_t portsc = regs->portsc & ~EHCI_PORTSC_MASK_W1C; - portsc &= ~EHCI_PORTSC_MASK_PORT_RESET; + regs->portsc = portsc; + } - regs->portsc = portsc; +#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) + // Enable disconnect detector for highspeed device only + if (hcd_port_speed_get(rhport) == TUSB_SPEED_HIGH) { + nxp_usbphy_disconn_detector_set(rhport, true); + } +#endif } bool hcd_port_connect_status(uint8_t rhport) { @@ -579,6 +619,10 @@ void port_connect_status_change_isr(uint8_t rhport) { hcd_event_device_attach(rhport, true); } else // device unplugged { +#if ((defined FSL_FEATURE_SOC_USBPHY_COUNT) && (FSL_FEATURE_SOC_USBPHY_COUNT > 0U)) + // Disable disconnect detector + nxp_usbphy_disconn_detector_set(rhport, false); +#endif hcd_event_device_remove(rhport, true); } } -- cgit v1.3.1 From 99bee6a900db60cf232766531e785108f50e614d Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 12 Sep 2025 14:25:44 +0200 Subject: ehci: fix removed qhd get reused Signed-off-by: HiFiPhile --- src/host/usbh.c | 2 +- src/portable/ehci/ehci.c | 14 +++++++++++--- 2 files changed, 12 insertions(+), 4 deletions(-) (limited to 'src/portable') diff --git a/src/host/usbh.c b/src/host/usbh.c index 1c63ac712..d09874d6e 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -844,7 +844,7 @@ static bool usbh_control_xfer_cb (uint8_t daddr, uint8_t ep_addr, xfer_result_t const uint8_t ep_status = tu_edpt_addr(0, 1 - request->bmRequestType_bit.direction); TU_ASSERT(hcd_edpt_xfer(rhport, daddr, ep_status, NULL, 0)); break; - } + } case CONTROL_STAGE_ACK: { // Abort all pending transfers if SET_CONFIGURATION request diff --git a/src/portable/ehci/ehci.c b/src/portable/ehci/ehci.c index 76b0142b2..953483583 100644 --- a/src/portable/ehci/ehci.c +++ b/src/portable/ehci/ehci.c @@ -35,6 +35,7 @@ #include "host/hcd.h" #include "host/usbh.h" +#include "host/usbh_pvt.h" #include "ehci_api.h" #include "ehci.h" @@ -866,14 +867,21 @@ static ehci_qhd_t *qhd_get_from_addr(uint8_t dev_addr, uint8_t ep_addr) { } ehci_qhd_t *qhd_pool = ehci_data.qhd_pool; + + // protect qhd_pool since 'used' and 'removing' can be changed in isr + ehci_qhd_t *result = NULL; + usbh_spin_lock(false); for (uint32_t i = 0; i < QHD_MAX; i++) { if ((qhd_pool[i].dev_addr == dev_addr) && - ep_addr == qhd_ep_addr(&qhd_pool[i])) { - return &qhd_pool[i]; + ep_addr == qhd_ep_addr(&qhd_pool[i]) && + qhd_pool[i].used && !qhd_pool[i].removing) { + result = &qhd_pool[i]; + break; } } + usbh_spin_unlock(false); - return NULL; + return result; } // Init queue head with endpoint descriptor -- cgit v1.3.1 From 8515e47ad9980f8ad380913bda72425b1bb83648 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 12 Sep 2025 16:49:55 +0200 Subject: Update comment Signed-off-by: HiFiPhile --- src/portable/st/stm32_fsdev/fsdev_stm32.h | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index 770baa05a..95f40269a 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -268,7 +268,10 @@ #endif #ifndef CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP - // Defaults to double-buffered isochronous endpoints on devices with >1KB PMA + // Default configuration for double-buffered isochronous endpoints: + // - Enable double buffering on devices with >1KB Packet Memory Area (PMA) + // to improve isochronous transfer reliability and performance + // - Disable on devices with limited PMA to conserve memory space #if FSDEV_PMA_SIZE > 1024u #define CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP 1 #else @@ -277,12 +280,16 @@ #endif #if FSDEV_HAS_SBUF_ISO != 0 && CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP == 0 - // If hardware has SBUF_ISO bit single-buffered endpoints consume only - // one half of endpoint pair register. + // SBUF_ISO configuration: + // - Some STM32 devices have special hardware support for single-buffered isochronous endpoints + // - When SBUF_ISO bit is available and double buffering is disabled: + // Enable SBUF_ISO to optimize endpoint register usage (one half of endpoint pair register) #define FSDEV_USE_SBUF_ISO 1 #else - // Otherwise it consumes entire endpoint pair but we can at least save - // memory by configuring the same buffer twice. + // When either: + // - Hardware doesn't support SBUF_ISO feature, or + // - Double buffering is enabled for isochronous endpoints + // We must use the entire endpoint pair register #define FSDEV_USE_SBUF_ISO 0 #endif -- cgit v1.3.1 From cf6cbf0d1aca1985dcc8d1b88279028ec044e7a8 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Fri, 12 Sep 2025 21:30:53 +0200 Subject: Fix AT32 compile after #3152 Signed-off-by: HiFiPhile --- src/portable/st/stm32_fsdev/fsdev_at32.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/fsdev_at32.h b/src/portable/st/stm32_fsdev/fsdev_at32.h index 3a785bbbd..f7ee89995 100644 --- a/src/portable/st/stm32_fsdev/fsdev_at32.h +++ b/src/portable/st/stm32_fsdev/fsdev_at32.h @@ -36,9 +36,14 @@ #endif #define FSDEV_PMA_SIZE (512u) +#define FSDEV_USE_SBUF_ISO 0 #define FSDEV_REG_BASE (APB1PERIPH_BASE + 0x00005C00UL) #define FSDEV_PMA_BASE (APB1PERIPH_BASE + 0x00006000UL) +#ifndef CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP + #define CFG_TUD_FSDEV_DOUBLE_BUFFERED_ISO_EP 0 +#endif + /**************************** ISTR interrupt events *************************/ #define USB_ISTR_CTR ((uint16_t)0x8000U) /*!< Correct TRansfer (clear-only bit) */ #define USB_ISTR_PMAOVR ((uint16_t)0x4000U) /*!< DMA OVeR/underrun (clear-only bit) */ -- cgit v1.3.1 From cc19c02f860f96299ceccdfcaf1befb308c9fab8 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 15 Sep 2025 15:47:06 +0700 Subject: dwc2: wait for ahb idle before core reset --- .idea/debugServers/AT32F423VCT7.xml | 13 +++++++++++++ .idea/debugServers/ST_LINK.xml | 13 +++++++++++++ .idea/debugServers/at32f403acgu7.xml | 13 +++++++++++++ .idea/debugServers/max32690.xml | 13 +++++++++++++ .idea/debugServers/s3.xml | 6 ++++++ .idea/debugServers/wch_riscv.xml | 14 ++++++++++++++ src/common/tusb_common.h | 4 ++-- src/portable/synopsys/dwc2/dwc2_common.c | 16 +++++++++++----- 8 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 .idea/debugServers/AT32F423VCT7.xml create mode 100644 .idea/debugServers/ST_LINK.xml create mode 100644 .idea/debugServers/at32f403acgu7.xml create mode 100644 .idea/debugServers/max32690.xml create mode 100644 .idea/debugServers/s3.xml create mode 100644 .idea/debugServers/wch_riscv.xml (limited to 'src/portable') diff --git a/.idea/debugServers/AT32F423VCT7.xml b/.idea/debugServers/AT32F423VCT7.xml new file mode 100644 index 000000000..38b3d76ef --- /dev/null +++ b/.idea/debugServers/AT32F423VCT7.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/debugServers/ST_LINK.xml b/.idea/debugServers/ST_LINK.xml new file mode 100644 index 000000000..7c21d3879 --- /dev/null +++ b/.idea/debugServers/ST_LINK.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/debugServers/at32f403acgu7.xml b/.idea/debugServers/at32f403acgu7.xml new file mode 100644 index 000000000..9df65140f --- /dev/null +++ b/.idea/debugServers/at32f403acgu7.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/debugServers/max32690.xml b/.idea/debugServers/max32690.xml new file mode 100644 index 000000000..3551f591e --- /dev/null +++ b/.idea/debugServers/max32690.xml @@ -0,0 +1,13 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/debugServers/s3.xml b/.idea/debugServers/s3.xml new file mode 100644 index 000000000..a03abf744 --- /dev/null +++ b/.idea/debugServers/s3.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/debugServers/wch_riscv.xml b/.idea/debugServers/wch_riscv.xml new file mode 100644 index 000000000..2e147f1b6 --- /dev/null +++ b/.idea/debugServers/wch_riscv.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/common/tusb_common.h b/src/common/tusb_common.h index 1fb93da11..e35d3e6fe 100644 --- a/src/common/tusb_common.h +++ b/src/common/tusb_common.h @@ -168,8 +168,8 @@ TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_high(uint16_t ui16) { return TU_ATTR_ALWAYS_INLINE static inline uint8_t tu_u16_low (uint16_t ui16) { return TU_U16_LOW(ui16); } //------------- Bits -------------// -TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_bit_set (uint32_t value, uint8_t pos) { return value | TU_BIT(pos); } -TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_bit_clear(uint32_t value, uint8_t pos) { return value & (~TU_BIT(pos)); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_bit_set (uint32_t value, uint8_t pos) { return value | TU_BIT(pos); } +TU_ATTR_ALWAYS_INLINE static inline uint32_t tu_bit_clear(uint32_t value, uint8_t pos) { return value & (~TU_BIT(pos)); } TU_ATTR_ALWAYS_INLINE static inline bool tu_bit_test (uint32_t value, uint8_t pos) { return (value & TU_BIT(pos)) ? true : false; } //------------- Min -------------// diff --git a/src/portable/synopsys/dwc2/dwc2_common.c b/src/portable/synopsys/dwc2/dwc2_common.c index d7d157149..5ff18ab94 100644 --- a/src/portable/synopsys/dwc2/dwc2_common.c +++ b/src/portable/synopsys/dwc2/dwc2_common.c @@ -45,20 +45,26 @@ // //-------------------------------------------------------------------- static void reset_core(dwc2_regs_t* dwc2) { + // The software must check that bit 31 in this register is set to 1 (AHB Master is Idle) before starting any operation + while (!(dwc2->grstctl & GRSTCTL_AHBIDL)) { + } + // load gsnpsid (it is not readable after reset is asserted) - uint32_t gsnpsid = dwc2->gsnpsid; + const uint32_t gsnpsid = dwc2->gsnpsid; // reset core dwc2->grstctl |= GRSTCTL_CSRST; if ((gsnpsid & DWC2_CORE_REV_MASK) < (DWC2_CORE_REV_4_20a & DWC2_CORE_REV_MASK)) { - // prior v4.20a CSRST is self-clearing + // prior v4.20a: CSRST is self-clearing and the core clears this bit after all the necessary logic is reset in + // the core, which can take several clocks, depending on the current state of the core. Once this bit has been + // cleared, the software must wait at least 3 PHY clocks before accessing the PHY domain (synchronization delay). while (dwc2->grstctl & GRSTCTL_CSRST) {} } else { - // From v4.20a CSRST bit is write only, CSRT_DONE (w1c) is introduced for checking. - // CSRST must also be explicitly cleared + // From v4.20a: CSRST bit is write only. The application must clear this bit after checking the bit 29 of this + // register i.e Core Soft Reset Done CSRT_DONE (w1c) while (!(dwc2->grstctl & GRSTCTL_CSRST_DONE)) {} - dwc2->grstctl = (dwc2->grstctl & ~GRSTCTL_CSRST) | GRSTCTL_CSRST_DONE; + dwc2->grstctl = (dwc2->grstctl & ~GRSTCTL_CSRST) | GRSTCTL_CSRST_DONE; } while (!(dwc2->grstctl & GRSTCTL_AHBIDL)) {} // wait for AHB master IDLE -- cgit v1.3.1 From 6f06effd03d1163b3e4069d61cf158fc55eb9133 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 15 Sep 2025 16:18:07 +0700 Subject: add nrf54 to dwc2 info --- src/portable/synopsys/dwc2/dwc2_info.md | 116 ++++++++++++++++---------------- src/portable/synopsys/dwc2/dwc2_info.py | 1 + 2 files changed, 59 insertions(+), 58 deletions(-) (limited to 'src/portable') diff --git a/src/portable/synopsys/dwc2/dwc2_info.md b/src/portable/synopsys/dwc2/dwc2_info.md index e6b7820bc..f655e4dba 100644 --- a/src/portable/synopsys/dwc2/dwc2_info.md +++ b/src/portable/synopsys/dwc2/dwc2_info.md @@ -1,58 +1,58 @@ -| | AT32 F405 FS | AT32 F405 HS | AT32 F415 | BCM2711 (Pi4) | EFM32GG | ESP32-S2/S3 | ESP32-P4 | ST F207/F407/411/429 FS | ST F407/429 HS | ST F412/76x FS | ST F723/L4P5 FS | ST F723 HS | ST F76x HS | ST H743/H750 | ST L476 FS | ST U5A5/H7RS/N6 HS | XMC4500 | GD32VF103 | -|:---------------------------|:---------------|:---------------|:------------|:----------------|:-------------|:--------------|:-------------|:--------------------------|:-----------------|:-----------------|:------------------|:-------------|:-------------|:---------------|:-------------|:---------------------|:-------------|:------------| -| GUID | 0x00002000 | 0x00000000 | 0x00001000 | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00AEC000 | 0x00001000 | -| GSNPSID | 0x4F54400A | 0x4F54400A | 0x4F54400A | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54400A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54320A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x4F54292A | 0x00000000 | -| - specs version | 4.00a | 4.00a | 4.00a | 2.80a | 3.30a | 4.00a | 4.00a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.20a | 3.30a | 3.10a | 4.11a | 2.92a | 0.00W | -| GHWCFG1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | -| GHWCFG2 | 0x228FDD00 | 0x229FDDD0 | 0x228DCD00 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x215FFFD0 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x228F5930 | 0x00000000 | -| - 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 | HNP SRP | HNP SRP | HNP SRP | noHNP noSRP | HNP SRP | HNP SRP | -| - arch | Slave only | DMA internal | Slave only | 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 | DMA internal | Slave only | -| - single_point | hub | hub | hub | hub | hub | n/a | hub | n/a | hub | n/a | n/a | hub | hub | hub | n/a | hub | n/a | hub | -| - hs_phy_type | n/a | UTMI+/ULPI | n/a | 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 | Dedicated | Dedicated | Dedicated | Shared ULPI | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | n/a | Dedicated | n/a | -| - num_dev_ep | 7 | 7 | 3 | 7 | 6 | 6 | 15 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 6 | 0 | -| - num_host_ch | 15 | 15 | 7 | 7 | 13 | 7 | 15 | 7 | 11 | 11 | 11 | 15 | 15 | 15 | 11 | 15 | 13 | 0 | -| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - mul_proc_intrpt | 0 | 1 | 0 | 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 | 0 | 0 | 0 | -| - nptx_q_depth | 8 | 8 | 8 | 8 | 8 | 4 | 4 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 2 | -| - ptx_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 4 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 2 | -| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | -| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| GHWCFG3 | 0x020004E8 | 0x03F006E8 | 0x020004E8 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x03805EB5 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x027A01E5 | 0x00000000 | -| - xfer_size_width | 8 | 8 | 8 | 8 | 8 | 5 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 5 | 0 | -| - packet_size_width | 6 | 6 | 6 | 6 | 6 | 3 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | -| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - i2c_enable | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | -| - vendor_ctrl_itf | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | -| - optional_feature_removed | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - synch_reset | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - otg_adp_support | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - battery_charger_support | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | -| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | -| - dfifo_depth | 512 | 1008 | 512 | 4080 | 498 | 200 | 896 | 512 | 1012 | 512 | 512 | 1006 | 1006 | 952 | 512 | 952 | 634 | 0 | -| GHWCFG4 | 0x1FF0A020 | 0x1FF0A020 | 0x0000000F | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0xDFF1A030 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0xDBF08030 | 0x00000000 | -| - num_dev_period_in_ep | 0 | 0 | 15 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - partial_powerdown | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - ahb_freq_min | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - enhanced_lpm_support | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | -| - phy_data_width | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8 bit | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8 bit | 8/16 bit | 8 bit | 8/16 bit | 8 bit | -| - ctrl_ep_num | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | -| - iddg_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - vbus_valid_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | -| - a_valid_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | -| - b_valid_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | -| - session_end_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | -| - dedicated_fifos | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | -| - num_dev_in_eps | 7 | 7 | 0 | 7 | 6 | 4 | 7 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 6 | 0 | -| - dma_desc_enable | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | -| - dma_desc_dynamic | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | +| | AT32 F405 FS | AT32 F405 HS | AT32 F415 | BCM2711 (Pi4) | EFM32GG | ESP32-S2/S3 | ESP32-P4 | nRF54 | ST F207/F407/411/429 FS | ST F407/429 HS | ST F412/76x FS | ST F723/L4P5 FS | ST F723 HS | ST F76x HS | ST H743/H750 | ST L476 FS | ST U5A5/H7RS/N6 HS | XMC4500 | GD32VF103 | +|:---------------------------|:---------------|:---------------|:------------|:----------------|:-------------|:--------------|:-------------|:-------------|:--------------------------|:-----------------|:-----------------|:------------------|:-------------|:-------------|:---------------|:-------------|:---------------------|:-------------|:------------| +| GUID | 0x00002000 | 0x00000000 | 0x00001000 | 0x2708A000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00001200 | 0x00001100 | 0x00002000 | 0x00003000 | 0x00003100 | 0x00002100 | 0x00002300 | 0x00002000 | 0x00005000 | 0x00AEC000 | 0x00001000 | +| GSNPSID | 0x4F54400A | 0x4F54400A | 0x4F54400A | 0x4F54280A | 0x4F54330A | 0x4F54400A | 0x4F54400A | 0x4F54430A | 0x4F54281A | 0x4F54281A | 0x4F54320A | 0x4F54330A | 0x4F54330A | 0x4F54320A | 0x4F54330A | 0x4F54310A | 0x4F54411A | 0x4F54292A | 0x00000000 | +| - specs version | 4.00a | 4.00a | 4.00a | 2.80a | 3.30a | 4.00a | 4.00a | 4.30a | 2.81a | 2.81a | 3.20a | 3.30a | 3.30a | 3.20a | 3.30a | 3.10a | 4.11a | 2.92a | 0.00W | +| GHWCFG1 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0xAA555000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | 0x00000000 | +| GHWCFG2 | 0x228FDD00 | 0x229FDDD0 | 0x228DCD00 | 0x228DDD50 | 0x228F5910 | 0x224DD930 | 0x215FFFD0 | 0x228BFC72 | 0x229DCD20 | 0x229ED590 | 0x229ED520 | 0x229ED520 | 0x229FE1D0 | 0x229FE190 | 0x229FE190 | 0x229ED520 | 0x228FE052 | 0x228F5930 | 0x00000000 | +| - op_mode | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | noHNP noSRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | HNP SRP | noHNP noSRP | HNP SRP | HNP SRP | +| - arch | Slave only | DMA internal | Slave only | DMA internal | 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 | DMA internal | Slave only | +| - single_point | hub | hub | hub | hub | hub | n/a | hub | n/a | n/a | hub | n/a | n/a | hub | hub | hub | n/a | hub | n/a | hub | +| - hs_phy_type | n/a | UTMI+/ULPI | n/a | UTMI+ | n/a | n/a | UTMI+/ULPI | UTMI+ | n/a | ULPI | n/a | n/a | UTMI+/ULPI | ULPI | ULPI | n/a | UTMI+ | n/a | n/a | +| - fs_phy_type | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Shared ULPI | n/a | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | Dedicated | n/a | Dedicated | n/a | +| - num_dev_ep | 7 | 7 | 3 | 7 | 6 | 6 | 15 | 15 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 6 | 0 | +| - num_host_ch | 15 | 15 | 7 | 7 | 13 | 7 | 15 | 15 | 7 | 11 | 11 | 11 | 15 | 15 | 15 | 11 | 15 | 13 | 0 | +| - period_channel_support | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - enable_dynamic_fifo | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - mul_proc_intrpt | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 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 | 0 | 0 | 0 | 0 | +| - nptx_q_depth | 8 | 8 | 8 | 8 | 8 | 4 | 4 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 2 | +| - ptx_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 4 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 2 | +| - token_q_depth | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 0 | +| - otg_enable_ic_usb | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| GHWCFG3 | 0x020004E8 | 0x03F006E8 | 0x020004E8 | 0x0FF000E8 | 0x01F204E8 | 0x00C804B5 | 0x03805EB5 | 0x0BEAC0E8 | 0x020001E8 | 0x03F403E8 | 0x0200D1E8 | 0x0200D1E8 | 0x03EED2E8 | 0x03EED2E8 | 0x03B8D2E8 | 0x0200D1E8 | 0x03B882E8 | 0x027A01E5 | 0x00000000 | +| - xfer_size_width | 8 | 8 | 8 | 8 | 8 | 5 | 5 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 8 | 5 | 0 | +| - packet_size_width | 6 | 6 | 6 | 6 | 6 | 3 | 3 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 6 | 0 | +| - otg_enable | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - i2c_enable | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 0 | 1 | 0 | +| - vendor_ctrl_itf | 0 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 0 | 0 | +| - optional_feature_removed | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - synch_reset | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - otg_adp_support | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - otg_enable_hsic | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - battery_charger_support | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | +| - lpm_mode | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | +| - dfifo_depth | 512 | 1008 | 512 | 4080 | 498 | 200 | 896 | 3050 | 512 | 1012 | 512 | 512 | 1006 | 1006 | 952 | 512 | 952 | 634 | 0 | +| GHWCFG4 | 0x1FF0A020 | 0x1FF0A020 | 0x0000000F | 0x1FF00020 | 0x1BF08030 | 0xD3F0A030 | 0xDFF1A030 | 0x1E10AA60 | 0x0FF08030 | 0x17F00030 | 0x17F08030 | 0x17F08030 | 0x23F00030 | 0x23F00030 | 0xE3F00030 | 0x17F08030 | 0xE2103E30 | 0xDBF08030 | 0x00000000 | +| - num_dev_period_in_ep | 0 | 0 | 15 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - partial_powerdown | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - ahb_freq_min | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - extended_hibernation | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - reserved8 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - enhanced_lpm_support1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - service_interval_flow | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - ipg_isoc_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - acg_support | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - enhanced_lpm_support | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | +| - phy_data_width | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8/16 bit | 8 bit | 8/16 bit | 8/16 bit | 8 bit | 8 bit | 8 bit | 8/16 bit | 8 bit | 8/16 bit | 8 bit | +| - ctrl_ep_num | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | +| - iddg_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - vbus_valid_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | +| - a_valid_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | +| - b_valid_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | +| - session_end_filter | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 0 | +| - dedicated_fifos | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | +| - num_dev_in_eps | 7 | 7 | 0 | 7 | 6 | 4 | 7 | 7 | 3 | 5 | 5 | 5 | 8 | 8 | 8 | 5 | 8 | 6 | 0 | +| - dma_desc_enable | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | +| - dma_desc_dynamic | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 | 0 | diff --git a/src/portable/synopsys/dwc2/dwc2_info.py b/src/portable/synopsys/dwc2/dwc2_info.py index a90150632..f6bd2785a 100755 --- a/src/portable/synopsys/dwc2/dwc2_info.py +++ b/src/portable/synopsys/dwc2/dwc2_info.py @@ -16,6 +16,7 @@ dwc2_reg_value = { 'EFM32GG': [0, 0x4F54330A, 0, 0x228F5910, 0x01F204E8, 0x1BF08030], 'ESP32-S2/S3': [0, 0x4F54400A, 0, 0x224DD930, 0x0C804B5, 0xD3F0A030], 'ESP32-P4': [0, 0x4F54400A, 0, 0x215FFFD0, 0x03805EB5, 0xDFF1A030], + 'nRF54': [0, 0x4F54430A, 0xAA555000, 0x228BFC72, 0x0BEAC0E8, 0x1E10AA60], 'ST F207/F407/411/429 FS': [0x1200, 0x4F54281A, 0, 0x229DCD20, 0x020001E8, 0x0FF08030], 'ST F407/429 HS': [0x1100, 0x4F54281A, 0, 0x229ED590, 0x03F403E8, 0x17F00030], 'ST F412/76x FS': [0x2000, 0x4F54320A, 0, 0x229ED520, 0x0200D1E8, 0x17F08030], -- cgit v1.3.1 From 4182342112d92898d2b55ef9562c545a9ebf52ac Mon Sep 17 00:00:00 2001 From: "igor.masar" Date: Tue, 16 Sep 2025 12:18:50 +0200 Subject: Add ESP32-H4 as a supported MCU in TinyUSB and wire it into build/runtime: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - tusb_option.h: define OPT_MCU_ESP32H4 - tusb_mcu.h: enable DWC2 USBIP for H4 - dcd_dwc2.c: add H4 USB_WRAP field aliases (wrap_* → legacy names) - dwc2_esp32.h: add H4 controller entry (FS base/IRQ, ep caps) - family.c: include H4 in USB init/PHY setup --- README.rst | 2 ++ hw/bsp/espressif/boards/family.c | 6 +++--- src/common/tusb_mcu.h | 2 +- src/portable/synopsys/dwc2/dwc2_esp32.h | 17 +++++++++++++++++ src/tusb_option.h | 1 + 5 files changed, 24 insertions(+), 4 deletions(-) (limited to 'src/portable') diff --git a/README.rst b/README.rst index d6830e707..4a17e1d1f 100644 --- a/README.rst +++ b/README.rst @@ -124,6 +124,8 @@ Supported CPUs | Espressif | S2, S3 | ✔ | ✔ | ✖ | dwc2 or esp32sx | | | ESP32 +-----------------------------+--------+------+-----------+------------------------+-------------------+ | | P4 | ✔ | ✔ | ✔ | dwc2 | | + +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | H4 | ✔ | ✔ | ✖ | dwc2 | | +--------------+----+------------------------+--------+------+-----------+------------------------+-------------------+ | GigaDevice | GD32VF103 | ✔ | | ✖ | dwc2 | | +--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ diff --git a/hw/bsp/espressif/boards/family.c b/hw/bsp/espressif/boards/family.c index 2a5deed26..28dd49143 100644 --- a/hw/bsp/espressif/boards/family.c +++ b/hw/bsp/espressif/boards/family.c @@ -49,7 +49,7 @@ static led_strip_handle_t led_strip; static void max3421_init(void); #endif -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_ESP32P4) +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_ESP32H4, OPT_MCU_ESP32P4) static bool usb_init(void); #endif @@ -105,7 +105,7 @@ void board_init(void) { #endif } -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_ESP32H4) #endif @@ -164,7 +164,7 @@ void board_putchar(int c) { // PHY Init //-------------------------------------------------------------------- -#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_ESP32P4) +#if TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_ESP32H4, OPT_MCU_ESP32P4) #if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 3, 0) #include "esp_private/usb_phy.h" diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 7722ca1e6..b647b2a7f 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -387,7 +387,7 @@ //--------------------------------------------------------------------+ // Espressif //--------------------------------------------------------------------+ -#elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3) +#elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_ESP32H4) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_ESP32 #define TUP_DCD_ENDPOINT_MAX 7 // only 5 TX FIFO for endpoint IN diff --git a/src/portable/synopsys/dwc2/dwc2_esp32.h b/src/portable/synopsys/dwc2/dwc2_esp32.h index 49b8c54cb..a4e0d1770 100644 --- a/src/portable/synopsys/dwc2/dwc2_esp32.h +++ b/src/portable/synopsys/dwc2/dwc2_esp32.h @@ -47,6 +47,23 @@ static const dwc2_controller_t _dwc2_controller[] = { { .reg_base = DWC2_FS_REG_BASE, .irqnum = ETS_USB_INTR_SOURCE, .ep_count = 7, .ep_in_count = 5, .ep_fifo_size = 1024 } }; +#elif TU_CHECK_MCU(OPT_MCU_ESP32H4) +// H4's USB_WRAP register block uses "wrap_*" field names. Map them to the +// names used by TinyUSB's DWC2 port to keep the source unchanged. +#define otg_conf wrap_otg_conf +#define pad_pull_override wrap_pad_pull_override +#define dp_pullup wrap_dp_pullup +#define dp_pulldown wrap_dp_pulldown +#define dm_pullup wrap_dm_pullup +#define dm_pulldown wrap_dm_pulldown + +#define DWC2_FS_REG_BASE 0x60040000UL +#define DWC2_EP_MAX 7 + +static const dwc2_controller_t _dwc2_controller[] = { + { .reg_base = DWC2_FS_REG_BASE, .irqnum = ETS_USB_OTG11_INTR_SOURCE, .ep_count = 7, .ep_in_count = 5, .ep_fifo_size = 1024 } +}; + #elif TU_CHECK_MCU(OPT_MCU_ESP32P4) #define DWC2_FS_REG_BASE 0x50040000UL #define DWC2_HS_REG_BASE 0x50000000UL diff --git a/src/tusb_option.h b/src/tusb_option.h index b2dd5fcb2..fe7e34111 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -131,6 +131,7 @@ #define OPT_MCU_ESP32P4 907 ///< Espressif ESP32-P4 #define OPT_MCU_ESP32C5 908 ///< Espressif ESP32-C5 #define OPT_MCU_ESP32C61 909 ///< Espressif ESP32-C61 +#define OPT_MCU_ESP32H4 910 ///< Espressif ESP32-H4 #define TUSB_MCU_VENDOR_ESPRESSIF (CFG_TUSB_MCU >= 900 && CFG_TUSB_MCU < 1000) // check if Espressif MCU #define TUP_MCU_ESPRESSIF TUSB_MCU_VENDOR_ESPRESSIF // for backward compatibility -- cgit v1.3.1 From 73f3900b2da5d00e707078a591067f0329118dcb Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 17 Sep 2025 22:45:25 +0200 Subject: Replace old delay functions by tusb_time_delay_ms_api Signed-off-by: HiFiPhile --- src/class/cdc/cdc_rndis_host.c | 2 +- src/osal/osal_none.h | 9 --------- src/portable/microchip/pic32mz/dcd_pic32mz.c | 8 +------- src/portable/ohci/ohci.c | 12 ++---------- src/portable/renesas/rusb2/rusb2_common.c | 4 ---- src/portable/sunxi/dcd_sunxi_musb.c | 12 +----------- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 18 ++---------------- 7 files changed, 7 insertions(+), 58 deletions(-) (limited to 'src/portable') diff --git a/src/class/cdc/cdc_rndis_host.c b/src/class/cdc/cdc_rndis_host.c index 11a5355aa..e975ea440 100644 --- a/src/class/cdc/cdc_rndis_host.c +++ b/src/class/cdc/cdc_rndis_host.c @@ -103,7 +103,7 @@ static tusb_error_t rndis_body_subtask(void) } - osal_task_delay(100); + tusb_time_delay_ms_api(100); OSAL_SUBTASK_END } diff --git a/src/osal/osal_none.h b/src/osal/osal_none.h index a8eb1042b..3e397ef35 100644 --- a/src/osal/osal_none.h +++ b/src/osal/osal_none.h @@ -31,15 +31,6 @@ extern "C" { #endif -//--------------------------------------------------------------------+ -// TASK API -//--------------------------------------------------------------------+ - -#if CFG_TUH_ENABLED -// currently only needed/available in host mode -TU_ATTR_WEAK void osal_task_delay(uint32_t msec); -#endif - //--------------------------------------------------------------------+ // Spinlock API //--------------------------------------------------------------------+ diff --git a/src/portable/microchip/pic32mz/dcd_pic32mz.c b/src/portable/microchip/pic32mz/dcd_pic32mz.c index 8709baf67..cbd157d6b 100644 --- a/src/portable/microchip/pic32mz/dcd_pic32mz.c +++ b/src/portable/microchip/pic32mz/dcd_pic32mz.c @@ -162,13 +162,7 @@ void dcd_remote_wakeup(uint8_t rhport) (void) rhport; USB_REGS->POWERbits.RESUME = 1; -#if CFG_TUSB_OS != OPT_OS_NONE - osal_task_delay(10); -#else - // TODO: Wait in non blocking mode - unsigned cnt = 2000; - while (cnt--) __asm__("nop"); -#endif + tusb_time_delay_ms_api(10); USB_REGS->POWERbits.RESUME = 0; } diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c index 81091c9a7..f517e044e 100644 --- a/src/portable/ohci/ohci.c +++ b/src/portable/ohci/ohci.c @@ -208,12 +208,7 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { //Wait 20 ms. (Ref Usb spec 7.1.7.7) OHCI_REG->control_bit.hc_functional_state = OHCI_CONTROL_FUNCSTATE_RESUME; -#if CFG_TUSB_OS != OPT_OS_NONE - // os_none implement task delay using usb frame counter which is not started yet - // therefore cause infinite delay. - // TODO find a way to delay in case of os none e.g __nop - osal_task_delay(20); -#endif + tusb_time_delay_ms_api(20); } // reset controller @@ -241,10 +236,7 @@ bool hcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { OHCI_REG->control_bit.hc_functional_state = OHCI_CONTROL_FUNCSTATE_OPERATIONAL; // make HC's state to operational state TODO use this to suspend (save power) OHCI_REG->rh_status_bit.local_power_status_change = 1; // set global power for ports -#if CFG_TUSB_OS != OPT_OS_NONE - // TODO as above delay - osal_task_delay(OHCI_REG->rh_descriptorA_bit.power_on_to_good_time * 2); // Wait POTG after power up -#endif + tusb_time_delay_ms_api(OHCI_REG->rh_descriptorA_bit.power_on_to_good_time * 2); // Wait POTG after power up return true; } diff --git a/src/portable/renesas/rusb2/rusb2_common.c b/src/portable/renesas/rusb2/rusb2_common.c index 72e65736b..856f9714f 100644 --- a/src/portable/renesas/rusb2/rusb2_common.c +++ b/src/portable/renesas/rusb2/rusb2_common.c @@ -50,10 +50,6 @@ void tusb_rusb2_set_irqnum(uint8_t rhport, int32_t irqnum) { rusb2_controller[rhport].irqnum = irqnum; } -// void osal_task_delay(uint32_t msec) { -// R_BSP_SoftwareDelay(msec, BSP_DELAY_UNITS_MILLISECONDS); -// } - #else #error "Unsupported MCU" #endif diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index 21f13b279..9801a485f 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -99,22 +99,12 @@ static void usb_phy_write(int addr, int data, int len) } } -static void delay_ms(uint32_t ms) -{ -#if CFG_TUSB_OS == OPT_OS_NONE - int now = board_millis(); - while (board_millis() - now <= ms) asm("nop"); -#else - osal_task_delay(ms); -#endif -} - static void USBC_HardwareReset(void) { // Reset phy and controller USBC_REG_set_bit_l(USBPHY_CLK_RST_BIT, USBPHY_CLK_REG); USBC_REG_set_bit_l(BUS_RST_USB_BIT, BUS_CLK_RST_REG); - delay_ms(2); + tusb_time_delay_ms_api(2); USBC_REG_set_bit_l(USBPHY_CLK_GAT_BIT, USBPHY_CLK_REG); USBC_REG_set_bit_l(USBPHY_CLK_RST_BIT, USBPHY_CLK_REG); diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 3752ae251..64cbc5087 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -662,24 +662,10 @@ static void handle_setup_packet(void) dcd_event_setup_received(0, (uint8_t*) &_setup_packet[0], true); } -#if CFG_TUSB_OS == OPT_OS_NONE -TU_ATTR_ALWAYS_INLINE static inline void tu_delay(uint32_t ms) { - // msp430 can run up to 25Mhz -> 40ns per cycle. 1 ms = 25000 cycles - // each loop need 4 cycle: 1 sub, 1 cmp, 1 jump, 1 nop - volatile uint32_t cycles = (25000 * ms) >> 2; - while (cycles > 0) { - cycles--; - asm("nop"); - } -} -#else -#define tu_delay(ms) osal_task_delay(ms) -#endif - static void handle_bus_power_event(void *param) { (void) param; - tu_delay(5); // Bus power settling delay. + tusb_time_delay_ms_api(5); // Bus power settling delay. USBKEYPID = USBKEY; @@ -694,7 +680,7 @@ static void handle_bus_power_event(void *param) { uint16_t attempts = 0; do { // Poll the PLL, checking for a successful lock. USBPLLIR = 0; - tu_delay(1); + tusb_time_delay_ms_api(1); attempts++; } while ((attempts < 10) && (USBPLLIR != 0)); -- cgit v1.3.1 From ce41292f1b49fe39d54a9d4c2951fec56b8c13f5 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 17 Sep 2025 23:48:58 +0200 Subject: Fix address translation functions Signed-off-by: HiFiPhile --- src/portable/ohci/ohci.c | 6 ++---- src/tusb.c | 8 ++++++++ 2 files changed, 10 insertions(+), 4 deletions(-) (limited to 'src/portable') diff --git a/src/portable/ohci/ohci.c b/src/portable/ohci/ohci.c index f517e044e..f1689b5b4 100644 --- a/src/portable/ohci/ohci.c +++ b/src/portable/ohci/ohci.c @@ -168,14 +168,12 @@ static gtd_extra_data_t *gtd_get_extra_data(ohci_gtd_t const * const gtd); // tusb_app_virt_to_phys and tusb_app_virt_to_phys in your application. TU_ATTR_ALWAYS_INLINE static inline void *_phys_addr(void *virtual_address) { - if (tusb_app_virt_to_phys) return tusb_app_virt_to_phys(virtual_address); - return virtual_address; + return tusb_app_virt_to_phys(virtual_address); } TU_ATTR_ALWAYS_INLINE static inline void *_virt_addr(void *physical_address) { - if (tusb_app_phys_to_virt) return tusb_app_phys_to_virt(physical_address); - return physical_address; + return tusb_app_phys_to_virt(physical_address); } // Initialization according to 5.1.1.4 diff --git a/src/tusb.c b/src/tusb.c index 5a3ea356b..083e6d861 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -55,6 +55,14 @@ TU_ATTR_WEAK void tusb_time_delay_ms_api(uint32_t ms) { #endif } +TU_ATTR_WEAK void* tusb_app_virt_to_phys(void *virt_addr) { + return virt_addr; +} + +TU_ATTR_WEAK void* tusb_app_phys_to_virt(void *phys_addr) { + return phys_addr; +} + //--------------------------------------------------------------------+ // Public API //--------------------------------------------------------------------+ -- cgit v1.3.1 From bd35dd17a8970c53a916ede6784137eafda8531b Mon Sep 17 00:00:00 2001 From: Mengsk Date: Mon, 29 Sep 2025 16:00:07 +0200 Subject: Fix PMA size for U0 Signed-off-by: Mengsk --- src/portable/st/stm32_fsdev/fsdev_stm32.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index 95f40269a..0f2b9e068 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -200,7 +200,8 @@ #elif CFG_TUSB_MCU == OPT_MCU_STM32U0 #include "stm32u0xx.h" - #define FSDEV_PMA_SIZE (2048u) + #define FSDEV_PMA_SIZE (1024u) + #define FSDEV_BUS_32BIT #define FSDEV_HAS_SBUF_ISO 1 #define USB USB_DRD_FS -- cgit v1.3.1 From 30f8a9dfae7d93130c2d1aebd9f2a5dc6a96785c Mon Sep 17 00:00:00 2001 From: Mengsk Date: Mon, 29 Sep 2025 16:07:35 +0200 Subject: Disable SBUF_ISO for U0 Signed-off-by: Mengsk --- src/portable/st/stm32_fsdev/fsdev_stm32.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index 0f2b9e068..63b50f13d 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -202,7 +202,8 @@ #include "stm32u0xx.h" #define FSDEV_PMA_SIZE (1024u) #define FSDEV_BUS_32BIT - #define FSDEV_HAS_SBUF_ISO 1 + // Disable SBUF_ISO on U0 for now due to bad performance (audio glitching) + #define FSDEV_HAS_SBUF_ISO 0 #define USB USB_DRD_FS #define USB_EP_CTR_RX USB_EP_VTRX -- cgit v1.3.1 From 7281bfbfc4c19feb63c7691ce0e4f98ccaa0a143 Mon Sep 17 00:00:00 2001 From: Mengsk Date: Mon, 29 Sep 2025 16:07:46 +0200 Subject: Fix warning Signed-off-by: Mengsk --- src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 1 + 1 file changed, 1 insertion(+) (limited to 'src/portable') diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 3b9825e25..ed823a832 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -678,6 +678,7 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet btable_set_addr(ep_idx, 1, pma_addr2); #else btable_set_addr(ep_idx, dir == TUSB_DIR_IN ? BTABLE_BUF_TX : BTABLE_BUF_RX, pma_addr); + (void) pma_addr2; #endif xfer_ctl_t* xfer = xfer_ctl_ptr(ep_num, dir); -- cgit v1.3.1 From f272d87a3f3cce71aa2d13813a1fee94aecb9fc5 Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 6 Oct 2025 10:58:58 +0700 Subject: remove dcd_esp32sx which is replaced by dwc2 --- README.rst | 2 +- src/class/audio/audio_device.c | 5 +- src/portable/espressif/esp32sx/dcd_esp32sx.c | 889 --------------------------- tools/iar_gen.py | 2 +- 4 files changed, 4 insertions(+), 894 deletions(-) delete mode 100644 src/portable/espressif/esp32sx/dcd_esp32sx.c (limited to 'src/portable') diff --git a/README.rst b/README.rst index 16de684a6..03ad3744c 100644 --- a/README.rst +++ b/README.rst @@ -122,7 +122,7 @@ Supported CPUs +--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ | Dialog | DA1469x | ✔ | ✖ | ✖ | da146xx | | +--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ -| Espressif | S2, S3 | ✔ | ✔ | ✖ | dwc2 or esp32sx | | +| Espressif | S2, S3 | ✔ | ✔ | ✖ | dwc2 | | | ESP32 +-----------------------------+--------+------+-----------+------------------------+-------------------+ | | P4 | ✔ | ✔ | ✔ | dwc2 | | | +-----------------------------+--------+------+-----------+------------------------+-------------------+ diff --git a/src/class/audio/audio_device.c b/src/class/audio/audio_device.c index 701411401..7df177773 100644 --- a/src/class/audio/audio_device.c +++ b/src/class/audio/audio_device.c @@ -79,10 +79,9 @@ // Linear buffer in case target MCU is not capable of handling a ring buffer FIFO e.g. no hardware buffer // is available or driver is would need to be changed dramatically -// Only STM32 and dcd_transdimension use non-linear buffer for now -// dwc2 except esp32sx (since it may use dcd_esp32sx) +// Only STM32 and ChipIdea HS use non-linear buffer for now // Ring buffer is incompatible with dcache, since neither address nor size is aligned to cache line -#if (defined(TUP_USBIP_DWC2) && !TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3)) || \ +#if defined(TUP_USBIP_DWC2) || \ defined(TUP_USBIP_FSDEV) || \ CFG_TUSB_MCU == OPT_MCU_RX63X || \ CFG_TUSB_MCU == OPT_MCU_RX65X || \ diff --git a/src/portable/espressif/esp32sx/dcd_esp32sx.c b/src/portable/espressif/esp32sx/dcd_esp32sx.c deleted file mode 100644 index 1b6aae026..000000000 --- a/src/portable/espressif/esp32sx/dcd_esp32sx.c +++ /dev/null @@ -1,889 +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) - * Additions Copyright (c) 2020, Espressif Systems (Shanghai) Co. Ltd. - * - * 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_TUSB_MCU == OPT_MCU_ESP32S2) || (CFG_TUSB_MCU == OPT_MCU_ESP32S3)) && CFG_TUD_ENABLED) - -// Espressif -#include "xtensa/xtensa_api.h" - -#include "esp_intr_alloc.h" -#include "esp_log.h" -#include "soc/dport_reg.h" -#include "soc/gpio_sig_map.h" -#include "soc/usb_periph.h" -#include "soc/usb_reg.h" -#include "soc/usb_struct.h" -#include "soc/periph_defs.h" // for interrupt source - -#include "device/dcd.h" - -#ifndef USB_OUT_EP_NUM -#define USB_OUT_EP_NUM ((int) (sizeof(USB0.out_ep_reg) / sizeof(USB0.out_ep_reg[0]))) -#endif - -#ifndef USB_IN_EP_NUM -#define USB_IN_EP_NUM ((int) (sizeof(USB0.in_ep_reg) / sizeof(USB0.in_ep_reg[0]))) -#endif - -// Max number of bi-directional endpoints including EP0 -// Note: ESP32S2 specs say there are only up to 5 IN active endpoints include EP0 -// We should probably prohibit enabling Endpoint IN > 4 (not done yet) -#define EP_MAX USB_OUT_EP_NUM - -// FIFO size in bytes -#define EP_FIFO_SIZE 1024 - -// Max number of IN EP FIFOs -#define EP_FIFO_NUM 5 - -typedef struct { - uint8_t *buffer; - // tu_fifo_t * ff; // TODO support dcd_edpt_xfer_fifo API - uint16_t total_len; - uint16_t queued_len; - uint16_t max_size; - bool short_packet; - uint8_t interval; -} xfer_ctl_t; - -static const char *TAG = "TUSB:DCD"; -static intr_handle_t usb_ih; - - -static uint32_t _setup_packet[2]; - -#define XFER_CTL_BASE(_ep, _dir) &xfer_status[_ep][_dir] -static xfer_ctl_t xfer_status[EP_MAX][2]; - -// Keep count of how many FIFOs are in use -static uint8_t _allocated_fifos = 1; //FIFO0 is always in use - -// Will either return an unused FIFO number, or 0 if all are used. -static uint8_t get_free_fifo(void) -{ - if (_allocated_fifos < EP_FIFO_NUM) return _allocated_fifos++; - return 0; -} - -// Setup the control endpoint 0. -static void bus_reset(void) -{ - for (int ep_num = 0; ep_num < USB_OUT_EP_NUM; ep_num++) { - USB0.out_ep_reg[ep_num].doepctl |= USB_DO_SNAK0_M; // DOEPCTL0_SNAK - } - - // clear device address - USB0.dcfg &= ~USB_DEVADDR_M; - - USB0.daintmsk = USB_OUTEPMSK0_M | USB_INEPMSK0_M; - USB0.doepmsk = USB_SETUPMSK_M | USB_XFERCOMPLMSK; - USB0.diepmsk = USB_TIMEOUTMSK_M | USB_DI_XFERCOMPLMSK_M /*| USB_INTKNTXFEMPMSK_M*/; - - // "USB Data FIFOs" section in reference manual - // Peripheral FIFO architecture - // - // --------------- 320 or 1024 ( 1280 or 4096 bytes ) - // | IN FIFO MAX | - // --------------- - // | ... | - // --------------- y + x + 16 + GRXFSIZ - // | IN FIFO 2 | - // --------------- x + 16 + GRXFSIZ - // | IN FIFO 1 | - // --------------- 16 + GRXFSIZ - // | IN FIFO 0 | - // --------------- 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 - // * 10 locations in hardware for setup packets + setup control words (up to 3 setup packets). - // * 2 locations for OUT endpoint control words. - // * 16 for largest packet size of 64 bytes. ( TODO Highspeed is 512 bytes) - // * 1 location for global NAK (not required/used here). - // * It is recommended to allocate 2 times the largest packet size, therefore - // Recommended value = 10 + 1 + 2 x (16+2) = 47 --> Let's make it 52 - USB0.grstctl |= 0x10 << USB_TXFNUM_S; // fifo 0x10, - USB0.grstctl |= USB_TXFFLSH_M; // Flush fifo - USB0.grxfsiz = 52; - - // Control IN uses FIFO 0 with 64 bytes ( 16 32-bit word ) - USB0.gnptxfsiz = (16 << USB_NPTXFDEP_S) | (USB0.grxfsiz & 0x0000ffffUL); - - // Ready to receive SETUP packet - USB0.out_ep_reg[0].doeptsiz |= USB_SUPCNT0_M; - - USB0.gintmsk |= USB_IEPINTMSK_M | USB_OEPINTMSK_M; -} - -static void enum_done_processing(void) -{ - ESP_EARLY_LOGV(TAG, "dcd_int_handler - Speed enumeration done! Sending DCD_EVENT_BUS_RESET then"); - // On current silicon on the Full Speed core, speed is fixed to Full Speed. - // However, keep for debugging and in case Low Speed is ever supported. - uint32_t enum_spd = (USB0.dsts >> USB_ENUMSPD_S) & (USB_ENUMSPD_V); - - // Maximum packet size for EP 0 is set for both directions by writing DIEPCTL - if (enum_spd == 0x03) { // Full-Speed (PHY on 48 MHz) - USB0.in_ep_reg[0].diepctl &= ~USB_D_MPS0_V; // 64 bytes - USB0.in_ep_reg[0].diepctl &= ~USB_D_STALL0_M; // clear Stall - xfer_status[0][TUSB_DIR_OUT].max_size = 64; - xfer_status[0][TUSB_DIR_IN].max_size = 64; - } else { - USB0.in_ep_reg[0].diepctl |= USB_D_MPS0_V; // 8 bytes - USB0.in_ep_reg[0].diepctl &= ~USB_D_STALL0_M; // clear Stall - xfer_status[0][TUSB_DIR_OUT].max_size = 8; - xfer_status[0][TUSB_DIR_IN].max_size = 8; - } -} - - -/*------------------------------------------------------------------*/ -/* Controller API - *------------------------------------------------------------------*/ -bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { - (void) rh_init; - ESP_LOGV(TAG, "DCD init - Start"); - - // A. Disconnect - ESP_LOGV(TAG, "DCD init - Soft DISCONNECT and Setting up"); - USB0.dctl |= USB_SFTDISCON_M; // Soft disconnect - - // B. Programming DCFG - /* If USB host misbehaves during status portion of control xfer - (non zero-length packet), send STALL back and discard. Full speed. */ - USB0.dcfg |= USB_NZSTSOUTHSHK_M | // NonZero .... STALL - (3 << 0); // dev speed: fullspeed 1.1 on 48 mhz // TODO no value in usb_reg.h (IDF-1476) - - USB0.gahbcfg |= USB_NPTXFEMPLVL_M | USB_GLBLLNTRMSK_M; // Global interruptions ON - USB0.gusbcfg |= USB_FORCEDEVMODE_M; // force devmode - USB0.gotgctl &= ~(USB_BVALIDOVVAL_M | USB_BVALIDOVEN_M | USB_VBVALIDOVVAL_M); //no overrides - - // C. Setting SNAKs, then connect - for (int n = 0; n < USB_OUT_EP_NUM; n++) { - USB0.out_ep_reg[n].doepctl |= USB_DO_SNAK0_M; // DOEPCTL0_SNAK - } - - // D. Interruption masking - USB0.gintmsk = 0; //mask all - USB0.gotgint = ~0U; //clear OTG ints - USB0.gintsts = ~0U; //clear pending ints - USB0.gintmsk = USB_OTGINTMSK_M | - USB_MODEMISMSK_M | - USB_RXFLVIMSK_M | - USB_ERLYSUSPMSK_M | - USB_USBSUSPMSK_M | - USB_USBRSTMSK_M | - USB_ENUMDONEMSK_M | - USB_RESETDETMSK_M | - USB_WKUPINT_M | - USB_DISCONNINTMSK_M; // host most only - - dcd_connect(rhport); - return true; -} - -void dcd_set_address(uint8_t rhport, uint8_t dev_addr) -{ - (void)rhport; - ESP_LOGV(TAG, "DCD init - Set address : %u", dev_addr); - USB0.dcfg |= ((dev_addr & USB_DEVADDR_V) << USB_DEVADDR_S); - // Response with status after changing device address - dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); -} - -void dcd_remote_wakeup(uint8_t rhport) -{ - (void)rhport; - - // set remote wakeup - USB0.dctl |= USB_RMTWKUPSIG_M; - - // enable SOF to detect bus resume - USB0.gintsts = USB_SOF_M; - USB0.gintmsk |= USB_SOFMSK_M; - - // Per specs: remote wakeup signal bit must be clear within 1-15ms - vTaskDelay(pdMS_TO_TICKS(1)); - - USB0.dctl &= ~USB_RMTWKUPSIG_M; -} - -// connect by enabling internal pull-up resistor on D+/D- -void dcd_connect(uint8_t rhport) -{ - (void) rhport; - USB0.dctl &= ~USB_SFTDISCON_M; -} - -// disconnect by disabling internal pull-up resistor on D+/D- -void dcd_disconnect(uint8_t rhport) -{ - (void) 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 - *------------------------------------------------------------------*/ - -bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const *desc_edpt) -{ - ESP_LOGV(TAG, "DCD endpoint opened"); - (void)rhport; - - usb_out_endpoint_t *out_ep = &(USB0.out_ep_reg[0]); - usb_in_endpoint_t *in_ep = &(USB0.in_ep_reg[0]); - - 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; - - if (dir == TUSB_DIR_OUT) { - out_ep[epnum].doepctl |= USB_USBACTEP1_M | - desc_edpt->bmAttributes.xfer << USB_EPTYPE1_S | - (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? USB_DO_SETD0PID1_M : 0) | - xfer->max_size << USB_MPS1_S; - USB0.daintmsk |= (1 << (16 + epnum)); - } else { - // "USB Data FIFOs" section in reference manual - // Peripheral FIFO architecture - // - // --------------- 320 or 1024 ( 1280 or 4096 bytes ) - // | IN FIFO MAX | - // --------------- - // | ... | - // --------------- y + x + 16 + GRXFSIZ - // | IN FIFO 2 | - // --------------- x + 16 + GRXFSIZ - // | IN FIFO 1 | - // --------------- 16 + GRXFSIZ - // | IN FIFO 0 | - // --------------- GRXFSIZ - // | OUT FIFO | - // | ( Shared ) | - // --------------- 0 - // - // Since OUT FIFO = GRXFSIZ, FIFO 0 = 16, for simplicity, we equally allocated for the rest of endpoints - // - Size : (FIFO_SIZE/4 - GRXFSIZ - 16) / (EP_MAX-1) - // - Offset: GRXFSIZ + 16 + Size*(epnum-1) - // - IN EP 1 gets FIFO 1, IN EP "n" gets FIFO "n". - - uint8_t fifo_num = get_free_fifo(); - TU_ASSERT(fifo_num != 0); - - in_ep[epnum].diepctl &= ~(USB_D_TXFNUM1_M | USB_D_EPTYPE1_M | USB_DI_SETD0PID1 | USB_D_MPS1_M); - in_ep[epnum].diepctl |= USB_D_USBACTEP1_M | - fifo_num << USB_D_TXFNUM1_S | - desc_edpt->bmAttributes.xfer << USB_D_EPTYPE1_S | - (desc_edpt->bmAttributes.xfer != TUSB_XFER_ISOCHRONOUS ? (1 << USB_DI_SETD0PID1_S) : 0) | - xfer->max_size << 0; - - USB0.daintmsk |= (1 << (0 + epnum)); - - // Both TXFD and TXSA are in unit of 32-bit words. - // IN FIFO 0 was configured during enumeration, hence the "+ 16". - uint16_t const allocated_size = (USB0.grxfsiz & 0x0000ffff) + 16; - uint16_t const fifo_size = (EP_FIFO_SIZE/4 - allocated_size) / (EP_FIFO_NUM-1); - uint32_t const fifo_offset = allocated_size + fifo_size*(fifo_num-1); - - // DIEPTXF starts at FIFO #1. - USB0.dieptxf[epnum - 1] = (fifo_size << USB_NPTXFDEP_S) | fifo_offset; - } - return true; -} - -void dcd_edpt_close_all(uint8_t rhport) -{ - (void) rhport; - - usb_out_endpoint_t *out_ep = &(USB0.out_ep_reg[0]); - usb_in_endpoint_t *in_ep = &(USB0.in_ep_reg[0]); - - // Disable non-control interrupt - USB0.daintmsk = USB_OUTEPMSK0_M | USB_INEPMSK0_M; - - 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; - } - - _allocated_fifos = 1; -} - -bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) -{ - (void)rhport; - - 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; // TODO support dcd_edpt_xfer_fifo API - xfer->total_len = total_bytes; - xfer->queued_len = 0; - xfer->short_packet = false; - - uint16_t num_packets = (total_bytes / xfer->max_size); - uint8_t short_packet_size = total_bytes % xfer->max_size; - - // Zero-size packet is special case. - if (short_packet_size > 0 || (total_bytes == 0)) { - num_packets++; - } - - ESP_LOGV(TAG, "Transfer <-> EP%i, %s, pkgs: %i, bytes: %i", - epnum, ((dir == TUSB_DIR_IN) ? "USB0.HOST (in)" : "HOST->DEV (out)"), - num_packets, 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. - USB0.in_ep_reg[epnum].dieptsiz = (num_packets << USB_D_PKTCNT0_S) | total_bytes; - USB0.in_ep_reg[epnum].diepctl |= USB_D_EPENA1_M | USB_D_CNAK1_M; // Enable | CNAK - - // For ISO endpoint with interval=1 set correct DATA0/DATA1 bit for next frame - if ((USB0.in_ep_reg[epnum].diepctl & USB_D_EPTYPE0_M) == (1 << USB_D_EPTYPE1_S) && xfer->interval == 1) { - // Take odd/even bit from frame counter. - uint32_t const odd_frame_now = (USB0.dsts & (1u << USB_SOFFN_S)); - USB0.in_ep_reg[epnum].diepctl |= (odd_frame_now ? USB_DI_SETD0PID1 : USB_DI_SETD1PID1); - } - - // Enable fifo empty interrupt only if there are something to put in the fifo. - if(total_bytes != 0) { - USB0.dtknqr4_fifoemptymsk |= (1 << epnum); - } - } else { - // Each complete packet for OUT xfers triggers XFRC. - USB0.out_ep_reg[epnum].doeptsiz |= USB_PKTCNT0_M | ((xfer->max_size & USB_XFERSIZE0_V) << USB_XFERSIZE0_S); - USB0.out_ep_reg[epnum].doepctl |= USB_EPENA0_M | USB_CNAK0_M; - - // For ISO endpoint with interval=1 set correct DATA0/DATA1 bit for next frame - if ((USB0.out_ep_reg[epnum].doepctl & USB_D_EPTYPE0_M) == (1 << USB_D_EPTYPE1_S) && xfer->interval == 1) { - // Take odd/even bit from frame counter. - uint32_t const odd_frame_now = (USB0.dsts & (1u << USB_SOFFN_S)); - USB0.out_ep_reg[epnum].doepctl |= (odd_frame_now ? USB_DO_SETD0PID1 : USB_DO_SETD1PID1); - } - } - return true; -} - -#if 0 // TODO support dcd_edpt_xfer_fifo API -bool dcd_edpt_xfer_fifo (uint8_t rhport, uint8_t ep_addr, tu_fifo_t * ff, uint16_t total_bytes) -{ - (void)rhport; -} -#endif - -void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) -{ - (void)rhport; - - usb_out_endpoint_t *out_ep = &(USB0.out_ep_reg[0]); - usb_in_endpoint_t *in_ep = &(USB0.in_ep_reg[0]); - - 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_D_EPENA1_M)) { - in_ep[epnum].diepctl |= (USB_DI_SNAK1_M | USB_D_STALL1_M); - } else { - // Stop transmitting packets and NAK IN xfers. - in_ep[epnum].diepctl |= USB_DI_SNAK1_M; - while ((in_ep[epnum].diepint & USB_DI_SNAK1_M) == 0) ; - - // Disable the endpoint. Note that both SNAK and STALL are set here. - in_ep[epnum].diepctl |= (USB_DI_SNAK1_M | USB_D_STALL1_M | USB_D_EPDIS1_M); - while ((in_ep[epnum].diepint & USB_D_EPDISBLD0_M) == 0) ; - in_ep[epnum].diepint = USB_D_EPDISBLD0_M; - } - - // Flush the FIFO, and wait until we have confirmed it cleared. - uint8_t const fifo_num = ((in_ep[epnum].diepctl >> USB_D_TXFNUM1_S) & USB_D_TXFNUM1_V); - USB0.grstctl |= (fifo_num << USB_TXFNUM_S); - USB0.grstctl |= USB_TXFFLSH_M; - while ((USB0.grstctl & USB_TXFFLSH_M) != 0) ; - } else { - // Only disable currently enabled non-control endpoint - if ((epnum == 0) || !(out_ep[epnum].doepctl & USB_EPENA0_M)) { - out_ep[epnum].doepctl |= USB_STALL0_M; - } 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. - USB0.dctl |= USB_SGOUTNAK_M; - while ((USB0.gintsts & USB_GOUTNAKEFF_M) == 0) ; - - // Ditto here- disable the endpoint. Note that only STALL and not SNAK - // is set here. - out_ep[epnum].doepctl |= (USB_STALL0_M | USB_EPDIS0_M); - while ((out_ep[epnum].doepint & USB_EPDISBLD0_M) == 0) ; - out_ep[epnum].doepint = USB_EPDISBLD0_M; - - // Allow other OUT endpoints to keep receiving. - USB0.dctl |= USB_CGOUTNAK_M; - } - } -} - -void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) -{ - (void)rhport; - - usb_out_endpoint_t *out_ep = &(USB0.out_ep_reg[0]); - usb_in_endpoint_t *in_ep = &(USB0.in_ep_reg[0]); - - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); - - if (dir == TUSB_DIR_IN) { - in_ep[epnum].diepctl &= ~USB_D_STALL1_M; - - uint8_t eptype = (in_ep[epnum].diepctl & USB_D_EPTYPE1_M) >> USB_D_EPTYPE1_S; - // Required by USB spec to reset DATA toggle bit to DATA0 on interrupt - // and bulk endpoints. - if (eptype == 2 || eptype == 3) { - in_ep[epnum].diepctl |= USB_DI_SETD0PID1_M; - } - } else { - out_ep[epnum].doepctl &= ~USB_STALL1_M; - - uint8_t eptype = (out_ep[epnum].doepctl & USB_EPTYPE1_M) >> USB_EPTYPE1_S; - // Required by USB spec to reset DATA toggle bit to DATA0 on interrupt - // and bulk endpoints. - if (eptype == 2 || eptype == 3) { - out_ep[epnum].doepctl |= USB_DO_SETD0PID1_M; - } - } -} - -/*------------------------------------------------------------------*/ - -static void receive_packet(xfer_ctl_t *xfer, /* usb_out_endpoint_t * out_ep, */ uint16_t xfer_size) -{ - ESP_EARLY_LOGV(TAG, "USB - receive_packet"); - volatile uint32_t *rx_fifo = USB0.fifo[0]; - - // See above TODO - // uint16_t remaining = (out_ep->DOEPTSIZ & UsbDOEPTSIZ_XFRSIZ_Msk) >> UsbDOEPTSIZ_XFRSIZ_Pos; - // xfer->queued_len = xfer->total_len - remaining; - - uint16_t remaining = xfer->total_len - xfer->queued_len; - uint16_t to_recv_size; - - if (remaining <= xfer->max_size) { - // Avoid buffer overflow. - to_recv_size = (xfer_size > remaining) ? remaining : xfer_size; - } else { - // Room for full packet, choose recv_size based on what the microcontroller - // claims. - to_recv_size = (xfer_size > xfer->max_size) ? xfer->max_size : xfer_size; - } - - // Common buffer read -#if 0 // TODO support dcd_edpt_xfer_fifo API - if (xfer->ff) - { - // Ring buffer - tu_fifo_write_n_const_addr_full_words(xfer->ff, (const void *) rx_fifo, to_recv_size); - } - else -#endif - { - uint8_t to_recv_rem = to_recv_size % 4; - uint16_t to_recv_size_aligned = to_recv_size - to_recv_rem; - - // Do not assume xfer buffer is aligned. - uint8_t *base = (xfer->buffer + xfer->queued_len); - - // This for loop always runs at least once- skip if less than 4 bytes - // to collect. - if (to_recv_size >= 4) { - for (uint16_t i = 0; i < to_recv_size_aligned; i += 4) { - uint32_t tmp = (*rx_fifo); - base[i] = tmp & 0x000000FF; - base[i + 1] = (tmp & 0x0000FF00) >> 8; - base[i + 2] = (tmp & 0x00FF0000) >> 16; - base[i + 3] = (tmp & 0xFF000000) >> 24; - } - } - - // Do not read invalid bytes from RX FIFO. - if (to_recv_rem != 0) { - uint32_t tmp = (*rx_fifo); - uint8_t *last_32b_bound = base + to_recv_size_aligned; - - last_32b_bound[0] = tmp & 0x000000FF; - if (to_recv_rem > 1) { - last_32b_bound[1] = (tmp & 0x0000FF00) >> 8; - } - if (to_recv_rem > 2) { - last_32b_bound[2] = (tmp & 0x00FF0000) >> 16; - } - } - } - - xfer->queued_len += xfer_size; - - // Per USB spec, a short OUT packet (including length 0) is always - // indicative of the end of a transfer (at least for ctl, bulk, int). - xfer->short_packet = (xfer_size < xfer->max_size); -} - -static void transmit_packet(xfer_ctl_t *xfer, volatile usb_in_endpoint_t *in_ep, uint8_t fifo_num) -{ - ESP_EARLY_LOGV(TAG, "USB - transmit_packet"); - volatile uint32_t *tx_fifo = USB0.fifo[fifo_num]; - - uint16_t remaining = (in_ep->dieptsiz & 0x7FFFFU) >> USB_D_XFERSIZE0_S; - xfer->queued_len = xfer->total_len - remaining; - - uint16_t to_xfer_size = (remaining > xfer->max_size) ? xfer->max_size : remaining; - -#if 0 // TODO support dcd_edpt_xfer_fifo API - if (xfer->ff) - { - tu_fifo_read_n_const_addr_full_words(xfer->ff, (void *) tx_fifo, to_xfer_size); - } - else -#endif - { - uint8_t to_xfer_rem = to_xfer_size % 4; - uint16_t to_xfer_size_aligned = to_xfer_size - to_xfer_rem; - - // Buffer might not be aligned to 32b, so we need to force alignment - // by copying to a temp var. - uint8_t *base = (xfer->buffer + xfer->queued_len); - - // This for loop always runs at least once- skip if less than 4 bytes - // to send off. - if (to_xfer_size >= 4) { - for (uint16_t i = 0; i < to_xfer_size_aligned; i += 4) { - uint32_t tmp = base[i] | (base[i + 1] << 8) | - (base[i + 2] << 16) | (base[i + 3] << 24); - (*tx_fifo) = tmp; - } - } - - // Do not read beyond end of buffer if not divisible by 4. - if (to_xfer_rem != 0) { - uint32_t tmp = 0; - uint8_t *last_32b_bound = base + to_xfer_size_aligned; - - tmp |= last_32b_bound[0]; - if (to_xfer_rem > 1) { - tmp |= (last_32b_bound[1] << 8); - } - if (to_xfer_rem > 2) { - tmp |= (last_32b_bound[2] << 16); - } - - (*tx_fifo) = tmp; - } - } -} - -static void read_rx_fifo(void) -{ - // Pop control word off FIFO (completed xfers will have 2 control words, - // we only pop one ctl word each interrupt). - uint32_t const ctl_word = USB0.grxstsp; - uint8_t const pktsts = (ctl_word & USB_PKTSTS_M) >> USB_PKTSTS_S; - uint8_t const epnum = (ctl_word & USB_CHNUM_M ) >> USB_CHNUM_S; - uint16_t const bcnt = (ctl_word & USB_BCNT_M ) >> USB_BCNT_S; - - switch (pktsts) { - case 0x01: // Global OUT NAK (Interrupt) - ESP_EARLY_LOGV(TAG, "TUSB IRQ - RX type : Global OUT NAK"); - break; - - case 0x02: { // Out packet recvd - ESP_EARLY_LOGV(TAG, "TUSB IRQ - RX type : Out packet"); - xfer_ctl_t *xfer = XFER_CTL_BASE(epnum, TUSB_DIR_OUT); - receive_packet(xfer, bcnt); - } - break; - - case 0x03: // Out packet done (Interrupt) - ESP_EARLY_LOGV(TAG, "TUSB IRQ - RX type : Out packet done"); - break; - - case 0x04: // Step 2: Setup transaction completed (Interrupt) - // After this event, OEPINT interrupt will occur with SETUP bit set - ESP_EARLY_LOGV(TAG, "TUSB IRQ - RX : Setup packet done"); - USB0.out_ep_reg[epnum].doeptsiz |= USB_SUPCNT0_M; - break; - - case 0x06: { // Step1: Setup data packet received - volatile uint32_t *rx_fifo = USB0.fifo[0]; - - // We can receive up to three setup packets in succession, but - // only the last one is valid. Therefore we just overwrite it - _setup_packet[0] = (*rx_fifo); - _setup_packet[1] = (*rx_fifo); - - ESP_EARLY_LOGV(TAG, "TUSB IRQ - RX : Setup packet : 0x%08x 0x%08x", _setup_packet[0], _setup_packet[1]); - } - break; - - default: // Invalid, do something here, like breakpoint? - TU_BREAKPOINT(); - break; - } -} - -static void handle_epout_ints(void) -{ - // GINTSTS will be cleared with DAINT == 0 - // DAINT for a given EP clears when DOEPINTx is cleared. - // DOEPINT will be cleared when DAINT's out bits are cleared. - for (int n = 0; n < USB_OUT_EP_NUM; n++) { - xfer_ctl_t *xfer = XFER_CTL_BASE(n, TUSB_DIR_OUT); - - if (USB0.daint & (1 << (16 + n))) { - // SETUP packet Setup Phase done. - if ((USB0.out_ep_reg[n].doepint & USB_SETUP0_M)) { - USB0.out_ep_reg[n].doepint = USB_STUPPKTRCVD0_M | USB_SETUP0_M; // clear - dcd_event_setup_received(0, (uint8_t *)&_setup_packet[0], true); - } - - // OUT XFER complete (single packet).q - if (USB0.out_ep_reg[n].doepint & USB_XFERCOMPL0_M) { - - ESP_EARLY_LOGV(TAG, "TUSB IRQ - EP OUT - XFER complete (single packet)"); - USB0.out_ep_reg[n].doepint = USB_XFERCOMPL0_M; - - // Transfer complete if short packet or total len is transferred - if (xfer->short_packet || (xfer->queued_len == xfer->total_len)) { - xfer->short_packet = false; - dcd_event_xfer_complete(0, n, xfer->queued_len, XFER_RESULT_SUCCESS, true); - } else { - // Schedule another packet to be received. - USB0.out_ep_reg[n].doeptsiz |= USB_PKTCNT0_M | ((xfer->max_size & USB_XFERSIZE0_V) << USB_XFERSIZE0_S); - USB0.out_ep_reg[n].doepctl |= USB_EPENA0_M | USB_CNAK0_M; - } - } - } - } -} - -static void handle_epin_ints(void) -{ - // GINTSTS will be cleared with DAINT == 0 - // DAINT for a given EP clears when DIEPINTx is cleared. - // IEPINT will be cleared when DAINT's out bits are cleared. - for (uint32_t n = 0; n < USB_IN_EP_NUM; n++) { - xfer_ctl_t *xfer = &xfer_status[n][TUSB_DIR_IN]; - - if (USB0.daint & (1 << (0 + n))) { - ESP_EARLY_LOGV(TAG, "TUSB IRQ - EP IN %u", n); - // IN XFER complete (entire xfer). - if (USB0.in_ep_reg[n].diepint & USB_D_XFERCOMPL0_M) { - ESP_EARLY_LOGV(TAG, "TUSB IRQ - IN XFER complete!"); - USB0.in_ep_reg[n].diepint = USB_D_XFERCOMPL0_M; - dcd_event_xfer_complete(0, n | TUSB_DIR_IN_MASK, xfer->total_len, XFER_RESULT_SUCCESS, true); - } - - // XFER FIFO empty - if (USB0.in_ep_reg[n].diepint & USB_D_TXFEMP0_M) { - ESP_EARLY_LOGV(TAG, "TUSB IRQ - IN XFER FIFO empty!"); - USB0.in_ep_reg[n].diepint = USB_D_TXFEMP0_M; - transmit_packet(xfer, &USB0.in_ep_reg[n], n); - - // Turn off TXFE if all bytes are written. - if (xfer->queued_len == xfer->total_len) - { - USB0.dtknqr4_fifoemptymsk &= ~(1 << n); - } - } - - // XFER Timeout - if (USB0.in_ep_reg[n].diepint & USB_D_TIMEOUT0_M) { - // Clear interrupt or endpoint will hang. - USB0.in_ep_reg[n].diepint = USB_D_TIMEOUT0_M; - // Maybe retry? - } - } - } -} - - -static void _dcd_int_handler(void* arg) -{ - (void) arg; - uint8_t const rhport = 0; - - const uint32_t int_msk = USB0.gintmsk; - const uint32_t int_status = USB0.gintsts & int_msk; - - if (int_status & USB_USBRST_M) { - // start of reset - ESP_EARLY_LOGV(TAG, "dcd_int_handler - reset"); - USB0.gintsts = USB_USBRST_M; - // FIFOs will be reassigned when the endpoints are reopen - _allocated_fifos = 1; - bus_reset(); - } - - if (int_status & USB_RESETDET_M) { - ESP_EARLY_LOGV(TAG, "dcd_int_handler - reset while suspend"); - USB0.gintsts = USB_RESETDET_M; - bus_reset(); - } - - if (int_status & USB_ENUMDONE_M) { - // ENUMDNE detects speed of the link. For full-speed, we - // always expect the same value. This interrupt is considered - // the end of reset. - USB0.gintsts = USB_ENUMDONE_M; - enum_done_processing(); - dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); - } - - if(int_status & USB_USBSUSP_M) - { - USB0.gintsts = USB_USBSUSP_M; - dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); - } - - if(int_status & USB_WKUPINT_M) - { - USB0.gintsts = USB_WKUPINT_M; - dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); - } - - if (int_status & USB_OTGINT_M) - { - // OTG INT bit is read-only - ESP_EARLY_LOGV(TAG, "dcd_int_handler - disconnected"); - - uint32_t const otg_int = USB0.gotgint; - - if (otg_int & USB_SESENDDET_M) - { - dcd_event_bus_signal(rhport, DCD_EVENT_UNPLUGGED, true); - } - - USB0.gotgint = otg_int; - } - - if (int_status & USB_SOF_M) { - USB0.gintsts = USB_SOF_M; - - // Disable SOF interrupt since currently only used for remote wakeup detection - USB0.gintmsk &= ~USB_SOFMSK_M; - - dcd_event_bus_signal(rhport, DCD_EVENT_SOF, true); - } - - - if (int_status & USB_RXFLVI_M) { - // RXFLVL bit is read-only - ESP_EARLY_LOGV(TAG, "dcd_int_handler - rx!"); - - // Mask out RXFLVL while reading data from FIFO - USB0.gintmsk &= ~USB_RXFLVIMSK_M; - read_rx_fifo(); - USB0.gintmsk |= USB_RXFLVIMSK_M; - } - - // OUT endpoint interrupt handling. - if (int_status & USB_OEPINT_M) { - // OEPINT is read-only - ESP_EARLY_LOGV(TAG, "dcd_int_handler - OUT endpoint!"); - handle_epout_ints(); - } - - // IN endpoint interrupt handling. - if (int_status & USB_IEPINT_M) { - // IEPINT bit read-only - ESP_EARLY_LOGV(TAG, "dcd_int_handler - IN endpoint!"); - handle_epin_ints(); - } - - // Without handling - USB0.gintsts |= USB_CURMOD_INT_M | - USB_MODEMIS_M | - USB_OTGINT_M | - USB_NPTXFEMP_M | - USB_GINNAKEFF_M | - USB_GOUTNAKEFF | - USB_ERLYSUSP_M | - USB_USBSUSP_M | - USB_ISOOUTDROP_M | - USB_EOPF_M | - USB_EPMIS_M | - USB_INCOMPISOIN_M | - USB_INCOMPIP_M | - USB_FETSUSP_M | - USB_PTXFEMP_M; -} - -void dcd_int_enable (uint8_t rhport) -{ - (void) rhport; - esp_intr_alloc(ETS_USB_INTR_SOURCE, ESP_INTR_FLAG_LOWMED, (intr_handler_t) _dcd_int_handler, NULL, &usb_ih); -} - -void dcd_int_disable (uint8_t rhport) -{ - (void) rhport; - esp_intr_free(usb_ih); -} - -#endif // #if OPT_MCU_ESP32S2 || OPT_MCU_ESP32S3 diff --git a/tools/iar_gen.py b/tools/iar_gen.py index 8d45659db..571febb2c 100755 --- a/tools/iar_gen.py +++ b/tools/iar_gen.py @@ -74,7 +74,7 @@ def ListPath(path, blacklist=[]): print('') def List(): - ListPath('src', [ 'template.c', 'dcd_synopsys.c', 'dcd_esp32sx.c' ]) + ListPath('src', [ 'template.c' ]) ListPath('lib/SEGGER_RTT') if __name__ == "__main__": -- cgit v1.3.1