Skip to content

Commit

Permalink
[stm32] Configure GPIO when connecting to USB
Browse files Browse the repository at this point in the history
The HS port can use both the DP and DM or the ULPI signals.
All signals *must* be configured for high speed though!
  • Loading branch information
salkinium committed Jan 3, 2024
1 parent 5e37df4 commit fd1a51b
Showing 1 changed file with 77 additions and 6 deletions.
83 changes: 77 additions & 6 deletions src/modm/platform/usb/stm32/usb.hpp.in
Original file line number Diff line number Diff line change
Expand Up @@ -48,20 +48,91 @@ public:
connect()
{
using Connector = GpioConnector<Peripheral::{{ peripheral }}, Signals...>;
%% 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<Dp> and Connector::template IsValid<Dm>) and sizeof...(Signals) >= 2),
"{{ name }}::connect() requires at least one Dp and one Dm signal!");
static constexpr bool all_usb =
Connector::template IsValid<Dp> and Connector::template IsValid<Dm>;
%% if port == "hs"
static constexpr bool any_usb =
Connector::template IsValid<Dp> or Connector::template IsValid<Dm>;

%% 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<Dp, Dm>::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();
}
};
Expand Down

0 comments on commit fd1a51b

Please sign in to comment.