From fd1a51b96bd29c99a597000a501e0bb69c79706c Mon Sep 17 00:00:00 2001 From: Niklas Hauser Date: Wed, 3 Jan 2024 02:51:22 +0100 Subject: [PATCH] [stm32] Configure GPIO when connecting to USB The HS port can use both the DP and DM or the ULPI signals. All signals *must* be configured for high speed though! --- src/modm/platform/usb/stm32/usb.hpp.in | 83 ++++++++++++++++++++++++-- 1 file changed, 77 insertions(+), 6 deletions(-) diff --git a/src/modm/platform/usb/stm32/usb.hpp.in b/src/modm/platform/usb/stm32/usb.hpp.in index 0bf2c4df5c..b5ae009597 100644 --- a/src/modm/platform/usb/stm32/usb.hpp.in +++ b/src/modm/platform/usb/stm32/usb.hpp.in @@ -48,20 +48,91 @@ 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 port == "hs" + static constexpr bool any_usb = + Connector::template IsValid or Connector::template IsValid; -%% if is_otg - Id::configure(Gpio::OutputType::OpenDrain, Gpio::OutputSpeed::High); - Id::configure(Gpio::InputType::PullUp); + 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) + { + 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) +%% else + static_assert(all_usb and sizeof...(Signals) >= 2, + "{{ name }}::connect() requires at least one Dp and one Dm signal!"); %% endif + { + GpioSet::configure(Gpio::OutputType::PushPull, Gpio::OutputSpeed::High); +%% if is_otg + Id::configure(Gpio::OutputType::OpenDrain, Gpio::OutputSpeed::High); + Id::configure(Gpio::InputType::PullUp); %% endif + } + Connector::connect(); } };