driverge-mcp 0.1.0-beta.1 โ 0.1.0-beta.3
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 +145 -196
- package/dist/codegen/esp32.d.ts +8 -5
- package/dist/codegen/esp32.js +124 -54
- package/dist/codegen/esp32.js.map +1 -1
- package/dist/codegen/ident.d.ts +9 -0
- package/dist/codegen/ident.js +11 -0
- package/dist/codegen/ident.js.map +1 -1
- package/dist/codegen/lint.js +61 -9
- package/dist/codegen/lint.js.map +1 -1
- package/dist/codegen/portable-cpp.js +50 -42
- package/dist/codegen/portable-cpp.js.map +1 -1
- package/dist/codegen/portable.d.ts +20 -10
- package/dist/codegen/portable.js +166 -117
- package/dist/codegen/portable.js.map +1 -1
- package/dist/codegen/stm32.d.ts +8 -5
- package/dist/codegen/stm32.js +123 -53
- package/dist/codegen/stm32.js.map +1 -1
- package/dist/mcp/cache.js +1 -1
- package/dist/mcp/cache.js.map +1 -1
- package/dist/mcp/register.js +17 -3
- package/dist/mcp/register.js.map +1 -1
- package/dist/pdf/manufacturer.js +12 -0
- package/dist/pdf/manufacturer.js.map +1 -1
- package/dist/pdf/microchip-summary-table.d.ts +10 -0
- package/dist/pdf/microchip-summary-table.js +300 -0
- package/dist/pdf/microchip-summary-table.js.map +1 -0
- package/dist/pdf/onsemi-register-table.d.ts +7 -0
- package/dist/pdf/onsemi-register-table.js +271 -0
- package/dist/pdf/onsemi-register-table.js.map +1 -0
- package/dist/pdf/part.js +3 -0
- package/dist/pdf/part.js.map +1 -1
- package/dist/pdf/ti-field-descriptions.js +9 -3
- package/dist/pdf/ti-field-descriptions.js.map +1 -1
- package/dist/pdf/ti-register-map.js +44 -8
- package/dist/pdf/ti-register-map.js.map +1 -1
- package/dist/schema/assemble.js +15 -0
- package/dist/schema/assemble.js.map +1 -1
- package/dist/schema/validate.js +22 -0
- package/dist/schema/validate.js.map +1 -1
- package/package.json +1 -1
- package/schemas/datasheet.schema.json +4 -1
package/README.md
CHANGED
|
@@ -4,23 +4,27 @@
|
|
|
4
4
|
<p align="center"><em>Datasheet PDF โ embedded C/C++ driver, from any MCP client.</em></p>
|
|
5
5
|
|
|
6
6
|
<p align="center">
|
|
7
|
-
<a href="https://www.npmjs.com/package/driverge-mcp"><img alt="npm" src="https://img.shields.io/npm/v/driverge-mcp"></a>
|
|
7
|
+
<a href="https://www.npmjs.com/package/driverge-mcp"><img alt="npm (beta)" src="https://img.shields.io/npm/v/driverge-mcp/beta"></a>
|
|
8
8
|
<a href="https://github.com/MehmetTopuz/driverge-mcp/actions/workflows/ci.yml"><img alt="CI" src="https://github.com/MehmetTopuz/driverge-mcp/actions/workflows/ci.yml/badge.svg"></a>
|
|
9
9
|
<a href="LICENSE"><img alt="license" src="https://img.shields.io/badge/license-MIT-blue"></a>
|
|
10
10
|
<img alt="status" src="https://img.shields.io/badge/status-closed%20beta-orange">
|
|
11
11
|
<img alt="mcp" src="https://img.shields.io/badge/MCP-server-black">
|
|
12
12
|
</p>
|
|
13
13
|
|
|
14
|
-
> ๐งช **Closed beta** โ
|
|
15
|
-
>
|
|
16
|
-
>
|
|
17
|
-
>
|
|
18
|
-
>
|
|
19
|
-
> See **[Maturity & status](#maturity--status)**, and **[BETA.md](BETA.md)** if
|
|
20
|
-
> you're testing.
|
|
14
|
+
> ๐งช **Closed beta** โ install with **`npm i driverge-mcp@beta`** or run directly
|
|
15
|
+
> with `npx -y driverge-mcp@beta`. Generated drivers are reviewed *drafts*, not
|
|
16
|
+
> hardware-certified firmware, and the JSON schema may still change before the
|
|
17
|
+
> stable **v0.1.0** โ see [Maturity & status](#maturity--status), and
|
|
18
|
+
> [BETA.md](BETA.md) if you're testing.
|
|
21
19
|
|
|
22
20
|
---
|
|
23
21
|
|
|
22
|
+
**Contents:** [What is Driverge?](#what-is-driverge) ยท
|
|
23
|
+
[Quick start](#quick-start) ยท [Why Driverge?](#why-driverge) ยท
|
|
24
|
+
[What it does](#what-it-does) ยท [Maturity & status](#maturity--status) ยท
|
|
25
|
+
[Concepts](#concepts-behind-driverge) ยท [Installation](#installation) ยท
|
|
26
|
+
[Usage](#usage) ยท [Troubleshooting](#troubleshooting) ยท [Roadmap](#roadmap)
|
|
27
|
+
|
|
24
28
|
## What is Driverge?
|
|
25
29
|
|
|
26
30
|
**Driverge is a client-agnostic [MCP](https://modelcontextprotocol.io) server**
|
|
@@ -28,10 +32,14 @@ that turns an IC datasheet PDF into an embedded C/C++ driver. It plugs into any
|
|
|
28
32
|
MCP-capable host โ Claude Desktop, Claude Code (VS Code), Cursor, and others.
|
|
29
33
|
|
|
30
34
|
Its guiding principle: **deterministic code parses and validates; the host AI
|
|
31
|
-
reasons.** Driverge
|
|
32
|
-
TypeScript pipeline extracts a *validated, structured JSON* model of the chip,
|
|
33
|
-
the host AI you're already talking to fills in the reasoning-heavy parts
|
|
34
|
-
sequence, vendor quirks, docs). Your datasheet never leaves your machine.
|
|
35
|
+
reasons.** Driverge contains **no internal LLM and needs no API keys** โ a
|
|
36
|
+
TypeScript pipeline extracts a *validated, structured JSON* model of the chip,
|
|
37
|
+
and the host AI you're already talking to fills in the reasoning-heavy parts
|
|
38
|
+
(init sequence, vendor quirks, docs). Your datasheet never leaves your machine.
|
|
39
|
+
|
|
40
|
+
<p align="center">
|
|
41
|
+
<img src="assets/driverge-flow.png" alt="How Driverge works: a datasheet PDF flows through the deterministic analyze โ frozen JSON โ generate โ validate pipeline; the host AI fills the TODO(driverge) gaps and the loop repeats until validation passes, producing driver.c/.h" width="760">
|
|
42
|
+
</p>
|
|
35
43
|
|
|
36
44
|
## Quick start
|
|
37
45
|
|
|
@@ -58,30 +66,22 @@ That's it โ no clone, no build, no API key. Details in
|
|
|
58
66
|
|
|
59
67
|
Bringing up a new sensor or IC means hand-transcribing dozens of register
|
|
60
68
|
addresses, bit-field masks, and command codes out of a 40-page PDF โ slow work,
|
|
61
|
-
and a classic source of silent bugs (one wrong mask
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
- **No hallucinated register maps.** Addresses,
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
(Claude Desktop, Claude Code, Cursor, โฆ) and reasons with the model you're
|
|
72
|
-
already paying for โ no separate subscription or service.
|
|
73
|
-
- **Private & offline.** The datasheet is parsed locally and never uploaded โ safe
|
|
74
|
-
for NDA'd or unreleased parts.
|
|
69
|
+
and a classic source of silent bugs (one wrong mask and the driver "works" but
|
|
70
|
+
reads garbage). Driverge does that mechanical part deterministically and leaves
|
|
71
|
+
the judgment to the AI you already use.
|
|
72
|
+
|
|
73
|
+
- **No hallucinated register maps.** Addresses, masks, and command codes are
|
|
74
|
+
*extracted from the datasheet and validated* โ not guessed. Invalid or
|
|
75
|
+
incomplete data is rejected before it can become code.
|
|
76
|
+
- **Bring your own client โ private by design.** A plain MCP server with no
|
|
77
|
+
embedded LLM: it reasons with the model you're already paying for, and the
|
|
78
|
+
datasheet is parsed locally, never uploaded โ safe for NDA'd parts.
|
|
75
79
|
- **Deterministic & reproducible.** The same PDF always yields the same JSON and
|
|
76
|
-
the same driver skeleton โ reviewable, diff-able, and testable
|
|
77
|
-
black box.
|
|
80
|
+
the same driver skeleton โ reviewable, diff-able, and testable.
|
|
78
81
|
- **Portable by construction.** One driver core targets any platform through a
|
|
79
|
-
tiny per-bus thin-HAL seam
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
init-sequence ordering, timing quirks, and compensation math need judgment.
|
|
83
|
-
Driverge marks exactly those spots with `TODO(driverge)` and a `fill_in_brief`,
|
|
84
|
-
the host AI completes them, then `validate_driver` checks the result.
|
|
82
|
+
tiny per-bus thin-HAL seam; native targets (STM32, ESP32) pre-fill it. The AI
|
|
83
|
+
completes only the marked `TODO(driverge)` gaps, and `validate_driver` checks
|
|
84
|
+
the result.
|
|
85
85
|
|
|
86
86
|
**Good for:** quickly evaluating a new sensor, prototyping, porting an existing
|
|
87
87
|
driver to a different MCU, or just learning an unfamiliar chip's register map.
|
|
@@ -93,43 +93,40 @@ driver to a different MCU, or just learning an unfamiliar chip's register map.
|
|
|
93
93
|
commands + CRC) and the bus protocol into a **frozen JSON contract**, gated by
|
|
94
94
|
a validator.
|
|
95
95
|
2. **Generate** a driver for a target platform, in C or C++: a deterministic
|
|
96
|
-
**thin-HAL skeleton** โ register/bit-field constants, the per-bus
|
|
97
|
-
|
|
98
|
-
telling the host AI exactly what to complete.
|
|
99
|
-
3. **Validate** the completed driver: thin-HAL purity, no leftover TODOs,
|
|
100
|
-
references exist, bit-field masks match the JSON.
|
|
96
|
+
**thin-HAL skeleton** โ register/bit-field constants, the per-bus seam,
|
|
97
|
+
function stubs โ with every reasoning gap marked `TODO(driverge)` plus a
|
|
98
|
+
`fill_in_brief` telling the host AI exactly what to complete.
|
|
99
|
+
3. **Validate** the completed driver: thin-HAL purity, no leftover TODOs,
|
|
100
|
+
register references exist, bit-field masks match the JSON.
|
|
101
101
|
|
|
102
102
|
### Supported targets
|
|
103
103
|
|
|
104
|
-
Every target specializes the same portable
|
|
105
|
-
seam โ
|
|
104
|
+
Every target specializes the same portable
|
|
105
|
+
**[thin-HAL](https://en.wikipedia.org/wiki/Hardware_abstraction_layer)** seam โ
|
|
106
|
+
the driver core is identical across platforms; only the seam implementation
|
|
106
107
|
changes.
|
|
107
108
|
|
|
108
109
|
| Target | Bus binding | Buses | Language | Maturity |
|
|
109
110
|
|---|---|---|---|---|
|
|
110
|
-
| **Portable (thin-HAL)** | user-implemented
|
|
111
|
-
| **ESP32** | ESP-IDF (`i2c_master_*`, `spi_master`, `uart`, TWAI) | IยฒC, SPI, UART, CAN | C / C++ | **Experimental** |
|
|
112
|
-
| **STM32** | CubeHAL (`HAL_I2C_*`, `HAL_SPI_*` + GPIO CS, `HAL_UART_*`) | IยฒC, SPI, UART | C / C++ | **Experimental** |
|
|
111
|
+
| **Portable (thin-HAL)** | user-implemented `<part>_hal_*` seam | IยฒC, SPI, UART, CAN | C / C++ | **Beta** โ host-tested, gcc-compiled in CI; not yet on hardware |
|
|
112
|
+
| **ESP32** | ESP-IDF (`i2c_master_*`, `spi_master`, `uart`, TWAI) | IยฒC, SPI, UART, CAN | C / C++ | **Experimental** โ one informal IยฒC bring-up; SPI/UART/CAN never on hardware |
|
|
113
|
+
| **STM32** | CubeHAL (`HAL_I2C_*`, `HAL_SPI_*` + GPIO CS, `HAL_UART_*`) | IยฒC, SPI, UART | C / C++ | **Experimental** โ 3 hardware field tests (NUCLEO-G474RE, hand-completed); no automated compile gate yet |
|
|
113
114
|
| **Arduino** | `Wire` / `SPI` | โ | C++ | not implemented |
|
|
114
115
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
a target for a bus it doesn't support fails fast
|
|
119
|
-
`UnsupportedBusError` rather than emitting a wrong seam. Pass
|
|
116
|
+
STM32 CAN is planned (the bxCAN/FDCAN family split needs its own pass), and a
|
|
117
|
+
next wave of native targets โ RP2040/RP2350, TI MSPM0, NXP MCX/i.MX RT,
|
|
118
|
+
Nuvoton NuMicro, Microchip PIC, and eventually Zephyr โ is on the
|
|
119
|
+
[Roadmap](#roadmap). Asking a target for a bus it doesn't support fails fast
|
|
120
|
+
with a clear `UnsupportedBusError` rather than emitting a wrong seam. Pass
|
|
120
121
|
`language: "cpp"` to `generate_driver` for a class-based C++ driver
|
|
121
122
|
(`.hpp`/`.cpp`) instead of the default C output โ same registers, same seam,
|
|
122
|
-
same validation.
|
|
123
|
-
|
|
124
|
-
> โ ๏ธ **Generated code is a strong draft, not a certified driver.** Init sequences,
|
|
125
|
-
> compensation formulas, and timing quirks are completed by the host AI and
|
|
126
|
-
> **must be reviewed** before use on hardware. Not safety-certified.
|
|
123
|
+
same validation. What "Beta" and "Experimental" mean exactly is spelled out in
|
|
124
|
+
[Maturity & status](#maturity--status).
|
|
127
125
|
|
|
128
126
|
### Verified parts
|
|
129
127
|
|
|
130
128
|
The extraction pipeline is regression-tested against real datasheets from
|
|
131
|
-
**12 manufacturers**. Parts with fully automatic extraction
|
|
132
|
-
bit-fields, or a clean command set):
|
|
129
|
+
**12 manufacturers**. Parts with fully automatic extraction:
|
|
133
130
|
|
|
134
131
|
| Part | Manufacturer | Kind | Extracted |
|
|
135
132
|
|---|---|---|---|
|
|
@@ -141,52 +138,40 @@ bit-fields, or a clean command set):
|
|
|
141
138
|
| LSM6DSRX | STMicroelectronics | register map | 31 regs, 91 bit-fields |
|
|
142
139
|
| MAX30102 | Maxim Integrated | register map | 20 regs, 33 bit-fields |
|
|
143
140
|
|
|
144
|
-
Other tested parts (ADXL345, MLX90614, AEAT-8811, PCA9685, VL53L3CX, TLE5014
|
|
145
|
-
extract **partially** or **defer** to the host AI โ the pipeline says so
|
|
146
|
-
explicitly instead of guessing,
|
|
147
|
-
what to complete. The full, always-current matrix lives in the
|
|
141
|
+
Other tested parts (ADXL345, MLX90614, AEAT-8811, PCA9685, VL53L3CX, TLE5014,
|
|
142
|
+
TCA6408A) extract **partially** or **defer** to the host AI โ the pipeline says so
|
|
143
|
+
explicitly instead of guessing. The full, always-current matrix lives in the
|
|
148
144
|
[coverage scorecard](tests/scorecard/scorecard.snap.md).
|
|
149
145
|
|
|
150
146
|
## Maturity & status
|
|
151
147
|
|
|
152
|
-
Driverge is in **closed beta** (`0.1.0-beta.x`, npm `beta` dist-tag).
|
|
153
|
-
exactly what that means โ what's proven, what isn't, and how much to trust the
|
|
154
|
-
output.
|
|
148
|
+
Driverge is in **closed beta** (`0.1.0-beta.x`, npm `beta` dist-tag).
|
|
155
149
|
|
|
156
150
|
**Proven today (host-level):**
|
|
157
|
-
- The full deterministic test suite is green (
|
|
158
|
-
TypeScript build
|
|
159
|
-
|
|
160
|
-
- The extraction pipeline is regression-tested against **
|
|
161
|
-
and reports its own coverage honestly โ
|
|
162
|
-
deferred
|
|
163
|
-
[coverage scorecard](tests/scorecard/scorecard.snap.md)).
|
|
151
|
+
- The full deterministic test suite is green (540-plus tests) on a clean
|
|
152
|
+
TypeScript build, and the **portable** driver is compiled by a real `gcc`
|
|
153
|
+
gate in CI (including a multi-driver link gate).
|
|
154
|
+
- The extraction pipeline is regression-tested against **14 real datasheets**
|
|
155
|
+
and reports its own coverage honestly โ 7 fully extracted, 4 partial, 3
|
|
156
|
+
deferred (see the [coverage scorecard](tests/scorecard/scorecard.snap.md)).
|
|
164
157
|
|
|
165
158
|
**Not yet proven โ this is the beta โ v0.1.0 gate:**
|
|
166
|
-
- **On-hardware behavior is not gated.**
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
159
|
+
- **On-hardware behavior is not gated by CI.** STM32 has now run on real
|
|
160
|
+
hardware โ three NUCLEO-G474RE field tests (onsemi FXL6408 IยฒC, TI TUSS4470
|
|
161
|
+
SPI, Microchip CAP1206 IยฒC), each hand-completed and folded back into the
|
|
162
|
+
generator โ and ESP32 has one informal IยฒC bring-up (MPU-9250). There is still
|
|
163
|
+
no clean, repeatable automated hardware pass, so every generated driver needs
|
|
164
|
+
review before you flash it.
|
|
165
|
+
- The native ESP32/STM32 seams are not yet built by an automated compile gate
|
|
171
166
|
(ESP-IDF / CubeIDE) โ only the portable target is.
|
|
172
167
|
- Only one MCP client has been exercised end-to-end.
|
|
173
168
|
|
|
174
|
-
**
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|---|---|---|
|
|
178
|
-
| Portable (thin-HAL) | IยฒC (host-compiled only) | **Beta** โ host-tested + gcc-compiled, not on hardware |
|
|
179
|
-
| ESP32 (ESP-IDF) | IยฒC (one informal bring-up) | **Experimental** โ codegen shipped; SPI/UART/CAN never on hardware |
|
|
180
|
-
| STM32 (CubeHAL) | none | **Experimental** โ codegen shipped; never on hardware |
|
|
181
|
-
| Arduino ยท STM32 CAN | โ | **Not implemented** |
|
|
182
|
-
|
|
183
|
-
> Treat every generated driver as a **reviewed draft**: check register addresses,
|
|
184
|
-
> the init sequence, and any compensation math against the datasheet before you
|
|
185
|
-
> flash it. Driverge is not safety-certified.
|
|
169
|
+
> โ ๏ธ Treat every generated driver as a **reviewed draft**: check register
|
|
170
|
+
> addresses, the init sequence, and any compensation math against the datasheet
|
|
171
|
+
> before you flash it. Driverge is not safety-certified.
|
|
186
172
|
|
|
187
173
|
**Testing the beta?** [BETA.md](BETA.md) has the identity-register smoke test to
|
|
188
|
-
run and how to send a field report
|
|
189
|
-
`raw/DRIVERGE_ISSUES.md` is the template.
|
|
174
|
+
run and how to send a field report.
|
|
190
175
|
|
|
191
176
|
## Concepts behind Driverge
|
|
192
177
|
|
|
@@ -194,34 +179,16 @@ Driverge splits driver-writing into two kinds of work: the **mechanical part**
|
|
|
194
179
|
(register addresses, masks, command tables โ extracted and checked by
|
|
195
180
|
deterministic code) and the **judgment part** (init ordering, timing quirks,
|
|
196
181
|
compensation math โ completed by the host AI). Everything below exists to keep
|
|
197
|
-
that boundary sharp
|
|
198
|
-
|
|
199
|
-
```mermaid
|
|
200
|
-
flowchart LR
|
|
201
|
-
PDF["Datasheet PDF"]
|
|
202
|
-
subgraph D["Driverge โ deterministic, no LLM"]
|
|
203
|
-
A["analyze_datasheet<br>L1โL5 parse + validate"]
|
|
204
|
-
J[("frozen JSON<br>cached under a ref")]
|
|
205
|
-
G["generate_driver<br>thin-HAL skeleton +<br>TODO(driverge) markers"]
|
|
206
|
-
V["validate_driver<br>static lint"]
|
|
207
|
-
end
|
|
208
|
-
subgraph H["Host AI โ reasoning"]
|
|
209
|
-
F["fill the TODOs: init sequence,<br>quirks, compensation docs"]
|
|
210
|
-
end
|
|
211
|
-
OUT["driver.c / driver.h"]
|
|
212
|
-
PDF --> A --> J --> G --> F --> V
|
|
213
|
-
V -->|pass| OUT
|
|
214
|
-
V -->|fail| F
|
|
215
|
-
```
|
|
182
|
+
that boundary sharp; the diagram at the top of this page shows how the pieces
|
|
183
|
+
connect.
|
|
216
184
|
|
|
217
185
|
### Deterministic core, reasoning at the edge
|
|
218
186
|
|
|
219
187
|
Register geometry is mechanical: an address is right or wrong, a mask either
|
|
220
188
|
matches the datasheet or it doesn't. Driverge handles that part with plain
|
|
221
|
-
TypeScript โ no
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
is left to the host AI you're already talking to.
|
|
189
|
+
TypeScript โ no sampling, so the output is the same on every run. What genuinely
|
|
190
|
+
needs judgment (in what order to poke the registers, which timing quirk applies)
|
|
191
|
+
is left to the host AI.
|
|
225
192
|
|
|
226
193
|
### The frozen JSON contract
|
|
227
194
|
|
|
@@ -244,30 +211,27 @@ re-parse, and the full JSON stays readable at `driverge://datasheet/<ref>`.
|
|
|
244
211
|
### The thin-HAL seam
|
|
245
212
|
|
|
246
213
|
Generated drivers touch hardware through a tiny per-bus seam โ and nothing
|
|
247
|
-
else
|
|
214
|
+
else. Seam symbols are **prefixed with the part's slug** (e.g.
|
|
215
|
+
`bme280_hal_i2c_read`) so two Driverge drivers can link into one firmware
|
|
216
|
+
image without symbol collisions:
|
|
248
217
|
|
|
249
|
-
| Bus | Seam functions (plus `
|
|
218
|
+
| Bus | Seam functions (plus `<part>_hal_delay_ms`) |
|
|
250
219
|
|---|---|
|
|
251
|
-
| IยฒC |
|
|
252
|
-
| SPI | `
|
|
253
|
-
| UART |
|
|
254
|
-
| CAN | `
|
|
255
|
-
|
|
256
|
-
The
|
|
257
|
-
|
|
258
|
-
(
|
|
259
|
-
status,
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
(
|
|
266
|
-
`validate_driver` enforces this purity: a driver that calls a vendor peripheral
|
|
267
|
-
API outside the seam fails the lint. Buses with no universal register-access
|
|
268
|
-
primitive (UART, CAN) keep the same discipline โ the device-specific framing is
|
|
269
|
-
a marked `TODO(driverge)` reasoning gap (`framing_todo`), completed by the host
|
|
270
|
-
AI and then linted.
|
|
220
|
+
| IยฒC | `<part>_hal_i2c_read`, `<part>_hal_i2c_write` |
|
|
221
|
+
| SPI | `<part>_hal_spi_transfer(tx, rx, len)` (one call = one CS-framed **full-duplex** transaction; `rx` may be `NULL` for write-only, and write-then-read devices are served by padding `tx` with dummy bytes) |
|
|
222
|
+
| UART | `<part>_hal_uart_write`, `<part>_hal_uart_read` |
|
|
223
|
+
| CAN | `<part>_hal_can_transfer` (one call = one frame exchange) |
|
|
224
|
+
|
|
225
|
+
The transfer seams return `int` โ **`0` on success, non-zero on a bus error**
|
|
226
|
+
(NACK, timeout) โ and the generated register accessors propagate that status
|
|
227
|
+
instead of swallowing it; native seams (ESP32, STM32) return their vendor
|
|
228
|
+
status, which is already `0` on success. Native targets also emit a seam
|
|
229
|
+
companion header (`<part>_hal_stm32.h` / `<part>_hal_esp32.h`) declaring the
|
|
230
|
+
one-time `bind` call that points the seam at your peripheral handle.
|
|
231
|
+
`validate_driver` enforces seam purity: a driver that calls a vendor
|
|
232
|
+
peripheral API outside the seam fails the lint. Buses with no universal
|
|
233
|
+
register-access primitive (UART, CAN) get their device-specific framing as a
|
|
234
|
+
marked `TODO(driverge)` gap, completed by the host AI and then linted.
|
|
271
235
|
|
|
272
236
|
### The fill-in loop
|
|
273
237
|
|
|
@@ -281,28 +245,17 @@ matching the JSON โ and the loop repeats until it passes.
|
|
|
281
245
|
|
|
282
246
|
**Prerequisites:** Node.js LTS (โฅ 18; CI-tested on Node 20 & 22).
|
|
283
247
|
|
|
284
|
-
|
|
285
|
-
[npx](https://docs.npmjs.com/cli/commands/npx) fetches and runs it):
|
|
248
|
+
Install the beta from npm:
|
|
286
249
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
{
|
|
290
|
-
"mcpServers": {
|
|
291
|
-
"driverge": { "command": "npx", "args": ["-y", "driverge-mcp"] }
|
|
292
|
-
}
|
|
293
|
-
}
|
|
250
|
+
```bash
|
|
251
|
+
npm i driverge-mcp@beta
|
|
294
252
|
```
|
|
295
253
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
"driverge": { "command": "npx", "args": ["-y", "driverge-mcp"] }
|
|
301
|
-
}
|
|
302
|
-
}
|
|
303
|
-
```
|
|
254
|
+
Or skip the install entirely โ the config below launches Driverge via
|
|
255
|
+
[npx](https://docs.npmjs.com/cli/commands/npx), which downloads it from npm on
|
|
256
|
+
first run, caches it, and starts it automatically each time the client does
|
|
257
|
+
(`-y` skips npx's install prompt). Add one entry to your MCP client's config:
|
|
304
258
|
|
|
305
|
-
**Cursor** โ `.cursor/mcp.json`:
|
|
306
259
|
```json
|
|
307
260
|
{
|
|
308
261
|
"mcpServers": {
|
|
@@ -311,25 +264,29 @@ Add Driverge to your MCP client (no build step โ
|
|
|
311
264
|
}
|
|
312
265
|
```
|
|
313
266
|
|
|
314
|
-
|
|
315
|
-
|
|
267
|
+
| Client | Config file |
|
|
268
|
+
|---|---|
|
|
269
|
+
| Claude Desktop | `claude_desktop_config.json` |
|
|
270
|
+
| Claude Code (VS Code) | `.mcp.json` in your workspace root |
|
|
271
|
+
| Cursor | `.cursor/mcp.json` |
|
|
272
|
+
| Others (Codex, Gemini CLI, โฆ) | same `command` + `args` pair in their own MCP config |
|
|
316
273
|
|
|
317
274
|
> **Beta testers:** pin the beta channel explicitly with `["-y",
|
|
318
275
|
> "driverge-mcp@beta"]` as the `args`. Plain `driverge-mcp` resolves the npm
|
|
319
276
|
> `latest` tag, which deliberately lags the beta during closed beta.
|
|
320
277
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
(
|
|
325
|
-
|
|
326
|
-
the repo (below) is only for development.
|
|
278
|
+
You never run the server by hand โ to confirm it's wired up, ask your client to
|
|
279
|
+
run the `ping` tool, which replies `pong`. On Windows, prefer writing the
|
|
280
|
+
config file directly over `claude mcp add` โ see
|
|
281
|
+
[Troubleshooting](#troubleshooting). Cloning the repo (below) is only for
|
|
282
|
+
development.
|
|
327
283
|
|
|
328
284
|
### Configuration
|
|
329
285
|
|
|
330
286
|
| Env var | Default | Purpose |
|
|
331
287
|
|---|---|---|
|
|
332
288
|
| `DRIVERGE_OUT_ROOT` | server's working directory | Root that `generate_driver`'s `out_dir` writes are confined to. Any `out_dir` that resolves outside this root is rejected (`out_dir "โฆ" escapes the allowed root`). Set it to the directory you want drivers written into. |
|
|
289
|
+
| `DRIVERGE_MAX_PDF_BYTES` | `67108864` (64 MiB) | Maximum PDF size `analyze_datasheet` will read. A larger file is rejected with a clear "PDF too large" error before any parsing โ bounds memory use on a hostile or accidentally huge input. |
|
|
333
290
|
|
|
334
291
|
Set it in the MCP config's `env` block, e.g.:
|
|
335
292
|
|
|
@@ -348,30 +305,6 @@ Set it in the MCP config's `env` block, e.g.:
|
|
|
348
305
|
Without `out_dir` the generated files are returned in the tool result only โ
|
|
349
306
|
no disk writes, no configuration needed.
|
|
350
307
|
|
|
351
|
-
### Windows & npx notes
|
|
352
|
-
|
|
353
|
-
The config blocks above (writing `.mcp.json` / `claude_desktop_config.json`
|
|
354
|
-
**directly**) are the most reliable way to add Driverge on Windows. A few
|
|
355
|
-
environment-specific snags worth knowing:
|
|
356
|
-
|
|
357
|
-
- **Prefer editing the config file over `claude mcp add โฆ -- npx -y driverge-mcp`.**
|
|
358
|
-
The `-y` after `npx` can be parsed by the `claude` CLI itself
|
|
359
|
-
(`unknown option '-y'`) rather than passed through. Writing the JSON block
|
|
360
|
-
directly sidesteps it. (`-y` still belongs in the `args` array, as shown above โ
|
|
361
|
-
it only misbehaves as a bare CLI flag.)
|
|
362
|
-
- **PowerShell 5.1 + `claude mcp add-json`.** Nested double-quotes in the inline
|
|
363
|
-
JSON can get mangled before the CLI sees them (`Invalid configuration: Invalid
|
|
364
|
-
input`). Again, write the `.mcp.json` file directly instead of passing JSON on
|
|
365
|
-
the command line.
|
|
366
|
-
- **Spawning the server yourself?** On Windows, launching `npx.cmd` from Node
|
|
367
|
-
needs `shell: true` (otherwise `spawn EINVAL`) โ Node no longer runs `.cmd`
|
|
368
|
-
shims without a shell. MCP clients handle this for you; this only bites custom
|
|
369
|
-
smoke-test scripts.
|
|
370
|
-
- **"Pending approval" in `claude mcp list`.** A project-scope `.mcp.json` may show
|
|
371
|
-
as `โธ Pending approval` in a separate `claude mcp list` process while the
|
|
372
|
-
`driverge` tools are already callable in your active session โ the listing lags
|
|
373
|
-
the running session, it does not mean the server failed to load.
|
|
374
|
-
|
|
375
308
|
### Run from source (development)
|
|
376
309
|
|
|
377
310
|
To contribute, or to run the latest unreleased changes:
|
|
@@ -413,13 +346,11 @@ Give your MCP client a datasheet and ask it to build a driver. The typical flow:
|
|
|
413
346
|
Reusing the same `ref` with a different `target` re-renders with **no re-parse**.
|
|
414
347
|
|
|
415
348
|
**Completing a `deferred` datasheet.** When `analyze_datasheet` reports
|
|
416
|
-
`extraction: deferred
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
under that `ref`. The next `generate_driver({ "ref": "โฆ" })` then renders the real
|
|
422
|
-
registers instead of a TODO stub. This closes the loop without re-analyzing.
|
|
349
|
+
`extraction: deferred`, the host AI reconstructs the register map from the
|
|
350
|
+
`driverge://datasheet/<ref>` resource and persists it back with
|
|
351
|
+
`validate_datasheet({ "ref": "โฆ", "json": { โฆ } })` โ passing **both** `ref` and
|
|
352
|
+
the completed `json` overwrites the cached datasheet under that `ref`, so the
|
|
353
|
+
next `generate_driver` renders the real registers instead of a TODO stub.
|
|
423
354
|
|
|
424
355
|
### Worked example โ BME280 โ portable driver
|
|
425
356
|
|
|
@@ -463,7 +394,7 @@ datasheet prose, and `validate_driver` checks the result.
|
|
|
463
394
|
| Tool | `analyze_datasheet` | PDF โ validated JSON, cached under a `ref` |
|
|
464
395
|
| Tool | `generate_driver` | `ref` + `target` โ driver skeleton + `fill_in_brief` |
|
|
465
396
|
| Tool | `validate_driver` | static-lint a completed driver against its `ref` |
|
|
466
|
-
| Tool | `validate_datasheet` | re-run the
|
|
397
|
+
| Tool | `validate_datasheet` | re-run the validator over a `ref` or JSON; passing **both** persists the completed datasheet under that `ref` |
|
|
467
398
|
| Tool | `ping` | health check โ confirms the server is running |
|
|
468
399
|
| Resource | `driverge://datasheet/<ref>` | full parsed JSON for an analyzed datasheet |
|
|
469
400
|
| Resource | `driverge://schema` | the frozen datasheet JSON-Schema contract |
|
|
@@ -487,18 +418,36 @@ datasheet prose, and `validate_driver` checks the result.
|
|
|
487
418
|
- **`UnsupportedBusError` on a native target.** The target doesn't support that
|
|
488
419
|
part's bus yet (today that means CAN on STM32, or a bus the parser couldn't
|
|
489
420
|
identify). Generate the **portable** target instead and implement its seam.
|
|
421
|
+
- **Windows: prefer editing the config file over the `claude mcp add` CLI.**
|
|
422
|
+
`claude mcp add โฆ -- npx -y driverge-mcp` can eat the `-y` itself (`unknown
|
|
423
|
+
option '-y'`), and PowerShell 5.1 mangles the nested quotes in `claude mcp
|
|
424
|
+
add-json`. Writing the JSON block directly into `.mcp.json` /
|
|
425
|
+
`claude_desktop_config.json` sidesteps both.
|
|
426
|
+
- **Windows: spawning the server from your own script.** Launching `npx.cmd`
|
|
427
|
+
from Node needs `shell: true` (otherwise `spawn EINVAL`). MCP clients handle
|
|
428
|
+
this for you; it only bites custom smoke-test scripts.
|
|
429
|
+
- **"Pending approval" in `claude mcp list`.** A project-scope `.mcp.json` may
|
|
430
|
+
show as `โธ Pending approval` in a separate `claude mcp list` process while
|
|
431
|
+
the `driverge` tools are already callable in your active session โ the
|
|
432
|
+
listing lags the running session.
|
|
490
433
|
|
|
491
434
|
## Roadmap
|
|
492
435
|
|
|
493
436
|
- **v0.x** โ one reference sensor (BME280), portable thin-HAL core, MCP surface,
|
|
494
437
|
multiple clients. โ
|
|
495
438
|
- **v0.y** โ native codegen: ESP32 โ
, STM32 โ
*(on-hardware verification is the
|
|
496
|
-
beta โ v0.1.0 gate
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
CAN) โ
; C or C++ output โ
. *(current)*
|
|
439
|
+
beta โ v0.1.0 gate)*, Arduino (next); multi-manufacturer extraction โ
|
|
440
|
+
(12 vendors โ see [Verified parts](#verified-parts)); multi-bus seam families
|
|
441
|
+
(IยฒC, SPI, UART, CAN) โ
; C or C++ output โ
. *(current)*
|
|
500
442
|
- **v1.0** โ broader vendor/part coverage, STM32 CAN (bxCAN/FDCAN), and a
|
|
501
443
|
stable, versioned JSON schema.
|
|
444
|
+
- **v1.x** โ new native MCU targets (same portable thin-HAL core, one seam
|
|
445
|
+
file per platform; prioritized by beta-tester demand): **RP2040/RP2350**
|
|
446
|
+
(pico-sdk), **TI MSPM0** (DriverLib), **NXP MCX / i.MX RT** (MCUXpresso
|
|
447
|
+
`fsl_lpi2c`/`fsl_lpspi`), **Nuvoton NuMicro** (BSP Standard Driver), and
|
|
448
|
+
**Microchip PIC** (MCC Melody for 8/16-bit; Harmony v3 for PIC32).
|
|
449
|
+
- **Later** โ a **Zephyr** meta-target (devicetree-based `i2c`/`spi` API):
|
|
450
|
+
one seam covering Nordic nRF and every other Zephyr-supported vendor.
|
|
502
451
|
|
|
503
452
|
Day-to-day progress is tracked in the [CHANGELOG](CHANGELOG.md).
|
|
504
453
|
|
package/dist/codegen/esp32.d.ts
CHANGED
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import type { DatasheetJson } from "../schema/types.js";
|
|
2
2
|
import type { CodegenLanguage, DriverArtifact } from "./types.js";
|
|
3
3
|
/**
|
|
4
|
-
* Portable core + an ESP-IDF seam implementation
|
|
5
|
-
* language "c" (default) the seam is `<slug>_hal_esp32.c
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
4
|
+
* Portable core + an ESP-IDF seam implementation + a seam companion header for
|
|
5
|
+
* the same part. With language "c" (default) the seam is `<slug>_hal_esp32.c`;
|
|
6
|
+
* with language "cpp" it is `<slug>_hal_esp32.cpp` and its core include is
|
|
7
|
+
* `#include "<slug>.hpp"` (see coreInclude/seamPath above) โ everything else
|
|
8
|
+
* in the seam content is identical either way. The companion header
|
|
9
|
+
* (`<slug>_hal_esp32.h`) is always a plain `.h` file, in BOTH language runs.
|
|
10
|
+
* File order in the artifact: [core header, core source, companion header,
|
|
11
|
+
* seam source] โ see tests/codegen/esp32.test.ts.
|
|
9
12
|
*/
|
|
10
13
|
export declare function generateEsp32Driver(json: DatasheetJson, opts?: {
|
|
11
14
|
language?: CodegenLanguage;
|