embedded-hal icon indicating copy to clipboard operation
embedded-hal copied to clipboard

[Discussion] `digital` marker traits, such as `digital::StronglyDriven`, `digital::OpenDrain`, `digital::OpenCollector`, etc.

Open austinglaser opened this issue 6 years ago • 1 comments

Many MCUs (the STM32s especially) implement a plethora of different output options for their GPIO pins. A driver generally has specific output requirements for its pins -- but enforcing these with API traits will mean there will be many traits available, all implementing similar or identical APIs -- i.e. OutputStronglyDrivenPin, OutputOpenDrainPin, OutputOpenDrainPullupPin, etc.

Advantages

  • One API for high-level pin mode (IoPin, InputPin, OutputPin), with additional traits providing fine-grained configurability
  • Unusual combinations easy to express (OutputPin + OpenDrain + PullUp)

Disadvantages

  • Possible huge proliferation of implementer types
    • The actual pin driving code will likely look similar for all, but initialization will be different. Does this force too much duplication/boilerplate?
    • Could this be handled by a builder-like pattern? i.e. pin init functions which consume a type with/without the marker trait, change the config, and return a type without/with the trait?
  • Possibility of expressing impossible bounds (i.e. OutputPin + StronglyDriven + OpenDrain).
    • Mostly a problem from the driver writer's standpoint, and it will become quickly clear that no available HAL provides the type needed

Example driver usage

pub struct BitBangedI2c<D, C> {
    sda: D,
    scl: C,
}

impl<D, C> BitBangedI2c<D, C> {
    pub fn new<D, C>(sda: D, scl: C) -> BitBangedI2c<D, C>
    where
        D: digital::IoPin + digital::OpenDrain,
        C: digital::IoPin + digital::OpenDrain,
    {
        BitBangedI2c { sda, scl }
    }
}

austinglaser avatar Mar 01 '18 18:03 austinglaser

Please find a related discssion here: https://github.com/japaric/stm32f103xx-hal/pull/51

tib888 avatar Apr 03 '18 10:04 tib888