@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,190 @@
1
+ /**
2
+ * TMF8829 frame layout and pixel decoding (contracts/14_SENSOR_TMF8829.md §3).
3
+ * Mirrors the Python reference `depz_sensor_sdk.tmf8829.frames`.
4
+ */
5
+ import { DepzError } from "../../errors.js";
6
+ export const TMF8829_PRE_HEADER_SIZE = 5;
7
+ export const TMF8829_HEADER_SIZE = 16;
8
+ export const TMF8829_FOOTER_SIZE = 12;
9
+ /** The 21 bytes the bridge reads at 0xFA. */
10
+ export const TMF8829_FRAME_HEAD = TMF8829_PRE_HEADER_SIZE + TMF8829_HEADER_SIZE;
11
+ export const TMF8829_FRAME_EOF = 0xe0f7;
12
+ export const TMF8829_FID_MASK = 0xf0;
13
+ export const TMF8829_FID_RESULTS = 0x10;
14
+ export const TMF8829_FID_HISTOGRAMS = 0x20;
15
+ export const TMF8829_FID_REF_SPAD = 0x30;
16
+ export const TMF8829_LAYOUT_PEAKS = 0x07;
17
+ export const TMF8829_LAYOUT_SIGNAL = 0x08;
18
+ export const TMF8829_LAYOUT_NOISE = 0x10;
19
+ export const TMF8829_LAYOUT_XTALK = 0x20;
20
+ /** 32x32/48x32: set on the second (odd-row) half-frame. */
21
+ export const TMF8829_LAYOUT_SUBFRAME = 0x40;
22
+ const FRAME_VALID = 0x01;
23
+ const FRAME_ABORTED = 0xc0;
24
+ const FRAME_WARNINGS = [
25
+ [0x08, "HV_CP_OVERLOAD"],
26
+ [0x10, "VCDRV_OVERLOAD"],
27
+ [0x20, "VCDRV_BURST_EXCEEDED"],
28
+ ];
29
+ const FOOTER_DIST_IN_MM = 0x01;
30
+ const FIFO_TX_UNDERRUN = 0x10;
31
+ const FIFO_RX_OVERRUN = 0x20;
32
+ /** fp_mode → [rows, cols] of the full focal plane. */
33
+ export const TMF8829_FP_GRID = {
34
+ 0: [8, 8],
35
+ 1: [8, 8],
36
+ 2: [16, 16],
37
+ 3: [32, 32],
38
+ 4: [32, 32],
39
+ 5: [32, 48],
40
+ };
41
+ export const TMF8829_FP_NAMES = {
42
+ 0: "8x8A",
43
+ 1: "8x8B",
44
+ 2: "16x16",
45
+ 3: "32x32",
46
+ 4: "32x32s",
47
+ 5: "48x32",
48
+ };
49
+ /** Full frame size (pre-header included) from its first 21 bytes. */
50
+ export function tmf8829FrameSize(head) {
51
+ return TMF8829_PRE_HEADER_SIZE + 4 + (head[7] | (head[8] << 8));
52
+ }
53
+ export function parseTmf8829Frame(raw) {
54
+ if (raw.length < TMF8829_FRAME_HEAD + TMF8829_FOOTER_SIZE) {
55
+ throw new DepzError(`frame of ${raw.length} B is shorter than header + footer`);
56
+ }
57
+ const v = new DataView(raw.buffer, raw.byteOffset, raw.byteLength);
58
+ const h = TMF8829_PRE_HEADER_SIZE;
59
+ const f = raw.length - TMF8829_FOOTER_SIZE;
60
+ const id = raw[h];
61
+ const layout = raw[h + 1];
62
+ const reserved = raw[f + 9];
63
+ return {
64
+ fifoStatus: raw[0],
65
+ systick: v.getUint32(1, true),
66
+ id,
67
+ kind: id & TMF8829_FID_MASK,
68
+ fpMode: id & 0x0f,
69
+ layout,
70
+ payload: v.getUint16(h + 2, true),
71
+ fNumber: v.getUint32(h + 4, true),
72
+ temperature: [v.getInt8(h + 8), v.getInt8(h + 9), v.getInt8(h + 10)],
73
+ bdv: raw[h + 11],
74
+ refPos: [v.getUint16(h + 12, true), v.getUint16(h + 14, true)],
75
+ t0Integration: v.getUint32(f, true),
76
+ t1Integration: v.getUint32(f + 4, true),
77
+ frameStatus: raw[f + 8],
78
+ reserved,
79
+ eof: v.getUint16(f + 10, true),
80
+ size: raw.length,
81
+ isSecondHalf: (layout & TMF8829_LAYOUT_SUBFRAME) !== 0,
82
+ distanceInMm: (reserved & FOOTER_DIST_IN_MM) !== 0,
83
+ };
84
+ }
85
+ /** What is wrong with a frame, human-readable; empty when fine. */
86
+ export function tmf8829FrameProblems(f) {
87
+ const out = [];
88
+ if (f.eof !== TMF8829_FRAME_EOF)
89
+ out.push(`EOF 0x${f.eof.toString(16).toUpperCase().padStart(4, "0")}`);
90
+ if (!(f.frameStatus & FRAME_VALID)) {
91
+ out.push(`status 0x${f.frameStatus.toString(16).toUpperCase().padStart(2, "0")} not valid`);
92
+ }
93
+ if (f.frameStatus & FRAME_ABORTED)
94
+ out.push("aborted");
95
+ for (const [bit, name] of FRAME_WARNINGS)
96
+ if (f.frameStatus & bit)
97
+ out.push(name);
98
+ if (f.fifoStatus & FIFO_TX_UNDERRUN)
99
+ out.push("txfifo_underrun");
100
+ if (f.fifoStatus & FIFO_RX_OVERRUN)
101
+ out.push("rxfifo_overrun");
102
+ return out;
103
+ }
104
+ /** [rows, cols] one results frame carries: half the rows for 32x32/48x32. */
105
+ export function tmf8829FrameRows(fpMode) {
106
+ const g = TMF8829_FP_GRID[fpMode];
107
+ if (!g)
108
+ throw new DepzError(`unknown fp_mode ${fpMode}`);
109
+ return g[0] === 32 ? [g[0] / 2, g[1]] : [g[0], g[1]];
110
+ }
111
+ /** Pixel results of one results frame. */
112
+ export function parseTmf8829Results(raw, info) {
113
+ const f = info ?? parseTmf8829Frame(raw);
114
+ if (f.kind !== TMF8829_FID_RESULTS) {
115
+ throw new DepzError(`frame id 0x${f.id.toString(16)} is not a results frame`);
116
+ }
117
+ const [rows, cols] = tmf8829FrameRows(f.fpMode);
118
+ const peaks = f.layout & TMF8829_LAYOUT_PEAKS;
119
+ const noise = (f.layout & TMF8829_LAYOUT_NOISE) !== 0;
120
+ const xtalk = (f.layout & TMF8829_LAYOUT_XTALK) !== 0;
121
+ const signal = (f.layout & TMF8829_LAYOUT_SIGNAL) !== 0;
122
+ const peakSize = 3 + (signal ? 2 : 0);
123
+ const pxSize = (noise ? 2 : 0) + (xtalk ? 2 : 0) + peaks * peakSize;
124
+ const n = rows * cols;
125
+ const dataSize = f.size - TMF8829_FRAME_HEAD - TMF8829_FOOTER_SIZE;
126
+ if (pxSize * n !== dataSize) {
127
+ throw new DepzError(`result data ${dataSize} B, expected ${n} px × ${pxSize} B (layout 0x${f.layout.toString(16)})`);
128
+ }
129
+ const out = {
130
+ peaks,
131
+ rows,
132
+ cols,
133
+ distance: peaks ? new Uint16Array(peaks * n) : null,
134
+ snr: peaks ? new Uint8Array(peaks * n) : null,
135
+ signal: peaks && signal ? new Uint16Array(peaks * n) : null,
136
+ noise: noise ? new Uint16Array(n) : null,
137
+ xtalk: xtalk ? new Uint16Array(n) : null,
138
+ };
139
+ let o = TMF8829_FRAME_HEAD;
140
+ const u16 = (at) => raw[at] | (raw[at + 1] << 8);
141
+ for (let i = 0; i < n; i++) {
142
+ if (out.noise) {
143
+ out.noise[i] = u16(o);
144
+ o += 2;
145
+ }
146
+ if (out.xtalk) {
147
+ out.xtalk[i] = u16(o);
148
+ o += 2;
149
+ }
150
+ for (let p = 0; p < peaks; p++) {
151
+ out.distance[p * n + i] = u16(o);
152
+ out.snr[p * n + i] = raw[o + 2];
153
+ o += 3;
154
+ if (out.signal) {
155
+ out.signal[p * n + i] = u16(o);
156
+ o += 2;
157
+ }
158
+ }
159
+ }
160
+ return out;
161
+ }
162
+ /** 32x32/48x32: the first half-frame holds the even rows, the second the odd ones. */
163
+ export function mergeTmf8829Halves(first, second) {
164
+ const rows = first.rows * 2;
165
+ const cols = first.cols;
166
+ function merge(a, b, layers) {
167
+ if (a === null || b === null)
168
+ return null;
169
+ const m = new a.constructor(layers * rows * cols);
170
+ for (let l = 0; l < layers; l++) {
171
+ for (let r = 0; r < first.rows; r++) {
172
+ const src = (l * first.rows + r) * cols;
173
+ m.set(a.subarray(src, src + cols), (l * rows + 2 * r) * cols);
174
+ m.set(b.subarray(src, src + cols), (l * rows + 2 * r + 1) * cols);
175
+ }
176
+ }
177
+ return m;
178
+ }
179
+ return {
180
+ peaks: first.peaks,
181
+ rows,
182
+ cols,
183
+ distance: merge(first.distance, second.distance, first.peaks),
184
+ snr: merge(first.snr, second.snr, first.peaks),
185
+ signal: merge(first.signal, second.signal, first.peaks),
186
+ noise: merge(first.noise, second.noise, 1),
187
+ xtalk: merge(first.xtalk, second.xtalk, 1),
188
+ };
189
+ }
190
+ //# sourceMappingURL=frames.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frames.js","sourceRoot":"","sources":["../../../src/sensors/tmf8829/frames.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * TMF8829 multizone dToF sensor over the SPI register bridge
3
+ * (contracts/14_SENSOR_TMF8829.md).
4
+ *
5
+ * The board is a thin bridge: this class runs the sensor — soft reset,
6
+ * sensor firmware download through the sensor bootloader, presets and the
7
+ * config page, start/stop — and turns the bridge's chunked frame stream into
8
+ * measurements (half-frame merge, histograms, ref-SPAD frames, clock model,
9
+ * capture time). Mirrors the Python reference `depz_sensor_sdk.tmf8829.Tmf8829`.
10
+ */
11
+ import { DepzDevice, StreamQueue, type DeviceOptions } from "../../device/device.js";
12
+ import { DepzError } from "../../errors.js";
13
+ import type { PacketEvent } from "../../protocol/framing.js";
14
+ import { type Tmf8829Event, type Tmf8829Info } from "../../protocol/tmf8829.js";
15
+ import type { SerialTransport } from "../../transport/types.js";
16
+ import { type Tmf8829Measurement } from "./builder.js";
17
+ import { type Tmf8829CfgField, type Tmf8829Preset } from "./config.js";
18
+ /** ams tmf8829_application.hex load address (application 2.200.0). */
19
+ export declare const TMF8829_FIRMWARE_LOAD_ADDR = 65536;
20
+ /** The sensor firmware image `init()` downloads (14 444 B, MIT). Lazily decoded. */
21
+ export declare function tmf8829FirmwareImage(): Promise<Uint8Array>;
22
+ /** The sensor refused or did not answer (bootloader / application status). */
23
+ export declare class Tmf8829Error extends DepzError {
24
+ }
25
+ export interface Tmf8829ConfigureOptions {
26
+ periodMs?: number;
27
+ /** Defaults to the preset's own value. */
28
+ kiloIterations?: number;
29
+ nrPeaks?: number;
30
+ signalStrength?: boolean;
31
+ noiseStrength?: boolean;
32
+ xtalk?: boolean;
33
+ histograms?: boolean;
34
+ refFrame?: boolean;
35
+ /** Any other config-page field by name. */
36
+ fields?: Partial<Record<Tmf8829CfgField, number>>;
37
+ }
38
+ /** The config written by `configure()`, as read back from the sensor. */
39
+ export interface Tmf8829Config {
40
+ preset: Tmf8829Preset;
41
+ /** The 190-byte page 0x22..0xDF. */
42
+ page: Uint8Array;
43
+ histograms: boolean;
44
+ refFrame: boolean;
45
+ fields: Record<Tmf8829CfgField, number>;
46
+ /** [rows, cols] of a measurement. */
47
+ grid: readonly [number, number];
48
+ }
49
+ export interface Tmf8829Options extends DeviceOptions {
50
+ /** Injectable sleep (tests). */
51
+ sleepImpl?: (ms: number) => Promise<void>;
52
+ }
53
+ /**
54
+ * TMF8829 ToF device (8×8 … 48×32 zones, up to 4 peaks per zone, histograms).
55
+ * `init()` downloads the 14.4 KB sensor firmware (~0.15 s), `configure(preset,
56
+ * …)` writes the config page, `start()` streams measurements to
57
+ * `onMeasurement` / `measurements()`, `stop()` ends it. The sensor's EN pin is
58
+ * wired high: there is no sleep, recovery from any state is `init()`.
59
+ */
60
+ export declare class Tmf8829 extends DepzDevice {
61
+ appVersion: string | null;
62
+ sensorSerial: number | null;
63
+ private readonly sleepImpl;
64
+ private chain;
65
+ private readonly reassembler;
66
+ private readonly builder;
67
+ private measCbs;
68
+ private measQueues;
69
+ private interruptCbs;
70
+ private streamingFlag;
71
+ private stopping;
72
+ private cfg;
73
+ constructor(transport: SerialTransport, opts?: Tmf8829Options);
74
+ /**
75
+ * Read `length` bytes from `addr` in ≤1024-byte requests; reads that reach the
76
+ * FIFO port 0xFF stay there (the sensor does not auto-increment it).
77
+ */
78
+ readRegisters(addr: number, length: number): Promise<Uint8Array>;
79
+ /** Write `data` from `addr` in ≤1023-byte requests (writes to 0xFF stay at 0xFF). */
80
+ writeRegisters(addr: number, data: Uint8Array): Promise<void>;
81
+ /** Raw host-interface registers, for diagnostics. */
82
+ sensorState(): Promise<Record<string, number>>;
83
+ /** Bridge counters (never touches the sensor, safe mid-stream). */
84
+ getBridgeInfo(): Promise<Tmf8829Info>;
85
+ /**
86
+ * Bring the sensor from any state to its running RAM application: soft
87
+ * reset, bootloader, firmware download, start. Resolves [application
88
+ * version, sensor serial]. Stops a running stream first. `progress(done,
89
+ * total)` tracks the image download.
90
+ */
91
+ init(progress?: (done: number, total: number) => void): Promise<[string, number]>;
92
+ /** LOAD_CONFIG_PAGE → the 190-byte page 0x22..0xDF now in the sensor. */
93
+ configPage(): Promise<Uint8Array>;
94
+ /**
95
+ * Load `preset` and write the config page. Every field a preset does not
96
+ * reset is written (contract 14 §4), so the result never depends on an
97
+ * earlier config. Rejects with `Tmf8829Error` when the sensor refuses the
98
+ * page (e.g. ERR_CONFIG_RESULT_SIZE) or a written field does not read back.
99
+ */
100
+ configure(preset?: Tmf8829Preset, opts?: Tmf8829ConfigureOptions): Promise<Tmf8829Config>;
101
+ /** The last `configure()` result (null after `init()`). */
102
+ get config(): Tmf8829Config | null;
103
+ get streaming(): boolean;
104
+ /** MEASURE with the bridge stream armed; configures the 8x8 preset first if needed. */
105
+ start(): Promise<void>;
106
+ /**
107
+ * Sensor STOP, then the bridge stream (frames already queued drain). The
108
+ * bad-header event a STOP raises mid histogram dump is expected and
109
+ * swallowed.
110
+ */
111
+ stop(): Promise<void>;
112
+ close(): Promise<void>;
113
+ /** Subscribe to measurements (read-pump context; don't block). */
114
+ onMeasurement(cb: (m: Tmf8829Measurement) => void): () => void;
115
+ /** Async iterator over measurements — bounded, drop-oldest. */
116
+ measurements(maxsize?: number): StreamQueue<Tmf8829Measurement>;
117
+ /** Wait for the next measurement. */
118
+ getMeasurement(timeoutMs?: number): Promise<Tmf8829Measurement>;
119
+ /**
120
+ * RPT_TMF_EVENT that is not an expected stop artefact: a MOTION/PROXIMITY
121
+ * interrupt (code 0) or a refused frame header (code 1 — the sensor is lost,
122
+ * run `init()` again).
123
+ */
124
+ onInterrupt(cb: (e: Tmf8829Event) => void): () => void;
125
+ /** Frames the bridge dropped (frame_seq gaps) in this stream. */
126
+ get framesDropped(): number;
127
+ /** Frames lost to reassembly (incomplete, out-of-order chunks) in this stream. */
128
+ get framesDiscarded(): number;
129
+ get frameParseErrors(): number;
130
+ /** Current clock ratio (Q16), for diagnostics. */
131
+ get clockRatioQ16(): number;
132
+ /** Run `fn` after every previously queued sequence (non-reentrant). */
133
+ private locked;
134
+ private rd;
135
+ private rd8;
136
+ private wr;
137
+ private wr8;
138
+ private poll;
139
+ private blCmd;
140
+ private appCmd;
141
+ private loadConfig;
142
+ protected handleReport(pkt: PacketEvent): boolean;
143
+ }
144
+ //# sourceMappingURL=tmf8829.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tmf8829.d.ts","sourceRoot":"","sources":["../../../src/sensors/tmf8829/tmf8829.ts"],"names":[],"mappings":"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"}