I've got to admit, as a maintainer of the crate I'm not even 100% sure. I would say in general, that
constrain takes a set of registers, and wraps them behind some abstraction to make them safe.
split takes a chunk of registers and divides them into smaller parts. The prime example is the
gpio split function which takes
gpiox and splits it into structs representing each individual pin.
As far as I know,
take is only present on the
pac and gives a unique owned object containing all the registers. If
take is called multiple times, an error is thrown, since the whole abstraction relies on there only being one copy of each register around.
Yes, the docs are pretty lacking in a lot of places. I'm aware of some, and not others. I would really apreciate a heads up whenever the docs are lacking. For example, in this issue: Doc improvements · Issue #158 · stm32-rs/stm32f1xx-hal · GitHub (which I just realised has 0 out of 10 items completed )
When I search
rcc in the docs I get this . Based on the blog post, I think I understand that there would be two layers here one to represent the
svd2rust generated stuff, and another to represent the higher level
embedded-hal stuff. However, I see at least four
::stm32::rcc . How do I know which is which and when and how to use each? The docs seem almost identical for each one.
Oh yea, that's annoying. Ideally, the
stm32f1xx_hal::rcc::RCC is the one that should be shown. The 4 others are from various names of the
pac crate. These are caused by this issue Exporting the sdv2rust crate as device · Issue #16 · stm32-rs/stm32f1xx-hal · GitHub in which we decided that rather than deciding on one of
device, we'd export it as all three. I can see this causing confusion and I think we should deprecate
However, I can also think back to several instances I have certainly required more flexibility than just a straight forward static initialization at startup. For instance, having different peripherals connected to the same pins, or changing pin modes at different points in the application's life cycle or disabling peripherals for reduced current consumption, or putting out the system clock through the hardware support for this in
This is indeed a limitation. I guess we have to sacrifice some generality to get the safety that rust achieves, but rust can also be pretty good at giving you both safety and other things. Turning peripherals off can certainly be achieved, the ADC for example has a
power_down function (or at least I thought it did, maybe that was in my fork and has never been upstreamed).
As for GPIO, it's a known issue see for example the most angry issue I've ever received. A partial solution is in the works [WIP/RFC] Improve GPIO API by TheZoq2 · Pull Request #211 · stm32-rs/stm32f1xx-hal · GitHub
I agree, there is probably a way to write a function in the hal to modify
MCO without breaking the frozen clock contract, which would expose the
MCO hardware functionality in a safe way while still allowing the clocks to be locked. It's not that I'm not willing to do that, but I'm pretty sure I'm not the right one to do it just yet... Maybe in a few months I'll be able to put a PR together for something like that .
I don't recall what the
MCO hardware does, but the guarantee given by
freeze is just that the clocks won't change. I assume
mco does not assume that, so it should probably be exposed. If you would like to implement that, I'll gladly give you some pointers for where to start
Hope that lengthy message answers some of your questions