Dev Log
Product Ashley Golland

Embedd Workflow, Explained

See how a datasheet becomes a compiled, tested driver in a real project, with annotated steps for both the web UI and CLI.

Embedd diagram tracing PDF datasheet upload to generated C driver code

A typical MCU peripheral datasheet can produce a compiling driver in under two minutes. This walkthrough follows each stage in Embedd, from the web UI and CLI upload through generation, so you can see both the tool's work and your choices.

Step 1: Upload a datasheet

Upload the chip's reference manual or peripheral datasheet as a PDF. For many NXP, ST, TI, Nordic, Renesas, and Microchip chips, the vendor product page links to a searchable PDF reference manual.

The source document makes a difference. Embedd reads peripheral chapters from a reference manual, rather than a short product brief or selection guide. If the chip has a separate peripheral user guide, as many NXP and Microchip parts do, upload it instead of only the datasheet overview.

Web UI path: Drop the PDF on the dashboard upload area, or browse for it. Files can be up to 50 MB, enough for large MCU reference manuals such as the STM32H7 manual, which is around 35 MB.

CLI path:

embedd upload stm32f4_rm0090.pdf

After upload, you get a document ID for later commands. Processing happens server-side, so a local copy is not required.

Step 2: Check the parsed register map

Once PDF processing finishes, usually in 10 to 45 seconds depending on size and complexity, you can inspect Embedd's extraction before creating code.

Web UI: The register map browser lists detected peripherals on the left. Select one to reveal its registers, then select a register to view the extracted bitfield table, including field names, bit positions, widths, access modes, reset values, and descriptions. Ambiguous fields carry a yellow indicator. Select it to compare the datasheet's raw text with the parser's interpretation.

CLI:

embedd chips list --doc-id <document_id>

The result is a JSON array of detected peripherals. To inspect one peripheral's register model in more detail:

embedd chips inspect --doc-id <document_id> --peripheral SPI1

Treat this review as a verification step. Check the extracted register model against the datasheet before building on it. Supported chips in the library generally need only a quick sanity check, while a newly onboarded, unlisted chip may show parsing notes that require attention first.

Step 3: Set options and generate

After checking the parsed model, choose the peripherals that need drivers and set the output options.

Peripheral selection: Select the peripherals for code generation. With an STM32F4 reference manual, for example, you could choose USART, SPI, and I2C now, and leave ADC and TIM for a later run.

Output configuration (per peripheral):

  • Transfer mode: polling, interrupt, or DMA
  • Output language: C99, or a C++17 wrapper for Engineer tier and above
  • RTOS-aware locking: mutex acquire/release around state machines (FreeRTOS or Zephyr)
  • Test stubs: include or omit register read-back test functions

Web UI: Set these options in each peripheral's accordion panel, then select Generate.

CLI:

embedd generate \
  --doc-id <document_id> \
  --peripherals SPI1,I2C1,USART1 \
  --mode interrupt \
  --lang c99 \
  --rtos freertos \
  --test-stubs

The server generates the output, usually in under 30 seconds, and returns a job ID.

Step 4: Download the output

Web UI: When the job finishes, select "Download archive". The .zip includes a directory for every selected peripheral and a top-level CMakeLists.txt defining a static library target for each one.

CLI:

embedd download --job-id <job_id> --output ./drivers

Extract the archive into your project's drivers/ directory, or another location you choose. Its directory structure is:

drivers/
  stm32f4_spi/
    include/
      stm32f4_spi.h
      stm32f4_spi_types.h
    src/
      stm32f4_spi.c
      stm32f4_spi_test.c
    CMakeLists.txt
  stm32f4_i2c/
    ...
  CMakeLists.txt   <-- top-level, adds all subdirectory targets

Step 5: Add it to CMake

Including the generated drivers takes three lines in the top-level CMakeLists.txt:

add_subdirectory(drivers)

target_link_libraries(my_firmware
    PRIVATE stm32f4_spi stm32f4_i2c
)

target_include_directories(my_firmware
    PRIVATE drivers/stm32f4_spi/include
            drivers/stm32f4_i2c/include
)

Generated drivers have no dependency on vendor HAL headers. Instead, they use offset macros from the generated headers to refer to peripheral registers. Provide the peripheral base address from your existing CMSIS headers or your own memory map defines when calling the init function.

What the workflow leaves out

Embedd creates peripheral drivers, including register map code, configuration functions, data transfer functions, and interrupt service routine stubs. It does not create system initialization code for the clock tree, PLL configuration, GPIO mux, or power sequencing. Those details depend on the board, power budget, and clock requirements, which a peripheral datasheet does not describe. The generated documentation notes each peripheral's required system resources and the state they must be in before its init function is called.

You can repeat the Embedd workflow as project requirements shift. For example, changing a UART from polling to interrupt mode mid-project still takes the same two minutes to regenerate. The register definitions remain aligned with the silicon register map, while the transfer mode plumbing changes between runs.

Generate your first driver

Upload a chip datasheet and generate C99 peripheral drivers.

Get started free