-
Notifications
You must be signed in to change notification settings - Fork 226
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
port: Add methods to temporarily switch a pin to a different mode #205
base: main
Are you sure you want to change the base?
Conversation
FWIW, other HALs have come up with a very similar API. For example: https://docs.rs/stm32f4xx-hal/0.11.1/stm32f4xx_hal/gpio/struct.Pin.html#method.with_floating_input |
I wonder how this would behave if the pin were currently being used as the CS for an SPI transaction. |
Well, the CS pin must be managed manually anyway so you can do weird stuff in any case... I don't think this changeset here would make it worse than it already is, or am I missing something? |
c1225f2
to
4952650
Compare
Hello, |
@haennes, giving me some feedback and testing this PR here is all I need. I just held off merging it because I wanted to hear from users first. Maybe you can comment on some of the open questions from the OP? What would be best for your usecase? |
It works on an Arduino Nano (from Elegoo) (Atmega m328p). |
let pin: Self = unsafe { core::ptr::read(self) }; | ||
let mut pin = pin.into_pull_up_input(); | ||
let res = f(&mut pin); | ||
*self = if state { | ||
pin.into_output_high() | ||
} else { | ||
pin.into_output() | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This implementation is still quite ugly and not 100% sound either. I quite like the approach in stm32f4xx-hal
: https://docs.rs/stm32f4xx-hal/0.11.1/src/stm32f4xx_hal/gpio/convert.rs.html#476-490
This is at least more sound than my hack. So I'll try to reimplement that pattern here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like this will unfortunately require a larger change to make it work. But I think following that route is still a good idea and will improve the remainder of the port
module as well. Will just need a bit more time...
4952650
to
7a79cf4
Compare
Am I correct in saying that implementing the IoPin trait from embedded-hal would take care of this as well? |
@hiszd, not really. |
Hi, I just finished implementing a driver for the DHT11 sensor on an Elegoo Arduino Uno R3. This might need a little refactoring before it is anywhere close to presentable, but it could eventually be integrated into the examples someday. |
With regards to the final bullet in the first comment, I think the user should not be responsible for returning a valid pin from the closure. We should assume the Is there a difference between changing mode with |
The original code sets pins to floating inputs in the `all_off` function, which is not what this code was doing until now. This change converts the activation function to move the LED pins to hi/lo output when activating a specific LED, then moving them back to the pin array when done, as deactivated. This isn't exactly nice, and we eagerly await Rahix/avr-hal#205 to land so this code doesn't use `mode::Dynamic` overhead, or the unsafe pointer access.
If we switch to the design from stm32-hal I linked above, this can be done. The pin is only passed to the closure by (mutable) reference so there is no way the closure can move the pin to the outside world and break invariants. I agree that a user-controller closure return type makes for a much nicer API.
Yes, there is a difference. Calling |
This allows temporarily making an output pin an input and vice versa:
Similarly:
pin.with_pin_as_pull_up_input()
pin.with_pin_as_output()
pin.with_pin_as_output_high()
TODO