I'm currently trying to learn Rust (for embedded specifically), coming from a background of C for embedded systems and Python. So far, I've been reading Rust Programming Language and Rust for Embedded, and read a few blog posts on the web.
I want my first project to be a simple "Blinky", where an LED blinks infinitely. I've got an STM32L152CDISCOVERY board with an STM32L152 chip in it (basically same as STM32L151), which is a Cortex M3.
Instead of implementing everything from scratch, I want to leverage existing crates and HALs. I've found two that seem promising: stm32l1 and stm32l1xx-hal. I've tried to read the documentation of each of them and also part of the source code, but I still can't figure out how to use them correctly.
Got a few questions about Rust and about the crates:
I see that
stm32l1xx-hal
has a dependency onstm32l1
. Do I need to add both as a dependency in myCargo.toml
file? Or will that create problems related to ownership?Is this the correct way to add them? Why is the second one added like that
[dependencies.stm32l1]
?[dependencies] cortex-m-rt = "0.6.10" cortex-m-semihosting = "0.3.3" panic-halt = "0.2.0" stm32l1xx-hal = "0.1.0" [dependencies.stm32l1] version = "0.13.0" features = ["stm32l151", "rt"]
To blink the LD4 (which is connected to
PB4PB6), I've got to enable the GPIOB in the RCC register and then configure the pin to push pull output. By inspecting the documentation ofstm32l1xx-hal
, I see that there is an RCC struct and a PB4 struct with the methodinto_push_pull_output
. However, I still don't understand how to use these structs: how to import them or how to get an instance of them.
I've seen code examples for stm32l1
but not for stm32l1xx-hal
. I know that I can do this:
use stm32l1::{stm32l151};
...
let p = stm32l151::Peripherals::take().unwrap();
p.RCC.ahbenr.modify(|_,w| w.gpiopben().set_bit());
But in the source code of stm32l1xx-hal
I see that the RCC part is already done in impl GpioExt for $GPIOX
, but I don't know how to get to this "Parts" functionality.
Any help that points me in the right direction is appreciated.
I got some help from a Discord community. The answers were (modified a bit by me):
stm32l1xx-hal
already depends onstm32l1
as seen here. There's no need to import it twice. It is enough to add to Cargo.toml:default-features = false
is optional, but without it the compiler was giving me an error.The syntaxes are equivalent, but as I said above, I only need to add the HAL one. You can add curly braces
{}
in the first style to add the options, such as:The right code for doing the blinky (which was on PB6, not PB4, sigh) was:
split
method can be called from thePeripherals
becausestm32l1xx-hal
implementedsplit
for a struct defined instm32l1
. In other words, the HAL crate is not only defining new structs, but also extending functionality for existing structs. I need to wrap my head around trait design patterns.