Inspiration
Writing a driver for a new sensor means reading a 50–100 page datasheet and turning its register tables, bit fields, timing diagrams and conversion formulas into C. AI coding agents can now write that C in minutes, and it usually compiles. But compiling says nothing about whether the bytes the code sends are the bytes the chip expects. A wrong bit in a configuration register, two bytes swapped, or a missing power-up delay only shows up later, on a real board, as a sensor that reads nonsense. We wanted the agent's work checked against the datasheet itself, before any board or simulator exists.
What it does
EmbedForge is an IDE and agent for embedded firmware. You describe the part, the board and the wiring, and an NVIDIA Nemotron agent:
- Researches the official datasheet with Tavily: Search to find it, Map to find the vendor's own PDFs, Extract to read them.
- Records what it relies on: pins, bus addresses, register fields, byte layouts, conversion formulas, timing rules and init sequences. Every record must quote the datasheet word for word, or it is refused.
- Writes the driver and builds it with the real vendor toolchain (PlatformIO).
- Verifies it.
verifyreads the C without running it, works out every byte the code would send to the chip, and compares that with the records: wrong field values, reserved bits, swapped bytes, a conversion that does not match the datasheet formula, settings written in an order the datasheet forbids, a missing delay. Each error has a file and line, and goes back to the agent to fix. - Measures its own check. On every delivered driver, a mutation test plants realistic bugs (a constant off by one bit, a pin moved, a delay deleted, a check inverted) and reports how many verify catches.
It also builds Betaflight flight-controller board configs the same way.
How we built it
- NVIDIA open models throughout. Nemotron 3 Ultra is the agent; Super, Nano and 3.5 Lightning were tested too. Nemotron Embed (
nemotron-3-embed-1b) searches long datasheets by section, and Nemotron 3.5 Super VL transcribes timing diagrams that text extraction loses. - Nebius Token Factory. EmbedForge was built and evaluated there: 69 runs over four Nemotron models, using the model card's sampling and
enable_thinkingfor tool calling. Token Factory served Ultra at about 5 s per agent step, which matters for loops of 50–150 steps. When our credits ran out on 9 October, we continued with the same Nemotron 3 Ultra through NVIDIA's API, at about 20 s per step.deploy/nebius-vm/serves Nemotron 3 Super with vLLM on a Nebius AI Cloud GPU VM. - A truth layer: a fact ledger with a verbatim-quote gate, a register book (fields, register widths, byte order, layouts, formulas, constraints) and a sequence book (the datasheet's order and timing).
- Our own static C tracer. It walks the driver from
setup()/main()through Arduino Wire/SPI, pico-sdk, STM32 HAL, ESP-IDF and Zephyr bus calls, keeps every byte it reads tied to its register, and can run the code on concrete register values to compare its arithmetic with the recorded formulas. - Evidence: a benchmark of 30 driver variants with 673 planted bugs, 392 unit tests, and a run table generated from every run's trace.
Challenges we ran into
- Models invent sources. So every fact must be quoted verbatim. Then the opposite problem appeared: half of the agent's recording calls were refused, often for typography (
x8for the datasheet's×8, curly quotes, TI's1001000xaddress notation). We measured the refusal reasons across runs and fixed the matching, without loosening what has to be true. - PDFs break formulas. Exponents and fraction bars vanish ("2osr_p" is 2^osr_p). The agent can quote the manufacturer's reference code from its official GitHub organisation instead.
- A second vendor broke our assumptions. TI's TMP117 has 16-bit registers, writes hex as
0Fhand names fieldsT/nA. Verify only modelled 8-bit registers. It now records each register's width and the datasheet's sentence on byte order, and catches bytes assembled swapped or a register written in half. - A PASS that wasn't. One TMP117 run passed verify, but its temperature formula had never been compared with the code (the probe gave the ID register a random value, so the driver stopped at its ID check), and the formula came from a hobbyist library. Since then we treat every PASS as a claim to test. The mutation test exposed several more gaps this way, and each was closed in general, not for that one driver.
- Keeping long runs alive through crashes and restarts: atomic writes, a conversation saved at every step, and resume.
Accomplishments we're proud of
- A Nemotron-written BMP388 driver (Bosch) for an RP2350B board. Verify caught real bugs in it: a calibration coefficient divided instead of multiplied, wrong signedness, and normal mode switched on before the oversampling settings, which breaks the datasheet's conversion-time rule. After Nemotron fixed them: verify PASS, and 48 of 49 planted bugs caught.
- The same TI TMP117 task, run cold twice. The first run took 150 steps and did not pass. After the fixes: 55 steps, 1 Tavily credit, verify PASS with 0 errors and 0 warnings, and every value quoted from TI's datasheet.
- Bosch's own BMP3 reference driver. Run on it, verify found a real defect: the soft-reset routine uses the command register's address as a bit mask.
What we learned
- Verification has to be grounded in something the model cannot write itself: the datasheet's own words.
- A green check needs its own test. Mutation testing found more weaknesses in our verifier than any review did.
- Measure before blaming the model. Most of the agent's "mistakes" were our harness being strict about format.
- In long agent loops, context size and per-step latency drive cost and time. The larger Nemotron models (Ultra, Super) held 50–150-step loops; Nano tended to loop in research.
What's next
An optional hardware-in-the-loop confirmation as the last step, more register styles (16-bit register addresses), and more vendor drivers checked, to measure the false-positive rate.
Log in or sign up for Devpost to join the conversation.