Dec 1st, 2025; - min read

Writing a Custom and Faster Driver for the STM32 Family of Microcontrollers

Part 1 - Initial Setup


Motivations


To keep short, doing this makes you end up with cleaner code, faster compilaton time, more memory available for you to use as you want and less buggy-prone code. Here's a complete list:

  1. Have only the code needed on your application. I'll talk more about this on the next chapters and how this is critical for faster, lighter and optimized applications.
  2. The more you understand about the low-level register set-clear process, the better you can debug and understand what is happening under the hood.
  3. Be closer to the design aspects of the microcontroller, where you grasp why design choises were made and how it influences hardware performance.
  4. If you're cost constrained, you can select a smaller flash size and have even more space for application data than selecting a bigger one and storing lots of unnused compiled library code.
  5. Simply because it's fun! You can say to your friends that you now live between sanity border when programming.

As mentioned on book Bare-Metal Embedded C Programming[1]:

Bare-metal programming is all about working directly with the registers in the microcontroller without going through a library [...]. This approach enables us to optimize our firmware for speed and efficiency, which are two very important parameters in embedded systems where resources are limited.

- Israel Gbati[1]

There are multiple layers companies like ST make available for progammers that need to develop a Microcontroller application. This is done so that developers with multiple experience levels can program to the target, which makes the microcontrollers more "accessible". Of course, that comes with a cost.

The table below showcases the different levels available and their main characteristics:

Layer Complexity Level Optimization Level Suitable for
MAINSTREAM FRAMEWORKS (ex ARDUINO) Easiest Lowest Suitable for Students, Hobbists, Quick Prototyping
HARDWARE ABSTRACTION LAYER (HAL) Easy Average Firmware Developers (Beginners), Highly Verbose
LOW LEVEL LAYER (LL) Average Good Used for a mix of portability and optimizaiton. More advanced controlls.
BARE-METAL C Hard Great Granular controll and memory optimized. Used on final product lines.
ASSEMBLY Hardest Great, but dangerous Not very used since it is extremely time-consuming to implement and have limited portability

Requirements


The below list is a what I consider a must. It's important to state that learning Bare-metal C using a micrcontroller can be a plesant experience or just hell depending on the tools you have.

the nucelo-wb55 development board
The NUCLEO Board used to develop the driver

How to navigate inside the Reference Manual


Since the Reference Manual is the most important document you'll use, it's important to know how to navigate through it.

Take a first look on the table of contents. There, you'll find the first headers pointing to overall details (which include the memory map), and then each section will be a peripheral, or a main feature of the microcontroller. Each one of this sections will guide you with the relevant details, register names, their actions, and if they are read/write. The most important section is the register map for each of the features.

Once you start navigating through the manual, you'll get confortable on identifying the correct place to go. Basically the thought process is the following:

references


^ [1] Gbati, I. (2024). Bare-Metal Embedded C Programming: Develop high-performance embedded systems with C for Arm microcontrollers. Packt Publishing Ltd.
^ [2] RM0434 Reference Manual. ST. (2025, January 1). https://www.st.com/resource/en/reference_manual/rm0434-multiprotocol-wireless-32bit-mcu-armbased-cortexm4-with-fpu-bluetooth-lowenergy-and-802154-radio-solution-stmicroelectronics.pdf