Dev Log
Product Ashley Golland

STM32 HAL Drivers: Generated vs Manual Time

Early-access pilot data compares time to a working driver for three STM32 peripheral families using Embedd or manual datasheet-based development.

Chart comparing STM32 driver development time by phase

In the early-access pilot, participants timed the path from opening a reference manual to running a compiled driver on hardware. Across three STM32 peripheral families, manual work consistently took longer than Embedd generation, with the difference concentrated in particular stages rather than spread evenly across the process.

This account uses early-access pilot data from a small participant group working under controlled conditions. The phase-by-phase pattern is useful even apart from the exact figures, and it reflects our experience building drivers before Embedd. The results are not presented as broadly representative: development time varies with engineer experience, chip complexity, and project constraints.

The three peripheral families measured

We compared USART, SPI, and I2C on STM32F4 parts. All three are well documented, commonly used, and familiar to most participants, limiting the learning-curve effect on manual work. A less familiar peripheral would likely widen the gap.

For every participant and peripheral, the endpoint was a warning-free GCC ARM build with a driver that initialized the peripheral, completed a transfer, passed register read-back checks, and ran on hardware: SPI loopback, USART byte send/receive, or an I2C device read.

Where manual driver time goes

Manual development fell into four phases. Participants were surprised by how the time was divided among them.

Datasheet reading and register identification: Locating the relevant chapter, linking registers to behavior, and forming a model of the peripheral's modes. For STM32F4 SPI, that means studying SPI_CR1, SPI_CR2, SPI_SR, and SPI_DR in RM0090. For I2C, it includes the BUSY flag errata and timing effects. Complex interactions, especially in I2C, make this phase longer than expected.

Implementation: Writing initialization and transfer functions, plus an interrupt handler or DMA setup when required. For an experienced embedded engineer, this is often the quickest phase because the code becomes mechanical after the register map is understood.

Debugging address and bitfield errors: Manual work loses much of its time here: a shifted bit position, a copied register offset, or a field assigned to the wrong register or peripheral instance. Such constants look correct during review. Logic-analyzer checks and GDB inspection of register reads usually expose them.

Integration and build verification: Adding the driver header, fixing include paths, and reaching a clean compile.

In the pilot, debugging took a greater portion of manual time than implementation or integration. The difference was especially clear for STM32F4 I2C, where the BUSY flag errata cost time for every participant meeting it for the first time.

Where Embedd time goes

Embedd changes the split: generation and review replace implementation and debugging. Review still matters. Participants checked the parsed register model against the datasheet before downloading code. Those who skipped that check sometimes regenerated after noticing an overlooked parsing note.

The integration phase, including CMake setup, takes about the same time as in the manual case. The generated driver's CMake target structure still requires the same kind of project work.

The address-error debugging phase nearly vanishes. Generated initialization functions come from the parsed register model, which comes from the datasheet tables, so positions and offsets are not manually transcribed. Parsing errors can still occur, such as a field being misidentified during PDF extraction, but they differ from transcription mistakes. Generated output flags them with a comment identifying the field and the parser's confidence level.

What this comparison leaves out

Time to a working driver is one measure, not the whole picture.

Writing a driver manually gives an engineer detailed knowledge of the peripheral. That understanding can help with later system debugging, chip evaluations, and reading a colleague's driver. An Embedd-generated driver does not provide the same learning transfer.

Generated drivers still require hardware understanding. Someone unfamiliar with CPOL and CPHA cannot configure the generated SPI driver correctly, since those choices appear during generation setup. The engineer must still understand the peripheral well enough to select the appropriate options.

The time shifts from transcribing and debugging address constants to making configuration decisions and reviewing output. That is more useful during a new chip bring-up, especially when several new peripherals need drivers at once.

USART, SPI, and I2C: pilot notes

USART: The simplest of the three. Its USART_SR / USART_DR model is familiar, while generated code handles the common BRR baud-rate calculation error, particularly when the clock tree differs from its default. Participants showed a consistent time difference in the pilot.

SPI: Manual development most often causes confusion around NSS management: software or hardware, with hardware output or input. Embedd makes the choice explicit and briefly describes each mode, prompting a deliberate selection instead of an unsuitable default for the hardware design.

I2C: The pilot's largest time gap came mainly from the BUSY flag errata on STM32F4 I2C v1. Generated initialization includes the nine-clock bit-bang sequence by default, so participants using it did not debug that issue. Manual participants encountered it at a rate consistent with published embedded-community errata reports.

ST's errata sheet and many forum threads document the STM32F4 I2C BUSY errata. The challenge is not merely knowing about it, but implementing recovery correctly. That sequence needs GPIO access inside peripheral initialization, requiring careful integration with the driver's structure.

Repeatability and regenerating

Timing does not capture repeatability. A USART driver correct for one STM32F4 variant may not suit another with a different reference manual revision. Copying and editing drivers between variants is common, but it brings back transcription risk.

For a chip-variant change, Embedd's path is to upload the new datasheet and regenerate. It takes the same time as the first generation, while producing output for the new register layout rather than relying on edits to the previous driver's copy.

Generate your first driver

Upload a chip datasheet and receive C99 peripheral drivers in under two minutes.

Get started free