Expand description

This library provides high-level access to STM32 peripherals.

Current family support: F3, F4, L4, L5, G0, G4, H7, and WB. U5 is planned once its SVD files and PAC become available.

Please see the Readme for a detailed overview, and the examples folder on Github for example code and project structure.

Getting started

Review the syntax overview example for example uses of many of this library’s features. Copy and paste its whole folder (It’s set up using Knurling’s app template), or copy parts of Cargo.toml and main.rs as required.

The blinky example, written by toudi, provides a detailed example and instructions for how to set up a blinking light (ie hello world) using an STM32F411 “blackpill” board. Its readme provides instructions for how to get started from scratch, and its code contains detailed comments explaining each part.

The conductivity module example is a complete example of simple production firmware. It uses the DAC, I2C, Timer, and UART peripherals, with a simple interupt-based control flow.

The PDM mic, DAC output passthrough example demonstrates how to read audio from a digital microphone, output it to headphones or speakers using the DAC, and use DMA to do this efficiently. It conducts minimal processing, but can be modified to process using DSP between input and output. This example uses RTIC.

Additional examples in the examples folder demonstrate how to use various STM32 peripherals; most of these examples focus on a single peripheral.

When specifying this crate as a dependency in Cargo.toml, you need to specify a feature representing your MCU. If this is for code that runs on an MCU directly (ie not a library), also include a run-time feature, following the template l4rt. For example:

cortex-m = "0.7.3"
cortex-m-rt = "0.6.13"
stm32-hal2 = { version = "^1.4.5", features = ["l4x3", "l4rt"]}

If you need embedded-hal traits, include the embedded-hal feature.

You can review this section of Cargo.toml to see which MCU and runtime features are available.

Example highlights:

use cortex_m;
use cortex_m_rt::entry;
use stm32_hal2::{
    gpio::{Pin, Port, PinMode, OutputType},
    timer::{Timer, TimerInterrupt},

fn main() -> ! {
    let mut dp = pac::Peripherals::take().unwrap();

    let clock_cfg = Clocks::default();

    let mut pb15 = Pin::new(Port::A, 15, PinMode::Output);

    let mut timer = Timer::new_tim3(dp.TIM3, 0.2, Default::default(), &clock_cfg);

    let mut scl = Pin::new(Port::B, 6, PinMode::Alt(4));

    let mut sda = Pin::new(Port::B, 7, PinMode::Alt(4));

    let i2c = I2c::new(dp.I2C1, Default::default(), &clock_cfg);

    loop {
        i2c.write(0x50, &[1, 2, 3]);

This article provides some information on using this library, as well as background information on Rust embedded in general.

Docs caveat

This Rust docs page is built for STM32L4x3, and some aspects are not accurate for other variants. We currently don’t have a good solution to this problem, and may self-host docs in the future.


Support for the ADC (Analog to Digital Converter) peripheral.

This module contains clock configurations for various MCUs. They tend to be significantly different from one another, so we’ve feature-gated these files, rather than code within the files, to differentiate families.

Cyclic Redundancy Check (CRC) support

Support for the digital to Analog converter (DAC) peripheral.

Digital filter for sigma delta modulators (DFSDM) support. Seem H742 RM, chapter 30.

Support for the Direct Memory Access (DMA) peripheral. This module handles initialization, and transfer configuration for DMA. The Dma::cfg_channel method is called by modules that use DMA.

Read and write onboard flash memory.

This module provides functionality for General Purpose Input and Output (GPIO) pins, including all GPIOx register functions. It also configures GPIO interrupts using SYSCFG and EXTI registers as appropriate.

Support for the Inter-Integrated Circuit (I2C) bus peripheral. Also supports SMBUS. Provides APIs to configure, read, and write from I2C, with blocking, nonblocking, and DMA functionality.

This module contains code used to place the MCU in low power modes. Reference section 5.3.3: Low power modes of the L4 Reference Manual.

Peripheral access API for STM32H743 microcontrollers (generated using svd2rust v0.19.0 ( ))

In the prelude, we export helper macros.

Quad Serial Peripheral Interface (SPI) bus: A specialized interface used for high-speed communications with external flash memory.

Support for the Random Number Generator (RNG) peripheral.

Support for the Real Time Clock (RTC) peripheral. For more details, see ST AN4759 Uses Chrono for dates and times.

Serial audio interface (SAI) support. Used for I2S, PCM/DSP, TDM, AC’97 etc. See L443 Reference Manual, section 41. H743 FM, section 51.

Support for the Serial Peripheral Interface (SPI) bus peripheral. Provides APIs to configure, read, and write from SPI, with blocking, nonblocking, and DMA functionality.

Provides support for timers. Includes initialization, interrupts, and PWM features.

This module allows for serial communication using the STM32 USART module. Provides APIs to configure, read, and write from USART, with blocking, nonblocking, and DMA functionality.

USB support, including for simulated COM ports. This module is a thin wrapper required to work with the usbd crate.


Syntax helper for getting global variables of the form Mutex<RefCell<Option>>> from an interrupt-free context - eg in interrupt handlers.

Syntax helper for setting global variables of the form Mutex<RefCell<Option>>>. eg in interrupt handlers. Ideal for non-copy-type variables that can’t be initialized immediatiately.

Syntax helper for setting global variables of the form Mutex<Cell<>>>. eg in interrupt handlers. Ideal for copy-type variables.

Enables and resets peripheral clocks on various RCC registesr. The first argument is a apb1, ahb2 etc to specify the reg block. The second is something like tim1, and the third is a pac::RCC.


Workaround due to debugger disconnecting in WFI (and low-power) modes. This affects most (all?) STM32 devices. In production on battery-powered devices that don’t use DMA, consider removing this, to prevent power use by the DMA clock. For why we enable the DMA clock, see STM32F446 errata, section 2.1.1.