diff --git a/src/modm/platform/usb/stm32/module.lb b/src/modm/platform/usb/stm32/module.lb index 6edbdb6d15..f68c087cc3 100644 --- a/src/modm/platform/usb/stm32/module.lb +++ b/src/modm/platform/usb/stm32/module.lb @@ -1,7 +1,7 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- # -# Copyright (c) 2020, Niklas Hauser +# Copyright (c) 2020, 2024, Niklas Hauser # # This file is part of the modm project. # @@ -58,6 +58,10 @@ def common_usb_irqs(env): def generate_instance(env, port, otg=False): env.outbasepath = "modm/src/modm/platform/usb" irq_data = env.query(":platform:usb:irqs") + all_signals = env.query(":platform:gpio:all_signals") + is_ulpi = {"Ulpick", "Ulpistp", "Ulpidir", "Ulpinxt", + "Ulpid0", "Ulpid1", "Ulpid2", "Ulpid3", + "Ulpid4", "Ulpid5", "Ulpid6", "Ulpid7"} in set(all_signals) env.substitutions = { "port": port, "peripheral": "Usbotg{}".format(port) if otg else "Usb", @@ -65,6 +69,7 @@ def generate_instance(env, port, otg=False): "is_remap": irq_data["is_remap"], "irqs": irq_data["port_irqs"][port], "target": env[":target"].identifier, + "is_ulpi": port == "hs" and is_ulpi, } if otg: env.template("usb.hpp.in", "usb_{}.hpp".format(port)) diff --git a/src/modm/platform/usb/stm32/usb.hpp.in b/src/modm/platform/usb/stm32/usb.hpp.in index 0bf2c4df5c..f01e45a2fa 100644 --- a/src/modm/platform/usb/stm32/usb.hpp.in +++ b/src/modm/platform/usb/stm32/usb.hpp.in @@ -1,6 +1,6 @@ /* * Copyright (c) 2020, Erik Henriksson -* Copyright (c) 2020, Niklas Hauser +* Copyright (c) 2020, 2024, Niklas Hauser * * This file is part of the modm project. * @@ -33,6 +33,14 @@ public: #ifdef PWR_CR2_USV PWR->CR2 |= PWR_CR2_USV; #endif +%% elif target.family in ["h5"] +#ifdef PWR_USBSCR_USB33DEN + PWR->USBSCR |= PWR_USBSCR_USB33DEN; +#endif +%% elif target.family in ["h7"] +#ifdef PWR_CR3_USB33DEN + PWR->CR3 |= PWR_CR3_USB33DEN; +#endif %% endif Rcc::enable(); %% if is_remap @@ -48,20 +56,97 @@ public: connect() { using Connector = GpioConnector; -%% if port == "fs" using Dp = typename Connector::template GetSignal< Gpio::Signal::Dp >; using Dm = typename Connector::template GetSignal< Gpio::Signal::Dm >; %% if is_otg using Id = typename Connector::template GetSignal< Gpio::Signal::Id >; %% endif - static_assert(((Connector::template IsValid and Connector::template IsValid) and sizeof...(Signals) >= 2), - "{{ name }}::connect() requires at least one Dp and one Dm signal!"); + static constexpr bool all_usb = + Connector::template IsValid and Connector::template IsValid; +%% if is_ulpi + static constexpr bool any_usb = + Connector::template IsValid or Connector::template IsValid; + + using Ulpick = typename Connector::template GetSignal< Gpio::Signal::Ulpick >; + using Ulpistp = typename Connector::template GetSignal< Gpio::Signal::Ulpistp >; + using Ulpidir = typename Connector::template GetSignal< Gpio::Signal::Ulpidir >; + using Ulpinxt = typename Connector::template GetSignal< Gpio::Signal::Ulpinxt >; + using Ulpid0 = typename Connector::template GetSignal< Gpio::Signal::Ulpid0 >; + using Ulpid1 = typename Connector::template GetSignal< Gpio::Signal::Ulpid1 >; + using Ulpid2 = typename Connector::template GetSignal< Gpio::Signal::Ulpid2 >; + using Ulpid3 = typename Connector::template GetSignal< Gpio::Signal::Ulpid3 >; + using Ulpid4 = typename Connector::template GetSignal< Gpio::Signal::Ulpid4 >; + using Ulpid5 = typename Connector::template GetSignal< Gpio::Signal::Ulpid5 >; + using Ulpid6 = typename Connector::template GetSignal< Gpio::Signal::Ulpid6 >; + using Ulpid7 = typename Connector::template GetSignal< Gpio::Signal::Ulpid7 >; + + static constexpr bool all_ulpi = + Connector::template IsValid< Ulpick > and + Connector::template IsValid< Ulpistp > and + Connector::template IsValid< Ulpidir > and + Connector::template IsValid< Ulpinxt > and + Connector::template IsValid< Ulpid0 > and + Connector::template IsValid< Ulpid1 > and + Connector::template IsValid< Ulpid2 > and + Connector::template IsValid< Ulpid3 > and + Connector::template IsValid< Ulpid4 > and + Connector::template IsValid< Ulpid5 > and + Connector::template IsValid< Ulpid6 > and + Connector::template IsValid< Ulpid7 >; + static constexpr bool any_ulpi = + Connector::template IsValid< Ulpick > or + Connector::template IsValid< Ulpistp > or + Connector::template IsValid< Ulpidir > or + Connector::template IsValid< Ulpinxt > or + Connector::template IsValid< Ulpid0 > or + Connector::template IsValid< Ulpid1 > or + Connector::template IsValid< Ulpid2 > or + Connector::template IsValid< Ulpid3 > or + Connector::template IsValid< Ulpid4 > or + Connector::template IsValid< Ulpid5 > or + Connector::template IsValid< Ulpid6 > or + Connector::template IsValid< Ulpid7 >; + static_assert((any_ulpi xor any_usb) and (all_ulpi or all_usb), + "{{ name }}::connect() requires at least Dp, Dm (+Id) signals OR 12 ULPI signals:\n" + " - CK\n" + " - STP\n" + " - DIR\n" + " - NXT\n" + " - D0\n" + " - D1\n" + " - D2\n" + " - D3\n" + " - D4\n" + " - D5\n" + " - D6\n" + " - D7"); + + if constexpr (all_ulpi and not all_usb) + { + Rcc::enable(); + GpioSet< Ulpick, Ulpistp, Ulpidir, Ulpinxt, Ulpid0, Ulpid1, + Ulpid2, Ulpid3, Ulpid4, Ulpid5, Ulpid6, Ulpid7>::configure( + Gpio::OutputType::PushPull, Gpio::OutputSpeed::High); + } + else if constexpr (not all_ulpi and all_usb) + { + Rcc::disable(); +%% set idt = "\t" +%% else + static_assert(all_usb and sizeof...(Signals) >= 2, + "{{ name }}::connect() requires at least one Dp and one Dm signal!"); +%% set idt = "" +%% endif + {{idt}}GpioSet::configure(Gpio::OutputType::PushPull, Gpio::OutputSpeed::High); %% if is_otg - Id::configure(Gpio::OutputType::OpenDrain, Gpio::OutputSpeed::High); - Id::configure(Gpio::InputType::PullUp); + {{idt}}Id::configure(Gpio::OutputType::OpenDrain, Gpio::OutputSpeed::High); + {{idt}}Id::configure(Gpio::InputType::PullUp); %% endif +%% if is_ulpi + } %% endif + Connector::connect(); } };