driverge-mcp 0.0.0 → 0.0.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 +275 -29
- package/dist/codegen/esp32.d.ts +11 -3
- package/dist/codegen/esp32.js +221 -10
- package/dist/codegen/esp32.js.map +1 -1
- package/dist/codegen/ident.d.ts +24 -2
- package/dist/codegen/ident.js +37 -4
- package/dist/codegen/ident.js.map +1 -1
- package/dist/codegen/index.d.ts +12 -7
- package/dist/codegen/index.js +17 -14
- package/dist/codegen/index.js.map +1 -1
- package/dist/codegen/lint.js +28 -8
- package/dist/codegen/lint.js.map +1 -1
- package/dist/codegen/portable-cpp.d.ts +8 -0
- package/dist/codegen/portable-cpp.js +281 -0
- package/dist/codegen/portable-cpp.js.map +1 -0
- package/dist/codegen/portable.d.ts +99 -3
- package/dist/codegen/portable.js +419 -99
- package/dist/codegen/portable.js.map +1 -1
- package/dist/codegen/stm32.d.ts +11 -3
- package/dist/codegen/stm32.js +156 -11
- package/dist/codegen/stm32.js.map +1 -1
- package/dist/codegen/types.d.ts +32 -0
- package/dist/codegen/types.js +27 -0
- package/dist/codegen/types.js.map +1 -1
- package/dist/mcp/cache.d.ts +15 -2
- package/dist/mcp/cache.js +32 -4
- package/dist/mcp/cache.js.map +1 -1
- package/dist/mcp/register.d.ts +17 -0
- package/dist/mcp/register.js +149 -21
- package/dist/mcp/register.js.map +1 -1
- package/dist/mcp/summary.js +8 -0
- package/dist/mcp/summary.js.map +1 -1
- package/dist/pdf/address.d.ts +4 -0
- package/dist/pdf/address.js +28 -0
- package/dist/pdf/address.js.map +1 -0
- package/dist/pdf/command.js +87 -14
- package/dist/pdf/command.js.map +1 -1
- package/dist/pdf/extract.js +23 -2
- package/dist/pdf/extract.js.map +1 -1
- package/dist/pdf/generic-register-table.d.ts +5 -0
- package/dist/pdf/generic-register-table.js +125 -0
- package/dist/pdf/generic-register-table.js.map +1 -0
- package/dist/pdf/index.d.ts +2 -0
- package/dist/pdf/index.js +2 -0
- package/dist/pdf/index.js.map +1 -1
- package/dist/pdf/interface-kind.d.ts +11 -0
- package/dist/pdf/interface-kind.js +18 -0
- package/dist/pdf/interface-kind.js.map +1 -1
- package/dist/pdf/manufacturer.js +39 -0
- package/dist/pdf/manufacturer.js.map +1 -1
- package/dist/pdf/maxim-register-map.d.ts +11 -0
- package/dist/pdf/maxim-register-map.js +544 -0
- package/dist/pdf/maxim-register-map.js.map +1 -0
- package/dist/pdf/part.js +8 -0
- package/dist/pdf/part.js.map +1 -1
- package/dist/pdf/prose-commands.d.ts +4 -0
- package/dist/pdf/prose-commands.js +90 -0
- package/dist/pdf/prose-commands.js.map +1 -0
- package/dist/pdf/st-bit-layout.d.ts +3 -0
- package/dist/pdf/st-bit-layout.js +238 -0
- package/dist/pdf/st-bit-layout.js.map +1 -0
- package/dist/pdf/ti-field-descriptions.d.ts +10 -0
- package/dist/pdf/ti-field-descriptions.js +87 -0
- package/dist/pdf/ti-field-descriptions.js.map +1 -0
- package/dist/pdf/ti-register-map.d.ts +5 -0
- package/dist/pdf/ti-register-map.js +84 -0
- package/dist/pdf/ti-register-map.js.map +1 -0
- package/dist/pdf/types.d.ts +15 -3
- package/dist/pdf/types.js +4 -1
- package/dist/pdf/types.js.map +1 -1
- package/dist/schema/assemble.d.ts +35 -3
- package/dist/schema/assemble.js +86 -13
- package/dist/schema/assemble.js.map +1 -1
- package/dist/schema/types.d.ts +21 -1
- package/dist/schema/validate.js +37 -10
- package/dist/schema/validate.js.map +1 -1
- package/dist/server.d.ts +18 -0
- package/dist/server.js +49 -3
- package/dist/server.js.map +1 -1
- package/package.json +1 -1
- package/schemas/datasheet.schema.json +17 -3
|
@@ -0,0 +1,544 @@
|
|
|
1
|
+
// L4a (Maxim register-matrix path) — extract Maxim Integrated's "Register Maps
|
|
2
|
+
// and Descriptions" table shape (e.g. MAX30102: pages 10-22), added as a NEW
|
|
3
|
+
// specialized adapter (mirrors ti-register-map.ts's parse+find shape) rather
|
|
4
|
+
// than folding into register-table.ts: the column ORDER differs from every
|
|
5
|
+
// existing adapter (REGISTER | bit region | REG ADDR | POR STATE | R/W — the
|
|
6
|
+
// bit region sits BETWEEN the name and the address, not after it), and the
|
|
7
|
+
// per-bit cells mix BME280-style bracketed spans ("MODE[2:0]") with
|
|
8
|
+
// Microchip-style bare single-bit names ("SHDN") in the SAME table, which
|
|
9
|
+
// neither existing per-bit path handles together.
|
|
10
|
+
//
|
|
11
|
+
// The header itself is a *band*: "REG"/"ADDR" and "POR"/"STATE" render as two
|
|
12
|
+
// physical lines a few px apart (sometimes with a third line above carrying
|
|
13
|
+
// "REG"/"POR" and the "REGISTER"/B7..B0/"R/W" line in between) — too close for
|
|
14
|
+
// clusterRows' 5px tolerance to merge but too far to land in one row, so this
|
|
15
|
+
// adapter folds the header band explicitly (mirrors register-table.ts's
|
|
16
|
+
// findHeaderBand approach; reimplemented locally rather than exported, since
|
|
17
|
+
// the column semantics differ enough that sharing the type isn't worth it).
|
|
18
|
+
//
|
|
19
|
+
// Real Maxim datasheets also wrap a register's own name, and occasionally a
|
|
20
|
+
// bit-field label, across the line(s) ABOVE and BELOW the data row itself (the
|
|
21
|
+
// label is vertically centered on the row, so it renders split — e.g.
|
|
22
|
+
// MAX30102's "Mode" / <data row> / "Configuration", or a label split across
|
|
23
|
+
// TWO lines on the SAME side, "A_" / "FULL_" (on the data row) / "EN"). Those
|
|
24
|
+
// wrap lines sit within a few px of each other (much closer than the gap to
|
|
25
|
+
// any unrelated content), so a chain of such lines on either side of a
|
|
26
|
+
// valid-address row is folded into that register instead of ending the table
|
|
27
|
+
// — see WRAP_GAP/WRAP_CHAIN_MAX and gatherChain below.
|
|
28
|
+
//
|
|
29
|
+
// A single page frequently carries MORE THAN ONE of these recap sections back
|
|
30
|
+
// to back (e.g. "Interrupt Enable (0x02-0x03)" then "FIFO (0x04-0x07)"), so
|
|
31
|
+
// this adapter scans every header band on a page (findHeaderBands), not just
|
|
32
|
+
// the first — each section's body is bounded below by the NEXT section's
|
|
33
|
+
// header (or the page end) so sections never bleed into each other.
|
|
34
|
+
//
|
|
35
|
+
// See wiki: cross-vendor-coverage-scorecard, pdf-parsing-pipeline.
|
|
36
|
+
import { isRegisterAddress, normalizeRegisterAddress } from "./address.js";
|
|
37
|
+
import { centerX, clusterRows } from "./table.js";
|
|
38
|
+
// name[hi:lo] | name[n] | name<hi:lo> | name<n>
|
|
39
|
+
const BITFIELD = /^(.+?)[<[](\d+)(?::(\d+))?[>\]]$/;
|
|
40
|
+
// Max vertical span (px) a folded header band's lines may sit apart.
|
|
41
|
+
const HEADER_BAND = 14;
|
|
42
|
+
// Max vertical gap (px) between consecutive lines of a wrapped name/bit-label
|
|
43
|
+
// chain. Comfortably above the ~5-6px real-world wrap gap and comfortably
|
|
44
|
+
// below the ~15px+ gap between distinct registers/sections.
|
|
45
|
+
const WRAP_GAP = 8;
|
|
46
|
+
// Max hops a chain of WRAP_GAP-sized steps may take — either to reach an
|
|
47
|
+
// anchor row (chainsToAnchor, deciding whether a row ends the table) or to
|
|
48
|
+
// gather wrap fragments into a register (gatherChain). A label occasionally
|
|
49
|
+
// wraps across MORE than one line on either side of its data row (e.g.
|
|
50
|
+
// MAX30102's interrupt-enable names split "A_" / "FULL_" (on the data row) /
|
|
51
|
+
// "EN", three lines deep).
|
|
52
|
+
const WRAP_CHAIN_MAX = 3;
|
|
53
|
+
// Max vertical gap (px) between two adjacent registers' OWN anchor rows for
|
|
54
|
+
// their (otherwise unrelated-looking) names to be considered two halves of
|
|
55
|
+
// ONE shared title — see mergeSplitTitles. Hand-verified against the real
|
|
56
|
+
// fixture: LED Pulse Amplitude's 0x0C/0x0D anchors sit 14.4px apart (must
|
|
57
|
+
// merge); Revision ID/Part ID's 0xFE/0xFF anchors sit 15.85px apart (must
|
|
58
|
+
// NOT merge, they're genuinely different registers) — 15 sits cleanly
|
|
59
|
+
// between the two.
|
|
60
|
+
const TITLE_SPLIT_GAP = 15;
|
|
61
|
+
// Wider gap tolerance used ONLY when the wrap candidate is a bare name-only
|
|
62
|
+
// line (see isNameOnly): a title's second/third physical line sits a little
|
|
63
|
+
// farther from the data row than a bit-label fragment does (hand-verified:
|
|
64
|
+
// SpO2 Configuration's "Configuration" sits 11px below its anchor — over
|
|
65
|
+
// WRAP_GAP but a genuine title line, not a section-ending decoy, which sit
|
|
66
|
+
// 14.5px+ away — see PART ID/DIE TEMPERATURE in the file header).
|
|
67
|
+
const NAME_WRAP_GAP = 12;
|
|
68
|
+
// Two glyph runs are considered part of the SAME token (joined with no
|
|
69
|
+
// space) when the gap between them is at or below this — pdfjs renders a
|
|
70
|
+
// subscript/superscript ("SpO₂") as separate horizontally-adjacent runs with
|
|
71
|
+
// an ~0px gap, versus tens of px between genuinely distinct words.
|
|
72
|
+
const GLYPH_ADJACENT_EPS = 1.5;
|
|
73
|
+
const norm = (s) => s.toLowerCase().replace(/\s+/g, "");
|
|
74
|
+
function isHeader(row) {
|
|
75
|
+
const cells = row.items.map((it) => norm(it.str));
|
|
76
|
+
return (cells.includes("register") &&
|
|
77
|
+
cells.includes("b7") &&
|
|
78
|
+
cells.includes("b0") &&
|
|
79
|
+
cells.includes("reg") &&
|
|
80
|
+
cells.includes("addr") &&
|
|
81
|
+
cells.includes("por") &&
|
|
82
|
+
cells.includes("state"));
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Find every header band on the page, folding each into one synthetic row
|
|
86
|
+
* (see file header — "REG"/"POR" and/or "ADDR"/"STATE" commonly sit a
|
|
87
|
+
* physical line away from the main "REGISTER B7..B0 R/W" line). Scanning
|
|
88
|
+
* resumes right after each matched band's folded rows, so a page carrying
|
|
89
|
+
* several recap sections back to back yields one band per section, in order.
|
|
90
|
+
*/
|
|
91
|
+
function findHeaderBands(rows) {
|
|
92
|
+
const bands = [];
|
|
93
|
+
let i = 0;
|
|
94
|
+
while (i < rows.length) {
|
|
95
|
+
let merged = [...rows[i].items];
|
|
96
|
+
let bandBottom = rows[i].y;
|
|
97
|
+
let consumedRows = 0;
|
|
98
|
+
for (let k = 0; k < 3; k++) {
|
|
99
|
+
if (isHeader({ y: rows[i].y, items: merged })) {
|
|
100
|
+
consumedRows = k + 1;
|
|
101
|
+
bands.push({ header: { y: rows[i].y, items: merged }, bandBottom });
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
const next = rows[i + k + 1];
|
|
105
|
+
if (!next || rows[i].y - next.y > HEADER_BAND)
|
|
106
|
+
break;
|
|
107
|
+
merged = merged.concat(next.items);
|
|
108
|
+
bandBottom = next.y;
|
|
109
|
+
}
|
|
110
|
+
i += consumedRows > 0 ? consumedRows : 1;
|
|
111
|
+
}
|
|
112
|
+
return bands;
|
|
113
|
+
}
|
|
114
|
+
function columnsFromHeader(header) {
|
|
115
|
+
const bitCenters = [];
|
|
116
|
+
let nameCenter;
|
|
117
|
+
let regCenter;
|
|
118
|
+
let addrCenter;
|
|
119
|
+
let porCenter;
|
|
120
|
+
let stateCenter;
|
|
121
|
+
let rwCenter;
|
|
122
|
+
for (const it of header.items) {
|
|
123
|
+
const tok = norm(it.str);
|
|
124
|
+
const bit = /^b([0-7])$/.exec(tok);
|
|
125
|
+
if (bit) {
|
|
126
|
+
bitCenters[Number(bit[1])] = centerX(it);
|
|
127
|
+
}
|
|
128
|
+
else if (tok === "register") {
|
|
129
|
+
nameCenter = centerX(it);
|
|
130
|
+
}
|
|
131
|
+
else if (tok === "reg") {
|
|
132
|
+
regCenter = centerX(it);
|
|
133
|
+
}
|
|
134
|
+
else if (tok === "addr") {
|
|
135
|
+
addrCenter = centerX(it);
|
|
136
|
+
}
|
|
137
|
+
else if (tok === "por") {
|
|
138
|
+
porCenter = centerX(it);
|
|
139
|
+
}
|
|
140
|
+
else if (tok === "state") {
|
|
141
|
+
stateCenter = centerX(it);
|
|
142
|
+
}
|
|
143
|
+
else if (tok === "r/w") {
|
|
144
|
+
rwCenter = centerX(it);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
if (nameCenter === undefined ||
|
|
148
|
+
bitCenters[7] === undefined ||
|
|
149
|
+
bitCenters[0] === undefined ||
|
|
150
|
+
regCenter === undefined ||
|
|
151
|
+
addrCenter === undefined ||
|
|
152
|
+
porCenter === undefined ||
|
|
153
|
+
stateCenter === undefined) {
|
|
154
|
+
return undefined;
|
|
155
|
+
}
|
|
156
|
+
const addrColCenter = (regCenter + addrCenter) / 2;
|
|
157
|
+
const resetColCenter = (porCenter + stateCenter) / 2;
|
|
158
|
+
return {
|
|
159
|
+
nameMax: (nameCenter + bitCenters[7]) / 2,
|
|
160
|
+
bitMax: (bitCenters[0] + addrColCenter) / 2,
|
|
161
|
+
addrMax: (addrColCenter + resetColCenter) / 2,
|
|
162
|
+
resetMax: rwCenter !== undefined ? (resetColCenter + rwCenter) / 2 : Number.POSITIVE_INFINITY,
|
|
163
|
+
bitCenters,
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
function regionOf(it, cols) {
|
|
167
|
+
const c = centerX(it);
|
|
168
|
+
if (c < cols.nameMax)
|
|
169
|
+
return "name";
|
|
170
|
+
if (c < cols.bitMax)
|
|
171
|
+
return "bit";
|
|
172
|
+
if (c < cols.addrMax)
|
|
173
|
+
return "address";
|
|
174
|
+
if (c < cols.resetMax)
|
|
175
|
+
return "reset";
|
|
176
|
+
return "other";
|
|
177
|
+
}
|
|
178
|
+
function cellsIn(row, cols, region) {
|
|
179
|
+
return row.items.filter((it) => regionOf(it, cols) === region);
|
|
180
|
+
}
|
|
181
|
+
/** True when EVERY item in the row is in the name column — a bare subtitle
|
|
182
|
+
* or caption line (e.g. "DIE TEMPERATURE", "PART ID") rather than table data.
|
|
183
|
+
*/
|
|
184
|
+
function isNameOnly(row, cols) {
|
|
185
|
+
return row.items.length > 0 && row.items.every((it) => regionOf(it, cols) === "name");
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Join a row's cells left-to-right (items already come x-sorted from
|
|
189
|
+
* clusterRows). Two cells with essentially no horizontal gap between them
|
|
190
|
+
* (see GLYPH_ADJACENT_EPS) are glued with no space — pdfjs's own split of a
|
|
191
|
+
* subscript ("SpO" + superscript "2") into separate runs, not two words —
|
|
192
|
+
* everything else gets a normal single space.
|
|
193
|
+
*/
|
|
194
|
+
function joinText(items) {
|
|
195
|
+
let out = "";
|
|
196
|
+
for (let i = 0; i < items.length; i++) {
|
|
197
|
+
const it = items[i];
|
|
198
|
+
if (i === 0) {
|
|
199
|
+
out = it.str;
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
const prev = items[i - 1];
|
|
203
|
+
const gap = it.x - (prev.x + prev.width);
|
|
204
|
+
out += (gap <= GLYPH_ADJACENT_EPS ? "" : " ") + it.str;
|
|
205
|
+
}
|
|
206
|
+
return out.replace(/\s+/g, " ").trim();
|
|
207
|
+
}
|
|
208
|
+
/** Mirrors register-table.ts's bitPosition: center a `[hi:lo]` span over the bit columns. */
|
|
209
|
+
function bitPosition(fieldCenter, width, bitCenters) {
|
|
210
|
+
let best = { msb: width - 1, lsb: 0, err: Infinity };
|
|
211
|
+
for (let msb = width - 1; msb <= 7; msb++) {
|
|
212
|
+
const lsb = msb - width + 1;
|
|
213
|
+
const hiC = bitCenters[msb];
|
|
214
|
+
const loC = bitCenters[lsb];
|
|
215
|
+
if (hiC === undefined || loC === undefined)
|
|
216
|
+
continue;
|
|
217
|
+
const spanCenter = (hiC + loC) / 2;
|
|
218
|
+
const err = Math.abs(fieldCenter - spanCenter);
|
|
219
|
+
if (err < best.err)
|
|
220
|
+
best = { msb, lsb, err };
|
|
221
|
+
}
|
|
222
|
+
return { msb: best.msb, lsb: best.lsb };
|
|
223
|
+
}
|
|
224
|
+
/** Snap a bare bit-name cell to its nearest B<n> column. */
|
|
225
|
+
function nearestBitColumn(c, bitCenters) {
|
|
226
|
+
let idx = -1;
|
|
227
|
+
let err = Infinity;
|
|
228
|
+
for (let i = 0; i <= 7; i++) {
|
|
229
|
+
if (bitCenters[i] === undefined)
|
|
230
|
+
continue;
|
|
231
|
+
const e = Math.abs(c - bitCenters[i]);
|
|
232
|
+
if (e < err) {
|
|
233
|
+
err = e;
|
|
234
|
+
idx = i;
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
return idx;
|
|
238
|
+
}
|
|
239
|
+
/**
|
|
240
|
+
* Build a register's bit fields from several cell groups (wrapped
|
|
241
|
+
* name/bit-label continuation lines on either side, plus the data row's own)
|
|
242
|
+
* in top-to-bottom order. Bracketed spans are sized from the bracket and
|
|
243
|
+
* positioned geometrically (never wrap in practice) — except a colon-less
|
|
244
|
+
* top-bit bracket ("NAME[7]") with nothing else in the register's bit region,
|
|
245
|
+
* which is Maxim's own shorthand for the whole byte rather than a literal
|
|
246
|
+
* single-bit flag (hand-verified: MAX30102's PART_ID[7] sits at the same
|
|
247
|
+
* column as REV_ID[7:0] directly above it). Bare cells snap to their nearest
|
|
248
|
+
* column and — since a long bare label can itself wrap across several lines
|
|
249
|
+
* (e.g. "PWR_" above + "RDY" below the data row, both centered on B0, or
|
|
250
|
+
* "A_" / "FULL_" / "EN" straddling it three deep) — fragments landing in the
|
|
251
|
+
* same column concatenate in the order encountered, reconstructing the
|
|
252
|
+
* original label.
|
|
253
|
+
*/
|
|
254
|
+
function collectBitFields(groups, cols) {
|
|
255
|
+
const spanFields = [];
|
|
256
|
+
const byColumn = new Map();
|
|
257
|
+
const soleCandidate = groups.flat().length === 1 ? groups.flat()[0] : undefined;
|
|
258
|
+
for (const cells of groups) {
|
|
259
|
+
for (const cell of cells) {
|
|
260
|
+
const text = cell.str.trim();
|
|
261
|
+
if (!text || text === "—" || text === "-" || /^[01]$/.test(text))
|
|
262
|
+
continue;
|
|
263
|
+
const m = BITFIELD.exec(text);
|
|
264
|
+
if (m) {
|
|
265
|
+
const name = m[1].trim();
|
|
266
|
+
const hi = Number(m[2]);
|
|
267
|
+
let width = m[3] !== undefined ? hi - Number(m[3]) + 1 : 1;
|
|
268
|
+
if (m[3] === undefined && hi === 7 && cell === soleCandidate)
|
|
269
|
+
width = 8;
|
|
270
|
+
if (!name || width < 1 || width > 8)
|
|
271
|
+
continue;
|
|
272
|
+
const pos = bitPosition(centerX(cell), width, cols.bitCenters);
|
|
273
|
+
spanFields.push({ name, msb: pos.msb, lsb: pos.lsb });
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
const idx = nearestBitColumn(centerX(cell), cols.bitCenters);
|
|
277
|
+
if (idx < 0)
|
|
278
|
+
continue;
|
|
279
|
+
const parts = byColumn.get(idx) ?? [];
|
|
280
|
+
parts.push(text);
|
|
281
|
+
byColumn.set(idx, parts);
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
const bareFields = [...byColumn.entries()].map(([idx, parts]) => ({
|
|
285
|
+
name: parts.join(""),
|
|
286
|
+
msb: idx,
|
|
287
|
+
lsb: idx,
|
|
288
|
+
}));
|
|
289
|
+
return [...spanFields, ...bareFields].sort((a, b) => b.msb - a.msb);
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* True when, starting at `body[start]` (itself not an anchor), a chain of
|
|
293
|
+
* WRAP_GAP-sized steps reaches an anchor row within WRAP_CHAIN_MAX hops. Used
|
|
294
|
+
* to tell a genuine decoy/end-of-table row apart from a wrap line that's
|
|
295
|
+
* merely farther than one hop from the register it belongs to.
|
|
296
|
+
*/
|
|
297
|
+
function chainsToAnchor(body, start, isAnchor) {
|
|
298
|
+
let cur = body[start];
|
|
299
|
+
for (let j = start + 1; j < body.length && j <= start + WRAP_CHAIN_MAX; j++) {
|
|
300
|
+
const next = body[j];
|
|
301
|
+
if (cur.y - next.y > WRAP_GAP)
|
|
302
|
+
return false;
|
|
303
|
+
if (isAnchor(next))
|
|
304
|
+
return true;
|
|
305
|
+
cur = next;
|
|
306
|
+
}
|
|
307
|
+
return false;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Gather up to WRAP_CHAIN_MAX rows of wrap fragments on one side of an anchor
|
|
311
|
+
* (step = -1 for the lines above, +1 for the lines below), stopping at the
|
|
312
|
+
* first row already consumed by another register, the first anchor, or the
|
|
313
|
+
* first gap over the applicable tolerance — WRAP_GAP normally, or the wider
|
|
314
|
+
* NAME_WRAP_GAP when the candidate is a bare name-only title line (a title's
|
|
315
|
+
* second/third physical line sits a little farther from the data row than a
|
|
316
|
+
* bit-label fragment does; see NAME_WRAP_GAP).
|
|
317
|
+
*
|
|
318
|
+
* A name-only candidate that ALSO sits within NAME_WRAP_GAP of a FURTHER
|
|
319
|
+
* anchor on the same side (i.e. it's sandwiched between two registers, e.g.
|
|
320
|
+
* MAX30102's "Mode Control" between 0x11 and 0x12) is left unclaimed here —
|
|
321
|
+
* it's a title shared by both neighbors, not a one-sided trailing/leading
|
|
322
|
+
* fragment, and is spliced in by mergeSplitTitles' between-anchors sweep
|
|
323
|
+
* instead. A candidate with no such further anchor (e.g. SpO2
|
|
324
|
+
* Configuration's trailing "Configuration", followed only by prose) is
|
|
325
|
+
* claimed normally.
|
|
326
|
+
*
|
|
327
|
+
* Returned index order always reads top-to-bottom (farthest-to-nearest above
|
|
328
|
+
* the anchor, nearest-to-farthest below it) so joining their text/bit-region
|
|
329
|
+
* content reconstructs the original label.
|
|
330
|
+
*/
|
|
331
|
+
function gatherChain(body, anchorIdx, step, isAnchor, consumed, cols) {
|
|
332
|
+
const indices = [];
|
|
333
|
+
let cur = body[anchorIdx];
|
|
334
|
+
for (let hop = 1; hop <= WRAP_CHAIN_MAX; hop++) {
|
|
335
|
+
const idx = anchorIdx + step * hop;
|
|
336
|
+
if (idx < 0 || idx >= body.length || consumed.has(idx))
|
|
337
|
+
break;
|
|
338
|
+
const candidate = body[idx];
|
|
339
|
+
const gap = step < 0 ? candidate.y - cur.y : cur.y - candidate.y;
|
|
340
|
+
const nameOnly = isNameOnly(candidate, cols);
|
|
341
|
+
const limit = nameOnly ? NAME_WRAP_GAP : WRAP_GAP;
|
|
342
|
+
if (gap > limit || isAnchor(candidate))
|
|
343
|
+
break;
|
|
344
|
+
if (nameOnly) {
|
|
345
|
+
const beyond = body[idx + step];
|
|
346
|
+
if (beyond && isAnchor(beyond)) {
|
|
347
|
+
const beyondGap = step < 0 ? beyond.y - candidate.y : candidate.y - beyond.y;
|
|
348
|
+
if (beyondGap <= NAME_WRAP_GAP)
|
|
349
|
+
break;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
indices.push(idx);
|
|
353
|
+
cur = candidate;
|
|
354
|
+
}
|
|
355
|
+
return step < 0 ? indices.reverse() : indices;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* True when a row's own name-region text sits at a DIFFERENT y than that same
|
|
359
|
+
* row's address cell — the signature of clusterRows having glued a
|
|
360
|
+
* neighboring line's fragment onto this row's cluster (see mergeSplitTitles)
|
|
361
|
+
* rather than the name genuinely belonging to this data row. A row built from
|
|
362
|
+
* a single uniform y (every real single-line row, and every synthetic test
|
|
363
|
+
* row) never trips this.
|
|
364
|
+
*/
|
|
365
|
+
function hasForeignOwnName(row, cols) {
|
|
366
|
+
const nameItems = cellsIn(row, cols, "name");
|
|
367
|
+
const addressItems = cellsIn(row, cols, "address");
|
|
368
|
+
if (nameItems.length === 0 || addressItems.length === 0)
|
|
369
|
+
return false;
|
|
370
|
+
const addressY = addressItems[0].y;
|
|
371
|
+
return nameItems.every((it) => it.y !== addressY);
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* A register whose datasheet title is split across physical lines that got
|
|
375
|
+
* attributed to a DIFFERENT adjacent register's own row (e.g. MAX30102's "LED
|
|
376
|
+
* Pulse" / "Amplitude" landing on 0x0C's and 0x0D's rows respectively via
|
|
377
|
+
* clusterRows' ordinary tolerance, rather than as wrap lines this adapter's
|
|
378
|
+
* own chain-gathering would fold together) ends up with a half-name instead
|
|
379
|
+
* of the one shared title. Two adjacent registers are merge candidates only
|
|
380
|
+
* when BOTH carry a "foreign" own-name (glued from a different y, see
|
|
381
|
+
* hasForeignOwnName) — genuinely distinct back-to-back registers (e.g.
|
|
382
|
+
* Interrupt Status 1/2) never have foreign own-names, since their names come
|
|
383
|
+
* from prefix/suffix wrap chains, not a glued same-row fragment.
|
|
384
|
+
*
|
|
385
|
+
* Two shapes trigger the merge:
|
|
386
|
+
* - the anchors sit within TITLE_SPLIT_GAP of each other (LED Pulse /
|
|
387
|
+
* Amplitude: 12.7px apart), or
|
|
388
|
+
* - every row STRICTLY BETWEEN the two anchors that isn't already claimed by
|
|
389
|
+
* a wrap chain is a bare name-only title line (Multi-LED / "Mode Control"
|
|
390
|
+
* / Registers: the middle line sits ~9.7-11px from EITHER anchor — past
|
|
391
|
+
* WRAP_GAP and NAME_WRAP_GAP both — so gatherChain never claims it, but
|
|
392
|
+
* it's still unambiguously the shared title's middle third, spliced into
|
|
393
|
+
* the combined name in y-order). A genuinely unrelated, non-name-only row
|
|
394
|
+
* sitting between the two (prose, another field) blocks the merge outright.
|
|
395
|
+
*/
|
|
396
|
+
function mergeSplitTitles(records, body, cols, consumed) {
|
|
397
|
+
for (let i = 0; i + 1 < records.length; i++) {
|
|
398
|
+
const a = records[i];
|
|
399
|
+
const b = records[i + 1];
|
|
400
|
+
if (!a.foreignName || !b.foreignName)
|
|
401
|
+
continue;
|
|
402
|
+
// Rows already folded into a's or b's own wrap chain are already
|
|
403
|
+
// accounted for in their names — skip rather than double-count or block.
|
|
404
|
+
const between = [];
|
|
405
|
+
let blocked = false;
|
|
406
|
+
for (let idx = a.rowIdx + 1; idx < b.rowIdx; idx++) {
|
|
407
|
+
if (consumed.has(idx))
|
|
408
|
+
continue;
|
|
409
|
+
const row = body[idx];
|
|
410
|
+
if (isNameOnly(row, cols)) {
|
|
411
|
+
between.push(row);
|
|
412
|
+
}
|
|
413
|
+
else {
|
|
414
|
+
blocked = true;
|
|
415
|
+
break;
|
|
416
|
+
}
|
|
417
|
+
}
|
|
418
|
+
if (blocked)
|
|
419
|
+
continue;
|
|
420
|
+
if (between.length === 0 && a.y - b.y > TITLE_SPLIT_GAP)
|
|
421
|
+
continue;
|
|
422
|
+
const an = a.reg.name.toLowerCase();
|
|
423
|
+
const bn = b.reg.name.toLowerCase();
|
|
424
|
+
if (!an || !bn || an === bn || an.includes(bn) || bn.includes(an))
|
|
425
|
+
continue;
|
|
426
|
+
const betweenNames = between.map((r) => joinText(cellsIn(r, cols, "name"))).filter(Boolean);
|
|
427
|
+
const combined = [a.reg.name, ...betweenNames, b.reg.name].filter(Boolean).join(" ").trim();
|
|
428
|
+
a.reg.name = combined;
|
|
429
|
+
b.reg.name = combined;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
/** Parse one recap section's body (below its header, above the next section's) into registers. */
|
|
433
|
+
function registersForSection(body, cols) {
|
|
434
|
+
const isAnchor = (row) => isRegisterAddress(joinText(cellsIn(row, cols, "address")));
|
|
435
|
+
const consumed = new Set();
|
|
436
|
+
const records = [];
|
|
437
|
+
for (let i = 0; i < body.length; i++) {
|
|
438
|
+
if (consumed.has(i))
|
|
439
|
+
continue;
|
|
440
|
+
const row = body[i];
|
|
441
|
+
if (!isAnchor(row)) {
|
|
442
|
+
// A bare subtitle/caption (e.g. "DIE TEMPERATURE", "PART ID") never
|
|
443
|
+
// ends the table — it carries no data of its own, and more registers
|
|
444
|
+
// routinely follow it a few lines down.
|
|
445
|
+
if (isNameOnly(row, cols))
|
|
446
|
+
continue;
|
|
447
|
+
if (chainsToAnchor(body, i, isAnchor))
|
|
448
|
+
continue; // leads into the next register
|
|
449
|
+
break; // a genuine decoy/unrelated row — ends the table body
|
|
450
|
+
}
|
|
451
|
+
const prefixIdx = gatherChain(body, i, -1, isAnchor, consumed, cols);
|
|
452
|
+
const suffixIdx = gatherChain(body, i, 1, isAnchor, consumed, cols);
|
|
453
|
+
for (const idx of prefixIdx)
|
|
454
|
+
consumed.add(idx);
|
|
455
|
+
for (const idx of suffixIdx)
|
|
456
|
+
consumed.add(idx);
|
|
457
|
+
const prefixRows = prefixIdx.map((idx) => body[idx]);
|
|
458
|
+
const suffixRows = suffixIdx.map((idx) => body[idx]);
|
|
459
|
+
const name = [
|
|
460
|
+
...prefixRows.map((r) => joinText(cellsIn(r, cols, "name"))),
|
|
461
|
+
joinText(cellsIn(row, cols, "name")),
|
|
462
|
+
...suffixRows.map((r) => joinText(cellsIn(r, cols, "name"))),
|
|
463
|
+
]
|
|
464
|
+
.filter(Boolean)
|
|
465
|
+
.join(" ")
|
|
466
|
+
.replace(/\s+/g, " ")
|
|
467
|
+
.trim();
|
|
468
|
+
// A reserved-range row ("0x13-0x17", "0x18-0x1E", ...) prints its address
|
|
469
|
+
// as two fragments straddling the anchor; only the tail ("0x17") reads as
|
|
470
|
+
// a valid single address, which would otherwise surface as a mangled
|
|
471
|
+
// single-address "RESERVED" register. Mirror the generic extractor and
|
|
472
|
+
// drop it instead (see generic-register-table).
|
|
473
|
+
if (/^reserved$/i.test(name))
|
|
474
|
+
continue;
|
|
475
|
+
const bitFields = collectBitFields([
|
|
476
|
+
...prefixRows.map((r) => cellsIn(r, cols, "bit")),
|
|
477
|
+
cellsIn(row, cols, "bit"),
|
|
478
|
+
...suffixRows.map((r) => cellsIn(r, cols, "bit")),
|
|
479
|
+
], cols);
|
|
480
|
+
const rawAddress = joinText(cellsIn(row, cols, "address"));
|
|
481
|
+
const reset = joinText(cellsIn(row, cols, "reset"));
|
|
482
|
+
records.push({
|
|
483
|
+
reg: {
|
|
484
|
+
name,
|
|
485
|
+
address: normalizeRegisterAddress(rawAddress) ?? rawAddress,
|
|
486
|
+
reset,
|
|
487
|
+
bitFields,
|
|
488
|
+
},
|
|
489
|
+
y: row.y,
|
|
490
|
+
rowIdx: i,
|
|
491
|
+
foreignName: hasForeignOwnName(row, cols),
|
|
492
|
+
});
|
|
493
|
+
}
|
|
494
|
+
mergeSplitTitles(records, body, cols, consumed);
|
|
495
|
+
return records.map((r) => r.reg);
|
|
496
|
+
}
|
|
497
|
+
/** Parse a Maxim register-matrix table from a single page, if it holds one. */
|
|
498
|
+
export function parseMaximRegisterMap(page) {
|
|
499
|
+
const rows = clusterRows(page.items);
|
|
500
|
+
const bands = findHeaderBands(rows);
|
|
501
|
+
if (bands.length === 0)
|
|
502
|
+
return undefined;
|
|
503
|
+
const registers = [];
|
|
504
|
+
for (let b = 0; b < bands.length; b++) {
|
|
505
|
+
const cols = columnsFromHeader(bands[b].header);
|
|
506
|
+
if (!cols)
|
|
507
|
+
continue;
|
|
508
|
+
const nextTop = bands[b + 1]?.header.y;
|
|
509
|
+
const body = rows
|
|
510
|
+
.filter((r) => r.y < bands[b].bandBottom && (nextTop === undefined || r.y > nextTop))
|
|
511
|
+
.sort((r1, r2) => r2.y - r1.y);
|
|
512
|
+
registers.push(...registersForSection(body, cols));
|
|
513
|
+
}
|
|
514
|
+
return { page: page.index, registers };
|
|
515
|
+
}
|
|
516
|
+
/**
|
|
517
|
+
* Accumulate the Maxim register-matrix table across pages (mirrors
|
|
518
|
+
* findTiRegisterMap's dedup shape). Unlike TI's single contiguous summary
|
|
519
|
+
* table, Maxim spreads per-register tables across many pages interleaved with
|
|
520
|
+
* prose (bit-field descriptions, examples) between them — a page with no table
|
|
521
|
+
* is simply skipped, not treated as the end of the document's table.
|
|
522
|
+
*/
|
|
523
|
+
export function findMaximRegisterMap(pages) {
|
|
524
|
+
let firstPage;
|
|
525
|
+
const registers = [];
|
|
526
|
+
const seen = new Set();
|
|
527
|
+
for (const page of pages) {
|
|
528
|
+
const frag = parseMaximRegisterMap(page);
|
|
529
|
+
if (!frag || frag.registers.length === 0)
|
|
530
|
+
continue;
|
|
531
|
+
if (firstPage === undefined)
|
|
532
|
+
firstPage = frag.page;
|
|
533
|
+
for (const r of frag.registers) {
|
|
534
|
+
if (!seen.has(r.address)) {
|
|
535
|
+
seen.add(r.address);
|
|
536
|
+
registers.push(r);
|
|
537
|
+
}
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
if (firstPage === undefined)
|
|
541
|
+
return undefined;
|
|
542
|
+
return { page: firstPage, registers };
|
|
543
|
+
}
|
|
544
|
+
//# sourceMappingURL=maxim-register-map.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"maxim-register-map.js","sourceRoot":"","sources":["../../src/pdf/maxim-register-map.ts"],"names":[],"mappings":"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"}
|
package/dist/pdf/part.js
CHANGED
|
@@ -13,6 +13,14 @@ const PART_PATTERNS = [
|
|
|
13
13
|
/\bSTM32[A-Z]\d[A-Z0-9]+\b/gi,
|
|
14
14
|
/\b(?:PCA|PCF)\d{3,4}[A-Z]?\b/gi, // PCA9555
|
|
15
15
|
/\b(?:TCA|SN65|SN74|ADS)\d{3,4}[A-Z]?\b/gi,
|
|
16
|
+
/\bTMAG\d{4}\b/gi, // TMAG5170
|
|
17
|
+
/\b(?:DHT|AHT)\d{2}\b/gi, // DHT20, AHT20
|
|
18
|
+
/\bAEAT-?\d{3,4}\b/gi, // AEAT-8811
|
|
19
|
+
/\bTLE\d{4}[A-Z0-9]*\b/gi, // TLE5014, TLE5014SP16D (ordering suffix)
|
|
20
|
+
/\bVL53L\d[A-Z0-9]*\b/gi, // VL53L3CX, VL53L1X (ST ToF)
|
|
21
|
+
/\bADXL\d{3}\b/gi, // ADXL345
|
|
22
|
+
/\bMAX\d{4,5}[A-Z]?\b/gi, // MAX30102
|
|
23
|
+
/\bMLX\d{5}[A-Z]*\b/gi, // MLX90614
|
|
16
24
|
];
|
|
17
25
|
/** The most frequently occurring vendor part token, uppercased; "" if none. */
|
|
18
26
|
export function detectPart(pages) {
|
package/dist/pdf/part.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"part.js","sourceRoot":"","sources":["../../src/pdf/part.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,gFAAgF;AAChF,+EAA+E;AAC/E,8EAA8E;AAI9E,iFAAiF;AACjF,6EAA6E;AAC7E,MAAM,aAAa,GAAsB;IACvC,qBAAqB,EAAE,yBAAyB;IAChD,wBAAwB,EAAE,qBAAqB;IAC/C,2BAA2B,EAAE,eAAe;IAC5C,mCAAmC,EAAE,eAAe;IACpD,iCAAiC,EAAE,kBAAkB;IACrD,6BAA6B;IAC7B,gCAAgC,EAAE,UAAU;IAC5C,0CAA0C;
|
|
1
|
+
{"version":3,"file":"part.js","sourceRoot":"","sources":["../../src/pdf/part.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,gFAAgF;AAChF,+EAA+E;AAC/E,8EAA8E;AAI9E,iFAAiF;AACjF,6EAA6E;AAC7E,MAAM,aAAa,GAAsB;IACvC,qBAAqB,EAAE,yBAAyB;IAChD,wBAAwB,EAAE,qBAAqB;IAC/C,2BAA2B,EAAE,eAAe;IAC5C,mCAAmC,EAAE,eAAe;IACpD,iCAAiC,EAAE,kBAAkB;IACrD,6BAA6B;IAC7B,gCAAgC,EAAE,UAAU;IAC5C,0CAA0C;IAC1C,iBAAiB,EAAE,WAAW;IAC9B,wBAAwB,EAAE,eAAe;IACzC,qBAAqB,EAAE,YAAY;IACnC,yBAAyB,EAAE,0CAA0C;IACrE,wBAAwB,EAAE,6BAA6B;IACvD,iBAAiB,EAAE,UAAU;IAC7B,wBAAwB,EAAE,WAAW;IACrC,sBAAsB,EAAE,WAAW;CACpC,CAAC;AAEF,+EAA+E;AAC/E,MAAM,UAAU,UAAU,CAAC,KAAoB;IAC7C,MAAM,IAAI,GAAG,KAAK;SACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;SAClB,IAAI,CAAC,GAAG,CAAC;SACT,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAExB,MAAM,MAAM,GAAG,IAAI,GAAG,EAAkB,CAAC;IACzC,KAAK,MAAM,OAAO,IAAI,aAAa,EAAE,CAAC;QACpC,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACvC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;YACjC,MAAM,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IAED,IAAI,IAAI,GAAG,EAAE,CAAC;IACd,IAAI,SAAS,GAAG,CAAC,CAAC;IAClB,KAAK,MAAM,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,MAAM,EAAE,CAAC;QACpC,2EAA2E;QAC3E,IAAI,KAAK,GAAG,SAAS,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7E,IAAI,GAAG,KAAK,CAAC;YACb,SAAS,GAAG,KAAK,CAAC;QACpB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
|