Thanks to visit codestin.com
Credit goes to lib.rs

32 releases (13 breaking)

Uses new Rust 2024

new 0.14.0 Jan 21, 2026
0.12.3 Jan 13, 2026
0.10.0 Dec 31, 2025
0.2.1 Sep 10, 2025

#803 in Embedded development

MIT/Apache

530KB
15K SLoC

stm32f1-hal

CI Crates.io Docs.rs License Downloads

stm32f1-hal is a Rust Hardware Abstraction Layer (HAL) for STM32F1 microcontrollers (All F1 series devices). It provides a clear, idiomatic interface for embedded development on STM32F1.

  • It implements selected embedded-hal traits.
  • It uses the os-trait crate, which makes it easy to integrate with different RTOSes.
  • It works with stable Rust.

🎯 Motivation

Existing crates didn’t fully meet my needs:

  • stm32f1xx-hal’s design didn’t align with my workflow.
  • stm32-hal lacks support for the STM32F1 series.
  • Embassy and RTIC are async frameworks, but I need a sync one.

To address this gap, I created stm32f1-hal. While parts of the implementation are adapted from stm32f1xx-hal, the focus here is on clarity, readability, and usability.

📖 Design Philosophy

  • Readability is the most important. We only write code a few times, but we read it countless times. Clear understanding is essential for long-term maintenance.

    • Prefer sync-code over complex macros In complex modules, combining macros with generics and calling a lot of low level interfaces often makes the code harder to follow and maintain. Instead, I use sync-code to synchronizes code blocks across peripherals, keeping peripheral code easy to read and maintain.

    • A script is used to generate code for GPIO alternate function remapping.

  • Concise is not equal to simple. Fewer lines of code do not necessarily mean easier to read or understand.

    • The initialization code is not hidden. This makes the main function more verbose, but everything that’s happening is clearly visible.
    • Static variables are kept to a minimum in the library.

📦 Usage

cargo add stm32f1-hal
use stm32f1_hal::{self as hal, pac, cortex_m_rt::entry, prelude::*};

#[entry]
fn main() -> ! {
    let dp = pac::Peripherals::take().unwrap();
    let mut flash = dp.FLASH.init();

    let cfg = rcc::Config::default();
    let mut rcc = dp.RCC.init().freeze(cfg, &mut flash.acr);
    let mut gpioa = dp.GPIOA.split(&mut rcc);

    let mut led = gpioa.pa5.into_push_pull_output(&mut gpioa.crl);

    loop {
        led.set_high();
        // delay...
        led.set_low();
        // delay...
    }
}

Examples

For a more complete example, see example. And stm32f1-FreeRTOS-example shows how to use this crate with FreeRTOS together.

🗺 Roadmap

This project is still in its early stages, with only a few features implemented so far. Contributions and feedback are welcome to help expand support for more peripherals and features.

  • GPIO (tested)
  • EXTI (tested)
  • UART + poll mode (tested)
  • UART + interrupt (stress tested)
  • UART + DMA (stress tested)
  • I2C + interrupt (tested)
  • SPI + interrupt (tested)
  • DMA
  • PWM output
  • DAC
  • ADC
  • More features

🛠 Contributing

  • Submit PRs with documents, improvements or new peripheral support.
  • Open issues for bugs or feature requests.

🔖 Keywords

stm32 · stm32f1 · rust · embedded-hal · hal · microcontroller · embedded development

Dependencies

~1.7–6MB
~119K SLoC