Skip to main content
Use this workflow to write or adapt a driver for one fitted part on a specific board revision. You confirm the hardware facts, agree on the driver’s interface in a plan, implement it in stages with host tests, and then verify it on the board. Start with Rapid bring-up if the board doesn’t yet build, boot, or give you a working way to observe it.

Establish the hardware facts

  1. Open the firmware workspace and run /project to select the project.
  2. Run /peripheral and add the fitted part. For a part outside the catalog, add a custom peripheral from its datasheet PDF.
  3. Provide the exact datasheet revision, relevant errata, the MCU reference manual, and the complete schematic set for this board. To add a PDF that is already in your workspace to the project’s documents, ask Embedder. It asks you to confirm before adding the file.
  4. If the workspace isn’t configured yet, run /init. Check the toolchain, SDK version, build and test commands, flash method, and monitoring setup it records in EMBEDDER.md.
A catalog match doesn’t identify the populated variant or confirm the board’s wiring. Check the package, supply and signal voltages, address straps or chip select, reset polarity, clock source, interrupts, and routed MCU pins against the actual design. Reference the schematic and your source files directly in the request:
Replace U4 and the source path with your own. Resolve any conflict that affects wiring, electrical limits, or initialization before you continue.

Define the driver contract

Run /plan to agree on the driver’s interface and limits before Embedder changes several modules. In Plan mode, Embedder reads code, documents, and schematics and writes a plan. It doesn’t edit your source or run a build.
Make sure the plan settles these points: Retry only operations that the device lets you repeat safely. Repeating a command, clearing a status bit, or reading a FIFO can change the device’s state.

Choose reuse or a custom implementation

Ask Embedder to inspect the existing SDK, HAL, and drivers before it adds code. Prefer an existing driver when it supports the exact device and the behavior you need. Check its version, license, supported modes, and error handling. A similarly named part may use a different register map. For a custom driver, separate device behavior from bus access so host tests can supply controlled responses. Keep board pins, bus instances, and interrupt routing in the project’s board layer. Respect generated-code boundaries and the project’s existing style. Check the reference documents for the details that differ between parts:
  • MCU peripherals: clock enables, reset order, pin multiplexing, interrupt flags, and DMA requirements, from the reference manual and errata.
  • External devices: framing, byte order, command sequences, reserved bits, and read or write side effects, from the datasheet.
Derive constants from the exact reference. Don’t copy them from a nearby device family.

Implement and test in stages

Review the plan, then approve it so Embedder implements it in Act mode. In VS Code, select Approve & Execute on the plan card. Start with initialization and one bounded transaction before you add buffered, interrupt, or DMA operation.
Test decoding with boundary values, sign handling, units, and invalid responses. Exercise error paths through a fake transport or the project’s existing test framework. Check that a timed-out request ends, reports the intended error, and allows the documented next operation. Fix test, compile, and link failures before you flash. Each check covers only part of the result:

Validate on the intended board

Confirm the board revision, fitted part, firmware file, and probe or port. Set up the UART, logic analyzer, or oscilloscope from its guide, including voltage limits and channel assignments.
Adapt the bus and observation method to your device. Compare the transmitted sequence with the datasheet, and the returned values with known test conditions. An acknowledgment alone doesn’t show that the configuration or measurement is correct. Use an oscilloscope when the question concerns signal levels, rise time, ringing, or setup and hold timing. Choose a sample rate and trigger that suit the signal. When you measure timing, use the achieved sample rate, which can differ from the one you request. If the conclusion depends on one event appearing in several captures, use a common marker or trigger. Independent logs don’t necessarily share a clock. For a hang or unexpected driver state, switch to Debug mode with /debug. Keep the existing evidence, and follow the attachment precautions before you connect a debugger. Halting changes timing, so reproduce timing-sensitive results while the firmware runs normally.

Keep the regression repeatable

Ask Embedder to save the verified sequence as a hardware script under .embedder/hardware/, with the bench settings, bounded waits, pass conditions, and cleanup. Hardware scripts run in Act or Debug mode.
Keep a host regression test for each software failure you correct. Add target checks for reset, repeated initialization, power-state, or recovery behavior, following the board’s approved test procedure. Run the same checks after SDK, clock, bus, or driver changes, and record any requirement that remains unverified. To run these checks routinely, see Automated testing.
Last modified on October 13, 2026