stm32f4-emu 1.1.1 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -14
- package/index.d.ts +7 -0
- package/index.mjs +1 -0
- package/mcp/server.mjs +23 -0
- package/package.json +7 -3
- package/site/app.js +607 -25
- package/site/boards.js +337 -0
- package/site/components.js +37 -0
- package/site/console.html +1098 -0
- package/site/emulator.d.ts +9 -0
- package/site/emulator.js +795 -75
- package/site/firmware.js +184 -8
- package/site/index.html +142 -696
- package/site/netsim.js +564 -6
- package/site/remote-emu.js +30 -1
- package/site/stm32f4.js +44 -0
- package/site/vendor/stm32_periph_wasm.d.ts +829 -0
- package/site/vendor/stm32_periph_wasm.js +1438 -56
- package/site/vendor/stm32_periph_wasm_bg.wasm +0 -0
- package/site/vendor/stm32_periph_wasm_bg.wasm.d.ts +124 -0
- package/site/vendor/stm32f401.svd +24876 -0
- package/site/vendor/stm32f411.svd +24914 -0
- package/site/vendor/stm32f429.svd +62106 -0
- package/site/ws-bridge.mjs +35 -0
- package/tools/make_firmware.mjs +182 -1
package/README.md
CHANGED
|
@@ -6,6 +6,14 @@
|
|
|
6
6
|
[](https://github.com/danish9661/stm32F4-emulator/actions/workflows/ci.yml)
|
|
7
7
|
[](https://github.com/danish9661/stm32F4-emulator/actions/workflows/pages.yml)
|
|
8
8
|
|
|
9
|
+
> **Status: emulation complete.** All 41 peripheral modules are Detailed
|
|
10
|
+
> (0 Partial), all five board maps verify green (37/37/72/73/59 presets),
|
|
11
|
+
> and the Ethernet descriptor layer (EDFE, TCH/TER + RCH/RER walks, RDES4,
|
|
12
|
+
> backoff probe) plus the Wireshark-validated pcap capture (`a1b2c3d4`,
|
|
13
|
+
> tcpdump-verified DHCP→TCP→HTTP) are in. What remains is product work,
|
|
14
|
+
> not emulation: npm publish, https gateway endpoint, VS Code packaging
|
|
15
|
+
> (see [docs/progress-and-future.md](docs/progress-and-future.md)).
|
|
16
|
+
|
|
9
17
|
An STM32F407 microcontroller emulator that runs real Cortex-M4 firmware. It
|
|
10
18
|
combines a **Rust CPU core** (a WASM-native Thumb-2 interpreter with exact
|
|
11
19
|
Cortex-M exception entry/return, including the VFPv4-SP FPU) with a
|
|
@@ -15,7 +23,12 @@ browser tab**, with no SDL, no native deps, no hardware.
|
|
|
15
23
|
|
|
16
24
|
It ships three real networking firmwares (`eth_http`, `eth_dhcp`, `eth_test`)
|
|
17
25
|
that do DHCP + TCP + HTTP against a simulated (or a real gVisor-backed)
|
|
18
|
-
network, a
|
|
26
|
+
network, a 66-marker Ethernet feature matrix (`eth_feat_test`: PHY/MDIO,
|
|
27
|
+
checksum offload, hash/perfect/SA/DA filtering, VLAN, PTP, WOL, wire
|
|
28
|
+
pacing, deferral/collisions, pause frames, MMC, RBUS — see
|
|
29
|
+
[NETWORKING.md](NETWORKING.md)) plus real LwIP 2.2.1 (`lwip_demo`) and
|
|
30
|
+
MII/RMII pin mirrors (`eth_pins_test`), a browser demo, and a publishable
|
|
31
|
+
npm package.
|
|
19
32
|
|
|
20
33
|
## Live demo
|
|
21
34
|
|
|
@@ -24,7 +37,7 @@ The browser demo deploys to GitHub Pages:
|
|
|
24
37
|
**https://danish9661.github.io/stm32F4-emulator/**
|
|
25
38
|
|
|
26
39
|
A single console page that starts **idle** — nothing runs until you pick a
|
|
27
|
-
firmware: a preset dropdown with
|
|
40
|
+
firmware: a preset dropdown with 223 bundled binaries (network demos, a
|
|
28
41
|
bare-metal LED blinker, peripheral/crypto/UART/SPI test binaries), custom
|
|
29
42
|
firmware upload (`.bin`, Intel `.hex`, `.elf` — with loadable RAM segments
|
|
30
43
|
and symbols — plus `.map` for a symbol table), Run/Stop/Reset, a **gateway
|
|
@@ -35,7 +48,7 @@ characters excluded per HTML spec, see AGENTS.md §11), GPIO pin readout
|
|
|
35
48
|
for banks A–E, and key peripheral registers. Interrupt-driven firmware
|
|
36
49
|
(`rx_interrupt_test`, `rx_crypto_test`) gets inline guest-IRQ delivery;
|
|
37
50
|
polling firmware (the ETH demos) never uses it. For automation, a
|
|
38
|
-
preset can auto-boot via the URL:
|
|
51
|
+
preset can auto-boot via the URL: `console.html?fw=eth_http`, `console.html?fw=blinky`, `console.html?fw=crypto_test`, …
|
|
39
52
|
|
|
40
53
|
## DOOM (in the browser)
|
|
41
54
|
|
|
@@ -60,7 +73,7 @@ reloads.
|
|
|
60
73
|
- Controls: move W/S/A/D + arrows · strafe Shift · fire Ctrl · use
|
|
61
74
|
Space · menu Enter/Esc · save F2/F6 · load F3/F9 · F1/F10/F11/F12.
|
|
62
75
|
- Boot → menu → gameplay verified end-to-end by
|
|
63
|
-
`node site/
|
|
76
|
+
`node site/test_doom_wasm.mjs` (boot markers, menu navigation to E1M1,
|
|
64
77
|
palette + framebuffer, W-move + turn, audio, **save → `SAVE ok slot=0`
|
|
65
78
|
→ load handshake**).
|
|
66
79
|
- `site/doom1.wad` is the 4.2 MB shareware WAD; the firmware never reads
|
|
@@ -78,7 +91,7 @@ npm test # == node site/test_flow.mjs
|
|
|
78
91
|
|
|
79
92
|
# websocket bridge: headless Node serves the emulator, browser is a thin UI
|
|
80
93
|
npm run bridge -- blinky/blinky.bin --port 8234
|
|
81
|
-
# then open http://127.0.0.1:8123?bridge=ws://127.0.0.1:8234
|
|
94
|
+
# then open http://127.0.0.1:8123/console.html?bridge=ws://127.0.0.1:8234
|
|
82
95
|
|
|
83
96
|
# gateway-backed run: firmware talks to a REAL network stack (gVisor)
|
|
84
97
|
cd stm32-periph-wasm/pkg
|
|
@@ -145,14 +158,14 @@ is a thin UI. Zero impact on the existing local WASM path:
|
|
|
145
158
|
node site/ws-bridge.mjs eth_http/eth_http.bin --port 8234
|
|
146
159
|
|
|
147
160
|
# 2. Open the browser console with the bridge URL param
|
|
148
|
-
open "http://127.0.0.1:8123
|
|
161
|
+
open "http://127.0.0.1:8123/console.html?bridge=ws://127.0.0.1:8234"
|
|
149
162
|
```
|
|
150
163
|
|
|
151
164
|
The `RemoteEmu` adapter (`site/remote-emu.js`) is a drop-in replacement
|
|
152
165
|
for the local `emu` object — same `step()`/`drainUart()`/`read32()` API,
|
|
153
166
|
all proxied over binary WebSocket. Device stubs (OLED/TFT/etc.) run in
|
|
154
167
|
Node and are not visible to browser JS. Without `?fw=`, the page boots
|
|
155
|
-
whatever firmware the bridge was started with; with
|
|
168
|
+
whatever firmware the bridge was started with; with `console.html?fw=blinky&bridge=ws://…`,
|
|
156
169
|
the browser sends the firmware image over the bridge.
|
|
157
170
|
|
|
158
171
|
See AGENTS.md §20 for the full binary protocol reference.
|
|
@@ -164,8 +177,11 @@ See AGENTS.md §20 for the full binary protocol reference.
|
|
|
164
177
|
| `eth_http/` | DHCP + TCP client + HTTP GET + prints the response | `TCP connected`, `=== HTTP <len>b ===` |
|
|
165
178
|
| `eth_dhcp/` | Loops DHCP Discover/Offer/Request/Ack | `DHCP SUCCESS` |
|
|
166
179
|
| `eth_test/` | Raw ETH TX/RX self-test | `ETH Test: done` |
|
|
180
|
+
| `eth_feat_test/` | 66-marker Ethernet feature matrix (netsim, F407 + F429) | `FEAT Test: done` (all 66 markers, `FAIL`/`TIMEOUT` anti-markers) |
|
|
181
|
+
| `lwip_demo/` | Real LwIP 2.2.1 (DHCP→DNS→TCP echo→TCP server→UDP echo) | `LWIP DEMO DONE` |
|
|
182
|
+
| `eth_pins_test/` | MII/RMII pin-level mirrors (TX_EN/CRS_DV/RXD/COL/MDIO/MDC) | `PINS ALL PASS` |
|
|
167
183
|
| `blinky/` | **No ethernet** — LED blinker on GPIOA PA5 + UART tick counter | `tick N LED=ON/OFF` |
|
|
168
|
-
| `doom/` | **DOOM 1 shareware** (doomgeneric F407 port, browser page `site/doom.html`) | `node site/
|
|
184
|
+
| `doom/` | **DOOM 1 shareware** (doomgeneric F407 port, browser page `site/doom.html`) | `node site/test_doom_wasm.mjs` (boot + menu + gameplay + save/load) |
|
|
169
185
|
|
|
170
186
|
Plus 17 more test binaries (`crypto_test`, `hal_test`, `timer_test`,
|
|
171
187
|
`periph_test`, `echo_test`, `blink_serial`, `rx_interrupt_test`,
|
|
@@ -199,9 +215,12 @@ firmware .bin ──► Rust WASM CPU (Thumb-2 + NVIC/exceptions)
|
|
|
199
215
|
exception stacking — no native deps, no JIT, no hooks.
|
|
200
216
|
- **Peripherals**: a `wasm-bindgen` crate (`stm32-periph-wasm/`); registers
|
|
201
217
|
and bit fields come from the vendor SVD (`monox/stm32f407.svd`).
|
|
202
|
-
- **Ethernet**: TX is captured from the DMA descriptors
|
|
203
|
-
|
|
204
|
-
|
|
218
|
+
- **Ethernet**: TX is captured from the DMA descriptors (OWN/FS/LS poll
|
|
219
|
+
demand); RX frames are delivered head-only with FS+LS status, IPHCE/PCE
|
|
220
|
+
checksum status, and PTP snapshots for event messages. The full MAC
|
|
221
|
+
register map is cross-checked against CMSIS `stm32f407xx.h` (DMASR/
|
|
222
|
+
DMAIER/MACFFR/MACPMTCTL positions — see [NETWORKING.md](NETWORKING.md)
|
|
223
|
+
§6 for the audit). Optionally, a Go gateway
|
|
205
224
|
(`openhw-local-gateway/`) with a gVisor network stack makes the firmware
|
|
206
225
|
talk to a real network: `node cli.mjs <fw.bin> <inst> --gateway`.
|
|
207
226
|
- **Browser build** (`site/`): same modules as ESM; `site/emulator.js` is an
|
|
@@ -259,7 +278,10 @@ rebuild — delete it so the vendor assets stay tracked/committed.
|
|
|
259
278
|
|
|
260
279
|
## Testing
|
|
261
280
|
|
|
262
|
-
- `npm test` — flow test (`site/test_flow.mjs`) +
|
|
281
|
+
- `npm test` — flow test (`site/test_flow.mjs`) + Ethernet mock harnesses
|
|
282
|
+
(`site/test_eth_mock_model.mjs`: 18 checks, fake bindings + real driver;
|
|
283
|
+
`site/test_eth_mock_consumer.mjs`: 44 checks, fake firmware + real model)
|
|
284
|
+
+ blinky test
|
|
263
285
|
(`site/test_blinky.mjs`) + interrupt-UART test (`site/test_rx_interrupt.mjs`)
|
|
264
286
|
+ component-API tests (`site/test_component_{led,button,pwm,i2cregfile}.mjs`,
|
|
265
287
|
each against real firmware — LED/blinky, Button/exti_test, Pwm/buzzer_test,
|
|
@@ -269,7 +291,7 @@ rebuild — delete it so the vendor assets stay tracked/committed.
|
|
|
269
291
|
process (see docs/components.md). The same suite runs in CI on
|
|
270
292
|
`ubuntu-latest`/`windows-latest`/`macos-latest`
|
|
271
293
|
([.github/workflows/ci.yml](.github/workflows/ci.yml)) on every push.
|
|
272
|
-
- `node site/
|
|
294
|
+
- `node site/test_doom_wasm.mjs` — DOOM boot → menu → E1M1 gameplay + save/load
|
|
273
295
|
(see the DOOM section above).
|
|
274
296
|
- `scripts/verify_ethernet.sh [max_inst]` — runs all three firmwares through
|
|
275
297
|
the gateway, asserts the success markers and 0 `TCP fail`.
|
|
@@ -281,7 +303,7 @@ rebuild — delete it so the vendor assets stay tracked/committed.
|
|
|
281
303
|
- [site/about.html](site/about.html) — in-repo About page: what it is, architecture, featured firmwares, and how to use it (CLI / browser / Node API / MCP).
|
|
282
304
|
- [docs/architecture.md](docs/architecture.md) — how the emulator is put
|
|
283
305
|
together (CPU, peripheral model, drivers, ETH flow, interrupts).
|
|
284
|
-
- [docs/peripherals.md](docs/peripherals.md) — all
|
|
306
|
+
- [docs/peripherals.md](docs/peripherals.md) — all 41 peripherals and the
|
|
285
307
|
level each is implemented to, plus external devices and known gaps.
|
|
286
308
|
- [docs/usage.md](docs/usage.md) — CLI, browser, and npm-library usage,
|
|
287
309
|
config files, env vars, building.
|
package/index.d.ts
CHANGED
|
@@ -46,3 +46,10 @@ export class Potentiometer {
|
|
|
46
46
|
export class I2cRegisterDevice {
|
|
47
47
|
constructor(emu: any, peripheral: string, opts?: any);
|
|
48
48
|
}
|
|
49
|
+
|
|
50
|
+
// Board LED map + host reset/boot control (see site/boards.js,
|
|
51
|
+
// site/emulator.js, site/stm32f4.js).
|
|
52
|
+
export interface BoardLed { bank: number; pin: number; label: string; }
|
|
53
|
+
export declare const BOARD_LED: Record<string, BoardLed>;
|
|
54
|
+
export declare const BOARD_LED_ALIASES: Record<string, BoardLed>;
|
|
55
|
+
export declare function boardLed(fwName: string, boardKey: string): BoardLed;
|
package/index.mjs
CHANGED
|
@@ -40,3 +40,4 @@ export async function createSTM32F407(opts = {}) {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
export { createEmulator, createNetSim, FIRMWARES, bindings, svdXml, LED, Button, Pwm, I2cRegisterDevice, Potentiometer, STM32F4, GPIOPin, USART, DMAStream };
|
|
43
|
+
export { boardLed, BOARD_LED, BOARD_LED_ALIASES } from './site/boards.js';
|
package/mcp/server.mjs
CHANGED
|
@@ -252,4 +252,27 @@ server.registerTool('reset', {
|
|
|
252
252
|
return text(`closed session (${was})`);
|
|
253
253
|
});
|
|
254
254
|
|
|
255
|
+
server.registerTool('reset_cpu', {
|
|
256
|
+
description: 'Host reset button: CPU back to the vector-table SP/PC, peripherals keep state (like a real NRST pulse without the hold). Prefer over load_firmware when re-running the same image.',
|
|
257
|
+
inputSchema: {},
|
|
258
|
+
}, async () => {
|
|
259
|
+
const { emu } = requireSession();
|
|
260
|
+
if (typeof emu.resetCpu === 'function') emu.resetCpu();
|
|
261
|
+
else emu.reset();
|
|
262
|
+
return text('cpu reset to vector table');
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
server.registerTool('set_nrst', {
|
|
266
|
+
description: 'Hold (assert=true) or release the NRST line. While held, step() only advances the model clock — the CPU executes nothing, like real hardware in reset. Query with level omitted.',
|
|
267
|
+
inputSchema: { level: z.boolean().optional().describe('true = assert (hold in reset), false = release; omit to query') },
|
|
268
|
+
}, async ({ level }) => {
|
|
269
|
+
const { emu } = requireSession();
|
|
270
|
+
if (level === undefined) {
|
|
271
|
+
const s = typeof emu.isNrstAsserted === 'function' ? emu.isNrstAsserted() : false;
|
|
272
|
+
return text({ asserted: !!s });
|
|
273
|
+
}
|
|
274
|
+
const s = typeof emu.setNrst === 'function' ? emu.setNrst(level) : false;
|
|
275
|
+
return text({ asserted: !!s });
|
|
276
|
+
});
|
|
277
|
+
|
|
255
278
|
await server.connect(new StdioServerTransport());
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stm32f4-emu",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "STM32F407 emulator: Rust CPU + peripheral model (WASM). Runs real Cortex-M4 firmware in Node or the browser.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.mjs",
|
|
@@ -31,6 +31,7 @@
|
|
|
31
31
|
"site/emulator.js",
|
|
32
32
|
"site/emulator.d.ts",
|
|
33
33
|
"site/stm32f4.js",
|
|
34
|
+
"site/boards.js",
|
|
34
35
|
"site/components.js",
|
|
35
36
|
"site/netsim.js",
|
|
36
37
|
"site/firmware.js",
|
|
@@ -39,6 +40,7 @@
|
|
|
39
40
|
"site/ws-bridge.mjs",
|
|
40
41
|
"site/app.js",
|
|
41
42
|
"site/index.html",
|
|
43
|
+
"site/console.html",
|
|
42
44
|
"site/vendor/",
|
|
43
45
|
"mcp/server.mjs",
|
|
44
46
|
"tools/make_firmware.mjs"
|
|
@@ -66,8 +68,8 @@
|
|
|
66
68
|
"node": ">=20"
|
|
67
69
|
},
|
|
68
70
|
"scripts": {
|
|
69
|
-
"test": "node site/test_stm32f4_api.mjs && node site/test_stm32f4_periph.mjs && node site/test_ws_bridge.mjs && node site/test_flow.mjs && node site/test_blinky.mjs && node site/test_rx_interrupt.mjs && node site/test_component_led.mjs && node site/test_component_button.mjs && node site/test_component_pwm.mjs && node site/test_component_i2cregfile.mjs && node site/test_component_adc.mjs && node site/test_multi_instance.mjs && node site/test_fsmc_dcmi.mjs && node site/test_fsmc.mjs && node site/test_dcmi.mjs && node site/probe_freertos.mjs && node site/test_candemo.mjs && node site/test_lowpower.mjs && node site/test_edge_cases.mjs && node site/test_can_inject.mjs && node site/test_watchdog.mjs && node site/test_wwdg.mjs && node site/test_wwdg_window.mjs && node site/test_tim_capture.mjs && node site/test_qspi.mjs && node site/test_fpu.mjs && node site/test_fpu_irq.mjs && node site/test_mpu.mjs && node site/test_usb.mjs && node site/test_qspi_cdp.mjs && node site/test_browser.mjs",
|
|
70
|
-
"test:unit": "node site/test_stm32f4_api.mjs && node site/test_stm32f4_periph.mjs && node site/test_ws_bridge.mjs && node site/test_flow.mjs && node site/test_blinky.mjs && node site/test_rx_interrupt.mjs && node site/test_component_led.mjs && node site/test_component_button.mjs && node site/test_component_pwm.mjs && node site/test_component_i2cregfile.mjs && node site/test_component_adc.mjs && node site/test_multi_instance.mjs && node site/test_fsmc_dcmi.mjs && node site/test_fsmc.mjs && node site/test_dcmi.mjs && node site/probe_freertos.mjs && node site/test_candemo.mjs && node site/test_lowpower.mjs && node site/test_edge_cases.mjs && node site/test_can_inject.mjs && node site/test_watchdog.mjs && node site/test_wwdg.mjs && node site/test_wwdg_window.mjs && node site/test_tim_capture.mjs && node site/test_qspi.mjs",
|
|
71
|
+
"test": "node site/test_stm32f4_api.mjs && node site/test_stm32f4_periph.mjs && node site/test_ws_bridge.mjs && node site/test_flow.mjs && node site/test_eth_mock_model.mjs && node site/test_eth_mock_consumer.mjs && node site/test_periph_mock_consumer.mjs && node site/test_blinky.mjs && node site/test_blinky_f401.mjs && node site/test_blinky_f411.mjs && node site/test_blinky_f407g.mjs && node site/test_blinky_nucleo_f401.mjs && node site/test_blinky_nucleo_f411.mjs && node site/test_blinky_f429.mjs && node site/test_blinky_f407ve.mjs && node site/test_rx_interrupt.mjs && node site/test_component_led.mjs && node site/test_component_button.mjs && node site/test_component_pwm.mjs && node site/test_component_i2cregfile.mjs && node site/test_component_adc.mjs && node site/test_multi_instance.mjs && node site/test_fsmc_dcmi.mjs && node site/test_fsmc.mjs && node site/test_dcmi.mjs && node site/probe_freertos.mjs && node site/test_candemo.mjs && node site/test_lowpower.mjs && node site/test_edge_cases.mjs && node site/test_can_inject.mjs && node site/test_watchdog.mjs && node site/test_wwdg.mjs && node site/test_wwdg_window.mjs && node site/test_tim_capture.mjs && node site/test_qspi.mjs && node site/test_fpu.mjs && node site/test_fpu_irq.mjs && node site/test_mpu.mjs && node site/test_usb.mjs && node site/test_arduino_boards.mjs && node site/test_exti.mjs && node site/test_flash.mjs && node site/test_spi_flash.mjs && node site/test_board_matrix.mjs && node site/test_qspi_cdp.mjs && node site/test_browser.mjs",
|
|
72
|
+
"test:unit": "node site/test_stm32f4_api.mjs && node site/test_stm32f4_periph.mjs && node site/test_ws_bridge.mjs && node site/test_flow.mjs && node site/test_blinky.mjs && node site/test_blinky_f401.mjs && node site/test_blinky_f411.mjs && node site/test_blinky_f407g.mjs && node site/test_blinky_nucleo_f401.mjs && node site/test_blinky_nucleo_f411.mjs && node site/test_blinky_f429.mjs && node site/test_blinky_f407ve.mjs && node site/test_rx_interrupt.mjs && node site/test_component_led.mjs && node site/test_component_button.mjs && node site/test_component_pwm.mjs && node site/test_component_i2cregfile.mjs && node site/test_component_adc.mjs && node site/test_multi_instance.mjs && node site/test_fsmc_dcmi.mjs && node site/test_fsmc.mjs && node site/test_dcmi.mjs && node site/probe_freertos.mjs && node site/test_candemo.mjs && node site/test_lowpower.mjs && node site/test_edge_cases.mjs && node site/test_can_inject.mjs && node site/test_watchdog.mjs && node site/test_wwdg.mjs && node site/test_wwdg_window.mjs && node site/test_tim_capture.mjs && node site/test_qspi.mjs",
|
|
71
73
|
"test:bridge": "node site/test_ws_bridge.mjs",
|
|
72
74
|
"test:bridge:browser": "node site/test_bridge_cdp.mjs",
|
|
73
75
|
"test:flow": "node site/test_flow.mjs",
|
|
@@ -81,7 +83,9 @@
|
|
|
81
83
|
"test:wwdgwin": "node site/test_wwdg_window.mjs",
|
|
82
84
|
"test:timcap": "node site/test_tim_capture.mjs",
|
|
83
85
|
"test:lowpower": "node site/test_lowpower.mjs",
|
|
86
|
+
"test:standby": "node site/test_standby.mjs",
|
|
84
87
|
"test:qspi": "node site/test_qspi.mjs",
|
|
88
|
+
"test:eth:mock": "node site/test_eth_mock_model.mjs && node site/test_eth_mock_consumer.mjs && node site/test_periph_mock_consumer.mjs",
|
|
85
89
|
"test:fpu": "node site/test_fpu.mjs",
|
|
86
90
|
"test:fpuirq": "node site/test_fpu_irq.mjs",
|
|
87
91
|
"test:mpu": "node site/test_mpu.mjs",
|