Of course !
So re. embedded-hal
, it is one level lower. msp430-periph
is really a PAC, not a HAL. Maybe I will write a hal on to of it one day.
Re. stm32f4
, it is exactly want type of crate msp430-periph
aims to be. Obviously they are not for the same family of microcontrollers, but there are (few) svd2rust
-generated crates for MSP340s and nothing prevents from writing/generating a crate based on peripherals
for STM32s.
So here are IMO the main differences:
Macro-based
It uses macros to define peripherals, registers, and register fields, which makes the source code readable and editable by hand (and quite smaller).
svd2rust
generates code from patched svd files. When an error is found in the svd file, the patch is updated and the crate regenerated. With peripherals
, one can just fix the error in the PAC crate source code.
Shared peripherals
peripherals
is really designed to allow devices that have similar peripherals to use the same types for these. This should make HAL (and any generic code) quite easier to write, with way less copy-paste from one device to another.
Zero-sized struct instead of aliased struct
This one is a bit of an implementation detail. A lot of crates define struct that have the same layout in memory that the related registers. peripherals
use only zero-sized struct, which avoid issues such as https://github.com/rust-embedded/wg/pull/387, and makes easy to move registers out of peripherals.
API
The API is heavily based on operator overloading. A quick example:
With peripherals
:
let p1 = p.port_1;
// set P0 high and P6 low
p1.pout.modify(POUT0(true) | POUT6(false));
// Set P0 and P6 as outputs
p1.pdir.modify(PDIR0(true) | PDIR6(true));
With svd2rust
:
let p12 = p.PORT_1_2;
// set P0 high and P6 low
p12.p1out
.modify(|_, w| w.p0().set_bit().p6().clear_bit());
// Set P0 and P6 as outputs
p12.p1dir
.modify(|_, w| w.p0().set_bit().p6().set_bit());
Usage
Re. which crate to use, I think it primarily depends on how much time you're ready to spend in writing/generating PAC crates, and which API you prefer.
Currently, using peripherals
with a non-MSP430 target would require to manually write peripherals definitions, or to write code to generate these. On MSP430 targets, there isn't much svd2rust
PAC crates, although they aren't hard to generate, so it really depends on API preference.