Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Converting GpioPin<Input> To GpioPin<SubscribedInput> #66

Closed
Moran296 opened this issue May 7, 2022 · 5 comments
Closed

Converting GpioPin<Input> To GpioPin<SubscribedInput> #66

Moran296 opened this issue May 7, 2022 · 5 comments

Comments

@Moran296
Copy link

Moran296 commented May 7, 2022

Hi!
First of all, thank you for your amazing work, it is really interesting trying out rust in the esp32 world.

Building a driver for a sensor, I would like to be able to receive a generic GpioPin<Input> (or maybe GpioPin<Unknown>?) and be able to install an interrupt for it thus making it a SubscribedInput.

The motivation is of course to decouple the driver from the specific GPIO received.

Example:

struct RotaryEncoder {
    pub clk: GpioPin<SubscribedInput>,
    pub dt: GpioPin<Input>,
}

impl RotaryEncoder {
    fn new(clk: GpioPin<Input>, dt: GpioPin<Input>) -> Self {
       let clk = unsafe clk.into_subscribed(|| {/*some interrupt logic*/}, InterruptType::AnyEdge);

        Self { clk, dt }
    }
} 

As I am not very well trained in rust yet, I am not sure what is the best way to acheive that.. prehaps a trait Subscribe for all 'Pin + InputPin' which implements the into_subscribed function?

A different approach would be to receive a GpioPin<SubscribedInput>,
but with an empty callback (maybe an Option<FnMut> instead of FnMut) and allow subscribing to it after it's creation.

It would be good to be able to change ISR and interrupt type on a pin in runtime especially due to esp32 limitations in AnyEdge interrupts. see espressif's ECO workarounds_for_bugs_in_esp32 3.14

Thank you again

@MabezDev
Copy link
Member

GpioPin<SubscribedInput> implements the

pub trait SubscribedPin: Pin {}
trait, however, because it has no trait methods its not possible to do what you want right now. WIth that said, I can't really see why we can't move the into_subscribed method from the concrete input type to the trait. I believe @pyaillet worked on this originally, any thoughts on this?

@pyaillet
Copy link
Contributor

We could move into_subscribed into the esp-idf-hal::gpio::InputPin. In this case, it would help make a driver for the esp32 family but it would not be portable as the trait is not in embedded-hal.

Is this what you are suggesting @MabezDev ?

@MabezDev
Copy link
Member

We could move into_subscribed into the esp-idf-hal::gpio::InputPin. In this case, it would help make a driver for the esp32 family but it would not be portable as the trait is not in embedded-hal.

You're right, it doesn't help at all here, sorry for the ping!

@Moran296, could you use https://crates.io/crates/rotary-encoder-embedded or https://crates.io/crates/rotary-encoder-hal? You could register the callback before passing the pin in. You'll probably need to store the encoder struct in a static mut, but you'd have to do that if you were using ISRs directly too.

@Moran296
Copy link
Author

Hi again,
The encoder was just an example to how I would like to imlement drivers of the sort, but now I understand that it is not a matter of implemantion but of inconsistency with embedded_hal.

I will just implement the interrupts myself on the pin using esp-idf from esp-idf-sys. I don't really understand why it means that it needs to be static mut? (I tried it here)

Anyway,
thank you both for all the awsome work! :)

@Snapstromegon
Copy link
Contributor

Snapstromegon commented Jul 16, 2022

Would it be possible to implement this by adding a new trait parallel to InputPin/OutputPin/... which contains things like into_subscribed, into_input, into_output, ... and would be implemented by all explicit Pins and the generic GpioPin? This would keep portability with the embedded_hal and improve usage of the pins.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants