@depz/sensor-sdk 0.5.0 → 0.6.0

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 (55) hide show
  1. package/README.md +6 -3
  2. package/dist/dataset.d.ts.map +1 -1
  3. package/dist/dataset.js +15 -7
  4. package/dist/dataset.js.map +1 -1
  5. package/dist/discovery.d.ts.map +1 -1
  6. package/dist/discovery.js +3 -0
  7. package/dist/discovery.js.map +1 -1
  8. package/dist/index.d.ts +7 -0
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +7 -0
  11. package/dist/index.js.map +1 -1
  12. package/dist/protocol/common.d.ts +6 -4
  13. package/dist/protocol/common.d.ts.map +1 -1
  14. package/dist/protocol/common.js +6 -4
  15. package/dist/protocol/common.js.map +1 -1
  16. package/dist/protocol/identity.d.ts +1 -1
  17. package/dist/protocol/identity.d.ts.map +1 -1
  18. package/dist/protocol/identity.js +1 -0
  19. package/dist/protocol/identity.js.map +1 -1
  20. package/dist/protocol/tmf8829.d.ts +113 -0
  21. package/dist/protocol/tmf8829.d.ts.map +1 -0
  22. package/dist/protocol/tmf8829.js +195 -0
  23. package/dist/protocol/tmf8829.js.map +1 -0
  24. package/dist/protocol/usb-ids.d.ts.map +1 -1
  25. package/dist/protocol/usb-ids.js +1 -0
  26. package/dist/protocol/usb-ids.js.map +1 -1
  27. package/dist/sensors/tmf8829/builder.d.ts +61 -0
  28. package/dist/sensors/tmf8829/builder.d.ts.map +1 -0
  29. package/dist/sensors/tmf8829/builder.js +175 -0
  30. package/dist/sensors/tmf8829/builder.js.map +1 -0
  31. package/dist/sensors/tmf8829/clock.d.ts +76 -0
  32. package/dist/sensors/tmf8829/clock.d.ts.map +1 -0
  33. package/dist/sensors/tmf8829/clock.js +166 -0
  34. package/dist/sensors/tmf8829/clock.js.map +1 -0
  35. package/dist/sensors/tmf8829/config.d.ts +22 -0
  36. package/dist/sensors/tmf8829/config.d.ts.map +1 -0
  37. package/dist/sensors/tmf8829/config.js +82 -0
  38. package/dist/sensors/tmf8829/config.js.map +1 -0
  39. package/dist/sensors/tmf8829/firmware-asset.d.ts +3 -0
  40. package/dist/sensors/tmf8829/firmware-asset.d.ts.map +1 -0
  41. package/dist/sensors/tmf8829/firmware-asset.js +7 -0
  42. package/dist/sensors/tmf8829/firmware-asset.js.map +1 -0
  43. package/dist/sensors/tmf8829/firmware-license.d.ts +3 -0
  44. package/dist/sensors/tmf8829/firmware-license.d.ts.map +1 -0
  45. package/dist/sensors/tmf8829/firmware-license.js +5 -0
  46. package/dist/sensors/tmf8829/firmware-license.js.map +1 -0
  47. package/dist/sensors/tmf8829/frames.d.ts +79 -0
  48. package/dist/sensors/tmf8829/frames.d.ts.map +1 -0
  49. package/dist/sensors/tmf8829/frames.js +190 -0
  50. package/dist/sensors/tmf8829/frames.js.map +1 -0
  51. package/dist/sensors/tmf8829/tmf8829.d.ts +144 -0
  52. package/dist/sensors/tmf8829/tmf8829.d.ts.map +1 -0
  53. package/dist/sensors/tmf8829/tmf8829.js +473 -0
  54. package/dist/sensors/tmf8829/tmf8829.js.map +1 -0
  55. package/package.json +1 -1
@@ -0,0 +1,195 @@
1
+ /**
2
+ * TMF8829 SPI register-bridge wire codecs (contracts/14_SENSOR_TMF8829.md §2).
3
+ * Mirrors the Python reference `depz_sensor_sdk.protocol.tmf8829`.
4
+ *
5
+ * Same command numbering as the VL53 bridges (0x32/0x33/0x35/0x36/0x37) but
6
+ * TMF8829 payloads: an 8-bit register address and self-sized frames.
7
+ */
8
+ export var Tmf8829Cmd;
9
+ (function (Tmf8829Cmd) {
10
+ Tmf8829Cmd[Tmf8829Cmd["ReadReg"] = 50] = "ReadReg";
11
+ Tmf8829Cmd[Tmf8829Cmd["WriteReg"] = 51] = "WriteReg";
12
+ Tmf8829Cmd[Tmf8829Cmd["StartStream"] = 53] = "StartStream";
13
+ Tmf8829Cmd[Tmf8829Cmd["StopStream"] = 54] = "StopStream";
14
+ Tmf8829Cmd[Tmf8829Cmd["GetInfo"] = 55] = "GetInfo";
15
+ })(Tmf8829Cmd || (Tmf8829Cmd = {}));
16
+ export var Tmf8829Rpt;
17
+ (function (Tmf8829Rpt) {
18
+ Tmf8829Rpt[Tmf8829Rpt["RegData"] = 145] = "RegData";
19
+ Tmf8829Rpt[Tmf8829Rpt["Info"] = 146] = "Info";
20
+ Tmf8829Rpt[Tmf8829Rpt["Frame"] = 147] = "Frame";
21
+ Tmf8829Rpt[Tmf8829Rpt["Event"] = 148] = "Event";
22
+ })(Tmf8829Rpt || (Tmf8829Rpt = {}));
23
+ /** RPT_TMF_EVENT.code */
24
+ export var Tmf8829EventCode;
25
+ (function (Tmf8829EventCode) {
26
+ /** MOTION/PROXIMITY interrupt, no frame; its bits already cleared. */
27
+ Tmf8829EventCode[Tmf8829EventCode["Int"] = 0] = "Int";
28
+ /** Frame header refused, frame not read (expected once on STOP mid histogram dump). */
29
+ Tmf8829EventCode[Tmf8829EventCode["BadHeader"] = 1] = "BadHeader";
30
+ })(Tmf8829EventCode || (Tmf8829EventCode = {}));
31
+ export const TMF8829_READ_MAX = 1024;
32
+ export const TMF8829_WRITE_MAX = 1023;
33
+ export const TMF8829_CHUNK_MAX = 1024;
34
+ export const TMF8829_INT_RESULTS = 0x01;
35
+ export const TMF8829_INT_MOTION = 0x02;
36
+ export const TMF8829_INT_PROXIMITY = 0x04;
37
+ export const TMF8829_INT_HISTOGRAMS = 0x08;
38
+ export const TMF8829_INT_MASK_ALL = 0x0f;
39
+ /** TMF_START_STREAM flags: emit the ref-SPAD frame before each results frame. */
40
+ export const TMF8829_SF_REF_FRAME = 0x01;
41
+ export function packTmf8829ReadReg(addr, length) {
42
+ if (!Number.isInteger(addr) || addr < 0 || addr > 0xff)
43
+ throw new RangeError("addr must be 0..255");
44
+ if (!Number.isInteger(length) || length < 1 || length > TMF8829_READ_MAX) {
45
+ throw new RangeError(`length must be 1..${TMF8829_READ_MAX}`);
46
+ }
47
+ return Uint8Array.of(addr, length & 0xff, length >> 8);
48
+ }
49
+ export function packTmf8829WriteReg(addr, data) {
50
+ if (!Number.isInteger(addr) || addr < 0 || addr > 0xff)
51
+ throw new RangeError("addr must be 0..255");
52
+ if (data.length < 1 || data.length > TMF8829_WRITE_MAX) {
53
+ throw new RangeError(`data must be 1..${TMF8829_WRITE_MAX} bytes`);
54
+ }
55
+ const out = new Uint8Array(1 + data.length);
56
+ out[0] = addr;
57
+ out.set(data, 1);
58
+ return out;
59
+ }
60
+ export function packTmf8829StartStream(intMask, flags = 0) {
61
+ if (!Number.isInteger(intMask) || intMask < 1 || intMask > TMF8829_INT_MASK_ALL) {
62
+ throw new RangeError("intMask must be a non-zero subset of 0x0F");
63
+ }
64
+ if (flags & ~TMF8829_SF_REF_FRAME)
65
+ throw new RangeError("flags: only SF_REF_FRAME (0x01) is defined");
66
+ return Uint8Array.of(intMask, flags);
67
+ }
68
+ function view(b) {
69
+ return new DataView(b.buffer, b.byteOffset, b.byteLength);
70
+ }
71
+ export function unpackTmf8829RegData(p) {
72
+ if (p.length < 9)
73
+ throw new RangeError(`RPT_TMF_REG_DATA: need ≥9 bytes, got ${p.length}`);
74
+ if (p[0] !== Tmf8829Cmd.ReadReg) {
75
+ throw new RangeError(`RPT_TMF_REG_DATA: echoed cmd 0x${p[0].toString(16)}, expected 0x32`);
76
+ }
77
+ return { timestampUs: view(p).getBigUint64(1, true), data: p.slice(9) };
78
+ }
79
+ export function unpackTmf8829Info(p) {
80
+ if (p.length < 25)
81
+ throw new RangeError(`RPT_TMF_INFO: expected 25 bytes, got ${p.length}`);
82
+ const v = view(p);
83
+ return {
84
+ intEdges: v.getUint32(0, true),
85
+ frames: v.getUint32(4, true),
86
+ framesAborted: v.getUint32(8, true),
87
+ frameErrors: v.getUint32(12, true),
88
+ spiTimeouts: v.getUint32(16, true),
89
+ intLevel: p[20],
90
+ streaming: p[21] !== 0,
91
+ intMask: p[22],
92
+ lastIntStatus: p[23],
93
+ lastFifoStatus: p[24],
94
+ };
95
+ }
96
+ export function unpackTmf8829FrameChunk(p) {
97
+ if (p.length < 21)
98
+ throw new RangeError(`RPT_TMF_FRAME: need ≥21 bytes, got ${p.length}`);
99
+ const v = view(p);
100
+ return {
101
+ timestampUs: v.getBigUint64(0, true),
102
+ fullSize: v.getUint16(8, true),
103
+ offset: v.getUint16(10, true),
104
+ frameSeq: p[12],
105
+ edgeUs: v.getBigUint64(13, true),
106
+ data: p.slice(21),
107
+ };
108
+ }
109
+ export function unpackTmf8829Event(p) {
110
+ if (p.length < 12)
111
+ throw new RangeError(`RPT_TMF_EVENT: expected 12 bytes, got ${p.length}`);
112
+ return {
113
+ timestampUs: view(p).getBigUint64(0, true),
114
+ intStatus: p[8],
115
+ code: p[9],
116
+ frameId: p[10],
117
+ fifoStatus: p[11],
118
+ };
119
+ }
120
+ /**
121
+ * Rebuilds frames from RPT_TMF_FRAME chunks (contract 14 §2): reset on offset
122
+ * 0; append only a chunk of the same frame_seq at the expected offset;
123
+ * complete at full_size. Never stitches chunks of different frame_seq.
124
+ * `seqGaps` counts frames the bridge dropped (frame_seq jumps).
125
+ */
126
+ export class Tmf8829FrameReassembler {
127
+ completed = 0;
128
+ discarded = 0;
129
+ seqGaps = 0;
130
+ buf = null;
131
+ filled = 0;
132
+ head = null;
133
+ nextSeq = null;
134
+ /** Forget everything — call at every stream start (frame_seq restarts at 0). */
135
+ reset() {
136
+ this.completed = 0;
137
+ this.discarded = 0;
138
+ this.seqGaps = 0;
139
+ this.buf = null;
140
+ this.filled = 0;
141
+ this.head = null;
142
+ this.nextSeq = null;
143
+ }
144
+ drop() {
145
+ this.head = null;
146
+ this.buf = null;
147
+ this.filled = 0;
148
+ }
149
+ feed(chunk) {
150
+ if (chunk.offset === 0) {
151
+ if (this.head !== null)
152
+ this.discarded += 1; // the previous frame never completed
153
+ if (this.nextSeq !== null && chunk.frameSeq !== this.nextSeq) {
154
+ this.seqGaps += (chunk.frameSeq - this.nextSeq) & 0xff;
155
+ }
156
+ this.nextSeq = (chunk.frameSeq + 1) & 0xff;
157
+ this.head = chunk;
158
+ this.buf = new Uint8Array(Math.max(chunk.fullSize, chunk.data.length));
159
+ this.buf.set(chunk.data, 0);
160
+ this.filled = chunk.data.length;
161
+ }
162
+ else if (this.head !== null &&
163
+ chunk.frameSeq === this.head.frameSeq &&
164
+ chunk.fullSize === this.head.fullSize &&
165
+ chunk.offset === this.filled &&
166
+ this.filled + chunk.data.length <= this.buf.length) {
167
+ this.buf.set(chunk.data, this.filled);
168
+ this.filled += chunk.data.length;
169
+ }
170
+ else {
171
+ if (this.head !== null)
172
+ this.discarded += 1;
173
+ this.drop();
174
+ return null;
175
+ }
176
+ const head = this.head;
177
+ if (this.filled === head.fullSize) {
178
+ const frame = {
179
+ timestampUs: head.timestampUs,
180
+ edgeUs: head.edgeUs,
181
+ frameSeq: head.frameSeq,
182
+ data: this.buf.subarray(0, this.filled),
183
+ };
184
+ this.drop();
185
+ this.completed += 1;
186
+ return frame;
187
+ }
188
+ if (this.filled > head.fullSize) {
189
+ this.discarded += 1;
190
+ this.drop();
191
+ }
192
+ return null;
193
+ }
194
+ }
195
+ //# sourceMappingURL=tmf8829.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tmf8829.js","sourceRoot":"","sources":["../../src/protocol/tmf8829.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"usb-ids.d.ts","sourceRoot":"","sources":["../../src/protocol/usb-ids.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,4DAA4D;AAC5D,eAAO,MAAM,QAAQ,OAAS,CAAC;AAE/B;;;GAGG;AACH,eAAO,MAAM,OAAO,OAAS,CAAC;AAC9B,eAAO,MAAM,OAAO,QAAS,CAAC;AAE9B;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,QAAQ,CAAC;AACzC,eAAO,MAAM,mBAAmB,QAAQ,CAAC;AAEzC,2CAA2C;AAC3C,MAAM,WAAW,YAAY;IAC3B,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;CAC/B;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAiBlE,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAMtG;AAED,4EAA4E;AAC5E,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,YAAY,GAAG,IAAI,CAG9E;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC9B,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC7B,MAAM,GAAG,IAAI,CAKf"}
1
+ {"version":3,"file":"usb-ids.d.ts","sourceRoot":"","sources":["../../src/protocol/usb-ids.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAEhD,4DAA4D;AAC5D,eAAO,MAAM,QAAQ,OAAS,CAAC;AAE/B;;;GAGG;AACH,eAAO,MAAM,OAAO,OAAS,CAAC;AAC9B,eAAO,MAAM,OAAO,QAAS,CAAC;AAE9B;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,QAAQ,CAAC;AACzC,eAAO,MAAM,mBAAmB,QAAQ,CAAC;AAEzC,2CAA2C;AAC3C,MAAM,WAAW,YAAY;IAC3B,iCAAiC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;CAC/B;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAkBlE,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAMtG;AAED,4EAA4E;AAC5E,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,YAAY,GAAG,IAAI,CAG9E;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAC1B,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,EAC9B,GAAG,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC7B,MAAM,GAAG,IAAI,CAKf"}
@@ -44,6 +44,7 @@ export const DEPZ_USB_MODELS = {
44
44
  0xed49: { name: "vl53l7cx", sensorType: null }, // 60745
45
45
  0xed4a: { name: "vl53l7ch", sensorType: null }, // 60746
46
46
  0xed4b: { name: "vl53l8cx", sensorType: "vl53l8" }, // 60747 — VL53L8CX production PID, verified on hw: 1bcf:ed4b
47
+ 0xed4c: { name: "tmf8829", sensorType: "tmf8829" }, // 60748 — TMF8829 dToF (catalog p_TM88)
47
48
  0xee08: { name: "bno086", sensorType: "bno086" }, // 60936 — verified on hw: 1bcf:ee08
48
49
  0xee09: { name: "bno085", sensorType: null }, // 60937
49
50
  0xee0a: { name: "bno055", sensorType: null }, // 60938
@@ -1 +1 @@
1
- {"version":3,"file":"usb-ids.js","sourceRoot":"","sources":["../../src/protocol/usb-ids.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"usb-ids.js","sourceRoot":"","sources":["../../src/protocol/usb-ids.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Frames in stream order → measurements (contracts/14_SENSOR_TMF8829.md §6).
3
+ * Mirrors the Python reference `depz_sensor_sdk.tmf8829.builder`.
4
+ */
5
+ import { Tmf8829CaptureTimer, Tmf8829SensorClock, type Tmf8829FrameTime } from "./clock.js";
6
+ import { type Tmf8829FrameInfo, type Tmf8829HistogramFrame, type Tmf8829PixelResults } from "./frames.js";
7
+ /**
8
+ * One measurement: its results frame (8x8, 16x16) or both half-frames (32x32,
9
+ * 48x32) merged, with the histogram / ref-SPAD frames before it.
10
+ */
11
+ export interface Tmf8829Measurement {
12
+ /** Capture time, MCU µs (floor mean of the half-frame captures). */
13
+ timestampUs: number;
14
+ /** TMF8829_FT_* of all its results frames. */
15
+ flags: number;
16
+ fpMode: number;
17
+ fNumber: number;
18
+ rows: number;
19
+ cols: number;
20
+ /** Raw sensor integers. */
21
+ results: Tmf8829PixelResults;
22
+ /** Clock-corrected mm, flat [peak][row][col] (null without peaks). */
23
+ distanceMm: Float64Array | null;
24
+ /** Clock ratio the distances were corrected with (Q16). */
25
+ ratioQ16: number;
26
+ frames: Tmf8829FrameInfo[];
27
+ times: Tmf8829FrameTime[];
28
+ histograms: Tmf8829HistogramFrame[];
29
+ /** 65 B each, zero pre-header. */
30
+ refFrames: Uint8Array[];
31
+ /** What went wrong since the previous measurement, human-readable. */
32
+ problems: string[];
33
+ /** Sensor die temperature (header byte 0 of the last frame), °C. */
34
+ temperatureC: number;
35
+ }
36
+ /** Raw distances → mm, clock-corrected (×ratio; ÷4 for 0.25 mm units). */
37
+ export declare function tmf8829DistanceMm(results: Tmf8829PixelResults, ratio: number, inMm: boolean): Float64Array | null;
38
+ /**
39
+ * Histogram frames between two results frames belong to the second; a
40
+ * ref-SPAD frame comes right before its results frame. Call `reset()` at
41
+ * every stream start: the clock model and T1 are per stream.
42
+ */
43
+ export declare class Tmf8829MeasurementBuilder {
44
+ readonly clock: Tmf8829SensorClock;
45
+ readonly timer: Tmf8829CaptureTimer;
46
+ parseErrors: number;
47
+ private pending;
48
+ private hist;
49
+ private refs;
50
+ private half;
51
+ private problems;
52
+ reset(): void;
53
+ /**
54
+ * One frame with the MCU time of its header read and its INT edge (0 =
55
+ * none) → the measurement it completes, or null. `raw` is copied.
56
+ */
57
+ add(rawIn: Uint8Array, timestampUs: number, edgeUs?: number): Tmf8829Measurement | null;
58
+ }
59
+ /** Contract 09 `tmf8829` record value of a measurement (distances rounded to 0.1 mm). */
60
+ export declare function tmf8829RecordValue(m: Tmf8829Measurement): Record<string, unknown>;
61
+ //# sourceMappingURL=builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../../src/sensors/tmf8829/builder.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC5F,OAAO,EAUL,KAAK,gBAAgB,EACrB,KAAK,qBAAqB,EAC1B,KAAK,mBAAmB,EACzB,MAAM,aAAa,CAAC;AAErB;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,oEAAoE;IACpE,WAAW,EAAE,MAAM,CAAC;IACpB,8CAA8C;IAC9C,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,2BAA2B;IAC3B,OAAO,EAAE,mBAAmB,CAAC;IAC7B,sEAAsE;IACtE,UAAU,EAAE,YAAY,GAAG,IAAI,CAAC;IAChC,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,UAAU,EAAE,qBAAqB,EAAE,CAAC;IACpC,kCAAkC;IAClC,SAAS,EAAE,UAAU,EAAE,CAAC;IACxB,sEAAsE;IACtE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,oEAAoE;IACpE,YAAY,EAAE,MAAM,CAAC;CACtB;AAED,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,mBAAmB,EAC5B,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,OAAO,GACZ,YAAY,GAAG,IAAI,CAQrB;AAED;;;;GAIG;AACH,qBAAa,yBAAyB;IACpC,QAAQ,CAAC,KAAK,qBAA4B;IAC1C,QAAQ,CAAC,KAAK,sBAAuC;IACrD,WAAW,SAAK;IAChB,OAAO,CAAC,OAAO,CAA6C;IAC5D,OAAO,CAAC,IAAI,CAA+B;IAC3C,OAAO,CAAC,IAAI,CAAoB;IAChC,OAAO,CAAC,IAAI,CAA0E;IACtF,OAAO,CAAC,QAAQ,CAAgB;IAEhC,KAAK,IAAI,IAAI;IAWb;;;OAGG;IACH,GAAG,CAAC,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,SAAI,GAAG,kBAAkB,GAAG,IAAI;CA0GnF;AAED,yFAAyF;AACzF,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAiBjF"}
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Frames in stream order → measurements (contracts/14_SENSOR_TMF8829.md §6).
3
+ * Mirrors the Python reference `depz_sensor_sdk.tmf8829.builder`.
4
+ */
5
+ import { Tmf8829CaptureTimer, Tmf8829SensorClock } from "./clock.js";
6
+ import { TMF8829_FID_HISTOGRAMS, TMF8829_FID_REF_SPAD, TMF8829_FID_RESULTS, TMF8829_FP_GRID, TMF8829_LAYOUT_SUBFRAME, mergeTmf8829Halves, parseTmf8829Frame, parseTmf8829Results, tmf8829FrameProblems, } from "./frames.js";
7
+ /** Raw distances → mm, clock-corrected (×ratio; ÷4 for 0.25 mm units). */
8
+ export function tmf8829DistanceMm(results, ratio, inMm) {
9
+ if (results.distance === null)
10
+ return null;
11
+ const out = new Float64Array(results.distance.length);
12
+ for (let i = 0; i < out.length; i++) {
13
+ const d = results.distance[i] * ratio;
14
+ out[i] = inMm ? d : d / 4;
15
+ }
16
+ return out;
17
+ }
18
+ /**
19
+ * Histogram frames between two results frames belong to the second; a
20
+ * ref-SPAD frame comes right before its results frame. Call `reset()` at
21
+ * every stream start: the clock model and T1 are per stream.
22
+ */
23
+ export class Tmf8829MeasurementBuilder {
24
+ clock = new Tmf8829SensorClock();
25
+ timer = new Tmf8829CaptureTimer(this.clock);
26
+ parseErrors = 0;
27
+ pending = [];
28
+ hist = [];
29
+ refs = [];
30
+ half = null;
31
+ problems = [];
32
+ reset() {
33
+ this.clock.reset();
34
+ this.timer.reset();
35
+ this.pending = [];
36
+ this.hist = [];
37
+ this.refs = [];
38
+ this.half = null;
39
+ this.problems = [];
40
+ this.parseErrors = 0;
41
+ }
42
+ /**
43
+ * One frame with the MCU time of its header read and its INT edge (0 =
44
+ * none) → the measurement it completes, or null. `raw` is copied.
45
+ */
46
+ add(rawIn, timestampUs, edgeUs = 0) {
47
+ const raw = rawIn.slice();
48
+ let f;
49
+ try {
50
+ f = parseTmf8829Frame(raw);
51
+ }
52
+ catch (e) {
53
+ this.parseErrors += 1;
54
+ this.problems.push(e instanceof Error ? e.message : String(e));
55
+ return null;
56
+ }
57
+ if (f.kind === TMF8829_FID_REF_SPAD) {
58
+ this.pending.push([f, raw]); // zero pre-header: no clock pair
59
+ return null;
60
+ }
61
+ if (f.kind !== TMF8829_FID_RESULTS && f.kind !== TMF8829_FID_HISTOGRAMS) {
62
+ this.parseErrors += 1;
63
+ this.problems.push(`frame id 0x${f.id.toString(16).toUpperCase().padStart(2, "0")}: unknown kind`);
64
+ return null;
65
+ }
66
+ const flags = this.clock.add(timestampUs, f.systick);
67
+ const bad = tmf8829FrameProblems(f);
68
+ if (bad.length) {
69
+ this.problems.push(`frame id=0x${f.id.toString(16).toUpperCase().padStart(2, "0")} fN=${f.fNumber} ${f.size} B: ${bad.join(", ")}`);
70
+ }
71
+ if (f.kind === TMF8829_FID_HISTOGRAMS) {
72
+ this.timer.histograms();
73
+ this.pending.push([f, raw]);
74
+ return null;
75
+ }
76
+ const t = this.timer.results(f.fpMode, f.systick, f.t0Integration, f.t1Integration, timestampUs, edgeUs, flags);
77
+ for (const [pf, praw] of this.pending) {
78
+ if (pf.kind === TMF8829_FID_HISTOGRAMS)
79
+ this.hist.push({ info: pf, raw: praw });
80
+ else
81
+ this.refs.push(praw);
82
+ }
83
+ this.pending = [];
84
+ let res;
85
+ try {
86
+ res = parseTmf8829Results(raw, f);
87
+ }
88
+ catch (e) {
89
+ this.parseErrors += 1;
90
+ this.problems.push(`fN=${f.fNumber}: ${e instanceof Error ? e.message : String(e)}`);
91
+ this.half = null;
92
+ return null;
93
+ }
94
+ let frames;
95
+ let times;
96
+ if ((TMF8829_FP_GRID[f.fpMode]?.[0] ?? 0) === 32) {
97
+ if (this.half === null) {
98
+ if (f.isSecondHalf) {
99
+ this.problems.push(`second half fN=${f.fNumber} without a first one - dropped`);
100
+ this.hist = [];
101
+ this.refs = [];
102
+ return null;
103
+ }
104
+ this.half = [f, res, t];
105
+ return null;
106
+ }
107
+ if (!f.isSecondHalf) {
108
+ this.problems.push(`two first halves in a row (fN ${this.half[0].fNumber}, ${f.fNumber})`);
109
+ this.half = [f, res, t];
110
+ return null;
111
+ }
112
+ const [f0, res0, t0] = this.half;
113
+ this.half = null;
114
+ const fmt = (x) => (x.fpMode << 8) | (x.layout & ~TMF8829_LAYOUT_SUBFRAME);
115
+ if (fmt(f0) !== fmt(f)) {
116
+ // Impossible within one stream (configure() needs a stop); never crash the read pump.
117
+ this.problems.push(`half-frames of different formats (fN ${f0.fNumber}, ${f.fNumber}) - dropped`);
118
+ this.hist = [];
119
+ this.refs = [];
120
+ return null;
121
+ }
122
+ frames = [f0, f];
123
+ times = [t0, t];
124
+ res = mergeTmf8829Halves(res0, res);
125
+ }
126
+ else {
127
+ frames = [f];
128
+ times = [t];
129
+ }
130
+ const m = {
131
+ timestampUs: Math.floor(times.reduce((s, x) => s + x.timestampUs, 0) / times.length),
132
+ flags: times.reduce((s, x) => s | x.flags, 0),
133
+ fpMode: f.fpMode,
134
+ fNumber: f.fNumber,
135
+ rows: res.rows,
136
+ cols: res.cols,
137
+ results: res,
138
+ distanceMm: tmf8829DistanceMm(res, this.clock.ratio, f.distanceInMm),
139
+ ratioQ16: this.clock.ratioQ16,
140
+ frames,
141
+ times,
142
+ histograms: this.hist,
143
+ refFrames: this.refs,
144
+ problems: this.problems,
145
+ temperatureC: f.temperature[0],
146
+ };
147
+ this.hist = [];
148
+ this.refs = [];
149
+ this.problems = [];
150
+ return m;
151
+ }
152
+ }
153
+ /** Contract 09 `tmf8829` record value of a measurement (distances rounded to 0.1 mm). */
154
+ export function tmf8829RecordValue(m) {
155
+ const r = m.results;
156
+ const v = {
157
+ fp_mode: m.fpMode,
158
+ rows: m.rows,
159
+ cols: m.cols,
160
+ peaks: r.peaks,
161
+ f_number: m.fNumber,
162
+ flags: m.flags,
163
+ temperature_c: m.temperatureC,
164
+ distance_mm: m.distanceMm ? Array.from(m.distanceMm, (x) => Math.round(x * 10) / 10) : [],
165
+ snr: r.snr ? Array.from(r.snr) : [],
166
+ };
167
+ if (r.signal)
168
+ v.signal = Array.from(r.signal);
169
+ if (r.noise)
170
+ v.noise = Array.from(r.noise);
171
+ if (r.xtalk)
172
+ v.xtalk = Array.from(r.xtalk);
173
+ return v;
174
+ }
175
+ //# sourceMappingURL=builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"builder.js","sourceRoot":"","sources":["../../../src/sensors/tmf8829/builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Sensor clock model and frame capture time (contracts/14_SENSOR_TMF8829.md §5).
3
+ * Mirrors the Python reference `depz_sensor_sdk.tmf8829.clock`; the vectors in
4
+ * `contracts/vectors/tmf8829_frame_time.json` pin it bit for bit.
5
+ *
6
+ * Plain numbers, not bigint: every intermediate stays below 2^53 (µs values
7
+ * ~2^31, `span << 16` ~2^37, tick × ratio ~2^51), so `Math.floor(a / b)` is
8
+ * exact. `>>` in JS is 32-bit, so the Q16 shifts are divisions by 65536.
9
+ */
10
+ export declare const TMF8829_NOMINAL_Q16: number;
11
+ /** Clock ratio not measured yet (nominal 8 µs/tick used). */
12
+ export declare const TMF8829_FT_NOMINAL = 1;
13
+ /** Clock model restarted at this frame (SYSTICK jump). */
14
+ export declare const TMF8829_FT_CLOCK_RESET = 2;
15
+ /** INT edge > 2 ms later after t1 than usual in this stream. */
16
+ export declare const TMF8829_FT_EDGE_LATE = 4;
17
+ /** Sub-integrations not back to back (histogram FIFO wait). */
18
+ export declare const TMF8829_FT_STALLED = 8;
19
+ /** Histograms + 32x32/48x32: T1 may be too long, centre late. */
20
+ export declare const TMF8829_FT_T1_UNSURE = 16;
21
+ export declare const TMF8829_FT_NAMES: ReadonlyArray<[number, string]>;
22
+ export declare function tmf8829FlagNames(flags: number): string[];
23
+ /**
24
+ * Sensor SYSTICK (125 kHz) → MCU µs, fed one clock pair per frame. The ratio
25
+ * is taken over a sliding 1..2 s window, first after 200 ms; it is also the
26
+ * distance correction.
27
+ */
28
+ export declare class Tmf8829SensorClock {
29
+ ratioQ16: number;
30
+ nominal: boolean;
31
+ private valid;
32
+ private last;
33
+ private anchor;
34
+ private mid;
35
+ reset(): void;
36
+ /** MCU/sensor clock ratio (≈ 1.015): distances are scaled by it. */
37
+ get ratio(): number;
38
+ private static stepOk;
39
+ /** Add a pair → TMF8829_FT_CLOCK_RESET if it does not fit the model, else 0. */
40
+ add(us: number, tick: number): number;
41
+ /** SYSTICK `tick` → MCU µs through the pair (pairUs, pairTick). */
42
+ toUs(pairUs: number, pairTick: number, tick: number): number;
43
+ }
44
+ /** Capture time of one results frame, MCU µs. */
45
+ export interface Tmf8829FrameTime {
46
+ /** Centre of the capture window. */
47
+ timestampUs: number;
48
+ /** TMF8829_FT_* */
49
+ flags: number;
50
+ /** Sub-integration length used. */
51
+ t1LenUs: number;
52
+ t0Us: number;
53
+ t1Us: number;
54
+ /** INT edge credited to the frame, 0 = none. */
55
+ edgeUs: number;
56
+ /** MCU time of the header read (the clock pair). */
57
+ pairUs: number;
58
+ /** Clock ratio after this frame. */
59
+ ratioQ16: number;
60
+ }
61
+ /**
62
+ * When a results frame was captured: the centre of [t0, t1 + T1], T1 the
63
+ * stream's shortest (t1 − t0)/(N − 1).
64
+ */
65
+ export declare class Tmf8829CaptureTimer {
66
+ readonly clock: Tmf8829SensorClock;
67
+ private lagMin;
68
+ private histSeen;
69
+ private subMin;
70
+ constructor(clock: Tmf8829SensorClock);
71
+ reset(): void;
72
+ /** A histogram frame was seen in the stream. */
73
+ histograms(): void;
74
+ results(fpMode: number, systick: number, t0Tick: number, t1Tick: number, pairUs: number, edgeUs: number, flagsIn: number): Tmf8829FrameTime;
75
+ }
76
+ //# sourceMappingURL=clock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"clock.d.ts","sourceRoot":"","sources":["../../../src/sensors/tmf8829/clock.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,eAAO,MAAM,mBAAmB,QAAY,CAAC;AAK7C,6DAA6D;AAC7D,eAAO,MAAM,kBAAkB,IAAO,CAAC;AACvC,0DAA0D;AAC1D,eAAO,MAAM,sBAAsB,IAAO,CAAC;AAC3C,gEAAgE;AAChE,eAAO,MAAM,oBAAoB,IAAO,CAAC;AACzC,+DAA+D;AAC/D,eAAO,MAAM,kBAAkB,IAAO,CAAC;AACvC,iEAAiE;AACjE,eAAO,MAAM,oBAAoB,KAAO,CAAC;AAEzC,eAAO,MAAM,gBAAgB,EAAE,aAAa,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAM5D,CAAC;AAEF,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAExD;AAcD;;;;GAIG;AACH,qBAAa,kBAAkB;IAC7B,QAAQ,SAAuB;IAC/B,OAAO,UAAQ;IACf,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,IAAI,CAA4B;IACxC,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,GAAG,CAAiC;IAE5C,KAAK,IAAI,IAAI;IASb,oEAAoE;IACpE,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,OAAO,CAAC,MAAM,CAAC,MAAM;IAMrB,gFAAgF;IAChF,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;IA6BrC,mEAAmE;IACnE,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM;CAG7D;AAED,iDAAiD;AACjD,MAAM,WAAW,gBAAgB;IAC/B,oCAAoC;IACpC,WAAW,EAAE,MAAM,CAAC;IACpB,mBAAmB;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,gDAAgD;IAChD,MAAM,EAAE,MAAM,CAAC;IACf,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;IACf,oCAAoC;IACpC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,qBAAa,mBAAmB;IAKlB,QAAQ,CAAC,KAAK,EAAE,kBAAkB;IAJ9C,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAK;gBAEE,KAAK,EAAE,kBAAkB;IAE9C,KAAK,IAAI,IAAI;IAMb,gDAAgD;IAChD,UAAU,IAAI,IAAI;IAIlB,OAAO,CACL,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,GACd,gBAAgB;CAkCpB"}