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.
Files changed (81) hide show
  1. package/README.md +275 -29
  2. package/dist/codegen/esp32.d.ts +11 -3
  3. package/dist/codegen/esp32.js +221 -10
  4. package/dist/codegen/esp32.js.map +1 -1
  5. package/dist/codegen/ident.d.ts +24 -2
  6. package/dist/codegen/ident.js +37 -4
  7. package/dist/codegen/ident.js.map +1 -1
  8. package/dist/codegen/index.d.ts +12 -7
  9. package/dist/codegen/index.js +17 -14
  10. package/dist/codegen/index.js.map +1 -1
  11. package/dist/codegen/lint.js +28 -8
  12. package/dist/codegen/lint.js.map +1 -1
  13. package/dist/codegen/portable-cpp.d.ts +8 -0
  14. package/dist/codegen/portable-cpp.js +281 -0
  15. package/dist/codegen/portable-cpp.js.map +1 -0
  16. package/dist/codegen/portable.d.ts +99 -3
  17. package/dist/codegen/portable.js +419 -99
  18. package/dist/codegen/portable.js.map +1 -1
  19. package/dist/codegen/stm32.d.ts +11 -3
  20. package/dist/codegen/stm32.js +156 -11
  21. package/dist/codegen/stm32.js.map +1 -1
  22. package/dist/codegen/types.d.ts +32 -0
  23. package/dist/codegen/types.js +27 -0
  24. package/dist/codegen/types.js.map +1 -1
  25. package/dist/mcp/cache.d.ts +15 -2
  26. package/dist/mcp/cache.js +32 -4
  27. package/dist/mcp/cache.js.map +1 -1
  28. package/dist/mcp/register.d.ts +17 -0
  29. package/dist/mcp/register.js +149 -21
  30. package/dist/mcp/register.js.map +1 -1
  31. package/dist/mcp/summary.js +8 -0
  32. package/dist/mcp/summary.js.map +1 -1
  33. package/dist/pdf/address.d.ts +4 -0
  34. package/dist/pdf/address.js +28 -0
  35. package/dist/pdf/address.js.map +1 -0
  36. package/dist/pdf/command.js +87 -14
  37. package/dist/pdf/command.js.map +1 -1
  38. package/dist/pdf/extract.js +23 -2
  39. package/dist/pdf/extract.js.map +1 -1
  40. package/dist/pdf/generic-register-table.d.ts +5 -0
  41. package/dist/pdf/generic-register-table.js +125 -0
  42. package/dist/pdf/generic-register-table.js.map +1 -0
  43. package/dist/pdf/index.d.ts +2 -0
  44. package/dist/pdf/index.js +2 -0
  45. package/dist/pdf/index.js.map +1 -1
  46. package/dist/pdf/interface-kind.d.ts +11 -0
  47. package/dist/pdf/interface-kind.js +18 -0
  48. package/dist/pdf/interface-kind.js.map +1 -1
  49. package/dist/pdf/manufacturer.js +39 -0
  50. package/dist/pdf/manufacturer.js.map +1 -1
  51. package/dist/pdf/maxim-register-map.d.ts +11 -0
  52. package/dist/pdf/maxim-register-map.js +544 -0
  53. package/dist/pdf/maxim-register-map.js.map +1 -0
  54. package/dist/pdf/part.js +8 -0
  55. package/dist/pdf/part.js.map +1 -1
  56. package/dist/pdf/prose-commands.d.ts +4 -0
  57. package/dist/pdf/prose-commands.js +90 -0
  58. package/dist/pdf/prose-commands.js.map +1 -0
  59. package/dist/pdf/st-bit-layout.d.ts +3 -0
  60. package/dist/pdf/st-bit-layout.js +238 -0
  61. package/dist/pdf/st-bit-layout.js.map +1 -0
  62. package/dist/pdf/ti-field-descriptions.d.ts +10 -0
  63. package/dist/pdf/ti-field-descriptions.js +87 -0
  64. package/dist/pdf/ti-field-descriptions.js.map +1 -0
  65. package/dist/pdf/ti-register-map.d.ts +5 -0
  66. package/dist/pdf/ti-register-map.js +84 -0
  67. package/dist/pdf/ti-register-map.js.map +1 -0
  68. package/dist/pdf/types.d.ts +15 -3
  69. package/dist/pdf/types.js +4 -1
  70. package/dist/pdf/types.js.map +1 -1
  71. package/dist/schema/assemble.d.ts +35 -3
  72. package/dist/schema/assemble.js +86 -13
  73. package/dist/schema/assemble.js.map +1 -1
  74. package/dist/schema/types.d.ts +21 -1
  75. package/dist/schema/validate.js +37 -10
  76. package/dist/schema/validate.js.map +1 -1
  77. package/dist/server.d.ts +18 -0
  78. package/dist/server.js +49 -3
  79. package/dist/server.js.map +1 -1
  80. package/package.json +1 -1
  81. package/schemas/datasheet.schema.json +17 -3
@@ -0,0 +1,90 @@
1
+ // L4c generalization (Phase 4) — a role-based, high-precision TEXT pass for
2
+ // command-set devices whose commands are only ever named in running prose
3
+ // rather than tabulated (e.g. the Aosong DHT20's "sending the measurement
4
+ // command 0xAC"). The Sensirion-shaped tabulated extractor (extractCommands in
5
+ // command.ts) misses these entirely, so this runs as a fallback when that one
6
+ // finds nothing. A sentence yields a command only when it carries BOTH a
7
+ // command cue ("command" / "send(ing)") AND a role keyword (trigger/
8
+ // measurement/measure, status, reset) — so a bare hex mention (an I2C
9
+ // address, an unrelated register, a status-equality check) is never mistaken
10
+ // for a command. Reliable > complete: this never invents a name or code that
11
+ // isn't anchored by both signals.
12
+ //
13
+ // Phase 4b: after the commands are found, extractCrc (command.ts) is run over
14
+ // the same pages and — if it resolves both poly and init (incl. the
15
+ // polynomial-expression and "initial value" prose forms DHT20 uses) — the CRC
16
+ // is attached to the measurement-role command only, mirroring the gating
17
+ // extractCommands already applies via isDataReturning/isMeasurement. See
18
+ // wiki: command-set-interface, cross-vendor-coverage-scorecard.
19
+ import { extractCrc } from "./command.js";
20
+ const joinText = (pages) => pages
21
+ .map((p) => p.text)
22
+ .join(" ")
23
+ .replace(/\s+/g, " ");
24
+ /** A hex command/byte token, e.g. "0xAC". */
25
+ const CODE = /0x([0-9a-f]{2,4})\b/gi;
26
+ /** A command cue: the sentence is *doing* something with a command. */
27
+ const CUE = /\bcommand\b|\bsend(?:ing)?\b/i;
28
+ /** Ordered role list — first match in this order wins. */
29
+ const ROLES = [
30
+ { re: /\btrigger\b|\bmeasurement\b|\bmeasure\b/i, name: "trigger_measurement" },
31
+ { re: /\bstatus\b/i, name: "status" },
32
+ { re: /\breset\b/i, name: "soft_reset" },
33
+ ];
34
+ const upperCode = (hex) => "0x" + hex.toUpperCase();
35
+ /** L4c fallback — extract commands that are only ever named in prose. */
36
+ export function extractProseCommands(pages) {
37
+ const text = joinText(pages);
38
+ const sentences = text.split(/\.\s+/);
39
+ const byCode = new Map();
40
+ const byName = new Map();
41
+ let last;
42
+ for (const sentence of sentences) {
43
+ const codes = [...sentence.matchAll(CODE)];
44
+ // Param sentence: "parameter" + >=2 hex bytes -> attach to the previous
45
+ // command and never itself emit a new one.
46
+ if (/\bparameter\b/i.test(sentence) && codes.length >= 2) {
47
+ if (last && !last.params) {
48
+ last.params = [upperCode(codes[0][1]), upperCode(codes[1][1])];
49
+ }
50
+ continue;
51
+ }
52
+ if (codes.length === 0 || !CUE.test(sentence))
53
+ continue;
54
+ const role = ROLES.find((r) => r.re.test(sentence));
55
+ if (!role)
56
+ continue;
57
+ // Code nearest the cue: the cue may be re-used by different command
58
+ // mentions within a sentence, so anchor to the closest hex token.
59
+ const cueIndex = CUE.exec(sentence)?.index ?? 0;
60
+ let nearest = codes[0];
61
+ let nearestDist = Math.abs((nearest.index ?? 0) - cueIndex);
62
+ for (const m of codes) {
63
+ const dist = Math.abs((m.index ?? 0) - cueIndex);
64
+ if (dist < nearestDist) {
65
+ nearest = m;
66
+ nearestDist = dist;
67
+ }
68
+ }
69
+ const code = upperCode(nearest[1]);
70
+ const existing = byCode.get(code) ?? byName.get(role.name);
71
+ if (existing) {
72
+ last = existing;
73
+ continue;
74
+ }
75
+ const command = { name: role.name, code };
76
+ byCode.set(code, command);
77
+ byName.set(role.name, command);
78
+ last = command;
79
+ }
80
+ const commands = [...byCode.values()].sort((a, b) => a.code.localeCompare(b.code));
81
+ const crc = extractCrc(pages);
82
+ if (crc) {
83
+ for (const c of commands) {
84
+ if (/measurement/i.test(c.name))
85
+ c.crc = crc;
86
+ }
87
+ }
88
+ return commands;
89
+ }
90
+ //# sourceMappingURL=prose-commands.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prose-commands.js","sourceRoot":"","sources":["../../src/pdf/prose-commands.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { BitField, PageContent } from "./types.js";
2
+ /** Map each ST register acronym to its bit fields (msb-first, deduped). */
3
+ export declare function findStBitFields(pages: PageContent[]): Map<string, BitField[]>;
@@ -0,0 +1,238 @@
1
+ // L4a (ST bit-layout path) — extract per-register bit fields from ST's
2
+ // two-stacked-table register format (Section 9 "Register description" of
3
+ // datasheets such as the LSM6DSRX): a "Table N. <ACRONYM> register" bit-layout
4
+ // table (one row of exactly 8 per-bit columns, leftmost = bit7, values either
5
+ // a field-label fragment or a reserved "0"/"1" with a footnote superscript)
6
+ // sits directly above a "Table N+1. <ACRONYM> register description" table
7
+ // whose left column (x≈102) carries the canonical field names, e.g.
8
+ // "ODR_XL[3:0]", "LPF2_XL_EN". Multi-bit fields render as per-bit indexed
9
+ // labels (ODR_XL3 ODR_XL2 ...), one per column, and a label may wrap across
10
+ // 2-3 vertical rows within a column. This adapter reconstructs the bit
11
+ // position of each canonical name by rebuilding the per-bit label from the
12
+ // bracket's own index space and looking it up in the layout table — the
13
+ // bracket range need not equal the field's physical bit position (see
14
+ // FIFO_CTRL2's UNCOPTR_RATE_[1:0]). Deterministic and narrow by design:
15
+ // prefer reliable partial coverage over guessing at layouts this doesn't
16
+ // recognize. Feeds assembleDatasheet's generic-fallback branch only (the
17
+ // specialized BME280/Microchip/TI adapters never call this). See wiki:
18
+ // st-bit-layout, generic-register-table.
19
+ import { centerX, clusterRows } from "./table.js";
20
+ // Any table title, used only to bound regions (the floor under a description
21
+ // table may be an unrelated title, e.g. "Table 50. Accelerometer ODR
22
+ // selection").
23
+ const TABLE_TITLE = /^Table\s+[\d.\-–]+\./;
24
+ // "Table 48. CTRL1_XL register" — must NOT match "... register description"
25
+ // (anchored at the end).
26
+ const LAYOUT_TITLE = /Table\s+[\d.\-–]+\.\s+([A-Z][A-Z0-9_]+)\s+register$/;
27
+ // "Table 49. CTRL1_XL register description".
28
+ const DESC_TITLE = /Table\s+[\d.\-–]+\.\s+([A-Z][A-Z0-9_]+)\s+register description$/;
29
+ // Footnote markers within the bit-layout region: a bare ordinal ("1.") or a
30
+ // bare superscript ("(1)"). Both are dropped before column assignment; a
31
+ // superscript glued onto a label (defense in depth) is stripped later too.
32
+ const FOOTNOTE_MARKER = /^\d+\.$/;
33
+ const BARE_SUPERSCRIPT = /^\(\d+\)$/;
34
+ const SUPERSCRIPT = /\(\d+\)/g;
35
+ // A canonical field name from the description table's left column:
36
+ // "ODR_XL[3:0]", "FS[1:0]_XL", "LPF2_XL_EN", "WTM8".
37
+ const CANONICAL_NAME = /^[A-Z][A-Z0-9_]*(\[\d+:\d+\])?[A-Z0-9_]*$/;
38
+ // A bracketed field name split into its prefix/hi/lo/suffix.
39
+ const BRACKET = /^([A-Z0-9_]*)\[(\d+):(\d+)\]([A-Z0-9_]*)$/;
40
+ // The description table's left column sits close to the region's leftmost
41
+ // edge (x≈102); prose starts well to the right (x≈196+).
42
+ const LEFT_COLUMN_TOLERANCE = 40;
43
+ // The bit row occupies a narrow vertical band; anything further below (e.g. a
44
+ // footnote sentence) is excluded even if it slipped past the token filter.
45
+ const BIT_ROW_BAND = 22;
46
+ // A register's description table is sometimes the last thing on its page —
47
+ // no further `Table N.` title follows to floor the region, so it would
48
+ // otherwise run all the way down into the page's running footer (a document
49
+ // ID + revision + page number, isolated from real content by a wide gap).
50
+ // Real table/prose rows are packed within ~15-25 units of each other; a gap
51
+ // this much larger marks the page-margin boundary.
52
+ const CONTENT_GAP = 60;
53
+ /** Classify each title row on a page (top-to-bottom, per `clusterRows`). */
54
+ function findTitleEvents(page) {
55
+ const events = [];
56
+ for (const row of clusterRows(page.items)) {
57
+ const joined = row.items.map((it) => it.str).join(" ");
58
+ if (!TABLE_TITLE.test(joined))
59
+ continue;
60
+ const desc = DESC_TITLE.exec(joined);
61
+ if (desc) {
62
+ events.push({ type: "desc", acronym: desc[1], y: row.y });
63
+ continue;
64
+ }
65
+ const layout = LAYOUT_TITLE.exec(joined);
66
+ if (layout) {
67
+ events.push({ type: "layout", acronym: layout[1], y: row.y });
68
+ continue;
69
+ }
70
+ events.push({ type: "other", y: row.y });
71
+ }
72
+ return events;
73
+ }
74
+ /** Build bit -> label from the bit-layout table's region. */
75
+ function buildBitMap(items) {
76
+ const tokens = items.filter((it) => {
77
+ const s = it.str.trim();
78
+ if (!s || /\s/.test(s))
79
+ return false;
80
+ if (FOOTNOTE_MARKER.test(s) || BARE_SUPERSCRIPT.test(s))
81
+ return false;
82
+ return true;
83
+ });
84
+ if (tokens.length === 0)
85
+ return new Map();
86
+ const topY = Math.max(...tokens.map((it) => it.y));
87
+ const bitRow = tokens.filter((it) => it.y > topY - BIT_ROW_BAND);
88
+ if (bitRow.length === 0)
89
+ return new Map();
90
+ const centers = bitRow.map((it) => centerX(it));
91
+ const minC = Math.min(...centers);
92
+ const maxC = Math.max(...centers);
93
+ const colW = (maxC - minC) / 7 || 1;
94
+ const byBit = new Map();
95
+ for (const it of bitRow) {
96
+ const raw = Math.round((centerX(it) - minC) / colW);
97
+ const bit = Math.min(7, Math.max(0, 7 - raw));
98
+ const list = byBit.get(bit);
99
+ if (list)
100
+ list.push(it);
101
+ else
102
+ byBit.set(bit, [it]);
103
+ }
104
+ const bitMap = new Map();
105
+ for (const [bit, list] of byBit) {
106
+ const label = list
107
+ .slice()
108
+ .sort((a, b) => b.y - a.y)
109
+ .map((it) => it.str.trim())
110
+ .join("")
111
+ .replace(SUPERSCRIPT, "");
112
+ if (label === "0" || label === "1")
113
+ continue; // reserved
114
+ bitMap.set(bit, label);
115
+ }
116
+ return bitMap;
117
+ }
118
+ /** Canonical field names from the description table's left column. */
119
+ function canonicalNames(items) {
120
+ // Restrict to identifier-shaped tokens first, then derive the left column's
121
+ // x from THOSE alone. The floor bounding this region is the next `Table N.`
122
+ // title, which in the real datasheet can trail past the description
123
+ // table's actual end into the next register's subsection heading/intro
124
+ // prose (e.g. "9.2 PIN_CTRL (02h)" at x≈42) — computing the left edge from
125
+ // every item in the region would let that stray heading (never
126
+ // identifier-shaped) drag the reference point away from the true x≈102
127
+ // name column. Distinguish the name column from the prose column by the
128
+ // item's own left edge, not its centerX — a long field name (e.g.
129
+ // "UNCOPTR_RATE_[1:0]") still starts flush at x≈102 even though its center
130
+ // drifts well past a fixed offset from the region's leftmost edge.
131
+ const candidates = items.filter((it) => CANONICAL_NAME.test(it.str.trim()));
132
+ if (candidates.length === 0)
133
+ return [];
134
+ const minLeftX = Math.min(...candidates.map((it) => it.x));
135
+ const names = [];
136
+ for (const it of candidates) {
137
+ if (Math.abs(it.x - minLeftX) > LEFT_COLUMN_TOLERANCE)
138
+ continue;
139
+ names.push(it.str.trim());
140
+ }
141
+ return names;
142
+ }
143
+ /**
144
+ * The lowest y still considered part of the description table's real content
145
+ * when no further title bounds it on the page (see `CONTENT_GAP`).
146
+ */
147
+ function contentFloor(page, descTitleY) {
148
+ const rows = clusterRows(page.items)
149
+ .filter((r) => r.y < descTitleY)
150
+ .sort((a, b) => b.y - a.y);
151
+ let prevY = descTitleY;
152
+ for (const row of rows) {
153
+ if (prevY - row.y > CONTENT_GAP)
154
+ return row.y;
155
+ prevY = row.y;
156
+ }
157
+ return -Infinity;
158
+ }
159
+ /** Clean a bracket's prefix+suffix concatenation into a field name. */
160
+ function cleanName(raw) {
161
+ return raw.replace(/_+/g, "_").replace(/^_+|_+$/g, "");
162
+ }
163
+ /** Resolve one canonical name to its bit field via the layout's bit map. */
164
+ function correlate(name, bitMap) {
165
+ const bracket = BRACKET.exec(name);
166
+ if (bracket) {
167
+ const [, prefix, hiStr, loStr, suffix] = bracket;
168
+ const hi = Number(hiStr);
169
+ const lo = Number(loStr);
170
+ const bits = [];
171
+ for (let idx = lo; idx <= hi; idx++) {
172
+ const label = `${prefix}${idx}${suffix}`;
173
+ let found;
174
+ for (const [bit, lbl] of bitMap) {
175
+ if (lbl === label) {
176
+ found = bit;
177
+ break;
178
+ }
179
+ }
180
+ if (found === undefined)
181
+ return undefined;
182
+ bits.push(found);
183
+ }
184
+ return {
185
+ name: cleanName(prefix + suffix),
186
+ msb: Math.max(...bits),
187
+ lsb: Math.min(...bits),
188
+ };
189
+ }
190
+ for (const [bit, lbl] of bitMap) {
191
+ if (lbl === name)
192
+ return { name, msb: bit, lsb: bit };
193
+ }
194
+ return undefined;
195
+ }
196
+ /** Map each ST register acronym to its bit fields (msb-first, deduped). */
197
+ export function findStBitFields(pages) {
198
+ const out = new Map();
199
+ for (const page of pages) {
200
+ const events = findTitleEvents(page);
201
+ for (let i = 0; i < events.length; i++) {
202
+ const layoutEvt = events[i];
203
+ if (layoutEvt.type !== "layout")
204
+ continue;
205
+ const descEvt = events[i + 1];
206
+ if (!descEvt ||
207
+ descEvt.type !== "desc" ||
208
+ descEvt.acronym !== layoutEvt.acronym) {
209
+ continue;
210
+ }
211
+ const nextEvt = events[i + 2];
212
+ const floor = nextEvt ? nextEvt.y : contentFloor(page, descEvt.y);
213
+ const layoutItems = page.items.filter((it) => it.y > descEvt.y && it.y < layoutEvt.y);
214
+ const descItems = page.items.filter((it) => it.y > floor && it.y < descEvt.y);
215
+ const bitMap = buildBitMap(layoutItems);
216
+ const names = canonicalNames(descItems);
217
+ const seen = new Set();
218
+ const fields = [];
219
+ for (const name of names) {
220
+ const field = correlate(name, bitMap);
221
+ if (!field)
222
+ continue;
223
+ const key = `${field.msb}:${field.lsb}`;
224
+ if (seen.has(key))
225
+ continue;
226
+ seen.add(key);
227
+ fields.push(field);
228
+ }
229
+ if (fields.length === 0)
230
+ continue;
231
+ fields.sort((a, b) => b.msb - a.msb);
232
+ if (!out.has(layoutEvt.acronym))
233
+ out.set(layoutEvt.acronym, fields);
234
+ }
235
+ }
236
+ return out;
237
+ }
238
+ //# sourceMappingURL=st-bit-layout.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"st-bit-layout.js","sourceRoot":"","sources":["../../src/pdf/st-bit-layout.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { BitField, PageContent } from "./types.js";
2
+ /** A register's extracted bit-field detail. */
3
+ export interface FieldTable {
4
+ /** 8/16/32, from the highest bit index seen (RESERVED bits included). */
5
+ width: number;
6
+ /** Named (non-RESERVED) fields, msb-first. */
7
+ bitFields: BitField[];
8
+ }
9
+ /** Map each register acronym to its Field Descriptions detail (width + fields). */
10
+ export declare function findTiFieldDescriptions(pages: PageContent[]): Map<string, FieldTable>;
@@ -0,0 +1,87 @@
1
+ // L4a (TI bit-field path) — extract per-register bit fields from Texas
2
+ // Instruments' "Register Field Descriptions" tables (e.g. TMAG5170). These sit
3
+ // separately from the register-summary table parsed by ti-register-map: each is
4
+ // titled "Table 7-N. <ACRONYM> Register Field Descriptions" and lists one field
5
+ // per row as `Bit | Field | Type | Reset | Description`, where Bit is a single
6
+ // index ("15") or a range ("14-12"). Bits reach 15, so these are 16-bit registers.
7
+ // Returns acronym -> bit fields, which ti-register-map merges into its summary.
8
+ // See wiki: register-width, generic-register-table.
9
+ import { centerX, clusterRows } from "./table.js";
10
+ // "Table 7-6. DEVICE_CONFIG Register Field Descriptions" (+ optional "(continued)").
11
+ const TITLE = /Table\s+[\d.\-–]+\.\s+([A-Z][A-Z0-9_]+)\s+Register Field Descriptions/;
12
+ // A Bit cell: a single index or an "msb-lsb" span.
13
+ const BIT = /^(\d{1,2})(?:-(\d{1,2}))?$/;
14
+ // The Bit column sits at the far left (x≈76); enum-continuation rows start at the
15
+ // Description column (x≈308), so this bound rejects them.
16
+ const BIT_X_MAX = 100;
17
+ // A TI field acronym (CONV_AVG, T_CH_EN, RESERVED). Rejects footer text like
18
+ // "Submit Document Feedback" whose page-number cell can masquerade as a Bit value.
19
+ const FIELD_NAME = /^[A-Z][A-Z0-9_]*$/;
20
+ /** A field row → its bit field, or undefined if the row isn't one. */
21
+ function fieldFromRow(row) {
22
+ const cells = [...row.items].sort((a, b) => a.x - b.x);
23
+ const bitCell = cells[0];
24
+ const nameCell = cells[1];
25
+ if (!bitCell || !nameCell || centerX(bitCell) > BIT_X_MAX)
26
+ return undefined;
27
+ const m = BIT.exec(bitCell.str.trim());
28
+ if (!m)
29
+ return undefined;
30
+ const hi = Number(m[1]);
31
+ const lo = m[2] !== undefined ? Number(m[2]) : hi;
32
+ const msb = Math.max(hi, lo);
33
+ // A register bit can't exceed 31 (a "34" is a footer page number, not a bit).
34
+ if (msb > 31)
35
+ return undefined;
36
+ const name = nameCell.str.trim();
37
+ if (!FIELD_NAME.test(name))
38
+ return undefined;
39
+ return { name, msb, lsb: Math.min(hi, lo) };
40
+ }
41
+ const widthFor = (maxBit) => maxBit >= 16 ? 32 : maxBit >= 8 ? 16 : 8;
42
+ /** Map each register acronym to its Field Descriptions detail (width + fields). */
43
+ export function findTiFieldDescriptions(pages) {
44
+ const acc = new Map();
45
+ for (const page of pages) {
46
+ // Require the field-descriptions title on the page (TI repeats it, even on
47
+ // "(continued)" pages), so unrelated pages with a stray left-column number
48
+ // never contribute fields.
49
+ let current;
50
+ for (const row of clusterRows(page.items)) {
51
+ const title = TITLE.exec(row.items.map((it) => it.str).join(" "));
52
+ if (title) {
53
+ current = title[1];
54
+ if (!acc.has(current)) {
55
+ acc.set(current, { maxBit: -1, bitFields: [], seen: new Set() });
56
+ }
57
+ continue;
58
+ }
59
+ if (!current)
60
+ continue;
61
+ const field = fieldFromRow(row);
62
+ if (!field)
63
+ continue;
64
+ const entry = acc.get(current);
65
+ if (!entry)
66
+ continue;
67
+ // RESERVED bits still count toward the register width, but aren't emitted.
68
+ entry.maxBit = Math.max(entry.maxBit, field.msb);
69
+ if (/^reserved$/i.test(field.name))
70
+ continue;
71
+ const key = `${field.msb}:${field.lsb}`;
72
+ if (entry.seen.has(key))
73
+ continue;
74
+ entry.seen.add(key);
75
+ entry.bitFields.push(field);
76
+ }
77
+ }
78
+ const out = new Map();
79
+ for (const [acronym, entry] of acc) {
80
+ if (entry.bitFields.length === 0)
81
+ continue;
82
+ entry.bitFields.sort((a, b) => b.msb - a.msb);
83
+ out.set(acronym, { width: widthFor(entry.maxBit), bitFields: entry.bitFields });
84
+ }
85
+ return out;
86
+ }
87
+ //# sourceMappingURL=ti-field-descriptions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ti-field-descriptions.js","sourceRoot":"","sources":["../../src/pdf/ti-field-descriptions.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { PageContent, RegisterTable } from "./types.js";
2
+ /** Parse the Table 7-4 fragment on a single page (rows below its header). */
3
+ export declare function parseTiRegisterMap(page: PageContent): RegisterTable | undefined;
4
+ /** Accumulate the (possibly page-continued) TI register-summary table. */
5
+ export declare function findTiRegisterMap(pages: PageContent[]): RegisterTable | undefined;
@@ -0,0 +1,84 @@
1
+ // L4a (TI register path) — extract Texas Instruments' register-summary table.
2
+ //
3
+ // TI datasheets (e.g. TMAG5170) don't use a single BME280/Microchip-style bit
4
+ // table; they list registers in a plain "Register Map" summary table
5
+ // ("Table 7-4. … Registers": Offset | Acronym | Register Name | Section) and put
6
+ // the bit fields in separate per-register sections. This adapter parses that
7
+ // summary — enough to produce a validated register list (name = acronym,
8
+ // address = the offset) that codegen turns into address #defines. Bit-field
9
+ // extraction from the per-register tables is a separate, 16-bit-aware follow-up.
10
+ import { findTiFieldDescriptions } from "./ti-field-descriptions.js";
11
+ import { clusterRows } from "./table.js";
12
+ const OFFSET = /^([0-9A-Fa-f]{1,2})h$/; // bare hex + "h": "0h", "8h", "10h"
13
+ const ACRONYM = /^[A-Z][A-Z0-9_]+$/; // register acronym: DEVICE_CONFIG, X_CH_RESULT
14
+ const norm = (s) => s.toLowerCase().replace(/\s+/g, "");
15
+ function isHeader(row) {
16
+ const cells = row.items.map((it) => norm(it.str));
17
+ return cells.includes("offset") && cells.includes("acronym");
18
+ }
19
+ /** "0h"/"Ah"/"10h" -> "0x00"/"0x0A"/"0x10". */
20
+ function normalizeAddress(raw) {
21
+ const m = OFFSET.exec(raw);
22
+ return m ? `0x${m[1].toUpperCase().padStart(2, "0")}` : raw;
23
+ }
24
+ /** Parse the Table 7-4 fragment on a single page (rows below its header). */
25
+ export function parseTiRegisterMap(page) {
26
+ const rows = clusterRows(page.items);
27
+ const header = rows.find(isHeader);
28
+ if (!header)
29
+ return undefined;
30
+ const below = rows.filter((r) => r.y < header.y).sort((a, b) => b.y - a.y);
31
+ const registers = [];
32
+ for (const row of below) {
33
+ const toks = row.items.map((it) => it.str.trim()).filter(Boolean);
34
+ // A register row is `<offset> <ACRONYM> …`. Anything else (prose, the
35
+ // "0h = 1x …" bit-value decoys whose 2nd token is "=") ends the table.
36
+ if (toks.length < 2 || !OFFSET.test(toks[0]) || !ACRONYM.test(toks[1])) {
37
+ break;
38
+ }
39
+ registers.push({
40
+ name: toks[1],
41
+ address: normalizeAddress(toks[0]),
42
+ reset: "",
43
+ bitFields: [],
44
+ });
45
+ }
46
+ return { page: page.index, registers };
47
+ }
48
+ /** Accumulate the (possibly page-continued) TI register-summary table. */
49
+ export function findTiRegisterMap(pages) {
50
+ let firstPage;
51
+ const registers = [];
52
+ const seen = new Set();
53
+ for (const page of pages) {
54
+ const frag = parseTiRegisterMap(page);
55
+ if (frag && frag.registers.length > 0) {
56
+ if (firstPage === undefined)
57
+ firstPage = frag.page;
58
+ for (const r of frag.registers) {
59
+ if (!seen.has(r.address)) {
60
+ seen.add(r.address);
61
+ registers.push(r);
62
+ }
63
+ }
64
+ }
65
+ else if (firstPage !== undefined) {
66
+ break; // the summary table ended on the previous page
67
+ }
68
+ }
69
+ if (firstPage === undefined)
70
+ return undefined;
71
+ // Enrich the summary with per-register bit fields from the separate "Register
72
+ // Field Descriptions" tables (16-bit registers — see ti-field-descriptions and
73
+ // register-width). Registers without a field table stay address-only (width 8).
74
+ const detail = findTiFieldDescriptions(pages);
75
+ for (const r of registers) {
76
+ const table = detail.get(r.name);
77
+ if (table) {
78
+ r.width = table.width;
79
+ r.bitFields = table.bitFields;
80
+ }
81
+ }
82
+ return { page: firstPage, registers };
83
+ }
84
+ //# sourceMappingURL=ti-register-map.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ti-register-map.js","sourceRoot":"","sources":["../../src/pdf/ti-register-map.ts"],"names":[],"mappings":"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"}
@@ -19,7 +19,15 @@ export interface PageContent {
19
19
  /** Whitespace-normalized concatenation of the page's text runs. */
20
20
  text: string;
21
21
  items: PositionedText[];
22
- /** Whether the page paints a raster image (a "scanned" signal). */
22
+ /**
23
+ * Whether the page paints a raster image (a "scanned" signal).
24
+ *
25
+ * Lazily computed: only meaningful for sparse-text pages, i.e. exactly
26
+ * the pages classifyPage() consults it for (textLength < MIN_TEXT_CHARS).
27
+ * On a text-rich page this is always `false`, regardless of whether the
28
+ * page actually paints an image — the extractor skips the operator-list
29
+ * walk there because nothing reads the value.
30
+ */
23
31
  hasImage: boolean;
24
32
  }
25
33
  /** Minimal per-page signal the classifier needs — kept PDF-free so it is pure. */
@@ -36,9 +44,9 @@ export type PageMap = Record<string, number[]>;
36
44
  /** One bit field within a register, positioned by absolute bit index. */
37
45
  export interface BitField {
38
46
  name: string;
39
- /** Most-significant bit index within the register (0-7). */
47
+ /** Most-significant bit index within the register (0 .. width-1). */
40
48
  msb: number;
41
- /** Least-significant bit index within the register (0-7). */
49
+ /** Least-significant bit index within the register (0 .. width-1). */
42
50
  lsb: number;
43
51
  }
44
52
  /** A single register row reconstructed from a memory-map table. */
@@ -48,8 +56,12 @@ export interface Register {
48
56
  address: string;
49
57
  /** Verbatim reset/default cell, e.g. "0x00", "0x60", "individual". */
50
58
  reset: string;
59
+ /** Register width in bits (8/16/32); absent ⇒ 8. Bounds bit-field indices/reset. */
60
+ width?: number;
51
61
  bitFields: BitField[];
52
62
  }
63
+ /** Register width in bits, defaulting to 8 when unspecified. */
64
+ export declare function registerWidth(r: Register): number;
53
65
  /** The register map extracted from one table. */
54
66
  export interface RegisterTable {
55
67
  /** 1-based page the table was found on. */
package/dist/pdf/types.js CHANGED
@@ -1,3 +1,6 @@
1
1
  // Shared types for the PDF parsing pipeline (L1 format detection + L2 page map).
2
- export {};
2
+ /** Register width in bits, defaulting to 8 when unspecified. */
3
+ export function registerWidth(r) {
4
+ return r.width ?? 8;
5
+ }
3
6
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/pdf/types.ts"],"names":[],"mappings":"AAAA,iFAAiF"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/pdf/types.ts"],"names":[],"mappings":"AAAA,iFAAiF;AAyEjF,gEAAgE;AAChE,MAAM,UAAU,aAAa,CAAC,CAAW;IACvC,OAAO,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;AACtB,CAAC"}