# vemu - Browser Hardware Emulator > Boot embedded firmware in the browser. vemu is a WebAssembly hardware emulator for Cortex-M and more - no hardware required. > Generated: 2026-06-01 --- ## Getting Started URL: https://vemulator.com/docs/getting-started # Getting Started vemu runs real firmware in the browser through WebAssembly. Two npm packages get you there: - `@swedishembedded/vemu` - the emulator runtime (freeware wasm build) - `@swedishembedded/vemu-react` - React components and hooks for embedding it ## Install ```bash npm install @swedishembedded/vemu @swedishembedded/vemu-react ``` `@swedishembedded/vemu-react` declares `react >= 18` and `@swedishembedded/vemu` as peer dependencies. ## Initialize the runtime The wasm module loads lazily. Call `initVemu()` once before constructing an emulator: ```ts await initVemu(); const boards = JSON.parse(list_boards()); // -> [{ id: "nordic,nrf5340-dk-cpuapp", name: "nRF5340 DK (App core)", arch: "..." }, ...] ``` ## Boot a board Construct an `Emulator` with a board id, firmware bytes, and the image kind (`"elf"` for ELF binaries, `"bin"` for raw flash images, `"hex"` for Intel HEX images). An empty byte array builds a firmware-less machine - useful for inspecting peripherals before loading code. ```ts const elf = new Uint8Array(await (await fetch("/firmware/zephyr.elf")).arrayBuffer()); const emu = new Emulator("nordic,nrf5340-dk-cpuapp", elf, "elf"); emu.onEvent((events) => { for (const { kind, payload } of events) { if (kind === "uart.tx") { // payload.bytes is a Uint8Array of console output } } }); function frame() { const running = emu.step_frame(); if (running) requestAnimationFrame(frame); } requestAnimationFrame(frame); ``` Console input goes the other way through `dispatch`: ```ts emu.dispatch("uart.rx", JSON.stringify({ bytes: [...new TextEncoder().encode("help\n")] })); ``` Every event kind the runtime accepts and emits is documented in the [event vocabulary](/docs/reference/events) and on the per-peripheral pages of the [runtime reference](/docs/reference) - generated from the exact build you install. ## Use the React components `@swedishembedded/vemu-react` wraps the loop, the canvas, and an xterm.js terminal so you don't write any of the above by hand: ```tsx function EmbeddedVemu() { const vemu = useVemu(); return (
); } ``` See the [React API reference](/docs/react) for every component, hook, and prop. The demo on the front page of this site is built with exactly these components - what you install is what you see. ## Next steps - [Build your own peripheral view components](/docs/custom-views) - [Query peripherals and events at runtime](/docs/runtime-introspection) - [Browse the runtime reference](/docs/reference) --- ## Custom Views URL: https://vemulator.com/docs/custom-views # Custom View Components The peripheral panel in `@swedishembedded/vemu-react` is a plugin system: every peripheral view is a React component implementing one interface, looked up from a registry by peripheral name. The built-in inspectors (KMU, UICR) use the same mechanism - your views are not second-class. ## The view contract A view receives everything it needs through [`PeripheralViewProps`](/docs/react/peripheralviewprops): ```tsx export function MyTimerView({ name, events, refreshKey, getSnapshot, sendCommand }: PeripheralViewProps) { // 1. Filter the event stream for kinds your peripheral emits. const myEvents = events.filter((e) => e.kind.startsWith("nrf.timer.")); // 2. Pull a state snapshot whenever refreshKey bumps. // The shape is the peripheral's snapshot field map - see its reference page. const snapshot = getSnapshot(); // 3. Drive the peripheral with its documented commands. const inject = () => sendCommand({ name: "inject_fault", params: { kind: "bus" } }); return
{JSON.stringify(snapshot, null, 2)}
; } ``` The pieces: - `events` - the recent [host event](/docs/reference/events) envelopes (`{ kind, payload }`); filter by the kinds listed on your peripheral's [reference page](/docs/reference). - `refreshKey` - a monotonic counter that bumps when new events arrive or snapshots change; depend on it in `useEffect` to re-read snapshots. - `getSnapshot()` - the peripheral's current inspector field map (documented as "snapshot fields" on its reference page). - `sendCommand(cmd)` - sends an inspector command; names and params are documented per peripheral. ## Register the view Map a peripheral name to your component in the `PERIPHERAL_VIEWS` registry: ```tsx PERIPHERAL_VIEWS["timer0"] = MyTimerView; PERIPHERAL_LABELS["timer0"] = "TIMER0"; ``` When `peripheral_list()` reports a peripheral named `timer0`, the `PeripheralPanel` renders your view; unregistered peripherals fall back to the generic JSON inspector ([`GenericInspector`](/docs/react/genericinspector)). ## Discover what a peripheral supports You never have to guess kinds, commands, or snapshot shapes: - **At design time** - every published peripheral has a reference page listing its accepted/emitted event kinds with payload schemas, commands with params, and snapshot fields. The same data is machine-readable at [`/docs/reference.json`](/docs/reference.json). - **At runtime** - the emulator describes itself; see [runtime introspection](/docs/runtime-introspection). The docs and the runtime can't disagree: peripheral metadata is declared in the emulator source and extracted from the same wasm build this site ships. --- ## Runtime Introspection URL: https://vemulator.com/docs/runtime-introspection # Runtime Introspection A running emulator can tell you what it is made of: which peripherals are wired, which event kinds each accepts and emits (with payload schemas), which commands it understands, and what its inspector snapshots look like. This is the same reflection data these docs are generated from - exposed to your code and to AI tooling at runtime. ## List and inspect peripherals ```ts const emu = new Emulator("nordic,nrf5340-dk-cpuapp", new Uint8Array(), "elf"); // Named peripherals with inspectors: const names = JSON.parse(emu.peripheral_list()); // ["kmu", "uicr", ...] // Current inspector state (field map; shape per the peripheral's docs): const snapshot = JSON.parse(emu.peripheral_snapshot("kmu")); // Drive a documented command: emu.peripheral_command("kmu", JSON.stringify({ name: "write_slot", params: { slot: "5", k0: "0xDEADBEEF", k1: "0x1", k2: "0x2", k3: "0x3" }, })); ``` Command params always travel as strings; integer params accept `0x`/`0b` prefixes. Each peripheral's commands and their parsing are listed on its [reference page](/docs/reference). ## Describe one machine `describe()` returns the full reflection document for the constructed machine: its board identity, every wired peripheral (name, base address, capabilities), each peripheral's static metadata - accepted inputs and event kinds, emitted effects and event kinds with payload schemas, commands - plus the builtin event vocabulary: ```ts const description = JSON.parse(emu.describe()); for (const p of description.peripherals) { console.log(p.name, p.metadata?.events_out?.map((e) => e.kind)); } ``` ## Describe the whole build The module-level `describe_runtime()` catalogs **every board compiled into the wasm build you installed** without constructing them yourself: ```ts await initVemu(); const runtime: RuntimeDescription = JSON.parse(describe_runtime()); runtime.boards; // every board in this build runtime.peripherals; // catalog keyed by compatible (e.g. "nordic,nrf-kmu-nvmc") runtime.global_events; // builtin in/out event vocabulary ``` This is the document the [runtime reference](/docs/reference) pages are built from at site-build time - and the right entry point for an AI agent that needs to know what it can and cannot do with a given peripheral before debugging firmware on it. Because the metadata is declared inside each peripheral model and extracted from the compiled runtime, `describe_runtime()` always reflects exactly the build you are running - never a stale document. ## Machine-readable docs The curated reference data for this site's build ships next to these pages: - [`/docs/reference.json`](/docs/reference.json) - boards, peripherals, events, commands - [`/docs/react-api.json`](/docs/react-api.json) - the vemu-react API surface Both are stable, versioned artifacts - point your tooling at them. --- ## Event Vocabulary URL: https://vemulator.com/docs/reference/events ### Outbound events (emulator -> host) #### `audio.samples` Interleaved PCM audio samples were produced. Payload schema: ```json { "properties": { "sample_count": { "description": "Number of samples in the batch.", "format": "u64", "type": "integer" } }, "required": [ "sample_count" ], "type": "object" } ``` #### `gpio.change` A GPIO output pin changed level. Payload schema: ```json { "properties": { "level": { "description": "New logical level (`true` = high).", "type": "boolean" }, "pin": { "description": "Pin number within the port.", "format": "u32", "type": "integer" }, "port": { "description": "GPIO port index.", "format": "u32", "type": "integer" } }, "required": [ "port", "pin", "level" ], "type": "object" } ``` #### `irq.lower` An interrupt line was deasserted. Payload schema: ```json { "properties": { "line": { "description": "NVIC IRQ number (Cortex-M) or GIC SPI number (Cortex-A).", "format": "u32", "type": "integer" } }, "required": [ "line" ], "type": "object" } ``` #### `irq.raise` An interrupt line was asserted (pended). Payload schema: ```json { "properties": { "line": { "description": "NVIC IRQ number (Cortex-M) or GIC SPI number (Cortex-A).", "format": "u32", "type": "integer" } }, "required": [ "line" ], "type": "object" } ``` #### `uart.tx` Bytes transmitted by the guest on a UART/serial port. Payload schema: ```json { "properties": { "bytes": { "description": "Transmitted bytes.", "format": "bytes", "items": { "format": "u8", "type": "integer" }, "type": "array" }, "port": { "description": "Logical UART port index (0 = primary console).", "format": "u32", "type": "integer" } }, "required": [ "port", "bytes" ], "type": "object" } ``` #### `video.frame` A completed display frame is available; fetch pixels via the framebuffer API. Payload schema: ```json { "properties": { "height": { "description": "Frame height in pixels.", "format": "u32", "type": "integer" }, "width": { "description": "Frame width in pixels.", "format": "u32", "type": "integer" } }, "required": [ "width", "height" ], "type": "object" } ``` ### Inbound events (host -> emulator) #### `joypad` Game controller state for console boards. Payload schema: ```json { "properties": { "bits": { "description": "Packed button bitmask.", "format": "u32", "type": "integer" } }, "required": [ "bits" ], "type": "object" } ``` #### `uart.rx` Bytes from the host (terminal keystrokes) delivered to the guest UART RX line. Payload schema: ```json { "properties": { "bytes": { "description": "Received bytes.", "format": "bytes", "items": { "format": "u8", "type": "integer" }, "type": "array" } }, "required": [ "bytes" ], "type": "object" } ``` --- ## Boards URL: https://vemulator.com/docs/reference ### VEMU Cortex-M55 + Ethos-U65 URL: https://vemulator.com/docs/reference/boards/arm-vemu-cortex-m55-npu Architecture: armv8m ID: arm,vemu-cortex-m55-npu Peripheral map: - 0x4000c000 uart0 (arm,pl011) - 0x4000d000 uart1 (arm,pl011) - 0x4000e000 uart2 (arm,pl011) - 0x50004000 npu (arm,ethos-u65) ### nRF5340-DK Application Core URL: https://vemulator.com/docs/reference/boards/nordic-nrf5340-dk-cpuapp Architecture: armv8m ID: nordic,nrf5340-dk-cpuapp Peripheral map: - 0x00ff0000 ficr (nordic,nrf-ficr) - 0x00ff8000 uicr (nordic,nrf-uicr) - 0x40000000 dcnf (nordic,nrf-dcnf) - 0x40001000 cache (nordic,nrf-cache) - 0x40003000 spu (nordic,nrf-spu) - 0x40004000 oscillators (nordic,nrf-oscillators) - 0x40005000 clock (nordic,nrf-clock) - 0x40006000 ctrlap (nordic,nrf-ctrlap) - 0x40008000 uarte0 (nordic,nrf-uarte) - 0x40009000 uarte1 (nordic,nrf-uarte) - 0x4000a000 spim4 (nordic,nrf-spim) - 0x4000b000 uarte2 (nordic,nrf-uarte) - 0x4000c000 uarte3 (nordic,nrf-uarte) - 0x4000d000 gpiote0 (nordic,nrf-gpiote) - 0x4000e000 saadc (nordic,nrf-saadc) - 0x4000f000 timer0 (nordic,nrf-timer) - 0x40010000 timer1 (nordic,nrf-timer) - 0x40011000 timer2 (nordic,nrf-timer) - 0x40014000 rtc0 (nordic,nrf-rtc) - 0x40015000 rtc1 (nordic,nrf-rtc) - 0x40017000 dppic (nordic,nrf-dppic) - 0x40018000 wdt0 (nordic,nrf-wdt) - 0x40019000 wdt1 (nordic,nrf-wdt) - 0x4001a000 comp (nordic,nrf-comp) - 0x4001b000 egu0 (nordic,nrf-egu) - 0x4001c000 egu1 (nordic,nrf-egu) - 0x4001d000 egu2 (nordic,nrf-egu) - 0x4001e000 egu3 (nordic,nrf-egu) - 0x4001f000 egu4 (nordic,nrf-egu) - 0x40020000 egu5 (nordic,nrf-egu) - 0x40021000 pwm0 (nordic,nrf-pwm) - 0x40022000 pwm1 (nordic,nrf-pwm) - 0x40023000 pwm2 (nordic,nrf-pwm) - 0x40024000 pwm3 (nordic,nrf-pwm) - 0x40026000 pdm0 (nordic,nrf-pdm) - 0x40028000 i2s0 (nordic,nrf-i2s) - 0x4002a000 ipc (nordic,nrf-ipc) - 0x4002b000 qspi (nordic,nrf-qspi) - 0x4002d000 nfct (nordic,nrf-nfct) - 0x4002f000 gpiote1 (nordic,nrf-gpiote) - 0x40030000 mutex (nordic,nrf-mutex) - 0x40033000 qdec0 (nordic,nrf-qdec) - 0x40034000 qdec1 (nordic,nrf-qdec) - 0x40036000 usbd (nordic,nrf-usbd) - 0x40037000 usbreg (nordic,nrf-usbreg) - 0x40039000 kmu (nordic,nrf-kmu-nvmc) - 0x40081000 vmc (nordic,nrf-vmc) - 0x40842500 gpio0 (nordic,nrf-gpio) - 0x40842800 gpio1 (nordic,nrf-gpio) - 0x40844000 cryptocell (nordic,nrf-cryptocell) --- ## Peripherals URL: https://vemulator.com/docs/reference ### Arm Ethos-U65 NPU URL: https://vemulator.com/docs/reference/peripherals/arm-ethos-u65 ID: arm,ethos-u65 Class: System & Infrastructure / Miscellaneous Arm Ethos-U65 microNPU. The driver writes the command-stream address/length to `QBASE`/`QSIZE` and sets `CMD`=run; the model fetches the command stream by bus-mastered read-back, decodes and sequences it into a neutral operator, gathers the IFM/weight/scale tensors (further read-backs), runs the op on the injected accelerator backend, writes the OFM back to guest memory, and raises the NPU IRQ with the `NPU_OP_STOP` mask reflected into `STATUS`. #### Events emitted - `ethos.npu.inference_complete`: The NPU finished executing a command stream (reached NPU_OP_STOP) and raised its completion IRQ. #### Events accepted - `vemu.easydma.read_back_complete`: Bus-internal completion: EasyDMA read-back bytes are available. #### Snapshot fields - `status` (u32): STATUS - `running` (bool): Running - `qbase` (u64): QBASE (cmd stream addr) - `qsize` (u32): QSIZE (bytes) - `qread` (u32): QREAD (progress) - `op_count` (u32): Decoded compute ops - `stop_mask` (u32): Last NPU_OP_STOP mask - `inferences` (u64): Inferences completed - `errors` (u64): Inference errors - `irq_line` (u32): IRQ line - `executor` (str): Compute backend ### ARM PrimeCell PL011 UART URL: https://vemulator.com/docs/reference/peripherals/arm-pl011 ID: arm,pl011 Class: Connectivity / UART / Serial Behavioral PL011 UART model (also covers `ti,stellaris-uart`). TX bytes surface as `uart.tx` events; host bytes arrive as `uart.rx` inputs and are buffered in a small RX FIFO popped via `DR` reads. No baud timing - TX is always ready. #### Commands - `rx`: Inject receive bytes into the UART RX FIFO from a hex string (e.g. "68656c6c6f" or "68 65 6c"; spaces and a 0x prefix are ignored). The guest then reads the bytes via DR. #### Snapshot fields - `DR` (u32): Data Register - `FR` (u32): Flag Register - `IBRD` (u32): Integer Baud Rate - `FBRD` (u32): Fractional Baud Rate - `LCRH` (u32): Line Control Register - `CR` (u32): Control Register ### nRF5340 CACHE URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-cache ID: nordic,nrf-cache Class: Memory & Storage / Cache Transparent no-op cache controller: READY always reads 1, TASKS_STARTERASE latches EVENTS_STARTED and EVENTS_DONE in the same write (instant erase), INTEN/INTENSET/INTENCLR gate the IRQ, and ENABLE/PROFILING are stored with no effect on memory access behaviour or timing. #### Events emitted - `nrf.cache.erase_done`: Fires immediately after nrf.cache.erase_started: the emulated erase completes in the same write cycle, so EVENTS_DONE is set atomically. - `nrf.cache.erase_started`: Fires when TASKS_STARTERASE is written and the EVENTS_STARTED latch is set. In emulation the erase is instantaneous so EVENTS_DONE fires in the same write cycle. #### Snapshot fields - `state_json` (str): CACHE State (JSON) - `inten` (u32): INTEN - `enable` (u32): ENABLE - `profiling` (u32): PROFILING - `ev_started` (bool): EVENTS_STARTED - `ev_done` (bool): EVENTS_DONE ### nRF5340 CLOCK/POWER/RESET URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-clock ID: nordic,nrf-clock Class: System & Infrastructure / Clock Control Combined model of the shared CLOCK, POWER, and RESET block. All clock start/stop tasks and LFRC calibration complete instantly: the matching `STARTED`/`DONE` event latches in the same write cycle (IRQ when enabled). GPREGRET, RESETREAS (W1C), and `NETWORK.FORCEOFF` are stored; DPPI subscribe/publish registers are stored but not acted on. #### Snapshot fields - `state_json` (str): CLOCK/POWER/RESET State (JSON) - `inten` (u32): INTEN (interrupt enable mask) - `hfclkstat` (u32): HFCLKSTAT - `lfclkstat` (u32): LFCLKSTAT - `hfclk192mstat` (u32): HFCLK192MSTAT - `resetreas` (u32): RESETREAS - `network_forceoff` (u32): NETWORK.FORCEOFF ### nRF5340 COMP (comparator) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-comp ID: nordic,nrf-comp Class: Analog / Comparator Behavioral COMP model: `TASKS_START` fires `EVENTS_READY` (IRQ when enabled). `TASKS_SAMPLE` captures the comparator output. `TASKS_STOP` halts the comparator. SHORTS (READY_SAMPLE, READY_STOP, DOWN_STOP, UP_STOP, CROSS_STOP) and DPPI SUBSCRIBE/PUBLISH are supported. No real analog signal: RESULT always reads 0 (input below threshold); UP/DOWN/CROSS events never fire. #### Events emitted - `nrf.comp.ready`: COMP peripheral is ready and output is valid (EVENTS_READY fired). - `nrf.comp.sampled`: Comparator value was sampled by TASKS_SAMPLE. #### Snapshot fields - `state_json` (str): COMP State (JSON) - `inten` (u32): INTEN - `ev_ready` (u32): EVENTS_READY - `ev_down` (u32): EVENTS_DOWN - `ev_up` (u32): EVENTS_UP - `ev_cross` (u32): EVENTS_CROSS - `enable` (u32): ENABLE - `running` (bool): Running - `shorts` (u32): SHORTS ### nRF5340 CRYPTOCELL (ARM CryptoCell-312 wrapper) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-cryptocell ID: nordic,nrf-cryptocell Class: Security / Crypto Accelerator Software-fallback stub for the CC312 hardware crypto engine: the wrapper `ENABLE` register (reset value 0) and the `HOST_RGF` IRR/IMR/ICR registers are modelled, which is enough for PSA/TF-M to detect that CryptoCell is unavailable and fall back to Mbed TLS software crypto. The CC_RNG TRNG block at +0x1000 is modelled functionally (EHR entropy registers fed by a deterministic xorshift64 generator) so secure-world provisioning code that drives the TRNG register protocol directly (e.g. TF-M HUK/IAK generation) completes in VEMU. No other crypto operations are emulated. #### Events emitted - `nrf.cryptocell.trng_refresh`: Fires when the TRNG entropy health registers (EHR) are refreshed, either on a TRNG_RESET write or after RNG_SW_RESET. #### Snapshot fields - `state_json` (str): CryptoCell State (JSON) - `cc_enable` (u32): CC ENABLE - `host_irr` (u32): HOST_RGF IRR (pending IRQs) - `host_imr` (u32): HOST_RGF IMR (IRQ mask) - `rng_imr` (u32): RNG IMR (RNG interrupt mask) - `trng_valid` (u32): TRNG_VALID (entropy ready) - `sample_cnt` (u32): SAMPLE_CNT (subsampling rate) ### nRF5340 CTRLAP (control access port) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-ctrlap ID: nordic,nrf-ctrlap Class: System & Infrastructure / Debug & Trace Behavioral model of the nRF5340 CTRL-AP peripheral (CPU side, sec 8.10.7). The CPU-to-debugger mailbox is fully modeled: writing TXDATA emits a `nrf.ctrlap.mailbox_tx` event and sets TXSTATUS=DataPending; reading RXDATA auto-clears RXSTATUS. Protection LOCK/DISABLE/STATUS registers are stored and read back. All protection is disabled by default in emulation so the debugger always has full access. #### Events emitted - `nrf.ctrlap.approtect_disable`: Firmware wrote a value to APPROTECT.DISABLE or SECUREAPPROTECT.DISABLE, attempting to disable access port protection. - `nrf.ctrlap.mailbox_tx`: Firmware wrote data to the CTRLAP MAILBOX.TXDATA register, sending a message to the debugger. The payload carries the data value. #### Snapshot fields - `state_json` (str): CTRLAP State (JSON) - `mailbox_rxdata` (u32): MAILBOX.RXDATA - `mailbox_rxstatus` (u32): MAILBOX.RXSTATUS - `mailbox_txdata` (u32): MAILBOX.TXDATA - `mailbox_txstatus` (u32): MAILBOX.TXSTATUS - `approtect_disable` (u32): APPROTECT.DISABLE - `secureapprotect_disable` (u32): SECUREAPPROTECT.DISABLE - `status` (u32): STATUS ### nRF5340 DCNF (domain configuration) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-dcnf ID: nordic,nrf-dcnf Class: System & Infrastructure / System Config Domain configuration block present on both application and network cores of the nRF5340. The read-only `CPUID` register reports the core identity (0 = application, 1 = network) so firmware can identify its own core. On the application core the EXTPERI[0], EXTRAM[0], and EXTCODE[0] PROTECT registers gate AHB multilayer interconnect (AMLI) access by the network core; on the network core those registers are not present and writes to them are silently ignored. #### Snapshot fields - `core_id` (u32): Core ID (CPUID) - `extperi0_protect` (u32): EXTPERI[0].PROTECT - `extram0_protect` (u32): EXTRAM[0].PROTECT - `extcode0_protect` (u32): EXTCODE[0].PROTECT - `state_json` (str): DCNF State Summary (JSON) ### nRF5340 DPPIC (distributed PPI controller) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-dppic ID: nordic,nrf-dppic Class: System & Infrastructure / Event Routing DPPI controller with 32 channels and 6 channel groups. CHEN/CHENSET/CHENCLR writes (and CHG group enable/disable tasks) propagate immediately to the shared `DppiBus` channel-enable mask so publishes within the same tick are routed correctly; the event routing itself happens inside the bus, not via effects. #### Snapshot fields - `chen` (u32): CHEN (channel enable) - `chg0` (u32): CHG[0] (channel group 0) - `chg1` (u32): CHG[1] (channel group 1) - `chg2` (u32): CHG[2] (channel group 2) - `chg3` (u32): CHG[3] (channel group 3) - `chg4` (u32): CHG[4] (channel group 4) - `chg5` (u32): CHG[5] (channel group 5) - `state_json` (str): DPPIC State (JSON) ### nRF5340 EGU (event generator unit) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-egu ID: nordic,nrf-egu Class: System & Infrastructure / Event Routing 16-channel software event generator: `TASKS_TRIGGER[n]` (via MMIO or DPPI subscribe) latches `EVENTS_TRIGGERED[n]`, publishes to the DPPI bus when configured, and pulses the IRQ for channels enabled in `INTEN`. #### Snapshot fields - `inten` (u32): INTEN (interrupt enable mask) - `events_triggered` (u32): EVENTS_TRIGGERED bitmask - `state_json` (str): EGU State Summary (JSON) ### nRF5340/nRF9160 FICR (factory information configuration registers) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-ficr ID: nordic,nrf-ficr Class: Memory & Storage / Config / OTP Memory Read-only factory information block pre-populated with plausible nRF5340 or nRF9160 values (`INFO.PART`, `INFO.DEVICEID`, RAM/flash sizes, code page geometry). Writes are silently ignored; unimplemented fields read as `0xFFFFFFFF`. #### Snapshot fields - `configid` (u32): INFO.CONFIGID - `deviceid0` (u32): INFO.DEVICEID[0] - `deviceid1` (u32): INFO.DEVICEID[1] - `part` (u32): INFO.PART - `variant` (u32): INFO.VARIANT - `package` (u32): INFO.PACKAGE - `ram_kb` (u32): INFO.RAM (KiB) - `flash_kb` (u32): INFO.FLASH (KiB) - `codepagesize` (u32): INFO.CODEPAGESIZE (bytes) - `codesize` (u32): INFO.CODESIZE (pages) - `devicetype` (u32): INFO.DEVICETYPE - `state_json` (str): FICR Summary (JSON) ### nRF5340 GPIO port URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-gpio ID: nordic,nrf-gpio Class: Digital I/O / GPIO 32-pin GPIO port model: `OUT`/`OUTSET`/`OUTCLR`, `DIR` variants, `IN`, `LATCH` (W1C), `DETECTMODE` and per-pin `PIN_CNF` with SENSE-based DETECT. Output-pin changes emit `GpioChange` effects. Input edges driven via `GpioSet`/`GpioClear`/`GpioToggle` inputs update `IN` and `LATCH` and are forwarded to GPIOTE through the wiring-time edge callback. ### nRF5340 GPIOTE (GPIO tasks and events) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-gpiote ID: nordic,nrf-gpiote Class: Digital I/O / GPIO 8-channel GPIOTE model. Event-mode channels latch `EVENTS_IN[n]` on matching pin edges reported by the GPIO ports and latch `EVENTS_PORT` when a SENSE-configured pin reaches its active level; task-mode channels drive (`TASKS_SET`/`TASKS_CLR`) or toggle (`TASKS_OUT`) pins on the injected GPIO port instances. Enabled events pulse the IRQ signal. ### nRF5340 I2S (inter-IC sound) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-i2s ID: nordic,nrf-i2s Class: Audio / I2S Functional I2S model with no real audio interface: `TASKS_START` fires `TXPTRUPD`/`RXPTRUPD` immediately (single-buffer completion model, IRQ when enabled). TX data is consumed via EasyDMA and discarded; the RX buffer is filled with silence (zeros). `TASKS_STOP` latches `STOPPED`. DPPI SUBSCRIBE/PUBLISH registers are modelled for `TASKS_START`, `TASKS_STOP` and all four events. #### Snapshot fields - `state_json` (str): I2S State (JSON summary) - `inten` (u32): INTEN (interrupt enable mask) - `enable` (u32): ENABLE - `ev_rxptrupd` (u32): EVENTS_RXPTRUPD latch - `ev_stopped` (u32): EVENTS_STOPPED latch - `ev_txptrupd` (u32): EVENTS_TXPTRUPD latch - `ev_framestart` (u32): EVENTS_FRAMESTART latch - `config_mode` (u32): CONFIG.MODE - `config_mckfreq` (u32): CONFIG.MCKFREQ - `config_ratio` (u32): CONFIG.RATIO - `config_swidth` (u32): CONFIG.SWIDTH - `config_channels` (u32): CONFIG.CHANNELS - `rxd_ptr` (u32): RXD.PTR - `txd_ptr` (u32): TXD.PTR - `rxtxd_maxcnt` (u32): RXTXD.MAXCNT ### nRF5340 IPC (inter-processor communication) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-ipc ID: nordic,nrf-ipc Class: System & Infrastructure / Mailbox / IPC 16-channel IPC mailbox model. `TASKS_SEND[n]` latches `EVENTS_RECEIVE` for every channel enabled in `SEND_CNF[n]` (loopback) and accumulates an outgoing channel mask that the compose orchestrator delivers to the peer core's IPC each quantum. Latched events with their `INTEN` bit set pulse the IRQ signal. ### nRF5340 KMU + NVMC (key management + flash controller) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-kmu-nvmc ID: nordic,nrf-kmu-nvmc Class: Security / Key Management Combined model of the shared 4 KiB KMU/NVMC block. KMU pushes and revokes the 128 UICR-backed key slots (zeroizing on revoke, as per the product specification); NVMC provides the flash write-enable gate, page erase, and ERASEALL. #### Events emitted - `nrf.kmu.slot_pushed`: A KMU key slot was pushed to its destination address (`TASKS_PUSH`). - `nrf.kmu.slot_revoked`: A KMU key slot was revoked: key words zeroized, STATE cleared. #### Commands - `push_slot`: Trigger a host-side `TASKS_PUSH` of the selected slot. - `revoke_slot`: Revoke a slot: clear its STATE permission bit and zeroize the key words. - `write_slot`: Write the four key words of a slot directly into UICR (host-side provisioning shortcut). #### Snapshot fields - `state_json` (str): KMU Slot State (JSON) - `kmu_info` (str): KMU FSM Info (JSON) ### nRF5340 MUTEX (mutual exclusion) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-mutex ID: nordic,nrf-mutex Class: System & Infrastructure / Hardware Semaphore Hardware spinlock model with 16 `MUTEX[n]` registers implementing atomic test-and-set: a read returning 0 claims the mutex, a read returning 1 means it is already held, and writing 0 releases it, per nRF5340 PS sec 7.19. #### Commands - `release`: Forcibly release a held mutex (fault injection). `index` is the mutex number 0-15. #### Snapshot fields - `claimed_mask` (u32): Claimed mask (bitmask, bit n = mutex n held) - `state_json` (str): Mutex State Summary (JSON) ### nRF5340 NFCT (NFC tag interface) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-nfct ID: nordic,nrf-nfct Class: Wireless / NFC Behavioral NFCT model: state-machine tasks latch the matching events and pulse the IRQ when enabled. `TASKS_STARTTX` emits a `nrf.nfct.tx_frame` effect carrying TXD configuration. No real RF field; `FIELDPRESENT`, `NFCTAGSTATE`, and `SLEEPSTATE` always read 0. All config registers (PACKETPTR, MAXLEN, NFC-ID, SENSRES, ...) are plain R/W storage. #### Events emitted - `nrf.nfct.tx_frame`: NFCT TASKS_STARTTX was triggered: a TX frame configuration was captured. #### Snapshot fields - `inten` (u32): INTEN (interrupt enable mask) - `shorts` (u32): SHORTS - `packetptr` (u32): PACKETPTR - `txd_amount` (u32): TXD.AMOUNT - `rxd_amount` (u32): RXD.AMOUNT - `errorstatus` (u32): ERRORSTATUS - `state_json` (str): NFCT State Summary (JSON) ### nRF5340 OSCILLATORS URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-oscillators ID: nordic,nrf-oscillators Class: System & Infrastructure / Clock Control Nordic nRF5340 OSCILLATORS peripheral (sec 4.12): three retained configuration registers - `XOSC32MCAPS` (HFXO internal capacitor trim), `XOSC32KI.BYPASS` (LFXO external-clock bypass), and `XOSC32KI.INTCAP` (LFXO internal load capacitor selection). No TASKS, EVENTS, or IRQ; all writes are stored as-is. #### Snapshot fields - `state_json` (str): OSCILLATORS State (JSON) - `xosc32mcaps` (u32): XOSC32MCAPS - `xosc32ki_bypass` (u32): XOSC32KI.BYPASS - `xosc32ki_intcap` (u32): XOSC32KI.INTCAP ### nRF5340 PDM (pulse density modulation microphone) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-pdm ID: nordic,nrf-pdm Class: Audio / Digital Microphone (PDM) Functional PDM model with no real microphone: `TASKS_START` latches `STARTED`, fills the EasyDMA sample buffer with silence (zeros), and latches `END` immediately; `TASKS_STOP` latches `STOPPED` (IRQ when enabled). Supports DPPI SUBSCRIBE/PUBLISH. #### Events emitted - `nrf.pdm.end`: Fires when the PDM EasyDMA has written the last sample to RAM (EVENTS_END latched). - `nrf.pdm.started`: Fires when the PDM peripheral starts a transfer (EVENTS_STARTED latched). - `nrf.pdm.stopped`: Fires when the PDM peripheral stops (EVENTS_STOPPED latched). #### Snapshot fields - `inten` (u32): INTEN (interrupt enable mask) - `ev_started` (u32): EVENTS_STARTED latch - `ev_stopped` (u32): EVENTS_STOPPED latch - `ev_end` (u32): EVENTS_END latch - `enable` (u32): ENABLE register - `sample_ptr` (u32): SAMPLE.PTR (EasyDMA destination) - `sample_maxcnt` (u32): SAMPLE.MAXCNT (number of samples) - `state_json` (str): PDM State Summary (JSON) ### nRF5340 PWM (pulse width modulation with EasyDMA) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-pwm ID: nordic,nrf-pwm Class: Digital I/O / PWM Functional PWM model with no electrical output. `TASKS_SEQSTART[n]` consumes the sequence descriptor via an EasyDMA read and latches `SEQSTARTED`, `SEQEND`, `PWMPERIODEND`, and `LOOPSDONE` immediately (single-loop completion, IRQ when enabled); `TASKS_STOP` latches `STOPPED`. DPPI subscribe/publish is supported. #### Snapshot fields - `inten` (u32): INTEN (interrupt enable mask) - `enable` (u32): ENABLE - `countertop` (u32): COUNTERTOP - `ev_stopped` (u32): EVENTS_STOPPED latch - `ev_seqstarted0` (u32): EVENTS_SEQSTARTED[0] latch - `ev_seqstarted1` (u32): EVENTS_SEQSTARTED[1] latch - `ev_seqend0` (u32): EVENTS_SEQEND[0] latch - `ev_seqend1` (u32): EVENTS_SEQEND[1] latch - `ev_pwmperiodend` (u32): EVENTS_PWMPERIODEND latch - `ev_loopsdone` (u32): EVENTS_LOOPSDONE latch - `state_json` (str): PWM State Summary (JSON) ### nRF5340 QDEC (quadrature decoder) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-qdec ID: nordic,nrf-qdec Class: Digital I/O / Input Functional QDEC model with no encoder connected: `TASKS_START` latches `SAMPLERDY` and `REPORTRDY` immediately, `TASKS_STOP` latches `STOPPED` (IRQ when enabled). `ACC`, `SAMPLE`, and the read-clear accumulator registers always read 0 (no movement). DPPI SUBSCRIBE/PUBLISH are fully wired. Two instances: QDEC0, QDEC1. #### Snapshot fields - `inten` (u32): INTEN (interrupt enable mask) - `enable` (u32): ENABLE register - `running` (bool): Decoder running - `ev_samplerdy` (u32): EVENTS_SAMPLERDY latch - `ev_reportrdy` (u32): EVENTS_REPORTRDY latch - `ev_stopped` (u32): EVENTS_STOPPED latch - `state_json` (str): QDEC State Summary (JSON) ### nRF5340 QSPI (quad SPI external flash interface) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-qspi ID: nordic,nrf-qspi Class: Connectivity / SPI Behavioral QSPI model with no external flash connected: every task (`ACTIVATE`, `DEACTIVATE`, erase tasks, `READ`, `WRITE`) latches `EVENTS_READY` immediately (IRQ when enabled). `TASKS_READ` fills the destination buffer with `0xFF` (erased flash) via EasyDMA; writes and erases are discarded. Custom events `nrf.qspi.transfer` and `nrf.qspi.erase` are emitted for host-side observation. #### Events emitted - `nrf.qspi.erase`: Emitted when a QSPI erase task completes (TASKS_ERASESTART, TASKS_ERASE128, TASKS_ERASE4, or TASKS_ERASE). Carries the flash pointer and the erase length in bytes. - `nrf.qspi.transfer`: Emitted when a QSPI read or write transfer completes (TASKS_READ or TASKS_WRITE). The `direction` field is `"read"` or `"write"`. #### Snapshot fields - `state_json` (str): QSPI State Summary (JSON) - `inten` (u32): INTEN - `ev_ready` (u32): EVENTS_READY - `enable` (u32): ENABLE - `read_cnt` (u32): READ.CNT - `write_cnt` (u32): WRITE.CNT - `erase_ptr` (u32): ERASE.PTR - `erase_len` (u32): ERASE.LEN ### nRF5340 RTC (real-time counter) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-rtc ID: nordic,nrf-rtc Class: Timing / Real-Time Counter 24-bit LFCLK (32.768 kHz) counter with prescaler, four compare channels, TICK/OVRFLW/COMPARE events, and DPPI subscribe/publish. Events latch unconditionally; `EVTEN` gates the DPPI publish path and `INTEN` gates the IRQ pulse, matching the product specification. #### Snapshot fields - `state_json` (str): RTC State Summary (JSON) - `inten` (u32): INTEN (interrupt enable mask) - `evten` (u32): EVTEN (event routing enable) - `counter` (u32): COUNTER (current 24-bit value) - `prescaler` (u32): PRESCALER (12-bit divider) - `running` (bool): Running (RTC is counting) - `ev_tick` (u32): EVENTS_TICK latch - `ev_ovrflw` (u32): EVENTS_OVRFLW latch - `ev_compare` (u32): EVENTS_COMPARE bitmask (bits 0-3) ### nRF5340 SAADC (successive-approximation ADC with EasyDMA) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-saadc ID: nordic,nrf-saadc Class: Analog / ADC Functional SAADC model with no analog front-end. `TASKS_SAMPLE` fills the EasyDMA result buffer with zero samples (0 V input) and latches `RESULTDONE`, `DONE`, and `END` immediately; `TASKS_START` latches `STARTED` and `TASKS_CALIBRATEOFFSET` completes instantly with `CALIBRATEDONE` (IRQ when enabled). DPPI subscribe/publish is supported. External samples can be injected via `nrf.saadc.inject_sample` Custom inputs. #### Events emitted - `nrf.saadc.calibratedone`: SAADC offset calibration completed (EVENTS_CALIBRATEDONE fired). - `nrf.saadc.done`: One SAADC sampling step completed (EVENTS_DONE fired). - `nrf.saadc.end`: EasyDMA result buffer is full; all requested samples written (EVENTS_END fired). - `nrf.saadc.resultdone`: SAADC result data is available in the EasyDMA buffer (EVENTS_RESULTDONE fired). - `nrf.saadc.started`: SAADC peripheral has started a sampling run (EVENTS_STARTED fired). - `nrf.saadc.stopped`: SAADC peripheral has stopped (EVENTS_STOPPED fired). #### Events accepted - `nrf.saadc.inject_sample`: Inject an ADC sample value for a given channel index. The value will be written by the next TASKS_SAMPLE. #### Snapshot fields - `state_json` (str): SAADC State (JSON) - `inten` (u32): INTEN - `ev_started` (u32): EVENTS_STARTED - `ev_end` (u32): EVENTS_END - `ev_done` (u32): EVENTS_DONE - `ev_resultdone` (u32): EVENTS_RESULTDONE - `ev_calibratedone` (u32): EVENTS_CALIBRATEDONE - `ev_stopped` (u32): EVENTS_STOPPED - `enable` (u32): ENABLE - `running` (bool): Running - `shorts` (u32): SHORTS - `result_maxcnt` (u32): RESULT.MAXCNT - `result_amount` (u32): RESULT.AMOUNT ### nRF5340 SPIM (SPI master with EasyDMA) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-spim ID: nordic,nrf-spim Class: Connectivity / SPI Behavioral SPIM model with no real SPI bus: `TASKS_START` fires `STARTED` immediately, queues the TXD/RXD EasyDMA transfers (RX is filled with the `ORC` idle byte), and latches `ENDTX`, `ENDRX`, and `END` in the same write cycle (IRQ when enabled). DPPI subscribe/publish is supported; the `END_START` short does not auto-restart in emulation. A `nrf.spim.transfer` custom event is emitted on every transfer so the host can observe SPI traffic. #### Events emitted - `nrf.spim.transfer`: Fires when a SPIM EasyDMA transfer completes (END event). Carries the TX pointer, TX byte count, RX pointer, and RX byte count. #### Snapshot fields - `inten` (u32): INTEN (interrupt enable mask) - `ev_stopped` (u32): EVENTS_STOPPED latch - `ev_endrx` (u32): EVENTS_ENDRX latch - `ev_end` (u32): EVENTS_END latch - `ev_endtx` (u32): EVENTS_ENDTX latch - `ev_started` (u32): EVENTS_STARTED latch - `enable` (u32): ENABLE register - `frequency` (u32): FREQUENCY register - `config` (u32): CONFIG register (CPHA/CPOL/ORDER) - `orc` (u32): ORC (over-run character) - `txd_ptr` (u32): TXD.PTR - `txd_maxcnt` (u32): TXD.MAXCNT - `txd_amount` (u32): TXD.AMOUNT - `rxd_ptr` (u32): RXD.PTR - `rxd_maxcnt` (u32): RXD.MAXCNT - `rxd_amount` (u32): RXD.AMOUNT - `state_json` (str): SPIM State Summary (JSON) ### nRF5340 SPU (system protection unit) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-spu ID: nordic,nrf-spu Class: Security / Access Control / TrustZone Secure/Non-Secure partitioning model: stores `FLASHREGION`, `RAMREGION`, `PERIPHID`, NSC and GPIOPORT permission registers consulted by the bus IDAU/security controller and the NVMC (`FLASHREGION[n].PERM.LOCK` gates write/erase). Access violations injected by the bus latch `EVENTS_RAMACCERR`/`FLASHACCERR`/`PERIPHACCERR` and pulse the IRQ when enabled. #### Commands - `inject_event`: Inject an access-error event latch by name for fault-injection testing. ### nRF5340 TIMER URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-timer ID: nordic,nrf-timer Class: Timing / Timer Functional TIMER/counter model: 16 MHz base clock with prescaler, `BITMODE` widths, eight CC channels with capture and compare, `SHORTS` (COMPARE-CLEAR/STOP), `ONESHOTEN`, and DPPI subscribe/publish. COMPARE events latch unconditionally and pulse the IRQ when enabled in `INTEN`. #### Snapshot fields - `state_json` (str): TIMER State Summary (JSON) - `inten` (u32): INTEN (interrupt enable mask) - `running` (bool): Running (timer is counting) - `mode` (u32): MODE (0=Timer, 1=Counter, 2=LowPowerCounter) - `bitmode` (u32): BITMODE (0=16-bit, 1=8-bit, 2=24-bit, 3=32-bit) - `prescaler` (u32): PRESCALER (0-9; fTIMER = 16 MHz / 2^PRESCALER) - `counter` (u32): COUNTER (current masked value) - `shorts` (u32): SHORTS bitmask - `events_compare` (u32): EVENTS_COMPARE latch bitmask (bit i = channel i latched) ### nRF5340 UARTE (UART with EasyDMA) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-uarte ID: nordic,nrf-uarte Class: Connectivity / UART / Serial UART with EasyDMA model. `TASKS_STARTTX` queues an EasyDMA read of `TXD.PTR`/`TXD.MAXCNT` from guest SRAM (console bytes are routed by the bus); the bus reports completion back, latching `EVENTS_ENDTX`. Received bytes pass through a 4-byte hardware FIFO into the active `RXD` buffer via DMA writes, with ENDRX/RXTO and SHORTS handling and level-sensitive IRQ re-evaluation on every event change. #### Events accepted - `vemu.easydma.tx_complete`: Bus-internal completion: an EasyDMA TX transfer finished. #### Commands - `rx`: Inject receive bytes into the UARTE RX FIFO from a hex string (e.g. "68656c6c6f" or "68 65 6c"; spaces and a 0x prefix are ignored). The bytes flow through the EasyDMA RX path exactly like real line input, so an attached guest reads them via RXD. #### Snapshot fields - `state_json` (str): UARTE State Summary (JSON) - `inten` (u32): INTEN (interrupt enable mask) - `enable` (u32): ENABLE (0=disabled, 8=enabled) - `rx_active` (bool): RX active (EasyDMA RX transfer in progress) - `errorsrc` (u32): ERRORSRC (error source bitmask) - `baudrate` (u32): BAUDRATE register value - `shorts` (u32): SHORTS bitmask - `rxd_amount` (u32): RXD.AMOUNT (bytes received into current DMA buffer) - `txd_amount` (u32): TXD.AMOUNT (bytes sent in last DMA transfer) ### nRF5340 UICR (user information configuration registers) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-uicr ID: nordic,nrf-uicr Class: Memory & Storage / Config / OTP Memory Non-volatile UICR flash model backed by a shared (optionally file-backed) byte store. Enforces the real NVMC WEN write-enable gate: stores with `NVMC.CONFIG != WEN` are dropped. Survives reset like silicon; only an NVMC ERASEALL clears it. #### Events emitted - `nrf.uicr.write_dropped`: A UICR store was silently dropped because NVMC was not in WEN (write-enable) mode - mirrors real nRF5340 flash-controller behaviour. - `nrf.uicr.written`: A UICR write was committed to the non-volatile store (e.g. BL2 ROTPK provisioning into the OTP/CUSTOMER region). #### Commands - `load_image`: Overwrite the UICR region with a raw image supplied as a hex string (host-side provisioning shortcut, e.g. the web UI 'Load UICR' button). Shorter images leave the tail unchanged. #### Snapshot fields - `approtect` (u32): APPROTECT - `secureapprotect` (u32): SECUREAPPROTECT - `state_json` (str): UICR Region Summary (JSON) ### nRF5340 USBD (USB 2.0 full-speed device controller) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-usbd ID: nordic,nrf-usbd Class: Connectivity / USB Behavioral USBD stub: writing ENABLE latches EVENTS_USBRESET (no VBUS - disconnected-bus semantics). All endpoint EasyDMA registers, EPINEN/EPOUTEN, EPSTALL, EPDATASTATUS, HALTED, and SETUP data registers are modelled as plain R/W storage. INTEN/INTENSET/INTENCLR gate IRQ assertion on every latched event. #### Snapshot fields - `state_json` (str): USBD State (JSON summary) - `inten` (u32): INTEN (interrupt enable mask) - `enable` (u32): ENABLE register - `ev_usbreset` (u32): EVENTS_USBRESET latch - `ev_started` (u32): EVENTS_STARTED latch - `ev_ep0datadone` (u32): EVENTS_EP0DATADONE latch - `ev_epdata` (u32): EVENTS_EPDATA latch - `ev_sof` (u32): EVENTS_SOF latch - `ev_usbevent` (u32): EVENTS_USBEVENT latch - `epinen` (u32): EPINEN (endpoint IN enable bitmask) - `epouten` (u32): EPOUTEN (endpoint OUT enable bitmask) - `epstatus` (u32): EPSTATUS - `epdatastatus` (u32): EPDATASTATUS - `eventcause` (u32): EVENTCAUSE - `shorts` (u32): SHORTS bitmask - `usbaddr` (u32): USBADDR (assigned USB address) ### nRF5340 USBREG URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-usbreg ID: nordic,nrf-usbreg Class: Connectivity / USB Nordic Semiconductor USBREG peripheral (nRF5340). Models VBUS detection events (USBDETECTED, USBREMOVED) and USB regulator ready event (USBPWRRDY). USBREGSTATUS reflects the current VBUS and regulator state. Events latch unconditionally; INTEN gates the IRQ assertion only. No real VBUS modeled at reset: all events are 0 and USBREGSTATUS reads 0 (no VBUS, output not ready). #### Snapshot fields - `inten` (u32): INTEN (interrupt enable mask) - `usbregstatus` (u32): USBREGSTATUS (VBUSDETECT | OUTPUTRDY) - `ev_detected` (u32): EVENTS_USBDETECTED latch - `ev_removed` (u32): EVENTS_USBREMOVED latch - `ev_pwrrdy` (u32): EVENTS_USBPWRRDY latch - `state_json` (str): USBREG State Summary (JSON) ### nRF5340 VMC (volatile memory controller) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-vmc ID: nordic,nrf-vmc Class: Memory & Storage / RAM Control RAM block power control model. `RAMBLOCK[n].POWER` registers (with POWERSET/POWERCLR set/clear semantics) are stored and read back, but RAM is always powered and retained in emulation - the programmed values have no behavioural effect on guest SRAM access. #### Snapshot fields - `power0` (u32): RAMBLOCK[0].POWER - `power1` (u32): RAMBLOCK[1].POWER - `power2` (u32): RAMBLOCK[2].POWER - `power3` (u32): RAMBLOCK[3].POWER - `state_json` (str): VMC State Summary (JSON) ### nRF5340 WDT (watchdog timer) URL: https://vemulator.com/docs/reference/peripherals/nordic-nrf-wdt ID: nordic,nrf-wdt Class: Timing / Watchdog Behavioral watchdog model: LFCLK-driven down-counter with `CRV` reload value, eight `RR[n]` reload slots gated by `RREN`, `CONFIG.STOPEN`-guarded stop requiring `TSEN` unlock, DPPI SUBSCRIBE/PUBLISH support, and INTEN/NMIEN gating. On timeout `EVENTS_TIMEOUT` latches and the IRQ/NMI signal is pulsed; on deliberate stop `EVENTS_STOPPED` latches. No system reset is performed by the model itself. #### Snapshot fields - `state_json` (str): WDT State Summary (JSON) - `inten` (u32): INTEN (interrupt enable mask) - `nmien` (u32): NMIEN (NMI enable mask) - `running` (bool): Running (WDT is counting) - `crv` (u32): CRV (counter reload value) - `rren` (u32): RREN (reload register enable bitmask) - `config` (u32): CONFIG (SLEEP/HALT/STOPEN) - `reqstatus` (u32): REQSTATUS (pending reload requests) - `ev_timeout` (u32): EVENTS_TIMEOUT latch - `ev_stopped` (u32): EVENTS_STOPPED latch --- ## React API URL: https://vemulator.com/docs/react Package: @swedishembedded/vemu-react v0.8.0 ### GenericInspector URL: https://vemulator.com/docs/react/genericinspector Kind: component Default inspector view used for any peripheral that has no domain-specific view registered in `PERIPHERAL_VIEWS`. Renders the raw snapshot field map, pretty-printing any JSON-string fields. This is what makes "implement the inspector, see it in the UI" work before a custom view exists. Accepts the uniform PeripheralViewProps shape, so it can stand in for any registered view. Signature: ```tsx function GenericInspector(props: PeripheralViewProps): JSX.Element ``` Props: - `name` `string`: Peripheral name as reported by the machine (e.g. "kmu", "uicr"). - `events` `PeripheralEvent[]`: All peripheral events seen so far; the view filters for the ones it cares about. - `refreshKey` `number`: Monotonic counter that increments whenever new events arrive. - `getSnapshot` `() => PeripheralSnapshot | null`: Pull the current snapshot for this peripheral (null if unavailable). - `sendCommand` `(cmd: { name: string; params: Record }) => void`: Send a command to this peripheral's inspector. - `sendUartRx` (optional) `(target: string, bytes: number[], timing?: TimingSpec) => void`: Deliver UART RX bytes to this peripheral, optionally at a precise virtual time (`timing`). Absent `timing` is immediate. Undefined on hosts/boards without timed-delivery support (feature-detect before use). - `clockHz` (optional) `number`: Guest clock in Hz (cycles/sec), or 0 when unknown. For timing conversions. Examples: ```tsx getPeripheralSnapshot("uicr")} sendCommand={(cmd) => sendPeripheralCommand("uicr", cmd)} /> ``` ### PERIPHERAL_LABELS URL: https://vemulator.com/docs/react/peripheral-labels Kind: constant Optional human-friendly labels for the selector. Unknown peripherals fall back to an upper-cased name. Signature: ```tsx const PERIPHERAL_LABELS: Record ``` ### PERIPHERAL_VIEWS URL: https://vemulator.com/docs/react/peripheral-views Kind: constant Registry mapping a peripheral name (as reported by the machine) to a domain-specific inspector view. A peripheral without an entry here still appears in the list and is rendered with the generic fallback view. To add a richer view for a peripheral: write a component that accepts `PeripheralViewProps`, then add one line here. Signature: ```tsx const PERIPHERAL_VIEWS: Record> ``` ### peripheralLabel URL: https://vemulator.com/docs/react/peripherallabel Kind: function Display label for a peripheral name: registered label or upper-cased name. Signature: ```tsx function peripheralLabel(name: string): string ``` Returns: `string` ### PeripheralPanel URL: https://vemulator.com/docs/react/peripheralpanel Kind: component Generic peripheral inspector panel. A permanent section (like Display and Console): it always renders, lists whatever inspectable peripherals the live machine exposes, and shows a domain-specific view when registered, otherwise the generic fallback. Empty/error states keep it visible and diagnosable. Signature: ```tsx function PeripheralPanel(props: PeripheralPanelProps): JSX.Element ``` Props: - `peripherals` `string[]`: Names of inspectable peripherals reported by the running machine. - `events` `PeripheralEvent[]`: All peripheral events seen so far (passed through to the selected view). - `error` (optional) `string | null`: Build/exposure error to surface (instead of a silent empty panel). - `refreshKey` `number`: Monotonic counter that bumps when new events arrive. - `getSnapshot` `(name: string) => PeripheralSnapshot | null`: Pull the current snapshot for a peripheral by name (null if unavailable). - `sendCommand` `(name: string, cmd: { name: string; params: Record }) => void`: Send a command to a peripheral's inspector. - `sendUartRx` (optional) `(target: string, bytes: number[], timing?: import("./timing").TimingSpec) => void`: Deliver UART RX bytes to a named UART, optionally at a precise virtual time. - `clockHz` (optional) `number`: Guest clock in Hz (cycles/sec); 0 when unknown. Examples: ```tsx const { peripheralList, peripheralEvents, peripheralError, snapshotVersion, getPeripheralSnapshot, sendPeripheralCommand } = useVemu(); ``` ### PeripheralSelector URL: https://vemulator.com/docs/react/peripheralselector Kind: component Vertical list of inspectable peripherals (the left pane of PeripheralPanel). Renders human-friendly labels via `peripheralLabel` and highlights the current selection. Signature: ```tsx function PeripheralSelector(props: PeripheralSelectorProps): JSX.Element ``` Props: - `peripherals` `string[]`: Names of the peripherals to list, in display order. - `selected` `string | null`: Currently selected peripheral name, or null when nothing is selected. - `onSelect` `(name: string) => void`: Called with the peripheral name when the user clicks an entry. Examples: ```tsx const [selected, setSelected] = useState(null); ``` ### PeripheralViewProps URL: https://vemulator.com/docs/react/peripheralviewprops Kind: interface Uniform props every peripheral inspector view receives. Domain-specific views (KMU, UICR) and the generic fallback all implement this interface, so adding a new view is: write a component matching these props + register it in peripheralViews.tsx. Signature: ```tsx interface PeripheralViewProps ``` Fields: - `name` `string`: Peripheral name as reported by the machine (e.g. "kmu", "uicr"). - `events` `PeripheralEvent[]`: All peripheral events seen so far; the view filters for the ones it cares about. - `refreshKey` `number`: Monotonic counter that increments whenever new events arrive. - `getSnapshot` `() => PeripheralSnapshot | null`: Pull the current snapshot for this peripheral (null if unavailable). - `sendCommand` `(cmd: { name: string; params: Record }) => void`: Send a command to this peripheral's inspector. - `sendUartRx` `(target: string, bytes: number[], timing?: TimingSpec) => void`: Deliver UART RX bytes to this peripheral, optionally at a precise virtual time (`timing`). Absent `timing` is immediate. Undefined on hosts/boards without timed-delivery support (feature-detect before use). - `clockHz` `number`: Guest clock in Hz (cycles/sec), or 0 when unknown. For timing conversions. ### useVemu URL: https://vemulator.com/docs/react/usevemu Kind: hook Core VEMU hook. Manages wasm init, board selection, firmware loading, the RAF render loop, UART I/O, and peripheral inspector state. Signature: ```tsx function useVemu(options?: { loadModule?: () => Promise }): UseVemuResult ``` Returns: `UseVemuResult` Examples: ```tsx function Emu() { const { boards, selectedBoard, setSelectedBoard, loadProgram, hasVideo, setDraw, setUartSink, sendUart } = useVemu(); return ( <> ); } ``` ### UseVemuResult URL: https://vemulator.com/docs/react/usevemuresult Kind: interface Everything useVemu returns: emulator status, board selection, program/run controls, video + UART wiring callbacks, and the peripheral inspector surface. Signature: ```tsx interface UseVemuResult ``` Fields: - `status` `VemuStatus`: Current emulator lifecycle state. - `boards` `BoardInfo[]`: Boards compiled into the loaded runtime. - `selectedBoard` `string`: Id of the currently selected board (empty string until boards are listed). - `setSelectedBoard` `Dispatch>`: Select a board by id; instantiates a fresh (non-running) machine for it. - `selectedHasDisplay` `boolean`: Static display capability of the selected board (false when unknown). - `hasVideo` `boolean`: True once the running machine has produced at least one video frame. - `ips` `string`: Human-readable simulated clock speed (e.g. "4.2 MHz"); empty while not running. - `loadProgram` `(data: Uint8Array, kind: ProgramKind, boardOverride?: string) => void`: Load a program (ROM/ELF/binary) and start running, optionally switching board first. - `loadLinux` `(kernel: Uint8Array, initrd: Uint8Array, boardOverride?: string) => void`: Boot a Linux kernel + initramfs (arm64) and start running, optionally switching board first. Uses the wasm `newLinux` factory: the board builder generates the DTB and bootargs, so only the raw kernel `Image` and `initrd` bytes are passed. UART wiring is identical to loadProgram. - `loadRiscvLinux` `( firmware: Uint8Array, image: Uint8Array, initrd: Uint8Array, boardOverride?: string, ) => void`: Build + start a RISC-V Linux machine from OpenSBI firmware + kernel Image + initramfs (the `vemu_riscv64_virt` board), optionally switching board. - `loadUicr` `(data: Uint8Array) => boolean`: Load a raw UICR image (uicr.bin) into the running machine's UICR region. Returns false when no machine is built or the board has no UICR. Not persisted - re-apply after loading a new program image. - `loadWithFiles` `( files: Array<{ id: string; bytes: Uint8Array; addr?: number; kind?: ProgramKind }>, boardOverride?: string, cmdline?:...`: Build + start a machine from a board-declared set of file slots (the generic path behind every board's loader UI). Each entry pairs a slot id with its bytes plus an optional load-address override and program `kind`. Supersedes loadProgram/loadLinux/loadRiscvLinux for the slot-based UI. - `stop` `() => void`: Pause the run loop (status returns to "ready"). - `reset` `() => void`: Reset the machine and restart with the last loaded program. - `eraseAll` `() => void`: Discard the current machine and rebuild the selected board with empty flash. - `setDraw` `(cb: (f: VemuFrame) => void) => void`: Register the callback that renders video frames (wired up by `VemuCanvas`). - `setUartSink` `(cb: (b: Uint8Array) => void) => void`: Register the sink for UART output bytes (wired up by `VemuTerminal`). - `setTerminalClear` `(cb: () => void) => void`: Register a callback that clears the terminal UI (wired up by `VemuTerminal`); invoked on `reset()` / `eraseAll()` so a reboot starts from a clean screen. - `sendUart` `(bytes: Uint8Array) => void`: Send UART input bytes to the running machine. - `peripheralList` `string[]`: Names of inspectable peripherals exposed by the current machine. - `peripheralEvents` `PeripheralEvent[]`: Rolling buffer (last 100) of peripheral events emitted by the machine. - `peripheralError` `string | null`: Build/exposure error to surface in the peripheral panel, or null. - `snapshotVersion` `number`: Monotonic counter that bumps when inspector snapshots should be re-pulled. - `getPeripheralSnapshot` `(name: string) => PeripheralSnapshot | null`: Pull the current snapshot for a peripheral by name (null if unavailable). - `sendPeripheralCommand` `(name: string, cmd: { name: string; params: Record }) => void`: Send a command to a peripheral's inspector. - `sendUartRx` `(target: string, bytes: number[], timing?: TimingSpec) => void`: Deliver UART RX bytes to a named UART, optionally at a precise virtual time (deterministic timed delivery). Absent `timing` is immediate. - `clockHz` `number`: Guest clock in Hz (cycles/sec), or 0 when unknown. ### VemuCanvas URL: https://vemulator.com/docs/react/vemucanvas Kind: component Pixel-perfect display surface for the emulator's video output. Registers a draw callback that blits each RGBA frame into a 2D canvas, resizing the backing store whenever the frame dimensions change, and shows a "NO SIGNAL" overlay until the first frame arrives. Signature: ```tsx function VemuCanvas(props: VemuCanvasProps): JSX.Element ``` Props: - `hasVideo` `boolean`: True once the machine has produced a video frame; gates the "NO SIGNAL" overlay. - `setDraw` `(cb: (f: VemuFrame) => void) => void`: Registers the frame-draw callback with the hook (`useVemu().setDraw`). Examples: ```tsx const { hasVideo, setDraw } = useVemu(); ``` ### VemuLoader URL: https://vemulator.com/docs/react/vemuloader Kind: interface Optional override for testing / stub mode. Returned by the `loadModule` factory passed to useVemu to replace the default wasm loading. Signature: ```tsx interface VemuLoader ``` Fields: - `EmulatorClass` `VemuModuleStatic`: Constructor used to build emulator instances (the wasm `Emulator` class or a stub). - `listBoards` `() => string`: Returns the available boards as a JSON-encoded `BoardInfo[]` string. ### VemuTerminal URL: https://vemulator.com/docs/react/vemuterminal Kind: component xterm.js console bound to the emulator's UART. Machine output is written to the terminal; keystrokes are passed through raw (picocom-style) as UART input. Auto-fits to its container and re-fits on resize. Signature: ```tsx function VemuTerminal(props: VemuTerminalProps): JSX.Element ``` Props: - `setUartSink` `(cb: (b: Uint8Array) => void) => void`: Registers the UART output sink with the hook (`useVemu().setUartSink`). - `sendUart` `(bytes: Uint8Array) => void`: Sends keystrokes to the machine as UART input bytes (`useVemu().sendUart`). - `setTerminalClear` (optional) `(cb: () => void) => void`: Registers a terminal-clear callback with the hook (`useVemu().setTerminalClear`); invoked on machine reset / erase. Examples: ```tsx const { setUartSink, sendUart } = useVemu(); ``` ### VemuTitleBar URL: https://vemulator.com/docs/react/vemutitlebar Kind: function Branded title bar for the VEMU emulator window. Renders the `vemu.` wordmark as a link back to https://vemulator.com - every embedding carries attribution. Signature: ```tsx function VemuTitleBar(): import("react").JSX.Element ``` Returns: `import("react").JSX.Element` Examples: ```tsx ```