eldruin/pcf857x-rs

Pins don't implement Peripheral

Closed this issue · 2 comments

Looks like there is a lack of impl DerefMut for pins.
Example:

fn main() -> eyre::Result<()> {
    // It is necessary to call this function once. Otherwise some patches to the runtime
    // implemented by esp-idf-sys might not link properly. See https://github.com/esp-rs/esp-idf-template/issues/71
    esp_idf_svc::sys::link_patches();

    let peripherals = Peripherals::take().unwrap();

    let i2c = peripherals.i2c0;
    let sda = peripherals.pins.gpio5;
    let scl = peripherals.pins.gpio6;

    let config = I2cConfig::new().baudrate(100.kHz().into());
    let i2c = I2cDriver::new(i2c, sda, scl, &config)?;
    let mut expander: Pcf8574<I2cDriver> = pcf857x::Pcf8574::new(i2c, SlaveAddr::Alternative(true, true, true));
    let parts = expander.split();

    fn test<'d>(p: impl Peripheral<P = impl OutputPin> + 'd) {
        todo!()
    }
    
    test(parts.p0); // doesn't work
}

Error:

error[E0277]: the trait bound `P0<'_, Pcf8574<I2cDriver<'_>>, I2cError>: DerefMut` is not satisfied
  --> examples/uln2003_via_pcf8574.rs:42:10
   |
42 |     test(parts.p0);
   |     ---- ^^^^^^^^ the trait `DerefMut` is not implemented for `P0<'_, Pcf8574<I2cDriver<'_>>, I2cError>`
   |     |
   |     required by a bound introduced by this call
   |
   = help: the following other types implement trait `Peripheral`:
             AnyIOPin
             AnyInputPin
             AnyOutputPin
             Modem
             ADC1
             ADC2
             CAN
             Gpio0
           and 46 others
   = note: required for `P0<'_, Pcf8574<I2cDriver<'_>>, I2cError>` to implement `Peripheral`
note: required by a bound in `test`
  --> examples/uln2003_via_pcf8574.rs:38:25
   |
38 |     fn test<'d>(p: impl Peripheral<P = impl OutputPin> + 'd) {
   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `test`

I am guessing the Peripheral trait is a trait provided by your device HAL and can thus not be implemented by a generic driver.
Please feel free to add a DerefMut implementation to the pin structs here and send a PR. It should be fairly easy to do, you just need to get the generic parameters right.

HI, looks like DerefMut doesn't make sense for pins, what should I deference?

            impl <'a, S, E> core::ops::Deref for $PX<'a, S, E> {
                type Target = Self; // self or may be I2C? Both look strange.
                fn deref(&self) -> &Self::Target {
                    self 
                }
            }

I think there is no need to do something like this. Sorry for this issue)

p.s. Peripheral comes from esp-idf-hal is a tricky stuff for for HAL authors and .