From 05b61c409df90784e0b81062c7909038f0aefa2c Mon Sep 17 00:00:00 2001 From: Onlyou_tzZ <17393117531@163.com> Date: Wed, 28 Jan 2026 14:58:58 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=9B=BD=E6=B0=91?= =?UTF-8?q?=E6=8A=80=E6=9C=AFBSP=E6=9E=B6=E6=9E=84=EF=BC=8C=E6=B7=BB?= =?UTF-8?q?=E5=8A=A0N32H7xx=E7=B3=BB=E5=88=97BSP?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修改clang_format-ignore文件,根据反馈修改n32h7xxx/libraries/N32_Drivers/nano/*下的文件格式,修改n32h7xxx/n32/n32hxxx/n32h760zil7-stb/applications/main.c文件,区别处理Nano下头文件包含 将N32 BSP的.clang-format-ignore文件放入libraries同级目录 忽略库文件格式检查 fix(cherryusb): fix dwc2 host size check Signed-off-by: sakumisu <1203593632@qq.com> [components][clock_time] Refactor time subsystem around clock_time (#11111) * [components][clock_time] Refactor time subsystem around clock_time Introduce the clock_time core with clock source/event separation, high-resolution scheduling, and boot-time helpers, plus clock_timer adapters for timer peripherals. Remove legacy ktime/cputime/hwtimer implementations and migrate arch and BSP time paths to the new subsystem while keeping POSIX time integration functional. Update drivers, Kconfig/SConscript wiring, documentation, and tests; add clock_time overview docs and align naming to clock_boottime/clock_hrtimer/clock_timer. * [components][clock_time] Use BSP-provided clock timer frequency on riscv64 * [risc-v] Use runtime clock timer frequency for tick and delays * [bsp] Add clock timer frequency hooks for riscv64 boards * [bsp] Update Renesas RA driver doc clock_timer link * [bsp] Sync zynqmp-r5-axu4ev rtconfig after config refresh * [bsp][rk3500] Update rk3500 clock configuration * [bsp][hpmicro] Add rt_hw_us_delay hook and update board delays * [bsp][stm32l496-st-nucleo] enable clock_time for hwtimer sample in ci * [bsp][hpmicro] Fix rtconfig include scope for hpm6750evk Move rtconfig.h include outside the ENET_MULTIPLE_PORT guard for hpm6750evk and hpm6750evk2 so configuration macros are available regardless of ENET settings. * [bsp][raspi3] select clock time for systimer * [bsp][hpm5300evk] Trim trailing blank line * [bsp][hpm5301evklite] Trim trailing blank line * [bsp][hpm5e00evk] Trim trailing blank line * [bsp][hpm6200evk] Trim trailing blank line * [bsp][hpm6300evk] Trim trailing blank line * [bsp][hpm6750evk] Trim trailing blank line * [bsp][hpm6750evk2] Trim trailing blank line * [bsp][hpm6750evkmini] Trim trailing blank line * [bsp][hpm6800evk] Trim trailing blank line * [bsp][hpm6e00evk] Trim trailing blank line * [bsp][nxp] switch lpc178x to gcc and remove mcx timer source * [bsp][stm32] fix the CONFIG_RT_USING_CLOCK_TIME issue. * [docs][clock_time] add clock time documentation * [docs][clock_time] Update clock time subsystem documentation - Update device driver index to use correct page reference - Clarify upper layer responsibilities in architecture overview - Update README to describe POSIX/libc, Soft RTC, and device driver usage - Refine architecture diagram with improved layout and color scheme - Remove obsolete clock_timer.md file * [kernel][utest] Trim trailing space * [clock_time] Fix hrtimer wrap handling * [clock_time] fix the static rt_inline issue * [clock_time] fix the rt_clock_hrtimer_control result issue 解决N32 BSP project.ewp和project.uvprojx冲突 更新RTT最新同步 sdio: fix missing card status polling after CMD6 in eMMC DDR mode switch fix[dfs_v1]: prevent vnode ref underflow and double release on close/fd release feat[STM32][CAN]: drain RX FIFO frames in ISR with a bounded limit to reduce overruns - Add CAN_ISR_DRAIN_LIMIT (default 3) to cap ISR work - Drain multiple frames per RX0/RX1 interrupt to reduce FIFO FULL/OVERRUN docs(can): improve dev_can.h docs for batched RX example fix[STM32][RTC]: Compute tv_usec from SecondFraction/SubSeconds and skip during shift pending Use the generic SecondFraction/SubSeconds formula when SSR/PRER are available. If SHPF is present and a shift is pending, keep tv_usec at 0. Platforms without SSR/PRER (e.g. F1) default to 0. [bsp][gd32]:add gd32vw533xx pwm support Update Nsing's BSP architecture and add N32H7xx series BSPs. (#11159) * 更新国民技术BSP架构,添加N32H7xx系列BSP * 修改clang_format-ignore文件,根据反馈修改n32h7xxx/libraries/N32_Drivers/nano/*下的文件格式,修改n32h7xxx/n32/n32hxxx/n32h760zil7-stb/applications/main.c文件,区别处理Nano下头文件包含 * 将N32 BSP的.clang-format-ignore文件放入libraries同级目录 * 忽略库文件格式检查 * 解决N32 BSP project.ewp和project.uvprojx冲突 * 更新RTT最新同步 rename i2c mutex Co-authored-by: BernardXiong <1241087+BernardXiong@users.noreply.github.com> Squashed commit of the following: commit cadd095cd34bb2eaab5e39466f56674a9fe3f19b Merge: 5ad4edcf39 68da106253 Author: Onlyou_tzZ <97173915+OnlyoutzZ@users.noreply.github.com> Date: Wed Feb 4 22:50:54 2026 +0800 Merge branch 'RT-Thread:master' into master commit 68da10625347cfe34fad8b73a78feffbe311d561 Author: CYFS <2805686936@qq.com> Date: Wed Feb 4 16:45:30 2026 +0800 [components][drivers]:fix wlan err commit 5ad4edcf39330f01f698d95c322c3d0f8aae2feb Author: Onlyou_tzZ <17393117531@163.com> Date: Wed Feb 4 20:22:40 2026 +0800 更新BSP下README.md中N32相关的描述 更新BSP下README.md中N32相关的描述 [components][drivers]:fix wlan err [components][lwip]: fix ping timeout handling and support LWIP_SO_SNDRCVTIMEO_NONSTANDARD [gd32][uart] Add GD32VW553 series UART driver support (#11147) * feat(gd32): add GD32VW55x series USART driver support - Add support for GD32VW55x series UART/USART peripherals - Implement proper GPIO alternate function configuration for GD32VW55x - Add conditional compilation for different GD32 series (GD32VF103V vs GD32VW55x) - Remove unused UART3/UART4 configurations from Kconfig * Update drv_usart.c * Update drv_usart.h follow AI Review. * Update bsp/gd32/risc-v/libraries/gd32_drivers/drv_usart.c Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * feat: optimize gd32 uart driver error messages --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- bsp/README.md | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/bsp/README.md b/bsp/README.md index 1b77f596260..6bb02cceabe 100644 --- a/bsp/README.md +++ b/bsp/README.md @@ -317,18 +317,19 @@ This document is based on the RT-Thread mainline repository and categorizes the | BSP Name | GPIO | UART | ADC | CAN | DAC | HWTimer | I2C | RTC | SPI | WDT | |----------|------|------|-----|-----|-----|---------|-----|-----|-----|-----| -| [n32g43xcl-stb](n32/n32g43xcl-stb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [n32g457gel-stb](n32) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [n32g45xcl-stb](n32/n32g45xcl-stb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [n32g45xml-stb](n32/n32g45xml-stb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [n32g45xrl-stb](n32/n32g45xrl-stb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [n32g45xvl-stb](n32/n32g45xvl-stb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [n32g47rml-stb](n32/n32g47rml-stb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [n32l40xcl-stb](n32/n32l40xcl-stb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [n32l436-evb](n32/n32l436-evb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [n32l43xml-stb](n32/n32l43xml-stb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [n32l43xrl-stb](n32/n32l43xrl-stb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | -| [n32wb45xl-evb](n32/n32wb45xl-evb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [n32g43xcl-stb](n32/n32gxx_lxx/n32g43xcl-stb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [n32g457gel-stb](n32/n32gxx_lxx/n32g457gel-stb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [n32g45xcl-stb](n32/n32gxx_lxx/n32g45xcl-stb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [n32g45xml-stb](n32/n32gxx_lxx/n32g45xml-stb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [n32g45xrl-stb](n32/n32gxx_lxx/n32g45xrl-stb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [n32g45xvl-stb](n32/n32gxx_lxx/n32g45xvl-stb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [n32g47rml-stb](n32/n32gxx_lxx/n32g47rml-stb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [n32l40xcl-stb](n32/n32gxx_lxx/n32l40xcl-stb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [n32l436-evb](n32/n32gxx_lxx/n32l436-evb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [n32l43xml-stb](n32/n32gxx_lxx/n32l43xml-stb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [n32l43xrl-stb](n32/n32gxx_lxx/n32l43xrl-stb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [n32wb45xl-evb](n32/n32gxx_lxx/n32wb45xl-evb) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | +| [n32h760zil7-stb](n32/n32hxxx/n32h760zil7-stb) | ✅ | ✅ | ✅ | - | - | - | ✅ | ✅ | ✅ | - | #### 🟡 NRF5x From b22d05ac35048da7928246f788d3c98f5a40b373 Mon Sep 17 00:00:00 2001 From: luofan <17393117531@163.com> Date: Fri, 26 Jun 2026 16:04:48 +0800 Subject: [PATCH 2/3] =?UTF-8?q?1=E3=80=81usb=5Fglue=5Fnation.c=E4=B8=AD?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0N32H49X=E5=92=8CN32H7XX=E7=B3=BB=E5=88=97MCU?= =?UTF-8?q?=E7=9A=84USBHS=E6=94=AF=E6=8C=81=202=E3=80=81usb=5Fhc.h?= =?UTF-8?q?=E4=B8=ADstruct=20usbh=5Furb=E7=BB=93=E6=9E=84=E4=BD=93?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0defined(=5F=5FCC=5FARM)=E5=88=A4=E6=96=AD?= =?UTF-8?q?=EF=BC=8CMDK=20AC5=E7=BC=96=E8=AF=91=E5=99=A8=E4=B8=8D=E6=94=AF?= =?UTF-8?q?=E6=8C=81struct=20usbh=5Fiso=5Fframe=5Fpacket=20iso=5Fpacket[0]?= =?UTF-8?q?=E5=8F=AA=E6=94=AF=E6=8C=81struct=20usbh=5Fiso=5Fframe=5Fpacket?= =?UTF-8?q?=20*iso=5Fpacket=203=E3=80=81usbd=5Fhid.c=EF=BC=8Cusb=5Fversion?= =?UTF-8?q?.h=EF=BC=8Cusb=5Fosal=5Frtthread.c,=20usb=5Fdwc2=5Fparam.h?= =?UTF-8?q?=E6=9C=80=E5=90=8E=E6=B7=BB=E5=8A=A0=E4=B8=80=E8=A1=8C=EF=BC=8C?= =?UTF-8?q?=E6=B6=88=E9=99=A4keil=E4=B8=AD=E7=9A=84=E8=AD=A6=E5=91=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../usb/cherryusb/class/hid/usbd_hid.c | 3 +- .../drivers/usb/cherryusb/common/usb_hc.h | 2 +- .../usb/cherryusb/common/usb_version.h | 3 +- .../usb/cherryusb/osal/usb_osal_rtthread.c | 3 +- .../usb/cherryusb/port/dwc2/usb_dwc2_param.h | 3 +- .../usb/cherryusb/port/dwc2/usb_glue_nation.c | 955 ++++++++++++++++-- 6 files changed, 903 insertions(+), 66 deletions(-) diff --git a/components/drivers/usb/cherryusb/class/hid/usbd_hid.c b/components/drivers/usb/cherryusb/class/hid/usbd_hid.c index ad8dfa22ab6..c882c9c0889 100644 --- a/components/drivers/usb/cherryusb/class/hid/usbd_hid.c +++ b/components/drivers/usb/cherryusb/class/hid/usbd_hid.c @@ -122,4 +122,5 @@ __WEAK void usbd_hid_set_protocol(uint8_t busid, uint8_t intf, uint8_t protocol) (void)busid; (void)intf; (void)protocol; -} \ No newline at end of file +} + diff --git a/components/drivers/usb/cherryusb/common/usb_hc.h b/components/drivers/usb/cherryusb/common/usb_hc.h index aa411eef7fb..cf040de60b9 100644 --- a/components/drivers/usb/cherryusb/common/usb_hc.h +++ b/components/drivers/usb/cherryusb/common/usb_hc.h @@ -51,7 +51,7 @@ struct usbh_urb { uint32_t start_frame; usbh_complete_callback_t complete; void *arg; -#if defined(__ICCARM__) || defined(__ICCRISCV__) || defined(__ICCRX__) +#if defined(__ICCARM__) || defined(__ICCRISCV__) || defined(__ICCRX__) || defined(__CC_ARM) struct usbh_iso_frame_packet *iso_packet; #else struct usbh_iso_frame_packet iso_packet[0]; diff --git a/components/drivers/usb/cherryusb/common/usb_version.h b/components/drivers/usb/cherryusb/common/usb_version.h index 5c59978f732..fe040707efd 100644 --- a/components/drivers/usb/cherryusb/common/usb_version.h +++ b/components/drivers/usb/cherryusb/common/usb_version.h @@ -18,4 +18,5 @@ #define CHERRYUSB_VERSION 0x010601 #define CHERRYUSB_VERSION_STR "v1.6.1" -#endif \ No newline at end of file +#endif + diff --git a/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c b/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c index cf0e683eaf0..4f3dc3e223b 100644 --- a/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c +++ b/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c @@ -226,4 +226,5 @@ void *usb_osal_malloc(size_t size) void usb_osal_free(void *ptr) { rt_free(ptr); -} \ No newline at end of file +} + diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_dwc2_param.h b/components/drivers/usb/cherryusb/port/dwc2/usb_dwc2_param.h index 74e436c225f..3300f3dc906 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/usb_dwc2_param.h +++ b/components/drivers/usb/cherryusb/port/dwc2/usb_dwc2_param.h @@ -364,4 +364,5 @@ static inline void dwc2_get_hwparams(uint32_t reg_base, struct dwc2_hw_params *h void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params); void dwc2_get_user_fifo_config(uint32_t reg_base, struct usb_dwc2_user_fifo_config *config); -#endif \ No newline at end of file +#endif + diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_nation.c b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_nation.c index 3e96b22f593..1239711688a 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_nation.c +++ b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_nation.c @@ -17,8 +17,8 @@ __WEAK void USBH_IRQHandler(uint8_t busid) #if defined(N32H473) || defined(N32H474) || defined(N32H475) || defined(N32H482) || defined(N32H487) #include "n32h47x_48x_rcc.h" #include "n32h47x_48x_gpio.h" -#include "n32h47x_48x_exti.h" #include "misc.h" +#include "usb_dwc2_param.h" typedef void (*usb_dwc2_irq)(uint8_t busid); @@ -29,95 +29,346 @@ static void usbhs_common_init(void) { RCC_EnableAHB1PeriphClk(RCC_AHB_PERIPHEN_GPIOA | RCC_AHB_PERIPHEN_GPIOB, ENABLE); RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE); - /* PLL= 240MHz */ #if (HSE_VALUE == 8000000) - /* Select PLL clock as USBHS clock source , clock 15 divisions = 16M */ + /* System PLL = 240 MHz; divide by 15 to produce 16 MHz USB PHY reference. */ RCC_ConfigUSBPLLPresClk(RCC_USBPLLCLK_SRC_PLL, RCC_USBPLLCLK_DIV15); - - /* Select the corresponding bandwidth and frequency*/ RCC_ConfigUSBHSBandwidth(RCC_USBHS_BW_16M); - - /* Select USBHS clock source frequency */ RCC_ConfigUSBHSFrequency(RCC_USBHS_FREQ_16_OR_32M); - - /* Select PLL as USBHS clock */ RCC_ConfigUSBHSClk(RCC_USBHS_CLKSRC_PLLPRES); -#else //HSE 16M +#else /* HSE 16 MHz — feed directly to USBHS */ RCC_ConfigUSBHSBandwidth(RCC_USBHS_BW_16M); RCC_ConfigUSBHSFrequency(RCC_USBHS_FREQ_16_OR_32M); RCC_ConfigUSBHSClk(RCC_USBHS_CLKSRC_HSE); #endif - /* Reset the USBHS phy clock*/ RCC_EnableAHBPeriphReset(RCC_AHBPRST_USBHSPHYRST); - /* Enables the USBHS peripheral clock*/ RCC_EnableAHBPeriphClk(RCC_AHB_PERIPHEN_USBHS, ENABLE); - NVIC_InitType NVIC_InitStructure; - // EXTI_InitType EXTI_InitStructure; + /* TX analog tuning for 8-bit UTMI PHY (N32H47x_48x USBHSCTRL2 layout). */ + RCC->USBHSCTRL2 = (RCC->USBHSCTRL2 & (~(0xF << 4))) | (0x5 << 4); /* TX vref TUNE [7:4] */ + RCC->USBHSCTRL2 = (RCC->USBHSCTRL2 & (~(0x3 << 12))) | (0x3 << 12); /* TX Rise TUNE [13:12] */ + RCC->USBHSCTRL2 = (RCC->USBHSCTRL2 & (~(0x3 << 14))) | (0x3 << 14); /* TX Res TUNE [15:14] */ + RCC->USBHSCTRL2 = (RCC->USBHSCTRL2 & (~(0x3 << 16))) | (0x3 << 16); /* TX preempamp TUNE [17:16] */ - // NVIC_InitStructure.NVIC_IRQChannel = USB_HS_WKUP_IRQn; - // NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; - // NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; - // NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; - // NVIC_Init(&NVIC_InitStructure); + NVIC_InitType NVIC_InitStructure; NVIC_InitStructure.NVIC_IRQChannel = USB_HS_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); +} - /* Configure the EXTI line 23 connected internally to the USBHS IP */ - // EXTI_ClrITPendBit(EXTI_LINE23); - // EXTI_InitStructure.EXTI_Line = EXTI_LINE23; - // EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt; - // EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising; - // EXTI_InitStructure.EXTI_LineCmd = ENABLE; - // EXTI_InitPeripheral(&EXTI_InitStructure); +/* Override in the board layer to configure USB DM/DP alternate-function pins. + * In host mode, also drive any VBUS power-switch GPIO here (e.g. board/ports/usb_gpio.c). */ +__weak void n32h47x_48x_usbhs_gpio_init(void) { } + +void usb_dc_low_level_init(uint8_t busid) +{ + g_usb_dwc2_irq = USBD_IRQHandler; + g_usb_dwc2_busid = busid; + + n32h47x_48x_usbhs_gpio_init(); + usbhs_common_init(); + + RCC->USBHSCTRL2 |= (uint32_t)0x01 << 19; + RCC->USBHSCTRL1 |= (uint32_t)0x01 << 31; } -static void usbhs_gpio_init(void) +void usb_dc_low_level_deinit(uint8_t busid) { - GPIO_InitType GPIO_InitStructure; + NVIC_InitType NVIC_InitStructure; - RCC_EnableAHB1PeriphClk(RCC_AHB_PERIPHEN_GPIOA | RCC_AHB_PERIPHEN_GPIOB | RCC_AHB_PERIPHEN_GPIOE, ENABLE); - RCC_EnableAPB2PeriphClk(RCC_APB2_PERIPH_AFIO, ENABLE); - GPIO_ConfigPinRemap(0, 0, GPIO_RMP_SWJ_SWD); - - GPIO_InitStruct(&GPIO_InitStructure); -#ifdef USBHS_HOST - GPIO_InitStructure.Pin = GPIO_PIN_1; - GPIO_InitStructure.GPIO_Mode = GPIO_MODE_OUTPUT_PP; - GPIO_InitPeripheral(GPIOE, &GPIO_InitStructure); - GPIO_ResetBits(GPIOE, GPIO_PIN_1); - - GPIO_InitStructure.Pin = GPIO_PIN_3; - GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure); - GPIO_ResetBits(GPIOB, GPIO_PIN_3); + NVIC_InitStructure.NVIC_IRQChannel = USB_HS_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; + NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; + NVIC_Init(&NVIC_InitStructure); + + RCC_EnableAHBPeriphReset(RCC_AHBPRST_USBHSPHYRST); + /* Disable the USBHS peripheral clock. */ + RCC_EnableAHBPeriphClk(RCC_AHB_PERIPHEN_USBHS, DISABLE); +} + +void usb_hc_low_level_init(struct usbh_bus *bus) +{ + g_usb_dwc2_irq = USBH_IRQHandler; + g_usb_dwc2_busid = 0; + + n32h47x_48x_usbhs_gpio_init(); + usbhs_common_init(); + + RCC->USBHSCTRL2 &= ~(uint32_t)0x01 << 19; + RCC->USBHSCTRL1 |= (uint32_t)0x01 << 31; +} + +void usb_hc_low_level_deinit(struct usbh_bus *bus) +{ + NVIC_InitType NVIC_InitStructure; + + NVIC_InitStructure.NVIC_IRQChannel = USB_HS_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; + NVIC_InitStructure.NVIC_IRQChannelCmd = DISABLE; + NVIC_Init(&NVIC_InitStructure); + + RCC_EnableAHBPeriphReset(RCC_AHBPRST_USBHSPHYRST); + /* Disable the USBHS peripheral clock. */ + RCC_EnableAHBPeriphClk(RCC_AHB_PERIPHEN_USBHS, DISABLE); +} + +uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base) +{ + return 0; +} + +uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base) +{ + return 0; +} + +void USB_HS_IRQHandler(void) +{ + g_usb_dwc2_irq(g_usb_dwc2_busid); +} + +void usbd_dwc2_delay_ms(uint8_t ms) +{ + RCC_ClocksType RCC_clocks = { 0 }; + + RCC_GetClocksFreqValue(&RCC_clocks); + + uint32_t count = RCC_clocks.SysclkFreq / 1000 * ms; + while (count--) + { + __asm volatile("nop"); + } +} + +uint32_t usbd_dwc2_get_system_clock(void) +{ + RCC_ClocksType RCC_clocks = { 0 }; + + RCC_GetClocksFreqValue(&RCC_clocks); + return RCC_clocks.SysclkFreq; +} + +/* + * N32H47x_48x USBHS has 4 KB (1024 x 32-bit words) of dedicated FIFO RAM; + * GRXFSIZ.RXFDEP max = 1024. + * + * Internal HS UTMI+ PHY, 8-bit data bus (GCFG.PHYIF = 0). + * PHY is configured via RCC USBHSCTRL registers, not DWC2 GCCFG, + * so device_gccfg / host_gccfg are both zero. + * + * Device FIFO layout (1024 words, 4096 bytes): + * RX shared 512 words (2048 bytes) + * EP0 IN TX 64 words ( 256 bytes) — control + * EP1 IN TX 256 words (1024 bytes) — bulk / isochronous HS + * EP2 IN TX 64 words ( 256 bytes) + * EP3 IN TX 64 words ( 256 bytes) + * EP4 IN TX 64 words ( 256 bytes) + * Total 1024 words (4096 bytes) + * + * Host FIFO layout (1024 words, 4096 bytes): + * RX 512 words (2048 bytes) + * Non-periodic TX 256 words (1024 bytes) + * Periodic TX 256 words (1024 bytes) + * Total 1024 words (4096 bytes) + * + */ +static const struct dwc2_user_params param_n32h47x_48x = +{ + /* Built-in HS UTMI+ PHY; sets GUSBCFG.ULPI_UTMI_SEL = 0. */ + .phy_type = DWC2_PHY_TYPE_PARAM_UTMI, + + /* 8-bit UTMI data bus (USBHS_GCFG.PHYIF = 0). + * USB_CoreInit() in usbhs_core.c explicitly clears PHYIF. + * CherryUSB only sets GUSBCFG.PHYIF16 when this field == 16. */ + .phy_utmi_width = 8, + + /* Slave mode vs DMA mode; controlled by CONFIG_USB_DWC2_DMA_ENABLE. + * DMA mode frees the CPU from FIFO polling but requires aligned buffers. */ +#ifdef CONFIG_USB_DWC2_DMA_ENABLE + .device_dma_enable = true, +#else + .device_dma_enable = false, +#endif + + /* Scatter-Gather descriptor DMA: not supported by this hardware + * (GHWCFG4.DESC_DMA_ENABLED = 0). */ + .device_dma_desc_enable = false, + + /* Shared RX FIFO depth for device mode, in 32-bit words. + * All OUT endpoints and SETUP packets share this single FIFO. + * Minimum formula: + * RX >= (5*ctrl_eps + 8) + (max_pkt/4 + 1) + (2*OUT_eps) + 1 + * With HS MPS=512 and 7 OUT eps: (5+8) + (129) + (14) + 1 = 157 words min. + * 512 words (2048 bytes) matches Nations CDC demo (RX_FIFO_HS_SIZE=512). + * Hardware limit: GRXFSIZ.RXFDEP max = 1024. + * To redistribute, define CONFIG_USB_DWC2_CUSTOM_FIFO; keep total <= 1024. */ + .device_rx_fifo_size = 512, + + /* Per-IN-endpoint dedicated TX FIFO depths, in 32-bit words. + * Index matches endpoint number: [0]=EP0, [1]=EP1, ..., [8]=EP8. + * N32H47x_48x has EP0 (control) + EP1..EP8 (IN); [9]..[15] unused. + * + * Current allocation (512 words TX + 512 words RX = 1024 words total): + * [0] EP0: 64 words (256 bytes) -- control, buffers 4x 64-byte HS packets. + * Matches Nations TX0_FIFO_HS_SIZE = 64. + * [1] EP1: 256 words (1024 bytes) -- primary HS bulk/isochronous endpoint. + * Double-buffers one HS bulk packet (512 bytes max). + * Matches Nations TX1_FIFO_HS_SIZE = 256. + * [2] EP2: 64 words (256 bytes) -- interrupt or secondary bulk. + * [3] EP3: 64 words (256 bytes) -- same. + * [4] EP4: 64 words (256 bytes) -- same. + * [5]..[8]: 0 -- EP5..EP8 unallocated by default. + * Use CONFIG_USB_DWC2_CUSTOM_FIFO to add more IN endpoints; + * sum of all TX entries must stay <= (1024 - device_rx_fifo_size). + * Per-FIFO hardware limit: INEPTXFDEP max = 768 words. */ + .device_tx_fifo_size = { + [0] = 64, /* EP0: 256 bytes, control */ + [1] = 256, /* EP1: 1024 bytes, HS bulk/iso primary */ + [2] = 64, /* EP2: 256 bytes */ + [3] = 64, /* EP3: 256 bytes */ + [4] = 64, /* EP4: 256 bytes */ + [5] = 0, /* EP5..EP8: unallocated, use CUSTOM_FIFO to enable */ + [6] = 0, + [7] = 0, + [8] = 0, + [9] = 0, /* [9]..[15]: invalid for N32H47x_48x (only EP0..EP8 exist) */ + [10] = 0, + [11] = 0, + [12] = 0, + [13] = 0, + [14] = 0, + [15] = 0, + }, + + /* Host descriptor DMA: not supported, same reason as device_dma_desc_enable. */ + .host_dma_desc_enable = false, + + /* Host mode shared RX FIFO depth, in 32-bit words. + * All host channel IN data shares this single FIFO. + * Minimum formula: + * Host RX >= (max_pkt/4 + 1) + 1 + * With HS MPS=1024: (256 + 1) + 1 = 258 words min. + * 512 words matches Nations Host demo (RX_FIFO_HS_SIZE=512). */ + .host_rx_fifo_size = 512, + + /* Host non-periodic TX FIFO depth (control + bulk OUT), in 32-bit words. + * Recommended >= max_nonperiodic_pkt/4; double for pipelining. + * HS MPS=512: 512/4 = 128 words min; 256 words provides double-buffering. + * Matches Nations Host demo (TXH_NP_HS_FIFOSIZE=256). + * Hardware limit: NPTXFDEP max = 1024. */ + .host_nperio_tx_fifo_size = 256, + + /* Host periodic TX FIFO depth (interrupt + isochronous OUT), in 32-bit words. + * Recommended >= max_periodic_pkt/4; double for isochronous. + * HS iso MPS=1024: 1024/4 = 256 words min. + * Matches Nations Host demo (TXH_P_HS_FIFOSIZE=256). + * Host FIFO total: 512 + 256 + 256 = 1024 words, fills the 4 KB RAM exactly. */ + .host_perio_tx_fifo_size = 256, + + /* Extra bits OR'd into GCCFG for device mode. + * Some DWC2 platforms use GCCFG to enable VBUS sensing via an external PHY. + * N32H47x_48x PHY is controlled through RCC USBHSCTRL1/2, not GCCFG, + * so no additional bits are needed. */ + .device_gccfg = 0, + + /* Same as device_gccfg but applied in host mode. */ + .host_gccfg = 0, + + /* Set to true to bypass VBUS hardware sensing on boards that do not route + * USB VBUS to a GPIO sense pin. false = rely on hardware VBUS detection. */ + .b_session_valid_override = true, + + /* Total FIFO RAM depth, in 32-bit words. + * CherryUSB asserts at init: device_rx + sum(device_tx) <= total_fifo_size. + * N32H47x_48x has 4 KB dedicated FIFO RAM = 1024 x 32-bit words; + * GRXFSIZ.RXFDEP max = 1024. */ + .total_fifo_size = 1024, +}; + +#ifndef CONFIG_USB_DWC2_CUSTOM_PARAM +void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params) +{ + memcpy(params, ¶m_n32h47x_48x, sizeof(struct dwc2_user_params)); +#ifdef CONFIG_USB_DWC2_CUSTOM_FIFO + struct usb_dwc2_user_fifo_config s_dwc2_fifo_config; + + dwc2_get_user_fifo_config(reg_base, &s_dwc2_fifo_config); + + params->device_rx_fifo_size = s_dwc2_fifo_config.device_rx_fifo_size; + for (uint8_t i = 0; i < MAX_EPS_CHANNELS; i++) + { + params->device_tx_fifo_size[i] = s_dwc2_fifo_config.device_tx_fifo_size[i]; + } +#endif /* CONFIG_USB_DWC2_CUSTOM_FIFO */ +} +#endif /* CONFIG_USB_DWC2_CUSTOM_PARAM */ + +#elif defined(N32H49X) + +/* + * N32H49x series: single USBHS controller, internal HS UTMI+ PHY (8-bit bus). + * + * FIFO RAM: 4 KB (1024 x 32-bit words). + * USBHS base address: 0x40040000 (AHBPERIPH_BASE + 0x20000). + * IRQ: USB_HS_IRQn (62), USB_HS_WKUP_IRQn (84). + */ + +#include "n32h49x_rcc.h" +#include "n32h49x_gpio.h" +#include "misc.h" +#include "usb_dwc2_param.h" + +typedef void (*usb_dwc2_irq)(uint8_t busid); + +static usb_dwc2_irq g_usb_dwc2_irq; +static volatile uint8_t g_usb_dwc2_busid = 0; + +static void usbhs_common_init(void) +{ + RCC_EnableAHB1PeriphClk(RCC_AHB_PERIPHEN_GPIOA | RCC_AHB_PERIPHEN_GPIOB, ENABLE); +#if (HSE_VALUE == 8000000) + /* System PLL = 240 MHz; divide by 15 to produce 16 MHz USB PHY reference. */ + RCC_ConfigUSBPLLPresClk(RCC_USBPLLCLK_SRC_PLL, RCC_USBPLLCLK_DIV15); + RCC_ConfigUSBHSBandwidth(RCC_USBHS_BW_16M); + RCC_ConfigUSBHSFrequency(RCC_USBHS_FREQ_16_OR_32M); + RCC_ConfigUSBHSClk(RCC_USBHS_CLKSRC_PLLPRES); +#else /* HSE 16 MHz — feed directly to USBHS */ + RCC_ConfigUSBHSBandwidth(RCC_USBHS_BW_16M); + RCC_ConfigUSBHSFrequency(RCC_USBHS_FREQ_16_OR_32M); + RCC_ConfigUSBHSClk(RCC_USBHS_CLKSRC_HSE); #endif - // VBUS - // GPIO_InitStructure.Pin = GPIO_PIN_13; - // GPIO_InitStructure.GPIO_Mode = GPIO_MODE_INPUT; - // GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure); + RCC_EnableAHBPeriphReset(RCC_AHBPRST_USBHSPHYRST); + RCC_EnableAHBPeriphClk(RCC_AHB_PERIPHEN_USBHS, ENABLE); - // // SOF - // GPIO_InitStructure.Pin = GPIO_PIN_4; - // GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AF_PP; - // GPIO_InitStructure.GPIO_Alternate = 8; // SOF - // GPIO_InitPeripheral(GPIOA, &GPIO_InitStructure); + /* TX analog tuning for 8-bit UTMI PHY (N32H49x USBHSCTRL layout). */ + RCC->USBHSCTRL2 = (RCC->USBHSCTRL2 & (~(0xF << 4))) | (0xB << 4); /* HDCVTRIM[7:4] */ + RCC->USBHSCTRL1 = (RCC->USBHSCTRL1 & (~(0x7 << 12))) | (0x5 << 12); /* USBHSCTRL1[14:12] */ + RCC->USBHSCTRL2 = (RCC->USBHSCTRL2 & (~(0x3 << 12))) | (0x0 << 14); /* RFTRIM[13:12] = 0 (clear) */ + RCC->USBHSCTRL2 = (RCC->USBHSCTRL2 & (~(0x3 << 16))) | (0x1 << 16); /* USBHSCTRL2[17:16] */ + + NVIC_InitType NVIC_InitStructure; - // // ID - // GPIO_InitStructure.Pin = GPIO_PIN_12; - // GPIO_InitStructure.GPIO_Mode = GPIO_MODE_AF_PP; - // GPIO_InitStructure.GPIO_Alternate = 14; // ID - // GPIO_InitPeripheral(GPIOB, &GPIO_InitStructure); + NVIC_InitStructure.NVIC_IRQChannel = USB_HS_IRQn; + NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; + NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; + NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&NVIC_InitStructure); } +/* Override in the board layer to configure USB DM/DP alternate-function pins. + * In host mode, also drive any VBUS power-switch GPIO here (e.g. board/ports/usb_gpio.c). */ +__weak void n32h49x_usbhs_gpio_init(void) { } + void usb_dc_low_level_init(uint8_t busid) { g_usb_dwc2_irq = USBD_IRQHandler; g_usb_dwc2_busid = busid; + n32h49x_usbhs_gpio_init(); usbhs_common_init(); RCC->USBHSCTRL2 |= (uint32_t)0x01 << 19; @@ -135,7 +386,7 @@ void usb_dc_low_level_deinit(uint8_t busid) NVIC_Init(&NVIC_InitStructure); RCC_EnableAHBPeriphReset(RCC_AHBPRST_USBHSPHYRST); - /* Enables the USBHS peripheral clock*/ + /* Disable the USBHS peripheral clock. */ RCC_EnableAHBPeriphClk(RCC_AHB_PERIPHEN_USBHS, DISABLE); } @@ -144,6 +395,7 @@ void usb_hc_low_level_init(struct usbh_bus *bus) g_usb_dwc2_irq = USBH_IRQHandler; g_usb_dwc2_busid = 0; + n32h49x_usbhs_gpio_init(); usbhs_common_init(); RCC->USBHSCTRL2 &= ~(uint32_t)0x01 << 19; @@ -161,7 +413,7 @@ void usb_hc_low_level_deinit(struct usbh_bus *bus) NVIC_Init(&NVIC_InitStructure); RCC_EnableAHBPeriphReset(RCC_AHBPRST_USBHSPHYRST); - /* Enables the USBHS peripheral clock*/ + /* Disable the USBHS peripheral clock. */ RCC_EnableAHBPeriphClk(RCC_AHB_PERIPHEN_USBHS, DISABLE); } @@ -180,14 +432,595 @@ void USB_HS_IRQHandler(void) g_usb_dwc2_irq(g_usb_dwc2_busid); } -extern uint32_t SystemCoreClock; +void usbd_dwc2_delay_ms(uint8_t ms) +{ + RCC_ClocksType RCC_clocks = { 0 }; + + RCC_GetClocksFreqValue(&RCC_clocks); + uint32_t count = RCC_clocks.SysclkFreq / 1000U * ms; + while (count--) + { + __asm volatile("nop"); + } +} + +uint32_t usbd_dwc2_get_system_clock(void) +{ + RCC_ClocksType RCC_clocks = { 0 }; + + RCC_GetClocksFreqValue(&RCC_clocks); + return RCC_clocks.SysclkFreq; +} + +/* + * N32H49x USBHS has 4 KB (1024 x 32-bit words) of dedicated FIFO RAM. + * + * Internal HS UTMI+ PHY, 8-bit data bus (GCFG.PHYIF = 0). + * PHY is configured via RCC USBHSCTRL1/2, not DWC2 GCCFG, + * so device_gccfg / host_gccfg are both zero. + * + * FIFO layout matches N32H47x_48x CDC demo (same FIFO sizes confirmed): + * RX shared 512 words (2048 bytes) + * EP0 IN TX 64 words ( 256 bytes) + * EP1 IN TX 256 words (1024 bytes) + * EP2 IN TX 64 words ( 256 bytes) + * EP3 IN TX 64 words ( 256 bytes) + * EP4 IN TX 64 words ( 256 bytes) + * Total 1024 words (4096 bytes) + * + * Host FIFO layout: + * RX 512 words (2048 bytes) + * Non-periodic TX 256 words (1024 bytes) + * Periodic TX 256 words (1024 bytes) + * Total 1024 words (4096 bytes) + */ +static const struct dwc2_user_params param_n32h49x = +{ + .phy_type = DWC2_PHY_TYPE_PARAM_UTMI, + + /* 8-bit UTMI data bus (GCFG.PHYIF = 0). + * USB_CoreInit() in usbhs_core.c explicitly clears PHYIF. */ + .phy_utmi_width = 8, + +#ifdef CONFIG_USB_DWC2_DMA_ENABLE + .device_dma_enable = true, +#else + .device_dma_enable = false, +#endif + + /* Scatter-Gather descriptor DMA: not supported (GHWCFG4.DESC_DMA_ENABLED = 0). */ + .device_dma_desc_enable = false, + + /* Shared RX FIFO: 512 words (2048 bytes). */ + .device_rx_fifo_size = 512, + + .device_tx_fifo_size = { + [0] = 64, /* EP0: 256 bytes, control */ + [1] = 256, /* EP1: 1024 bytes, HS bulk/iso primary */ + [2] = 64, /* EP2: 256 bytes */ + [3] = 64, /* EP3: 256 bytes */ + [4] = 64, /* EP4: 256 bytes */ + [5] = 0, /* EP5..EP8: unallocated, use CUSTOM_FIFO to enable */ + [6] = 0, + [7] = 0, + [8] = 0, + [9] = 0, /* [9]..[15]: invalid for N32H49x (only EP0..EP8 exist) */ + [10] = 0, + [11] = 0, + [12] = 0, + [13] = 0, + [14] = 0, + [15] = 0, + }, + + /* Host descriptor DMA: not supported, same reason as device_dma_desc_enable. */ + .host_dma_desc_enable = false, + + /* Host RX: 512 words (2048 bytes). */ + .host_rx_fifo_size = 512, + + /* Host non-periodic TX (control + bulk OUT): 256 words (1024 bytes). */ + .host_nperio_tx_fifo_size = 256, + + /* Host periodic TX (interrupt + iso OUT): 256 words. + * Host FIFO total: 512 + 256 + 256 = 1024 words, fills 4 KB RAM exactly. */ + .host_perio_tx_fifo_size = 256, + + /* N32H49x PHY is controlled through RCC USBHSCTRL1/2, not DWC2 GCCFG. */ + .device_gccfg = 0, + .host_gccfg = 0, + + /* Set to true to bypass VBUS hardware sensing on boards that do not route + * USB VBUS to a GPIO sense pin. false = rely on hardware VBUS detection. */ + .b_session_valid_override = true, + + /* 4 KB dedicated FIFO RAM = 1024 x 32-bit words. */ + .total_fifo_size = 1024, +}; + +#ifndef CONFIG_USB_DWC2_CUSTOM_PARAM +void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params) +{ + memcpy(params, ¶m_n32h49x, sizeof(struct dwc2_user_params)); +#ifdef CONFIG_USB_DWC2_CUSTOM_FIFO + struct usb_dwc2_user_fifo_config s_dwc2_fifo_config; + + dwc2_get_user_fifo_config(reg_base, &s_dwc2_fifo_config); + + params->device_rx_fifo_size = s_dwc2_fifo_config.device_rx_fifo_size; + for (uint8_t i = 0; i < MAX_EPS_CHANNELS; i++) + { + params->device_tx_fifo_size[i] = s_dwc2_fifo_config.device_tx_fifo_size[i]; + } +#endif /* CONFIG_USB_DWC2_CUSTOM_FIFO */ +} +#endif /* CONFIG_USB_DWC2_CUSTOM_PARAM */ + +#elif defined(N32H73x) || defined(N32H76x) || defined(N32H73x_76x) || defined(N32H78x) + +/* + * N32H7xx series: dual USBHS controllers (USBHS1 + USBHS2). + * + * Each controller is a DWC2 IP core with an internal HS UTMI+ PHY + * accessed through a Wrapper register block (WRPCFG / WRPCTRL). + * The PHY uses a 16-bit UTMI data bus (GCFG.PHYIF = 1). + * + * Controller base addresses: + * USBHS1 core: 0x40100000 wrapper: 0x40140000 + * USBHS2 core: 0x40060000 wrapper: 0x400A0000 + * + * busid convention used by this glue layer: + * busid 0 -> USBHS1 (PA11=DM, PA12=DP, USB1_HS_IRQn, EXTI_LINE62) + * busid 1 -> USBHS2 (PB14=DM, PB15=DP, USB2_HS_IRQn, EXTI_LINE63) + * + * For usb_hc_low_level_init the controller is identified by bus->hcd.reg_base + * rather than busid to avoid aliasing with the device busid namespace in + * dual-USB (one host + one device) configurations. + * + * Both controllers share identical DWC2 hardware parameters and + * 4 KB (1024-word) dedicated FIFO RAM. + */ + +#include "n32h7xx_rcc.h" +#include "n32h7xx_gpio.h" +#include "n32h7xx_pwr.h" +#include "misc.h" +#include "n32h7xx.h" +#include "usb_dwc2_param.h" + +#define N32H7XX_USBHS1_BASE 0x40100000U +#define N32H7XX_USBHS2_BASE 0x40060000U +#define N32H7XX_USBHS1_WRAP 0x40140000U +#define N32H7XX_USBHS2_WRAP 0x400A0000U + +typedef void (*usb_dwc2_irq_fn)(uint8_t busid); + +/* Per-controller IRQ dispatch: index 0 = USBHS1, index 1 = USBHS2. */ +static struct +{ + usb_dwc2_irq_fn fn; + uint8_t busid; +} g_n32h7xx_irq[2]; void usbd_dwc2_delay_ms(uint8_t ms) { - uint32_t count = SystemCoreClock / 1000 * ms; - while (count--) { + RCC_ClocksTypeDef RCC_Clocks = { 0 }; + + RCC_GetClocksFreqValue(&RCC_Clocks); + uint32_t count = RCC_Clocks.SysClkFreq / 1000U * ms; + while (count--) + { __asm volatile("nop"); } } +uint32_t usbd_dwc2_get_system_clock(void) +{ + RCC_ClocksTypeDef RCC_Clocks = { 0 }; + + RCC_GetClocksFreqValue(&RCC_Clocks); + return RCC_Clocks.SysClkFreq; +} + +/* + * Wrapper register init: configure PHY PLL clock source, enable PLL, + * set IDSIG (device/host role), enable ID-pin detection, then pulse + * the PHY power-on reset. + * + * IDSIG MUST be set here, before USB_CoreInit() runs. + * USB_CoreInitHost() does NOT clear IDSIG, so if left at 1 the host + * controller cannot operate. When two controllers run simultaneously + * (one host + one device) failing to clear IDSIG on the host is the + * root cause of host malfunction. + * + * is_device: true -> IDSIG = 1 (device role) + * false -> IDSIG = 0 (host role) + * is_usbhs1: selects the RCC PHY reset register (AHB2 vs AHB1). + */ +static void n32h7xx_wrapper_init(uint32_t wrap_base, bool is_device, bool is_usbhs1) +{ + USB_Wrapper_Registers *wrap = (USB_Wrapper_Registers *)wrap_base; + uint32_t wrpcfg; + uint32_t wrpctrl; + + wrpcfg = wrap->WRPCFG; + wrpcfg &= ~USBHS_WRPCFG_PHYCLKSEL; + +#if (HSE_VALUE == 10000000U) + wrpcfg |= USBHS_WRPCFG_PHYCLKSEL_10M; +#elif (HSE_VALUE == 12000000U) + wrpcfg |= USBHS_WRPCFG_PHYCLKSEL_12M; +#elif (HSE_VALUE == 19200000U) + wrpcfg |= USBHS_WRPCFG_PHYCLKSEL_19_2M; +#elif (HSE_VALUE == 24000000U) + wrpcfg |= USBHS_WRPCFG_PHYCLKSEL_24M; +#elif (HSE_VALUE == 25000000U) + wrpcfg |= USBHS_WRPCFG_PHYCLKSEL_25M; +#elif (HSE_VALUE == 27000000U) + wrpcfg |= USBHS_WRPCFG_PHYCLKSEL_27M; +#elif (HSE_VALUE == 30000000U) + wrpcfg |= USBHS_WRPCFG_PHYCLKSEL_30M; +#elif (HSE_VALUE == 40000000U) + wrpcfg |= USBHS_WRPCFG_PHYCLKSEL_40M; +#else +#error "Unsupported HSE_VALUE for N32H7xx USBHS PHY. Supported: 10/12/19.2/24/25/27/30/40 MHz." +#endif + + wrpcfg |= USBHS_WRPCFG_PLLEN; + + if (is_device) + { + wrpcfg |= USBHS_WRPCFG_IDSIG; + } + else + { + wrpcfg &= ~USBHS_WRPCFG_IDSIG; + } + + wrap->WRPCFG = wrpcfg; + + wrpctrl = wrap->WRPCTRL; + wrpctrl |= USBHS_WRPCTRL_PINDETEN; + wrap->WRPCTRL = wrpctrl; + + if (is_usbhs1) + { + RCC_EnableAHB2PeriphReset1(RCC_AHB2_PERIPHRST_USB1POR); + } + else + { + RCC_EnableAHB1PeriphReset1(RCC_AHB1_PERIPHRST_USB2POR); + } + + usbd_dwc2_delay_ms(1); +} + +/* ----------------------------------------------------------------------- + * GPIO init: weak stubs — override in your board layer. + * Implement n32h7xx_usbhs1_gpio_init / n32h7xx_usbhs2_gpio_init to configure + * the DM/DP pins (and optionally SOF/ID) for your specific board. + * In host mode, also drive any VBUS power-switch GPIO here. + * ----------------------------------------------------------------------- */ +__weak void n32h7xx_usbhs1_gpio_init(void) { } +__weak void n32h7xx_usbhs2_gpio_init(void) { } + +/* ----------------------------------------------------------------------- + * NVIC + init + * ----------------------------------------------------------------------- */ +static void n32h7xx_usbhs1_irq_enable(void) +{ + NVIC_InitType nvic; + + nvic.NVIC_IRQChannel = USB1_HS_IRQn; + nvic.NVIC_IRQChannelPreemptionPriority = 1; + nvic.NVIC_IRQChannelSubPriority = 3; + nvic.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&nvic); +} + +static void n32h7xx_usbhs2_irq_enable(void) +{ + NVIC_InitType nvic; + + nvic.NVIC_IRQChannel = USB2_HS_IRQn; + nvic.NVIC_IRQChannelPreemptionPriority = 1; + nvic.NVIC_IRQChannelSubPriority = 3; + nvic.NVIC_IRQChannelCmd = ENABLE; + NVIC_Init(&nvic); +} + +/* ----------------------------------------------------------------------- + * Per-controller hardware bringup + * ----------------------------------------------------------------------- */ +static void n32h7xx_usbhs1_hw_init(uint8_t busid, usb_dwc2_irq_fn irq_fn) +{ + /* AFIO alternate-function remapping clock */ + RCC_EnableAHB5PeriphClk2(RCC_AHB5_PERIPHEN_M7_AFIO, ENABLE); + + n32h7xx_usbhs1_gpio_init(); + + /* Route HSE directly to the USB PHY reference clock input. + * HSE must already be running (done by system clock init). + * PHYCLKSEL in WRPCFG must match the resulting frequency. */ + RCC_ConfigUSBRefClk(RCC_USBREFCLK_HSE_DIV1); + + /* PWR peripheral clock is required before calling PWR_MoudlePowerEnable. */ + RCC_EnableAHB5PeriphClk2(RCC_AHB5_PERIPHEN_PWR, ENABLE); + + /* Enable USBHS1 peripheral clock (AHB2). */ + RCC_EnableAHB2PeriphClk1(RCC_AHB2_PERIPHEN_M7_USB1, ENABLE); + + /* Power up the USBHS1 hardware module. Without this the USB core + * registers are inaccessible and the PHY will not start. */ + PWR_MoudlePowerEnable(HSC1_USB1_PWRCTRL, ENABLE); + + g_n32h7xx_irq[0].fn = irq_fn; + g_n32h7xx_irq[0].busid = busid; + n32h7xx_usbhs1_irq_enable(); +} + +static void n32h7xx_usbhs2_hw_init(uint8_t busid, usb_dwc2_irq_fn irq_fn) +{ + RCC_EnableAHB5PeriphClk2(RCC_AHB5_PERIPHEN_M7_AFIO, ENABLE); + + n32h7xx_usbhs2_gpio_init(); + + RCC_ConfigUSBRefClk(RCC_USBREFCLK_HSE_DIV1); + + RCC_EnableAHB5PeriphClk2(RCC_AHB5_PERIPHEN_PWR, ENABLE); + + /* Enable USBHS2 peripheral clock (AHB1). */ + RCC_EnableAHB1PeriphClk1(RCC_AHB1_PERIPHEN_M7_USB2, ENABLE); + + /* Power up the USBHS2 hardware module. */ + PWR_MoudlePowerEnable(HSC2_USB2_PWRCTRL, ENABLE); + + g_n32h7xx_irq[1].fn = irq_fn; + g_n32h7xx_irq[1].busid = busid; + n32h7xx_usbhs2_irq_enable(); +} + +/* ----------------------------------------------------------------------- + * Device mode + * ----------------------------------------------------------------------- */ +void usb_dc_low_level_init(uint8_t busid) +{ + /* Identify the controller by reg_base, not busid. + * busid is a user-assigned index and does not imply a fixed controller mapping. */ + if (g_usbdev_bus[busid].reg_base == N32H7XX_USBHS1_BASE) + { + n32h7xx_usbhs1_hw_init(busid, USBD_IRQHandler); + n32h7xx_wrapper_init(N32H7XX_USBHS1_WRAP, true, true); + } + else + { + n32h7xx_usbhs2_hw_init(busid, USBD_IRQHandler); + n32h7xx_wrapper_init(N32H7XX_USBHS2_WRAP, true, false); + } +} + +void usb_dc_low_level_deinit(uint8_t busid) +{ + NVIC_InitType nvic; + + if (g_usbdev_bus[busid].reg_base == N32H7XX_USBHS1_BASE) + { + nvic.NVIC_IRQChannel = USB1_HS_IRQn; + nvic.NVIC_IRQChannelCmd = DISABLE; + NVIC_Init(&nvic); + RCC_EnableAHB2PeriphReset1(RCC_AHB2_PERIPHRST_USB1POR); + RCC_EnableAHB2PeriphClk1(RCC_AHB2_PERIPHEN_M7_USB1, DISABLE); + } + else + { + nvic.NVIC_IRQChannel = USB2_HS_IRQn; + nvic.NVIC_IRQChannelCmd = DISABLE; + NVIC_Init(&nvic); + RCC_EnableAHB1PeriphReset1(RCC_AHB1_PERIPHRST_USB2POR); + RCC_EnableAHB1PeriphClk1(RCC_AHB1_PERIPHEN_M7_USB2, DISABLE); + } +} + +/* ----------------------------------------------------------------------- + * Host mode + * ----------------------------------------------------------------------- */ +void usb_hc_low_level_init(struct usbh_bus *bus) +{ + if (bus->hcd.reg_base == N32H7XX_USBHS1_BASE) + { + n32h7xx_usbhs1_hw_init(bus->busid, USBH_IRQHandler); + n32h7xx_wrapper_init(N32H7XX_USBHS1_WRAP, false, true); + } + else + { + n32h7xx_usbhs2_hw_init(bus->busid, USBH_IRQHandler); + n32h7xx_wrapper_init(N32H7XX_USBHS2_WRAP, false, false); + } +} + +void usb_hc_low_level_deinit(struct usbh_bus *bus) +{ + NVIC_InitType nvic; + + if (bus->hcd.reg_base == N32H7XX_USBHS1_BASE) + { + nvic.NVIC_IRQChannel = USB1_HS_IRQn; + nvic.NVIC_IRQChannelCmd = DISABLE; + NVIC_Init(&nvic); + RCC_EnableAHB2PeriphReset1(RCC_AHB2_PERIPHRST_USB1POR); + RCC_EnableAHB2PeriphClk1(RCC_AHB2_PERIPHEN_M7_USB1, DISABLE); + } + else + { + nvic.NVIC_IRQChannel = USB2_HS_IRQn; + nvic.NVIC_IRQChannelCmd = DISABLE; + NVIC_Init(&nvic); + RCC_EnableAHB1PeriphReset1(RCC_AHB1_PERIPHRST_USB2POR); + RCC_EnableAHB1PeriphClk1(RCC_AHB1_PERIPHEN_M7_USB2, DISABLE); + } +} + +/* PHY is controlled via Wrapper registers, not GCCFG. */ +uint32_t usbd_get_dwc2_gccfg_conf(uint32_t reg_base) +{ + return 0; +} + +uint32_t usbh_get_dwc2_gccfg_conf(uint32_t reg_base) +{ + return 0; +} + +/* ----------------------------------------------------------------------- + * IRQ handlers -- one per controller, fixed at link time. + * ----------------------------------------------------------------------- */ +void USB1_HS_IRQHandler(void) +{ + g_n32h7xx_irq[0].fn(g_n32h7xx_irq[0].busid); +} + +void USB2_HS_IRQHandler(void) +{ + g_n32h7xx_irq[1].fn(g_n32h7xx_irq[1].busid); +} + +/* + * N32H7xx USBHS DWC2 parameters (applies to both USBHS1 and USBHS2). + * + * Both controllers have identical hardware: 4 KB FIFO RAM (1024 words), + * 16-bit UTMI PHY, no descriptor DMA. Differs from N32H47x_48x only in + * phy_utmi_width = 16 (GCFG.PHYIF = 1). + * + * Device FIFO layout (1024 words, 4096 bytes): + * RX shared 512 words (2048 bytes) + * EP0 IN TX 64 words ( 256 bytes) -- control + * EP1 IN TX 256 words (1024 bytes) -- primary HS bulk/iso + * EP2 IN TX 64 words ( 256 bytes) + * EP3 IN TX 64 words ( 256 bytes) + * EP4 IN TX 64 words ( 256 bytes) + * Total 1024 words (4096 bytes) + * + * Host FIFO layout (1024 words, 4096 bytes): + * RX 512 words (2048 bytes) + * Non-periodic TX 256 words (1024 bytes) + * Periodic TX 256 words (1024 bytes) + * Total 1024 words (4096 bytes) + * + * Adjust via CONFIG_USB_DWC2_CUSTOM_FIFO or CONFIG_USB_DWC2_CUSTOM_PARAM; + * keep RX + sum(TX) <= 1024 words. + */ +static const struct dwc2_user_params param_n32h7xx = +{ + /* Built-in HS UTMI+ PHY; GUSBCFG.ULPI_UTMI_SEL = 0. */ + .phy_type = DWC2_PHY_TYPE_PARAM_UTMI, + + /* 16-bit UTMI data bus (GCFG.PHYIF = 1). + * USB_CoreInit() sets PHYIF via USBHS_GCFG_PHYIF. + * CherryUSB sets GUSBCFG.PHYIF16 only when phy_utmi_width == 16. + * GCFG.PHYIF: 0 = 8-bit bus, 1 = 16-bit bus. */ + .phy_utmi_width = 16, + +#ifdef CONFIG_USB_DWC2_DMA_ENABLE + .device_dma_enable = true, +#else + .device_dma_enable = false, +#endif + + /* Scatter-Gather descriptor DMA: not supported (GHWCFG4.DESC_DMA_ENABLED = 0). */ + .device_dma_desc_enable = false, + + /* Shared RX FIFO depth for device mode, in 32-bit words. + * Minimum formula: (5+8) + (512/4+1) + (2*7) + 1 = 157 words. + * 512 words matches Nations CDC demo (RX_FIFO_HS_SIZE = 512). + * Hardware limit: RXFDEP max = 1024 words. */ + .device_rx_fifo_size = 512, + + /* Per-IN-endpoint TX FIFO depths, in 32-bit words. + * 512 TX + 512 RX = 1024 words total. + * Per-FIFO hardware limit: INEPTXFDEP max = 768 words. */ + .device_tx_fifo_size = { + [0] = 64, /* EP0: 256 bytes, control; matches TX0_FIFO_HS_SIZE = 64 */ + [1] = 256, /* EP1: 1024 bytes, HS bulk/iso; matches TX1_FIFO_HS_SIZE = 256 */ + [2] = 64, /* EP2: 256 bytes */ + [3] = 64, /* EP3: 256 bytes */ + [4] = 64, /* EP4: 256 bytes */ + [5] = 0, /* EP5..EP8: unallocated; use CONFIG_USB_DWC2_CUSTOM_FIFO to enable */ + [6] = 0, + [7] = 0, + [8] = 0, + [9] = 0, + [10] = 0, + [11] = 0, + [12] = 0, + [13] = 0, + [14] = 0, + [15] = 0, + }, + + .host_dma_desc_enable = false, + + /* Host RX FIFO: 512 words (min formula: (1024/4+1)+1 = 258 words). */ + .host_rx_fifo_size = 512, + + /* Host NP TX FIFO: 256 words (double-buffer, HS MPS = 512 bytes). + * Matches Nations Host demo (TXH_NP_HS_FIFOSIZE = 256). */ + .host_nperio_tx_fifo_size = 256, + + /* Host periodic TX FIFO: 256 words (HS iso MPS = 1024: 1024/4 = 256 min). + * Matches Nations Host demo (TXH_P_HS_FIFOSIZE = 256). + * Host total: 512 + 256 + 256 = 1024 words. */ + .host_perio_tx_fifo_size = 256, + + /* PHY controlled via Wrapper registers (WRPCFG/WRPCTRL), not GCCFG. */ + .device_gccfg = 0, + .host_gccfg = 0, + + /* Set to true to bypass VBUS hardware sensing on boards that do not route + * USB VBUS to a GPIO sense pin. false = rely on hardware VBUS detection. */ + .b_session_valid_override = true, + + /* 4 KB dedicated FIFO RAM = 1024 x 32-bit words; GRXFSIZ.RXFDEP max = 1024. */ + .total_fifo_size = 1024, +}; + +#ifndef CONFIG_USB_DWC2_CUSTOM_PARAM +void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params) +{ + memcpy(params, ¶m_n32h7xx, sizeof(struct dwc2_user_params)); +#ifdef CONFIG_USB_DWC2_CUSTOM_FIFO + struct usb_dwc2_user_fifo_config s_dwc2_fifo_config; + + dwc2_get_user_fifo_config(reg_base, &s_dwc2_fifo_config); + params->device_rx_fifo_size = s_dwc2_fifo_config.device_rx_fifo_size; + for (uint8_t i = 0; i < MAX_EPS_CHANNELS; i++) + { + params->device_tx_fifo_size[i] = s_dwc2_fifo_config.device_tx_fifo_size[i]; + } +#endif /* CONFIG_USB_DWC2_CUSTOM_FIFO */ +} +#endif /* CONFIG_USB_DWC2_CUSTOM_PARAM */ + +#endif /* N32H73x || N32H76x || N32H78x */ + +/* USB DMA buffers reside in AXI SRAM (D-Cache enabled). + * The DWC2 AHB DMA master cannot reach DTCM/TCM, so buffers are placed in + * normal cached SRAM. Cache coherency is maintained via CMSIS SCB helpers: + * clean -- flush CPU write-buffer to SRAM before DMA TX + * invalidate -- discard stale cache lines after DMA RX + * flush -- clean + invalidate (bi-directional transfers) */ +#ifdef CONFIG_USB_DCACHE_ENABLE +void usb_dcache_clean(uintptr_t addr, size_t size) +{ + SCB_CleanDCache_by_Addr((void *)addr, size); +} + +void usb_dcache_invalidate(uintptr_t addr, size_t size) +{ + SCB_InvalidateDCache_by_Addr((void *)addr, size); +} + +void usb_dcache_flush(uintptr_t addr, size_t size) +{ + SCB_CleanInvalidateDCache_by_Addr((void *)addr, size); +} #endif From d7ae6e985b5b4cbe1a916091421d558882f4e724 Mon Sep 17 00:00:00 2001 From: OnlyoutzZ Date: Fri, 26 Jun 2026 08:19:13 +0000 Subject: [PATCH 3/3] style: format code with clang-format [skip ci] --- .../usb/cherryusb/class/hid/usbd_hid.c | 1 - .../usb/cherryusb/common/usb_version.h | 1 - .../usb/cherryusb/osal/usb_osal_rtthread.c | 1 - .../usb/cherryusb/port/dwc2/usb_dwc2_param.h | 73 ++++--- .../usb/cherryusb/port/dwc2/usb_glue_nation.c | 187 ++++++++---------- 5 files changed, 120 insertions(+), 143 deletions(-) diff --git a/components/drivers/usb/cherryusb/class/hid/usbd_hid.c b/components/drivers/usb/cherryusb/class/hid/usbd_hid.c index c882c9c0889..41e8bde34ce 100644 --- a/components/drivers/usb/cherryusb/class/hid/usbd_hid.c +++ b/components/drivers/usb/cherryusb/class/hid/usbd_hid.c @@ -123,4 +123,3 @@ __WEAK void usbd_hid_set_protocol(uint8_t busid, uint8_t intf, uint8_t protocol) (void)intf; (void)protocol; } - diff --git a/components/drivers/usb/cherryusb/common/usb_version.h b/components/drivers/usb/cherryusb/common/usb_version.h index fe040707efd..ed72b204671 100644 --- a/components/drivers/usb/cherryusb/common/usb_version.h +++ b/components/drivers/usb/cherryusb/common/usb_version.h @@ -19,4 +19,3 @@ #define CHERRYUSB_VERSION_STR "v1.6.1" #endif - diff --git a/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c b/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c index 4f3dc3e223b..0fa655adfa8 100644 --- a/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c +++ b/components/drivers/usb/cherryusb/osal/usb_osal_rtthread.c @@ -227,4 +227,3 @@ void usb_osal_free(void *ptr) { rt_free(ptr); } - diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_dwc2_param.h b/components/drivers/usb/cherryusb/port/dwc2/usb_dwc2_param.h index 3300f3dc906..d741dbcce14 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/usb_dwc2_param.h +++ b/components/drivers/usb/cherryusb/port/dwc2/usb_dwc2_param.h @@ -217,41 +217,41 @@ struct dwc2_hw_params { uint32_t snpsid; uint32_t dev_ep_dirs; - unsigned op_mode : 3; - unsigned arch : 2; - unsigned enable_dynamic_fifo : 1; - unsigned host_channels : 5; - unsigned hs_phy_type : 2; - unsigned fs_phy_type : 2; - unsigned num_dev_ep : 4; - unsigned nperio_tx_q_depth : 3; - unsigned host_perio_tx_q_depth : 3; - unsigned dev_token_q_depth : 5; - - unsigned max_transfer_size : 26; - unsigned max_packet_count : 11; - unsigned i2c_enable : 1; - unsigned total_fifo_size : 16; - unsigned lpm_mode : 1; - - unsigned en_multiple_tx_fifo : 1; - unsigned num_dev_in_eps : 4; - unsigned num_dev_perio_in_ep : 4; - unsigned dma_desc_enable : 1; - unsigned power_optimized : 1; - unsigned hibernation : 1; - unsigned utmi_phy_data_width : 2; - unsigned acg_enable : 1; - unsigned ipg_isoc_en : 1; - unsigned service_interval_mode : 1; + unsigned op_mode : 3; + unsigned arch : 2; + unsigned enable_dynamic_fifo : 1; + unsigned host_channels : 5; + unsigned hs_phy_type : 2; + unsigned fs_phy_type : 2; + unsigned num_dev_ep : 4; + unsigned nperio_tx_q_depth : 3; + unsigned host_perio_tx_q_depth : 3; + unsigned dev_token_q_depth : 5; + + unsigned max_transfer_size : 26; + unsigned max_packet_count : 11; + unsigned i2c_enable : 1; + unsigned total_fifo_size : 16; + unsigned lpm_mode : 1; + + unsigned en_multiple_tx_fifo : 1; + unsigned num_dev_in_eps : 4; + unsigned num_dev_perio_in_ep : 4; + unsigned dma_desc_enable : 1; + unsigned power_optimized : 1; + unsigned hibernation : 1; + unsigned utmi_phy_data_width : 2; + unsigned acg_enable : 1; + unsigned ipg_isoc_en : 1; + unsigned service_interval_mode : 1; }; -#define DWC2_PHY_TYPE_PARAM_FS 0 -#define DWC2_PHY_TYPE_PARAM_UTMI 1 -#define DWC2_PHY_TYPE_PARAM_ULPI 2 +#define DWC2_PHY_TYPE_PARAM_FS 0 +#define DWC2_PHY_TYPE_PARAM_UTMI 1 +#define DWC2_PHY_TYPE_PARAM_ULPI 2 struct dwc2_user_params { - uint8_t phy_type; + uint8_t phy_type; uint8_t phy_utmi_width; bool device_dma_enable; @@ -261,18 +261,18 @@ struct dwc2_user_params { */ uint16_t device_rx_fifo_size; /* IN Endpoints Max packet Size / 4 */ - uint16_t device_tx_fifo_size[MAX_EPS_CHANNELS]; + uint16_t device_tx_fifo_size[MAX_EPS_CHANNELS]; bool host_dma_desc_enable; /* * (largest USB packet used / 4) + 1 for status information + 1 transfer complete + * 1 location each for Bulk/Control endpoint for handling NAK/NYET scenario */ - uint16_t host_rx_fifo_size; + uint16_t host_rx_fifo_size; /* largest non-periodic USB packet used / 4 */ - uint16_t host_nperio_tx_fifo_size; + uint16_t host_nperio_tx_fifo_size; /* largest periodic USB packet used / 4 */ - uint16_t host_perio_tx_fifo_size; + uint16_t host_perio_tx_fifo_size; uint32_t device_gccfg; uint32_t host_gccfg; @@ -282,7 +282,7 @@ struct dwc2_user_params { }; struct usb_dwc2_user_fifo_config { - /* (5 * number of control endpoints + 8) + ((largest USB packet used / 4) + 1 for + /* (5 * number of control endpoints + 8) + ((largest USB packet used / 4) + 1 for * status information) + (2 * number of OUT endpoints) + 1 for Global NAK */ uint16_t device_rx_fifo_size; @@ -365,4 +365,3 @@ void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params); void dwc2_get_user_fifo_config(uint32_t reg_base, struct usb_dwc2_user_fifo_config *config); #endif - diff --git a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_nation.c b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_nation.c index 1239711688a..18ad6499aa7 100644 --- a/components/drivers/usb/cherryusb/port/dwc2/usb_glue_nation.c +++ b/components/drivers/usb/cherryusb/port/dwc2/usb_glue_nation.c @@ -44,7 +44,7 @@ static void usbhs_common_init(void) RCC_EnableAHBPeriphClk(RCC_AHB_PERIPHEN_USBHS, ENABLE); /* TX analog tuning for 8-bit UTMI PHY (N32H47x_48x USBHSCTRL2 layout). */ - RCC->USBHSCTRL2 = (RCC->USBHSCTRL2 & (~(0xF << 4))) | (0x5 << 4); /* TX vref TUNE [7:4] */ + RCC->USBHSCTRL2 = (RCC->USBHSCTRL2 & (~(0xF << 4))) | (0x5 << 4); /* TX vref TUNE [7:4] */ RCC->USBHSCTRL2 = (RCC->USBHSCTRL2 & (~(0x3 << 12))) | (0x3 << 12); /* TX Rise TUNE [13:12] */ RCC->USBHSCTRL2 = (RCC->USBHSCTRL2 & (~(0x3 << 14))) | (0x3 << 14); /* TX Res TUNE [15:14] */ RCC->USBHSCTRL2 = (RCC->USBHSCTRL2 & (~(0x3 << 16))) | (0x3 << 16); /* TX preempamp TUNE [17:16] */ @@ -60,7 +60,9 @@ static void usbhs_common_init(void) /* Override in the board layer to configure USB DM/DP alternate-function pins. * In host mode, also drive any VBUS power-switch GPIO here (e.g. board/ports/usb_gpio.c). */ -__weak void n32h47x_48x_usbhs_gpio_init(void) { } +__weak void n32h47x_48x_usbhs_gpio_init(void) +{ +} void usb_dc_low_level_init(uint8_t busid) { @@ -138,8 +140,7 @@ void usbd_dwc2_delay_ms(uint8_t ms) RCC_GetClocksFreqValue(&RCC_clocks); uint32_t count = RCC_clocks.SysclkFreq / 1000 * ms; - while (count--) - { + while (count--) { __asm volatile("nop"); } } @@ -176,8 +177,7 @@ uint32_t usbd_dwc2_get_system_clock(void) * Total 1024 words (4096 bytes) * */ -static const struct dwc2_user_params param_n32h47x_48x = -{ +static const struct dwc2_user_params param_n32h47x_48x = { /* Built-in HS UTMI+ PHY; sets GUSBCFG.ULPI_UTMI_SEL = 0. */ .phy_type = DWC2_PHY_TYPE_PARAM_UTMI, @@ -186,7 +186,7 @@ static const struct dwc2_user_params param_n32h47x_48x = * CherryUSB only sets GUSBCFG.PHYIF16 when this field == 16. */ .phy_utmi_width = 8, - /* Slave mode vs DMA mode; controlled by CONFIG_USB_DWC2_DMA_ENABLE. +/* Slave mode vs DMA mode; controlled by CONFIG_USB_DWC2_DMA_ENABLE. * DMA mode frees the CPU from FIFO polling but requires aligned buffers. */ #ifdef CONFIG_USB_DWC2_DMA_ENABLE .device_dma_enable = true, @@ -226,16 +226,16 @@ static const struct dwc2_user_params param_n32h47x_48x = * sum of all TX entries must stay <= (1024 - device_rx_fifo_size). * Per-FIFO hardware limit: INEPTXFDEP max = 768 words. */ .device_tx_fifo_size = { - [0] = 64, /* EP0: 256 bytes, control */ - [1] = 256, /* EP1: 1024 bytes, HS bulk/iso primary */ - [2] = 64, /* EP2: 256 bytes */ - [3] = 64, /* EP3: 256 bytes */ - [4] = 64, /* EP4: 256 bytes */ - [5] = 0, /* EP5..EP8: unallocated, use CUSTOM_FIFO to enable */ - [6] = 0, - [7] = 0, - [8] = 0, - [9] = 0, /* [9]..[15]: invalid for N32H47x_48x (only EP0..EP8 exist) */ + [0] = 64, /* EP0: 256 bytes, control */ + [1] = 256, /* EP1: 1024 bytes, HS bulk/iso primary */ + [2] = 64, /* EP2: 256 bytes */ + [3] = 64, /* EP3: 256 bytes */ + [4] = 64, /* EP4: 256 bytes */ + [5] = 0, /* EP5..EP8: unallocated, use CUSTOM_FIFO to enable */ + [6] = 0, + [7] = 0, + [8] = 0, + [9] = 0, /* [9]..[15]: invalid for N32H47x_48x (only EP0..EP8 exist) */ [10] = 0, [11] = 0, [12] = 0, @@ -299,8 +299,7 @@ void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params) dwc2_get_user_fifo_config(reg_base, &s_dwc2_fifo_config); params->device_rx_fifo_size = s_dwc2_fifo_config.device_rx_fifo_size; - for (uint8_t i = 0; i < MAX_EPS_CHANNELS; i++) - { + for (uint8_t i = 0; i < MAX_EPS_CHANNELS; i++) { params->device_tx_fifo_size[i] = s_dwc2_fifo_config.device_tx_fifo_size[i]; } #endif /* CONFIG_USB_DWC2_CUSTOM_FIFO */ @@ -345,7 +344,7 @@ static void usbhs_common_init(void) RCC_EnableAHBPeriphClk(RCC_AHB_PERIPHEN_USBHS, ENABLE); /* TX analog tuning for 8-bit UTMI PHY (N32H49x USBHSCTRL layout). */ - RCC->USBHSCTRL2 = (RCC->USBHSCTRL2 & (~(0xF << 4))) | (0xB << 4); /* HDCVTRIM[7:4] */ + RCC->USBHSCTRL2 = (RCC->USBHSCTRL2 & (~(0xF << 4))) | (0xB << 4); /* HDCVTRIM[7:4] */ RCC->USBHSCTRL1 = (RCC->USBHSCTRL1 & (~(0x7 << 12))) | (0x5 << 12); /* USBHSCTRL1[14:12] */ RCC->USBHSCTRL2 = (RCC->USBHSCTRL2 & (~(0x3 << 12))) | (0x0 << 14); /* RFTRIM[13:12] = 0 (clear) */ RCC->USBHSCTRL2 = (RCC->USBHSCTRL2 & (~(0x3 << 16))) | (0x1 << 16); /* USBHSCTRL2[17:16] */ @@ -361,7 +360,9 @@ static void usbhs_common_init(void) /* Override in the board layer to configure USB DM/DP alternate-function pins. * In host mode, also drive any VBUS power-switch GPIO here (e.g. board/ports/usb_gpio.c). */ -__weak void n32h49x_usbhs_gpio_init(void) { } +__weak void n32h49x_usbhs_gpio_init(void) +{ +} void usb_dc_low_level_init(uint8_t busid) { @@ -438,8 +439,7 @@ void usbd_dwc2_delay_ms(uint8_t ms) RCC_GetClocksFreqValue(&RCC_clocks); uint32_t count = RCC_clocks.SysclkFreq / 1000U * ms; - while (count--) - { + while (count--) { __asm volatile("nop"); } } @@ -474,8 +474,7 @@ uint32_t usbd_dwc2_get_system_clock(void) * Periodic TX 256 words (1024 bytes) * Total 1024 words (4096 bytes) */ -static const struct dwc2_user_params param_n32h49x = -{ +static const struct dwc2_user_params param_n32h49x = { .phy_type = DWC2_PHY_TYPE_PARAM_UTMI, /* 8-bit UTMI data bus (GCFG.PHYIF = 0). @@ -495,16 +494,16 @@ static const struct dwc2_user_params param_n32h49x = .device_rx_fifo_size = 512, .device_tx_fifo_size = { - [0] = 64, /* EP0: 256 bytes, control */ - [1] = 256, /* EP1: 1024 bytes, HS bulk/iso primary */ - [2] = 64, /* EP2: 256 bytes */ - [3] = 64, /* EP3: 256 bytes */ - [4] = 64, /* EP4: 256 bytes */ - [5] = 0, /* EP5..EP8: unallocated, use CUSTOM_FIFO to enable */ - [6] = 0, - [7] = 0, - [8] = 0, - [9] = 0, /* [9]..[15]: invalid for N32H49x (only EP0..EP8 exist) */ + [0] = 64, /* EP0: 256 bytes, control */ + [1] = 256, /* EP1: 1024 bytes, HS bulk/iso primary */ + [2] = 64, /* EP2: 256 bytes */ + [3] = 64, /* EP3: 256 bytes */ + [4] = 64, /* EP4: 256 bytes */ + [5] = 0, /* EP5..EP8: unallocated, use CUSTOM_FIFO to enable */ + [6] = 0, + [7] = 0, + [8] = 0, + [9] = 0, /* [9]..[15]: invalid for N32H49x (only EP0..EP8 exist) */ [10] = 0, [11] = 0, [12] = 0, @@ -548,8 +547,7 @@ void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params) dwc2_get_user_fifo_config(reg_base, &s_dwc2_fifo_config); params->device_rx_fifo_size = s_dwc2_fifo_config.device_rx_fifo_size; - for (uint8_t i = 0; i < MAX_EPS_CHANNELS; i++) - { + for (uint8_t i = 0; i < MAX_EPS_CHANNELS; i++) { params->device_tx_fifo_size[i] = s_dwc2_fifo_config.device_tx_fifo_size[i]; } #endif /* CONFIG_USB_DWC2_CUSTOM_FIFO */ @@ -588,10 +586,10 @@ void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params) #include "n32h7xx.h" #include "usb_dwc2_param.h" -#define N32H7XX_USBHS1_BASE 0x40100000U -#define N32H7XX_USBHS2_BASE 0x40060000U -#define N32H7XX_USBHS1_WRAP 0x40140000U -#define N32H7XX_USBHS2_WRAP 0x400A0000U +#define N32H7XX_USBHS1_BASE 0x40100000U +#define N32H7XX_USBHS2_BASE 0x40060000U +#define N32H7XX_USBHS1_WRAP 0x40140000U +#define N32H7XX_USBHS2_WRAP 0x400A0000U typedef void (*usb_dwc2_irq_fn)(uint8_t busid); @@ -608,8 +606,7 @@ void usbd_dwc2_delay_ms(uint8_t ms) RCC_GetClocksFreqValue(&RCC_Clocks); uint32_t count = RCC_Clocks.SysClkFreq / 1000U * ms; - while (count--) - { + while (count--) { __asm volatile("nop"); } } @@ -646,7 +643,7 @@ static void n32h7xx_wrapper_init(uint32_t wrap_base, bool is_device, bool is_usb wrpcfg = wrap->WRPCFG; wrpcfg &= ~USBHS_WRPCFG_PHYCLKSEL; -#if (HSE_VALUE == 10000000U) +#if (HSE_VALUE == 10000000U) wrpcfg |= USBHS_WRPCFG_PHYCLKSEL_10M; #elif (HSE_VALUE == 12000000U) wrpcfg |= USBHS_WRPCFG_PHYCLKSEL_12M; @@ -668,27 +665,21 @@ static void n32h7xx_wrapper_init(uint32_t wrap_base, bool is_device, bool is_usb wrpcfg |= USBHS_WRPCFG_PLLEN; - if (is_device) - { + if (is_device) { wrpcfg |= USBHS_WRPCFG_IDSIG; - } - else - { + } else { wrpcfg &= ~USBHS_WRPCFG_IDSIG; } wrap->WRPCFG = wrpcfg; - wrpctrl = wrap->WRPCTRL; + wrpctrl = wrap->WRPCTRL; wrpctrl |= USBHS_WRPCTRL_PINDETEN; wrap->WRPCTRL = wrpctrl; - if (is_usbhs1) - { + if (is_usbhs1) { RCC_EnableAHB2PeriphReset1(RCC_AHB2_PERIPHRST_USB1POR); - } - else - { + } else { RCC_EnableAHB1PeriphReset1(RCC_AHB1_PERIPHRST_USB2POR); } @@ -701,8 +692,12 @@ static void n32h7xx_wrapper_init(uint32_t wrap_base, bool is_device, bool is_usb * the DM/DP pins (and optionally SOF/ID) for your specific board. * In host mode, also drive any VBUS power-switch GPIO here. * ----------------------------------------------------------------------- */ -__weak void n32h7xx_usbhs1_gpio_init(void) { } -__weak void n32h7xx_usbhs2_gpio_init(void) { } +__weak void n32h7xx_usbhs1_gpio_init(void) +{ +} +__weak void n32h7xx_usbhs2_gpio_init(void) +{ +} /* ----------------------------------------------------------------------- * NVIC + init @@ -711,10 +706,10 @@ static void n32h7xx_usbhs1_irq_enable(void) { NVIC_InitType nvic; - nvic.NVIC_IRQChannel = USB1_HS_IRQn; + nvic.NVIC_IRQChannel = USB1_HS_IRQn; nvic.NVIC_IRQChannelPreemptionPriority = 1; - nvic.NVIC_IRQChannelSubPriority = 3; - nvic.NVIC_IRQChannelCmd = ENABLE; + nvic.NVIC_IRQChannelSubPriority = 3; + nvic.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic); } @@ -722,10 +717,10 @@ static void n32h7xx_usbhs2_irq_enable(void) { NVIC_InitType nvic; - nvic.NVIC_IRQChannel = USB2_HS_IRQn; + nvic.NVIC_IRQChannel = USB2_HS_IRQn; nvic.NVIC_IRQChannelPreemptionPriority = 1; - nvic.NVIC_IRQChannelSubPriority = 3; - nvic.NVIC_IRQChannelCmd = ENABLE; + nvic.NVIC_IRQChannelSubPriority = 3; + nvic.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&nvic); } @@ -754,7 +749,7 @@ static void n32h7xx_usbhs1_hw_init(uint8_t busid, usb_dwc2_irq_fn irq_fn) * registers are inaccessible and the PHY will not start. */ PWR_MoudlePowerEnable(HSC1_USB1_PWRCTRL, ENABLE); - g_n32h7xx_irq[0].fn = irq_fn; + g_n32h7xx_irq[0].fn = irq_fn; g_n32h7xx_irq[0].busid = busid; n32h7xx_usbhs1_irq_enable(); } @@ -775,7 +770,7 @@ static void n32h7xx_usbhs2_hw_init(uint8_t busid, usb_dwc2_irq_fn irq_fn) /* Power up the USBHS2 hardware module. */ PWR_MoudlePowerEnable(HSC2_USB2_PWRCTRL, ENABLE); - g_n32h7xx_irq[1].fn = irq_fn; + g_n32h7xx_irq[1].fn = irq_fn; g_n32h7xx_irq[1].busid = busid; n32h7xx_usbhs2_irq_enable(); } @@ -787,13 +782,10 @@ void usb_dc_low_level_init(uint8_t busid) { /* Identify the controller by reg_base, not busid. * busid is a user-assigned index and does not imply a fixed controller mapping. */ - if (g_usbdev_bus[busid].reg_base == N32H7XX_USBHS1_BASE) - { + if (g_usbdev_bus[busid].reg_base == N32H7XX_USBHS1_BASE) { n32h7xx_usbhs1_hw_init(busid, USBD_IRQHandler); n32h7xx_wrapper_init(N32H7XX_USBHS1_WRAP, true, true); - } - else - { + } else { n32h7xx_usbhs2_hw_init(busid, USBD_IRQHandler); n32h7xx_wrapper_init(N32H7XX_USBHS2_WRAP, true, false); } @@ -803,17 +795,14 @@ void usb_dc_low_level_deinit(uint8_t busid) { NVIC_InitType nvic; - if (g_usbdev_bus[busid].reg_base == N32H7XX_USBHS1_BASE) - { - nvic.NVIC_IRQChannel = USB1_HS_IRQn; + if (g_usbdev_bus[busid].reg_base == N32H7XX_USBHS1_BASE) { + nvic.NVIC_IRQChannel = USB1_HS_IRQn; nvic.NVIC_IRQChannelCmd = DISABLE; NVIC_Init(&nvic); RCC_EnableAHB2PeriphReset1(RCC_AHB2_PERIPHRST_USB1POR); RCC_EnableAHB2PeriphClk1(RCC_AHB2_PERIPHEN_M7_USB1, DISABLE); - } - else - { - nvic.NVIC_IRQChannel = USB2_HS_IRQn; + } else { + nvic.NVIC_IRQChannel = USB2_HS_IRQn; nvic.NVIC_IRQChannelCmd = DISABLE; NVIC_Init(&nvic); RCC_EnableAHB1PeriphReset1(RCC_AHB1_PERIPHRST_USB2POR); @@ -826,13 +815,10 @@ void usb_dc_low_level_deinit(uint8_t busid) * ----------------------------------------------------------------------- */ void usb_hc_low_level_init(struct usbh_bus *bus) { - if (bus->hcd.reg_base == N32H7XX_USBHS1_BASE) - { + if (bus->hcd.reg_base == N32H7XX_USBHS1_BASE) { n32h7xx_usbhs1_hw_init(bus->busid, USBH_IRQHandler); n32h7xx_wrapper_init(N32H7XX_USBHS1_WRAP, false, true); - } - else - { + } else { n32h7xx_usbhs2_hw_init(bus->busid, USBH_IRQHandler); n32h7xx_wrapper_init(N32H7XX_USBHS2_WRAP, false, false); } @@ -842,17 +828,14 @@ void usb_hc_low_level_deinit(struct usbh_bus *bus) { NVIC_InitType nvic; - if (bus->hcd.reg_base == N32H7XX_USBHS1_BASE) - { - nvic.NVIC_IRQChannel = USB1_HS_IRQn; + if (bus->hcd.reg_base == N32H7XX_USBHS1_BASE) { + nvic.NVIC_IRQChannel = USB1_HS_IRQn; nvic.NVIC_IRQChannelCmd = DISABLE; NVIC_Init(&nvic); RCC_EnableAHB2PeriphReset1(RCC_AHB2_PERIPHRST_USB1POR); RCC_EnableAHB2PeriphClk1(RCC_AHB2_PERIPHEN_M7_USB1, DISABLE); - } - else - { - nvic.NVIC_IRQChannel = USB2_HS_IRQn; + } else { + nvic.NVIC_IRQChannel = USB2_HS_IRQn; nvic.NVIC_IRQChannelCmd = DISABLE; NVIC_Init(&nvic); RCC_EnableAHB1PeriphReset1(RCC_AHB1_PERIPHRST_USB2POR); @@ -909,8 +892,7 @@ void USB2_HS_IRQHandler(void) * Adjust via CONFIG_USB_DWC2_CUSTOM_FIFO or CONFIG_USB_DWC2_CUSTOM_PARAM; * keep RX + sum(TX) <= 1024 words. */ -static const struct dwc2_user_params param_n32h7xx = -{ +static const struct dwc2_user_params param_n32h7xx = { /* Built-in HS UTMI+ PHY; GUSBCFG.ULPI_UTMI_SEL = 0. */ .phy_type = DWC2_PHY_TYPE_PARAM_UTMI, @@ -939,16 +921,16 @@ static const struct dwc2_user_params param_n32h7xx = * 512 TX + 512 RX = 1024 words total. * Per-FIFO hardware limit: INEPTXFDEP max = 768 words. */ .device_tx_fifo_size = { - [0] = 64, /* EP0: 256 bytes, control; matches TX0_FIFO_HS_SIZE = 64 */ - [1] = 256, /* EP1: 1024 bytes, HS bulk/iso; matches TX1_FIFO_HS_SIZE = 256 */ - [2] = 64, /* EP2: 256 bytes */ - [3] = 64, /* EP3: 256 bytes */ - [4] = 64, /* EP4: 256 bytes */ - [5] = 0, /* EP5..EP8: unallocated; use CONFIG_USB_DWC2_CUSTOM_FIFO to enable */ - [6] = 0, - [7] = 0, - [8] = 0, - [9] = 0, + [0] = 64, /* EP0: 256 bytes, control; matches TX0_FIFO_HS_SIZE = 64 */ + [1] = 256, /* EP1: 1024 bytes, HS bulk/iso; matches TX1_FIFO_HS_SIZE = 256 */ + [2] = 64, /* EP2: 256 bytes */ + [3] = 64, /* EP3: 256 bytes */ + [4] = 64, /* EP4: 256 bytes */ + [5] = 0, /* EP5..EP8: unallocated; use CONFIG_USB_DWC2_CUSTOM_FIFO to enable */ + [6] = 0, + [7] = 0, + [8] = 0, + [9] = 0, [10] = 0, [11] = 0, [12] = 0, @@ -992,8 +974,7 @@ void dwc2_get_user_params(uint32_t reg_base, struct dwc2_user_params *params) dwc2_get_user_fifo_config(reg_base, &s_dwc2_fifo_config); params->device_rx_fifo_size = s_dwc2_fifo_config.device_rx_fifo_size; - for (uint8_t i = 0; i < MAX_EPS_CHANNELS; i++) - { + for (uint8_t i = 0; i < MAX_EPS_CHANNELS; i++) { params->device_tx_fifo_size[i] = s_dwc2_fifo_config.device_tx_fifo_size[i]; } #endif /* CONFIG_USB_DWC2_CUSTOM_FIFO */