Skip to content

Repository files navigation

STM32F411 Bare-Metal Peripheral Drivers

Register-level GPIO, SPI, I2C, and USART drivers for the STM32 NUCLEO-F411RE, written from scratch against the reference manual with no vendor HAL.

CI MCU Core

Overview

Every peripheral driver in this repository is built by reading the STM32F411 reference manual and configuring the hardware registers directly. There is no STM32 HAL, no CMSIS driver layer, and no third-party libraries: the peripheral register map, bit-field definitions, and NVIC access are all declared in a single MCU header (drivers/Inc/nucleof41xx.h) and driven by hand.

The project demonstrates bare-metal firmware fundamentals: memory-mapped register access, peripheral clock gating, interrupt configuration through the Cortex-M NVIC and EXTI, blocking and interrupt-driven I/O, and a reproducible cross-compiled build. Each driver exposes both polling APIs and interrupt-driven (*_IT) variants with application callbacks.

Target hardware

  • Board: STM32 NUCLEO-F411RE
  • MCU: STM32F411RE, ARM Cortex-M4F with hardware single-precision FPU
  • Compiler flags target the core directly: -mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 -mfloat-abi=hard

Drivers

All drivers live in drivers/src/ with matching headers in drivers/Inc/.

  • GPIO (nucleof41xx_gpio_driver.c): pin mode, output type, speed, and pull configuration; alternate-function mapping; pin and port read/write; toggle; EXTI interrupt configuration with NVIC enable, priority, and IRQ handling.
  • SPI (nucleof41xx_spi_driver.c): master configuration, full-duplex send and receive, clock polarity and phase control, software slave management (SSI/SSOE), blocking and interrupt-driven transfers, and overrun handling with an application event callback.
  • I2C (nucleof41xx_i2c_driver.c): master send and receive with 7-bit addressing, start/stop generation, address-phase read/write, ACK/NACK management, repeated start, plus interrupt-driven transfers and event/error IRQ handling. Basic slave send/receive is also present.
  • USART (nucleof41xx_usart_driver.c): configurable baud rate, word length, parity, and stop bits; blocking and interrupt-driven transmit and receive; flag status and control helpers.
  • RCC (nucleof41xx_rcc_driver.c): clock helper routines (for example PLL output clock and APB prescaler resolution) used by the peripheral drivers to compute timing from the active clock tree.

Board support code in bsp/ builds on these drivers: a DS1307 real-time-clock module over I2C (ds1307.c) and an HD44780-style character LCD (lcd.c).

Building

The project cross-compiles from the command line with CMake and arm-none-eabi-gcc; no IDE is required. This is the exact flow that runs in CI.

# one-time toolchain install (Debian/Ubuntu)
sudo apt-get install -y gcc-arm-none-eabi cmake

# configure and build
cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=cmake/arm-none-eabi-gcc.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build build

The build produces build/firmware.elf, build/firmware.bin, and build/firmware.hex, and prints a section size and memory-usage report. The toolchain file cmake/arm-none-eabi-gcc.cmake selects the ARM cross-compiler and links against STM32F411RETX_FLASH.ld with nano.specs/nosys.specs.

Each file in Src/ is a standalone example with its own main(), so exactly one is built at a time. The build defaults to Src/main.c; select a different example with -DAPP:

cmake -S . -B build -DCMAKE_TOOLCHAIN_FILE=cmake/arm-none-eabi-gcc.cmake -DAPP=Src/003spi_tx_arduino.c

Flashing

Flash the resulting binary to the board with the ST-Link command-line tools:

st-flash write build/firmware.bin 0x08000000

The application can also be imported into STM32CubeIDE and flashed or debugged over the on-board ST-Link via USB.

Continuous integration

.github/workflows/ci.yml runs on every push and pull request:

  • Firmware build: installs the ARM GCC toolchain and CMake, configures and builds the firmware exactly as above, and uploads the .elf, .bin, and .hex as artifacts. A green badge means the firmware genuinely compiles.
  • Static analysis: runs cppcheck over drivers/ and Src/. This job is currently advisory and does not fail the build.

Project layout

drivers/Inc/   peripheral driver headers + nucleof41xx.h MCU register map
drivers/src/   peripheral driver sources (GPIO, SPI, I2C, USART, RCC)
bsp/           board support: ds1307 RTC over I2C, HD44780 LCD
Src/           example applications, one main() per file
Startup/       startup_stm32f411retx.s (reset handler, vector table)
cmake/         arm-none-eabi-gcc toolchain file
*.ld           linker scripts (STM32F411RETX_FLASH.ld / _RAM.ld)

About

STM32F411 GPIO/SPI/I2C/USART drivers written from scratch, no vendor HAL — with a CMake build and CI

Topics

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages