STK8BA58 Embedded Driver
This driver is the most complex thing I’ve written to date.
Why? #
Long story short: Helping someone who reached out to me through this website led things to me getting the same device as them, the Picoboy. I ended up wanting to make a BSP to make working with the Picoboy easier, and in the proccess I found out that there isn’t a crate for the accelerometer it uses. So what other option did I have other than to make one myself?
How #
I started by implementing the traits from the accelerometer
crate, just reading the registers where the acceleration is and doing the math needed to get a g
value.
I would have stopped there, but I saw that other crates that implemented accelerometer
’s trait had extra functionaliy. Mostly methods to configure and tweak the registers on the accelerometers.
I figured I’d do the same, and what a rabbithole.
I started by manually implementing a method for each function of the accelerometer.
For context, the accelerometer has 31
registers, and many of those have various separate functions.
I quickly realized this wouldn’t be sustainable. Lots and lots of work to implement every single function for every single register.
At the same time, I noticed a pattern in the methods that wrote bit flags to the registers.
So I decided to try generics. Sure, I had written some generic code before - but it wasn’t without hand holding.
embedded_hal
makes it easy and even gives you examples on how to use it’s generic types. But I was on my own on this one.
I also had been reading Rust for Rustaceans (by Jon Gjengset), which at the point I was, generics had been talked about a bit already.
And I did it, on my own I made a generic function to read flags from registers.
But it required a lot of impl From<BITFLAGS_STRUCT> for Register
, which ends up causing the same problem:
Code repetition an lots of work. After seeing what I had done though, I couldn’t help but feel like I could go further.
That I could Really get out of my comfort zone with this one. And I did: I wrote a macro. My first macro! Here it is:
macro_rules! reg_from_flags {
($f:ident) => {
impl From<$f> for Register {
fn from(_value: $f) -> Self {
Self::$f
}
}
};
}
Honestly, I couldn’t believe it. I know it’s a really simple macro, and that just using ident
is not the right way to do it.
But I made a macro! This feels like an acheivement for me.
I really didn’t think I was capable of doing something I consider so complex.
So if I wrote a macro, what’s stopping me from trying to make everything generic? Nothing.
Not only I made the setting of flags generic, but also the reading of “mode
s”, which consist of several bits and are therefore represented as enums.
I know this crate is not the best, that it has a lot that can be improved, but I’m really proud of it. I feel like I’ve really got out of my comfort zone with it and learnt a lot making it. It’s missing unit tests, which is something I’ve never done yet either. But for now, I’m done working on it. I might add them some time later.