Bare-metal TMC2209 UART driver for STM32 (CMSIS) — Feedback on API design & next steps
- July 28, 2026
- 6 replies
- 149 views
Hi everyone!
I'm writing my first bare-metal driver for STM32 in C (CMSIS, no HAL). The driver controls a TMC2209 stepper motor driver over half-duplex UART.
The basic functionality is currently working: initialization, frame assembly, CRC calculation, and movement control via VACTUAL. To keep it hardware-agnostic, the UART send function is decoupled using a function pointer (handler->send). Registers are defined using union and bitfields (struct).
Since this is my first driver, I'd love to get feedback from experienced embedded developers on the following questions:
-
API Design & User Access: What level of API access should I expose to the user, and how should it be structured? Is it better to hide register manipulation behind high-level functions (e.g.,
set_speed,set_current), or keep direct register access accessible? -
Bitfields vs. Shifts/Masks: Is using
union+struct(bitfields) acceptable for production-ready embedded code, or is it better to switch to explicit bit shifts and masks (1 << N) for strict C standard compliance and cross-compiler portability? -
Where to go next: In what direction should I evolve this driver overall? Which features or architectural improvements should I focus on next (e.g., implementing UART read, error handling, register caching, StallGuard, etc.)?
I'd really appreciate any critique on my code, architecture, or general advice on best practices!
