diff --git a/boards/st/nucleo_n657x0_q/doc/index.rst b/boards/st/nucleo_n657x0_q/doc/index.rst index ae9fa5e432696..866f8f59de7e1 100644 --- a/boards/st/nucleo_n657x0_q/doc/index.rst +++ b/boards/st/nucleo_n657x0_q/doc/index.rst @@ -62,6 +62,36 @@ Supported Features .. zephyr:board-supported-hw:: +USB +=== + +The USB pin assignments on the STM32N657XX microcontroller are immutable. This means that the specific +pins designated for USB functionality are fixed and cannot be changed or reassigned to other functions, +ensuring consistent and reliable USB communication. + +USB PIN (IOs) +============= + ++------------------+--------------------------------------+ +| Name | Description | ++==================+======================================+ +| OTG1_HSDM | USB OTG1 High-Speed Data- (negative) | ++------------------+--------------------------------------+ +| OTG1_HSDP | USB OTG1 High-Speed Data+ (positive) | ++------------------+--------------------------------------+ +| OTG1_ID | USB OTG1 ID Pin | ++------------------+--------------------------------------+ +| OTG1_TXRTUNE | USB OTG1 Transmit Retune | ++------------------+--------------------------------------+ +| OTG2_HSDM | USB OTG2 High-Speed Data- (negative) | ++------------------+--------------------------------------+ +| OTG2_HSDP | USB OTG2 High-Speed Data+ (positive) | ++------------------+--------------------------------------+ +| OTG2_ID | USB OTG2 ID Pin | ++------------------+--------------------------------------+ +| OTG2_TXRTUNE | USB OTG2 Transmit Retune | ++------------------+--------------------------------------+ + Connections and IOs =================== diff --git a/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_common.dtsi b/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_common.dtsi index 7bc6fd76e162e..85ef0af2ac083 100644 --- a/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_common.dtsi +++ b/boards/st/nucleo_n657x0_q/nucleo_n657x0_q_common.dtsi @@ -56,6 +56,12 @@ }; }; +&clk_hse { + hse-div2; + clock-frequency = ; + status = "okay"; +}; + &clk_hsi { hsi-div = <1>; status = "okay"; @@ -174,6 +180,9 @@ pinctrl-0 = <&usart3_tx_pd8 &usart3_rx_pd9>; pinctrl-names = "default"; current-speed = <115200>; +}; + +zephyr_udc0: &usbotg_hs1 { status = "okay"; }; diff --git a/boards/st/nucleo_n657x0_q/twister.yaml b/boards/st/nucleo_n657x0_q/twister.yaml index b1316a29fcf3d..1b3b669ae47ec 100644 --- a/boards/st/nucleo_n657x0_q/twister.yaml +++ b/boards/st/nucleo_n657x0_q/twister.yaml @@ -14,6 +14,8 @@ supported: - gpio - spi - uart + - usb_device + - usbd vendor: st variants: nucleo_n657x0_q/stm32n657xx: diff --git a/boards/st/stm32n6570_dk/doc/index.rst b/boards/st/stm32n6570_dk/doc/index.rst index d38ca7eaa1a15..dd66f90d77f46 100644 --- a/boards/st/stm32n6570_dk/doc/index.rst +++ b/boards/st/stm32n6570_dk/doc/index.rst @@ -66,6 +66,36 @@ Supported Features .. zephyr:board-supported-hw:: +USB +=== + +The USB pin assignments on the STM32N657XX microcontroller are immutable. This means that the specific +pins designated for USB functionality are fixed and cannot be changed or reassigned to other functions, +ensuring consistent and reliable USB communication. + +USB PIN (IOs) +============= + ++------------------+--------------------------------------+ +| Name | Description | ++==================+======================================+ +| OTG1_HSDM | USB OTG1 High-Speed Data- (negative) | ++------------------+--------------------------------------+ +| OTG1_HSDP | USB OTG1 High-Speed Data+ (positive) | ++------------------+--------------------------------------+ +| OTG1_ID | USB OTG1 ID Pin | ++------------------+--------------------------------------+ +| OTG1_TXRTUNE | USB OTG1 Transmit Retune | ++------------------+--------------------------------------+ +| OTG2_HSDM | USB OTG2 High-Speed Data- (negative) | ++------------------+--------------------------------------+ +| OTG2_HSDP | USB OTG2 High-Speed Data+ (positive) | ++------------------+--------------------------------------+ +| OTG2_ID | USB OTG2 ID Pin | ++------------------+--------------------------------------+ +| OTG2_TXRTUNE | USB OTG2 Transmit Retune | ++------------------+--------------------------------------+ + Connections and IOs =================== diff --git a/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi b/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi index a5f102bc6e3bf..a71e2bfc08d10 100644 --- a/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi +++ b/boards/st/stm32n6570_dk/stm32n6570_dk_common.dtsi @@ -45,6 +45,12 @@ }; }; +&clk_hse { + hse-div2; + clock-frequency = ; + status = "okay"; +}; + &clk_hsi { hsi-div = <1>; status = "okay"; @@ -191,6 +197,9 @@ pinctrl-0 = <&usart2_tx_pd5 &usart2_rx_pf6>; pinctrl-names = "default"; current-speed = <115200>; +}; + +zephyr_udc0: &usbotg_hs1 { status = "okay"; }; diff --git a/boards/st/stm32n6570_dk/twister.yaml b/boards/st/stm32n6570_dk/twister.yaml index f7adeb84b6154..27d6d2d79759d 100644 --- a/boards/st/stm32n6570_dk/twister.yaml +++ b/boards/st/stm32n6570_dk/twister.yaml @@ -16,6 +16,8 @@ supported: - memc - spi - uart + - usb_device + - usbd variants: stm32n6570_dk/stm32n657xx: twister: false diff --git a/drivers/usb/device/usb_dc_stm32.c b/drivers/usb/device/usb_dc_stm32.c index 440b446b80eab..a33adf8cc4794 100644 --- a/drivers/usb/device/usb_dc_stm32.c +++ b/drivers/usb/device/usb_dc_stm32.c @@ -67,9 +67,11 @@ LOG_MODULE_REGISTER(usb_dc_stm32); static const struct stm32_pclken pclken[] = STM32_DT_INST_CLOCKS(0); +#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_otghs) PINCTRL_DT_INST_DEFINE(0); static const struct pinctrl_dev_config *usb_pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0); +#endif #define USB_OTG_HS_EMB_PHYC (DT_HAS_COMPAT_STATUS_OKAY(st_stm32_usbphyc) && \ DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs)) @@ -339,6 +341,14 @@ static int usb_dc_stm32_phy_specific_clock_enable(const struct device *const clk * with LL_PWR_EnableVDDUSB function (higher case) */ LL_PWR_EnableVDDUSB(); +#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_otghs) + /* Enable Vdd USB voltage monitoring */ + LL_PWR_EnableVddUSBMonitoring(); + while (__HAL_PWR_GET_FLAG(PWR_FLAG_USB33RDY)) { + /* Wait for VDD33USB ready */ + } + /* Enable VDDUSB */ + LL_PWR_EnableVddUSB(); #endif if (DT_INST_NUM_CLOCKS(0) > 1) { @@ -417,13 +427,15 @@ static int usb_dc_stm32_clock_enable(void) /* Both OTG HS and USBPHY sleep clock MUST be disabled here at the same time */ LL_AHB2_GRP1_DisableClockStopSleep(LL_AHB2_GRP1_PERIPH_OTG_HS || LL_AHB2_GRP1_PERIPH_USBPHY); -#else +#elif !DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_otghs) LL_AHB1_GRP1_DisableClockLowPower(LL_AHB1_GRP1_PERIPH_OTGHSULPI); #endif #if USB_OTG_HS_EMB_PHYC +#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_otghs) LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_OTGPHYC); #endif +#endif #endif /* USB_OTG_HS_ULPI_PHY */ return 0; @@ -464,11 +476,7 @@ static int usb_dc_stm32_init(void) usb_dc_stm32_state.pcd.Init.ep0_mps = PCD_EP0MPS_64; usb_dc_stm32_state.pcd.Init.low_power_enable = 0; #else /* USB_OTG_FS || USB_OTG_HS */ -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs) - usb_dc_stm32_state.pcd.Instance = USB_OTG_HS; -#else - usb_dc_stm32_state.pcd.Instance = USB_OTG_FS; -#endif + usb_dc_stm32_state.pcd.Instance = (USB_OTG_GlobalTypeDef *)USB_BASE_ADDRESS; usb_dc_stm32_state.pcd.Init.dev_endpoints = USB_NUM_BIDIR_ENDPOINTS; #if USB_OTG_HS_EMB_PHYC || USB_OTG_HS_EMB_PHY usb_dc_stm32_state.pcd.Init.phy_itface = USB_OTG_HS_EMBEDDED_PHY; @@ -511,12 +519,14 @@ static int usb_dc_stm32_init(void) } #endif +#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_otghs) LOG_DBG("Pinctrl signals configuration"); ret = pinctrl_apply_state(usb_pcfg, PINCTRL_STATE_DEFAULT); if (ret < 0) { LOG_ERR("USB pinctrl setup failed (%d)", ret); return ret; } +#endif LOG_DBG("HAL_PCD_Init"); status = HAL_PCD_Init(&usb_dc_stm32_state.pcd); diff --git a/drivers/usb/udc/udc_stm32.c b/drivers/usb/udc/udc_stm32.c index 12febc6ca829a..bec4860c375f8 100644 --- a/drivers/usb/udc/udc_stm32.c +++ b/drivers/usb/udc/udc_stm32.c @@ -37,9 +37,16 @@ LOG_MODULE_REGISTER(udc_stm32, CONFIG_UDC_DRIVER_LOG_LEVEL); #define UDC_STM32_IRQ_NAME usb #endif +#define UDC_STM32_BASE_ADDRESS DT_INST_REG_ADDR(0) #define UDC_STM32_IRQ DT_INST_IRQ_BY_NAME(0, UDC_STM32_IRQ_NAME, irq) #define UDC_STM32_IRQ_PRI DT_INST_IRQ_BY_NAME(0, UDC_STM32_IRQ_NAME, priority) +#define USB_OTG_HS_EMB_PHY (DT_HAS_COMPAT_STATUS_OKAY(st_stm32_usbphyc) && \ + DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs)) + +#define USB_OTG_HS_ULPI_PHY (DT_HAS_COMPAT_STATUS_OKAY(usb_ulpi_phy) && \ + DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs)) + /** * The following defines are used to map the value of the "maxiumum-speed" * DT property to the corresponding definition used by the STM32 HAL. @@ -962,12 +969,6 @@ static const struct udc_api udc_stm32_api = { #define USB_BTABLE_SIZE 0 #endif /* USB */ -#define USB_OTG_HS_EMB_PHY (DT_HAS_COMPAT_STATUS_OKAY(st_stm32_usbphyc) && \ - DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs)) - -#define USB_OTG_HS_ULPI_PHY (DT_HAS_COMPAT_STATUS_OKAY(usb_ulpi_phy) && \ - DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs)) - static struct udc_stm32_data udc0_priv; static struct udc_data udc0_data = { @@ -1001,12 +1002,8 @@ static void priv_pcd_prepare(const struct device *dev) priv->pcd.Instance = USB; #elif defined(USB_DRD_FS) priv->pcd.Instance = USB_DRD_FS; -#elif defined(USB_OTG_FS) || defined(USB_OTG_HS) -#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs) - priv->pcd.Instance = USB_OTG_HS; -#else - priv->pcd.Instance = USB_OTG_FS; -#endif +#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otgfs) || DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otghs) + priv->pcd.Instance = (USB_OTG_GlobalTypeDef *)UDC_STM32_BASE_ADDRESS; #endif /* USB */ #if USB_OTG_HS_EMB_PHY @@ -1061,6 +1058,15 @@ static int priv_clock_enable(void) HAL_SYSCFG_SetOTGPHYReferenceClockSelection(SYSCFG_OTG_HS_PHY_CLK_SELECT_1); /* Configuring the SYSCFG registers OTG_HS PHY : OTG_HS PHY enable*/ HAL_SYSCFG_EnableOTGPHY(SYSCFG_OTG_HS_PHY_ENABLE); +#elif DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_otghs) + /* Enable Vdd USB voltage monitoring */ + LL_PWR_EnableVddUSBMonitoring(); + while (__HAL_PWR_GET_FLAG(PWR_FLAG_USB33RDY)) { + /* Wait FOR VDD33USB ready */ + } + + /* Enable VDDUSB */ + LL_PWR_EnableVddUSB(); #elif defined(PWR_USBSCR_USB33SV) || defined(PWR_SVMCR_USV) /* * VDDUSB independent USB supply (PWR clock is on) @@ -1136,13 +1142,15 @@ static int priv_clock_enable(void) /* Both OTG HS and USBPHY sleep clock MUST be disabled here at the same time */ LL_AHB2_GRP1_DisableClockStopSleep(LL_AHB2_GRP1_PERIPH_OTG_HS || LL_AHB2_GRP1_PERIPH_USBPHY); -#else +#elif !DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_otghs) LL_AHB1_GRP1_DisableClockLowPower(LL_AHB1_GRP1_PERIPH_OTGHSULPI); #endif /* defined(CONFIG_SOC_SERIES_STM32H7X) */ #if USB_OTG_HS_EMB_PHY +#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_otghs) LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_OTGPHYC); #endif +#endif #elif defined(CONFIG_SOC_SERIES_STM32H7X) && DT_HAS_COMPAT_STATUS_OKAY(st_stm32_otgfs) /* The USB2 controller only works in FS mode, but the ULPI clock needs * to be disabled in sleep mode for it to work. @@ -1171,9 +1179,11 @@ static int priv_clock_disable(void) static struct udc_ep_config ep_cfg_in[DT_INST_PROP(0, num_bidir_endpoints)]; static struct udc_ep_config ep_cfg_out[DT_INST_PROP(0, num_bidir_endpoints)]; +#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_otghs) PINCTRL_DT_INST_DEFINE(0); static const struct pinctrl_dev_config *usb_pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(0); +#endif #if USB_OTG_HS_ULPI_PHY static const struct gpio_dt_spec ulpi_reset = @@ -1256,11 +1266,13 @@ static int udc_stm32_driver_init0(const struct device *dev) IRQ_CONNECT(UDC_STM32_IRQ, UDC_STM32_IRQ_PRI, udc_stm32_irq, DEVICE_DT_INST_GET(0), 0); +#if !DT_HAS_COMPAT_STATUS_OKAY(st_stm32n6_otghs) err = pinctrl_apply_state(usb_pcfg, PINCTRL_STATE_DEFAULT); if (err < 0) { LOG_ERR("USB pinctrl setup failed (%d)", err); return err; } +#endif #ifdef SYSCFG_CFGR1_USB_IT_RMP /* diff --git a/dts/arm/st/n6/stm32n6.dtsi b/dts/arm/st/n6/stm32n6.dtsi index 60f15f8398a18..d1a31635dff24 100644 --- a/dts/arm/st/n6/stm32n6.dtsi +++ b/dts/arm/st/n6/stm32n6.dtsi @@ -710,6 +710,27 @@ #size-cells = <0>; status = "disabled"; }; + + usbotg_hs1: otghs@58040000 { + compatible = "st,stm32n6-otghs", "st,stm32-otghs"; + reg = <0x58040000 0x2000>; + interrupts = <177 0>; + interrupt-names = "otghs"; + num-bidir-endpoints = <9>; + ram-size = <4096>; + maximum-speed = "high-speed"; + clocks = <&rcc STM32_CLOCK(AHB5, 26)>, + <&rcc STM32_SRC_HSE OTGPHY1CKREF_SEL(1)>; + phys = <&usbphyc1>; + status = "disabled"; + }; + + usbphyc1: usbphyc@5803fc00 { + compatible = "st,stm32-usbphyc"; + reg = <0x5803FC00 0x400>; + clocks = <&rcc STM32_CLOCK(AHB5, 27)>; + #phy-cells = <0>; + }; }; }; diff --git a/dts/bindings/usb/st,stm32-otghs-common.yaml b/dts/bindings/usb/st,stm32-otghs-common.yaml new file mode 100644 index 0000000000000..d1aab33d93ae2 --- /dev/null +++ b/dts/bindings/usb/st,stm32-otghs-common.yaml @@ -0,0 +1,27 @@ +# Copyright (c) 2025, STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +# Common fields for STM32 OTGHS controller + +include: [usb-ep.yaml, pinctrl-device.yaml] + +properties: + reg: + required: true + + interrupts: + required: true + + ram-size: + type: int + required: true + description: | + Size of USB dedicated RAM. STM32 SOC's reference + manual defines a shared FIFO size. + + phys: + type: phandle + description: PHY provider specifier + + clocks: + required: true diff --git a/dts/bindings/usb/st,stm32-otghs.yaml b/dts/bindings/usb/st,stm32-otghs.yaml index dfd40a9ed3d40..58f4f5b5523ad 100644 --- a/dts/bindings/usb/st,stm32-otghs.yaml +++ b/dts/bindings/usb/st,stm32-otghs.yaml @@ -1,35 +1,16 @@ # Copyright (c) 2017, I-SENSE group of ICCS +# Copyright (c) 2025, STMicroelectronics # SPDX-License-Identifier: Apache-2.0 description: STM32 OTGHS controller compatible: "st,stm32-otghs" -include: [usb-ep.yaml, pinctrl-device.yaml] +include: st,stm32-otghs-common.yaml properties: - reg: - required: true - - interrupts: - required: true - pinctrl-0: required: true pinctrl-names: required: true - - ram-size: - type: int - required: true - description: | - Size of USB dedicated RAM. STM32 SOC's reference - manual defines a shared FIFO size. - - phys: - type: phandle - description: PHY provider specifier - - clocks: - required: true diff --git a/dts/bindings/usb/st,stm32n6-otghs.yaml b/dts/bindings/usb/st,stm32n6-otghs.yaml new file mode 100644 index 0000000000000..b7c73fb728784 --- /dev/null +++ b/dts/bindings/usb/st,stm32n6-otghs.yaml @@ -0,0 +1,13 @@ +# Copyright (c) 2025, STMicroelectronics +# SPDX-License-Identifier: Apache-2.0 + +description: | + STM32N6 OTGHS controller + + In the STM32N6 series, the `pinctrl-0` and `pinctrl-names` properties are not required + for the USB OTG HS peripheral configuration. This is because the pin multiplexing + for the USB OTG HS peripheral are handled automatically by the hardware. + +compatible: "st,stm32n6-otghs" + +include: st,stm32-otghs-common.yaml