Recommendations for GPIO Interfaces
Pin types are zero-sized by default (C-ZST-PIN)
GPIO Interfaces exposed by the HAL should provide dedicated zero-sized types for each pin on every interface or port, resulting in a zero-cost GPIO abstraction when all pin assignments are statically known.
Each GPIO Interface or Port should implement a split
method returning a
struct with every pin.
Example:
Pin types provide methods to erase pin and port (C-ERASED-PIN)
Pins should provide type erasure methods that move their properties from compile time to runtime, and allow more flexibility in applications.
Example:
Pin state should be encoded as type parameters (C-PIN-STATE)
Pins may be configured as input or output with different characteristics depending on the chip or family. This state should be encoded in the type system to prevent use of pins in incorrect states.
Additional, chip-specific state (eg. drive strength) may also be encoded in this way, using additional type parameters.
Methods for changing the pin state should be provided as into_input
and
into_output
methods.
Additionally, with_{input,output}_state
methods should be provided that
temporarily reconfigure a pin in a different state without moving it.
The following methods should be provided for every pin type (that is, both erased and non-erased pin types should provide the same API):
pub fn into_input<N: InputState>(self, input: N) -> Pin<N>
pub fn into_output<N: OutputState>(self, output: N) -> Pin<N>
-
pub fn with_input_state<N: InputState, R>( &mut self, input: N, f: impl FnOnce(&mut PA1<N>) -> R, ) -> R
-
pub fn with_output_state<N: OutputState, R>( &mut self, output: N, f: impl FnOnce(&mut PA1<N>) -> R, ) -> R
Pin state should be bounded by sealed traits. Users of the HAL should have no need to add their own state. The traits can provide HAL-specific methods required to implement the pin state API.
Example: