@depz/sensor-sdk 0.1.2 → 0.1.4

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 (40) hide show
  1. package/README.md +4 -3
  2. package/dist/discovery.d.ts.map +1 -1
  3. package/dist/discovery.js +3 -0
  4. package/dist/discovery.js.map +1 -1
  5. package/dist/index.d.ts +4 -0
  6. package/dist/index.d.ts.map +1 -1
  7. package/dist/index.js +3 -0
  8. package/dist/index.js.map +1 -1
  9. package/dist/protocol/identity.d.ts +1 -1
  10. package/dist/protocol/identity.d.ts.map +1 -1
  11. package/dist/protocol/identity.js +1 -0
  12. package/dist/protocol/identity.js.map +1 -1
  13. package/dist/protocol/usb-ids.d.ts +1 -1
  14. package/dist/protocol/usb-ids.js +2 -2
  15. package/dist/protocol/usb-ids.js.map +1 -1
  16. package/dist/protocol/vl53l4.d.ts +82 -0
  17. package/dist/protocol/vl53l4.d.ts.map +1 -0
  18. package/dist/protocol/vl53l4.js +108 -0
  19. package/dist/protocol/vl53l4.js.map +1 -0
  20. package/dist/sensors/bno086/bno086.d.ts +4 -3
  21. package/dist/sensors/bno086/bno086.d.ts.map +1 -1
  22. package/dist/sensors/bno086/bno086.js +7 -5
  23. package/dist/sensors/bno086/bno086.js.map +1 -1
  24. package/dist/sensors/vl53l4/uld.d.ts +214 -0
  25. package/dist/sensors/vl53l4/uld.d.ts.map +1 -0
  26. package/dist/sensors/vl53l4/uld.js +504 -0
  27. package/dist/sensors/vl53l4/uld.js.map +1 -0
  28. package/dist/sensors/vl53l4/vl53l4.d.ts +195 -0
  29. package/dist/sensors/vl53l4/vl53l4.d.ts.map +1 -0
  30. package/dist/sensors/vl53l4/vl53l4.js +399 -0
  31. package/dist/sensors/vl53l4/vl53l4.js.map +1 -0
  32. package/dist/sensors/vl53l8/uld.d.ts +8 -0
  33. package/dist/sensors/vl53l8/uld.d.ts.map +1 -1
  34. package/dist/sensors/vl53l8/uld.js +9 -1
  35. package/dist/sensors/vl53l8/uld.js.map +1 -1
  36. package/dist/transport/ws-backend.d.ts +19 -0
  37. package/dist/transport/ws-backend.d.ts.map +1 -1
  38. package/dist/transport/ws-backend.js +25 -1
  39. package/dist/transport/ws-backend.js.map +1 -1
  40. package/package.json +3 -2
@@ -0,0 +1,195 @@
1
+ /**
2
+ * VL53L4CD ToF sensor: host-side ULD over the firmware register bridge.
3
+ *
4
+ * The MCU is a thin I2C bridge (contracts/10): the full ST ULD 2.2.3 driver
5
+ * runs here on the host (`uld.ts`). Result streaming is INT-driven push from
6
+ * the device — one 17-byte result block per RPT_VL53_STREAM, no reassembly
7
+ * needed.
8
+ *
9
+ * Mirrors the Python reference `depz_sensor_sdk.vl53l4.Vl53l4Cd`.
10
+ */
11
+ import { DepzDevice, StreamQueue, type DeviceOptions } from "../../device/device.js";
12
+ import type { PacketEvent } from "../../protocol/framing.js";
13
+ import { type Vl53l4Info } from "../../protocol/vl53l4.js";
14
+ import type { SerialTransport } from "../../transport/types.js";
15
+ import { VL53L4CD, type RangeTiming } from "./uld.js";
16
+ /** One decoded ranging result (VL53L4CD_ResultsData_t + MCU timestamp). */
17
+ export interface Vl53l4Measurement {
18
+ /** MCU uptime at the INT edge (stream) / read (poll). */
19
+ timestampUs: bigint;
20
+ /** 0 = valid (RANGE_STATUS_NAMES). */
21
+ rangeStatus: number;
22
+ distanceMm: number;
23
+ sigmaMm: number;
24
+ signalRateKcps: number;
25
+ ambientRateKcps: number;
26
+ signalPerSpadKcps: number;
27
+ ambientPerSpadKcps: number;
28
+ numberOfSpad: number;
29
+ /** Sensor frame counter, wraps at 255. */
30
+ streamCount: number;
31
+ /** rangeStatus === 0. */
32
+ valid: boolean;
33
+ /** Human-readable range status. */
34
+ statusText: string;
35
+ }
36
+ export interface Vl53l4Options extends DeviceOptions {
37
+ /** ULD sleep implementation (tests inject an instant one). */
38
+ sleepImpl?: (ms: number) => Promise<void>;
39
+ }
40
+ /**
41
+ * VL53L4CD single-zone ToF device.
42
+ *
43
+ * `init()` runs the ULD boot sequence (no firmware blob — the sensor carries
44
+ * its own), then configure and `startRanging()`. Configuration methods must
45
+ * not be called while ranging: the INT-driven stream owns the register bank
46
+ * (contract 10). Measurements stream via callbacks (`onMeasurement`) and/or
47
+ * the pull iterator (`measurements()`).
48
+ */
49
+ export declare class Vl53l4Cd extends DepzDevice {
50
+ private readonly uldDriver;
51
+ private measureCbs;
52
+ private measureQueues;
53
+ private rangingFlag;
54
+ private initializedFlag;
55
+ private streamParseErrorCount;
56
+ /** MCU timestamp of the latest register read (poll-mode measurements). */
57
+ private lastRegTimestampUs;
58
+ private readonly sleepImpl;
59
+ /** ULD `platform` object mapped onto the firmware register bridge. */
60
+ private readonly platform;
61
+ constructor(transport: SerialTransport, opts?: Vl53l4Options);
62
+ /** The underlying ULD driver (escape hatch for raw register access). */
63
+ get uld(): VL53L4CD;
64
+ /**
65
+ * True after a successful init(). Cleared by resetSensor() and xshut() — a
66
+ * power-cycled sensor holds none of the ULD configuration.
67
+ */
68
+ get initialized(): boolean;
69
+ /** True when the sensor answers with the VL53L4CD model id (0xEBAA). */
70
+ isAlive(): Promise<boolean>;
71
+ /**
72
+ * Initialise the sensor: default configuration block + VHV calibration
73
+ * (ULD sensorInit). Takes well under a second; the bus is left at `busKhz`
74
+ * (one of I2C_KHZ_STEPS).
75
+ */
76
+ init(busKhz?: number): Promise<void>;
77
+ /**
78
+ * Drive the XSHUT pin: XSHUT_OFF / XSHUT_ON / XSHUT_RESET. OFF and RESET
79
+ * stop any active stream on the bridge; a power-cycled sensor needs init()
80
+ * again.
81
+ */
82
+ xshut(action: number): Promise<void>;
83
+ /**
84
+ * Hardware sensor reset via XSHUT (blocks ~3 ms on the MCU). The ULD
85
+ * configuration is wiped — call init() again.
86
+ */
87
+ resetSensor(): Promise<void>;
88
+ /**
89
+ * RPT_VL53_INFO: sensor identity, pin levels and bridge counters. Counters
90
+ * are free-running (wrap silently) — watch increments. Safe to call while
91
+ * streaming.
92
+ */
93
+ bridgeInfo(): Promise<Vl53l4Info>;
94
+ /**
95
+ * Re-time the bridge's I2C bus to the nominal step nearest `khz`
96
+ * (I2C_KHZ_STEPS). Not while ranging — re-timing refuses a transfer in
97
+ * flight (ERR_BUSY). Read back the programmed step via bridgeInfo().
98
+ */
99
+ setI2cSpeedKhz(khz: number): Promise<void>;
100
+ /**
101
+ * → { timingBudgetMs, interMeasurementMs }. interMeasurement 0 means
102
+ * continuous mode.
103
+ */
104
+ getRangeTiming(): Promise<RangeTiming>;
105
+ /**
106
+ * Set the timing budget (10–200 ms) and inter-measurement period.
107
+ * `interMeasurementMs = 0` selects continuous ranging; a value larger than
108
+ * the budget selects autonomous low-power mode. Not while ranging.
109
+ */
110
+ setRangeTiming(timingBudgetMs: number, interMeasurementMs?: number): Promise<void>;
111
+ /** Configured ranging offset in mm (signed). */
112
+ getOffsetMm(): Promise<number>;
113
+ /** Set the ranging offset correction in mm. Not while ranging. */
114
+ setOffsetMm(offsetMm: number): Promise<void>;
115
+ /** Configured crosstalk compensation in kcps (0 = disabled). */
116
+ getXtalkKcps(): Promise<number>;
117
+ /** Set the crosstalk compensation in kcps. Not while ranging. */
118
+ setXtalkKcps(xtalkKcps: number): Promise<void>;
119
+ /**
120
+ * → { distanceLowMm, distanceHighMm, window }. Window is one of
121
+ * WINDOW_BELOW / WINDOW_ABOVE / WINDOW_OUT / WINDOW_IN.
122
+ */
123
+ getDetectionThresholds(): Promise<{
124
+ distanceLowMm: number;
125
+ distanceHighMm: number;
126
+ window: number;
127
+ }>;
128
+ /**
129
+ * Program the distance-window interrupt (INT only fires when the window
130
+ * condition holds). Not while ranging.
131
+ */
132
+ setDetectionThresholds(distanceLowMm: number, distanceHighMm: number, window: number): Promise<void>;
133
+ getSignalThresholdKcps(): Promise<number>;
134
+ /**
135
+ * Discard measurements whose return signal is below `signalKcps`. Not
136
+ * while ranging.
137
+ */
138
+ setSignalThresholdKcps(signalKcps: number): Promise<void>;
139
+ getSigmaThresholdMm(): Promise<number>;
140
+ /**
141
+ * Discard measurements whose sigma exceeds `sigmaMm` (≤ 16383). Not while
142
+ * ranging.
143
+ */
144
+ setSigmaThresholdMm(sigmaMm: number): Promise<void>;
145
+ /**
146
+ * Re-run VHV calibration; recommended after a >8 °C ambient change. Not
147
+ * while ranging (runs a short ranging burst internally).
148
+ */
149
+ startTemperatureUpdate(): Promise<void>;
150
+ /**
151
+ * Offset calibration against a target at `targetDistMm` (10–1000). Blocks
152
+ * for the sample burst; returns the offset now programmed.
153
+ */
154
+ calibrateOffset(targetDistMm: number, nbSamples?: number): Promise<number>;
155
+ /**
156
+ * Crosstalk calibration against a target at `targetDistMm` (10–5000).
157
+ * Blocks for the sample burst; returns the xtalk now programmed (kcps).
158
+ */
159
+ calibrateXtalk(targetDistMm: number, nbSamples?: number): Promise<number>;
160
+ /**
161
+ * Start the sensor's ranging loop and arm the MCU stream: one
162
+ * RPT_VL53_STREAM per INT edge carrying the 17-byte result block.
163
+ */
164
+ startRanging(): Promise<void>;
165
+ stopRanging(): Promise<void>;
166
+ get ranging(): boolean;
167
+ /**
168
+ * Single poll-mode measurement: start ranging, wait for data-ready, read
169
+ * the result block, stop. Rejects while the stream is running.
170
+ */
171
+ measureOnce(timeoutMs?: number): Promise<Vl53l4Measurement>;
172
+ /**
173
+ * Subscribe to streamed measurements (read-pump context; don't block).
174
+ * Returns an unsubscribe function.
175
+ */
176
+ onMeasurement(cb: (m: Vl53l4Measurement) => void): () => void;
177
+ /**
178
+ * Async iterator over measurements — bounded, drop-oldest (contract 07
179
+ * §3). The returned queue exposes `droppedCount`; it ends when the device
180
+ * closes or the consumer breaks out of iteration.
181
+ */
182
+ measurements(maxsize?: number): StreamQueue<Vl53l4Measurement>;
183
+ /** Convenience: wait for the next streamed measurement. */
184
+ getMeasurement(timeoutMs?: number): Promise<Vl53l4Measurement>;
185
+ /**
186
+ * Stream reports dropped because the result block failed to decode (short
187
+ * block from a reconfigured stream, corrupt read).
188
+ */
189
+ get streamParseErrors(): number;
190
+ /** Drop counters of all live measurement queues (diagnostics). */
191
+ get streamDroppedCounts(): number[];
192
+ protected requireNotRanging(): void;
193
+ protected handleReport(pkt: PacketEvent): boolean;
194
+ }
195
+ //# sourceMappingURL=vl53l4.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vl53l4.d.ts","sourceRoot":"","sources":["../../../src/sensors/vl53l4/vl53l4.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,399 @@
1
+ /**
2
+ * VL53L4CD ToF sensor: host-side ULD over the firmware register bridge.
3
+ *
4
+ * The MCU is a thin I2C bridge (contracts/10): the full ST ULD 2.2.3 driver
5
+ * runs here on the host (`uld.ts`). Result streaming is INT-driven push from
6
+ * the device — one 17-byte result block per RPT_VL53_STREAM, no reassembly
7
+ * needed.
8
+ *
9
+ * Mirrors the Python reference `depz_sensor_sdk.vl53l4.Vl53l4Cd`.
10
+ */
11
+ import { DepzDevice, StreamQueue } from "../../device/device.js";
12
+ import { DepzError, DepzTimeoutError } from "../../errors.js";
13
+ import { Vl53l4Cmd, Vl53l4Rpt, XFER_MAX, XSHUT_RESET, packReadReg, packSetI2cSpeed, packStartStream, packWriteReg, packXshut, unpackInfo, unpackRegData, unpackStream, } from "../../protocol/vl53l4.js";
14
+ import { I2C_KHZ_DEFAULT, RESULT_BLOCK_ADDR, RESULT_BLOCK_LEN, VL53L4CD, Vl53l4cdError, parseResultBlock, rangeStatusText, } from "./uld.js";
15
+ function measurementFromResults(timestampUs, r) {
16
+ return {
17
+ timestampUs,
18
+ rangeStatus: r.rangeStatus,
19
+ distanceMm: r.distanceMm,
20
+ sigmaMm: r.sigmaMm,
21
+ signalRateKcps: r.signalRateKcps,
22
+ ambientRateKcps: r.ambientRateKcps,
23
+ signalPerSpadKcps: r.signalPerSpadKcps,
24
+ ambientPerSpadKcps: r.ambientPerSpadKcps,
25
+ numberOfSpad: r.numberOfSpad,
26
+ streamCount: r.streamCount,
27
+ valid: r.rangeStatus === 0,
28
+ statusText: rangeStatusText(r.rangeStatus),
29
+ };
30
+ }
31
+ /**
32
+ * VL53L4CD single-zone ToF device.
33
+ *
34
+ * `init()` runs the ULD boot sequence (no firmware blob — the sensor carries
35
+ * its own), then configure and `startRanging()`. Configuration methods must
36
+ * not be called while ranging: the INT-driven stream owns the register bank
37
+ * (contract 10). Measurements stream via callbacks (`onMeasurement`) and/or
38
+ * the pull iterator (`measurements()`).
39
+ */
40
+ export class Vl53l4Cd extends DepzDevice {
41
+ uldDriver;
42
+ measureCbs = [];
43
+ measureQueues = [];
44
+ rangingFlag = false;
45
+ initializedFlag = false;
46
+ streamParseErrorCount = 0;
47
+ /** MCU timestamp of the latest register read (poll-mode measurements). */
48
+ lastRegTimestampUs = 0n;
49
+ sleepImpl;
50
+ /** ULD `platform` object mapped onto the firmware register bridge. */
51
+ platform = {
52
+ rdMulti: async (addr, size) => {
53
+ const out = new Uint8Array(size);
54
+ let off = 0;
55
+ while (size > 0) {
56
+ const n = Math.min(size, XFER_MAX);
57
+ const rep = await this.request(Vl53l4Cmd.ReadReg, packReadReg(addr, n), {
58
+ matcher: DepzDevice.expectReport(Vl53l4Rpt.RegData, unpackRegData),
59
+ timeoutMs: 2000,
60
+ });
61
+ if (rep.data.length !== n) {
62
+ throw new DepzError(`READ_REG 0x${addr.toString(16).toUpperCase().padStart(4, "0")}: ` +
63
+ `expected ${n}, got ${rep.data.length}`);
64
+ }
65
+ this.lastRegTimestampUs = rep.timestampUs;
66
+ out.set(rep.data, off);
67
+ off += n;
68
+ addr += n;
69
+ size -= n;
70
+ }
71
+ return out;
72
+ },
73
+ wrMulti: async (addr, data) => {
74
+ let done = 0;
75
+ while (done < data.length) {
76
+ const chunk = data.subarray(done, done + XFER_MAX);
77
+ await this.request(Vl53l4Cmd.WriteReg, packWriteReg(addr, chunk), {
78
+ okCompletes: true,
79
+ timeoutMs: 2000,
80
+ });
81
+ addr += chunk.length;
82
+ done += chunk.length;
83
+ }
84
+ },
85
+ setI2cSpeed: async (khz) => {
86
+ await this.request(Vl53l4Cmd.SetI2cSpeed, packSetI2cSpeed(khz), { okCompletes: true });
87
+ },
88
+ sleepMs: (ms) => this.sleepImpl(ms),
89
+ };
90
+ constructor(transport, opts) {
91
+ super(transport, opts);
92
+ this.sleepImpl = opts?.sleepImpl ?? ((ms) => new Promise((r) => setTimeout(r, ms)));
93
+ this.uldDriver = new VL53L4CD(this.platform);
94
+ }
95
+ // ── lifecycle ──────────────────────────────────────────────────────────────
96
+ /** The underlying ULD driver (escape hatch for raw register access). */
97
+ get uld() {
98
+ return this.uldDriver;
99
+ }
100
+ /**
101
+ * True after a successful init(). Cleared by resetSensor() and xshut() — a
102
+ * power-cycled sensor holds none of the ULD configuration.
103
+ */
104
+ get initialized() {
105
+ return this.initializedFlag;
106
+ }
107
+ /** True when the sensor answers with the VL53L4CD model id (0xEBAA). */
108
+ async isAlive() {
109
+ try {
110
+ return await this.uldDriver.isAlive();
111
+ }
112
+ catch (err) {
113
+ if (err instanceof Vl53l4cdError || err instanceof DepzError)
114
+ return false;
115
+ throw err;
116
+ }
117
+ }
118
+ /**
119
+ * Initialise the sensor: default configuration block + VHV calibration
120
+ * (ULD sensorInit). Takes well under a second; the bus is left at `busKhz`
121
+ * (one of I2C_KHZ_STEPS).
122
+ */
123
+ async init(busKhz = I2C_KHZ_DEFAULT) {
124
+ this.requireNotRanging();
125
+ await this.uldDriver.sensorInit(busKhz);
126
+ this.initializedFlag = true;
127
+ }
128
+ // ── sensor power (XSHUT pin) ───────────────────────────────────────────────
129
+ /**
130
+ * Drive the XSHUT pin: XSHUT_OFF / XSHUT_ON / XSHUT_RESET. OFF and RESET
131
+ * stop any active stream on the bridge; a power-cycled sensor needs init()
132
+ * again.
133
+ */
134
+ async xshut(action) {
135
+ const timeoutMs = action === XSHUT_RESET ? 2000 : undefined;
136
+ await this.request(Vl53l4Cmd.Xshut, packXshut(action), { okCompletes: true, timeoutMs });
137
+ this.rangingFlag = false;
138
+ this.initializedFlag = false;
139
+ }
140
+ /**
141
+ * Hardware sensor reset via XSHUT (blocks ~3 ms on the MCU). The ULD
142
+ * configuration is wiped — call init() again.
143
+ */
144
+ async resetSensor() {
145
+ await this.xshut(XSHUT_RESET);
146
+ }
147
+ // ── bridge diagnostics ─────────────────────────────────────────────────────
148
+ /**
149
+ * RPT_VL53_INFO: sensor identity, pin levels and bridge counters. Counters
150
+ * are free-running (wrap silently) — watch increments. Safe to call while
151
+ * streaming.
152
+ */
153
+ bridgeInfo() {
154
+ return this.request(Vl53l4Cmd.GetInfo, undefined, {
155
+ matcher: DepzDevice.expectReport(Vl53l4Rpt.Info, unpackInfo),
156
+ });
157
+ }
158
+ /**
159
+ * Re-time the bridge's I2C bus to the nominal step nearest `khz`
160
+ * (I2C_KHZ_STEPS). Not while ranging — re-timing refuses a transfer in
161
+ * flight (ERR_BUSY). Read back the programmed step via bridgeInfo().
162
+ */
163
+ async setI2cSpeedKhz(khz) {
164
+ this.requireNotRanging();
165
+ await this.platform.setI2cSpeed(khz);
166
+ }
167
+ // ── configuration (init() first; not while ranging) ────────────────────────
168
+ /**
169
+ * → { timingBudgetMs, interMeasurementMs }. interMeasurement 0 means
170
+ * continuous mode.
171
+ */
172
+ getRangeTiming() {
173
+ return this.uldDriver.getRangeTiming();
174
+ }
175
+ /**
176
+ * Set the timing budget (10–200 ms) and inter-measurement period.
177
+ * `interMeasurementMs = 0` selects continuous ranging; a value larger than
178
+ * the budget selects autonomous low-power mode. Not while ranging.
179
+ */
180
+ async setRangeTiming(timingBudgetMs, interMeasurementMs = 0) {
181
+ this.requireNotRanging();
182
+ await this.uldDriver.setRangeTiming(timingBudgetMs, interMeasurementMs);
183
+ }
184
+ /** Configured ranging offset in mm (signed). */
185
+ getOffsetMm() {
186
+ return this.uldDriver.getOffset();
187
+ }
188
+ /** Set the ranging offset correction in mm. Not while ranging. */
189
+ async setOffsetMm(offsetMm) {
190
+ this.requireNotRanging();
191
+ await this.uldDriver.setOffset(offsetMm);
192
+ }
193
+ /** Configured crosstalk compensation in kcps (0 = disabled). */
194
+ getXtalkKcps() {
195
+ return this.uldDriver.getXtalk();
196
+ }
197
+ /** Set the crosstalk compensation in kcps. Not while ranging. */
198
+ async setXtalkKcps(xtalkKcps) {
199
+ this.requireNotRanging();
200
+ await this.uldDriver.setXtalk(xtalkKcps);
201
+ }
202
+ /**
203
+ * → { distanceLowMm, distanceHighMm, window }. Window is one of
204
+ * WINDOW_BELOW / WINDOW_ABOVE / WINDOW_OUT / WINDOW_IN.
205
+ */
206
+ getDetectionThresholds() {
207
+ return this.uldDriver.getDetectionThresholds();
208
+ }
209
+ /**
210
+ * Program the distance-window interrupt (INT only fires when the window
211
+ * condition holds). Not while ranging.
212
+ */
213
+ async setDetectionThresholds(distanceLowMm, distanceHighMm, window) {
214
+ this.requireNotRanging();
215
+ await this.uldDriver.setDetectionThresholds(distanceLowMm, distanceHighMm, window);
216
+ }
217
+ getSignalThresholdKcps() {
218
+ return this.uldDriver.getSignalThreshold();
219
+ }
220
+ /**
221
+ * Discard measurements whose return signal is below `signalKcps`. Not
222
+ * while ranging.
223
+ */
224
+ async setSignalThresholdKcps(signalKcps) {
225
+ this.requireNotRanging();
226
+ await this.uldDriver.setSignalThreshold(signalKcps);
227
+ }
228
+ getSigmaThresholdMm() {
229
+ return this.uldDriver.getSigmaThreshold();
230
+ }
231
+ /**
232
+ * Discard measurements whose sigma exceeds `sigmaMm` (≤ 16383). Not while
233
+ * ranging.
234
+ */
235
+ async setSigmaThresholdMm(sigmaMm) {
236
+ this.requireNotRanging();
237
+ await this.uldDriver.setSigmaThreshold(sigmaMm);
238
+ }
239
+ /**
240
+ * Re-run VHV calibration; recommended after a >8 °C ambient change. Not
241
+ * while ranging (runs a short ranging burst internally).
242
+ */
243
+ async startTemperatureUpdate() {
244
+ this.requireNotRanging();
245
+ await this.uldDriver.startTemperatureUpdate();
246
+ }
247
+ /**
248
+ * Offset calibration against a target at `targetDistMm` (10–1000). Blocks
249
+ * for the sample burst; returns the offset now programmed.
250
+ */
251
+ async calibrateOffset(targetDistMm, nbSamples = 20) {
252
+ this.requireNotRanging();
253
+ return this.uldDriver.calibrateOffset(targetDistMm, nbSamples);
254
+ }
255
+ /**
256
+ * Crosstalk calibration against a target at `targetDistMm` (10–5000).
257
+ * Blocks for the sample burst; returns the xtalk now programmed (kcps).
258
+ */
259
+ async calibrateXtalk(targetDistMm, nbSamples = 20) {
260
+ this.requireNotRanging();
261
+ return this.uldDriver.calibrateXtalk(targetDistMm, nbSamples);
262
+ }
263
+ // ── ranging ────────────────────────────────────────────────────────────────
264
+ /**
265
+ * Start the sensor's ranging loop and arm the MCU stream: one
266
+ * RPT_VL53_STREAM per INT edge carrying the 17-byte result block.
267
+ */
268
+ async startRanging() {
269
+ this.requireNotRanging();
270
+ await this.uldDriver.startRanging();
271
+ await this.request(Vl53l4Cmd.StartStream, packStartStream(RESULT_BLOCK_ADDR, RESULT_BLOCK_LEN), { okCompletes: true });
272
+ this.rangingFlag = true;
273
+ }
274
+ async stopRanging() {
275
+ if (!this.rangingFlag)
276
+ return;
277
+ // Clear host state and stop the sensor even if the MCU STOP_STREAM ack
278
+ // fails (link hiccup): otherwise the device is wedged "ranging" and no
279
+ // reconfiguration is possible.
280
+ try {
281
+ await this.request(Vl53l4Cmd.StopStream, undefined, { okCompletes: true });
282
+ }
283
+ finally {
284
+ this.rangingFlag = false;
285
+ await this.uldDriver.stopRanging();
286
+ }
287
+ }
288
+ get ranging() {
289
+ return this.rangingFlag;
290
+ }
291
+ /**
292
+ * Single poll-mode measurement: start ranging, wait for data-ready, read
293
+ * the result block, stop. Rejects while the stream is running.
294
+ */
295
+ async measureOnce(timeoutMs = 1000) {
296
+ this.requireNotRanging();
297
+ await this.uldDriver.startRanging();
298
+ let result;
299
+ try {
300
+ await this.uldDriver.waitDataReady(timeoutMs);
301
+ result = await this.uldDriver.getResult();
302
+ await this.uldDriver.clearInterrupt();
303
+ }
304
+ finally {
305
+ await this.uldDriver.stopRanging();
306
+ }
307
+ return measurementFromResults(this.lastRegTimestampUs, result);
308
+ }
309
+ /**
310
+ * Subscribe to streamed measurements (read-pump context; don't block).
311
+ * Returns an unsubscribe function.
312
+ */
313
+ onMeasurement(cb) {
314
+ this.measureCbs.push(cb);
315
+ return () => {
316
+ this.measureCbs = this.measureCbs.filter((c) => c !== cb);
317
+ };
318
+ }
319
+ /**
320
+ * Async iterator over measurements — bounded, drop-oldest (contract 07
321
+ * §3). The returned queue exposes `droppedCount`; it ends when the device
322
+ * closes or the consumer breaks out of iteration.
323
+ */
324
+ measurements(maxsize = 64) {
325
+ const queue = new StreamQueue(maxsize, () => {
326
+ this.measureQueues = this.measureQueues.filter((q) => q !== queue);
327
+ deregister();
328
+ });
329
+ this.measureQueues.push(queue);
330
+ const deregister = this.registerStream(queue);
331
+ return queue;
332
+ }
333
+ /** Convenience: wait for the next streamed measurement. */
334
+ async getMeasurement(timeoutMs = 2000) {
335
+ const queue = new StreamQueue(1);
336
+ this.measureQueues.push(queue);
337
+ // Register for teardown so a disconnect closes the queue promptly (the
338
+ // wait resolves `done` at once) instead of stalling until the timeout.
339
+ const deregister = this.registerStream(queue);
340
+ let timer;
341
+ try {
342
+ const result = await Promise.race([
343
+ queue.next(),
344
+ new Promise((_, reject) => {
345
+ timer = setTimeout(() => reject(new DepzTimeoutError(Vl53l4Rpt.Stream, timeoutMs)), timeoutMs);
346
+ }),
347
+ ]);
348
+ if (result.done === true)
349
+ throw new DepzError("device closed");
350
+ return result.value;
351
+ }
352
+ finally {
353
+ if (timer !== undefined)
354
+ clearTimeout(timer);
355
+ this.measureQueues = this.measureQueues.filter((q) => q !== queue);
356
+ deregister();
357
+ }
358
+ }
359
+ /**
360
+ * Stream reports dropped because the result block failed to decode (short
361
+ * block from a reconfigured stream, corrupt read).
362
+ */
363
+ get streamParseErrors() {
364
+ return this.streamParseErrorCount;
365
+ }
366
+ /** Drop counters of all live measurement queues (diagnostics). */
367
+ get streamDroppedCounts() {
368
+ return this.measureQueues.map((q) => q.droppedCount);
369
+ }
370
+ // ── internal ───────────────────────────────────────────────────────────────
371
+ requireNotRanging() {
372
+ if (this.rangingFlag) {
373
+ throw new DepzError("stopRanging() first — the stream owns the register bank");
374
+ }
375
+ }
376
+ handleReport(pkt) {
377
+ if (pkt.cmd !== Vl53l4Rpt.Stream || pkt.payload.length < 12) {
378
+ return false;
379
+ }
380
+ const sample = unpackStream(pkt.payload);
381
+ let result;
382
+ try {
383
+ result = parseResultBlock(sample.data);
384
+ }
385
+ catch {
386
+ // Somebody re-armed the stream on a different block — count, don't
387
+ // crash the read pump.
388
+ this.streamParseErrorCount += 1;
389
+ return true;
390
+ }
391
+ const m = measurementFromResults(sample.timestampUs, result);
392
+ for (const cb of [...this.measureCbs])
393
+ cb(m);
394
+ for (const q of [...this.measureQueues])
395
+ q.push(m);
396
+ return true;
397
+ }
398
+ }
399
+ //# sourceMappingURL=vl53l4.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vl53l4.js","sourceRoot":"","sources":["../../../src/sensors/vl53l4/vl53l4.ts"],"names":[],"mappings":"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"}
@@ -258,6 +258,14 @@ export declare class VL53L8CX {
258
258
  getIntegrationTimeMs(): Promise<number>;
259
259
  /** Integration time 2..1000 ms. No effect in continuous ranging mode. */
260
260
  setIntegrationTimeMs(timeMs: number): Promise<void>;
261
+ /**
262
+ * Sharpener 0..99 %. Rounds to nearest: the register holds pct scaled to
263
+ * 0..255, and truncating the way back (as ST's C ULD does) loses a count for
264
+ * 95 of the 100 legal values — set(25) read back as 24. That also made
265
+ * calibrateXtalk's save/restore decay the setting by 1 % on every run
266
+ * (25 -> 24 -> 23 -> ...). The stored byte is unchanged; only this host-side
267
+ * interpretation is. Kept in lockstep with the Python SDK's uld.py.
268
+ */
261
269
  getSharpenerPercent(): Promise<number>;
262
270
  /** Sharpener 0..99 % (0 = disabled). */
263
271
  setSharpenerPercent(pct: number): Promise<void>;