stm32f1xx-hal
stm32f1xx-hal copied to clipboard
Issues with `as_mode` functions
I tried using the as_mode
GPIO functions for reading from a DHT22 sensor and ran into some issues that i'm documenting here.
No returns from as_input
closures
For the DHT sensor, I'd like to write something like this:
let reading = pin.as_floating_input(crl, |pin| {
make_reading(pin)
});
but that is not possible because no values can be returned from the as_input
family of functions.
The fix should be fairly simple, just add a generic parameter though that might be a breaking change...
While it might not be super useful, it probably makes sense to add it for both as_input
and as_output
Generic functions using the as_
functions is difficult
This part is kind of rambly, but I felt like I had to write out my thoughts on it:
While the traits work for rigidly specified functions, writing code that is
generic over a pin that can be transformed is difficult because of the
requirement of passing a cr
register when transforming the pin
I think a solution to that might be to add a new trait for the pins that just has an associated type with the pin. That way, one can blanket impl some external traits for all our GPIO pins.
This is more of a broader question, probably related to e-h in general:
Another problem with generic use is that embedded_hal
, and by extension,
generic code does not care about the electrical characteristics of IO pins.
However, to transform the pin, the HAL needs to know what configuration to use.
Sure. The way the F1 implements the mode switching simply means that one cannot nilly willy switch modes and something has to give. What are the options:
- The "Arduino" way: Allow the user to do anything without any safety whatsoever
- Provide
unsafe
functions which require the user to anything but it's up to them to ensure upholding the invariants - Provide safe functions which internally guarantee safety (potentially by using a CS which might thwart hard realtime use)
- Provide safe functions which require to present a CS token (and can potentially produced by the user in case they can guarantee race free use)
I think we can do better but not by much, the hardware is the limitation here.
Yep, things would certainly be easier with a better architecture. Since you're more familiar with other architectures, is this something that is unique to the f1 or are there a lot of microcontrollers with similar constraints out there?
Provide safe functions which require to present a CS token (and can potentially produced by the user in case they can guarantee race free use)
This seems like it would have similar issues as it would still require passing additional types around, which if the f1 is fairly unique would either work badly with generic code, or make other generic code more annoying to use
Provide safe functions which internally guarantee safety (potentially by using a CS which might thwart hard realtime use)
This seems like the most convenient version but as you say, it has issues with real time use. Would it make sense to have 2 separate GPIO implementations? One using CSes and one that is what we currently have. That way a user can chose which one fits for their project.
Yep, things would certainly be easier with a better architecture. Since you're more familiar with other architectures, is this something that is unique to the f1 or are there a lot of microcontrollers with similar constraints out there?
Details are different but from what I can tell it pretty much affects any architecture. Chips like nRF which have a per GPIO configuration register might be at an slight advantage here.
This seems like it would have similar issues as it would still require passing additional types around, which if the f1 is fairly unique would either work badly with generic code, or make other generic code more annoying to use
The CS token can be provided by the implementation or conjured out of thin air and is a generic type so far less cumbersome to obtain then say a clock register.
Would it make sense to have 2 separate GPIO implementations? One using CSes and one that is what we currently have. That way a user can chose which one fits for their project.
That was what I was trying to imply but seemingly I failed. 😅
Can't we use the bit band forbatomic bit access, as each needed bits are owned by the pin as far as I remember? It would allow an argument free method with safe implementation.
Can't we use the bit band forbatomic bit access, as each needed bits are owned by the pin as far as I remember? It would allow an argument free method with safe implementation.
Hmm, I think the problem is that the configuration registers for gpio have multi-bits fields and you can only change one bit at a time with bit banding. Might be a problem to set them sequentially.