[−][src]Trait trellis_m4::gpio::v2::AnyPin
Meta-type representing any Pin
All instances of Pin
implement this trait. When used as a trait bound,
it acts to encapsulate a Pin
. Without this trait, a completely generic
Pin
requires two type parameters, i.e. Pin<I, M>
. But when using this
trait, only one type parameter is required, i.e. P: AnyPin
. However, even
though we have dropped a type parameter, no information is lost, because the
PinId
and PinMode
type parameters are stored as associated types in
the trait. The implementation of AnyPin
looks something like this:
impl<I: PinId, M: PinMode> AnyPin for Pin<I, M> { type Id = I; type Mode = M; // ... }
Thus, there is a one-to-one mapping between Pin<I, M>
and
AnyPin<Id = I, Mode = M>
, so you can always recover the full, concrete
type from an implementation of AnyPin
. The type alias ConcretePin
is
provided for just this purpose.
AnyPin
as a trait bound
When using AnyPin
as a trait bound, you can constrain the associated
types to restrict the acceptable Pin
s. For example, you could restrict
a function to accept a particular pin in any mode.
fn example<P>(pin: P) where P: AnyPin<Id = PA27> { }
Or you could accept any pin, as long as it's in the desired mode.
fn example<P>(pin: P) where P: AnyPin<Mode = PullDownInput> { }
You can also apply more complex bounds.
fn example<P, C>(pin: P) where P: AnyPin<Mode = Output<C>>, C: OutputConfig, P::Id: UserTrait, { }
Generic AnyPin
s
Working with a generic type constrained by AnyPin
is slightly different
than working with a concrete Pin
. When compiling a generic function, the
compiler cannot assume anything about the specific concrete type. It can
only use what it knows about the AnyPin
trait. Consequently, we repeat
all of Pin
's inherent methods on the trait, for convenience. To cast a
generic type to a concrete type, use the
as_concrete
method. To cast back to the generic
type, use the Pin
method as_any
.
The following example walks through a few different ways to interact with a
generic type constrained by AnyPin
.
Suppose you wanted to store a completely generic Pin
within a struct.
You can do so using only one type parameter and the AnyPin
trait.
pub struct Example<P: AnyPin> { pin: P, }
Next, suppose you want to create a method that will take the Pin
out of
the struct, perform some operations in several PinMode
s, and put it back
into the struct before returning. The elided
method below shows such an
example. However, it can be a bit tricky to follow all of the type
conversions here. For clarity, the expanded
method shows the same behavior
with each transformation given its proper type annotation. Notice that it is
not enough to simply put back a type that implements
AnyPin<Id = P::Id, Mode = P::Mode>
. As far as the compiler is concerned,
there could be many different types that satisfy that trait bound. Instead,
you must put back a P
exactly. The as_any
function is the
key here. It transforms some type that implements
AnyPin<Id = P::Id, Mode = P::Mode>
into P
itself.
impl<P: AnyPin> Example<P> { pub fn elided(mut self) -> Self { let mut pin = self.pin.into_push_pull_output(); pin.set_high().unwrap(); let pin = pin.into_floating_input(); let _bit = pin.is_low().unwrap(); self.pin = pin.into_mode().as_any(); self } pub fn expanded(mut self) -> Self { // This step is skipped above, because the `into_push_pull_output` // trait method automatically calls `as_concrete`. // By definition, ConcretePin<P> == Pin<P::Id, P::Mode> let pin: ConcretePin<P> = self.pin.as_concrete(); let mut pin: Pin<P::Id, PushPullOutput> = pin.into_push_pull_output(); pin.set_high().unwrap(); let pin: Pin<P::Id, FloatingInput> = pin.into_floating_input(); let _bit = pin.is_low().unwrap(); let pin: ConcretePin<P> = pin.into_mode::<P::Mode>(); self.pin: P = pin.as_any::<P>(); self } }
Associated Types
Loading content...Required methods
pub fn as_concrete(self) -> Pin<Self::Id, Self::Mode>
[src]
Convert a type that implements AnyPin
to a concrete Pin
Even though there is a one-to-one mapping between Pin<I, M>
and
AnyPin<Id = I, Mode = M>
, the compiler doesn't know that. This method
provides a way to convert from an AnyPin
to a Pin
pub fn as_concrete_ref(&self) -> &Pin<Self::Id, Self::Mode>
[src]
Implement as_concrete
for references
pub fn as_concrete_mut(&mut self) -> &mut Pin<Self::Id, Self::Mode>
[src]
Implement as_concrete
for mutable references
Provided methods
pub fn into_mode<N>(self) -> Pin<Self::Id, N> where
N: PinMode,
[src]
N: PinMode,
Convert the pin to the requested PinMode
pub fn into_floating_disabled(self) -> Pin<Self::Id, Disabled<Floating>>
[src]
Disable the pin and set it to float
pub fn into_pull_down_disabled(self) -> Pin<Self::Id, Disabled<PullDown>>
[src]
Disable the pin and set it to pull down
pub fn into_pull_up_disabled(self) -> Pin<Self::Id, Disabled<PullUp>>
[src]
Disable the pin and set it to pull up
pub fn into_floating_input(self) -> Pin<Self::Id, Input<Floating>>
[src]
Configure the pin to operate as a floating input
pub fn into_pull_down_input(self) -> Pin<Self::Id, Input<PullDown>>
[src]
Configure the pin to operate as a pulled down input
pub fn into_pull_up_input(self) -> Pin<Self::Id, Input<PullUp>>
[src]
Configure the pin to operate as a pulled up input
pub fn into_push_pull_output(self) -> Pin<Self::Id, Output<PushPull>>
[src]
Configure the pin to operate as a push-pull output
pub fn into_readable_output(self) -> Pin<Self::Id, Output<Readable>>
[src]
Configure the pin to operate as a readable push pull output
pub fn into_alternate<C>(self) -> Pin<Self::Id, Alternate<C>> where
C: AlternateConfig,
[src]
C: AlternateConfig,
Configure the pin to operate as the corresponding peripheral function.
The type C
indicates the desired peripheral function.
pub fn get_drive_strength(&self)
[src]
Read the current drive strength of the pin.
The drive strength is reset to normal on every change in pin mode.
pub fn set_drive_strength(&mut self, stronger: bool)
[src]
Set the drive strength for the pin.
The drive strength is reset to normal on every change in pin mode.
Implementors
impl<I, M> AnyPin for Pin<I, M> where
M: PinMode,
I: PinId,
[src]
M: PinMode,
I: PinId,
type Id = I
type Mode = M
pub fn as_concrete(
self
) -> Pin<<Pin<I, M> as AnyPin>::Id, <Pin<I, M> as AnyPin>::Mode>
[src]
self
) -> Pin<<Pin<I, M> as AnyPin>::Id, <Pin<I, M> as AnyPin>::Mode>
pub fn as_concrete_ref(
&self
) -> &Pin<<Pin<I, M> as AnyPin>::Id, <Pin<I, M> as AnyPin>::Mode>
[src]
&self
) -> &Pin<<Pin<I, M> as AnyPin>::Id, <Pin<I, M> as AnyPin>::Mode>
pub fn as_concrete_mut(
&mut self
) -> &mut Pin<<Pin<I, M> as AnyPin>::Id, <Pin<I, M> as AnyPin>::Mode>
[src]
&mut self
) -> &mut Pin<<Pin<I, M> as AnyPin>::Id, <Pin<I, M> as AnyPin>::Mode>