@depz/sensor-sdk 0.1.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.
- package/README.md +69 -0
- package/dist/dataset.d.ts +93 -0
- package/dist/dataset.d.ts.map +1 -0
- package/dist/dataset.js +253 -0
- package/dist/dataset.js.map +1 -0
- package/dist/device/device.d.ts +185 -0
- package/dist/device/device.d.ts.map +1 -0
- package/dist/device/device.js +421 -0
- package/dist/device/device.js.map +1 -0
- package/dist/device/link.d.ts +62 -0
- package/dist/device/link.d.ts.map +1 -0
- package/dist/device/link.js +130 -0
- package/dist/device/link.js.map +1 -0
- package/dist/discovery.d.ts +109 -0
- package/dist/discovery.d.ts.map +1 -0
- package/dist/discovery.js +281 -0
- package/dist/discovery.js.map +1 -0
- package/dist/errors.d.ts +39 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +69 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +42 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/protocol/bno086.d.ts +36 -0
- package/dist/protocol/bno086.d.ts.map +1 -0
- package/dist/protocol/bno086.js +38 -0
- package/dist/protocol/bno086.js.map +1 -0
- package/dist/protocol/common.d.ts +103 -0
- package/dist/protocol/common.d.ts.map +1 -0
- package/dist/protocol/common.js +121 -0
- package/dist/protocol/common.js.map +1 -0
- package/dist/protocol/crc.d.ts +17 -0
- package/dist/protocol/crc.d.ts.map +1 -0
- package/dist/protocol/crc.js +55 -0
- package/dist/protocol/crc.js.map +1 -0
- package/dist/protocol/framing.d.ts +65 -0
- package/dist/protocol/framing.d.ts.map +1 -0
- package/dist/protocol/framing.js +152 -0
- package/dist/protocol/framing.js.map +1 -0
- package/dist/protocol/fwdepz.d.ts +21 -0
- package/dist/protocol/fwdepz.d.ts.map +1 -0
- package/dist/protocol/fwdepz.js +46 -0
- package/dist/protocol/fwdepz.js.map +1 -0
- package/dist/protocol/identity.d.ts +14 -0
- package/dist/protocol/identity.d.ts.map +1 -0
- package/dist/protocol/identity.js +28 -0
- package/dist/protocol/identity.js.map +1 -0
- package/dist/protocol/sr04.d.ts +38 -0
- package/dist/protocol/sr04.d.ts.map +1 -0
- package/dist/protocol/sr04.js +58 -0
- package/dist/protocol/sr04.js.map +1 -0
- package/dist/protocol/usb-ids.d.ts +60 -0
- package/dist/protocol/usb-ids.d.ts.map +1 -0
- package/dist/protocol/usb-ids.js +79 -0
- package/dist/protocol/usb-ids.js.map +1 -0
- package/dist/protocol/vl53l8.d.ts +59 -0
- package/dist/protocol/vl53l8.d.ts.map +1 -0
- package/dist/protocol/vl53l8.js +116 -0
- package/dist/protocol/vl53l8.js.map +1 -0
- package/dist/sensors/bno086/bno086.d.ts +197 -0
- package/dist/sensors/bno086/bno086.d.ts.map +1 -0
- package/dist/sensors/bno086/bno086.js +543 -0
- package/dist/sensors/bno086/bno086.js.map +1 -0
- package/dist/sensors/bno086/reports.d.ts +289 -0
- package/dist/sensors/bno086/reports.d.ts.map +1 -0
- package/dist/sensors/bno086/reports.js +397 -0
- package/dist/sensors/bno086/reports.js.map +1 -0
- package/dist/sensors/bno086/sh2.d.ts +307 -0
- package/dist/sensors/bno086/sh2.d.ts.map +1 -0
- package/dist/sensors/bno086/sh2.js +480 -0
- package/dist/sensors/bno086/sh2.js.map +1 -0
- package/dist/sensors/bno086/shtp.d.ts +98 -0
- package/dist/sensors/bno086/shtp.d.ts.map +1 -0
- package/dist/sensors/bno086/shtp.js +205 -0
- package/dist/sensors/bno086/shtp.js.map +1 -0
- package/dist/sensors/sr04.d.ts +65 -0
- package/dist/sensors/sr04.d.ts.map +1 -0
- package/dist/sensors/sr04.js +121 -0
- package/dist/sensors/sr04.js.map +1 -0
- package/dist/sensors/vl53l8/assets/ch.d.ts +16 -0
- package/dist/sensors/vl53l8/assets/ch.d.ts.map +1 -0
- package/dist/sensors/vl53l8/assets/ch.js +22 -0
- package/dist/sensors/vl53l8/assets/ch.js.map +1 -0
- package/dist/sensors/vl53l8/assets/cx.d.ts +16 -0
- package/dist/sensors/vl53l8/assets/cx.d.ts.map +1 -0
- package/dist/sensors/vl53l8/assets/cx.js +22 -0
- package/dist/sensors/vl53l8/assets/cx.js.map +1 -0
- package/dist/sensors/vl53l8/assets/decode.d.ts +7 -0
- package/dist/sensors/vl53l8/assets/decode.d.ts.map +1 -0
- package/dist/sensors/vl53l8/assets/decode.js +35 -0
- package/dist/sensors/vl53l8/assets/decode.js.map +1 -0
- package/dist/sensors/vl53l8/assets/index.d.ts +19 -0
- package/dist/sensors/vl53l8/assets/index.d.ts.map +1 -0
- package/dist/sensors/vl53l8/assets/index.js +11 -0
- package/dist/sensors/vl53l8/assets/index.js.map +1 -0
- package/dist/sensors/vl53l8/cnh.d.ts +113 -0
- package/dist/sensors/vl53l8/cnh.d.ts.map +1 -0
- package/dist/sensors/vl53l8/cnh.js +299 -0
- package/dist/sensors/vl53l8/cnh.js.map +1 -0
- package/dist/sensors/vl53l8/uld.d.ts +346 -0
- package/dist/sensors/vl53l8/uld.d.ts.map +1 -0
- package/dist/sensors/vl53l8/uld.js +1388 -0
- package/dist/sensors/vl53l8/uld.js.map +1 -0
- package/dist/sensors/vl53l8/vl53l8.d.ts +182 -0
- package/dist/sensors/vl53l8/vl53l8.d.ts.map +1 -0
- package/dist/sensors/vl53l8/vl53l8.js +411 -0
- package/dist/sensors/vl53l8/vl53l8.js.map +1 -0
- package/dist/transport/loopback.d.ts +18 -0
- package/dist/transport/loopback.d.ts.map +1 -0
- package/dist/transport/loopback.js +53 -0
- package/dist/transport/loopback.js.map +1 -0
- package/dist/transport/node.d.ts +51 -0
- package/dist/transport/node.d.ts.map +1 -0
- package/dist/transport/node.js +123 -0
- package/dist/transport/node.js.map +1 -0
- package/dist/transport/replay.d.ts +68 -0
- package/dist/transport/replay.d.ts.map +1 -0
- package/dist/transport/replay.js +196 -0
- package/dist/transport/replay.js.map +1 -0
- package/dist/transport/types.d.ts +23 -0
- package/dist/transport/types.d.ts.map +1 -0
- package/dist/transport/types.js +7 -0
- package/dist/transport/types.js.map +1 -0
- package/dist/transport/webserial.d.ts +69 -0
- package/dist/transport/webserial.d.ts.map +1 -0
- package/dist/transport/webserial.js +196 -0
- package/dist/transport/webserial.js.map +1 -0
- package/package.json +77 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fwdepz.d.ts","sourceRoot":"","sources":["../../src/protocol/fwdepz.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,eAAO,MAAM,YAAY,aAAa,CAAC;AACvC,eAAO,MAAM,kBAAkB,KAAK,CAAC;AAErC,qBAAa,WAAY,SAAQ,KAAK;CAAG;AAEzC,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,UAAU,CAAC;CACrB;AAED,oEAAoE;AACpE,wBAAgB,WAAW,CAAC,IAAI,EAAE,UAAU,GAAG,WAAW,CAgCzD;AAED,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,WAAW,GAAG,OAAO,CAE5D"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `.fwdepz` firmware container parse/validate (contracts/06 §2).
|
|
3
|
+
* Pure functions — used by the browser flashing flow to validate a dropped
|
|
4
|
+
* file before touching the device.
|
|
5
|
+
*/
|
|
6
|
+
import { crc16CcittFalse, crc32IsoHdlc } from "./crc.js";
|
|
7
|
+
export const FWDEPZ_MAGIC = "FWDEPZ00";
|
|
8
|
+
export const FWDEPZ_HEADER_SIZE = 64;
|
|
9
|
+
export class FwDepzError extends Error {
|
|
10
|
+
}
|
|
11
|
+
/** Validation order (contract 06 §2): magic → header CRC → size. */
|
|
12
|
+
export function parseFwDepz(blob) {
|
|
13
|
+
if (blob.length < FWDEPZ_HEADER_SIZE) {
|
|
14
|
+
throw new FwDepzError(`file too short: ${blob.length} < ${FWDEPZ_HEADER_SIZE}`);
|
|
15
|
+
}
|
|
16
|
+
for (let i = 0; i < 8; i++) {
|
|
17
|
+
if (blob[i] !== FWDEPZ_MAGIC.charCodeAt(i)) {
|
|
18
|
+
throw new FwDepzError("bad magic (not a .fwdepz file)");
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const dv = new DataView(blob.buffer, blob.byteOffset, blob.byteLength);
|
|
22
|
+
const storedCrc = dv.getUint16(62, true);
|
|
23
|
+
const actualCrc = crc16CcittFalse(blob.subarray(0, 62));
|
|
24
|
+
if (storedCrc !== actualCrc) {
|
|
25
|
+
throw new FwDepzError(`header CRC mismatch: stored=0x${storedCrc.toString(16)} actual=0x${actualCrc.toString(16)}`);
|
|
26
|
+
}
|
|
27
|
+
const loadAddr = dv.getUint32(8, true);
|
|
28
|
+
const fwSize = dv.getUint32(12, true);
|
|
29
|
+
const fwCrc32 = dv.getUint32(16, true);
|
|
30
|
+
const payload = blob.subarray(FWDEPZ_HEADER_SIZE);
|
|
31
|
+
if (fwSize !== payload.length) {
|
|
32
|
+
throw new FwDepzError(`fw_size=${fwSize} but payload is ${payload.length} bytes`);
|
|
33
|
+
}
|
|
34
|
+
return {
|
|
35
|
+
loadAddr,
|
|
36
|
+
fwSize,
|
|
37
|
+
fwCrc32,
|
|
38
|
+
curSec: blob[20],
|
|
39
|
+
totSec: blob[21],
|
|
40
|
+
payload,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export function fwDepzPayloadCrcOk(img) {
|
|
44
|
+
return crc32IsoHdlc(img.payload) === img.fwCrc32;
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=fwdepz.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fwdepz.js","sourceRoot":"","sources":["../../src/protocol/fwdepz.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAEzD,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC;AACvC,MAAM,CAAC,MAAM,kBAAkB,GAAG,EAAE,CAAC;AAErC,MAAM,OAAO,WAAY,SAAQ,KAAK;CAAG;AAWzC,oEAAoE;AACpE,MAAM,UAAU,WAAW,CAAC,IAAgB;IAC1C,IAAI,IAAI,CAAC,MAAM,GAAG,kBAAkB,EAAE,CAAC;QACrC,MAAM,IAAI,WAAW,CAAC,mBAAmB,IAAI,CAAC,MAAM,MAAM,kBAAkB,EAAE,CAAC,CAAC;IAClF,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,IAAI,IAAI,CAAC,CAAC,CAAC,KAAK,YAAY,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3C,MAAM,IAAI,WAAW,CAAC,gCAAgC,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IACD,MAAM,EAAE,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;IACvE,MAAM,SAAS,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACzC,MAAM,SAAS,GAAG,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;IACxD,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QAC5B,MAAM,IAAI,WAAW,CACnB,iCAAiC,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,aAAa,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAC7F,CAAC;IACJ,CAAC;IACD,MAAM,QAAQ,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;IACvC,MAAM,MAAM,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACtC,MAAM,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;IACvC,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC;IAClD,IAAI,MAAM,KAAK,OAAO,CAAC,MAAM,EAAE,CAAC;QAC9B,MAAM,IAAI,WAAW,CAAC,WAAW,MAAM,mBAAmB,OAAO,CAAC,MAAM,QAAQ,CAAC,CAAC;IACpF,CAAC;IACD,OAAO;QACL,QAAQ;QACR,MAAM;QACN,OAAO;QACP,MAAM,EAAE,IAAI,CAAC,EAAE,CAAE;QACjB,MAAM,EAAE,IAAI,CAAC,EAAE,CAAE;QACjB,OAAO;KACR,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,GAAgB;IACjD,OAAO,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,GAAG,CAAC,OAAO,CAAC;AACnD,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Firmware-name parsing (contracts/02_COMMON_COMMANDS.md §4). */
|
|
2
|
+
export type SensorType = "sr04" | "vl53l8" | "bno086" | "unknown";
|
|
3
|
+
export interface Identity {
|
|
4
|
+
mode: "app" | "bootloader" | "unknown";
|
|
5
|
+
sensorType: SensorType | null;
|
|
6
|
+
softwareName: string;
|
|
7
|
+
version: string;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Classify a GET_NAME_ACTIVE_SOFTWARE string. The string must already be
|
|
11
|
+
* stripped of trailing NUL/0xFF (`stripDeviceString`).
|
|
12
|
+
*/
|
|
13
|
+
export declare function parseSoftwareName(name: string): Identity;
|
|
14
|
+
//# sourceMappingURL=identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/protocol/identity.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAElE,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;AAElE,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,KAAK,GAAG,YAAY,GAAG,SAAS,CAAC;IACvC,UAAU,EAAE,UAAU,GAAG,IAAI,CAAC;IAC9B,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAUD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAexD"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/** Firmware-name parsing (contracts/02_COMMON_COMMANDS.md §4). */
|
|
2
|
+
const VERSION_RE = /_v(\d+(?:\.\d+)*)$/;
|
|
3
|
+
const PRODUCT_TOKENS = [
|
|
4
|
+
["SR04", "sr04"],
|
|
5
|
+
["VL53L8", "vl53l8"],
|
|
6
|
+
["BNO086", "bno086"],
|
|
7
|
+
];
|
|
8
|
+
/**
|
|
9
|
+
* Classify a GET_NAME_ACTIVE_SOFTWARE string. The string must already be
|
|
10
|
+
* stripped of trailing NUL/0xFF (`stripDeviceString`).
|
|
11
|
+
*/
|
|
12
|
+
export function parseSoftwareName(name) {
|
|
13
|
+
const m = VERSION_RE.exec(name);
|
|
14
|
+
const version = m ? m[1] : "";
|
|
15
|
+
if (name.startsWith("BOOTDEPZ")) {
|
|
16
|
+
return { mode: "bootloader", sensorType: null, softwareName: name, version };
|
|
17
|
+
}
|
|
18
|
+
if (name.startsWith("APP_")) {
|
|
19
|
+
for (const [token, sensor] of PRODUCT_TOKENS) {
|
|
20
|
+
if (name.includes(token)) {
|
|
21
|
+
return { mode: "app", sensorType: sensor, softwareName: name, version };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return { mode: "app", sensorType: "unknown", softwareName: name, version };
|
|
25
|
+
}
|
|
26
|
+
return { mode: "unknown", sensorType: null, softwareName: name, version };
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=identity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/protocol/identity.ts"],"names":[],"mappings":"AAAA,kEAAkE;AAWlE,MAAM,UAAU,GAAG,oBAAoB,CAAC;AAExC,MAAM,cAAc,GAAgC;IAClD,CAAC,MAAM,EAAE,MAAM,CAAC;IAChB,CAAC,QAAQ,EAAE,QAAQ,CAAC;IACpB,CAAC,QAAQ,EAAE,QAAQ,CAAC;CACrB,CAAC;AAEF;;;GAGG;AACH,MAAM,UAAU,iBAAiB,CAAC,IAAY;IAC5C,MAAM,CAAC,GAAG,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/B,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAChC,OAAO,EAAE,IAAI,EAAE,YAAY,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC/E,CAAC;IACD,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5B,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;YAC7C,IAAI,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;YAC1E,CAAC;QACH,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC7E,CAAC;IACD,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,YAAY,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC5E,CAAC"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** SR04 wire codecs (contracts/03_SENSOR_SR04.md). */
|
|
2
|
+
export declare enum Sr04Cmd {
|
|
3
|
+
GetSamplePeriod = 50,
|
|
4
|
+
SetSamplePeriod = 51,
|
|
5
|
+
GetEchoDecay = 52,
|
|
6
|
+
SetEchoDecay = 53,
|
|
7
|
+
MeasureOnce = 54,
|
|
8
|
+
StartMeasurementLoop = 55,
|
|
9
|
+
StopMeasurementLoop = 56
|
|
10
|
+
}
|
|
11
|
+
export declare enum Sr04Rpt {
|
|
12
|
+
Data = 145,
|
|
13
|
+
SamplePeriod = 146,
|
|
14
|
+
EchoDecay = 147
|
|
15
|
+
}
|
|
16
|
+
/** echo_time_us sentinel: no echo received. */
|
|
17
|
+
export declare const ECHO_TIMEOUT = 65535;
|
|
18
|
+
export declare const SAMPLE_PERIOD_DEFAULT_US = 50000;
|
|
19
|
+
export declare const ECHO_DECAY_DEFAULT_US = 5000;
|
|
20
|
+
export declare const ECHO_DECAY_MIN_US = 4000;
|
|
21
|
+
export declare const ECHO_DECAY_MAX_US = 65000;
|
|
22
|
+
export interface Sr04Data {
|
|
23
|
+
/** 0x36 single shot (host or SYNC_IN), 0x37 loop sample (ERRATA E3). */
|
|
24
|
+
sourceCmd: number;
|
|
25
|
+
timestampUs: bigint;
|
|
26
|
+
echoTimeUs: number;
|
|
27
|
+
}
|
|
28
|
+
export declare function unpackSr04Data(p: Uint8Array): Sr04Data;
|
|
29
|
+
export declare function packSamplePeriod(periodUs: number): Uint8Array;
|
|
30
|
+
export declare function unpackSamplePeriod(p: Uint8Array): number;
|
|
31
|
+
export declare function packEchoDecay(decayUs: number): Uint8Array;
|
|
32
|
+
export declare function unpackEchoDecay(p: Uint8Array): number;
|
|
33
|
+
/**
|
|
34
|
+
* Round-trip echo time → distance in mm; null for the timeout sentinel.
|
|
35
|
+
* Default speed of sound 343 m/s; with airTempC uses c = 331.3 + 0.606·T.
|
|
36
|
+
*/
|
|
37
|
+
export declare function distanceMmFromEcho(echoTimeUs: number, airTempC?: number): number | null;
|
|
38
|
+
//# sourceMappingURL=sr04.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sr04.d.ts","sourceRoot":"","sources":["../../src/protocol/sr04.ts"],"names":[],"mappings":"AAAA,sDAAsD;AAEtD,oBAAY,OAAO;IACjB,eAAe,KAAO;IACtB,eAAe,KAAO;IACtB,YAAY,KAAO;IACnB,YAAY,KAAO;IACnB,WAAW,KAAO;IAClB,oBAAoB,KAAO;IAC3B,mBAAmB,KAAO;CAC3B;AAED,oBAAY,OAAO;IACjB,IAAI,MAAO;IACX,YAAY,MAAO;IACnB,SAAS,MAAO;CACjB;AAED,+CAA+C;AAC/C,eAAO,MAAM,YAAY,QAAS,CAAC;AAEnC,eAAO,MAAM,wBAAwB,QAAS,CAAC;AAC/C,eAAO,MAAM,qBAAqB,OAAQ,CAAC;AAC3C,eAAO,MAAM,iBAAiB,OAAQ,CAAC;AACvC,eAAO,MAAM,iBAAiB,QAAS,CAAC;AAExC,MAAM,WAAW,QAAQ;IACvB,wEAAwE;IACxE,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAgB,cAAc,CAAC,CAAC,EAAE,UAAU,GAAG,QAAQ,CAOtD;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,CAI7D;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAExD;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAIzD;AAED,wBAAgB,eAAe,CAAC,CAAC,EAAE,UAAU,GAAG,MAAM,CAErD;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAIvF"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/** SR04 wire codecs (contracts/03_SENSOR_SR04.md). */
|
|
2
|
+
export var Sr04Cmd;
|
|
3
|
+
(function (Sr04Cmd) {
|
|
4
|
+
Sr04Cmd[Sr04Cmd["GetSamplePeriod"] = 50] = "GetSamplePeriod";
|
|
5
|
+
Sr04Cmd[Sr04Cmd["SetSamplePeriod"] = 51] = "SetSamplePeriod";
|
|
6
|
+
Sr04Cmd[Sr04Cmd["GetEchoDecay"] = 52] = "GetEchoDecay";
|
|
7
|
+
Sr04Cmd[Sr04Cmd["SetEchoDecay"] = 53] = "SetEchoDecay";
|
|
8
|
+
Sr04Cmd[Sr04Cmd["MeasureOnce"] = 54] = "MeasureOnce";
|
|
9
|
+
Sr04Cmd[Sr04Cmd["StartMeasurementLoop"] = 55] = "StartMeasurementLoop";
|
|
10
|
+
Sr04Cmd[Sr04Cmd["StopMeasurementLoop"] = 56] = "StopMeasurementLoop";
|
|
11
|
+
})(Sr04Cmd || (Sr04Cmd = {}));
|
|
12
|
+
export var Sr04Rpt;
|
|
13
|
+
(function (Sr04Rpt) {
|
|
14
|
+
Sr04Rpt[Sr04Rpt["Data"] = 145] = "Data";
|
|
15
|
+
Sr04Rpt[Sr04Rpt["SamplePeriod"] = 146] = "SamplePeriod";
|
|
16
|
+
Sr04Rpt[Sr04Rpt["EchoDecay"] = 147] = "EchoDecay";
|
|
17
|
+
})(Sr04Rpt || (Sr04Rpt = {}));
|
|
18
|
+
/** echo_time_us sentinel: no echo received. */
|
|
19
|
+
export const ECHO_TIMEOUT = 0xffff;
|
|
20
|
+
export const SAMPLE_PERIOD_DEFAULT_US = 50_000;
|
|
21
|
+
export const ECHO_DECAY_DEFAULT_US = 5_000;
|
|
22
|
+
export const ECHO_DECAY_MIN_US = 4_000;
|
|
23
|
+
export const ECHO_DECAY_MAX_US = 65_000;
|
|
24
|
+
export function unpackSr04Data(p) {
|
|
25
|
+
const v = new DataView(p.buffer, p.byteOffset, p.byteLength);
|
|
26
|
+
return {
|
|
27
|
+
sourceCmd: v.getUint8(0),
|
|
28
|
+
timestampUs: v.getBigUint64(1, true),
|
|
29
|
+
echoTimeUs: v.getUint16(9, true),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export function packSamplePeriod(periodUs) {
|
|
33
|
+
const out = new Uint8Array(4);
|
|
34
|
+
new DataView(out.buffer).setUint32(0, periodUs, true);
|
|
35
|
+
return out;
|
|
36
|
+
}
|
|
37
|
+
export function unpackSamplePeriod(p) {
|
|
38
|
+
return new DataView(p.buffer, p.byteOffset, p.byteLength).getUint32(0, true);
|
|
39
|
+
}
|
|
40
|
+
export function packEchoDecay(decayUs) {
|
|
41
|
+
const out = new Uint8Array(2);
|
|
42
|
+
new DataView(out.buffer).setUint16(0, decayUs, true);
|
|
43
|
+
return out;
|
|
44
|
+
}
|
|
45
|
+
export function unpackEchoDecay(p) {
|
|
46
|
+
return new DataView(p.buffer, p.byteOffset, p.byteLength).getUint16(0, true);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Round-trip echo time → distance in mm; null for the timeout sentinel.
|
|
50
|
+
* Default speed of sound 343 m/s; with airTempC uses c = 331.3 + 0.606·T.
|
|
51
|
+
*/
|
|
52
|
+
export function distanceMmFromEcho(echoTimeUs, airTempC) {
|
|
53
|
+
if (echoTimeUs === ECHO_TIMEOUT)
|
|
54
|
+
return null;
|
|
55
|
+
const c = airTempC === undefined ? 343.0 : 331.3 + 0.606 * airTempC;
|
|
56
|
+
return (echoTimeUs * c) / 2000.0;
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=sr04.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sr04.js","sourceRoot":"","sources":["../../src/protocol/sr04.ts"],"names":[],"mappings":"AAAA,sDAAsD;AAEtD,MAAM,CAAN,IAAY,OAQX;AARD,WAAY,OAAO;IACjB,4DAAsB,CAAA;IACtB,4DAAsB,CAAA;IACtB,sDAAmB,CAAA;IACnB,sDAAmB,CAAA;IACnB,oDAAkB,CAAA;IAClB,sEAA2B,CAAA;IAC3B,oEAA0B,CAAA;AAC5B,CAAC,EARW,OAAO,KAAP,OAAO,QAQlB;AAED,MAAM,CAAN,IAAY,OAIX;AAJD,WAAY,OAAO;IACjB,uCAAW,CAAA;IACX,uDAAmB,CAAA;IACnB,iDAAgB,CAAA;AAClB,CAAC,EAJW,OAAO,KAAP,OAAO,QAIlB;AAED,+CAA+C;AAC/C,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC;AAEnC,MAAM,CAAC,MAAM,wBAAwB,GAAG,MAAM,CAAC;AAC/C,MAAM,CAAC,MAAM,qBAAqB,GAAG,KAAK,CAAC;AAC3C,MAAM,CAAC,MAAM,iBAAiB,GAAG,KAAK,CAAC;AACvC,MAAM,CAAC,MAAM,iBAAiB,GAAG,MAAM,CAAC;AASxC,MAAM,UAAU,cAAc,CAAC,CAAa;IAC1C,MAAM,CAAC,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;IAC7D,OAAO;QACL,SAAS,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;QACxB,WAAW,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC;QACpC,UAAU,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC;KACjC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;IACtD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,CAAa;IAC9C,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,MAAM,GAAG,GAAG,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IAC9B,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACrD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,CAAa;IAC3C,OAAO,IAAI,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;AAC/E,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAAkB,EAAE,QAAiB;IACtE,IAAI,UAAU,KAAK,YAAY;QAAE,OAAO,IAAI,CAAC;IAC7C,MAAM,CAAC,GAAG,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,KAAK,GAAG,QAAQ,CAAC;IACpE,OAAO,CAAC,UAAU,GAAG,CAAC,CAAC,GAAG,MAAM,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* USB identity table for the DEPZ sensor line (contract 02 §4).
|
|
3
|
+
*
|
|
4
|
+
* VID/PID are *hints only* — the protocol probe (GET_NAME_ACTIVE_SOFTWARE)
|
|
5
|
+
* remains the source of truth for what a device actually is. This table lets
|
|
6
|
+
* discovery pick candidate ports fast and avoid poking unrelated hardware.
|
|
7
|
+
*
|
|
8
|
+
* To add a model: add one row to `DEPZ_USB_MODELS` (and, if it falls outside
|
|
9
|
+
* the recognized ranges below, teach `isKnownDepzUsb`). Mirrors the Python
|
|
10
|
+
* reference `depz_sensor_sdk.usb_ids`.
|
|
11
|
+
*/
|
|
12
|
+
import type { SensorType } from "./identity.js";
|
|
13
|
+
/** Production VID shared by all programmed DEPZ sensors. */
|
|
14
|
+
export declare const DEPZ_VID = 7119;
|
|
15
|
+
/**
|
|
16
|
+
* Dev / unprogrammed default (STMicroelectronics Virtual COM Port). Dev units
|
|
17
|
+
* before product-metadata flashing enumerate here; treated as a candidate.
|
|
18
|
+
*/
|
|
19
|
+
export declare const DEV_VID = 1155;
|
|
20
|
+
export declare const DEV_PID = 22236;
|
|
21
|
+
/**
|
|
22
|
+
* Contiguous production PID block: any PID in this inclusive range under the
|
|
23
|
+
* production VID is treated as a candidate DEPZ sensor even when it is not
|
|
24
|
+
* individually mapped below (e.g. future models, or the recognized-but-not-
|
|
25
|
+
* decodable IMU variants 60937 bno085 / 60938 bno055).
|
|
26
|
+
*/
|
|
27
|
+
export declare const DEPZ_SENSOR_PID_MIN = 60536;
|
|
28
|
+
export declare const DEPZ_SENSOR_PID_MAX = 65535;
|
|
29
|
+
/** A known DEPZ USB PID and what it is. */
|
|
30
|
+
export interface DepzUsbModel {
|
|
31
|
+
/** Human-readable model name. */
|
|
32
|
+
name: string;
|
|
33
|
+
/**
|
|
34
|
+
* Sensor class this SDK can decode, or null for a DEPZ sensor that is
|
|
35
|
+
* recognized but not (yet) driven by this SDK (still opens as a base
|
|
36
|
+
* device / warned about).
|
|
37
|
+
*/
|
|
38
|
+
sensorType: SensorType | null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* PID → model hint. Only the three `sensorType`-bearing rows are decodable by
|
|
42
|
+
* this SDK; the rest are recognized as DEPZ sensors for discovery/labelling.
|
|
43
|
+
* Values mirror the Python reference `depz_sensor_sdk.usb_ids.DEPZ_PID_MODEL`.
|
|
44
|
+
*/
|
|
45
|
+
export declare const DEPZ_USB_MODELS: Readonly<Record<number, DepzUsbModel>>;
|
|
46
|
+
/**
|
|
47
|
+
* True when `(vid, pid)` looks like a DEPZ sensor: the production VID with a
|
|
48
|
+
* mapped PID or a PID in the recognized block, or the dev default. A match
|
|
49
|
+
* means "worth probing", never "definitely this model".
|
|
50
|
+
*/
|
|
51
|
+
export declare function isKnownDepzUsb(vid: number | null | undefined, pid: number | null | undefined): boolean;
|
|
52
|
+
/** Model hint for a PID, or null when unrecognized (informational only). */
|
|
53
|
+
export declare function pidToModel(pid: number | null | undefined): DepzUsbModel | null;
|
|
54
|
+
/**
|
|
55
|
+
* Best-guess model name for a `(vid, pid)`, or null. Informational only —
|
|
56
|
+
* never used to decide how to decode a device; the firmware-name probe does
|
|
57
|
+
* that. Mirrors the Python reference `usb_model_hint`.
|
|
58
|
+
*/
|
|
59
|
+
export declare function usbModelHint(vid: number | null | undefined, pid: number | null | undefined): string | null;
|
|
60
|
+
//# sourceMappingURL=usb-ids.d.ts.map
|
|
@@ -0,0 +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;;;;;GAKG;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;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CASlE,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"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* USB identity table for the DEPZ sensor line (contract 02 §4).
|
|
3
|
+
*
|
|
4
|
+
* VID/PID are *hints only* — the protocol probe (GET_NAME_ACTIVE_SOFTWARE)
|
|
5
|
+
* remains the source of truth for what a device actually is. This table lets
|
|
6
|
+
* discovery pick candidate ports fast and avoid poking unrelated hardware.
|
|
7
|
+
*
|
|
8
|
+
* To add a model: add one row to `DEPZ_USB_MODELS` (and, if it falls outside
|
|
9
|
+
* the recognized ranges below, teach `isKnownDepzUsb`). Mirrors the Python
|
|
10
|
+
* reference `depz_sensor_sdk.usb_ids`.
|
|
11
|
+
*/
|
|
12
|
+
/** Production VID shared by all programmed DEPZ sensors. */
|
|
13
|
+
export const DEPZ_VID = 0x1bcf; // 7119
|
|
14
|
+
/**
|
|
15
|
+
* Dev / unprogrammed default (STMicroelectronics Virtual COM Port). Dev units
|
|
16
|
+
* before product-metadata flashing enumerate here; treated as a candidate.
|
|
17
|
+
*/
|
|
18
|
+
export const DEV_VID = 0x0483; // 1155
|
|
19
|
+
export const DEV_PID = 0x56dc; // 22236
|
|
20
|
+
/**
|
|
21
|
+
* Contiguous production PID block: any PID in this inclusive range under the
|
|
22
|
+
* production VID is treated as a candidate DEPZ sensor even when it is not
|
|
23
|
+
* individually mapped below (e.g. future models, or the recognized-but-not-
|
|
24
|
+
* decodable IMU variants 60937 bno085 / 60938 bno055).
|
|
25
|
+
*/
|
|
26
|
+
export const DEPZ_SENSOR_PID_MIN = 60536; // 0xEC78 (SR04)
|
|
27
|
+
export const DEPZ_SENSOR_PID_MAX = 65535; // whole reserved sensor block (catalog-types.ts)
|
|
28
|
+
/**
|
|
29
|
+
* PID → model hint. Only the three `sensorType`-bearing rows are decodable by
|
|
30
|
+
* this SDK; the rest are recognized as DEPZ sensors for discovery/labelling.
|
|
31
|
+
* Values mirror the Python reference `depz_sensor_sdk.usb_ids.DEPZ_PID_MODEL`.
|
|
32
|
+
*/
|
|
33
|
+
export const DEPZ_USB_MODELS = {
|
|
34
|
+
0xec78: { name: "sr04", sensorType: "sr04" }, // 60536
|
|
35
|
+
0xed40: { name: "vl53l8ch", sensorType: "vl53l8" }, // 60736
|
|
36
|
+
0xed41: { name: "vl53l0x", sensorType: null }, // 60737
|
|
37
|
+
0xed42: { name: "vl53l1cb", sensorType: null }, // 60738
|
|
38
|
+
0xed43: { name: "vl53l1cx", sensorType: null }, // 60739
|
|
39
|
+
0xee08: { name: "bno086", sensorType: "bno086" }, // 60936 — verified on hw: 1bcf:ee08
|
|
40
|
+
0xee09: { name: "bno085", sensorType: null }, // 60937
|
|
41
|
+
0xee0a: { name: "bno055", sensorType: null }, // 60938
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* True when `(vid, pid)` looks like a DEPZ sensor: the production VID with a
|
|
45
|
+
* mapped PID or a PID in the recognized block, or the dev default. A match
|
|
46
|
+
* means "worth probing", never "definitely this model".
|
|
47
|
+
*/
|
|
48
|
+
export function isKnownDepzUsb(vid, pid) {
|
|
49
|
+
if (vid == null || pid == null)
|
|
50
|
+
return false;
|
|
51
|
+
if (vid === DEV_VID && pid === DEV_PID)
|
|
52
|
+
return true;
|
|
53
|
+
if (vid !== DEPZ_VID)
|
|
54
|
+
return false;
|
|
55
|
+
if (pid in DEPZ_USB_MODELS)
|
|
56
|
+
return true;
|
|
57
|
+
return pid >= DEPZ_SENSOR_PID_MIN && pid <= DEPZ_SENSOR_PID_MAX;
|
|
58
|
+
}
|
|
59
|
+
/** Model hint for a PID, or null when unrecognized (informational only). */
|
|
60
|
+
export function pidToModel(pid) {
|
|
61
|
+
if (pid == null)
|
|
62
|
+
return null;
|
|
63
|
+
return DEPZ_USB_MODELS[pid] ?? null;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Best-guess model name for a `(vid, pid)`, or null. Informational only —
|
|
67
|
+
* never used to decide how to decode a device; the firmware-name probe does
|
|
68
|
+
* that. Mirrors the Python reference `usb_model_hint`.
|
|
69
|
+
*/
|
|
70
|
+
export function usbModelHint(vid, pid) {
|
|
71
|
+
if (vid == null || pid == null)
|
|
72
|
+
return null;
|
|
73
|
+
if (vid === DEV_VID && pid === DEV_PID)
|
|
74
|
+
return "dev";
|
|
75
|
+
if (vid === DEPZ_VID)
|
|
76
|
+
return DEPZ_USB_MODELS[pid]?.name ?? null;
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=usb-ids.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usb-ids.js","sourceRoot":"","sources":["../../src/protocol/usb-ids.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,4DAA4D;AAC5D,MAAM,CAAC,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,OAAO;AAEvC;;;GAGG;AACH,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,OAAO;AACtC,MAAM,CAAC,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,QAAQ;AAEvC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,CAAC,CAAC,gBAAgB;AAC1D,MAAM,CAAC,MAAM,mBAAmB,GAAG,KAAK,CAAC,CAAC,iDAAiD;AAc3F;;;;GAIG;AACH,MAAM,CAAC,MAAM,eAAe,GAA2C;IACrE,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,EAAE,QAAQ;IACtD,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,QAAQ;IAC5D,MAAM,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,QAAQ;IACvD,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,QAAQ;IACxD,MAAM,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,QAAQ;IACxD,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,oCAAoC;IACtF,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,QAAQ;IACtD,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,IAAI,EAAE,EAAE,QAAQ;CACvD,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,GAA8B,EAAE,GAA8B;IAC3F,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,IAAI,IAAI;QAAE,OAAO,KAAK,CAAC;IAC7C,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,OAAO;QAAE,OAAO,IAAI,CAAC;IACpD,IAAI,GAAG,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IACnC,IAAI,GAAG,IAAI,eAAe;QAAE,OAAO,IAAI,CAAC;IACxC,OAAO,GAAG,IAAI,mBAAmB,IAAI,GAAG,IAAI,mBAAmB,CAAC;AAClE,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,UAAU,CAAC,GAA8B;IACvD,IAAI,GAAG,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IAC7B,OAAO,eAAe,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC;AACtC,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,YAAY,CAC1B,GAA8B,EAC9B,GAA8B;IAE9B,IAAI,GAAG,IAAI,IAAI,IAAI,GAAG,IAAI,IAAI;QAAE,OAAO,IAAI,CAAC;IAC5C,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG,KAAK,OAAO;QAAE,OAAO,KAAK,CAAC;IACrD,IAAI,GAAG,KAAK,QAAQ;QAAE,OAAO,eAAe,CAAC,GAAG,CAAC,EAAE,IAAI,IAAI,IAAI,CAAC;IAChE,OAAO,IAAI,CAAC;AACd,CAAC"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VL53L8 register-bridge wire codecs (contracts/04_SENSOR_VL53L8.md).
|
|
3
|
+
* Mirrors the Python reference `depz_sensor_sdk.protocol.vl53l8`.
|
|
4
|
+
*/
|
|
5
|
+
export declare enum Vl53l8Cmd {
|
|
6
|
+
ReadReg = 50,
|
|
7
|
+
WriteReg = 51,
|
|
8
|
+
StartStream = 53,
|
|
9
|
+
StopStream = 54
|
|
10
|
+
}
|
|
11
|
+
export declare enum Vl53l8Rpt {
|
|
12
|
+
RegData = 145,
|
|
13
|
+
Vl53Frame = 147
|
|
14
|
+
}
|
|
15
|
+
export declare const READ_MAX_LEN = 2295;
|
|
16
|
+
export declare const CHUNK_SIZE = 2048;
|
|
17
|
+
/** Bytes of frame data per RPT_VL53_FRAME chunk. */
|
|
18
|
+
export declare const STREAM_CHUNK_MAX = 1528;
|
|
19
|
+
/** Max frame_size accepted by START_STREAM. */
|
|
20
|
+
export declare const STREAM_TOTAL_MAX = 8192;
|
|
21
|
+
export declare function packReadReg(addr: number, length: number): Uint8Array;
|
|
22
|
+
export declare function packWriteReg(addr: number, data: Uint8Array): Uint8Array;
|
|
23
|
+
export declare function packStartStream(frameSize: number): Uint8Array;
|
|
24
|
+
/** RPT_REG_DATA payload. */
|
|
25
|
+
export interface RegData {
|
|
26
|
+
/** Echoed READ_REG opcode. */
|
|
27
|
+
cmd: number;
|
|
28
|
+
timestampUs: bigint;
|
|
29
|
+
data: Uint8Array;
|
|
30
|
+
}
|
|
31
|
+
export declare function unpackRegData(payload: Uint8Array): RegData;
|
|
32
|
+
/** One RPT_VL53_FRAME chunk of a (possibly multi-chunk) sensor frame. */
|
|
33
|
+
export interface FrameChunk {
|
|
34
|
+
timestampUs: bigint;
|
|
35
|
+
fullSize: number;
|
|
36
|
+
offset: number;
|
|
37
|
+
data: Uint8Array;
|
|
38
|
+
}
|
|
39
|
+
export declare function unpackFrameChunk(payload: Uint8Array): FrameChunk;
|
|
40
|
+
/**
|
|
41
|
+
* Rebuilds full sensor frames from chunked RPT_VL53_FRAME reports.
|
|
42
|
+
*
|
|
43
|
+
* Rules (contract 04): reset on offset==0; chunks must be contiguous —
|
|
44
|
+
* a gap discards the frame in progress; a frame completes when the
|
|
45
|
+
* accumulated bytes equal `fullSize`.
|
|
46
|
+
*/
|
|
47
|
+
export declare class FrameReassembler {
|
|
48
|
+
completed: number;
|
|
49
|
+
discarded: number;
|
|
50
|
+
private buf;
|
|
51
|
+
private fullSize;
|
|
52
|
+
private timestampUs;
|
|
53
|
+
/** Returns `{ timestampUs, frame }` when a frame completes. */
|
|
54
|
+
feed(chunk: FrameChunk): {
|
|
55
|
+
timestampUs: bigint;
|
|
56
|
+
frame: Uint8Array;
|
|
57
|
+
} | null;
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=vl53l8.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vl53l8.d.ts","sourceRoot":"","sources":["../../src/protocol/vl53l8.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,oBAAY,SAAS;IACnB,OAAO,KAAO;IACd,QAAQ,KAAO;IAEf,WAAW,KAAO;IAClB,UAAU,KAAO;CAClB;AAED,oBAAY,SAAS;IACnB,OAAO,MAAO;IACd,SAAS,MAAO;CACjB;AAMD,eAAO,MAAM,YAAY,OAAO,CAAC;AACjC,eAAO,MAAM,UAAU,OAAO,CAAC;AAC/B,oDAAoD;AACpD,eAAO,MAAM,gBAAgB,OAAO,CAAC;AACrC,+CAA+C;AAC/C,eAAO,MAAM,gBAAgB,OAAO,CAAC;AAErC,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,UAAU,CAMpE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,UAAU,CAKvE;AAED,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAI7D;AAED,4BAA4B;AAC5B,MAAM,WAAW,OAAO;IACtB,8BAA8B;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,UAAU,CAAC;CAClB;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAO1D;AAED,yEAAyE;AACzE,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,UAAU,CAAC;CAClB;AAED,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,UAAU,GAAG,UAAU,CAQhE;AAED;;;;;;GAMG;AACH,qBAAa,gBAAgB;IAC3B,SAAS,SAAK;IACd,SAAS,SAAK;IAEd,OAAO,CAAC,GAAG,CAAqB;IAChC,OAAO,CAAC,QAAQ,CAAK;IACrB,OAAO,CAAC,WAAW,CAAM;IAEzB,+DAA+D;IAC/D,IAAI,CAAC,KAAK,EAAE,UAAU,GAAG;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,UAAU,CAAA;KAAE,GAAG,IAAI;CAqC3E"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VL53L8 register-bridge wire codecs (contracts/04_SENSOR_VL53L8.md).
|
|
3
|
+
* Mirrors the Python reference `depz_sensor_sdk.protocol.vl53l8`.
|
|
4
|
+
*/
|
|
5
|
+
export var Vl53l8Cmd;
|
|
6
|
+
(function (Vl53l8Cmd) {
|
|
7
|
+
Vl53l8Cmd[Vl53l8Cmd["ReadReg"] = 50] = "ReadReg";
|
|
8
|
+
Vl53l8Cmd[Vl53l8Cmd["WriteReg"] = 51] = "WriteReg";
|
|
9
|
+
// 0x34 intentionally unused (gap in the firmware's ID sequence)
|
|
10
|
+
Vl53l8Cmd[Vl53l8Cmd["StartStream"] = 53] = "StartStream";
|
|
11
|
+
Vl53l8Cmd[Vl53l8Cmd["StopStream"] = 54] = "StopStream";
|
|
12
|
+
})(Vl53l8Cmd || (Vl53l8Cmd = {}));
|
|
13
|
+
export var Vl53l8Rpt;
|
|
14
|
+
(function (Vl53l8Rpt) {
|
|
15
|
+
Vl53l8Rpt[Vl53l8Rpt["RegData"] = 145] = "RegData";
|
|
16
|
+
Vl53l8Rpt[Vl53l8Rpt["Vl53Frame"] = 147] = "Vl53Frame";
|
|
17
|
+
})(Vl53l8Rpt || (Vl53l8Rpt = {}));
|
|
18
|
+
// MCU TRANSPORT_PAYLOAD_BUF_SIZE = 2304:
|
|
19
|
+
// WRITE_REG payload = addr(2) + N → N ≤ 2302
|
|
20
|
+
// RPT_REG_DATA = hdr(9) + N → N ≤ 2295
|
|
21
|
+
// The reference tool uses a round 2048 for both directions.
|
|
22
|
+
export const READ_MAX_LEN = 2295;
|
|
23
|
+
export const CHUNK_SIZE = 2048;
|
|
24
|
+
/** Bytes of frame data per RPT_VL53_FRAME chunk. */
|
|
25
|
+
export const STREAM_CHUNK_MAX = 1528;
|
|
26
|
+
/** Max frame_size accepted by START_STREAM. */
|
|
27
|
+
export const STREAM_TOTAL_MAX = 8192;
|
|
28
|
+
export function packReadReg(addr, length) {
|
|
29
|
+
const out = new Uint8Array(4);
|
|
30
|
+
const dv = new DataView(out.buffer);
|
|
31
|
+
dv.setUint16(0, addr, true);
|
|
32
|
+
dv.setUint16(2, length, true);
|
|
33
|
+
return out;
|
|
34
|
+
}
|
|
35
|
+
export function packWriteReg(addr, data) {
|
|
36
|
+
const out = new Uint8Array(2 + data.length);
|
|
37
|
+
new DataView(out.buffer).setUint16(0, addr, true);
|
|
38
|
+
out.set(data, 2);
|
|
39
|
+
return out;
|
|
40
|
+
}
|
|
41
|
+
export function packStartStream(frameSize) {
|
|
42
|
+
const out = new Uint8Array(2);
|
|
43
|
+
new DataView(out.buffer).setUint16(0, frameSize, true);
|
|
44
|
+
return out;
|
|
45
|
+
}
|
|
46
|
+
export function unpackRegData(payload) {
|
|
47
|
+
const dv = new DataView(payload.buffer, payload.byteOffset, payload.byteLength);
|
|
48
|
+
return {
|
|
49
|
+
cmd: dv.getUint8(0),
|
|
50
|
+
timestampUs: dv.getBigUint64(1, true),
|
|
51
|
+
data: payload.slice(9),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
export function unpackFrameChunk(payload) {
|
|
55
|
+
const dv = new DataView(payload.buffer, payload.byteOffset, payload.byteLength);
|
|
56
|
+
return {
|
|
57
|
+
timestampUs: dv.getBigUint64(0, true),
|
|
58
|
+
fullSize: dv.getUint16(8, true),
|
|
59
|
+
offset: dv.getUint16(10, true),
|
|
60
|
+
data: payload.slice(12),
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Rebuilds full sensor frames from chunked RPT_VL53_FRAME reports.
|
|
65
|
+
*
|
|
66
|
+
* Rules (contract 04): reset on offset==0; chunks must be contiguous —
|
|
67
|
+
* a gap discards the frame in progress; a frame completes when the
|
|
68
|
+
* accumulated bytes equal `fullSize`.
|
|
69
|
+
*/
|
|
70
|
+
export class FrameReassembler {
|
|
71
|
+
completed = 0;
|
|
72
|
+
discarded = 0;
|
|
73
|
+
buf = new Uint8Array(0);
|
|
74
|
+
fullSize = 0;
|
|
75
|
+
timestampUs = 0n;
|
|
76
|
+
/** Returns `{ timestampUs, frame }` when a frame completes. */
|
|
77
|
+
feed(chunk) {
|
|
78
|
+
if (chunk.offset === 0) {
|
|
79
|
+
if (this.buf.length > 0 && this.buf.length !== this.fullSize) {
|
|
80
|
+
this.discarded += 1;
|
|
81
|
+
}
|
|
82
|
+
this.buf = chunk.data.slice();
|
|
83
|
+
this.fullSize = chunk.fullSize;
|
|
84
|
+
this.timestampUs = chunk.timestampUs;
|
|
85
|
+
}
|
|
86
|
+
else if (chunk.offset === this.buf.length &&
|
|
87
|
+
this.fullSize === chunk.fullSize &&
|
|
88
|
+
this.buf.length > 0) {
|
|
89
|
+
const next = new Uint8Array(this.buf.length + chunk.data.length);
|
|
90
|
+
next.set(this.buf, 0);
|
|
91
|
+
next.set(chunk.data, this.buf.length);
|
|
92
|
+
this.buf = next;
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
if (this.buf.length > 0)
|
|
96
|
+
this.discarded += 1;
|
|
97
|
+
this.buf = new Uint8Array(0);
|
|
98
|
+
this.fullSize = 0;
|
|
99
|
+
return null;
|
|
100
|
+
}
|
|
101
|
+
if (this.buf.length === this.fullSize && this.fullSize > 0) {
|
|
102
|
+
const frame = this.buf;
|
|
103
|
+
this.buf = new Uint8Array(0);
|
|
104
|
+
this.fullSize = 0;
|
|
105
|
+
this.completed += 1;
|
|
106
|
+
return { timestampUs: this.timestampUs, frame };
|
|
107
|
+
}
|
|
108
|
+
if (this.buf.length > this.fullSize) {
|
|
109
|
+
this.discarded += 1;
|
|
110
|
+
this.buf = new Uint8Array(0);
|
|
111
|
+
this.fullSize = 0;
|
|
112
|
+
}
|
|
113
|
+
return null;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=vl53l8.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vl53l8.js","sourceRoot":"","sources":["../../src/protocol/vl53l8.ts"],"names":[],"mappings":"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"}
|