This year ST released a very interesting new SoC, the STM32WLE. It is packing both an STM32L4 and a Semtech SX1262 LoRa radio die. In one very tiny package.
The problem is, the chip is so new that there is no support or additional resources and examples out there on the internet, whatsoever. Sure (at the time of writing) there is the V1.0 manual from ST. But that’s it. No official devkits yet. No example code. No debugger support.
Still, we were eager to try out this chip. So we designed our own devkit. Which was also exciting since we had never used a 0.5mm pitch bga footprint before. You need < 0.1mm traces and microvias for the fanout. Did you know many PCB shops don’t even go that small?
We also didn’t dare to do the assembly ourselves, so we had the board made and assembled by Weller PCB. Turned out very nicely.
Normally how you test a new board is by flashing a blinky program on it and check whether the LED is blinking. But we don’t have a known working blinky binary for this microcontroller, nor do we have a method to flash that imaginary binary. That will be the challenge to tackle for this article.
I figured the first step is to have a firmware binary that should work once it is flashed. Since I don’t have any chip libraries or peripheral access crates (PACs) yet it needs to be a very low-level program. To just write that and assume it is good is too risky. That’s why I decided to write it for the STM32G070 first. It is an mcu I have already done some projects with, so it easy to test. And the register interface is quite similar to other ST parts. When that works we will adjust the register addresses for the STM32WLE and hope for the best.
And by the way, we don’t really need it to blink, just turning on the led is enough to show that the code and toolchain are working. I also lied about no libraries. Because we will use the
cortex_m crate that will provide us with generic startup code that works for any cortex-m chip.
Now that we have a valid firmware binary (for the stm32g0) we need to test the flashing mechanism. We don’t have a working swd debug probe yet for the stm32wle. That’s why I want to try flashing over serial using the vendor bootloader. So let’s first test that with the G0 as well.
I found this slightly outdated open source command line utility stm32flash (on sourgeforge!). I hacked in support for the STM32G070 and STM32WLE by a adding these lines to the device table:
Then flashing it like this.
That worked as expected.
Adapt the code to use the correct register addresses and pin numbers (see repo).
Which worked! Nice.
But what is this? I cannot flash the board again. Turns out the uart bootloader is only available if there is no valid firmware or if the firmware sets a specific bit. Looks like it is flash-once then.
In order to unbrick this board I need to be able to access it through SWD. Normally we use the Black Magic Probe. However, it does not support such a brand new chip yet. And I am not familiar enough with the codebase to quickly add a new target with potentially a new flashing algorithm. So we need an alternative.
Recently I encountered Probe-rs. A very promising Rust tool for debugging and flashing. The cool part is that even though it did not support the stm32wl series yet, I could add it by generating the configuration from the family’s CMSIS Pack. So convenient. This configuration describes the flashing algorithm for probe-rs.
Flashing using probe-rs can be done with for example an st-link and the
cargo-flash command-line utility (install with
cargo install cargo-flash). Then, it is as easy as running the following command inside your rust project.
Yay, the board is unbricked!
So far we can run a very low level (unsafe) firmware. But it would be nice if we didn’t have to look up all those register addresses (which the user manual does not make very easy). Therefore we need a PAC, or a chip library in c-speak.
In the rust stm32 ecosystem, we can also just generate the PAC from the vendor SVD file. So I asked on the ST forums if I could get those, and they kindly provided them. Generating a new crate is as easy as adding a pull request to the stm32-rs repository. And voila, the stm32wl crate is live.
Now that we have this fancy register interface we can update our blinky app.
You can check the project out here on github.
In the end I could have skipped the flashing over uart (stm32flash) step and keep everything within the embedded Rust ecosystem. This shows that Rust might already be the best tool to bootstrap support for a new microcontroller! In C, without vendor chip libraries, this would have taken me ages. I am pretty happy that it went so smoothly because I was afraid this would cost me a lot of time.
UPDATE 26 November 2020
We only had 4 and they’re all gone already.
Of course, I didn’t get to the most interesting parts of the STM32WLE yet: the LoRa RF part (the SX126X). Unfortunately, some of our priorities have shifted and we don’t have time right now to work on that part. We have a few spare boards, so if anyone is interested to give it a go, we’re happy to send you one! Just drop us a line at firstname.lastname@example.org.