Under the Hood

Embedd pipeline

Four coordinated stages: ingestion, extraction, generation, validation, then export. Each stage is deterministic and auditable.

Stage 01

Ingestion stage

Embedd takes a chip identifier from the supported library or a raw PDF upload. The ingestion layer normalises page content, splits multi-column layouts, and divides the document into functional blocks: pin descriptions, electrical characteristics, register tables, and timing diagrams.

  • PDF or chip library search
  • Automatic layout separation
  • Register-block table boundary detection
  • Handles up to 800 pages
$ embedd ingest --file nxp_lpc5569.pdf
Parsing 643 pages...
Detected 94 register tables
Segmented 2,318 bitfield rows
Ingestion complete. Ready to extract.
Stage 02

Register extraction

The extraction engine examines each register-table row, determining bitfield offsets, widths, access modes (RW, RO, WO, RC), and reset values. It reconstructs fragmented tables spanning pages into one register model.

  • Bitfield offsets and widths resolved
  • Normalised access modes (RW, RO, WO, RC, RS)
  • Reset values from table headers
  • Cross-page stitching
register_model.json (intermediate) JSON
{
  "name": "USART_CR1",
  "offset": 0x00,
  "reset_value": 0x00000000,
  "fields": [
    {
      "name": "UE",
      "bit": 0,
      "width": 1,
      "access": "rw",
      "desc": "USART enable"
    },
    {
      "name": "UESM",
      "bit": 1,
      "width": 1,
      "access": "rw",
      "desc": "USART enable in stop mode"
    }
  ]
}
Stage 03

Code generation

The register model feeds a code generator that produces typed HAL accessors, bitfield masks, reset-value constants, and optional struct overlays. C99 is the default language output. C++17 and Rust (Team plan) provide stronger type safety and constexpr constants.

  • Typed accessors for each register
  • Bitfield masks and shift values
  • #defines and constexpr for reset values
  • Optional struct overlay
usart_hal.h (generated) C99
/* USART_CR1 bitfield accessors */
#define USART_CR1_UE_MSK    ((uint32_t)(1UL << 0U))
#define USART_CR1_UESM_MSK  ((uint32_t)(1UL << 1U))
#define USART_CR1_RESET     ((uint32_t)0x00000000U)

static inline void usart_enable(USART_TypeDef *u) {
  u->CR1 |= USART_CR1_UE_MSK;
}

static inline void usart_disable(USART_TypeDef *u) {
  u->CR1 &= ~USART_CR1_UE_MSK;
}
Stage 04

Quality gate

Before packaging, Embedd checks unique offsets, bitfield overlaps, access-mode consistency, and compilation with a bare-metal GCC cross-compiler. Only passing output is delivered.

  • Unique register offsets
  • Bitfield overlap and gap checks
  • Access-mode check (RO field not written)
  • GCC cross-compile check
$ embedd validate nxp_lpc5569_hal/
Checking offset uniqueness... OK
Checking bitfield overlaps... OK
Checking access consistency... OK
Compile smoke test (arm-none-eabi-gcc)... OK
All checks passed. Packaging output.
Stage 05

Export channels

Validated output is packaged and delivered via the channel that fits your workflow.

Download ZIP

A .zip archive containing headers, source files, and a minimal Makefile fragment is provided in the browser for immediate use.

CLI

The embedd CLI writes output to a path in your repository. Invoke it from a CMake custom target or Makefile rule to regenerate on demand.

REST API

POST a chip identifier; get a signed URL. Webhook callbacks alert your CI job when async generation completes for large datasheets.

Try it yourself

The free Explorer plan provides three driver generations with no time limit. No card required.