diff --git a/.github/workflows/html-format.yml b/.github/workflows/html-format.yml new file mode 100644 index 0000000..2f8b429 --- /dev/null +++ b/.github/workflows/html-format.yml @@ -0,0 +1,31 @@ +name: Format HTML + +on: + push: + +permissions: + contents: write + +jobs: + format-html: + if: github.actor != 'github-actions[bot]' + runs-on: ubuntu-latest + env: + PRETTIER_VERSION: 3.3.3 + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: "20" + + - name: Format HTML files + run: npx --yes prettier@${{ env.PRETTIER_VERSION }} --write "**/*.html" + + - name: Commit formatted files + uses: stefanzweifel/git-auto-commit-action@v5 + with: + commit_message: "chore: format HTML files" + file_pattern: "**/*.html" diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..c615276 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,15 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "chrome", + "request": "launch", + "name": "Verisense (localhost)", + "url": "http://localhost:5500/Verisense/index.html", + "webRoot": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/README.md b/README.md index 468bd83..7072a4c 100644 --- a/README.md +++ b/README.md @@ -1,34 +1,227 @@ # webBLEDemos -This examples are Pre-Alpha Releases, what that implies from a support perspective can be found [here](https://shimmersensing.com/wp-content/uploads/2022/04/Shimmer-Support-Policy_27.04.2022.pdf). If you encounter any technical issues, or would like to express interest in shaping future development, please reach out to our support team. -If sufficient interest is registered, we may prioritize building a more fully scoped and robust API. -## Migration notice -In the next 4–8 weeks, we plan to migrate to [`shimmer-web-sdk`](https://github.com/ShimmerResearch/shimmer-web-sdk) as a replacement for `shimmer3r.js` and `verisense.js`. -Migration work has already started on the [`copilot/restructure-repo-for-api-support`](https://github.com/ShimmerResearch/webBLEDemos/tree/copilot/restructure-repo-for-api-support) branch. +Web Bluetooth demos for Shimmer sensor devices, running entirely in the browser with no native app required. -# Requirements -- Shimmer3R -- FW Version >= v1.0.22 +> **Migration note** — this branch replaces the local `shimmer3r.js` / `verisense.js` files with the published [`shimmer-web-sdk`](https://github.com/ShimmerResearch/shimmer-web-sdk) package. If you need the pre-migration setup, check out the [v0.0.1](https://github.com/ShimmerResearch/webBLEDemos/releases/tag/v0.0.1) release tag. -[Gyro Example](https://shimmerresearch.github.io/webBLEDemos/break-gyro/) +> **Pre-Alpha Release** — these demos and the SDK are early-stage software. What that means from a support perspective is described [here](https://shimmersensing.com/wp-content/uploads/2022/04/Shimmer-Support-Policy_27.04.2022.pdf). If you encounter technical issues, or would like to express interest in shaping future development, please reach out to the Shimmer support team. If sufficient interest is registered, we may prioritise building a more fully scoped and robust API. -[EMG Example](https://shimmerresearch.github.io/webBLEDemos/break-emg/) +--- -[200G Accel Example](https://shimmerresearch.github.io/webBLEDemos/punch-highG/) +## Repository Layout -[EMG+GYRO Example](https://shimmerresearch.github.io/webBLEDemos/rythmgame-emggyro/) +``` +break-gyro/ ┐ +break-emg/ │ +punch-highG/ │ +brick/ │ +rythmgame-emggyro/ │ Shimmer3R demos +video-ppg/ │ +spell-gyro/ │ +ShimmerCapture/ ┘ +Verisense/ ← Verisense demo +shimmer-extension/ ← Shimmer3R/Verisense Chrome extension (source; load unpacked in Chrome) +sdk-source.json ← Single source-of-truth for SDK source mode/version +update-local-sdk.ps1 ← Build + sync local SDK artifacts +sync-local-sdk.ps1 ← Sync-only local SDK artifacts +update-local-sdk.cmd ← Windows CMD launcher for update script +``` -[PPG Example](https://shimmerresearch.github.io/webBLEDemos/video-ppg/) +The full Verisense control console now lives in a dedicated repository: -[Two Gyro Example](https://shimmerresearch.github.io/webBLEDemos/brick/) +- [ShimmerResearch/verisense-device-console](https://github.com/ShimmerResearch/verisense-device-console) -[Spell Caster — Gyro Demo](https://shimmerresearch.github.io/webBLEDemos/spell-gyro/) +--- -[Shimmer Capture](https://shimmerresearch.github.io/webBLEDemos/ShimmerCapture/) +## Live Demos -[Shimmer3R Chrome Extension](https://github.com/ShimmerEngineering/webBLEDemos/tree/main/shimmer-extension) source code only, will require loading this locally via Chrome +### Shimmer3R +**Requirements:** Shimmer3R device, firmware ≥ v1.0.22, Chrome/Edge (Web Bluetooth required) -# Requirements -- Verisense +| Demo | Link | +|---|---| +| Gyro breakout game | [break-gyro](https://shimmerresearch.github.io/webBLEDemos/break-gyro/) | +| EMG breakout game | [break-emg](https://shimmerresearch.github.io/webBLEDemos/break-emg/) | +| 200 G accel punch detector | [punch-highG](https://shimmerresearch.github.io/webBLEDemos/punch-highG/) | +| EMG + Gyro rhythm game | [rythmgame-emggyro](https://shimmerresearch.github.io/webBLEDemos/rythmgame-emggyro/) | +| PPG heart-rate visualiser | [video-ppg](https://shimmerresearch.github.io/webBLEDemos/video-ppg/) | +| Two-device gyro brick game | [brick](https://shimmerresearch.github.io/webBLEDemos/brick/) | +| Spell caster (gyro gestures) | [spell-gyro](https://shimmerresearch.github.io/webBLEDemos/spell-gyro/) | +| Data capture / CSV download | [ShimmerCapture](https://shimmerresearch.github.io/webBLEDemos/ShimmerCapture/) | -[Wrist Sensor Example](https://shimmerresearch.github.io/webBLEDemos/Verisense/) +### Verisense +**Requirements:** Verisense device (IMU or Pulse+), Chrome/Edge + +| Demo | Link | +|---|---| +| Wrist sensor (accel + GSR streaming) | [Verisense](https://shimmerresearch.github.io/webBLEDemos/Verisense/) | +| Verisense Device Console (full SDK operations) | [verisense-device-console](https://shimmerresearch.github.io/verisense-device-console/) | + +### Chrome Extension +[Shimmer3R Chrome Extension](https://github.com/ShimmerResearch/webBLEDemos/tree/main/shimmer-extension) — source code only; load via **chrome://extensions → Developer mode → Load unpacked** when you are specifically developing or testing extension features. + +This is optional and is **not required** for running the web demos in this repository. + +--- + +## Local Quickstart + +### Prerequisites + +- Chrome or Edge (Web Bluetooth support required) +- VS Code with the **Live Server** extension +- Node.js and npm (required when `sdk-source.json` uses `local-repo`, `local-version`, or `local-latest`) +- This repo (`webBLEDemos`) checked out next to `shimmer-web-sdk` (required by `update-local-sdk.ps1` / `sync-local-sdk.ps1` unless you pass a custom `-SdkRepoPath`) + +Expected folder layout: + +```text +.../shimmer-web-workspace/ + shimmer-web-sdk/ + webBLEDemos/ +``` + +If your folders are not siblings, use: + +```powershell +powershell -ExecutionPolicy Bypass -File .\update-local-sdk.ps1 -SdkRepoPath "C:\path\to\shimmer-web-sdk" +``` + +### SDK source selection (single location) + +Most demos import from `../shimmer-extension/vendor/shimmer-web-sdk.esm.js`. +The `Verisense` demo imports from `./vendor/shimmer-web-sdk.esm.js`. +The file that controls where vendor artifacts come from is `sdk-source.json`: + +```json +{ + "sourceMode": "local-repo", + "version": "0.1.7" +} +``` + +Supported `sourceMode` values: + +- `local-repo`: build/sync using the current local `shimmer-web-sdk` checkout +- `local-version`: build/sync from a specific local SDK git tag using `version` (for example `0.1.7` resolves to `v0.1.7`) +- `local-latest`: build/sync from the latest local SDK `v*` git tag + +In all modes, demos still import from the same vendored files already in this repo; `sourceMode` only changes which SDK source is used to generate those vendored files before sync. + +How `version` is used: + +- With `local-repo`, `version` is ignored (the current local SDK checkout is used). +- With `local-version`, `version` is required and selects the SDK tag to build (for example `0.1.7` -> `v0.1.7`). +- With `local-latest`, `version` is ignored (latest local `v*` tag is used). + +### 1) Build and sync the local SDK + +If you are using local SDK changes, rebuild and sync the vendored SDK files: + +Script reference: + +| Script | What it does | Typical use | +|---|---|---| +| `update-local-sdk.ps1` | Uses `sdk-source.json`; builds SDK only for `local-repo`, then syncs vendor artifacts | Main workflow after SDK/source changes | +| `sync-local-sdk.ps1` | Uses `sdk-source.json` to sync vendor artifacts only (no build) | You already built SDK elsewhere | +| `update-local-sdk.cmd` | Windows CMD launcher for `update-local-sdk.ps1` | Double-click or cmd.exe usage | + +```powershell +powershell -ExecutionPolicy Bypass -File .\update-local-sdk.ps1 +``` + +First run only (installs dependencies before build): + +```powershell +powershell -ExecutionPolicy Bypass -File .\update-local-sdk.ps1 -InstallDeps +``` + +If Node.js/npm is not installed and you only want to sync already-built vendor artifacts: + +```powershell +powershell -ExecutionPolicy Bypass -File .\update-local-sdk.ps1 -SkipBuild +``` + +Use a specific SDK version (for example `0.1.7`) from one place: + +1. Set `"sourceMode": "local-version"` in `sdk-source.json` +2. Set `"version": "0.1.7"` in `sdk-source.json` +3. Run `powershell -ExecutionPolicy Bypass -File .\update-local-sdk.ps1` + +Switch to latest SDK from one place: + +1. Set `"sourceMode": "local-latest"` in `sdk-source.json` +2. Run `powershell -ExecutionPolicy Bypass -File .\update-local-sdk.ps1` + +Manual equivalent: + +```powershell +cd ../shimmer-web-sdk +powershell -ExecutionPolicy Bypass -File .\build-local-sdk.ps1 +cd ../webBLEDemos +powershell -ExecutionPolicy Bypass -File .\sync-local-sdk.ps1 +``` + +### 2) Run a demo on localhost (required for BLE) + +Open a demo file (for example `Verisense/index.html`) in VS Code and choose **Open with Live Server**. + +Use the localhost URL opened by Live Server (commonly `http://localhost:5500/...`). + +### 3) Connect from the page + +- Click **Connect (BLE)** from the demo page (user gesture is required by the browser). +- For Verisense, you can also use **Connect USB (Serial)**. + +### Troubleshooting + +- If BLE buttons do not work, check the URL is `http://localhost/...` or `https://...` (not `file://...`). +- If a demo fails to import the SDK, run the sync command again from `webBLEDemos` root. +- If you updated SDK code but behavior did not change, re-run `.\update-local-sdk.ps1` from `webBLEDemos`. + +--- + +## `@shimmerresearch/shimmer-web-sdk` SDK + +The demos import the SDK from vendored files in this repository, using relative paths that work both on localhost and on GitHub Pages: + +```js +import { Shimmer3RClient } from '../shimmer-extension/vendor/shimmer-web-sdk.esm.js'; +``` + +This means: + +- Local development uses the vendored SDK file without external CDN dependency. +- GitHub Pages deployments also resolve the same path under the published `webBLEDemos` site. +- The demos work on GitHub Pages as long as vendored SDK files are committed with the site. + +For the Verisense demo in this repository: + +```js +import { VerisenseBleDevice } from './vendor/shimmer-web-sdk.esm.js'; +``` + +### Update vendored SDK from local source + +When you make SDK changes in the sibling `shimmer-web-sdk` repo, run: + +```powershell +powershell -ExecutionPolicy Bypass -File .\update-local-sdk.ps1 +``` + +Windows CMD alternative: + +```cmd +update-local-sdk.cmd +``` + +The sync script uses `sdk-source.json` to copy built artifacts from `shimmer-web-sdk/dist` into both: + +- `webBLEDemos/shimmer-extension/vendor` +- `webBLEDemos/Verisense/vendor` + +Build logic is centralized in `shimmer-web-sdk/build-local-sdk.ps1` and invoked by `update-local-sdk.ps1`. + +Manual copying into vendor folders is no longer required when you use `update-local-sdk.ps1` or `sync-local-sdk.ps1`. + +The SDK source lives at [ShimmerResearch/shimmer-web-sdk](https://github.com/ShimmerResearch/shimmer-web-sdk). diff --git a/ShimmerAPI/README.md b/ShimmerAPI/README.md deleted file mode 100644 index 65ea72e..0000000 --- a/ShimmerAPI/README.md +++ /dev/null @@ -1 +0,0 @@ -API for Shimmer3R \ No newline at end of file diff --git a/ShimmerAPI/shimmer3r.js b/ShimmerAPI/shimmer3r.js deleted file mode 100644 index a83c3fc..0000000 --- a/ShimmerAPI/shimmer3r.js +++ /dev/null @@ -1,973 +0,0 @@ -// --- Shimmer3R over Web Bluetooth: ACK-first Command Flow (v5) -// Adds explicit support for DATA marker (0x00) and **forces 24-bit timestamp** if requested. -// Your note: "timestamp is u24, so layout is: 0x00 [u24 timestamp] " -// This build defaults to u24, and you can also pass { timestampFmt: 'u24' } in the constructor. - -const OPCODES = { DATA: 0x00, INQUIRY_CMD: 0x01, INQUIRY_RSP: 0x02, START_STREAM: 0x07, STOP_STREAM: 0x20, ACK: 0xFF, SAMPLING_RATE: 0x05, SET_SENSORS_CMD: 0x08, SET_GSR_RANGE: 0x21, SET_INTERNAL_EXP_POWER_ENABLE_CMD: 0x5E, START_BT_STEAM_SD_Logging: 0x70, STOP_BT_STEAM_SD_Logging: 0x97}; - -const DEFAULTS = { - SERVICE_UUID: '65333333-a115-11e2-9e9a-0800200ca100', - CHAR_RX_UUID: '65333333-a115-11e2-9e9a-0800200ca102', - CHAR_TX_UUID: '65333333-a115-11e2-9e9a-0800200ca101', -}; - -const TIMESTAMP_FIELD = { - u16: { name: 'TIMESTAMP', fmt: 'u16', endian: 'le', sizeBytes: 2 }, - u24: { name: 'TIMESTAMP', fmt: 'u24', endian: 'le', sizeBytes: 3 }, -}; -const GSR_NAME = 'GSR'; -const GSR_UNCAL_LIMIT_RANGE3 = 683; -const RAW = 'raw'; -const CAL = 'cal'; - -const SHIMMER3_GSR_RESISTANCE_MIN_MAX_KOHMS = [ - [8.0, 63.0], // Range 0 - [63.0, 220.0], // Range 1 - [220.0, 680.0], // Range 2 - [680.0, 4700.0] // Range 3 -]; - - -// --- Sensor bitmap definitions (Shimmer3) --- -export const SensorBitmapShimmer3 = { - SENSOR_A_ACCEL: 0x000080, - SENSOR_GYRO: 0x000040, - SENSOR_MAG: 0x000020, - SENSOR_GSR: 0x000004, - - SENSOR_VBATT: 0x002000, - SENSOR_D_ACCEL: 0x001000, - SENSOR_PRESSURE: 0x040000, - SENSOR_EXG1_24BIT: 0x000010, - SENSOR_EXG2_24BIT: 0x000008, - SENSOR_EXG1_16BIT: 0x100000, - SENSOR_EXG2_16BIT: 0x080000, - SENSOR_BRIDGE_AMP: 0x008000, - SENSOR_ACCEL_ALT: 0x400000, - SENSOR_MAG_ALT: 0x200000, - - SENSOR_EXT_A0: 0x000002, - SENSOR_EXT_A1: 0x000001, - SENSOR_EXT_A2: 0x000800, - SENSOR_INT_A3: 0x000400, - SENSOR_INT_A0: 0x000200, - SENSOR_INT_A1: 0x000100, - SENSOR_INT_A2: 0x800000 -}; - -// Minimal ObjectCluster analogue -export class ObjectCluster { - constructor(deviceId){ - this.deviceId = deviceId; - this.fields = []; - this.raw = null; - } - - /** - * Add a field as a separate series. - * @param {string} name e.g. 'GYRO_X' or 'GYRO_X_RAW' - * @param {number} value - * @param {string|null} unit e.g. 'deg/s', 'g', 'µS', 'counts', 'raw' - * @param {'raw'|'cal'|null} kind tag of the series - */ - add(name, value, unit=null, kind=null){ - this.fields.push({ name, value, unit, kind }); - } - - /** - * Get by name, optionally by kind (when there are both RAW and CAL with same name). - */ - get(name, kind=null){ - return this.fields.find(f => f.name === name && (kind === null || f.kind === kind)) || null; - } -} - - -// Example subset (extend as needed) -const CHANNEL_FORMATS = { - 0x00: { name: 'LN_ACCEL_X', fmt: 'i16', endian: 'le', sizeBytes: 2 }, - 0x01: { name: 'LN_ACCEL_Y', fmt: 'i16', endian: 'le', sizeBytes: 2 }, - 0x02: { name: 'LN_ACCEL_Z', fmt: 'i16', endian: 'le', sizeBytes: 2 }, - 0x04: { name: 'WR_ACCEL_X', fmt: 'i16', endian: 'le', sizeBytes: 2 }, - 0x05: { name: 'WR_ACCEL_Y', fmt: 'i16', endian: 'le', sizeBytes: 2 }, - 0x06: { name: 'WR_ACCEL_Z', fmt: 'i16', endian: 'le', sizeBytes: 2 }, - 0x14: { name: 'HG_ACCEL_X', fmt: 'i12*', endian: 'le', sizeBytes: 2 }, - 0x15: { name: 'HG_ACCEL_Y', fmt: 'i12*', endian: 'le', sizeBytes: 2 }, - 0x16: { name: 'HG_ACCEL_Z', fmt: 'i12*', endian: 'le', sizeBytes: 2 }, - 0x0A: { name: 'GYRO_X', fmt: 'i16', endian: 'le', sizeBytes: 2 }, - 0x0B: { name: 'GYRO_Y', fmt: 'i16', endian: 'le', sizeBytes: 2 }, - 0x0C: { name: 'GYRO_Z', fmt: 'i16', endian: 'le', sizeBytes: 2 }, - 0x07: { name: 'MAG_X', fmt: 'i16', endian: 'le', sizeBytes: 2 }, - 0x08: { name: 'MAG_Y', fmt: 'i16', endian: 'le', sizeBytes: 2 }, - 0x09: { name: 'MAG_Z', fmt: 'i16', endian: 'le', sizeBytes: 2 }, - 0x1D: { name: 'Exg1_Status', fmt: 'u8', endian: 'le', sizeBytes: 1 }, - 0x20: { name: 'Exg2_Status', fmt: 'u8', endian: 'le', sizeBytes: 1 }, - 0x1E: { name: 'Exg1_CH1_24Bit', fmt: 'i24', endian: 'be', sizeBytes: 3 }, - 0x1F: { name: 'Exg1_CH2_24Bit', fmt: 'i24', endian: 'be', sizeBytes: 3 }, - 0x21: { name: 'Exg2_CH1_24Bit', fmt: 'i24', endian: 'be', sizeBytes: 3 }, - 0x22: { name: 'Exg2_CH2_24Bit', fmt: 'i24', endian: 'be', sizeBytes: 3 }, - 0x23: { name: 'Exg1_CH1_16Bit', fmt: 'i16', endian: 'be', sizeBytes: 2 }, - 0x24: { name: 'Exg1_CH2_16Bit', fmt: 'i16', endian: 'be', sizeBytes: 2 }, - 0x25: { name: 'Exg2_CH1_16Bit', fmt: 'i16', endian: 'be', sizeBytes: 2 }, - 0x26: { name: 'Exg2_CH2_16Bit', fmt: 'i16', endian: 'be', sizeBytes: 2 }, - 0x12: { name: 'PPG', fmt: 'i16', endian: 'le', sizeBytes: 2 }, - 0x1C: { name: GSR_NAME, fmt: 'u16', endian: 'le', sizeBytes: 2 } -}; - -export class Shimmer3RClient { - constructor(opts={}){ - this.serviceUUID = opts.serviceUUID || DEFAULTS.SERVICE_UUID; - this.rxUUID = opts.rxUUID || DEFAULTS.CHAR_RX_UUID; - this.txUUID = opts.txUUID || DEFAULTS.CHAR_TX_UUID; - - this.device=null; this.server=null; this.rx=null; this.tx=null; - this._rxBuf=new Uint8Array(0); - this._temps=new Set(); - - this.schema=null; // { timestampFmt, fields[], frameBytes } - this.debug = opts.debug ?? true; - - // Force a specific timestamp width; defaults to 'u24' per your device. - this.forceTimestampFmt = opts.timestampFmt || 'u24'; - - // Stash for ACK+RSP in same notify - this._lastAckRemainder = null; // Uint8Array | null - this.enabledSensors = 0x000000; // store 24-bit bitmask - this.ExpPower = 0; - // NEW: ACK expectation counter and streaming state - this._expectingAck = 0; - this._streaming = false; - this.samplingRateHz = 0; - this.LIMIT_MIN_VALID_USIEMENS = 0.03; - this.gsrRangeSetting = 0; - } - - _log(...a){ if(this.debug) console.log('[Shimmer3R]', ...a); } - _emitStatus(msg){ this._log(msg); this.onStatus?.(msg); } - - async connect(){ - this._emitStatus('Requesting Bluetooth device…'); - this.device = await navigator.bluetooth.requestDevice({ filters:[{services:[this.serviceUUID]}], optionalServices:[this.serviceUUID] }); - this._emitStatus(`Selected: ${this.device.name||'Shimmer3R'}`); - this.server = await this.device.gatt.connect(); - this._emitStatus('GATT connected'); - const svc = await this.server.getPrimaryService(this.serviceUUID); - this.rx = await svc.getCharacteristic(this.rxUUID); - this.tx = await svc.getCharacteristic(this.txUUID); - this._emitStatus('RX/TX obtained'); - await this.tx.startNotifications(); - this.tx.addEventListener('characteristicvaluechanged', this._handleNotify); - this._emitStatus('Notifications started'); - } - - async disconnect(){ - try{ - if(this.tx){ - try{await this.tx.stopNotifications();}catch{} - this.tx.removeEventListener('characteristicvaluechanged', this._handleNotify); - } - if(this.device?.gatt?.connected) this.device.gatt.disconnect(); - } finally { - this.device=this.server=this.rx=this.tx=null; - this._rxBuf=new Uint8Array(0); - this.schema=null; - this._streaming=false; - // Clear cached expansion power state because we're disconnected - this.ExpPower = 0; - this._emitStatus('Disconnected'); - } - } - - _handleNotify = (evt) => { - const chunk = new Uint8Array(evt.target.value.buffer); - this._log('Notify len=', chunk.length, 'data=', chunk); - - // 1) ACK handling only if we are actually expecting an ACK - if (chunk.length >= 1 && chunk[0] === OPCODES.ACK && (this._expectingAck ?? 0) > 0) { - this._log('ACK detected at start of notify (expected)'); - // consume one outstanding ACK expectation - this._expectingAck = Math.max(0, (this._expectingAck || 0) - 1); - - // remainder may be control-plane or stream bytes - const remainder = chunk.slice(1); - this._lastAckRemainder = remainder.length ? remainder : null; - - // wake ACK waiters - this._emitTemp(new Uint8Array([OPCODES.ACK])); - - // If streaming, only append remainder to stream if it *clearly* starts with DATA preamble - if (this._lastAckRemainder) { - if (this._streaming && this._lastAckRemainder[0] === OPCODES.DATA) { - this._log('Appending DATA remainder after ACK to stream buffer'); - this._rxBuf = concatU8(this._rxBuf, this._lastAckRemainder); - } else { - // forward to control-plane waiters - this._log('Forwarding non-DATA remainder to control handlers'); - this._emitTemp(this._lastAckRemainder); - } - this._lastAckRemainder = null; - } - // Don't parse here; let normal flow continue on next notify - return; - } - - // 2) During streaming, *all* bytes (including 0xFF heads) are data-plane - if (this._streaming) { - this._rxBuf = concatU8(this._rxBuf, chunk); - } else { - // Non-streaming → emit to temp listeners (e.g., responses) - this._emitTemp(chunk); - // If we already built schema and non-streaming bytes were actually DATA - // (rare race), keep them as well to avoid losing frames. - if (chunk.length && chunk[0] === OPCODES.DATA) { - this._rxBuf = concatU8(this._rxBuf, chunk); - } - } - - // 3) Try parsing if we have a schema - if (this.schema) { - try { this._parseBySchema(); } - catch (e) { this._log('parseBySchema error:', e); } - } - }; - - /** - * Control the internal expansion power (enable/disable) - * C# equivalent: - * WriteBytes([0x5E, expPower], 0, 2) - * @param {number} expPower - 0 = disable, 1 = enable - */ - async setInternalExpPower(expPower) { - if (!Number.isInteger(expPower) || expPower < 0 || expPower > 1) { - throw new Error('expPower must be 0 (off) or 1 (on)'); - } - if (!this.rx) throw new Error('Not connected (RX missing)'); - - const cmd = new Uint8Array([ - OPCODES.SET_INTERNAL_EXP_POWER_ENABLE_CMD, - expPower & 0xFF, - ]); - - this._emitStatus( - `SET_INTERNAL_EXP_POWER_ENABLE_CMD → ${expPower ? 'ON' : 'OFF'} waiting for ACK…` - ); - - const ackRemainder = await this._writeExpectingAck(cmd, 1500); - - this._emitStatus( - `Expansion power ${expPower ? 'enabled' : 'disabled'} (ACK received).` - ); - this.ExpPower = expPower; - // Notify any UI or caller interested in changes - try { this.onExpPowerChanged?.(expPower); } catch (e) { this._log('onExpPowerChanged handler error', e); } - return { expPower, ackRemainder }; - } - - /** - * Control the GSR Range - * @param {number} gsrRange is between 0 and 4. 0 = 8-63kOhm, 1 = 63-220kOhm, 2 = 220-680kOhm, 3 = 680kOhm-4.7MOhm, 4 = Auto range - */ - async setGSRRange(gsrRange) { - if (!Number.isInteger(gsrRange) || gsrRange < 0 || gsrRange > 4) { - throw new Error('gsr range must be 0-4 value'); - } - if (!this.rx) throw new Error('Not connected (RX missing)'); - - const cmd = new Uint8Array([ - OPCODES.SET_GSR_RANGE, - gsrRange & 0xFF, - ]); - - this._emitStatus( - `SET_GSR_RANGE → waiting for ACK…` - ); - - const ackRemainder = await this._writeExpectingAck(cmd, 1500); - - this._emitStatus( - `SET_GSR_RANGE (ACK received).` - ); - this.gsrRangeSetting = gsrRange; - // Notify any UI or caller interested in changes - return { gsrRange, ackRemainder }; - } - - getInternalExpPower(){ - return this.ExpPower; - } - - getEnabledSensors() { - return this.enabledSensors; - } - - /** - * Enable sensors via a 24-bit bitmask. - * Flow: write → wait for ACK → automatically perform Inquiry to refresh schema. - * @param {number} sensors - 24-bit bitmask of sensors to enable (0–0xFFFFFF). - */ - async setSensors(sensors) { - if (!Number.isFinite(sensors)) { - throw new Error('Sensors must be a finite number'); - } - if (!this.rx) throw new Error('Not connected (RX missing)'); - - // Coerce to uint32 then clamp to 24 bits - sensors = (sensors >>> 0) & 0xFFFFFF; - - const b1 = sensors & 0xFF; - const b2 = (sensors >>> 8) & 0xFF; - const b3 = (sensors >>> 16) & 0xFF; - const cmd = new Uint8Array([OPCODES.SET_SENSORS_CMD, b1, b2, b3]); - - this._emitStatus( - `SET_SENSORS_CMD → bitmask=0x${sensors.toString(16).toUpperCase().padStart(6, '0')} waiting for ACK…` - ); - - const ackRemainder = await this._writeExpectingAck(cmd, 1500); - - this._emitStatus( - `Sensors ACK received. Bitmask 0x${sensors.toString(16).toUpperCase().padStart(6, '0')} applied.` - ); - - // ✅ Automatically trigger inquiry to rebuild schema and detect active sensors - try { - this._emitStatus('Performing automatic inquiry to refresh schema…'); - const info = await this.inquiry(); - this.enabledSensors = info.schema.enabledSensors; - this._emitStatus(`Inquiry complete. Enabled sensors: 0x${this.enabledSensors.toString(16).toUpperCase()}`); - } catch (err) { - this._emitStatus(`Inquiry after setSensors failed: ${err.message}`); - } - - return { sensors, ackRemainder, enabledSensors: this.enabledSensors }; - } - - /** - * Set device sampling rate in Hz. - * Firmware expects a 16-bit divisor: divisor = floor(32768 / rateHz), little-endian. - * Flow: write [0x05, LSB, MSB] → wait for ACK (0xFF) → return applied rate info. - */ - async setSamplingRate(rateHz) { - if (!Number.isFinite(rateHz) || rateHz <= 0) { - throw new Error('Sampling rate must be a positive number (Hz)'); - } - if (!this.rx) throw new Error('Not connected (RX missing)'); - - // Match C#: (int)(32768 / rate) - let divisor = Math.floor(32768 / rateHz); - // keep within 16-bit 1..65535 - if (divisor < 1) divisor = 1; - if (divisor > 0xFFFF) divisor = 0xFFFF; - - const lsb = divisor & 0xFF; - const msb = (divisor >> 8) & 0xFF; - - const cmd = new Uint8Array([OPCODES.SAMPLING_RATE, lsb, msb]); - - this._emitStatus(`Set sampling rate → ${rateHz.toFixed(3)} Hz (divisor=${divisor}) — waiting for ACK…`); - - const ackRemainder = await this._writeExpectingAck(cmd, 1500); - - // Compute the *applied* Hz from what we actually sent - const appliedHz = 32768 / divisor; - - // Update any cached sampling info from Inquiry (purely informational) - this.samplingRateHz = appliedHz; - - this._emitStatus(`Sampling rate ACKed. Applied ≈ ${this.samplingRateHz.toFixed(3)} Hz`); - return { requestedHz: rateHz, appliedHz, divisor, ackRemainder }; - } - - // ---- Commands (ACK then response) ---- - async inquiry(){ - this._emitStatus('INQUIRY_CMD → waiting for ACK then RSP…'); - - const remainder = await this._writeExpectingAck(new Uint8Array([OPCODES.INQUIRY_CMD]), 1500); - if (remainder && remainder[0] === OPCODES.INQUIRY_RSP){ - this._log('Using post-ACK remainder as response'); - const info = this._interpretInquiryResponseShimmer3R(remainder); - this.onInquiry?.(info); return info; - } - const rsp = await this._waitForResponse(OPCODES.INQUIRY_RSP, 2000); - this._emitStatus(`Inquiry RSP (${rsp.length} bytes)`); - const info = this._interpretInquiryResponseShimmer3R(rsp); - this.onInquiry?.(info); return info; - } - /** - * Enable EMG (ADS1292R) in 16-bit mode on EXG1 & EXG2. - * - Powers the internal expansion rail - * - Writes the provided EXG1/EXG2 config pages - * - Enables SENSOR_EXG1_16BIT and SENSOR_EXG2_16BIT via setSensors() - * - Refreshes schema via inquiry() - */ - async enableEMG16Bit() { - if (!this.rx) throw new Error('Not connected (RX missing)'); - - // 1) Program ADS1292R pages (EXG1 then EXG2) - // These are the exact frames you provided. - let writeEXG1Command = new Uint8Array([0x61, 0x00, 0x00, 0x0A, 0x02, 0xA8, 0x10, 0x69, 0x60, 0x20, 0x00, 0x00, 0x02, 0x03]); - let writeEXG2Command = new Uint8Array([0x61, 0x01, 0x00, 0x0A, 0x02, 0xA0, 0x10, 0xE1, 0xE1, 0x00, 0x00, 0x00, 0x02, 0x01]); - const oversamplingRatio = getOversamplingRatioADS1292R(this.samplingRateHz) - writeEXG1Command[4] = (((writeEXG1Command[4] >> 3) << 3) | oversamplingRatio) & 0xFF;//index 4 is where the 1st byte of the exg array - writeEXG2Command[4] = (((writeEXG2Command[4] >> 3) << 3) | oversamplingRatio) & 0xFF;//index 4 is where the 1st byte of the exg array - - // Many firmwares ACK 0x61, but since that can vary, we do a plain write + short sleep. - await this._write(writeEXG1Command); - await new Promise(r => setTimeout(r, 200)); - await this._write(writeEXG2Command); - await new Promise(r => setTimeout(r, 50)); - - // 2) Enable EXG1/EXG2 (16-bit) sensors in the 24-bit bitmap and apply - const targetBits = - (SensorBitmapShimmer3.SENSOR_EXG1_16BIT | - SensorBitmapShimmer3.SENSOR_EXG2_16BIT) >>> 0; - - const newMask = ((this.enabledSensors >>> 0) | targetBits) & 0xFFFFFF; - await this.setSensors(newMask); // this already does an inquiry() to rebuild schema - - this._emitStatus('EMG 16-bit enabled on EXG1 & EXG2. Schema updated.'); - } - - /** - * Enable EMG (ADS1292R) in 16-bit mode on EXG1 & EXG2. - * - Powers the internal expansion rail - * - Writes the provided EXG1/EXG2 config pages - * - Enables SENSOR_EXG1_16BIT and SENSOR_EXG2_16BIT via setSensors() - * - Refreshes schema via inquiry() - */ - async enableEXGTestSignal16Bit() { - if (!this.rx) throw new Error('Not connected (RX missing)'); - - // 1) Program ADS1292R pages (EXG1 then EXG2) - // These are the exact frames you provided. - let writeEXG1Command = new Uint8Array([0x61, 0x00, 0x00, 0x0A, 0x02, 0xAB, 0x10, 0x15, 0x15, 0x00, 0x00, 0x00, 0x02, 0x01]); - let writeEXG2Command = new Uint8Array([0x61, 0x01, 0x00, 0x0A, 0x02, 0xA3, 0x10, 0x15, 0x15, 0x00, 0x00, 0x00, 0x02, 0x01]); - const oversamplingRatio = getOversamplingRatioADS1292R(this.samplingRateHz) - writeEXG1Command[4] = (((writeEXG1Command[4] >> 3) << 3) | oversamplingRatio) & 0xFF;//index 4 is where the 1st byte of the exg array - writeEXG2Command[4] = (((writeEXG2Command[4] >> 3) << 3) | oversamplingRatio) & 0xFF;//index 4 is where the 1st byte of the exg array - - - // Many firmwares ACK 0x61, but since that can vary, we do a plain write + short sleep. - await this._write(writeEXG1Command); - await new Promise(r => setTimeout(r, 200)); - await this._write(writeEXG2Command); - await new Promise(r => setTimeout(r, 50)); - - // 2) Enable EXG1/EXG2 (16-bit) sensors in the 24-bit bitmap and apply - const targetBits = - (SensorBitmapShimmer3.SENSOR_EXG1_16BIT | - SensorBitmapShimmer3.SENSOR_EXG2_16BIT) >>> 0; - - const newMask = ((this.enabledSensors >>> 0) | targetBits) & 0xFFFFFF; - await this.setSensors(newMask); // this already does an inquiry() to rebuild schema - - this._emitStatus('EMG 16-bit enabled on EXG1 & EXG2. Schema updated.'); - } - - async enableECG16Bit() { - if (!this.rx) throw new Error('Not connected (RX missing)'); - - // 1) Program ADS1292R pages (EXG1 then EXG2) - // These are the exact frames you provided. - let writeEXG1Command = new Uint8Array([0x61, 0x00, 0x00, 0x0A, 0x02, 0xA8, 0x10, 0x40, 0x40, 0x2D, 0x00, 0x00, 0x02, 0x03]); - let writeEXG2Command = new Uint8Array([0x61, 0x01, 0x00, 0x0A, 0x02, 0xA0, 0x10, 0x40, 0x47, 0x00, 0x00, 0x00, 0x02, 0x01]); - const oversamplingRatio = getOversamplingRatioADS1292R(this.samplingRateHz) - writeEXG1Command[4] = (((writeEXG1Command[4] >> 3) << 3) | oversamplingRatio) & 0xFF;//index 4 is where the 1st byte of the exg array - writeEXG2Command[4] = (((writeEXG2Command[4] >> 3) << 3) | oversamplingRatio) & 0xFF;//index 4 is where the 1st byte of the exg array - - - // Many firmwares ACK 0x61, but since that can vary, we do a plain write + short sleep. - await this._write(writeEXG1Command); - await new Promise(r => setTimeout(r, 200)); - await this._write(writeEXG2Command); - await new Promise(r => setTimeout(r, 50)); - - // 2) Enable EXG1/EXG2 (16-bit) sensors in the 24-bit bitmap and apply - const targetBits = - (SensorBitmapShimmer3.SENSOR_EXG1_16BIT | - SensorBitmapShimmer3.SENSOR_EXG2_16BIT) >>> 0; - - const newMask = ((this.enabledSensors >>> 0) | targetBits) & 0xFFFFFF; - await this.setSensors(newMask); // this already does an inquiry() to rebuild schema - - this._emitStatus('EMG 16-bit enabled on EXG1 & EXG2. Schema updated.'); - } - - async startStreaming(){ - if (!this.schema) this._emitStatus('Starting stream without schema (not recommended).'); - this._emitStatus('START_STREAM → waiting for ACK…'); - - const remainder = await this._writeExpectingAck(new Uint8Array([OPCODES.START_STREAM]), 1500); - - // Now streaming - this._streaming = true; - - if (remainder && remainder.length){ - if (remainder[0] === OPCODES.DATA) { - this._log('Unexpected DATA after START_STREAM ACK (appending to buffer)'); - this._rxBuf = concatU8(this._rxBuf, remainder); - } else { - this._emitTemp(remainder); // non-DATA control-plane - } - } - this._emitStatus('START_STREAM ACK received; frames should follow'); - } - - async stopStreaming() { - this._emitStatus('STOP_STREAM → sending (no ACK wait)…'); - - try { - await this._write(new Uint8Array([OPCODES.STOP_STREAM])); - this._emitStatus('STOP_STREAM command sent (skipped ACK wait).'); - } catch (err) { - this._emitStatus(`STOP_STREAM write failed: ${err.message}`); - } - - this._streaming = false; // stop treating notifies as data-plane - this._rxBuf = new Uint8Array(0); // optional flush - this._emitStatus('Streaming stopped (ACK skipped for latency tolerance).'); - } - - async startStreamingandLogging(){ - if (!this.schema) this._emitStatus('Starting stream without schema (not recommended).'); - this._emitStatus('START_STREAM → waiting for ACK…'); - - const remainder = await this._writeExpectingAck(new Uint8Array([OPCODES.START_BT_STEAM_SD_Logging]), 1500); - - // Now streaming - this._streaming = true; - - if (remainder && remainder.length){ - if (remainder[0] === OPCODES.DATA) { - this._log('Unexpected DATA after START_STREAM ACK (appending to buffer)'); - this._rxBuf = concatU8(this._rxBuf, remainder); - } else { - this._emitTemp(remainder); // non-DATA control-plane - } - } - this._emitStatus('START_STREAM ACK received; frames should follow'); - } - - async stopStreamingandLogging() { - this._emitStatus('STOP_STREAM → sending (no ACK wait)…'); - - try { - await this._write(new Uint8Array([OPCODES.STOP_BT_STEAM_SD_Logging])); - this._emitStatus('STOP_STREAM command sent (skipped ACK wait).'); - } catch (err) { - this._emitStatus(`STOP_STREAM write failed: ${err.message}`); - } - - this._streaming = false; // stop treating notifies as data-plane - this._rxBuf = new Uint8Array(0); // optional flush - this._emitStatus('Streaming stopped (ACK skipped for latency tolerance).'); - } - - // ---- Inquiry decode → schema ---- - // ✅ Best-practice version of `_interpretInquiryResponseShimmer3R()` and `_buildSchema()` -// This approach mirrors the C# `InterpretDataPacketFormat()` logic more closely. -// It returns a schema object that includes not only field info, but also enabledSensors and packetSize. - - _interpretInquiryResponseShimmer3R(u8) { - let base = 0; - if (u8[0] === OPCODES.INQUIRY_RSP && u8.length >= 2) base = 1; //base is 1 because the first index is the response code - - const adcRaw = u16le(u8, base + 0); - this._log("adc raw: " + adcRaw); - const samplingRateHz = 32768 / adcRaw; - this.samplingRateHz = samplingRateHz; - this._log("sampling rate: " + this.samplingRateHz); - - const cfg = - (BigInt(u8[base+2]) ) | - (BigInt(u8[base+3]) << 8n) | - (BigInt(u8[base+4]) << 16n) | - (BigInt(u8[base+5]) << 24n) | - (BigInt(u8[base+6]) << 32n) | - (BigInt(u8[base+7]) << 40n) | - (BigInt(u8[base+8]) << 48n); - - const internalExpPower = Number((cfg >> 24n) & 0x1n); - const gsrRange = Number((cfg >> 25n) & 0x7n); - this.ExpPower = internalExpPower; - this.gsrRangeSetting = gsrRange; - const numCh = u8[base + 9] ?? 0; - const bufSize = u8[base + 10] ?? 0; - const chStart = base + 11; - const chEnd = chStart + numCh; - const channelIds = [...u8.slice(chStart, chEnd)]; - - // Build schema — fixed to 24-bit timestamp format - const tsFmt = 'u24'; // Always use 24-bit timestamp - const schema = this._buildSchemaFromChannels(channelIds, tsFmt); - - this.schema = schema; - this._log( - `Schema built: timestampFmt=${schema.timestampFmt}, fields=${schema.fields.length}, enabledSensors=0x${schema.enabledSensors.toString(16)}` - ); - this._emitStatus( - `Expansion power ${this.ExpPower ? 'enabled' : 'disabled'} (ACK received).` - ); - return { - opcode: u8[0], - adcRaw, - samplingRateHz, - numChannels: numCh, - bufferSize: bufSize, - channelIds, - schema, - bytes: u8.slice(0) - }; - } - - _buildSchemaFromChannels(channelIds, timestampFmt = 'u24') { - const fields = []; - const ts = timestampFmt === 'u24' ? TIMESTAMP_FIELD.u24 : TIMESTAMP_FIELD.u16; - - // ✅ Include DATA preamble (0x00) in frame size for boundary check - let packetSize = 1 + ts.sizeBytes; // 1 = preamble 0x00 - - let enabledSensors = 0; - - for (const id of channelIds) { - const fmt = CHANNEL_FORMATS[id]; - if (!fmt) { - fields.push({ id, name: `CH_${hex2(id)}`, fmt: 'i16', endian: 'le', sizeBytes: 2 }); - packetSize += 2; - continue; - } - - fields.push({ id, ...fmt }); - packetSize += fmt.sizeBytes || 2; - - // Minimal sensor bitmask mapping (extend as needed) - switch (id) { - case 0x00: case 0x01: case 0x02: - enabledSensors |= SensorBitmapShimmer3.SENSOR_A_ACCEL; break; - case 0x04: case 0x05: case 0x06: - enabledSensors |= SensorBitmapShimmer3.SENSOR_D_ACCEL; break; - case 0x014: case 0x015: case 0x016: - enabledSensors |= SensorBitmapShimmer3.SENSOR_ACCEL_ALT; break; - case 0x07: case 0x08: case 0x09: - enabledSensors |= SensorBitmapShimmer3.SENSOR_MAG; break; - case 0x0A: case 0x0B: case 0x0C: - enabledSensors |= SensorBitmapShimmer3.SENSOR_GYRO; break; - case 0x12: - enabledSensors |= SensorBitmapShimmer3.SENSOR_INT_A1; break; - case 0x1C: - enabledSensors |= SensorBitmapShimmer3.SENSOR_GSR; break; - case 0x23: case 0x24: - enabledSensors |= SensorBitmapShimmer3.SENSOR_EXG1_16BIT; break; - case 0x25: case 0x26: - enabledSensors |= SensorBitmapShimmer3.SENSOR_EXG2_16BIT; break; - case 0x1E: case 0x1F: - enabledSensors |= SensorBitmapShimmer3.SENSOR_EXG1_24BIT; break; - case 0x21: case 0x22: - enabledSensors |= SensorBitmapShimmer3.SENSOR_EXG2_24BIT; break; - default: - console.warn(`⚠️ Unmapped channel ID 0x${id.toString(16)} — added as generic i16.`); - } - } - - this.enabledSensors = enabledSensors; - - return { - timestampFmt, - fields, - frameBytes: packetSize, // ✅ inclusive of preamble - enabledSensors, - dataPreambleByte: 0x00 - }; - } - - _calibrateData(oc){ - const snapshot = [...oc.fields]; // copy so pushes won't affect iteration - for (const field of snapshot) { - if (field.name === GSR_NAME){ - const field = oc.get(GSR_NAME, RAW); - const gsrraw = field?.value ?? null; - //console.log(gsrraw); - let adc12 = (gsrraw & 0x0FFF); - let currentRange = this.gsrRangeSetting; - if (currentRange === 4) { - currentRange = (gsrraw >> 14) & 0x03; // auto-range bits - } - if (currentRange === 3) { - if (adc12 < GSR_UNCAL_LIMIT_RANGE3) { - adc12 = GSR_UNCAL_LIMIT_RANGE3; - } - } - let gsrkOhm = calibrateGsrDataToResistanceFromAmplifierEq(adc12, currentRange); - gsrkOhm = nudgeGsrResistance(gsrkOhm, this.gsrRangeSetting); - let gsrConductanceUSiemens = (1.0 / gsrkOhm) * 1000; - //console.log('uSiemens: ' + gsrConductanceUSiemens + ' ' + this.gsrRangeSetting + ' ' + currentRange); - oc.add(GSR_NAME, gsrConductanceUSiemens, 'uSiemens', CAL); - //oc.add(GSR_NAME, gsr, 'kOhm', CAL); - - } - } - } - - _parseBySchema() { - const sch = this.schema; - if (!sch) { this._log('parse: no schema set; skipping'); return; } - - const preamble = sch.dataPreambleByte ?? 0x00; // 0x00 = DATA marker - const frameBytes = sch.frameBytes >>> 0; // includes preamble + ts + fields - const tsBytes = sch.timestampFmt === 'u16' ? 2 : 3; - const TS_MOD = tsBytes === 3 ? 16777216 : 65536; // 2^24 or 2^16 - - let buf = this._rxBuf; - let frames = 0, drops = 0, anomalies = 0; - - if (this._lastTs === undefined || this._lastTs === null) this._lastTs = 0; - - // Need at least two full frames to assert boundary: [0x00 ...][0x00 ...] - while (buf.length >= frameBytes * 2) { - // Quick preamble test at current offset and next-frame offset - if (buf[0] === preamble && buf[frameBytes] === preamble) { - // --- Peek timestamps from frame #1 and frame #2 to validate boundary --- - let ts1, ts2; - try { - ts1 = (tsBytes === 2) ? u16le(buf, 1) : u24le(buf, 1); - ts2 = (tsBytes === 2) ? u16le(buf, frameBytes + 1) : u24le(buf, frameBytes + 1); - } catch { - // If peek fails, slide one byte and retry - buf = buf.subarray(1); - drops++; - continue; - } - - // Monotonic check modulo TS range: dt must be > 0 (allow wrap) - const dt = ( (ts2 - ts1) % TS_MOD + TS_MOD ) % TS_MOD; - if (dt === 0) { - // False boundary (duplicate ts or corruption) → slide one byte - buf = buf.subarray(1); - drops++; - continue; - } - - // --- Decode *one* frame now that boundary is plausible --- - const frame = buf.subarray(0, frameBytes); - - try { - let cursor = 1; // skip preamble - - const oc = new ObjectCluster(this.device?.name || 'Shimmer3R'); - - // Timestamp - let ts; - if (tsBytes === 2) { ts = u16le(frame, cursor); cursor += 2; } - else { ts = u24le(frame, cursor); cursor += 3; } - oc.add('TIMESTAMP', ts, 'ticks', RAW); - - // Fields - for (const f of sch.fields) { - if (cursor + f.sizeBytes > frame.length) { - throw new Error(`short frame: need ${f.sizeBytes} @${cursor}, have ${frame.length}`); - } - let v; - switch (f.fmt) { - case 'i16': - v = f.endian === 'be' ? sign16(u16be(frame, cursor)) : sign16(u16le(frame, cursor)); - break; - case 'u16': - v = f.endian === 'be' ? u16be(frame, cursor) : u16le(frame, cursor); - break; - case 'i24': - v = f.endian === 'be' ? sign24(u24be(frame, cursor)) : sign24(u24le(frame, cursor)); - break; - case 'u24': - v = f.endian === 'be' ? u24be(frame, cursor) : u24le(frame, cursor); - break; - case 'i12*': { - const msb = frame[cursor] & 0xFF; - const lsb = frame[cursor + 1] & 0xFF; - const raw12 = (msb << 4) | (lsb >> 4); - // Two's complement on 12-bit value - v = (raw12 & 0x800) ? (raw12 - 0x1000) : raw12; - break; - } - case 'u8': v = frame[cursor]; break; - default: v = u16le(frame, cursor); // fallback - } - cursor += f.sizeBytes; - oc.add(f.name, v, null,RAW); - } - - // Optional: anomaly log against lastTs (purely diagnostic) - if (this._lastTs) { - const dLast = ( (ts - this._lastTs) % TS_MOD + TS_MOD ) % TS_MOD; - if (dLast === 0) { - anomalies++; - this._log(`⚠️ Timestamp anomaly#${anomalies}: ts=${ts}, last=${this._lastTs}, Δ=0, frameLen=${frame.length}`); - } - } - this._lastTs = ts; - - this._calibrateData(oc); - - // Emit and consume one frame - this.onStreamFrame?.(oc); - frames++; - buf = buf.subarray(frameBytes); - continue; - } catch (e) { - // If field decode failed despite boundary check, drop 1 byte to resync - this._log('⚠️ frame decode error → sliding 1 byte', e.message); - buf = buf.subarray(1); - drops++; - continue; - } - } - - // ❌ Not aligned: drop 1 byte and retry - buf = buf.subarray(1); - drops++; - if (this.debug && drops % 64 === 1) { - this._log(`resync: dropped ${drops} byte(s) so far; bufLen=${buf.length}`); - } - } - - // Keep remainder for next notify (may be < 2 frames or partial) - this._rxBuf = buf; - - // If we dropped a lot, reset lastTs so future monotonic checks don’t spam - if (drops && drops % 512 === 0) this._lastTs = 0; - - if (this.debug && (frames || drops)) { - this._log(`parse: frames=${frames}, drops=${drops}, leftover=${this._rxBuf.length}`); - } - } - - // ---- Low-level helpers ---- - async _write(u8){ - if(!this.rx) throw new Error('Not connected (RX missing)'); - this._log('Write', u8); - await this.rx.writeValue(u8); - } - - // NEW: helper that increments ACK expectation, writes, and waits - async _writeExpectingAck(u8, ackTimeoutMs = 1000) { - this._expectingAck++; - try { - await this._write(u8); - const rem = await this._waitForAck(ackTimeoutMs); - return rem; // may be null or a Uint8Array (remainder) - } catch (e) { - this._expectingAck = Math.max(0, this._expectingAck - 1); - throw e; - } - } - - _waitForAck(timeoutMs=1000){ - return new Promise((resolve, reject)=>{ - const t = setTimeout(()=>{ this.offTemp(handler); reject(new Error('ACK timeout')); }, timeoutMs); - const handler = (chunk)=>{ - if (!chunk||chunk.length===0) return; - - // pure ACK - if (chunk.length===1 && chunk[0]===OPCODES.ACK){ - clearTimeout(t); this.offTemp(handler); - const rem = this._lastAckRemainder; this._lastAckRemainder=null; - this._log('ACK observed', rem?`(+ remainder len ${rem.length})`:''); - resolve(rem||null); - return; - } - - // concatenated ACK + remainder that got emitted directly to temp listeners - if (chunk[0] === OPCODES.ACK && chunk.length > 1) { - clearTimeout(t); this.offTemp(handler); - const rem = chunk.slice(1); - this._log('ACK observed (inline) (+ remainder len', rem.length, ')'); - resolve(rem); - } - }; - this.onTemp(handler); - }); - } - - _waitForResponse(expectedOpcode, timeoutMs=1500){ - if (this._lastAckRemainder && this._lastAckRemainder[0]===expectedOpcode){ - const rem=this._lastAckRemainder; this._lastAckRemainder=null; this._log('Using stashed remainder for response'); - return Promise.resolve(rem); - } - return new Promise((resolve, reject)=>{ - const t = setTimeout(()=>{ this.offTemp(handler); reject(new Error('Response timeout')); }, timeoutMs); - const handler = (chunk)=>{ - if (!chunk||chunk.length===0) return; - if (chunk.length===1 && chunk[0]===OPCODES.ACK) return; - if (chunk[0]===expectedOpcode){ clearTimeout(t); this.offTemp(handler); resolve(chunk); } - }; - this.onTemp(handler); - }); - } - - onTemp(fn){ this._temps.add(fn); } - offTemp(fn){ this._temps.delete(fn); } - _emitTemp(buf){ this._temps.forEach(fn=>{ try{ fn(buf);}catch(e){ this._log('temp handler error', e);} }); } -} - -function calibrateGsrDataToResistanceFromAmplifierEq(gsrUncalibratedData, range) { - const SHIMMER3_REF_KOHMS = [40.2, 287.0, 1000.0, 3300.0]; - const rFeedback = SHIMMER3_REF_KOHMS[range]; - let volts = 0; - volts = calibrateShimmer3RAdcChannel(gsrUncalibratedData) / 1000.0; // convert mV → V - // Amplifier equation: Rsource = Rfeedback / ((Vout / 0.5) - 1) - const rSource = rFeedback / ((volts / 0.5) - 1.0); - return rSource; // in kΩ -} - -function calibrateShimmer3RAdcChannel(unCalData) { - const offset = 0; - const vRefP = 3; // reference voltage in volts - const gain = 1; - return calibrateU12AdcValue(unCalData, offset, vRefP, gain); -} - -function calibrateU12AdcValue(uncalibratedData, offset, vRefP, gain) { - // Formula: (uncalibrated - offset) * ((vRefP * 1000 / gain) / 4095) - const calibratedData = (uncalibratedData - offset) * (((vRefP * 1000) / gain) / 4095); - return calibratedData; -} - - -// ---- Byte helpers ---- -function concatU8(a,b){ const o=new Uint8Array(a.length+b.length); o.set(a); o.set(b,a.length); return o; } -function u16le(b,o){ return b[o] | (b[o+1]<<8); } -function u16be(b,o){ return (b[o]<<8) | b[o+1]; } -function u24le(b,o){ return b[o] | (b[o+1]<<8) | (b[o+2]<<16); } -function u24be(b,o){ return (b[o]<<16) | (b[o+1]<<8) | b[o+2]; } -function sign16(v){ return (v & 0x8000) ? (v | 0xFFFF0000) : v; } -function sign24(v){ return (v & 0x800000) ? (v | 0xFF000000) : v; } -function hex2(v){ return v.toString(16).padStart(2,'0').toUpperCase(); } -function getOversamplingRatioADS1292R(samplingRate) { - if (!Number.isFinite(samplingRate)) { - throw new TypeError('samplingRate must be a finite number'); - } - if (samplingRate < 0) { - throw new RangeError('samplingRate must be non-negative'); - } - - let oversamplingRatio = 6; // >=4000 - - if (samplingRate < 125) oversamplingRatio = 0; - else if (samplingRate < 250) oversamplingRatio = 1; - else if (samplingRate < 500) oversamplingRatio = 2; - else if (samplingRate < 1000) oversamplingRatio = 3; - else if (samplingRate < 2000) oversamplingRatio = 4; - else if (samplingRate < 4000) oversamplingRatio = 5; - - return oversamplingRatio; -} -function nudgeDouble(valToNudge, minVal, maxVal) { - return Math.max(minVal, Math.min(maxVal, valToNudge)); -} -function nudgeGsrResistance(gsrResistanceKOhms, gsrRangeSetting) { - // In your C# code, rangeSetting == 4 means "no nudge" (pass-through) - if (gsrRangeSetting !== 4) { - const [minVal, maxVal] = SHIMMER3_GSR_RESISTANCE_MIN_MAX_KOHMS[gsrRangeSetting]; - return nudgeDouble(gsrResistanceKOhms, minVal, maxVal); - } - return gsrResistanceKOhms; -} diff --git a/ShimmerCapture/README.md b/ShimmerCapture/README.md index 78793e2..9717360 100644 --- a/ShimmerCapture/README.md +++ b/ShimmerCapture/README.md @@ -1 +1,9 @@ -ShimmerCapture for Shimmer3R (BLE) Example +# ShimmerCapture + +A browser-based data capture tool for the Shimmer3R sensor platform. + +Connect a Shimmer3R over Web Bluetooth, configure sensors and sampling rate, then stream and download the recorded data as a CSV file — no native app or driver required. + +**Requirements:** Shimmer3R device, firmware ≥ v1.0.22, Chrome or Edge (Web Bluetooth required) + +- Live demo URL: [https://shimmerresearch.github.io/webBLEDemos/ShimmerCapture/](https://shimmerresearch.github.io/webBLEDemos/ShimmerCapture/) diff --git a/ShimmerCapture/index.html b/ShimmerCapture/index.html index be36ecb..6467570 100644 --- a/ShimmerCapture/index.html +++ b/ShimmerCapture/index.html @@ -1,185 +1,213 @@ - + - - - - - - ShimmerCapture (Shimmer3R) - - + + + ShimmerCapture (Shimmer3R) + + - - - - -

Shimmer Capture (Shimmer3R BLE)

-
+ + function onFrame(oc) { + if (!signalListInitialized) { + buildSignalList(oc.fields); // now pairs include RAW/CAL + signalListInitialized = true; + } + + if (!isStreaming || !chart) return; + sampleCounter++; + const row = [sampleCounter]; + + for (const ds of chart.data.datasets) { + const { name, kind } = ds._metaSel || {}; + const field = oc.get(name, kind ?? null); + const val = field?.value ?? null; + + const label = ds.label; // "NAME_KIND" + chartData[label].push({ x: sampleCounter, y: val }); + row.push(val); + } + + if (isSaving) fileBuffer.push(row.join(",")); + + for (const ds of chart.data.datasets) { + const label = ds.label; + const arr = chartData[label]; + if (arr.length > 200) arr.splice(0, arr.length - 200); + ds.data = arr; + } + chart.update(); + } + + shimmer.onStatus = (msg) => + (document.getElementById("log").textContent = msg); + + + + + + +

Shimmer Capture (Shimmer3R BLE)

+
@@ -392,20 +443,27 @@

Shimmer Capture (Shimmer3R BLE)

- + - -
- -
-
- - -
- - \ No newline at end of file + +
+ +
+
+ + +
+ + diff --git a/Verisense/README.md b/Verisense/README.md new file mode 100644 index 0000000..c8d5837 --- /dev/null +++ b/Verisense/README.md @@ -0,0 +1,9 @@ +# Verisense Demo + +A browser-based streaming demo for Verisense devices using the `@shimmerresearch/shimmer-web-sdk` SDK. + +The page supports BLE streaming, optional Web Serial connection, operational configuration, and live accel / GSR visualisation. + +**Requirements:** Verisense device (IMU or Pulse+), Chrome or Edge + +- Live demo URL: [https://shimmerresearch.github.io/webBLEDemos/Verisense/](https://shimmerresearch.github.io/webBLEDemos/Verisense/) diff --git a/Verisense/index.html b/Verisense/index.html index 8047f7a..2cadab0 100644 --- a/Verisense/index.html +++ b/Verisense/index.html @@ -1,830 +1,1166 @@ - - - - - - - Verisense Stream (Accel + GSR) - - - -

Verisense Stream (Accel1 + GSR)

- Must be served over https or http://localhost. Click buttons (user gesture required). - -
- -
- - - -
+ + + + + + + Verisense Stream (Accel + GSR) + + + + +

Verisense Stream (Accel1 + GSR)

+ Must be served over https or http://localhost. Click + buttons (user gesture required). + +
+
+ + + + +
+ +
+ + + + + + Status: idle +
-
-
+
Operational Config - +
- - - - (Checkboxes affect parsing immediately; Apply writes to device.) + + + + (Checkboxes affect parsing immediately; Apply writes to + device.)
-
-

Latest accel sample

-
- - -
+
+

Latest accel sample

+
+ + +
-
-

Latest GSR sample

-
- - -
+
+

Latest GSR sample

+
+ + +
-
-

Log

-

-      
- +
+

Log

+

+        
+ +
-
- - - - \ No newline at end of file + const names = formatPendingEventProperties(pending).map( + (p) => `${p.property} (${p.hex})`, + ); + log("pending events:", names.join(", ")); + } catch (e) { + log("pending-events error:", String(e?.message ?? e)); + } + }; + + btnClearPending.onclick = async () => { + try { + if (!v) throw new Error("Not connected"); + await v.clearPendingEvents(); + log("pending events cleared"); + } catch (e) { + log("clear-pending error:", String(e?.message ?? e)); + } + }; + + btnApplyOpCfg.onclick = async () => { + try { + if (!v) throw new Error("Not connected"); + await applyOpConfigToDevice(); + const adc = requireAdcDecoder(v); + log("opcfg applied:", { + accelEnabled: v?.accel1?.enabled, + gsrEnabled: adc?.gsrEnabled, + battEnabled: adc?.battEnabled, + }); + } catch (e) { + log("opcfg apply error:", String(e?.message ?? e)); + } + }; + + btnSync.onclick = async () => { + try { + if (!v) throw new Error("Not connected"); + + setStatus("syncing logged data..."); + log("sync: choose output file..."); + + const fileHandle = await window.showSaveFilePicker({ + suggestedName: `verisense_${new Date().toISOString().replace(/[:.]/g, "-")}.bin`, + types: [ + { + description: "Verisense binary", + accept: { "application/octet-stream": [".bin"] }, + }, + ], + }); + + v.debugSync = true; + + const res = await v.transferLoggedData({ + fileHandle, + timeoutMs: 5000, + maxNack: 5, + maxCrcNack: 5, + onProgress: (p) => log("sync progress:", p), + }); + + setStatus("sync complete"); + log("sync: complete ✅", res); + } catch (e) { + log("sync error:", String(e?.message ?? e)); + console.warn(e); + setStatus("error"); + } + }; + + + diff --git a/Verisense/vendor/.gitkeep b/Verisense/vendor/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/Verisense/vendor/shimmer-web-sdk.cjs b/Verisense/vendor/shimmer-web-sdk.cjs new file mode 100644 index 0000000..511b7d0 --- /dev/null +++ b/Verisense/vendor/shimmer-web-sdk.cjs @@ -0,0 +1,10030 @@ +'use strict'; + +/** + * Container for a single decoded sensor frame. + * + * Mirrors the ObjectCluster concept from the Shimmer C# SDK: + * a named, typed bag of raw and calibrated signal values produced + * by parsing one data packet from a device. + * + * @example + * ```ts + * const oc = new ObjectCluster('MyShimmer3R'); + * oc.add('GYRO_X', rawVal, null, 'raw'); + * oc.add('GYRO_X', degPerSec, 'deg/s', 'cal'); + * + * const cal = oc.get('GYRO_X', 'cal'); + * console.log(cal?.value, cal?.unit); // e.g. 12.5 "deg/s" + * ``` + */ +class ObjectCluster { + constructor(deviceId) { + this.deviceId = deviceId; + this.fields = []; + this.raw = null; + } + /** + * Append a named field to this cluster. + * + * @param name Signal name, e.g. `'GYRO_X'`. + * @param value Numeric value. + * @param unit Optional unit string, e.g. `'deg/s'`, `'µS'`, `'ticks'`. + * @param kind `'raw'` for ADC counts, `'cal'` for calibrated units, or `null`. + */ + add(name, value, unit = null, kind = null) { + this.fields.push({ name, value, unit, kind }); + } + /** + * Look up a field by name and optional kind. + * + * When both a raw and a calibrated version exist for the same signal name, + * pass `kind` to disambiguate. + * + * @returns The matching field, or `null` if not found. + */ + get(name, kind = null) { + return this.fields.find((f) => f.name === name && (kind === null || f.kind === kind)) ?? null; + } + /** + * Return all fields that match the given name (regardless of kind). + */ + getAll(name) { + return this.fields.filter((f) => f.name === name); + } +} + +/** + * Abstract base class shared by all Shimmer device clients. + * + * Provides: + * - A `debug` flag and `_log` helper. + * - Stub implementations of `onStatus` and `onStreamFrame` callback properties. + * - Abstract stubs for `connect`, `disconnect`, `startStreaming`, and `stopStreaming` + * that concrete sub-classes must override. + * + * Sub-classes should call `this._emitStatus(msg)` to surface status strings to + * the application layer without depending on a particular event-emitter library. + */ +class BaseShimmerClient { + constructor(opts = {}) { + /** + * Invoked whenever the client emits a human-readable status message + * (e.g. "GATT connected", "Sampling rate ACKed. Applied ≈ 51.200 Hz"). + */ + this.onStatus = null; + /** + * Invoked for every fully-decoded sensor frame while streaming. + * The exact shape depends on the concrete sub-class: + * - `Shimmer3RClient` passes an {@link ObjectCluster}. + * - `VerisenseBleDevice` passes a streaming packet object (see that class). + */ + this.onStreamFrame = null; + this.debug = opts.debug ?? true; + } + /** Log to console when debug is enabled. */ + _log(...args) { + if (this.debug) + console.log('[Shimmer]', ...args); + } + /** Emit a status message to `onStatus` and to the debug log. */ + _emitStatus(msg) { + this._log(msg); + this.onStatus?.(msg); + } +} + +function toArrayBuffer(u8) { + if (u8.buffer instanceof ArrayBuffer) { + if (u8.byteOffset === 0 && u8.byteLength === u8.buffer.byteLength) + return u8.buffer; + return u8.buffer.slice(u8.byteOffset, u8.byteOffset + u8.byteLength); + } + const out = new Uint8Array(u8.byteLength); + out.set(u8); + return out.buffer; +} +/** + * True if `bytes` is non-empty and every byte equals `value` (0–255). Useful for + * detecting uniform blobs such as erased flash (all `0xFF`) or zeroed regions. + * Returns false for empty or nullish input. + */ +function isUniformByteArray(bytes, value) { + const u8 = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes ?? []); + if (!u8.length) + return false; + const expected = value & 0xff; + for (let i = 0; i < u8.length; i++) { + if (u8[i] !== expected) + return false; + } + return true; +} + +/** + * Escape a value for a CSV cell (RFC 4180 style): whitespace runs — including + * newlines — collapse to a single space, then cells containing a quote or + * comma are quoted with internal quotes doubled. Null/undefined become the + * empty cell. + */ +function csvCell(text) { + const s = String(text ?? '') + .replace(/\s+/g, ' ') + .trim(); + return /[",]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s; +} + +/** + * Device RTC drift estimation over a live connection (DEV-844). + * + * Sample the device clock periodically against the host clock and fit a + * least-squares slope of (device − host) offset vs host time: the + * dimensionless slope × 1e6 is directly the crystal error in ppm, giving a + * usable estimate in hours instead of waiting days between connections. + * Device time resolves to 1/32768 s, so per-sample noise is just transport + * round-trip jitter (~tens of ms); the fit averages it out. Host timestamps + * should be taken at the midpoint of the read round-trip, bounding transport + * latency to ±rtt/2. + * + * Host clock steps (NTP corrections) are a measurement hazard: the wall + * clock jumping mid-series pollutes the least-squares slope while looking + * like device drift (seen live on DEV-844: a −1.4 s Windows NTP step bent + * the fit from 1020 to 1077 ppm). Each sample therefore also records a + * monotonic timestamp (`performance.now()`): wall-vs-monotonic divergence + * between samples attributes a jump to the HOST, which resets the fit + * baseline instead of counting as a device step. + * + * This class is pure bookkeeping — the caller owns the sampling timer, the + * device read, and any UI. Feed it one {@link RtcDriftSampleInput} per read. + */ +class RtcDriftMonitor { + constructor(options = {}) { + this.samples = []; + /** Device clock steps detected across the whole run (survives rebaselines). */ + this.deviceSteps = 0; + /** Host (NTP) clock steps detected; each one rebaselines the fit. */ + this.hostSteps = 0; + this.deviceStepThresholdSeconds = options.deviceStepThresholdSeconds ?? 1; + this.hostStepThresholdSeconds = options.hostStepThresholdSeconds ?? 0.5; + } + /** Drop all samples and step counts (e.g. when starting a new run). */ + reset() { + this.samples.length = 0; + this.deviceSteps = 0; + this.hostSteps = 0; + } + /** + * Drop the samples but keep the step counters. Call when the device time is + * written: a time write moves the offset baseline, so every prior sample is + * invalid and the fit must not straddle the discontinuity. + */ + rebaseline() { + this.samples.length = 0; + } + /** + * Record one device-time reading. Attributes any offset jump before + * recording it: wall-clock elapsed minus monotonic elapsed isolates host + * clock steps (NTP) from device steps. A host step resets the fit baseline + * (the fit must not straddle the discontinuity); a device step is counted + * and kept in-series. + */ + addSample(input) { + const sample = { ...input, offsetSec: input.devSec - input.hostSec }; + const prev = this.samples[this.samples.length - 1]; + const hostStepSec = prev + ? sample.hostSec - prev.hostSec - (sample.perfMs - prev.perfMs) / 1000 + : 0; + if (Math.abs(hostStepSec) > this.hostStepThresholdSeconds) { + this.hostSteps++; + this.samples.length = 0; + this.samples.push(sample); + return { kind: 'host-step', sample, hostStepSec }; + } + if (prev && Math.abs(sample.offsetSec - prev.offsetSec) > this.deviceStepThresholdSeconds) { + this.deviceSteps++; + this.samples.push(sample); + return { kind: 'device-step', sample, deltaSec: sample.offsetSec - prev.offsetSec }; + } + this.samples.push(sample); + return { kind: 'sample', sample }; + } + /** + * Least-squares slope of offset vs host time, in ppm (offset and time are + * both in seconds, so the dimensionless slope × 1e6 is directly ppm). + * Null until two samples spanning a non-zero interval exist. + */ + ppmFit() { + const s = this.samples; + if (s.length < 2) + return null; + const t0 = s[0].hostSec; + const y0 = s[0].offsetSec; + let sx = 0; + let sy = 0; + let sxx = 0; + let sxy = 0; + for (const p of s) { + const x = p.hostSec - t0; + const y = p.offsetSec - y0; + sx += x; + sy += y; + sxx += x * x; + sxy += x * y; + } + const n = s.length; + const denom = n * sxx - sx * sx; + if (denom === 0) + return null; + return ((n * sxy - sx * sy) / denom) * 1e6; + } + /** Elapsed span of the current sample series in minutes (0 when empty). */ + elapsedMinutes() { + const s = this.samples; + if (s.length < 2) + return 0; + return (s[s.length - 1].hostSec - s[0].hostSec) / 60; + } + /** + * CSV rows (header first) of the current series, matching the DEV-844 + * export format: host ISO time, host/device unix seconds, offset, rtt, + * monotonic seconds. + */ + toCsvRows() { + const rows = ['host_iso,host_unix_s,device_unix_s,offset_s,rtt_ms,perf_monotonic_s']; + for (const p of this.samples) { + rows.push(`${new Date(p.hostSec * 1000).toISOString()},${p.hostSec.toFixed(3)},${p.devSec.toFixed(5)},${p.offsetSec.toFixed(3)},${p.rttMs},${(p.perfMs / 1000).toFixed(3)}`); + } + return rows; + } +} + +/** + * Device-agnostic live stream statistics: throughput, packet rate and + * sample-gap-derived packet loss for a real-time sensor stream. + * + * The tracker is fed one call per received packet ({@link StreamStatsTracker.recordPacket}) + * and produces a {@link StreamStatsSnapshot} on demand ({@link StreamStatsTracker.snapshot}). + * + * Loss is derived from gaps in each sub-stream's *monotonic device clock* + * (`lastSampleMillis`), NOT host receive time — host BLE buffering bunches + * packets together and would otherwise create false gaps. Throughput and packet + * rate, by contrast, are measured over a sliding window of host receive time + * (`recvMillis`), which is what "bytes per wall-clock second" means. + */ +/** + * Drop ring events older than `cutoff` (by receive time), but always keep the + * last 2 so the rate/throughput still reflect the most recent delivery even when + * packets arrive less often than the window (big FIFO reads, slow sensors). + */ +function pruneRing(ring, cutoff) { + if (ring.length <= 2) + return ring; + let i = 0; + while (i < ring.length - 2 && ring[i].t < cutoff) + i++; + return i > 0 ? ring.slice(i) : ring; +} +/** + * Accumulates live statistics for one streaming session. Call {@link reset} on + * (re)start, {@link recordPacket} for every decoded packet, {@link recordCrcFail} + * for CRC failures, and {@link snapshot} to read the current numbers. + */ +class StreamStatsTracker { + constructor(opts) { + this.sessionStartMillis = null; + this.resyncDroppedBytes = 0; + this.sensors = new Map(); + this.streams = new Map(); + this.windowMillis = opts?.windowMillis ?? 2000; + } + /** Clear all state. Call when streaming (re)starts. */ + reset() { + this.sessionStartMillis = null; + this.resyncDroppedBytes = 0; + this.sensors.clear(); + this.streams.clear(); + } + getSensor(sensorId) { + let s = this.sensors.get(sensorId); + if (!s) { + s = { sensorId, packets: 0, bytes: 0, crcFails: 0, throughputRing: [] }; + this.sensors.set(sensorId, s); + } + return s; + } + getStream(key, sensorId, label) { + let st = this.streams.get(key); + if (!st) { + st = { + key, + sensorId, + label, + samplingRateHz: null, + samples: 0, + expectedSamples: 0, + lostSamples: 0, + lastSampleMillis: null, + started: false, + rateRing: [], + }; + this.streams.set(key, st); + } + return st; + } + /** Record one received (and decoded) streaming packet. */ + recordPacket(p) { + if (this.sessionStartMillis == null) + this.sessionStartMillis = p.recvMillis; + const sensor = this.getSensor(p.sensorId); + sensor.packets += 1; + sensor.bytes += p.byteLength; + sensor.throughputRing.push({ t: p.recvMillis, bytes: p.byteLength }); + // CRC failures, when a device reports them, are counted via recordCrcFail() + // rather than here, to avoid double-counting a packet also passed in here. + for (const c of p.contributions) { + const st = this.getStream(c.key, p.sensorId, c.label); + st.label = c.label; + st.samplingRateHz = c.samplingRateHz; + st.samples += c.sampleCount; + st.rateRing.push({ + t: p.recvMillis, + n: c.sampleCount, + devFirst: c.firstSampleMillis, + dev: c.lastSampleMillis, + }); + const prev = st.lastSampleMillis; + if (!st.started || + !c.samplingRateHz || + c.samplingRateHz <= 0 || + prev == null || + c.lastSampleMillis == null) { + // No measurable gap yet -> assume every sample we got was expected. + st.expectedSamples += c.sampleCount; + } + else { + const interval = 1000 / c.samplingRateHz; + const delta = c.lastSampleMillis - prev; + if (delta > 0) { + const expected = Math.round(delta / interval); + st.expectedSamples += expected; + st.lostSamples += Math.max(0, expected - c.sampleCount); + } + // delta <= 0 (reorder / duplicate): ignore for loss; still counted in samples. + } + st.started = true; + if (c.lastSampleMillis != null) + st.lastSampleMillis = c.lastSampleMillis; + } + } + /** Record a CRC failure for a (possibly unknown) sensor. */ + recordCrcFail(sensorId) { + const id = sensorId ?? -1; + this.getSensor(id).crcFails += 1; + } + /** + * Record bytes discarded while re-synchronising the frame parser after the + * stream lost alignment (typically a flaky link dropping bytes mid-stream). + */ + recordResyncDrop(byteCount = 1) { + if (byteCount > 0) + this.resyncDroppedBytes += byteCount; + } + prune(nowMillis) { + const cutoff = nowMillis - this.windowMillis; + for (const s of this.sensors.values()) { + s.throughputRing = pruneRing(s.throughputRing, cutoff); + } + for (const st of this.streams.values()) { + st.rateRing = pruneRing(st.rateRing, cutoff); + } + } + /** + * Cadence-relative stall test: a stream is "stalled" only if its newest packet + * is older than a multiple of its own observed packet interval (floored at the + * window). This keeps a stalled stream reading 0 while NOT zeroing a healthy + * stream that simply delivers less often than the window (big FIFO reads, slow + * sensors). Events carry a receive time `t`. + */ + isStalled(ring, nowMillis) { + if (ring.length === 0) + return true; + const newest = ring[ring.length - 1].t; + const avgIntervalMillis = ring.length >= 2 ? (newest - ring[0].t) / (ring.length - 1) : this.windowMillis; + const stallMillis = Math.max(this.windowMillis, 3 * avgIntervalMillis); + return nowMillis - newest > stallMillis; + } + /** + * Achieved sample rate for a sub-stream's windowed events. + * + * Measured over the *device-clock* span of the samples — from the first + * sample of the oldest packet to the last sample of the newest packet (their + * tsMillis), not the host receive-time window. This is robust to bursty BLE + * delivery AND to large packets: one packet can carry hundreds of samples + * spanning several seconds (e.g. a high FIFO watermark), so dividing its count + * by the fixed receive window would over-report. Using the samples' own + * device-time span gives the true rate even from a single packet. A stream + * whose newest packet is older than a cadence-relative threshold reads 0 (see + * {@link isStalled}). + */ + windowRateHz(ring, nowMillis) { + if (this.isStalled(ring, nowMillis)) + return 0; + let totalN = 0; + let oldestFirst = Infinity; + let newestLast = -Infinity; + for (const e of ring) { + totalN += e.n; + if (e.devFirst != null && e.devFirst < oldestFirst) + oldestFirst = e.devFirst; + if (e.dev != null && e.dev > newestLast) + newestLast = e.dev; + } + if (totalN <= 0) + return 0; + // N samples span N-1 intervals over the device-time window, so the rate is + // (N-1) / span. A single packet uses its own first->last sample span; a + // stream with no usable device span (1 sample / no timestamps) reads 0. + const spanMillis = newestLast - oldestFirst; + if (spanMillis > 0 && totalN > 1) + return ((totalN - 1) / spanMillis) * 1000; + return 0; + } + /** + * Windowed throughput (bytes/sec) and packet rate over the *actual* receive + * span of the retained events, robust to packets that arrive less often than + * the window. Bytes/packets are counted after the oldest event (the span's + * start point). Returns 0 if the stream is stalled (see {@link isStalled}). + */ + windowThroughput(ring, nowMillis) { + if (ring.length < 2 || this.isStalled(ring, nowMillis)) + return { bps: 0, packetRateHz: 0 }; + const spanMillis = ring[ring.length - 1].t - ring[0].t; + if (spanMillis <= 0) + return { bps: 0, packetRateHz: 0 }; + let bytesAfterOldest = 0; + for (let i = 1; i < ring.length; i++) + bytesAfterOldest += ring[i].bytes; + const spanSec = spanMillis / 1000; + return { bps: bytesAfterOldest / spanSec, packetRateHz: (ring.length - 1) / spanSec }; + } + /** Produce a snapshot of all statistics as of `nowMillis`. */ + snapshot(nowMillis) { + this.prune(nowMillis); + const perSensor = {}; + for (const s of this.sensors.values()) { + const tp = this.windowThroughput(s.throughputRing, nowMillis); + perSensor[s.sensorId] = { + sensorId: s.sensorId, + packets: s.packets, + bytes: s.bytes, + crcFails: s.crcFails, + windowThroughputBps: tp.bps, + windowPacketRateHz: tp.packetRateHz, + streams: [], + }; + } + let totalPackets = 0; + let totalBytes = 0; + let totalCrcFails = 0; + let totalSamples = 0; + let totalExpected = 0; + let totalLost = 0; + let throughputBps = 0; + for (const sid of Object.keys(perSensor)) { + const s = perSensor[Number(sid)]; + totalPackets += s.packets; + totalBytes += s.bytes; + totalCrcFails += s.crcFails; + throughputBps += s.windowThroughputBps; + } + const streamList = [...this.streams.values()].sort((a, b) => a.key.localeCompare(b.key)); + for (const st of streamList) { + const lossPct = st.expectedSamples > 0 ? (st.lostSamples / st.expectedSamples) * 100 : 0; + const row = { + key: st.key, + sensorId: st.sensorId, + label: st.label, + samplingRateHz: st.samplingRateHz, + samples: st.samples, + expectedSamples: st.expectedSamples, + lostSamples: st.lostSamples, + lossPct, + windowSampleRateHz: this.windowRateHz(st.rateRing, nowMillis), + lastSampleMillis: st.lastSampleMillis, + }; + totalSamples += st.samples; + totalExpected += st.expectedSamples; + totalLost += st.lostSamples; + // A stream's sensor row may not exist if recordPacket was never called for + // it (only possible via a stray CRC-fail id); guard defensively. + const sensorRow = perSensor[st.sensorId]; + if (sensorRow) + sensorRow.streams.push(row); + } + return { + durationMillis: this.sessionStartMillis != null ? Math.max(0, nowMillis - this.sessionStartMillis) : 0, + totalPackets, + totalSamples, + totalBytes, + totalCrcFails, + resyncDroppedBytes: this.resyncDroppedBytes, + throughputBps, + lossPct: totalExpected > 0 ? (totalLost / totalExpected) * 100 : 0, + perSensor, + }; + } +} + +/** + * Shimmer3R BLE protocol opcodes. + * Values taken directly from the Shimmer3 firmware header. + */ +const OPCODES = Object.freeze({ + DATA_PACKET: 0x00, + INQUIRY_COMMAND: 0x01, + INQUIRY_RESPONSE: 0x02, + GET_SAMPLING_RATE_COMMAND: 0x03, + SAMPLING_RATE_RESPONSE: 0x04, + SET_SAMPLING_RATE_COMMAND: 0x05, + TOGGLE_LED_COMMAND: 0x06, + START_STREAMING_COMMAND: 0x07, + SET_SENSORS_COMMAND: 0x08, + SET_WR_ACCEL_RANGE_COMMAND: 0x09, + WR_ACCEL_RANGE_RESPONSE: 0x0a, + GET_WR_ACCEL_RANGE_COMMAND: 0x0b, + SET_CONFIG_SETUP_BYTES_COMMAND: 0x0e, + CONFIG_SETUP_BYTES_RESPONSE: 0x0f, + GET_CONFIG_SETUP_BYTES_COMMAND: 0x10, + SET_LN_ACCEL_CALIBRATION_COMMAND: 0x11, + LN_ACCEL_CALIBRATION_RESPONSE: 0x12, + GET_LN_ACCEL_CALIBRATION_COMMAND: 0x13, + SET_GYRO_CALIBRATION_COMMAND: 0x14, + GYRO_CALIBRATION_RESPONSE: 0x15, + GET_GYRO_CALIBRATION_COMMAND: 0x16, + SET_MAG_CALIBRATION_COMMAND: 0x17, + MAG_CALIBRATION_RESPONSE: 0x18, + GET_MAG_CALIBRATION_COMMAND: 0x19, + SET_WR_ACCEL_CALIBRATION_COMMAND: 0x1a, + WR_ACCEL_CALIBRATION_RESPONSE: 0x1b, + GET_WR_ACCEL_CALIBRATION_COMMAND: 0x1c, + STOP_STREAMING_COMMAND: 0x20, + SET_GSR_RANGE_COMMAND: 0x21, + GSR_RANGE_RESPONSE: 0x22, + GET_GSR_RANGE_COMMAND: 0x23, + DEVICE_VERSION_RESPONSE: 0x25, + GET_ALL_CALIBRATION_COMMAND: 0x2c, + ALL_CALIBRATION_RESPONSE: 0x2d, + GET_FW_VERSION_COMMAND: 0x2e, + FW_VERSION_RESPONSE: 0x2f, + SET_CHARGE_STATUS_LED_COMMAND: 0x30, + CHARGE_STATUS_LED_RESPONSE: 0x31, + GET_CHARGE_STATUS_LED_COMMAND: 0x32, + BUFFER_SIZE_RESPONSE: 0x35, + GET_BUFFER_SIZE_COMMAND: 0x36, + SET_MAG_GAIN_COMMAND: 0x37, + MAG_GAIN_RESPONSE: 0x38, + GET_MAG_GAIN_COMMAND: 0x39, + SET_MAG_SAMPLING_RATE_COMMAND: 0x3a, + MAG_SAMPLING_RATE_RESPONSE: 0x3b, + GET_MAG_SAMPLING_RATE_COMMAND: 0x3c, + UNIQUE_SERIAL_RESPONSE: 0x3d, + GET_UNIQUE_SERIAL_COMMAND: 0x3e, + GET_DEVICE_VERSION_COMMAND: 0x3f, + SET_WR_ACCEL_SAMPLING_RATE_COMMAND: 0x40, + WR_ACCEL_SAMPLING_RATE_RESPONSE: 0x41, + GET_WR_ACCEL_SAMPLING_RATE_COMMAND: 0x42, + SET_WR_ACCEL_LPMODE_COMMAND: 0x43, + WR_ACCEL_LPMODE_RESPONSE: 0x44, + GET_WR_ACCEL_LPMODE_COMMAND: 0x45, + SET_WR_ACCEL_HRMODE_COMMAND: 0x46, + WR_ACCEL_HRMODE_RESPONSE: 0x47, + GET_WR_ACCEL_HRMODE_COMMAND: 0x48, + SET_GYRO_RANGE_COMMAND: 0x49, + GYRO_RANGE_RESPONSE: 0x4a, + GET_GYRO_RANGE_COMMAND: 0x4b, + SET_GYRO_SAMPLING_RATE_COMMAND: 0x4c, + GYRO_SAMPLING_RATE_RESPONSE: 0x4d, + GET_GYRO_SAMPLING_RATE_COMMAND: 0x4e, + SET_ALT_ACCEL_RANGE_COMMAND: 0x4f, + ALT_ACCEL_RANGE_RESPONSE: 0x50, + GET_ALT_ACCEL_RANGE_COMMAND: 0x51, + SET_PRESSURE_OVERSAMPLING_RATIO_COMMAND: 0x52, + PRESSURE_OVERSAMPLING_RATIO_RESPONSE: 0x53, + GET_PRESSURE_OVERSAMPLING_RATIO_COMMAND: 0x54, + BMP180_CALIBRATION_COEFFICIENTS_RESPONSE: 0x58, + GET_BMP180_CALIBRATION_COEFFICIENTS_COMMAND: 0x59, + RESET_TO_DEFAULT_CONFIGURATION_COMMAND: 0x5a, + RESET_CALIBRATION_VALUE_COMMAND: 0x5b, + MPU9150_MAG_SENS_ADJ_VALS_RESPONSE: 0x5c, + GET_MPU9150_MAG_SENS_ADJ_VALS_COMMAND: 0x5d, + SET_INTERNAL_EXP_POWER_ENABLE_COMMAND: 0x5e, + INTERNAL_EXP_POWER_ENABLE_RESPONSE: 0x5f, + GET_INTERNAL_EXP_POWER_ENABLE_COMMAND: 0x60, + SET_EXG_REGS_COMMAND: 0x61, + EXG_REGS_RESPONSE: 0x62, + GET_EXG_REGS_COMMAND: 0x63, + SET_DAUGHTER_CARD_ID_COMMAND: 0x64, + DAUGHTER_CARD_ID_RESPONSE: 0x65, + GET_DAUGHTER_CARD_ID_COMMAND: 0x66, + SET_DAUGHTER_CARD_MEM_COMMAND: 0x67, + DAUGHTER_CARD_MEM_RESPONSE: 0x68, + GET_DAUGHTER_CARD_MEM_COMMAND: 0x69, + SET_DERIVED_CHANNEL_BYTES: 0x6d, + DERIVED_CHANNEL_BYTES_RESPONSE: 0x6e, + GET_DERIVED_CHANNEL_BYTES: 0x6f, + START_SDBT_COMMAND: 0x70, + STATUS_RESPONSE: 0x71, + GET_STATUS_COMMAND: 0x72, + SET_TRIAL_CONFIG_COMMAND: 0x73, + TRIAL_CONFIG_RESPONSE: 0x74, + GET_TRIAL_CONFIG_COMMAND: 0x75, + SET_CENTER_COMMAND: 0x76, + CENTER_RESPONSE: 0x77, + GET_CENTER_COMMAND: 0x78, + SET_SHIMMERNAME_COMMAND: 0x79, + SHIMMERNAME_RESPONSE: 0x7a, + GET_SHIMMERNAME_COMMAND: 0x7b, + SET_EXPID_COMMAND: 0x7c, + EXPID_RESPONSE: 0x7d, + GET_EXPID_COMMAND: 0x7e, + SET_MYID_COMMAND: 0x7f, + MYID_RESPONSE: 0x80, + GET_MYID_COMMAND: 0x81, + SET_NSHIMMER_COMMAND: 0x82, + NSHIMMER_RESPONSE: 0x83, + GET_NSHIMMER_COMMAND: 0x84, + SET_CONFIGTIME_COMMAND: 0x85, + CONFIGTIME_RESPONSE: 0x86, + GET_CONFIGTIME_COMMAND: 0x87, + DIR_RESPONSE: 0x88, + GET_DIR_COMMAND: 0x89, + INSTREAM_CMD_RESPONSE: 0x8a, + SET_CRC_COMMAND: 0x8b, + SET_INFOMEM_COMMAND: 0x8c, + INFOMEM_RESPONSE: 0x8d, + GET_INFOMEM_COMMAND: 0x8e, + SET_RWC_COMMAND: 0x8f, + RWC_RESPONSE: 0x90, + GET_RWC_COMMAND: 0x91, + START_LOGGING_COMMAND: 0x92, + STOP_LOGGING_COMMAND: 0x93, + VBATT_RESPONSE: 0x94, + GET_VBATT_COMMAND: 0x95, + TEST_CONNECTION_COMMAND: 0x96, + STOP_SDBT_COMMAND: 0x97, + SET_CALIB_DUMP_COMMAND: 0x98, + RSP_CALIB_DUMP_COMMAND: 0x99, + GET_CALIB_DUMP_COMMAND: 0x9a, + UPD_CALIB_DUMP_COMMAND: 0x9b, + UPD_SDLOG_CFG_COMMAND: 0x9c, + BMP280_CALIBRATION_COEFFICIENTS_RESPONSE: 0x9f, + GET_BMP280_CALIBRATION_COEFFICIENTS_COMMAND: 0xa0, + GET_BT_VERSION_STR_COMMAND: 0xa1, + BT_VERSION_STR_RESPONSE: 0xa2, + SET_INSTREAM_RESPONSE_ACK_PREFIX_STATE: 0xa3, + SET_DATA_RATE_TEST: 0xa4, + DATA_RATE_TEST_RESPONSE: 0xa5, + PRESSURE_CALIBRATION_COEFFICIENTS_RESPONSE: 0xa6, + GET_PRESSURE_CALIBRATION_COEFFICIENTS_COMMAND: 0xa7, + SET_FACTORY_TEST: 0xa8, + SET_ALT_ACCEL_CALIBRATION_COMMAND: 0xa9, + ALT_ACCEL_CALIBRATION_RESPONSE: 0xaa, + GET_ALT_ACCEL_CALIBRATION_COMMAND: 0xab, + SET_ALT_ACCEL_SAMPLING_RATE_COMMAND: 0xac, + ALT_ACCEL_SAMPLING_RATE_RESPONSE: 0xad, + GET_ALT_ACCEL_SAMPLING_RATE_COMMAND: 0xae, + SET_ALT_MAG_CALIBRATION_COMMAND: 0xaf, + ALT_MAG_CALIBRATION_RESPONSE: 0xb0, + GET_ALT_MAG_CALIBRATION_COMMAND: 0xb1, + SET_ALT_MAG_SAMPLING_RATE_COMMAND: 0xb2, + ALT_MAG_SAMPLING_RATE_RESPONSE: 0xb3, + GET_ALT_MAG_SAMPLING_RATE_COMMAND: 0xb4, + DUMMY_COMMAND: 0xb5, + RESET_BT_ERROR_COUNTS: 0xb6, + SET_FEATURE: 0xb7, + SET_SD_SYNC_COMMAND: 0xe0, + SD_SYNC_RESPONSE: 0xe1, + NACK_COMMAND_PROCESSED: 0xfe, + ACK_COMMAND_PROCESSED: 0xff, +}); +/** Default BLE service / characteristic UUIDs for Shimmer3R. */ +const SHIMMER3R_DEFAULTS = Object.freeze({ + SERVICE_UUID: '65333333-a115-11e2-9e9a-0800200ca100', + /** Write characteristic (host → device). */ + CHAR_RX_UUID: '65333333-a115-11e2-9e9a-0800200ca102', + /** Notify characteristic (device → host). */ + CHAR_TX_UUID: '65333333-a115-11e2-9e9a-0800200ca101', +}); +/** + * Timestamp field descriptors keyed by width. + * Shimmer3R firmware ≥ v1.0.22 always uses u24. + */ +const TIMESTAMP_FIELD = Object.freeze({ + u16: { name: 'TIMESTAMP', fmt: 'u16', endian: 'le', sizeBytes: 2 }, + u24: { name: 'TIMESTAMP', fmt: 'u24', endian: 'le', sizeBytes: 3 }, +}); +/** GSR signal name constant used in ObjectCluster fields. */ +const GSR_NAME = 'GSR'; +/** ADC limit below which GSR range-3 calibration is clamped. */ +const GSR_UNCAL_LIMIT_RANGE3 = 683; +/** + * Shimmer3R GSR resistance min/max per hardware range (kΩ). + * Index 0 = range 0 (8–63 kΩ) … index 3 = range 3 (680–4700 kΩ). + */ +const SHIMMER3_GSR_RESISTANCE_MIN_MAX_KOHMS = [ + [8.0, 63.0], + [63.0, 220.0], + [220.0, 680.0], + [680.0, 4700.0], +]; + +/** + * Sensor enable bitmasks for Shimmer3 / Shimmer3R. + * + * Values are 24-bit integers sent as the payload of SET_SENSORS_CMD. + * Multiple sensors are ORed together. + * + * @example + * ```ts + * const mask = SensorBitmapShimmer3.SENSOR_GYRO | SensorBitmapShimmer3.SENSOR_A_ACCEL; + * await client.setSensors(mask); + * ``` + */ +const SensorBitmapShimmer3 = Object.freeze({ + SENSOR_A_ACCEL: 0x000080, + SENSOR_GYRO: 0x000040, + SENSOR_MAG: 0x000020, + SENSOR_GSR: 0x000004, + SENSOR_VBATT: 0x002000, + SENSOR_D_ACCEL: 0x001000, + SENSOR_PRESSURE: 0x040000, + SENSOR_EXG1_24BIT: 0x000010, + SENSOR_EXG2_24BIT: 0x000008, + SENSOR_EXG1_16BIT: 0x100000, + SENSOR_EXG2_16BIT: 0x080000, + SENSOR_BRIDGE_AMP: 0x008000, + SENSOR_ACCEL_ALT: 0x400000, + SENSOR_MAG_ALT: 0x200000, + SENSOR_EXT_A0: 0x000002, + SENSOR_EXT_A1: 0x000001, + SENSOR_EXT_A2: 0x000800, + SENSOR_INT_A3: 0x000400, + SENSOR_INT_A0: 0x000200, + SENSOR_INT_A1: 0x000100, + SENSOR_INT_A2: 0x800000, +}); + +/** + * Mapping from Shimmer3R channel ID byte to its format descriptor. + * Channel IDs are reported in the INQUIRY_RSP payload. + */ +const CHANNEL_FORMATS = Object.freeze({ + 0x00: { name: 'LN_ACCEL_X', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x01: { name: 'LN_ACCEL_Y', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x02: { name: 'LN_ACCEL_Z', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x04: { name: 'WR_ACCEL_X', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x05: { name: 'WR_ACCEL_Y', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x06: { name: 'WR_ACCEL_Z', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x14: { name: 'HG_ACCEL_X', fmt: 'i12*', endian: 'le', sizeBytes: 2 }, + 0x15: { name: 'HG_ACCEL_Y', fmt: 'i12*', endian: 'le', sizeBytes: 2 }, + 0x16: { name: 'HG_ACCEL_Z', fmt: 'i12*', endian: 'le', sizeBytes: 2 }, + 0x0a: { name: 'GYRO_X', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x0b: { name: 'GYRO_Y', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x0c: { name: 'GYRO_Z', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x07: { name: 'MAG_X', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x08: { name: 'MAG_Y', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x09: { name: 'MAG_Z', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x1d: { name: 'Exg1_Status', fmt: 'u8', endian: 'le', sizeBytes: 1 }, + 0x20: { name: 'Exg2_Status', fmt: 'u8', endian: 'le', sizeBytes: 1 }, + 0x1e: { name: 'Exg1_CH1_24Bit', fmt: 'i24', endian: 'be', sizeBytes: 3 }, + 0x1f: { name: 'Exg1_CH2_24Bit', fmt: 'i24', endian: 'be', sizeBytes: 3 }, + 0x21: { name: 'Exg2_CH1_24Bit', fmt: 'i24', endian: 'be', sizeBytes: 3 }, + 0x22: { name: 'Exg2_CH2_24Bit', fmt: 'i24', endian: 'be', sizeBytes: 3 }, + 0x23: { name: 'Exg1_CH1_16Bit', fmt: 'i16', endian: 'be', sizeBytes: 2 }, + 0x24: { name: 'Exg1_CH2_16Bit', fmt: 'i16', endian: 'be', sizeBytes: 2 }, + 0x25: { name: 'Exg2_CH1_16Bit', fmt: 'i16', endian: 'be', sizeBytes: 2 }, + 0x26: { name: 'Exg2_CH2_16Bit', fmt: 'i16', endian: 'be', sizeBytes: 2 }, + 0x12: { name: 'PPG', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x1c: { name: 'GSR', fmt: 'u16', endian: 'le', sizeBytes: 2 }, +}); + +// --------------------------------------------------------------------------- +// ADC helpers +// --------------------------------------------------------------------------- +/** + * Convert a Shimmer3R 12-bit ADC value to millivolts. + * + * @param unCalData Raw 12-bit ADC sample. + * @param offset ADC offset (typically 0). + * @param vRefP Reference voltage in volts (typically 3 V for Shimmer3R). + * @param gain Amplifier gain (typically 1). + * @returns Calibrated voltage in millivolts. + */ +function calibrateU12AdcValue(unCalData, offset, vRefP, gain) { + return (unCalData - offset) * ((vRefP * 1000) / gain / 4095); +} +/** + * Convert a Shimmer3R ADC channel value to millivolts using the + * default Shimmer3R ADC parameters (Vref = 3 V, gain = 1, offset = 0). + * + * @param unCalData Raw 12-bit ADC sample. + * @returns Voltage in millivolts. + */ +function calibrateShimmer3RAdcChannel(unCalData) { + return calibrateU12AdcValue(unCalData, 0, 3, 1); +} +// --------------------------------------------------------------------------- +// GSR calibration +// --------------------------------------------------------------------------- +/** + * Convert a raw GSR ADC sample to skin resistance (kΩ) using the + * Shimmer3R amplifier equation. + * + * Reference resistors per range (kΩ): [40.2, 287.0, 1000.0, 3300.0]. + * + * @param gsrUncalibratedData Raw 12-bit GSR ADC value. + * @param range Hardware range index 0–3. + * @returns Resistance in kΩ. + */ +function calibrateGsrDataToResistanceFromAmplifierEq(gsrUncalibratedData, range) { + const SHIMMER3_REF_KOHMS = [40.2, 287.0, 1000.0, 3300.0]; + const rFeedback = SHIMMER3_REF_KOHMS[range]; + const volts = calibrateShimmer3RAdcChannel(gsrUncalibratedData) / 1000.0; // mV → V + const rSource = rFeedback / (volts / 0.5 - 1.0); + return rSource; +} +/** + * Clamp a GSR resistance value to the physical limits of a given range. + * + * When `gsrRangeSetting === 4` (auto-range) no clamping is applied. + * + * @param gsrResistanceKOhms Calibrated resistance in kΩ. + * @param gsrRangeSetting Range 0–3 (fixed) or 4 (auto). + * @returns Clamped resistance in kΩ. + */ +function nudgeGsrResistance(gsrResistanceKOhms, gsrRangeSetting) { + if (gsrRangeSetting === 4) + return gsrResistanceKOhms; + const [minVal, maxVal] = SHIMMER3_GSR_RESISTANCE_MIN_MAX_KOHMS[gsrRangeSetting]; + return Math.max(minVal, Math.min(maxVal, gsrResistanceKOhms)); +} +// --------------------------------------------------------------------------- +// ExG (ADS1292R) oversampling ratio +// --------------------------------------------------------------------------- +/** + * Determine the ADS1292R oversampling ratio config byte for a given + * Shimmer3R sampling rate. + * + * This value is ORed into the lower 3 bits of ExG config byte index 4. + * + * @param samplingRate Shimmer3R sampling rate in Hz (must be ≥ 0). + * @returns Oversampling ratio index 0–6. + */ +function getOversamplingRatioADS1292R(samplingRate) { + if (!Number.isFinite(samplingRate)) { + throw new TypeError('samplingRate must be a finite number'); + } + if (samplingRate < 0) { + throw new RangeError('samplingRate must be non-negative'); + } + if (samplingRate < 125) + return 0; + if (samplingRate < 250) + return 1; + if (samplingRate < 500) + return 2; + if (samplingRate < 1000) + return 3; + if (samplingRate < 2000) + return 4; + if (samplingRate < 4000) + return 5; + return 6; // ≥ 4000 Hz +} + +/** + * Low-level byte-manipulation utilities used by the Shimmer3R protocol decoder. + * All functions are pure and have no side-effects, making them straightforward + * to unit-test without a BLE device. + */ +/** Concatenate two Uint8Arrays. */ +function concatU8(a, b) { + const out = new Uint8Array(a.length + b.length); + out.set(a); + out.set(b, a.length); + return out; +} +/** Read a 16-bit unsigned integer, little-endian. */ +function u16le$2(b, o) { + return (b[o] | (b[o + 1] << 8)) >>> 0; +} +/** Read a 16-bit unsigned integer, big-endian. */ +function u16be(b, o) { + return ((b[o] << 8) | b[o + 1]) >>> 0; +} +/** Read a 24-bit unsigned integer, little-endian. */ +function u24le$1(b, o) { + return (b[o] | (b[o + 1] << 8) | (b[o + 2] << 16)) >>> 0; +} +/** Read a 24-bit unsigned integer, big-endian. */ +function u24be(b, o) { + return ((b[o] << 16) | (b[o + 1] << 8) | b[o + 2]) >>> 0; +} +/** Sign-extend a 16-bit value to a signed integer. */ +function sign16(v) { + return v & 0x8000 ? v | 0xffff0000 : v; +} +/** Sign-extend a 24-bit value to a signed integer. */ +function sign24(v) { + return v & 0x800000 ? v | 0xff000000 : v; +} +/** Format a byte as a 2-digit uppercase hex string. */ +function hex2(v) { + return v.toString(16).padStart(2, '0').toUpperCase(); +} + +// --------------------------------------------------------------------------- +// Shimmer3RClient +// --------------------------------------------------------------------------- +/** + * Web Bluetooth client for the Shimmer3R sensor platform. + * + * Implements the ACK-first command flow used by Shimmer3R firmware ≥ v1.0.22: + * every configuration command awaits an ACK (0xFF) before resolving. + * Streaming data frames are framed with a DATA preamble (0x00). + * + * @example + * ```ts + * const client = new Shimmer3RClient({ timestampFmt: 'u24', debug: true }); + * client.onStatus = (msg) => console.log(msg); + * client.onStreamFrame = (oc) => { + * const gz = oc.get('GYRO_Z', 'raw')?.value; + * console.log('gz =', gz); + * }; + * + * await client.connect(); + * await client.setSamplingRate(51.2); + * await client.setSensors(SensorBitmapShimmer3.SENSOR_GYRO); + * await client.startStreaming(); + * ``` + */ +class Shimmer3RClient extends BaseShimmerClient { + constructor(opts = {}) { + super(opts); + this.device = null; + this.server = null; + this.rx = null; + this.tx = null; + // Protocol state + this._rxBuf = new Uint8Array(0); + this._temps = new Set(); + this.schema = null; + this._lastAckRemainder = null; + this._expectingAck = 0; + this._streaming = false; + this._lastTs = 0; + // Cached device configuration + this.enabledSensors = 0x000000; + this.samplingRateHz = 0; + this.gsrRangeSetting = 0; + this.ExpPower = 0; + /** Minimum valid GSR conductance in µS (below this, connectivity = "Disconnected"). */ + this.LIMIT_MIN_VALID_USIEMENS = 0.03; + // Callbacks + this.onInquiry = null; + this.onExpPowerChanged = null; + // --------------------------------------------------------------------------- + // BLE notify handler + // --------------------------------------------------------------------------- + this._handleNotify = (evt) => { + const chunk = new Uint8Array(evt.target.value.buffer); + this._log('Notify len=', chunk.length, 'data=', chunk); + // 1) Consume an expected ACK + if (chunk.length >= 1 && + chunk[0] === OPCODES.ACK_COMMAND_PROCESSED && + (this._expectingAck ?? 0) > 0) { + this._log('ACK detected at start of notify (expected)'); + this._expectingAck = Math.max(0, this._expectingAck - 1); + const remainder = chunk.slice(1); + this._lastAckRemainder = remainder.length ? remainder : null; + this._emitTemp(new Uint8Array([OPCODES.ACK_COMMAND_PROCESSED])); + if (this._lastAckRemainder) { + if (this._streaming && this._lastAckRemainder[0] === OPCODES.DATA_PACKET) { + this._log('Appending DATA remainder after ACK to stream buffer'); + this._rxBuf = concatU8(this._rxBuf, this._lastAckRemainder); + } + else { + this._log('Forwarding non-DATA remainder to control handlers'); + this._emitTemp(this._lastAckRemainder); + } + this._lastAckRemainder = null; + } + return; + } + // 2) During streaming, all bytes are data-plane + if (this._streaming) { + this._rxBuf = concatU8(this._rxBuf, chunk); + } + else { + this._emitTemp(chunk); + if (chunk.length && chunk[0] === OPCODES.DATA_PACKET) { + this._rxBuf = concatU8(this._rxBuf, chunk); + } + } + // 3) Try parsing if schema is available + if (this.schema) { + try { + this._parseBySchema(); + } + catch (e) { + this._log('parseBySchema error:', e); + } + } + }; + this.serviceUUID = opts.serviceUUID ?? SHIMMER3R_DEFAULTS.SERVICE_UUID; + this.rxUUID = opts.rxUUID ?? SHIMMER3R_DEFAULTS.CHAR_RX_UUID; + this.txUUID = opts.txUUID ?? SHIMMER3R_DEFAULTS.CHAR_TX_UUID; + this.forceTimestampFmt = opts.timestampFmt ?? 'u24'; + } + _log(...args) { + if (this.debug) + console.log('[Shimmer3R]', ...args); + } + // --------------------------------------------------------------------------- + // Connection management + // --------------------------------------------------------------------------- + async connect() { + this._emitStatus('Requesting Bluetooth device…'); + this.device = await navigator.bluetooth.requestDevice({ + filters: [{ services: [this.serviceUUID] }], + optionalServices: [this.serviceUUID], + }); + this._emitStatus(`Selected: ${this.device.name ?? 'Shimmer3R'}`); + this.server = await this.device.gatt.connect(); + this._emitStatus('GATT connected'); + const svc = await this.server.getPrimaryService(this.serviceUUID); + this.rx = await svc.getCharacteristic(this.rxUUID); + this.tx = await svc.getCharacteristic(this.txUUID); + this._emitStatus('RX/TX obtained'); + await this.tx.startNotifications(); + this.tx.addEventListener('characteristicvaluechanged', this._handleNotify); + this._emitStatus('Notifications started'); + } + async disconnect() { + try { + if (this.tx) { + try { + await this.tx.stopNotifications(); + } + catch { + /* ignore */ + } + this.tx.removeEventListener('characteristicvaluechanged', this._handleNotify); + } + if (this.device?.gatt?.connected) + this.device.gatt.disconnect(); + } + finally { + this.device = this.server = this.rx = this.tx = null; + this._rxBuf = new Uint8Array(0); + this.schema = null; + this._streaming = false; + this.ExpPower = 0; + this._emitStatus('Disconnected'); + } + } + // --------------------------------------------------------------------------- + // Configuration commands + // --------------------------------------------------------------------------- + /** + * Control the internal expansion power rail (required for ExG/EMG/ECG). + * @param expPower 0 = disable, 1 = enable. + */ + async setInternalExpPower(expPower) { + if (expPower !== 0 && expPower !== 1) + throw new Error('expPower must be 0 (off) or 1 (on)'); + if (!this.rx) + throw new Error('Not connected (RX missing)'); + const cmd = new Uint8Array([OPCODES.SET_INTERNAL_EXP_POWER_ENABLE_COMMAND, expPower]); + this._emitStatus(`SET_INTERNAL_EXP_POWER_ENABLE_CMD → ${expPower ? 'ON' : 'OFF'} waiting for ACK…`); + const ackRemainder = await this._writeExpectingAck(cmd, 1500); + this._emitStatus(`Expansion power ${expPower ? 'enabled' : 'disabled'} (ACK received).`); + this.ExpPower = expPower; + try { + this.onExpPowerChanged?.(expPower); + } + catch (e) { + this._log('onExpPowerChanged handler error', e); + } + return { expPower, ackRemainder }; + } + /** + * Set the GSR measurement range. + * @param gsrRange 0 = 8–63 kΩ, 1 = 63–220 kΩ, 2 = 220–680 kΩ, 3 = 680–4700 kΩ, 4 = Auto. + */ + async setGSRRange(gsrRange) { + if (!Number.isInteger(gsrRange) || gsrRange < 0 || gsrRange > 4) { + throw new Error('gsrRange must be 0–4'); + } + if (!this.rx) + throw new Error('Not connected (RX missing)'); + const cmd = new Uint8Array([OPCODES.SET_GSR_RANGE_COMMAND, gsrRange & 0xff]); + this._emitStatus('SET_GSR_RANGE → waiting for ACK…'); + const ackRemainder = await this._writeExpectingAck(cmd, 1500); + this._emitStatus('SET_GSR_RANGE (ACK received).'); + this.gsrRangeSetting = gsrRange; + return { gsrRange, ackRemainder }; + } + getInternalExpPower() { + return this.ExpPower; + } + getEnabledSensors() { + return this.enabledSensors; + } + /** + * Enable sensors via a 24-bit bitmask. + * Automatically performs an Inquiry after ACK to rebuild the stream schema. + */ + async setSensors(sensors) { + if (!Number.isFinite(sensors)) + throw new Error('sensors must be a finite number'); + if (!this.rx) + throw new Error('Not connected (RX missing)'); + sensors = (sensors >>> 0) & 0xffffff; + const b1 = sensors & 0xff; + const b2 = (sensors >>> 8) & 0xff; + const b3 = (sensors >>> 16) & 0xff; + const cmd = new Uint8Array([OPCODES.SET_SENSORS_COMMAND, b1, b2, b3]); + this._emitStatus(`SET_SENSORS_CMD → bitmask=0x${sensors.toString(16).toUpperCase().padStart(6, '0')} waiting for ACK…`); + const ackRemainder = await this._writeExpectingAck(cmd, 1500); + this._emitStatus(`Sensors ACK received. Bitmask 0x${sensors.toString(16).toUpperCase().padStart(6, '0')} applied.`); + try { + this._emitStatus('Performing automatic inquiry to refresh schema…'); + const info = await this.inquiry(); + this.enabledSensors = info.schema.enabledSensors; + this._emitStatus(`Inquiry complete. Enabled sensors: 0x${this.enabledSensors.toString(16).toUpperCase()}`); + } + catch (err) { + this._emitStatus(`Inquiry after setSensors failed: ${err.message}`); + } + return { sensors, ackRemainder, enabledSensors: this.enabledSensors }; + } + /** + * Set the sampling rate. + * The firmware expects a 16-bit divisor: `divisor = floor(32768 / rateHz)`. + */ + async setSamplingRate(rateHz) { + if (!Number.isFinite(rateHz) || rateHz <= 0) { + throw new Error('Sampling rate must be a positive number (Hz)'); + } + if (!this.rx) + throw new Error('Not connected (RX missing)'); + let divisor = Math.floor(32768 / rateHz); + divisor = Math.max(1, Math.min(0xffff, divisor)); + const lsb = divisor & 0xff; + const msb = (divisor >> 8) & 0xff; + const cmd = new Uint8Array([OPCODES.SET_SAMPLING_RATE_COMMAND, lsb, msb]); + this._emitStatus(`Set sampling rate → ${rateHz.toFixed(3)} Hz (divisor=${divisor}) — waiting for ACK…`); + const ackRemainder = await this._writeExpectingAck(cmd, 1500); + const appliedHz = 32768 / divisor; + this.samplingRateHz = appliedHz; + this._emitStatus(`Sampling rate ACKed. Applied ≈ ${this.samplingRateHz.toFixed(3)} Hz`); + return { requestedHz: rateHz, appliedHz, divisor, ackRemainder }; + } + // --------------------------------------------------------------------------- + // Inquiry + // --------------------------------------------------------------------------- + /** Send INQUIRY_CMD and parse the response to build the stream schema. */ + async inquiry() { + this._emitStatus('INQUIRY_CMD → waiting for ACK then RSP…'); + const remainder = await this._writeExpectingAck(new Uint8Array([OPCODES.INQUIRY_COMMAND]), 1500); + if (remainder && remainder[0] === OPCODES.INQUIRY_RESPONSE) { + this._log('Using post-ACK remainder as response'); + const info = this._interpretInquiryResponseShimmer3R(remainder); + this.onInquiry?.(info); + return info; + } + const rsp = await this._waitForResponse(OPCODES.INQUIRY_RESPONSE, 2000); + this._emitStatus(`Inquiry RSP (${rsp.length} bytes)`); + const info = this._interpretInquiryResponseShimmer3R(rsp); + this.onInquiry?.(info); + return info; + } + // --------------------------------------------------------------------------- + // ExG configuration helpers + // --------------------------------------------------------------------------- + /** Enable EMG (ADS1292R) in 16-bit mode on EXG1 & EXG2. */ + async enableEMG16Bit() { + if (!this.rx) + throw new Error('Not connected (RX missing)'); + await this._writeExgPages(new Uint8Array([ + 0x61, 0x00, 0x00, 0x0a, 0x02, 0xa8, 0x10, 0x69, 0x60, 0x20, 0x00, 0x00, 0x02, 0x03, + ]), new Uint8Array([ + 0x61, 0x01, 0x00, 0x0a, 0x02, 0xa0, 0x10, 0xe1, 0xe1, 0x00, 0x00, 0x00, 0x02, 0x01, + ])); + this._emitStatus('EMG 16-bit enabled on EXG1 & EXG2. Schema updated.'); + } + /** Enable EXG test signal in 16-bit mode (useful for verifying ExG hardware). */ + async enableEXGTestSignal16Bit() { + if (!this.rx) + throw new Error('Not connected (RX missing)'); + await this._writeExgPages(new Uint8Array([ + 0x61, 0x00, 0x00, 0x0a, 0x02, 0xab, 0x10, 0x15, 0x15, 0x00, 0x00, 0x00, 0x02, 0x01, + ]), new Uint8Array([ + 0x61, 0x01, 0x00, 0x0a, 0x02, 0xa3, 0x10, 0x15, 0x15, 0x00, 0x00, 0x00, 0x02, 0x01, + ])); + this._emitStatus('EXG test signal 16-bit enabled. Schema updated.'); + } + /** Enable ECG in 16-bit mode on EXG1 & EXG2. */ + async enableECG16Bit() { + if (!this.rx) + throw new Error('Not connected (RX missing)'); + await this._writeExgPages(new Uint8Array([ + 0x61, 0x00, 0x00, 0x0a, 0x02, 0xa8, 0x10, 0x40, 0x40, 0x2d, 0x00, 0x00, 0x02, 0x03, + ]), new Uint8Array([ + 0x61, 0x01, 0x00, 0x0a, 0x02, 0xa0, 0x10, 0x40, 0x47, 0x00, 0x00, 0x00, 0x02, 0x01, + ])); + this._emitStatus('ECG 16-bit enabled on EXG1 & EXG2. Schema updated.'); + } + async _writeExgPages(exg1, exg2) { + const oversamplingRatio = getOversamplingRatioADS1292R(this.samplingRateHz); + exg1 = new Uint8Array(exg1); + exg2 = new Uint8Array(exg2); + exg1[4] = (((exg1[4] >> 3) << 3) | oversamplingRatio) & 0xff; + exg2[4] = (((exg2[4] >> 3) << 3) | oversamplingRatio) & 0xff; + await this._write(exg1); + await new Promise((r) => setTimeout(r, 200)); + await this._write(exg2); + await new Promise((r) => setTimeout(r, 50)); + const targetBits = (SensorBitmapShimmer3.SENSOR_EXG1_16BIT | SensorBitmapShimmer3.SENSOR_EXG2_16BIT) >>> 0; + const newMask = ((this.enabledSensors >>> 0) | targetBits) & 0xffffff; + await this.setSensors(newMask); + } + // --------------------------------------------------------------------------- + // Streaming + // --------------------------------------------------------------------------- + async startStreaming() { + if (!this.schema) + this._emitStatus('Starting stream without schema (not recommended).'); + this._emitStatus('START_STREAM → waiting for ACK…'); + const remainder = await this._writeExpectingAck(new Uint8Array([OPCODES.START_STREAMING_COMMAND]), 1500); + this._streaming = true; + if (remainder?.length) { + if (remainder[0] === OPCODES.DATA_PACKET) { + this._rxBuf = concatU8(this._rxBuf, remainder); + } + else { + this._emitTemp(remainder); + } + } + this._emitStatus('START_STREAM ACK received; frames should follow'); + } + async stopStreaming() { + this._emitStatus('STOP_STREAM → sending (no ACK wait)…'); + try { + await this._write(new Uint8Array([OPCODES.STOP_STREAMING_COMMAND])); + this._emitStatus('STOP_STREAM command sent (skipped ACK wait).'); + } + catch (err) { + this._emitStatus(`STOP_STREAM write failed: ${err.message}`); + } + this._streaming = false; + this._rxBuf = new Uint8Array(0); + this._emitStatus('Streaming stopped.'); + } + /** Start streaming AND SD card logging simultaneously. */ + async startStreamingAndLogging() { + if (!this.schema) + this._emitStatus('Starting stream without schema (not recommended).'); + this._emitStatus('START_BT_STREAM_SD_LOGGING → waiting for ACK…'); + const remainder = await this._writeExpectingAck(new Uint8Array([OPCODES.START_SDBT_COMMAND]), 1500); + this._streaming = true; + if (remainder?.length) { + if (remainder[0] === OPCODES.DATA_PACKET) { + this._rxBuf = concatU8(this._rxBuf, remainder); + } + else { + this._emitTemp(remainder); + } + } + this._emitStatus('START_BT_STREAM_SD_LOGGING ACK received; frames should follow'); + } + /** Stop streaming AND SD card logging. */ + async stopStreamingAndLogging() { + this._emitStatus('STOP_BT_STREAM_SD_LOGGING → sending…'); + try { + await this._write(new Uint8Array([OPCODES.STOP_SDBT_COMMAND])); + } + catch (err) { + this._emitStatus(`STOP_BT_STREAM_SD_LOGGING write failed: ${err.message}`); + } + this._streaming = false; + this._rxBuf = new Uint8Array(0); + this._emitStatus('Streaming + logging stopped.'); + } + // --------------------------------------------------------------------------- + // Inquiry response / schema building + // --------------------------------------------------------------------------- + _interpretInquiryResponseShimmer3R(u8) { + let base = 0; + if (u8[0] === OPCODES.INQUIRY_RESPONSE && u8.length >= 2) + base = 1; + const adcRaw = u16le$2(u8, base + 0); + const samplingRateHz = 32768 / adcRaw; + this.samplingRateHz = samplingRateHz; + const cfg = BigInt(u8[base + 2]) | + (BigInt(u8[base + 3]) << 8n) | + (BigInt(u8[base + 4]) << 16n) | + (BigInt(u8[base + 5]) << 24n) | + (BigInt(u8[base + 6]) << 32n) | + (BigInt(u8[base + 7]) << 40n) | + (BigInt(u8[base + 8]) << 48n); + const internalExpPower = Number((cfg >> 24n) & 0x1n); + const gsrRange = Number((cfg >> 25n) & 0x7n); + this.ExpPower = internalExpPower; + this.gsrRangeSetting = gsrRange; + const numCh = u8[base + 9] ?? 0; + const bufSize = u8[base + 10] ?? 0; + const chStart = base + 11; + const channelIds = [...u8.slice(chStart, chStart + numCh)]; + const schema = this._buildSchemaFromChannels(channelIds, this.forceTimestampFmt ?? 'u24'); + this.schema = schema; + this._log(`Schema built: timestampFmt=${schema.timestampFmt}, fields=${schema.fields.length}, enabledSensors=0x${schema.enabledSensors.toString(16)}`); + this._emitStatus(`Expansion power ${this.ExpPower ? 'enabled' : 'disabled'} (ACK received).`); + return { + opcode: u8[0], + adcRaw, + samplingRateHz, + numChannels: numCh, + bufferSize: bufSize, + channelIds, + schema, + bytes: u8.slice(0), + }; + } + _buildSchemaFromChannels(channelIds, timestampFmt) { + const fields = []; + const ts = timestampFmt === 'u24' ? TIMESTAMP_FIELD.u24 : TIMESTAMP_FIELD.u16; + let packetSize = 1 + ts.sizeBytes; // 1 = preamble 0x00 + let enabledSensors = 0; + for (const id of channelIds) { + const fmt = CHANNEL_FORMATS[id]; + if (!fmt) { + fields.push({ id, name: `CH_${hex2(id)}`, fmt: 'i16', endian: 'le', sizeBytes: 2 }); + packetSize += 2; + continue; + } + fields.push({ id, ...fmt }); + packetSize += fmt.sizeBytes ?? 2; + switch (id) { + case 0x00: + case 0x01: + case 0x02: + enabledSensors |= SensorBitmapShimmer3.SENSOR_A_ACCEL; + break; + case 0x04: + case 0x05: + case 0x06: + enabledSensors |= SensorBitmapShimmer3.SENSOR_D_ACCEL; + break; + case 0x14: + case 0x15: + case 0x16: + enabledSensors |= SensorBitmapShimmer3.SENSOR_ACCEL_ALT; + break; + case 0x07: + case 0x08: + case 0x09: + enabledSensors |= SensorBitmapShimmer3.SENSOR_MAG; + break; + case 0x0a: + case 0x0b: + case 0x0c: + enabledSensors |= SensorBitmapShimmer3.SENSOR_GYRO; + break; + case 0x12: + enabledSensors |= SensorBitmapShimmer3.SENSOR_INT_A1; + break; + case 0x1c: + enabledSensors |= SensorBitmapShimmer3.SENSOR_GSR; + break; + case 0x23: + case 0x24: + enabledSensors |= SensorBitmapShimmer3.SENSOR_EXG1_16BIT; + break; + case 0x25: + case 0x26: + enabledSensors |= SensorBitmapShimmer3.SENSOR_EXG2_16BIT; + break; + case 0x1e: + case 0x1f: + enabledSensors |= SensorBitmapShimmer3.SENSOR_EXG1_24BIT; + break; + case 0x21: + case 0x22: + enabledSensors |= SensorBitmapShimmer3.SENSOR_EXG2_24BIT; + break; + default: + console.warn(`⚠️ Unmapped channel ID 0x${id.toString(16)} — added as generic i16.`); + } + } + this.enabledSensors = enabledSensors; + return { timestampFmt, fields, frameBytes: packetSize, enabledSensors, dataPreambleByte: 0x00 }; + } + // --------------------------------------------------------------------------- + // GSR calibration (applied inline during stream parsing) + // --------------------------------------------------------------------------- + _calibrateData(oc) { + const snapshot = [...oc.fields]; + for (const field of snapshot) { + if (field.name === GSR_NAME) { + const rawField = oc.get(GSR_NAME, 'raw'); + const gsrraw = rawField?.value ?? null; + if (gsrraw === null) + continue; + let adc12 = gsrraw & 0x0fff; + let currentRange = this.gsrRangeSetting; + if (currentRange === 4) { + currentRange = (gsrraw >> 14) & 0x03; + } + if (currentRange === 3 && adc12 < GSR_UNCAL_LIMIT_RANGE3) { + adc12 = GSR_UNCAL_LIMIT_RANGE3; + } + let gsrkOhm = calibrateGsrDataToResistanceFromAmplifierEq(adc12, currentRange); + gsrkOhm = nudgeGsrResistance(gsrkOhm, this.gsrRangeSetting); + const gsrConductanceUSiemens = (1.0 / gsrkOhm) * 1000; + oc.add(GSR_NAME, gsrConductanceUSiemens, 'uSiemens', 'cal'); + } + } + } + // --------------------------------------------------------------------------- + // Stream frame parser + // --------------------------------------------------------------------------- + _parseBySchema() { + const sch = this.schema; + const preamble = sch.dataPreambleByte; + const frameBytes = sch.frameBytes >>> 0; + const tsBytes = sch.timestampFmt === 'u16' ? 2 : 3; + const TS_MOD = tsBytes === 3 ? 16777216 : 65536; + let buf = this._rxBuf; + let frames = 0; + let drops = 0; + let anomalies = 0; + while (buf.length >= frameBytes * 2) { + if (buf[0] === preamble && buf[frameBytes] === preamble) { + let ts1, ts2; + try { + ts1 = tsBytes === 2 ? u16le$2(buf, 1) : u24le$1(buf, 1); + ts2 = tsBytes === 2 ? u16le$2(buf, frameBytes + 1) : u24le$1(buf, frameBytes + 1); + } + catch { + buf = buf.subarray(1); + drops++; + continue; + } + const dt = (((ts2 - ts1) % TS_MOD) + TS_MOD) % TS_MOD; + if (dt === 0) { + buf = buf.subarray(1); + drops++; + continue; + } + const frame = buf.subarray(0, frameBytes); + try { + let cursor = 1; + const oc = new ObjectCluster(this.device?.name ?? 'Shimmer3R'); + const ts = tsBytes === 2 ? u16le$2(frame, cursor) : u24le$1(frame, cursor); + cursor += tsBytes; + oc.add('TIMESTAMP', ts, 'ticks', 'raw'); + for (const f of sch.fields) { + if (cursor + f.sizeBytes > frame.length) { + throw new Error(`short frame: need ${f.sizeBytes} @${cursor}, have ${frame.length}`); + } + let v; + switch (f.fmt) { + case 'i16': + v = f.endian === 'be' ? sign16(u16be(frame, cursor)) : sign16(u16le$2(frame, cursor)); + break; + case 'u16': + v = f.endian === 'be' ? u16be(frame, cursor) : u16le$2(frame, cursor); + break; + case 'i24': + v = f.endian === 'be' ? sign24(u24be(frame, cursor)) : sign24(u24le$1(frame, cursor)); + break; + case 'u24': + v = f.endian === 'be' ? u24be(frame, cursor) : u24le$1(frame, cursor); + break; + case 'i12*': { + const msb = frame[cursor] & 0xff; + const lsb = frame[cursor + 1] & 0xff; + const raw12 = (msb << 4) | (lsb >> 4); + v = raw12 & 0x800 ? raw12 - 0x1000 : raw12; + break; + } + case 'u8': + v = frame[cursor]; + break; + default: + v = u16le$2(frame, cursor); + } + cursor += f.sizeBytes; + oc.add(f.name, v, null, 'raw'); + } + if (this._lastTs) { + const dLast = (((ts - this._lastTs) % TS_MOD) + TS_MOD) % TS_MOD; + if (dLast === 0) { + anomalies++; + this._log(`⚠️ Timestamp anomaly#${anomalies}: ts=${ts}, last=${this._lastTs}, Δ=0`); + } + } + this._lastTs = ts; + this._calibrateData(oc); + this.onStreamFrame?.(oc); + frames++; + buf = buf.subarray(frameBytes); + } + catch (e) { + this._log('⚠️ frame decode error → sliding 1 byte', e.message); + buf = buf.subarray(1); + drops++; + } + continue; + } + buf = buf.subarray(1); + drops++; + if (this.debug && drops % 64 === 1) { + this._log(`resync: dropped ${drops} byte(s) so far; bufLen=${buf.length}`); + } + } + this._rxBuf = buf; + if (drops && drops % 512 === 0) + this._lastTs = 0; + if (this.debug && (frames || drops)) { + this._log(`parse: frames=${frames}, drops=${drops}, leftover=${this._rxBuf.length}`); + } + } + // --------------------------------------------------------------------------- + // Low-level transport helpers + // --------------------------------------------------------------------------- + async _write(u8) { + if (!this.rx) + throw new Error('Not connected (RX missing)'); + this._log('Write', u8); + await this.rx.writeValue(toArrayBuffer(u8)); + } + async _writeExpectingAck(u8, ackTimeoutMs = 1000) { + this._expectingAck++; + try { + await this._write(u8); + return await this._waitForAck(ackTimeoutMs); + } + catch (e) { + this._expectingAck = Math.max(0, this._expectingAck - 1); + throw e; + } + } + _waitForAck(timeoutMs = 1000) { + return new Promise((resolve, reject) => { + const t = setTimeout(() => { + this._offTemp(handler); + reject(new Error('ACK timeout')); + }, timeoutMs); + const handler = (chunk) => { + if (!chunk || chunk.length === 0) + return; + if (chunk.length === 1 && chunk[0] === OPCODES.ACK_COMMAND_PROCESSED) { + clearTimeout(t); + this._offTemp(handler); + const rem = this._lastAckRemainder; + this._lastAckRemainder = null; + resolve(rem ?? null); + return; + } + if (chunk[0] === OPCODES.ACK_COMMAND_PROCESSED && chunk.length > 1) { + clearTimeout(t); + this._offTemp(handler); + resolve(chunk.slice(1)); + } + }; + this._onTemp(handler); + }); + } + _waitForResponse(expectedOpcode, timeoutMs = 1500) { + if (this._lastAckRemainder && this._lastAckRemainder[0] === expectedOpcode) { + const rem = this._lastAckRemainder; + this._lastAckRemainder = null; + return Promise.resolve(rem); + } + return new Promise((resolve, reject) => { + const t = setTimeout(() => { + this._offTemp(handler); + reject(new Error('Response timeout')); + }, timeoutMs); + const handler = (chunk) => { + if (!chunk || chunk.length === 0) + return; + if (chunk.length === 1 && chunk[0] === OPCODES.ACK_COMMAND_PROCESSED) + return; + if (chunk[0] === expectedOpcode) { + clearTimeout(t); + this._offTemp(handler); + resolve(chunk); + } + }; + this._onTemp(handler); + }); + } + _onTemp(fn) { + this._temps.add(fn); + } + _offTemp(fn) { + this._temps.delete(fn); + } + _emitTemp(buf) { + this._temps.forEach((fn) => { + try { + fn(buf); + } + catch (e) { + this._log('temp handler error', e); + } + }); + } +} + +// --------------------------------------------------------------------------- +// Nordic UART Service (NUS) UUIDs used by Verisense devices +// --------------------------------------------------------------------------- +/** NUS primary service UUID. */ +const NUS_SERVICE = '6e400001-b5a3-f393-e0a9-e50e24dcca9e'; +/** NUS TX characteristic UUID (host writes to this). */ +const NUS_TX = '6e400002-b5a3-f393-e0a9-e50e24dcca9e'; +/** NUS RX characteristic UUID (host subscribes to notifications from this). */ +const NUS_RX = '6e400003-b5a3-f393-e0a9-e50e24dcca9e'; +/** Nordic Secure DFU service UUID (buttonless DFU). */ +const NORDIC_DFU_SERVICE = '0000fe59-0000-1000-8000-00805f9b34fb'; +/** Nordic buttonless DFU control-point characteristic (without bond sharing). */ +const NORDIC_DFU_BUTTONLESS_WITHOUT_BONDS = '8ec90003-f315-4f60-9fb8-838830daea50'; +/** Nordic buttonless DFU control-point characteristic (with bond sharing). */ +const NORDIC_DFU_BUTTONLESS_WITH_BONDS = '8ec90004-f315-4f60-9fb8-838830daea50'; +/** Buttonless DFU control-point op-code that reboots the device into the bootloader. */ +const NORDIC_DFU_OP_ENTER_BOOTLOADER = 0x01; +// --------------------------------------------------------------------------- +// Verisense protocol command/property constants +// --------------------------------------------------------------------------- +/** Upper-nibble command classes used in protocol headers. */ +const ASM_COMMAND = Object.freeze({ + READ: 0x10, + WRITE: 0x20, + RESPONSE: 0x30, + ACK: 0x40, + NACK_BAD_HEADER_COMMAND: 0x50, + NACK_BAD_HEADER_PROPERTY: 0x60, + NACK_GENERIC: 0x70, + ACK_NEXT_STAGE: 0x80, +}); +/** Lower-nibble property IDs used in protocol headers. */ +const ASM_PROPERTY = Object.freeze({ + STATUS1: 0x01, + DATA: 0x02, + PRODUCTION_CONFIGURATION: 0x03, + OPERATIONAL_CONFIGURATION: 0x04, + TIME: 0x05, + DFU_MODE: 0x06, + PENDING_EVENTS: 0x07, + TEST_MODE: 0x08, + DEBUG_COMMAND: 0x09, + STREAM_MODE: 0x0a, + DEVICE_DISCONNECT: 0x0b, + STATUS2: 0x0c, + CALIBRATION: 0x0d, +}); +/** Stream mode payload values. */ +const STREAM_MODE = Object.freeze({ + ENABLE: 0x01, + DISABLE: 0x02, +}); +/** Test mode IDs documented by Verisense firmware. */ +const TEST_MODE_ID = Object.freeze({ + STOP: 0x00, + FLASH_8MB_1: 0x01, + FLASH_8MB_2: 0x02, + FLASH_128MB_512MB: 0x03, + EEPROM: 0x04, + ACCEL1_LIS2DW12: 0x05, + BATTERY_VOLTAGE: 0x06, + USB_POWER: 0x07, + ACCEL2_GYRO_LSM6DS3: 0x08, + PPG_MAX86XXX: 0x09, + BIOZ_MAX30002: 0x0b, + ACCEL2_GYRO_LSM6DSV: 0x0c, + MAG_LIS2MDL: 0x0d, + ALL_TESTS: 0xff, +}); +/** Debug command IDs documented by Verisense firmware. */ +const DEBUG_COMMAND_ID = Object.freeze({ + FLASH_LOOKUP_TABLE_READ: 0x01, + FLASH_LOOKUP_TABLE_ERASE: 0x02, + RWC_SCHEDULER_READ: 0x03, + ERASE_128MB_512MB_FLASH: 0x04, + ERASE_8MB_FLASH_1: 0x05, + ERASE_8MB_FLASH_2: 0x06, + ERASE_OPERATIONAL_CONFIG: 0x07, + ERASE_PRODUCTION_CONFIG: 0x08, + CLEAR_PENDING_EVENTS: 0x09, + ERASE_FLASH_AND_LOOKUP_TABLE: 0x0a, + TEST_DATA_TRANSFER_LOOP: 0x0b, + LOAD_TEST_LOOKUP_TABLE: 0x0c, + LED_TEST: 0x0d, + MAX86XXX_LED_TEST: 0x0e, + CHECK_PAYLOAD_CRC_ERRORS: 0x0f, + READ_EVENT_LOG: 0x10, + POWER_PROFILER_TEST: 0x11, + READ_RECORD_BUFFER_DETAILS: 0x12, + SYSTEM_RESET: 0x13, + IC_POWER_CONSUMPTION_TEST: 0x14, + DELETE_ALL_BONDS: 0x15, + BLE_LINK_PARAMS_READ: 0x16, + BLE_LINK_OPTIMIZE: 0x17, + /** Streamed MAX32674C algorithm-hub firmware (.msbl) upload (factory). The + * byte after this id is a HUB_FW_UPLOAD_STAGE sub-stage. */ + HUB_FW_UPLOAD: 0x18, +}); +/** Sub-stages for the streamed MAX32674C hub firmware upload, carried in the + * payload byte immediately after DEBUG_COMMAND_ID.HUB_FW_UPLOAD. */ +const HUB_FW_UPLOAD_STAGE = Object.freeze({ + BEGIN: 0x00, + PAGE_CHUNK: 0x01, + END: 0x02, + ABORT: 0x03, +}); +/** MAX32674C .msbl image geometry (mirrors firmware flashUpdater.h). A page on + * the wire is PAGE_PAYLOAD + PAGE_CRC bytes; HEADER_SIZE bytes precede page 0. */ +const MSBL = Object.freeze({ + HEADER_SIZE: 0x4c, + OFF_NUMPAGES: 0x44, + PAGE_PAYLOAD: 8192, + PAGE_CRC: 16, + PAGE_FILE_BYTES: 8208, +}); +// --------------------------------------------------------------------------- +// Operational config byte offsets +// --------------------------------------------------------------------------- +/** + * Byte indices into the Verisense operational config blob (`op[OP_IDX.xxx]`). + * Index 0 is the config version byte (must be 0x5A for a valid config). + */ +const OP_IDX = Object.freeze({ + GEN_CFG_0: 1, + GEN_CFG_1: 2, + GEN_CFG_2: 3, + GEN_CFG_3: 4, + ACCEL1_CFG_0: 5, + ACCEL1_CFG_1: 6, + ACCEL1_CFG_2: 7, + ACCEL1_CFG_3: 8, + GYRO_ACCEL2_CFG_0: 10, + GYRO_ACCEL2_CFG_1: 11, + GYRO_ACCEL2_CFG_2: 12, + GYRO_ACCEL2_CFG_3: 13, + GYRO_ACCEL2_CFG_4: 14, + GYRO_ACCEL2_CFG_5: 15, + GYRO_ACCEL2_CFG_6: 16, + GYRO_ACCEL2_CFG_7: 17, + LSM6DSV_CFG_0: 18, + LSM6DSV_CFG_1: 19, + LSM6DSV_CFG_2: 20, + START_TIME: 21, + END_TIME: 25, + INACTIVE_TIMEOUT: 29, + BLE_RETRY_COUNT: 30, + BLE_TX_POWER: 31, + BLE_DATA_TRANS_WKUP_INT_HRS: 32, + BLE_DATA_TRANS_WKUP_TIME: 33, + BLE_DATA_TRANS_WKUP_DUR: 35, + BLE_DATA_TRANS_RETRY_INT: 36, + BLE_STATUS_WKUP_INT_HRS: 38, + BLE_STATUS_WKUP_TIME: 39, + BLE_STATUS_WKUP_DUR: 41, + BLE_STATUS_RETRY_INT: 42, + BLE_RTC_SYNC_WKUP_INT_HRS: 44, + BLE_RTC_SYNC_WKUP_TIME: 45, + BLE_RTC_SYNC_WKUP_DUR: 47, + BLE_RTC_SYNC_RETRY_INT: 48, + ADC_CHANNEL_SETTINGS_0: 50, + ADC_CHANNEL_SETTINGS_1: 51, + ADAPTIVE_SCHEDULER_INT: 52, + ADAPTIVE_SCHEDULER_FAILCOUNT_MAX: 54, + PPG_REC_DUR_SECS_LSB: 55, + PPG_REC_DUR_SECS_MSB: 56, + PPG_REC_INT_MINS_LSB: 57, + PPG_REC_INT_MINS_MSB: 58, + PPG_FIFO_CONFIG: 59, + PPG_MODE_CONFIG2: 60, + PPG_MA_DEFAULT: 61, + PPG_MA_MAX_RED_IR: 62, + PPG_MA_MAX_GREEN_BLUE: 63, + PPG_AGC_TARGET_PERCENT_OF_RANGE: 64, + PPG_MA_LED_PILOT: 66, + PPG_DAC1_CROSSTALK: 67, + PPG_DAC2_CROSSTALK: 68, + PPG_DAC3_CROSSTALK: 69, + PPG_DAC4_CROSSTALK: 70, + PROX_AGC_MODE: 71, + // v9 second-generation sensor settings (only present when op[OP_CONFIG_VERSION] >= 9) + OP_CONFIG_VERSION: 9, + LIGHT_GAIN_INDEX: 72, + LIGHT_EXPOSURE_INDEX: 73, + LIGHT_CONFIG: 74, + LIGHT_SAMPLE_RATE_INDEX: 75, + SKIN_TEMP_CONFIG: 76, + SKIN_TEMP_SAMPLE_RATE_INDEX: 77, + ALGO_OP_MODE: 78, + ALGO_REPORT_MODE_RATE: 79, + ALGO_CONTROL: 80, + ALGO_INITIAL_HR: 81, + LED_AUTO_BRIGHTNESS_CFG: 82, + LED_MAX_BRIGHTNESS: 83, + LED_LUX_THRESHOLD: 84, + // MAX32674 algorithm-suite subject parameters (bytes 86-91) + PERSON_HEIGHT_CM: 86, // u16 LE, cm + PERSON_WEIGHT_KG: 88, // u16 LE, kg + PERSON_AGE: 90, // u8, years + PERSON_GENDER: 91, // u8, 0=Male, 1=Female +}); +/** Operational config layout version stored at OP_IDX.OP_CONFIG_VERSION (byte 9). + * 0 = legacy 72-byte layout; 9 = v9 layout with second-generation sensor settings. */ +const OP_CONFIG_VERSION_V9 = 9; +/** Minimum firmware version that supports the BLE-link debug commands + * (read/optimize connection parameters). */ +const BLE_LINK_MIN_FW = Object.freeze({ + major: 1, + minor: 4, + internal: 23, +}); +/** Human-readable labels for Verisense stream-packet sensor IDs. Each ID maps to + * the device part(s) that produce that stream (some streams interleave several + * physical sensors, e.g. id 6 = LSM6DSV accel + gyro + mag). */ +const VERISENSE_STREAM_SENSOR_LABELS = Object.freeze({ + 1: 'ADC (GSR / Battery)', + 2: 'Accel 1 (LIS2DW12)', + 3: 'Accel 2 + Gyro (LSM6DS3)', + 4: 'PPG (MAX86xxx)', + 6: 'Accel 2 + Gyro + Mag (LSM6DSV + LIS2MDL)', + 7: 'Ambient Light (VD6283)', + 8: 'Algo Hub (MAX32674 — HR + raw PPG)', + 9: 'Skin Temperature (MLX90632)', +}); + +/** Read a 16-bit unsigned integer, little-endian. */ +function u16le$1(b0, b1) { + return (b1 << 8) | b0; +} +/** Format a single byte as an uppercase `0xNN` string. */ +function formatByteAsHex(v) { + return `0x${(v & 0xff).toString(16).toUpperCase().padStart(2, '0')}`; +} +/** Format bytes as `[0xAA, 0xBB, ...]`. */ +function formatByteArrayAsHex(bytes) { + const u8 = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes ?? []); + return `[${Array.from(u8, (b) => formatByteAsHex(Number(b))).join(', ')}]`; +} +/** Parse text containing hex bytes like `0x5A, 00 12` into a Uint8Array. */ +function parseHexByteString(text) { + const matches = String(text ?? '').match(/[0-9a-fA-F]{2}/g) ?? []; + if (!matches.length) { + throw new Error('No hex bytes found. Example: 0x5A, 0x00, 0x12'); + } + return new Uint8Array(matches.map((h) => Number.parseInt(h, 16))); +} +/** + * Compare two firmware version triples. Returns a negative number if `a < b`, + * positive if `a > b`, and 0 if equal. Missing or non-numeric components are + * treated as 0. + */ +function compareVerisenseFirmwareVersion(a, b) { + const aMaj = Number(a?.major) || 0; + const aMin = Number(a?.minor) || 0; + const aInt = Number(a?.internal) || 0; + const bMaj = Number(b?.major) || 0; + const bMin = Number(b?.minor) || 0; + const bInt = Number(b?.internal) || 0; + if (aMaj !== bMaj) + return aMaj - bMaj; + if (aMin !== bMin) + return aMin - bMin; + return aInt - bInt; +} +/** Format a firmware version triple as `"major.minor.internal"`, or `"unknown"` + * when the version is null/undefined. */ +function formatVerisenseFirmwareVersion(v) { + if (!v) + return 'unknown'; + return `${Number(v.major) || 0}.${Number(v.minor) || 0}.${Number(v.internal) || 0}`; +} +/** Human-readable label for a Verisense stream-packet sensor ID, with a + * `"Sensor 0xNN"` hex fallback for unknown IDs. */ +function getVerisenseStreamSensorLabel(sensorId) { + const labels = VERISENSE_STREAM_SENSOR_LABELS; + return labels[sensorId] ?? `Sensor 0x${Number(sensorId).toString(16).toUpperCase()}`; +} +const ASM_PROPERTY_BY_VALUE = new Map(Object.entries(ASM_PROPERTY).map(([name, value]) => [Number(value), name])); +/** Label pending-event property values with both enum name and hex representation. */ +function formatPendingEventProperties(pendingProps) { + const list = Array.isArray(pendingProps) + ? pendingProps + : pendingProps == null + ? [] + : Array.from(pendingProps); + return list.map((prop) => { + const value = Number(prop) & 0xff; + return { + value, + hex: formatByteAsHex(value), + property: ASM_PROPERTY_BY_VALUE.get(value) ?? 'UNKNOWN_PROPERTY', + }; + }); +} +/** Read a signed 16-bit integer at byte offset `off`, little-endian. */ +function i16le(bytes, off) { + const v = bytes[off] | (bytes[off + 1] << 8); + return v & 0x8000 ? v - 0x10000 : v; +} +/** Read a 24-bit unsigned integer at byte offset `off`, little-endian. */ +function u24le(bytes, off) { + return (bytes[off] | (bytes[off + 1] << 8) | (bytes[off + 2] << 16)) >>> 0; +} +/** Read a 16-bit unsigned integer at byte offset `off`, little-endian (full-array form). */ +function u16le_at(bytes, off) { + return (bytes[off] | (bytes[off + 1] << 8)) >>> 0; +} +/** Read a 32-bit IEEE-754 float at byte offset `off`, little-endian. */ +function f32le(bytes, off) { + return new DataView(bytes.buffer, bytes.byteOffset + off, 4).getFloat32(0, true); +} +/** Return current time in milliseconds. */ +function nowMillis() { + return Date.now(); +} +/** + * Compute CRC-16/CCITT-FALSE over `bytes`. + * + * Parameters: poly=0x1021, init=0xFFFF, xorOut=0x0000. + * Matches the C# `ComputeCRC` implementation used by Verisense firmware. + */ +function crc16_ccitt_false(bytes) { + let crc = 0xffff; + for (let i = 0; i < bytes.length; i++) { + crc ^= bytes[i] << 8; + for (let b = 0; b < 8; b++) { + crc = crc & 0x8000 ? (crc << 1) ^ 0x1021 : crc << 1; + crc &= 0xffff; + } + } + return crc & 0xffff; +} +/** + * Extract the CRC that was appended to a logged payload (last 2 bytes, LE). + */ +function getOriginalCrcLE(payload) { + const n = payload.length; + return (payload[n - 2] | (payload[n - 1] << 8)) >>> 0; +} +/** + * Compute the CRC of a logged payload, excluding the trailing 2 CRC bytes, + * matching the C# `ComputeCRC(payload, 0, payload.Length - 2)` call. + */ +function computeCrcLikeCSharp(payload) { + return crc16_ccitt_false(payload.subarray(0, payload.length - 2)); +} +/** + * Convert any reasonable representation of an operational config to a + * `Uint8Array`. Throws if the input type is unrecognised. + */ +function normalizeOperationalConfig(payload) { + if (!payload) + return null; + if (payload instanceof Uint8Array) + return payload; + if (payload instanceof ArrayBuffer) + return new Uint8Array(payload); + if (Array.isArray(payload)) + return new Uint8Array(payload); + if (payload.buffer instanceof ArrayBuffer) { + const p = payload; + return new Uint8Array(p.buffer, p.byteOffset ?? 0, p.byteLength ?? p.buffer.byteLength); + } + throw new Error('normalizeOperationalConfig: unsupported payload type'); +} +/** Alias for arbitrary protocol byte payload normalization. */ +function normalizeBytePayload(payload) { + return normalizeOperationalConfig(payload); +} +/** + * Derive the 6-digit pairing PIN from a Verisense unique identifier. + * + * The PIN is built from digits 2, 4 and 6 (1-based) of the identifier, + * followed by the decimal value of the final byte padded to 3 digits. + */ +function computeVerisensePairingPin(uniqueId) { + const normalized = String(uniqueId ?? '') + .trim() + .replace(/^Verisense-/i, ''); + if (!/^[0-9a-fA-F]{8,}$/.test(normalized)) { + throw new Error('computeVerisensePairingPin: uniqueId must be a hex identifier string'); + } + if (normalized.length < 6) { + throw new Error('computeVerisensePairingPin: uniqueId must be at least 6 hex characters'); + } + const prefix = `${normalized[1]}${normalized[3]}${normalized[5]}`; + const suffixHex = normalized.slice(-2); + const suffixDec = Number.parseInt(suffixHex, 16); + return `${prefix}${suffixDec.toString().padStart(3, '0')}`; +} +/** Infer charger chip family from hardware revision fields in production config. */ +function inferVerisenseChargerChipFamily(revHwMajor, revHwMinor, revHwInternal) { + const major = Number(revHwMajor); + const minor = Number(revHwMinor); + const internal = Number(revHwInternal); + if ((major === 68 && minor === 7 && internal === 1) || (major === 68 && minor === 8)) { + return 'LTC4123'; + } + if (major === 62) { + return 'LM3658D'; + } + if ((major === 68 && minor >= 9) || (major === 61 && minor >= 5)) { + return 'XC6803'; + } + return 'UNKNOWN'; +} +/** Return chip-specific charger status text for a parsed 3-bit status code. */ +function describeVerisenseChargerStatus(chipFamily, statusCode) { + if (statusCode === 7) { + return 'Not read yet'; + } + if (chipFamily === 'LTC4123') { + if (statusCode === 0) { + return 'Zinc-air/reverse polarity/temp out-of-range/UVCL at start of charge cycle'; + } + if (statusCode === 1) { + return 'Powered on/charging'; + } + if (statusCode === 2) { + return 'Charge completed'; + } + if (statusCode === 3) { + return 'No power/not charging'; + } + } + if (chipFamily === 'LM3658D') { + if (statusCode === 0 || statusCode === 3) { + return 'Power-down, charging suspended or interrupted'; + } + if (statusCode === 1) { + return 'Pre-qualification, CC/CV charging, or top-off mode'; + } + if (statusCode === 2) { + return 'Charge completed'; + } + } + if (chipFamily === 'XC6803') { + if (statusCode === 0) { + return 'Fault (overvoltage, overcurrent, shorted battery, etc.)'; + } + if (statusCode === 1) { + return 'Pre-qualification, CC/CV charging, or top-off mode'; + } + if (statusCode === 2) { + return 'Charge completed'; + } + if (statusCode === 3) { + return 'Power-down, charging suspended or interrupted'; + } + if (statusCode === 4) { + return 'Trickle charging'; + } + } + return 'Unknown'; +} +/** Format charger summary text for UIs, e.g. "XC6803: Charge completed". */ +function formatVerisenseChargerStatus(status, hw) { + if (status.chargerPresent == null || + status.chargerStatusCode == null || + !status.chargerStatusName) { + return '-'; + } + if (!status.chargerPresent) { + return 'Not present'; + } + const chipFamily = inferVerisenseChargerChipFamily(hw?.revHwMajor ?? Number.NaN, hw?.revHwMinor ?? Number.NaN, hw?.revHwInternal ?? Number.NaN); + const text = describeVerisenseChargerStatus(chipFamily, Number(status.chargerStatusCode)); + return chipFamily === 'UNKNOWN' ? text : `${chipFamily}: ${text}`; +} +/** Upper bound for a plausible device timestamp (2100-01-01 UTC in unix + * seconds). Values beyond this are uninitialised/garbage bytes, not dates. */ +const VERISENSE_MAX_PLAUSIBLE_UNIX_SECONDS = 4102444800; +/** Format unix seconds as raw + human-readable local datetime for logging. */ +function formatVerisenseUnixAndHuman(unixSeconds) { + const unix = Number(unixSeconds); + if (!Number.isFinite(unix)) { + return { unix, human: 'invalid' }; + } + if (unix <= 0) { + return { unix, human: '1970-01-01 00:00:00 (epoch)' }; + } + if (unix > VERISENSE_MAX_PLAUSIBLE_UNIX_SECONDS) { + return { unix, human: 'not-valid' }; + } + const d = new Date(unix * 1000); + const yyyy = d.getFullYear(); + const mm = String(d.getMonth() + 1).padStart(2, '0'); + const dd = String(d.getDate()).padStart(2, '0'); + const HH = String(d.getHours()).padStart(2, '0'); + const MM = String(d.getMinutes()).padStart(2, '0'); + const SS = String(d.getSeconds()).padStart(2, '0'); + return { + unix, + human: `${yyyy}-${mm}-${dd} ${HH}:${MM}:${SS}`, + }; +} +/** Convert parsed status payload into an object with human-readable timestamps for logs. */ +function formatStatusPayloadForLog(status) { + return { + ...status, + statusTimestamp: formatVerisenseUnixAndHuman(status.statusTimestampSeconds), + lastOkTransfer: formatVerisenseUnixAndHuman(status.lastOkTransferSeconds), + lastFailTransfer: formatVerisenseUnixAndHuman(status.lastFailTransferSeconds), + }; +} +/** Convert parsed scheduler payload into an object with human-readable timestamps for logs. */ +function formatSchedulerPayloadForLog(parsed) { + const out = { + ...parsed, + adaptiveScheduler: undefined, + ltfRetry: undefined, + currentTime: formatVerisenseUnixAndHuman(parsed.currentTimeUnixSeconds), + pendingDataTransfer: formatVerisenseUnixAndHuman(parsed.pendingDataTransferUnixSeconds), + pendingStatus1: formatVerisenseUnixAndHuman(parsed.pendingStatus1UnixSeconds), + pendingRtcSync: formatVerisenseUnixAndHuman(parsed.pendingRtcSyncUnixSeconds), + pendingRetry: formatVerisenseUnixAndHuman(parsed.pendingRetryUnixSeconds), + }; + if (typeof parsed.pendingStatus2UnixSeconds === 'number') { + out.pendingStatus2 = formatVerisenseUnixAndHuman(parsed.pendingStatus2UnixSeconds); + } + if (typeof parsed.ppgMeasurementUnixSeconds === 'number') { + out.ppgMeasurement = formatVerisenseUnixAndHuman(parsed.ppgMeasurementUnixSeconds); + } + if (typeof parsed.stepCounterResetUnixSeconds === 'number') { + out.stepCounterReset = formatVerisenseUnixAndHuman(parsed.stepCounterResetUnixSeconds); + } + if (typeof parsed.sensorInactivityUnixSeconds === 'number') { + out.sensorInactivity = formatVerisenseUnixAndHuman(parsed.sensorInactivityUnixSeconds); + } + if (parsed.adaptiveScheduler) { + out.adaptiveScheduler = { + ...parsed.adaptiveScheduler, + nextTime: formatVerisenseUnixAndHuman(parsed.adaptiveScheduler.nextUnixSeconds), + }; + } + if (parsed.ltfRetry) { + out.ltfRetry = { + ...parsed.ltfRetry, + nextTime: formatVerisenseUnixAndHuman(parsed.ltfRetry.nextUnixSeconds), + }; + } + return out; +} +const PROD_CONFIG_FLAG_DFU_ENABLED = 1 << 0; +const LOG_EVENT_NAMES = { + 0: 'NONE', + 1: 'BATTERY_FALL', + 2: 'BATTERY_RECOVER', + 3: 'WRITE_TO_FLASH_SUCCESS', + 4: 'WRITE_TO_FLASH_FAIL_GENERAL', + 5: 'WRITE_TO_FLASH_FULL', + 6: 'WRITE_TO_FLASH_FAIL_CHECK_ADDR_FREE', + 7: 'WRITE_TO_FLASH_FAIL_LOW_BATT_CHECK_ADDR_FREE', + 8: 'WRITE_TO_FLASH_FAIL_LOW_BATT_FLASH_ON', + 9: 'WRITE_TO_FLASH_FAIL_LOW_BATT_FLASH_WRITE', + 10: 'WRITE_TO_FLASH_FAIL_LOW_BATT_BEFORE_START', + 11: 'USB_PLUGGED_IN_SOFT_DEVICE', + 12: 'USB_PLUGGED_OUT_SOFT_DEVICE', + 13: 'RECORDING_PAUSED', + 14: 'RECORDING_RESUMED', + 15: 'BATTERY_RECOVER_IN_BATT_CHECK_TIMER', + 16: 'TSK_FREE_UP_FLASH', + 17: 'FREE_UP_FLASH_FAIL_LOW_BATT', + 18: 'PAYLOAD_PACKAGING_TASK_SET', + 19: 'PAYLOAD_PACKAGING_FUNCTION_CALL', + 20: 'BATTERY_VOLTAGE', + 21: 'TSK_WRITE_LOOKUP_TBL_CHANGES_TO_EEPROM', + 22: 'LPCOMP_ON', + 23: 'LPCOMP_ON_ALREADY', + 24: 'LPCOMP_OFF', + 25: 'LPCOMP_TRIED_BUT_BATT_LOW', + 26: 'BLE_CONNECTED', + 27: 'BLE_DISCONNECTED', + 28: 'TSK_WRITE_FLASH', + 29: 'PPG_TIMER_START', + 30: 'PAYLOAD_OVERSHOT', + 31: 'ADVERTISING_START', + 32: 'ADVERTISING_STOP', + 33: 'NIMH_BATT_PPG_BLOCKED_BLE_RETRY', + 34: 'NIMH_BATT_PPG_BLOCKED_BLE_ADAPT_SCH', + 35: 'NIMH_BATT_PPG_BLOCKED_BLE_PENDING_EVENTS', + 36: 'NIMH_BATT_BLE_BLOCKED_PPG', + 37: 'USB_PORT_OPEN', + 38: 'USB_PORT_CLOSED', + 39: 'FIFO_INT_SAFETY_CHECK_EVENT_ACCEL1', + 40: 'FIFO_INT_SAFETY_CHECK_EVENT_ACCEL2GYRO', + 41: 'FIFO_INT_SAFETY_CHECK_EVENT_MAX86XXX', + 42: 'FIFO_INT_SAFETY_CHECK_EVENT_MAX3000X', + 43: 'FIFO_INT_SAFETY_CHECK_EVENT_ADC', + 44: 'USB_PLUGGED_IN_PIN_HANDLER', + 45: 'USB_PLUGGED_OUT_PIN_HANDLER', + 46: 'BATTERY_CHARGER_STATUS_BAD_BATTERY', + 47: 'BATTERY_CHARGER_STATUS_CHARGING', + 48: 'BATTERY_CHARGER_STATUS_CHARGING_COMPLETE', + 49: 'BATTERY_CHARGER_STATUS_POWER_DOWN', + 50: 'LTC4123_RECOVERY_ATTEMPT', + 51: 'LTC4123_RECOVERY_GAVE_UP', + 52: 'LTC4123_CHRG_COMPLETE_OVERRIDDEN_BAD_BATT', + // DEV-790 USB enumeration debug events + 53: 'USB_POWER_READY_EVT', + 54: 'USB_USBD_ENABLE_CALLED', + 55: 'USB_USBD_START_CALLED', + 56: 'USB_COM_PORT_DISABLED_ON_DETECT', + 57: 'USB_USBD_STOPPED_EVT', +}; +const LOOKUP_STATUS_NAMES = { + 0: 'Zero', + 1: 'Full', + 2: '2Del', + 3: 'Emty', + 4: 'Bad', + 5: 'NUse', +}; +function u32le_at(bytes, off) { + return (((bytes[off] ?? 0) | + ((bytes[off + 1] ?? 0) << 8) | + ((bytes[off + 2] ?? 0) << 16) | + ((bytes[off + 3] ?? 0) << 24)) >>> + 0); +} +function decodeAsciiTrimFF(bytes) { + let end = bytes.length; + while (end > 0 && bytes[end - 1] === 0xff) + end--; + if (end === 0) + return ''; + return new TextDecoder().decode(bytes.slice(0, end)); +} +/** Convert unix seconds into Verisense 7-byte RTC payload (4-byte minutes + 3-byte ticks). */ +function unixSecondsToAsmRtcBytes(unixSeconds) { + if (!Number.isFinite(unixSeconds) || unixSeconds < 0) { + throw new Error('unixSecondsToAsmRtcBytes: unixSeconds must be a finite positive number'); + } + const minutes = Math.floor(unixSeconds / 60); + const secondsInMinute = unixSeconds - minutes * 60; + const ticks = Math.floor(secondsInMinute * 32768); + return new Uint8Array([ + minutes & 0xff, + (minutes >> 8) & 0xff, + (minutes >> 16) & 0xff, + (minutes >> 24) & 0xff, + ticks & 0xff, + (ticks >> 8) & 0xff, + (ticks >> 16) & 0xff, + ]); +} +/** Convert Verisense 7-byte RTC payload into unix seconds. */ +function asmRtcBytesToUnixSeconds(rtc7) { + if (rtc7.length !== 7) { + throw new Error('asmRtcBytesToUnixSeconds: payload must be exactly 7 bytes'); + } + const minutes = u32le_at(rtc7, 0); + const ticks = u24le(rtc7, 4); + return minutes * 60 + ticks / 32768.0; +} +/** Convert Verisense 8-byte minute counter payload into unix seconds. */ +function asmRtcMinutesBytesToUnixSeconds(minutes8) { + if (minutes8.length !== 8) { + throw new Error('asmRtcMinutesBytesToUnixSeconds: payload must be exactly 8 bytes'); + } + let minutes = 0n; + for (let i = 0; i < 8; i++) { + minutes |= BigInt(minutes8[i]) << BigInt(i * 8); + } + return Number(minutes) * 60; +} +/** + * Build a production configuration payload (56 bytes) from structured options. + * This matches the Python tooling layout used by ASM_BLE.py / ASM_Device.py. + */ +function buildProductionConfigPayload(opts) { + const mo = String(opts.manufacturingOrderNumberHex ?? '').trim(); + const mac = String(opts.macIdHex ?? '').trim(); + if (!/^[0-9a-fA-F]{8}$/.test(mo)) { + throw new Error('buildProductionConfigPayload: manufacturingOrderNumberHex must be 8 hex chars'); + } + if (!/^[0-9a-fA-F]{4}$/.test(mac)) { + throw new Error('buildProductionConfigPayload: macIdHex must be 4 hex chars'); + } + const uniqueBytes = new Uint8Array(6); + uniqueBytes.set(new Uint8Array(mo.match(/../g).map((h) => Number.parseInt(h, 16))), 0); + uniqueBytes.set(new Uint8Array(mac.match(/../g).map((h) => Number.parseInt(h, 16))), 4); + uniqueBytes.reverse(); + const revHwInternal = (opts.revHwInternal ?? 0) & 0xffff; + const revFwInternal = (opts.revFwInternal ?? 0) & 0xffff; + const out = new Uint8Array(56); + out[0] = 0x5a; + out.set(uniqueBytes, 1); + out[7] = opts.revHwMajor & 0xff; + out[8] = opts.revHwMinor & 0xff; + out[9] = opts.revFwMajor & 0xff; + out[10] = opts.revFwMinor & 0xff; + out[11] = revFwInternal & 0xff; + out[12] = (revFwInternal >> 8) & 0xff; + out[13] = revHwInternal & 0xff; + out[14] = (revHwInternal >> 8) & 0xff; + // 0xFF is the "unset" sentinel for the passkey/advertising-name region + // (bytes 15..54). The configFlags byte (55) must NOT be left as 0xFF — its + // bit 0 is PROD_CONFIG_FLAG_DFU_ENABLED, so 0xFF reads as "DFU enabled" and + // disabling DFU would silently have no effect. It is set explicitly below. + out.fill(0xff, 15, 55); + const passkeyId = opts.passkeyId ?? ''; + if (passkeyId.length > 0) { + if (passkeyId.length !== 2) { + throw new Error('buildProductionConfigPayload: passkeyId must be 2 chars when provided'); + } + out.set(new TextEncoder().encode(passkeyId), 15); + } + const passkey = opts.passkey ?? ''; + if (passkey.length > 0) { + if (passkey.length !== 6) { + throw new Error('buildProductionConfigPayload: passkey must be 6 chars when provided'); + } + out.set(new TextEncoder().encode(passkey), 17); + } + const advPrefix = opts.advertisingNamePrefix ?? ''; + if (advPrefix.length > 32) { + throw new Error('buildProductionConfigPayload: advertisingNamePrefix must be <= 32 chars'); + } + if (advPrefix.length > 0) { + out.set(new TextEncoder().encode(advPrefix), 23); + } + // Always set configFlags explicitly (0x01 = DFU enabled on boot, 0x00 = + // disabled). Matches the firmware reference encoding in ASM_Device.py. + out[55] = (opts.dfuEnabled ?? true) ? PROD_CONFIG_FLAG_DFU_ENABLED : 0; + return out; +} +/** Parse production configuration with optional passkey/name/flag fields. */ +function parseProductionConfigPayloadFull(response) { + if (response.length < 11) { + throw new Error('parseProductionConfigPayloadFull: payload must be at least 11 bytes'); + } + const base = parseProductionConfigPayload(response); + const uniqueIdentifier = [...response.slice(1, 7)] + .reverse() + .map((b) => b.toString(16).padStart(2, '0')) + .join('') + .toUpperCase(); + const revHwMajor = response[7] ?? 0; + const revHwMinor = response[8] ?? 0; + const revFwMajor = response[9] ?? 0; + const revFwMinor = response[10] ?? 0; + const revFwInternal = response.length >= 13 ? u16le_at(response, 11) : 0; + const revHwInternal = response.length >= 15 ? u16le_at(response, 13) : 0; + const passkeyId = response.length >= 17 ? decodeAsciiTrimFF(response.slice(15, 17)) : ''; + const passkey = response.length >= 23 ? decodeAsciiTrimFF(response.slice(17, 23)) : ''; + const advertisingNamePrefix = response.length >= 55 ? decodeAsciiTrimFF(response.slice(23, 55)) : ''; + const dfuEnabled = response.length >= 56 ? !!(response[55] & PROD_CONFIG_FLAG_DFU_ENABLED) : true; + return { + ...base, + manufacturingOrderNumber: uniqueIdentifier.slice(0, 8), + macId: uniqueIdentifier.slice(8, 12), + uniqueIdentifier, + revHwMajor, + revHwMinor, + revHwInternal, + revFwMajor, + revFwMinor, + revFwInternal, + passkeyId, + passkey, + advertisingNamePrefix, + dfuEnabled, + }; +} +/** + * Parse STATUS1/STATUS2 payload into a typed object. + * + * This ports the core byte parsing from ASM_Device.parse_status while keeping + * the output concise and UI-friendly. + */ +function parseStatusPayload(response, sourceStatusProperty = 'status1') { + if (response.length < 24) { + throw new Error('parseStatusPayload: payload must be at least 24 bytes'); + } + const uniqueIdentifier = [...response.slice(0, 6)] + .reverse() + .map((b) => b.toString(16).padStart(2, '0')) + .join('') + .toUpperCase(); + const hasTickFields = response.length >= 56; + const hasExtendedCapacity = response.length >= 65; + const statusTimestampSeconds = hasTickFields + ? asmRtcBytesToUnixSeconds(new Uint8Array([...response.slice(6, 10), ...response.slice(34, 37)])) + : u32le_at(response, 6) * 60; + const batteryMilliVolts = u16le_at(response, 10); + const batteryPercent = response[12] ?? 0; + const lastOkTransferSeconds = hasTickFields + ? asmRtcBytesToUnixSeconds(new Uint8Array([...response.slice(13, 17), ...response.slice(37, 40)])) + : u32le_at(response, 13) * 60; + const lastFailTransferSeconds = hasTickFields + ? asmRtcBytesToUnixSeconds(new Uint8Array([...response.slice(17, 21), ...response.slice(40, 43)])) + : u32le_at(response, 17) * 60; + const memoryFreeKb = hasExtendedCapacity + ? (response[21] | (response[22] << 8) | (response[23] << 16) | (response[57] << 24)) >>> 0 + : (response[21] | (response[22] << 8) | (response[23] << 16)) >>> 0; + const memoryCapacityKb = hasExtendedCapacity ? u32le_at(response, 60) : null; + const memoryUsedKb = memoryCapacityKb == null ? null : Math.max(0, memoryCapacityKb - memoryFreeKb); + // Bank breakdown: FULL=syncable data, 2DEL=partially-deleted, BAD=unusable flash. + // Ported from ASM_Device.parse_status. Present in payloads >= 56 bytes. In the + // extended (fw v1.02.102+, payload >= 65 bytes) format the FULL and 2DEL totals + // are split: 3 low bytes at 47-49 / 50-52 plus a high byte appended at offset + // 58 / 59 respectively (mirroring the free-memory split to byte 57). + const hasBankData = response.length >= 56; + let memoryFullBanksKb = null; + let memoryTwoDelBanksKb = null; + let memoryBadBanksKb = null; + if (hasBankData) { + if (hasExtendedCapacity) { + memoryFullBanksKb = + (response[47] | (response[48] << 8) | (response[49] << 16) | (response[58] << 24)) >>> 0; + memoryTwoDelBanksKb = + (response[50] | (response[51] << 8) | (response[52] << 16) | (response[59] << 24)) >>> 0; + memoryBadBanksKb = u32le_at(response, 53); // bytes 53-56 + } + else { + memoryFullBanksKb = (response[47] | (response[48] << 8) | (response[49] << 16)) >>> 0; + memoryTwoDelBanksKb = (response[50] | (response[51] << 8) | (response[52] << 16)) >>> 0; + memoryBadBanksKb = (response[53] | (response[54] << 8) | (response[55] << 16)) >>> 0; + } + } + const batteryFallCounter = response.length >= 26 ? u16le_at(response, 24) : null; + let statusFlags = null; + if (response.length >= 34) { + const f = response[26]; + statusFlags = { + usbPluggedIn: (f & 0x01) !== 0, + recordingPaused: (f & 0x02) !== 0, + flashIsFull: (f & 0x04) !== 0, + powerIsGood: (f & 0x08) !== 0, + adaptiveSchedulerOn: (f & 0x10) !== 0, + dfuServiceOn: (f & 0x20) !== 0, + firstBoot: (f & 0x40) !== 0, + repeatedBatteryMeasurement: (f & 0x80) !== 0, + }; + } + let chargerPresent = null; + let chargerStatusCode = null; + let chargerStatusName = null; + if (hasExtendedCapacity) { + const chargerStatusByte = response[64] ?? 0; + chargerPresent = (chargerStatusByte & 0x01) !== 0; + chargerStatusCode = (chargerStatusByte >> 1) & 0x07; + chargerStatusName = + chargerStatusCode === 0 + ? 'CHARGER_STATUS_BAD_BATTERY' + : chargerStatusCode === 1 + ? 'CHARGER_STATUS_CHARGING' + : chargerStatusCode === 2 + ? 'CHARGER_STATUS_CHARGING_COMPLETE' + : chargerStatusCode === 3 + ? 'CHARGER_STATUS_POWER_DOWN' + : chargerStatusCode === 4 + ? 'CHARGER_STATUS_TRICKLE_CHARGING' + : chargerStatusCode === 7 + ? 'CHARGER_STATUS_NOT_READ' + : 'CHARGER_STATUS_UNKNOWN'; + } + return { + uniqueIdentifier, + sourceStatusProperty, + statusTimestampSeconds, + batteryMilliVolts, + batteryPercent, + lastOkTransferSeconds, + lastFailTransferSeconds, + memoryFreeKb, + memoryCapacityKb, + memoryUsedKb, + memoryFullBanksKb, + memoryTwoDelBanksKb, + memoryBadBanksKb, + statusFlags, + batteryFallCounter, + chargerPresent, + chargerStatusCode, + chargerStatusName, + }; +} +/** Parse scheduler debug response payload from DEBUG_COMMAND_ID.RWC_SCHEDULER_READ. */ +function parseSchedulerDebugPayload(payload) { + if (payload.length < 42) { + throw new Error('parseSchedulerDebugPayload: payload is too short'); + } + let idx = 0; + const currentTimeUnixSeconds = asmRtcBytesToUnixSeconds(payload.slice(idx, idx + 7)); + idx += 7; + const bleControlByte = payload[idx++] ?? 0xff; + const bleControlCounter = bleControlByte === 0x00 + ? 'data-transfer' + : bleControlByte === 0x01 + ? 'status1' + : bleControlByte === 0x02 + ? 'rtc-sync' + : bleControlByte === 0x03 + ? 'status2' + : bleControlByte === 0xff + ? 'never' + : 'unknown'; + const next8 = () => { + const v = asmRtcMinutesBytesToUnixSeconds(payload.slice(idx, idx + 8)); + idx += 8; + return v; + }; + const out = { + currentTimeUnixSeconds, + bleControlCounter, + pendingDataTransferUnixSeconds: next8(), + pendingStatus1UnixSeconds: next8(), + pendingRtcSyncUnixSeconds: next8(), + pendingRetryUnixSeconds: next8(), + retryCount: payload[idx++] ?? 0, + retryOperation: (payload[idx++] ?? 0) === 1 ? 'ble-on' : 'ble-off', + }; + if (payload.length >= idx + 10) { + out.adaptiveScheduler = { + nextUnixSeconds: next8(), + enabled: (payload[idx++] ?? 0) === 1, + syncFailCounter: payload[idx++] ?? 0, + }; + } + if (payload.length >= idx + 11) { + const nextUnixSeconds = next8(); + const op = payload[idx++] ?? 0; + out.ltfRetry = { + nextUnixSeconds, + currentOperation: op === 0 + ? 'flash-write-retry-inactive' + : op === 1 + ? 'short-flash-write-retry' + : op === 2 + ? 'attempt-flash-write' + : op === 3 + ? 'long-flash-write-retry' + : op === 4 + ? 'sensor-paused-until-usb-plug-in' + : 'unknown', + failCounterShort: payload[idx++] ?? 0, + failCounterLong: payload[idx++] ?? 0, + }; + } + if (payload.length >= idx + 8) { + out.pendingStatus2UnixSeconds = next8(); + } + if (payload.length >= idx + 8) { + out.ppgMeasurementUnixSeconds = next8(); + } + if (payload.length >= idx + 8) { + out.stepCounterResetUnixSeconds = next8(); + } + if (payload.length >= idx + 8) { + out.sensorInactivityUnixSeconds = next8(); + } + return out; +} +/** Decode the `optimizationResult` byte from {@link parseBleLinkDebugPayload} + * (see {@link VerisenseBleOptimizationResult} for the bit meanings). */ +function decodeVerisenseBleOptimizationResult(resultByte) { + const mask = Number(resultByte ?? 0) & 0xff; + return { + notConnected: (mask & 0x80) !== 0, + phyRequested: (mask & 0x01) !== 0, + connIntervalRequested: (mask & 0x02) !== 0, + dataLengthRequested: (mask & 0x04) !== 0, + resultMask: mask, + }; +} +/** Parse debug payload from BLE link read/optimize commands. */ +function parseBleLinkDebugPayload(payload) { + if (payload.length < 10) { + throw new Error('parseBleLinkDebugPayload: payload is too short'); + } + const connectionIntervalUnits = u16le_at(payload, 4); + return { + attMtu: u16le_at(payload, 0), + maxDataLength: u16le_at(payload, 2), + connectionIntervalUnits, + connectionIntervalMs: connectionIntervalUnits * 1.25, + txPhy: payload[6] ?? 0, + rxPhy: payload[7] ?? 0, + optimizationResult: payload[8] ?? 0, + isConnected: (payload[9] ?? 0) !== 0, + }; +} +/** Parse debug payload listing bank indexes with bad CRC (2-byte LE entries). */ +function parsePayloadCrcErrorBankIndexes(payload) { + if (payload.length % 2 !== 0) { + throw new Error('parsePayloadCrcErrorBankIndexes: payload length must be even'); + } + const out = []; + for (let i = 0; i < payload.length; i += 2) + out.push(u16le_at(payload, i)); + return out; +} +/** Parse 8-byte debug event-log entries. */ +function parseEventLogPayload(payload) { + if (payload.length % 8 !== 0) { + throw new Error('parseEventLogPayload: payload length must be a multiple of 8'); + } + const out = []; + for (let i = 0; i < payload.length; i += 8) { + const entry = payload.slice(i, i + 8); + const eventId = entry[7]; + if (eventId === 0) + continue; + out.push({ + index: i / 8, + eventId, + eventName: LOG_EVENT_NAMES[eventId] ?? `EVENT_${eventId}`, + timestampUnixSeconds: eventId === 20 ? null : asmRtcBytesToUnixSeconds(entry.slice(0, 7)), + batteryMilliVolts: eventId === 20 ? u24le(entry, 0) : null, + }); + } + return out; +} +/** Parse record-buffer details payload (26-byte current layout, 19-byte legacy layout). */ +function parseRecordBufferDetailsPayload(payload) { + const bytesPerBuffer = payload.length % 26 === 0 ? 26 : payload.length % 19 === 0 ? 19 : 0; + if (!bytesPerBuffer) { + throw new Error('parseRecordBufferDetailsPayload: unsupported payload length'); + } + const out = []; + for (let i = 0; i < payload.length; i += bytesPerBuffer) { + const row = payload.slice(i, i + bytesPerBuffer); + out.push({ + bufferIndex: row[0], + bufferState: row[1], + packagedPayloadIndex: u16le_at(row, 2), + currentByteIndexForSensorData: u16le_at(row, 4), + usedBufferLength: u16le_at(row, 6), + fifoTicks: u16le_at(row, 8), + dataTimestampRwcMinutes: u32le_at(row, 10), + dataTimestampRwcTicks: u24le(row, 14), + temperatureData: u16le_at(row, 17), + dataTimestampUcClockMinutes: bytesPerBuffer >= 23 ? u32le_at(row, 19) : null, + dataTimestampUcClockTicks: bytesPerBuffer >= 26 ? u24le(row, 23) : null, + }); + } + return out; +} +/** + * Infer the lookup-table bank count from a raw debug payload length. The payload + * is 3 bytes per bank, optionally prefixed with a 4-byte head/tail block. + * Returns 0 if the length matches neither layout. + */ +function inferVerisenseLookupBankCount(payloadLen) { + if (!Number.isFinite(payloadLen) || payloadLen <= 0) + return 0; + if (payloadLen >= 4 && (payloadLen - 4) % 3 === 0) + return Math.floor((payloadLen - 4) / 3); + if (payloadLen % 3 === 0) + return Math.floor(payloadLen / 3); + return 0; +} +/** + * Parse lookup-table debug payload entries (3 bytes per bank), with optional + * 4-byte tail/head prefix present in older firmware debug responses. When + * `totalBanks` is omitted it is inferred from the payload length via + * {@link inferVerisenseLookupBankCount}. + */ +function parseLookupTablePayload(payload, totalBanks) { + const bytesPerBank = 3; + const banks = totalBanks ?? inferVerisenseLookupBankCount(payload.length); + const expectedNoHeadTail = banks * bytesPerBank; + const expectedWithHeadTail = expectedNoHeadTail + 4; + let data = payload; + let head = null; + let tail = null; + if (payload.length === expectedWithHeadTail) { + tail = u16le_at(payload, 0); + head = u16le_at(payload, 2); + data = payload.slice(4); + } + else if (payload.length !== expectedNoHeadTail) { + throw new Error(`parseLookupTablePayload: payload length ${payload.length} does not match expected ${expectedNoHeadTail} or ${expectedWithHeadTail}`); + } + const entries = []; + for (let bankIndex = 0; bankIndex < banks; bankIndex++) { + const off = bankIndex * bytesPerBank; + const statusByte = data[off]; + const pendingEepromWrite = (statusByte & 0x80) !== 0; + const statusCode = statusByte & 0x7f; + entries.push({ + bankIndex, + statusCode, + statusName: LOOKUP_STATUS_NAMES[statusCode] ?? 'Unknown', + pendingEepromWrite, + payloadIndex: u16le_at(data, off + 1), + }); + } + return { head, tail, entries }; +} +/** + * Parse the production config response payload into a structured object. + */ +function parseProductionConfigPayload(response) { + const configHeader = response[0]; + const asmid = [...response.slice(1, 7)] + .reverse() + .map((b) => b.toString(16).padStart(2, '0')) + .join(''); + const revHwMajor = response[7]; + const revHwMinor = response[8]; + const revFwMajor = response[9]; + const revFwMinor = response[10]; + const fwInternalArray = response.slice(11, 13); + const revFwInternal = fwInternalArray[0] | (fwInternalArray[1] << 8); + let revHwInternal = 0; + if (response.length >= 15) { + const hwInternalArray = response.slice(13, 15); + if (!isUniformByteArray(hwInternalArray, 0xff)) { + revHwInternal = hwInternalArray[0] | (hwInternalArray[1] << 8); + } + } + return { + hardware: `${revHwMajor}.${revHwMinor}.${revHwInternal}`, + firmware: `${revFwMajor}.${revFwMinor}.${revFwInternal}`, + asmid: asmid.toUpperCase(), + configHeader, + revHwMajor, + revHwMinor, + revHwInternal, + revFwMajor, + revFwMinor, + revFwInternal, + }; +} +/** + * Firmware default passkeys by passkey ID: a production config programmed + * with passkey ID "01" pairs with the fixed PIN "123456". Other IDs have no + * fixed default (ID "00" uses the per-device derived PIN — see + * {@link computeVerisensePairingPin}). + */ +const VERISENSE_DEFAULT_PASSKEY_BY_ID = Object.freeze({ + '01': '123456', +}); +/** The fixed passkey for a passkey ID, or undefined when the ID has none + * (leave the passkey bytes unset in the production config). */ +function defaultVerisensePasskeyForId(passkeyId) { + return VERISENSE_DEFAULT_PASSKEY_BY_ID[String(passkeyId ?? '').trim()]; +} +/** + * Build the name a Verisense sensor advertises over BLE: + * `--` (e.g. "Verisense-01-25112101B10F"). + * Returns null when any part is missing — matches how apps derive the name + * from a parsed production config that may be blank/erased. + */ +function buildVerisenseAdvertisedName(parts) { + const prefix = String(parts.prefix ?? '').trim(); + const passkeyId = String(parts.passkeyId ?? '').trim(); + const uniqueId = String(parts.uniqueId ?? '').trim(); + if (!prefix || !passkeyId || !uniqueId) + return null; + return `${prefix}-${passkeyId}-${uniqueId}`; +} +/** + * Split a Verisense advertised name back into its parts. The unique ID is the + * final `-`-separated token; the passkey ID the token before it; anything + * earlier (which may itself contain `-`) is the prefix. Returns null when the + * name does not have at least three tokens. + */ +function parseVerisenseAdvertisedName(name) { + const tokens = String(name ?? '') + .trim() + .split('-'); + if (tokens.length < 3) + return null; + const uniqueId = tokens[tokens.length - 1]; + const passkeyId = tokens[tokens.length - 2]; + const prefix = tokens.slice(0, -2).join('-'); + if (!prefix || !passkeyId || !uniqueId) + return null; + return { prefix, passkeyId, uniqueId }; +} +/** + * The 4-hex MAC ID from a Verisense advertised name (the advertised name ends + * with the unique ID = manufacturing order + MAC; its last 4 hex chars are + * the MAC ID). Returns null when the tail is not valid hex. + */ +function deriveVerisenseMacIdFromName(name) { + const tail = (String(name ?? '') + .trim() + .split('-') + .pop() ?? '') + .replace(/[^0-9A-Fa-f]/g, '') + .toUpperCase() + .slice(-4); + return /^[0-9A-F]{4}$/.test(tail) ? tail : null; +} +/** + * Short device tag for file names (e.g. "…-B10F-…"): the last 4 hex chars of + * a device unique ID or advertised name. Returns "" when unknown so callers + * can omit it cleanly. + */ +function verisenseDeviceFileTag(idOrName) { + const hex = String(idOrName ?? '').replace(/[^0-9A-Fa-f]/g, ''); + return hex.length >= 4 ? hex.slice(-4).toUpperCase() : ''; +} + +/** + * Verisense sensor-calibration TLV codec. + * + * Mirrors the firmware `asm_calibration.{c,h}` byte format. A calibration "blob" + * is a self-describing block of per-sensor calibration that the device persists, + * exposes over the `CALIBRATION` command, and stamps into every logged payload + * header via a CRC-16 version tag. + * + * Layout (all little-endian): + * + * Global header (12 bytes) + * 0 u16 totalLen (= blob.length - 2) + * 2 u8 calibFormatVersion + * 3 u8 hwVerMajor + * 4 u8 hwVerMinor + * 5 u8 fwVerMajor + * 6 u8 fwVerMinor + * 7 u16 fwVerPatch + * 9 u8 sensorBlockCount + * 10 u16 reserved + * + * Per-sensor block (12-byte header + payload) + * 0 u16 sensorId (calibration-domain id, see {@link CalibSensorId}) + * 2 u8 range/quality (bits[5:0] full-scale index; bits[7:6] calib quality) + * 3 u8 dataLen + * 4 u8[8] ts (0 = default/seeded; RTC time = real per-unit cal) + * 12 payload[dataLen] + * + * IMU payload (60 bytes, float32): bias[3] · sens[3] · align[9] (row-major 3x3) + * + * Calibration math (ASM-DES04 §8): output = K·R·physical + b, so the host + * recovers physical = R⁻¹·K⁻¹·(raw − b). K is the diagonal sensitivity, R the + * rotation into the common ASM axes, b the offset bias. + */ +const SC_CALIB_FORMAT_VERSION = 1; +const SC_GLOBAL_HEADER_BYTES = 12; +const SC_BLOCK_HEADER_BYTES = 12; +const SC_TS_BYTES = 8; +const SC_DATA_LEN_IMU = 60; +/** + * The per-block `range` byte packs the full-scale index in bits [5:0] and a 2-bit + * calibration-quality indicator in bits [7:6]. Lookups/comparisons must use only + * the index (`range & SC_CAL_RANGE_MASK`). Quality has no producer yet (always 0), + * so it is reserved without growing the blob or bumping the format version. + */ +const SC_CAL_RANGE_MASK = 0x3f; +const SC_CAL_QUALITY_SHIFT = 6; +const SC_CAL_QUALITY_MASK = 0x03; +/** Calibration-quality indicator (ST MotionAC / Android sensor-accuracy convention). */ +const CalibQuality = { + UNKNOWN: 0, + POOR: 1, + OK: 2, + GOOD: 3, +}; +/** + * Calibration-domain sensor IDs. Distinct from the data-stream sensor IDs + * (1=ADC, 2=LIS2DW12, 3=LSM6DS3, 4=PPG, 6=LSM6DSV, 7=VD6283, 8=MAX32674, + * 9=MLX90632). These reuse the Shimmer3 `SC_SENSOR_*` values where they exist, + * so accel/gyro/mag can each carry their own calibration even though one + * data-stream id (6) covers all three. + * + * Data-stream → calibration mapping: 6 → {37, 38, 42}, 2 → {39}, 3 → {40, 41}. + */ +const CalibSensorId = { + LSM6DSV_ACCEL: 37, + LSM6DSV_GYRO: 38, + LIS2DW12_ACCEL: 39, + /** 1st-gen LSM6DS3 accel (data-stream id 3). */ + LSM6DS3_ACCEL: 40, + /** 1st-gen LSM6DS3 gyro (data-stream id 3). */ + LSM6DS3_GYRO: 41, + LIS2MDL_MAG: 42, +}; +function parseImuPayload(p) { + return { + bias: [f32le(p, 0), f32le(p, 4), f32le(p, 8)], + sens: [f32le(p, 12), f32le(p, 16), f32le(p, 20)], + align: [ + f32le(p, 24), + f32le(p, 28), + f32le(p, 32), + f32le(p, 36), + f32le(p, 40), + f32le(p, 44), + f32le(p, 48), + f32le(p, 52), + f32le(p, 56), + ], + }; +} +/** Parse a calibration blob into a typed, indexable {@link CalibrationSet}. */ +function parseCalibrationBlob(blob) { + if (blob.length < SC_GLOBAL_HEADER_BYTES) { + throw new Error(`parseCalibrationBlob: blob too short (${blob.length} < ${SC_GLOBAL_HEADER_BYTES})`); + } + const totalLen = u16le_at(blob, 0); + if (totalLen + 2 !== blob.length) { + throw new Error(`parseCalibrationBlob: totalLen ${totalLen} does not match blob.length-2 ${blob.length - 2}`); + } + const formatVersion = blob[2]; + const hwVerMajor = blob[3]; + const hwVerMinor = blob[4]; + const fwVerMajor = blob[5]; + const fwVerMinor = blob[6]; + const fwVerPatch = u16le_at(blob, 7); + const blockCount = blob[9]; + const reserved = u16le_at(blob, 10); + const blocks = []; + let off = SC_GLOBAL_HEADER_BYTES; + for (let i = 0; i < blockCount; i++) { + if (off + SC_BLOCK_HEADER_BYTES > blob.length) { + throw new Error(`parseCalibrationBlob: block ${i} header out of range`); + } + const sensorId = u16le_at(blob, off); + const rangeByte = blob[off + 2]; + const range = rangeByte & SC_CAL_RANGE_MASK; + const quality = (rangeByte >> SC_CAL_QUALITY_SHIFT) & SC_CAL_QUALITY_MASK; + const dataLen = blob[off + 3]; + const ts = blob.slice(off + 4, off + 4 + SC_TS_BYTES); + const payloadStart = off + SC_BLOCK_HEADER_BYTES; + if (payloadStart + dataLen > blob.length) { + throw new Error(`parseCalibrationBlob: block ${i} payload out of range`); + } + const payload = blob.slice(payloadStart, payloadStart + dataLen); + const isDefault = ts.every((b) => b === 0); + const block = { sensorId, range, quality, dataLen, ts, isDefault, payload }; + if (dataLen === SC_DATA_LEN_IMU) { + block.imu = parseImuPayload(payload); + } + blocks.push(block); + off = payloadStart + dataLen; + } + const crc16 = crc16_ccitt_false(blob); + return { + formatVersion, + hwVerMajor, + hwVerMinor, + fwVerMajor, + fwVerMinor, + fwVerPatch, + reserved, + blocks, + crc16, + getImu(sensorId, range) { + const b = blocks.find((x) => x.sensorId === sensorId && x.range === range && x.imu); + return b?.imu ?? null; + }, + }; +} +function serializeImuPayload(imu) { + const out = new Uint8Array(SC_DATA_LEN_IMU); + const dv = new DataView(out.buffer); + for (let i = 0; i < 3; i++) + dv.setFloat32(i * 4, imu.bias[i] ?? 0, true); + for (let i = 0; i < 3; i++) + dv.setFloat32(12 + i * 4, imu.sens[i] ?? 0, true); + for (let i = 0; i < 9; i++) + dv.setFloat32(24 + i * 4, imu.align[i] ?? 0, true); + return out; +} +/** Serialize a calibration set into a blob (inverse of {@link parseCalibrationBlob}). */ +function serializeCalibrationBlob(input) { + const payloads = input.blocks.map((b) => { + if (b.payload) + return b.payload; + if (b.imu) + return serializeImuPayload(b.imu); + throw new Error('serializeCalibrationBlob: each block needs imu or payload'); + }); + let total = SC_GLOBAL_HEADER_BYTES; + for (const p of payloads) + total += SC_BLOCK_HEADER_BYTES + p.length; + const out = new Uint8Array(total); + const dv = new DataView(out.buffer); + dv.setUint16(0, total - 2, true); + out[2] = input.formatVersion ?? SC_CALIB_FORMAT_VERSION; + out[3] = input.hwVerMajor & 0xff; + out[4] = input.hwVerMinor & 0xff; + out[5] = input.fwVerMajor & 0xff; + out[6] = input.fwVerMinor & 0xff; + dv.setUint16(7, input.fwVerPatch & 0xffff, true); + out[9] = input.blocks.length & 0xff; + dv.setUint16(10, (input.reserved ?? 0) & 0xffff, true); + let off = SC_GLOBAL_HEADER_BYTES; + input.blocks.forEach((b, i) => { + const payload = payloads[i]; + dv.setUint16(off, b.sensorId & 0xffff, true); + out[off + 2] = + (b.range & SC_CAL_RANGE_MASK) | + (((b.quality ?? 0) & SC_CAL_QUALITY_MASK) << SC_CAL_QUALITY_SHIFT); + out[off + 3] = payload.length & 0xff; + if (b.ts) + out.set(b.ts.subarray(0, SC_TS_BYTES), off + 4); // else leave zero (default) + out.set(payload, off + SC_BLOCK_HEADER_BYTES); + off += SC_BLOCK_HEADER_BYTES + payload.length; + }); + return out; +} +/** CRC-16/CCITT-FALSE over a serialized blob — the value stamped into payload headers. */ +function calibrationBlobCrc(blob) { + return crc16_ccitt_false(blob); +} +/** + * Apply IMU calibration to a raw tri-axial sample. + * + * physical = align · (K⁻¹ · (raw − bias)) + * + * `bias` (b) is subtracted and `sens` (K, diagonal) divided per axis, then the + * `align` matrix (row-major 3x3) is applied directly to rotate the sensor frame + * into the common ASM frame. With identity `align` and zero `bias` this reduces + * to `raw / sens`. + * + * Convention note: `align` is the directly-applied sensor-frame → ASM-frame + * matrix (= R⁻¹ in ASM-DES04 §8's `output = K·R·physical + b` notation). This + * matches the cloud calibration CSV `rotation_*` columns one-to-one — the CSV + * stores the same applied matrix, row-major — so the sensor-calibration parser + * maps blob → CSV with NO transpose. (Confirmed against a LIS2DW12 sample CSV: + * offset→bias, sensitivity→sens, rotation→align.) + */ +function applyImuCalibration(raw, cal) { + const v0 = (raw[0] - cal.bias[0]) / cal.sens[0]; + const v1 = (raw[1] - cal.bias[1]) / cal.sens[1]; + const v2 = (raw[2] - cal.bias[2]) / cal.sens[2]; + const a = cal.align; + return [ + a[0] * v0 + a[1] * v1 + a[2] * v2, + a[3] * v0 + a[4] * v1 + a[5] * v2, + a[6] * v0 + a[7] * v1 + a[8] * v2, + ]; +} + +/** Build a protocol header byte from command/property nibbles. */ +function buildHeader(command, property) { + return ((command & 0xf0) | (property & 0x0f)) & 0xff; +} +/** Decode a protocol header byte into command/property fields. */ +function parseHeader(header) { + return { + command: (header & 0xf0), + property: (header & 0x0f), + }; +} +/** Build a complete protocol message (header + 16-bit LE payload length + payload bytes). */ +function buildMessage(command, property, payloadBytes = []) { + const payload = payloadBytes instanceof Uint8Array ? payloadBytes : new Uint8Array(payloadBytes); + const out = new Uint8Array(3 + payload.length); + out[0] = buildHeader(command, property); + out[1] = payload.length & 0xff; + out[2] = (payload.length >> 8) & 0xff; + out.set(payload, 3); + return out; +} +// --------------------------------------------------------------------------- +// Streaming-frame framing / resynchronisation +// --------------------------------------------------------------------------- +/** + * Header byte that prefixes every streaming data frame: + * `RESPONSE (0x30) | STREAM_MODE (0x0a) === 0x3A`. + */ +const STREAM_FRAME_HEADER = buildHeader(ASM_COMMAND.RESPONSE, ASM_PROPERTY.STREAM_MODE); +/** Smallest valid streaming payload: sensorId(1) + tick(3) + CRC16(2). */ +const STREAM_FRAME_MIN_PAYLOAD = 6; +/** + * Largest streaming payload we will accept. The firmware packages multi-sample + * sensor records into a single logical frame that is frequently much larger + * than one BLE notification (e.g. ~1.8 kB for an LSM6DSV accel/gyro/mag burst) + * and fragments it across several notifications; the host reassembles them in + * its receive buffer before this scanner runs. The ceiling must therefore cover + * the firmware's largest packaged payload — it mirrors the length-only path's + * `MAX_FRAME_PAYLOAD_LEN` (see VerisenseClient) — not the BLE MTU. It still + * bounds how far a corrupt length field can run before the CRC rejects it + * during resync. + * + * WARNING: do NOT shrink this to an MTU-sized value. A small ceiling silently + * drops every large frame (accel/gyro/mag), because their length exceeds the + * cap and the CRC trailer is never reached — the stream just looks dead. + */ +const STREAM_FRAME_MAX_PAYLOAD = 40000; +const STREAM_SCAN_NEED_MORE = { status: 'need-more' }; +const STREAM_SCAN_INVALID = { status: 'invalid' }; +/** + * Try to read one CRC-validated streaming frame from the front of `buf`. + * + * On the wire a streaming frame is: + * + * ``` + * [0x3A][ len LE (2) ][ sensorId(1) | tick(3) | samples… | CRC16(2) ] + * ``` + * + * where `len` is the payload length **including** the trailing 2-byte CRC, and + * the CRC-16/CCITT-FALSE covers the payload up to (but not including) those last + * 2 bytes — matching the firmware's `crc16_ccitt(buf + 3, len - 2)`. + * + * The framing has no start/sync marker, so the CRC is what makes + * resynchronisation reliable: after a flaky link drops bytes and knocks the + * stream out of alignment, the caller slides one byte at a time and accepts a + * boundary only when its CRC checks out, so misaligned/garbage data can no + * longer masquerade as a valid (but wrong sensor-id) packet. + * + * Returns: + * - `need-more` — too few bytes buffered to decide; wait for the next chunk. + * - `invalid` — the front of the buffer is not a valid frame start; the + * caller should drop one byte and try again. + * - `frame` — a CRC-valid frame; `payload` is the `len`-byte payload (CRC + * trailer included) and `consumed` is `3 + len` bytes to remove. + */ +function scanStreamFrame(buf) { + if (buf.length < 3) + return STREAM_SCAN_NEED_MORE; + if (buf[0] !== STREAM_FRAME_HEADER) + return STREAM_SCAN_INVALID; + const len = (buf[1] | (buf[2] << 8)) >>> 0; + if (len < STREAM_FRAME_MIN_PAYLOAD || len > STREAM_FRAME_MAX_PAYLOAD) { + return STREAM_SCAN_INVALID; + } + if (buf.length < 3 + len) + return STREAM_SCAN_NEED_MORE; + // CRC trailer is the last 2 payload bytes (LE); it covers the payload before it. + const crcAt = 3 + len - 2; + const claimed = (buf[crcAt] | (buf[crcAt + 1] << 8)) >>> 0; + const calc = crc16_ccitt_false(buf.subarray(3, crcAt)); + if (calc !== claimed) + return STREAM_SCAN_INVALID; + return { status: 'frame', payload: buf.slice(3, 3 + len), consumed: 3 + len }; +} +/** Parse a complete protocol message into structured fields. */ +function parseMessage(msg) { + if (msg.length < 3) + throw new Error('Invalid Verisense message: header is incomplete'); + const header = msg[0]; + const payloadLength = u16le$1(msg[1], msg[2]); + if (msg.length !== payloadLength + 3) { + throw new Error(`Invalid Verisense message: length=${payloadLength}, actualPayload=${Math.max(0, msg.length - 3)}`); + } + const { command, property } = parseHeader(header); + return { + header, + command, + property, + payloadLength, + payload: msg.slice(3), + }; +} +function isAckCommand(command) { + return command === ASM_COMMAND.ACK || command === ASM_COMMAND.ACK_NEXT_STAGE; +} +function isNackCommand(command) { + return (command === ASM_COMMAND.NACK_BAD_HEADER_COMMAND || + command === ASM_COMMAND.NACK_BAD_HEADER_PROPERTY || + command === ASM_COMMAND.NACK_GENERIC); +} +/** Convert a pending-events payload (property IDs) into a typed array. */ +function parsePendingEvents(payload) { + const out = []; + for (let i = 0; i < payload.length; i++) + out.push((payload[i] & 0x0f)); + return out; +} + +function pad2(n) { + return Math.trunc(n).toString().padStart(2, '0'); +} +function pad5(n) { + return Math.trunc(n).toString().padStart(5, '0'); +} +function dateToYyMMddHHmmss(date) { + const yy = pad2(date.getUTCFullYear() % 100); + const mm = pad2(date.getUTCMonth() + 1); + const dd = pad2(date.getUTCDate()); + const hh = pad2(date.getUTCHours()); + const min = pad2(date.getUTCMinutes()); + const ss = pad2(date.getUTCSeconds()); + return `${yy}${mm}${dd}_${hh}${min}${ss}`; +} +/** Build a binary upload file name: yyMMdd_HHmmss_00000.bin */ +function buildUploadBinaryFileName(uploadDate, firstPayloadIndex) { + if (!Number.isFinite(firstPayloadIndex) || firstPayloadIndex < 0 || firstPayloadIndex > 0xffff) { + throw new Error('buildUploadBinaryFileName: firstPayloadIndex must be in range 0..65535'); + } + return `${dateToYyMMddHHmmss(uploadDate)}_${pad5(firstPayloadIndex)}.bin`; +} +/** Build parsed CSV file name: yyMMdd_HHmmss_DataSource_00000.csv */ +function buildParsedCsvFileName(startDate, dataSource, firstPayloadIndex) { + if (!dataSource || !String(dataSource).trim()) { + throw new Error('buildParsedCsvFileName: dataSource must be a non-empty string'); + } + if (!Number.isFinite(firstPayloadIndex) || firstPayloadIndex < 0 || firstPayloadIndex > 0xffff) { + throw new Error('buildParsedCsvFileName: firstPayloadIndex must be in range 0..65535'); + } + return `${dateToYyMMddHHmmss(startDate)}_${String(dataSource).trim()}_${pad5(firstPayloadIndex)}.csv`; +} +/** Add duplicate suffix like " (2)" before extension. */ +function applyDuplicateSuffix(fileName, duplicateIndex) { + if (duplicateIndex < 2) { + throw new Error('applyDuplicateSuffix: duplicateIndex must be >= 2'); + } + const idx = fileName.lastIndexOf('.'); + if (idx <= 0) + return `${fileName} (${duplicateIndex})`; + const stem = fileName.slice(0, idx); + const ext = fileName.slice(idx); + return `${stem} (${duplicateIndex})${ext}`; +} +/** Return first non-colliding duplicate name for a target file name. */ +function nextAvailableDuplicateFileName(fileName, existingNames) { + const existing = new Set(existingNames); + if (!existing.has(fileName)) + return fileName; + let i = 2; + while (true) { + const candidate = applyDuplicateSuffix(fileName, i); + if (!existing.has(candidate)) + return candidate; + i++; + } +} +/** Parse first payload index (uint16 LE) from a payload byte array. */ +function getFirstPayloadIndex(payload) { + if (payload.length < 2) { + throw new Error('getFirstPayloadIndex: payload must contain at least 2 bytes'); + } + return u16le_at(payload, 0); +} +/** + * Evaluate whether parsed CSV output should roll to a new file. + * Rules mirror ASM-DES08 split conditions. + */ +function evaluateParsedFileSplit(input) { + const reasons = []; + const prev = input.prevTimestampSec; + const curr = input.currTimestampSec; + // Split when crossing 12:00am or 12:00pm boundaries. + const prevHalfDay = Math.floor(prev / (12 * 60 * 60)); + const currHalfDay = Math.floor(curr / (12 * 60 * 60)); + if (currHalfDay !== prevHalfDay) + reasons.push('midday-midnight-boundary'); + if ((input.prevConfigSignature ?? null) !== (input.currConfigSignature ?? null)) { + reasons.push('config-change'); + } + if (input.expectedDeltaSec != null) { + const tol = Math.max(0, input.timestampToleranceSec ?? 0); + const delta = curr - prev; + if (Math.abs(delta - input.expectedDeltaSec) > tol) { + reasons.push('timestamp-discontinuity'); + } + } + if (input.powerResetDetected) { + reasons.push('power-reset'); + } + return { shouldSplit: reasons.length > 0, reasons }; +} + +const VERISENSE_HW_MAJOR_FRIENDLY_NAMES = { + 61: 'IMU', + 62: 'GSR+', + 64: 'SDK', + 68: 'Pulse+', +}; +function getVerisenseHardwareFriendlyName(revHwMajor) { + return VERISENSE_HW_MAJOR_FRIENDLY_NAMES[revHwMajor] ?? null; +} +/** + * Second-generation Verisense hardware is currently defined as: + * - SR61.5+ + * - SR68.9+ + * - Any future major revision above SR68 + */ +function isVerisenseSecondGenerationHardware(revHwMajor, revHwMinor) { + const major = Number(revHwMajor); + const minor = Number(revHwMinor); + if (!Number.isFinite(major) || !Number.isFinite(minor)) + return false; + if (major > 68) + return true; + if (major === 61 && minor >= 5) + return true; + if (major === 68 && minor >= 9) + return true; + return false; +} +function getVerisenseHardwareCapabilities(revHwMajor, revHwMinor) { + const secondGeneration = isVerisenseSecondGenerationHardware(revHwMajor, revHwMinor); + return { + secondGeneration, + supportsMagnetometer: secondGeneration, + }; +} +/** + * GSR-capable hardware. Mirrors the firmware's authoritative + * `ShimBrd_isGsrSupportedForHwVersion` (shimmer_boards.c): + * - SR62 (any revision) + * - SR61 minor >= 5 + * - SR68 minor >= 5 + * + * Deliberately NOT {@link isVerisenseSecondGenerationHardware}: that predicate + * requires SR68 >= 9, but GSR arrived on the SR68 at minor revision 5. + */ +function isVerisenseGsrSupportedHardware(revHwMajor, revHwMinor) { + const major = Number(revHwMajor); + const minor = Number(revHwMinor); + if (!Number.isFinite(major) || !Number.isFinite(minor)) + return false; + return major === 62 || ((major === 61 || major === 68) && minor >= 5); +} +const VERISENSE_SENSOR_SUPPORT_NONE = { + accel1: false, + gyroAccel2: false, + imuGen2: false, + gsr: false, + ppg: false, + ambientLight: false, + skinTemperature: false, + algorithmHub: false, + ledAutoBrightness: false, +}; +const VERISENSE_SENSOR_SUPPORT_ALL = { + accel1: true, + gyroAccel2: true, + imuGen2: true, + gsr: true, + ppg: true, + ambientLight: true, + skinTemperature: true, + algorithmHub: true, + ledAutoBrightness: true, +}; +/** + * Resolves which sensor blocks a given Verisense hardware revision carries, + * derived from the firmware Model IC matrix + * (verisense-firmware/docs/VERISENSE_MODEL_IC_MATRIX.md). + * + * Unknown / development hardware (e.g. SR64, or any unrecognised major + * revision) reports every block as present so consumers never hide a setting + * they cannot confidently rule out. + */ +function getVerisenseHardwareSensorSupport(revHwMajor, revHwMinor) { + const major = Number(revHwMajor); + const minor = Number(revHwMinor); + if (!Number.isFinite(major) || !Number.isFinite(minor)) { + return { ...VERISENSE_SENSOR_SUPPORT_ALL }; + } + const gen2 = isVerisenseSecondGenerationHardware(major, minor); + switch (major) { + case 61: // Verisense IMU + return gen2 + ? // SR61.5+: LSM6DSV + LIS2MDL, GSR, ambient light, 2xRGB LEDs. + { + ...VERISENSE_SENSOR_SUPPORT_NONE, + imuGen2: true, + gsr: true, + ambientLight: true, + ledAutoBrightness: true, + } + : // SR61.1-4: LIS2DW12 + LSM6DS3 only. + { ...VERISENSE_SENSOR_SUPPORT_NONE, accel1: true, gyroAccel2: true }; + case 62: // Verisense GSR+: LIS2DW12 + LSM6DS3, GSR, analog PPG. + return { + ...VERISENSE_SENSOR_SUPPORT_NONE, + accel1: true, + gyroAccel2: true, + gsr: true, + ppg: true, + }; + case 63: // Verisense PPG: LIS2DW12 + LSM6DS3 + PPG. + return { ...VERISENSE_SENSOR_SUPPORT_NONE, accel1: true, gyroAccel2: true, ppg: true }; + case 68: // Verisense Pulse+ + return gen2 + ? // SR68.9+: full 2nd-gen stack. The LIS2DW12 (accel1) is physically + // present but routed to the algorithm hub and not recorded from, so + // it is treated as unsupported for operational-config purposes. + { + ...VERISENSE_SENSOR_SUPPORT_NONE, + imuGen2: true, + gsr: true, + ppg: true, + ambientLight: true, + skinTemperature: true, + algorithmHub: true, + ledAutoBrightness: true, + } + : // SR68.1-8: LIS2DW12 + PPG; GSR added from SR68.5 (Model IC matrix + + // firmware ShimBrd_isGsrSupportedForHwVersion); skin temperature from + // SR68.7. + { + ...VERISENSE_SENSOR_SUPPORT_NONE, + accel1: true, + ppg: true, + gsr: isVerisenseGsrSupportedHardware(major, minor), + skinTemperature: minor >= 7, + }; + default: + // SR64 (dev board) and any future/unknown major: assume everything. + return { ...VERISENSE_SENSOR_SUPPORT_ALL }; + } +} +function getVerisenseHardwareRevision(source) { + if (!source) + return null; + const major = Number(source.revHwMajor); + const minor = Number(source.revHwMinor); + const internal = Number(source.revHwInternal); + if (!Number.isFinite(major) || !Number.isFinite(minor) || !Number.isFinite(internal)) { + return null; + } + if (major <= 0 || major > 255 || minor < 0 || minor > 255 || internal < 0 || internal > 65535) { + return null; + } + return { + major: Math.trunc(major), + minor: Math.trunc(minor), + internal: Math.trunc(internal), + }; +} +function supportsVerisenseMagnetometer(source) { + const hw = getVerisenseHardwareRevision(source); + if (!hw) + return false; + return getVerisenseHardwareCapabilities(hw.major, hw.minor).supportsMagnetometer; +} +function formatVerisenseHardwareRevision(revHwMajor, revHwMinor, revHwInternal = 0, opts = {}) { + const prefix = opts.prefix ?? 'SR'; + const base = `${prefix}${revHwMajor}.${revHwMinor}.${revHwInternal}`; + if (!opts.includeFriendlyName) + return base; + const friendly = getVerisenseHardwareFriendlyName(revHwMajor); + return friendly ? `${base} (${friendly})` : base; +} +/** + * Battery voltage scaling for streamed ADC battery samples. + * Status responses already contain firmware-scaled battery values and should not use this helper. + */ +function getVerisenseStreamingBatteryVoltageMultiplier(revHwMajor, revHwMinor) { + // SR62 + if (revHwMajor === 62) + return 2.0; + // SR61.5+, SR68.9+, and newer major revisions. + if (isVerisenseSecondGenerationHardware(revHwMajor, revHwMinor)) { + return 2.469; + } + return 1.0; +} + +const VERISENSE_OPERATIONAL_FIELD_SCHEMA = [ + // GEN_CFG_0 + { + key: 'BLUETOOTH_EN', + label: 'Bluetooth', + desc: 'Enable BLE', + kind: 'bit', + index: OP_IDX.GEN_CFG_0, + shift: 4, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'USB_EN', + label: 'USB', + desc: 'Enable USB interface', + kind: 'bit', + index: OP_IDX.GEN_CFG_0, + shift: 3, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + // GEN_CFG_0 bit 2 is unused (was PRIORITISE_LONG_TERM_FLASH, removed in + // DEV-806): never used and never read by the firmware. The bit is left unused + // in the byte layout (free to repurpose); older configs that set it are simply + // ignored. + { + key: 'DEVICE_EN', + label: 'Device', + desc: 'Master device enable', + kind: 'bit', + index: OP_IDX.GEN_CFG_0, + shift: 1, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'RECORDING_EN', + label: 'Recording', + desc: 'Enable recording', + kind: 'bit', + index: OP_IDX.GEN_CFG_0, + shift: 0, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + // GEN_CFG_1 + { + key: 'DATA_COMPRESSION_MODE', + label: 'Data Compression', + desc: '0: Off, 1: ZLIB (future), 2: XZ (future), 3: Reserved', + kind: 'bit', + index: OP_IDX.GEN_CFG_1, + shift: 0, + width: 2, + options: [ + [0, 'Off'], + [1, 'ZLIB (future)'], + [2, 'XZ (future)'], + [3, 'Reserved'], + ], + }, + // GEN_CFG_2/3 + { + key: 'HR_PPG_CHANNEL', + label: 'HR PPG Channel', + desc: 'Default HR channel', + kind: 'bit', + index: OP_IDX.GEN_CFG_2, + shift: 6, + width: 2, + options: [ + [0, 'IR'], + [1, 'RED'], + [2, 'GREEN'], + [3, 'BLUE'], + ], + }, + { + key: 'STEP_COUNT_EN', + label: 'Step Counter', + desc: 'Enable step counter', + kind: 'bit', + index: OP_IDX.GEN_CFG_2, + shift: 5, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'PENDING_EVENTS_SCHEDULER_DISABLED', + label: 'Pending Events Scheduler', + desc: 'Enable/disable pending events scheduler', + kind: 'bit', + index: OP_IDX.GEN_CFG_2, + shift: 4, + width: 1, + options: [ + [0, 'Enabled'], + [1, 'Disabled'], + ], + }, + { + key: 'LOW_BATT_AUTO_STOP_DISABLED', + label: 'Low-Power Auto-Stop', + desc: 'Stop recording and BLE data transfers when the battery drops below the low-power threshold. Disabling keeps the device recording until the battery is exhausted, at the risk of data loss from brown-out.', + kind: 'bit', + index: OP_IDX.GEN_CFG_2, + shift: 3, + width: 1, + options: [ + [0, 'Enabled'], + [1, 'Disabled'], + ], + }, + { + key: 'BATT_TYPE', + label: 'Battery Type', + desc: 'Battery chemistry', + kind: 'bit', + index: OP_IDX.GEN_CFG_2, + shift: 0, + width: 1, + options: [ + [0, 'Zinc-Air'], + [1, 'NiMH'], + ], + }, + { + key: 'MAG_EN', + label: 'Magnetometer', + desc: 'Enable LIS2MDL magnetometer (second-generation hardware)', + kind: 'bit', + index: OP_IDX.GEN_CFG_3, + shift: 2, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'LED_MODE', + label: 'LED Mode', + desc: '0 Off, 1 On, 2 Low-power', + kind: 'bit', + index: OP_IDX.GEN_CFG_3, + shift: 0, + width: 2, + options: [ + [0, 'Off'], + [1, 'On'], + [2, 'Low-power'], + [3, 'Reserved'], + ], + }, + // ACCEL1 + { + key: 'ODR', + label: 'Accel1 ODR', + desc: 'Accel1 sampling rate mode', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_0, + shift: 4, + width: 4, + options: [ + [0, 'Power-down'], + [1, '12.5/1.6 Hz'], + [2, '12.5 Hz'], + [3, '25 Hz'], + [4, '50 Hz'], + [5, '100 Hz'], + [6, '200 Hz'], + [7, '400/200 Hz'], + [8, '800/200 Hz'], + [9, '1600/200 Hz'], + ], + }, + { + key: 'MODE', + label: 'Accel1 Mode', + desc: 'Operating mode', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_0, + shift: 2, + width: 2, + options: [ + [0, 'Low-Power'], + [1, 'High-Performance'], + [2, 'Single conversion'], + [3, 'Reserved'], + ], + }, + { + key: 'LP_MODE', + label: 'Accel1 LP Mode', + desc: 'Low-power sub-mode', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_0, + shift: 0, + width: 2, + options: [ + [0, 'LP1'], + [1, 'LP2'], + [2, 'LP3'], + [3, 'LP4'], + ], + }, + { + key: 'BW_FILT', + label: 'Accel1 BW Filter', + desc: '00 ODR/2, 01 ODR/4, 10 ODR/10, 11 ODR/20', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_1, + shift: 6, + width: 2, + options: [ + [0, 'ODR/2'], + [1, 'ODR/4'], + [2, 'ODR/10'], + [3, 'ODR/20'], + ], + }, + { + key: 'FS', + label: 'Accel1 Range', + desc: 'Full-scale range', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_1, + shift: 4, + width: 2, + options: [ + [0, '+-2g'], + [1, '+-4g'], + [2, '+-8g'], + [3, '+-16g'], + ], + }, + { + key: 'FDS', + label: 'Accel1 FDS', + desc: 'Filtered data selection', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_1, + shift: 3, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'LOW_NOISE', + label: 'Accel1 Low Noise', + desc: 'Low-noise mode', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_1, + shift: 2, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'HP_REF_MODE', + label: 'Accel1 HP Ref Mode', + desc: 'High-pass reference mode', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_2, + shift: 1, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'FMode', + label: 'Accel1 FIFO Mode', + desc: 'LIS2DW12 FIFO mode', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_3, + shift: 5, + width: 3, + options: [ + [0, 'Bypass'], + [1, 'FIFO'], + [2, 'Reserved'], + [3, 'Continuous-to-FIFO'], + [4, 'Bypass-to-Continuous'], + [5, 'Reserved'], + [6, 'Continuous'], + [7, 'Reserved'], + ], + }, + { + key: 'FTH', + label: 'Accel1 FIFO Threshold', + desc: '5-bit threshold (0-31)', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_3, + shift: 0, + width: 5, + min: 0, + max: 31, + }, + // ACCEL2/GYRO + { + key: 'FTH_LSB', + label: 'LSM FIFO Threshold LSB', + desc: 'Lower 8 bits of LSM FIFO threshold', + kind: 'u8', + index: OP_IDX.GYRO_ACCEL2_CFG_0, + min: 0, + max: 255, + }, + { + key: 'TIMER_PEDO_FIFDO_EN', + label: 'Timer/Pedo FIFO Dataset', + desc: 'Include step/timestamp as 4th dataset', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_1, + shift: 7, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'TIMER_PEDO_FIFO_DRDY', + label: 'Timer/Pedo FIFO DRDY', + desc: '0 write by DRDY, 1 disable write at each step', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_1, + shift: 6, + width: 1, + options: [ + [0, 'DRDY'], + [1, 'Step detect'], + ], + }, + { + key: 'FTH_MSB', + label: 'LSM FIFO Threshold MSB', + desc: 'Upper 4 bits of LSM FIFO threshold', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_1, + shift: 0, + width: 4, + min: 0, + max: 15, + }, + { + key: 'DEC_FIFO_GYRO', + label: 'Gyro FIFO Decimation', + desc: 'Decimation factor for gyro', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_2, + shift: 3, + width: 3, + options: [ + [0, 'Not in FIFO'], + [1, 'No decimation'], + [2, 'x2'], + [3, 'x3'], + [4, 'x4'], + [5, 'x8'], + [6, 'x16'], + [7, 'x32'], + ], + }, + { + key: 'DEC_FIFO_XL', + label: 'Accel2 FIFO Decimation', + desc: 'Decimation factor for accel2', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_2, + shift: 0, + width: 3, + options: [ + [0, 'Not in FIFO'], + [1, 'No decimation'], + [2, 'x2'], + [3, 'x3'], + [4, 'x4'], + [5, 'x8'], + [6, 'x16'], + [7, 'x32'], + ], + }, + { + key: 'ODR_FIFO', + label: 'LSM FIFO ODR', + desc: 'FIFO sampling rate', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_3, + shift: 3, + width: 4, + options: [ + [0, 'Disabled'], + [1, '12.5 Hz'], + [2, '26 Hz'], + [3, '52 Hz'], + [4, '104 Hz'], + [5, '208 Hz'], + [6, '416 Hz'], + [7, '833 Hz'], + [8, '1.66 kHz'], + [9, '3.33 kHz'], + [10, '6.66 kHz'], + ], + }, + { + key: 'FIFO_MODE', + label: 'LSM FIFO Mode', + desc: 'FIFO behavior', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_3, + shift: 0, + width: 3, + options: [ + [0, 'Bypass'], + [1, 'FIFO'], + [2, 'Reserved'], + [3, 'Continuous-to-FIFO'], + [4, 'Bypass-to-Continuous'], + [5, 'Reserved'], + [6, 'Continuous'], + [7, 'Reserved'], + ], + }, + { + key: 'ODR_XL', + label: 'Accel2 ODR', + desc: 'Accel2 sampling rate', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_4, + shift: 4, + width: 4, + options: [ + [0, 'Power-down'], + [1, '12.5 Hz'], + [2, '26 Hz'], + [3, '52 Hz'], + [4, '104 Hz'], + [5, '208 Hz'], + [6, '416 Hz'], + [7, '833 Hz'], + [8, '1.66 kHz'], + [9, '3.33 kHz'], + [10, '6.66 kHz'], + ], + }, + { + key: 'FS_XL', + label: 'Accel2 Range', + desc: '00 +-2g, 01 +-16g, 10 +-4g, 11 +-8g', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_4, + shift: 2, + width: 2, + options: [ + [0, '+-2g'], + [1, '+-16g'], + [2, '+-4g'], + [3, '+-8g'], + ], + }, + { + key: 'BW_XL', + label: 'Accel2 BW', + desc: 'Anti-alias filter bandwidth', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_4, + shift: 0, + width: 2, + options: [ + [0, '400 Hz'], + [1, '200 Hz'], + [2, '100 Hz'], + [3, '50 Hz'], + ], + }, + { + key: 'ODR_G', + label: 'Gyro ODR', + desc: 'Gyro sampling rate', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_5, + shift: 4, + width: 4, + options: [ + [0, 'Power-down'], + [1, '12.5 Hz'], + [2, '26 Hz'], + [3, '52 Hz'], + [4, '104 Hz'], + [5, '208 Hz'], + [6, '416 Hz'], + [7, '833 Hz'], + [8, '1.66 kHz'], + ], + }, + { + key: 'FS_G', + label: 'Gyro Range', + desc: 'Gyro full-scale', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_5, + shift: 2, + width: 2, + options: [ + [0, '250 dps'], + [1, '500 dps'], + [2, '1000 dps'], + [3, '2000 dps'], + ], + }, + { + key: 'FS_125', + label: 'Gyro 125 dps', + desc: 'Enable 125 dps full-scale', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_5, + shift: 1, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'G_HM_MODE', + label: 'Gyro High-Performance Mode', + desc: '0 HP enabled, 1 HP disabled', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_6, + shift: 7, + width: 1, + options: [ + [0, 'Enabled'], + [1, 'Disabled'], + ], + }, + { + key: 'HP_G_EN', + label: 'Gyro HPF', + desc: 'Gyro high-pass filter', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_6, + shift: 6, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'HPCF_G', + label: 'Gyro HPF Cutoff', + desc: 'Gyro HPF cutoff frequency', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_6, + shift: 4, + width: 2, + options: [ + [0, '0.0081 Hz'], + [1, '0.0324 Hz'], + [2, '2.07 Hz'], + [3, '16.32 Hz'], + ], + }, + { + key: 'HP_G_RST', + label: 'Gyro HPF Reset', + desc: 'Reset digital HPF', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_6, + shift: 3, + width: 1, + options: [ + [0, 'Off'], + [1, 'On'], + ], + }, + { + key: 'ROUNDING_STATUS', + label: 'Rounding Status', + desc: 'Source register rounding', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_6, + shift: 2, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'LPF2_XL_EN', + label: 'Accel2 LPF2', + desc: 'LPF2 selection', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_7, + shift: 7, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'HPCF_XL', + label: 'Accel2 HP/Slope Cutoff', + desc: 'HPCF_XL bits', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_7, + shift: 5, + width: 2, + min: 0, + max: 3, + }, + { + key: 'HP_SLOPE_XL_EN', + label: 'Accel2 HP/Slope Enable', + desc: 'HP/slope filter selection', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_7, + shift: 2, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'LOW_PASS_ON_6D', + label: 'Low-pass on 6D', + desc: 'Low-pass filter on 6D function', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_7, + shift: 0, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + // LSM6DSV explicit host fields (bytes 18..20) + { + key: 'LSM6DSV_ODR_XL', + label: 'LSM6DSV Accel ODR', + desc: 'Accel ODR (LSM6DSV ODR_XL datasheet register value)', + kind: 'bit', + index: OP_IDX.LSM6DSV_CFG_0, + shift: 0, + width: 4, + options: [ + [0, 'Off'], + [1, '1.875 Hz'], + [2, '7.5 Hz'], + [3, '15 Hz'], + [4, '30 Hz'], + [5, '60 Hz'], + [6, '120 Hz'], + [7, '240 Hz'], + [8, '480 Hz'], + [9, '960 Hz'], + [10, '1920 Hz'], + [11, '3840 Hz'], + [12, '7680 Hz'], + ], + }, + { + key: 'LSM6DSV_FS_XL', + label: 'LSM6DSV Accel Range', + desc: 'Second-gen accel range code', + kind: 'bit', + index: OP_IDX.LSM6DSV_CFG_0, + shift: 4, + width: 2, + options: [ + [0, '+-2g'], + [1, '+-4g'], + [2, '+-8g'], + [3, '+-16g'], + ], + }, + { + key: 'LSM6DSV_ODR_G', + label: 'LSM6DSV Gyro ODR', + desc: 'Gyro ODR (LSM6DSV ODR_G datasheet register value)', + kind: 'bit', + index: OP_IDX.LSM6DSV_CFG_1, + shift: 0, + width: 4, + options: [ + [0, 'Off'], + [1, '1.875 Hz'], + [2, '7.5 Hz'], + [3, '15 Hz'], + [4, '30 Hz'], + [5, '60 Hz'], + [6, '120 Hz'], + [7, '240 Hz'], + [8, '480 Hz'], + [9, '960 Hz'], + [10, '1920 Hz'], + [11, '3840 Hz'], + [12, '7680 Hz'], + ], + }, + { + key: 'LSM6DSV_FS_G', + label: 'LSM6DSV Gyro Range', + desc: 'Gyro range (LSM6DSV FS_G datasheet register value)', + kind: 'bit', + index: OP_IDX.LSM6DSV_CFG_1, + shift: 4, + width: 4, + options: [ + [0, '125 dps'], + [1, '250 dps'], + [2, '500 dps'], + [3, '1000 dps'], + [4, '2000 dps'], + ], + }, + { + key: 'LIS2MDL_ODR', + label: 'Mag Output Rate', + desc: 'Magnetometer output (sensor-hub) rate. Firmware derives the LIS2MDL ODR to keep a fresh sample available. Bounded by the accel/gyro ODR (the sensor-hub trigger).', + kind: 'bit', + index: OP_IDX.LSM6DSV_CFG_2, + shift: 0, + width: 2, + options: [ + [0, '15 Hz (LIS2MDL 20 Hz)'], + [1, '30 Hz (LIS2MDL 50 Hz)'], + [2, '60 Hz (LIS2MDL 100 Hz)'], + [3, '120 Hz (LIS2MDL 100 Hz)'], + ], + }, + // Timing and BLE scheduler + { + key: 'START_TIME', + label: 'Start Time', + desc: '32-bit start time', + kind: 'u32', + index: OP_IDX.START_TIME, + min: 0, + max: 4294967295, + }, + { + key: 'END_TIME', + label: 'End Time', + desc: '32-bit end time', + kind: 'u32', + index: OP_IDX.END_TIME, + min: 0, + max: 4294967295, + }, + { + key: 'INACTIVE_TIMEOUT_MINUTES', + label: 'Inactive Timeout (minutes)', + desc: 'Minutes of no activity before the device stops recording and sleeps. 0 disables inactivity detection.', + kind: 'inactiveMinutes', + index: OP_IDX.INACTIVE_TIMEOUT, + min: 0, + max: 63, + }, + { + key: 'RESUME_REC_ON_ACTIVITY', + label: 'Resume Rec On Activity', + desc: 'Automatically resume recording when activity is detected after an inactivity sleep. Only has an effect when Logging is enabled and the inactive timeout is above 0.', + kind: 'inactiveResume', + index: OP_IDX.INACTIVE_TIMEOUT, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'BLE_CONNECTION_TRIES_PER_DAY', + label: 'Connection Attempts per Wake', + desc: 'Number of connection attempts the device makes each time a sync window opens (applies to all schedules).', + kind: 'u8', + index: OP_IDX.BLE_RETRY_COUNT, + min: 0, + max: 255, + }, + { + key: 'BLE_TX_POWER', + label: 'BLE TX Power', + desc: 'Radio TX power', + kind: 'u8', + index: OP_IDX.BLE_TX_POWER, + options: [ + [0x08, '+8 dBm'], + [0x07, '+7 dBm'], + [0x06, '+6 dBm'], + [0x05, '+5 dBm'], + [0x04, '+4 dBm'], + [0x03, '+3 dBm'], + [0x02, '+2 dBm'], + [0x00, '+0 dBm'], + [0xfc, '-4 dBm'], + [0xf8, '-8 dBm'], + [0xf4, '-12 dBm'], + [0xf0, '-16 dBm'], + [0xec, '-20 dBm'], + [0xd8, '-40 dBm'], + ], + }, + { + key: 'BLE_DATA_TRANS_WKUP_INT_HOURS', + label: 'Data Transfer Wake Interval (hrs)', + desc: 'How often the data-transfer sync runs: 0 = off, 24 = once daily at the sync time, 1–23 = every N hours.', + kind: 'u8', + index: OP_IDX.BLE_DATA_TRANS_WKUP_INT_HRS, + min: 0, + max: 24, + }, + { + key: 'BLE_DATA_TRANS_WKUP_TIME', + label: 'Data Transfer Sync Time', + desc: 'Time of day for the data-transfer sync (minutes since midnight, 0–1439).', + kind: 'u16', + index: OP_IDX.BLE_DATA_TRANS_WKUP_TIME, + min: 0, + max: 1439, + }, + { + key: 'BLE_DATA_TRANS_WKUP_DUR', + label: 'Data Transfer Active Duration (minutes)', + desc: 'Minutes Bluetooth stays active during the data-transfer sync window.', + kind: 'u8', + index: OP_IDX.BLE_DATA_TRANS_WKUP_DUR, + min: 0, + max: 255, + }, + { + key: 'BLE_DATA_TRANS_RETRY_INT', + label: 'Data Transfer Retry Interval (minutes)', + desc: 'Minutes between connection attempts within the data-transfer sync window.', + kind: 'u16', + index: OP_IDX.BLE_DATA_TRANS_RETRY_INT, + min: 0, + max: 1439, + }, + { + key: 'BLE_STATUS_WKUP_INT_HOURS', + label: 'Status Wake Interval (hrs)', + desc: 'How often the status sync runs: 0 = off, 24 = once daily at the sync time, 1–23 = every N hours.', + kind: 'u8', + index: OP_IDX.BLE_STATUS_WKUP_INT_HRS, + min: 0, + max: 24, + }, + { + key: 'BLE_STATUS_WKUP_TIME', + label: 'Status Sync Time', + desc: 'Time of day for the status sync (minutes since midnight, 0–1439).', + kind: 'u16', + index: OP_IDX.BLE_STATUS_WKUP_TIME, + min: 0, + max: 1439, + }, + { + key: 'BLE_STATUS_WKUP_DUR', + label: 'Status Active Duration (minutes)', + desc: 'Minutes Bluetooth stays active during the status sync window.', + kind: 'u8', + index: OP_IDX.BLE_STATUS_WKUP_DUR, + min: 0, + max: 255, + }, + { + key: 'BLE_STATUS_RETRY_INT', + label: 'Status Retry Interval (minutes)', + desc: 'Minutes between connection attempts within the status sync window.', + kind: 'u16', + index: OP_IDX.BLE_STATUS_RETRY_INT, + min: 0, + max: 1439, + }, + { + key: 'BLE_RTC_SYNC_WKUP_INT_HOURS', + label: 'Time Sync Wake Interval (hrs)', + desc: 'How often the time (RTC) sync runs: 0 = off, 24 = once daily at the sync time, 1–23 = every N hours.', + kind: 'u8', + index: OP_IDX.BLE_RTC_SYNC_WKUP_INT_HRS, + min: 0, + max: 24, + }, + { + key: 'BLE_RTC_SYNC_WKUP_TIME', + label: 'Time Sync Time', + desc: 'Time of day for the time (RTC) sync (minutes since midnight, 0–1439).', + kind: 'u16', + index: OP_IDX.BLE_RTC_SYNC_WKUP_TIME, + min: 0, + max: 1439, + }, + { + key: 'BLE_RTC_SYNC_WKUP_DUR', + label: 'Time Sync Active Duration (minutes)', + desc: 'Minutes Bluetooth stays active during the time (RTC) sync window.', + kind: 'u8', + index: OP_IDX.BLE_RTC_SYNC_WKUP_DUR, + min: 0, + max: 255, + }, + { + key: 'BLE_RTC_SYNC_RETRY_INT', + label: 'Time Sync Retry Interval (minutes)', + desc: 'Minutes between connection attempts within the time (RTC) sync window.', + kind: 'u16', + index: OP_IDX.BLE_RTC_SYNC_RETRY_INT, + min: 0, + max: 1439, + }, + // ADC/PPG + { + key: 'ADC_SAMPLE_RATE', + label: 'ADC Sample Rate', + desc: 'ADC sample rate code', + kind: 'bit', + index: OP_IDX.ADC_CHANNEL_SETTINGS_0, + shift: 0, + width: 6, + options: [ + [0, 'Off'], + [1, '32768.0 Hz'], + [2, '16384.0 Hz'], + [3, '8192.0 Hz'], + [4, '6553.6 Hz'], + [5, '4096.0 Hz'], + [6, '3276.8 Hz'], + [7, '2048.0 Hz'], + [8, '1638.4 Hz'], + [9, '1310.72 Hz'], + [10, '1024.0 Hz'], + [11, '819.2 Hz'], + [12, '655.36 Hz'], + [13, '512.0 Hz'], + [14, '409.6 Hz'], + [15, '327.68 Hz'], + [16, '256.0 Hz'], + [17, '204.8 Hz'], + [18, '163.84 Hz'], + [19, '128.0 Hz'], + [20, '102.4 Hz'], + [21, '81.92 Hz'], + [22, '64.0 Hz'], + [23, '51.2 Hz'], + [24, '40.96 Hz'], + [25, '32.0 Hz'], + [26, '25.6 Hz'], + [27, '20.48 Hz'], + [28, '16.0 Hz'], + [29, '12.8 Hz'], + [30, '10.24 Hz'], + [31, '8.0 Hz'], + [32, '6.4 Hz'], + [33, '5.12 Hz'], + [34, '4.0 Hz'], + [35, '3.2 Hz'], + [36, '2.56 Hz'], + [37, '2.0 Hz'], + [38, '1.6 Hz'], + [39, '1.28 Hz'], + [40, '1.0 Hz'], + [41, '0.8 Hz'], + [42, '0.64 Hz'], + ], + }, + { + key: 'ADC_OVERSAMPLE_RATE', + label: 'ADC Oversample', + desc: 'ADC oversampling', + kind: 'bit', + index: OP_IDX.ADC_CHANNEL_SETTINGS_1, + shift: 4, + width: 4, + options: [ + [0, 'Disabled'], + [1, '2x'], + [2, '4x'], + [3, '8x'], + [4, '16x'], + [5, '32x'], + [6, '64x'], + [7, '128x'], + [8, '256x'], + ], + }, + { + key: 'GSR_RANGE_SETTING', + label: 'GSR Range', + desc: 'Selectable GSR range setting', + kind: 'bit', + index: OP_IDX.ADC_CHANNEL_SETTINGS_1, + shift: 0, + width: 3, + options: [ + [0, 'Range 0 (8k-63k or 125uS-15.87uS)'], + [1, 'Range 1 (63k-220k or 15.87uS-4.5uS)'], + [2, 'Range 2 (220k-680k or 4.5uS-1.47uS)'], + [3, 'Range 3 (680k-4.7M or 1.47uS-0.21uS)'], + [4, 'Auto-Range'], + ], + }, + { + key: 'ADAPTIVE_SCHEDULER_FAILCOUNT_MAX', + label: 'Fallback Trigger (missed syncs)', + desc: 'Consecutive missed sync windows before the adaptive fallback turns on and starts retrying more often. Typical 2–3. 0 disables the fallback.', + kind: 'u8', + // Max is the full u8 range: the firmware disabled sentinel is 0xFF, and the + // encoder clamps to max — a tighter cap would corrupt a disabled config. + index: OP_IDX.ADAPTIVE_SCHEDULER_FAILCOUNT_MAX, + min: 0, + max: 255, + }, + { + key: 'ADAPTIVE_SCHEDULER_INTERVAL', + label: 'Fallback Retry Interval (minutes)', + desc: 'Once the fallback is on, minutes between extra BLE retry wakes. Typical ≈426 (about 7 hours). 0 (or 65535) disables the fallback.', + kind: 'u16', + // Max is the full u16 range: the firmware disabled sentinel is 0xFFFF, and + // the encoder clamps to max — a tighter cap would corrupt a disabled config. + index: OP_IDX.ADAPTIVE_SCHEDULER_INT, + min: 0, + max: 65535, + }, + { + key: 'PPG_REC_DUR_SECS', + label: 'PPG Record Duration (s)', + desc: '0 = always on', + kind: 'u16', + index: OP_IDX.PPG_REC_DUR_SECS_LSB, + min: 0, + max: 65535, + }, + { + key: 'PPG_REC_INT_MINS', + label: 'PPG Record Interval (minutes)', + desc: '0 = always on', + kind: 'u16', + index: OP_IDX.PPG_REC_INT_MINS_LSB, + min: 0, + max: 65535, + }, + { + key: 'SMP_AVE', + label: 'PPG Sample Averaging', + desc: 'FIFO sample averaging', + kind: 'bit', + index: OP_IDX.PPG_FIFO_CONFIG, + shift: 5, + width: 3, + options: [ + [0, '1'], + [1, '2'], + [2, '4'], + [3, '8'], + [4, '16'], + [5, '32'], + [6, '32'], + [7, '32'], + ], + }, + { + key: 'PPG_ADC_RGE', + label: 'PPG ADC Range', + desc: 'ADC range / full-scale', + kind: 'bit', + index: OP_IDX.PPG_MODE_CONFIG2, + shift: 5, + width: 2, + options: [ + [0, '7.8125 / 4096'], + [1, '15.625 / 8192'], + [2, '31.25 / 16384'], + [3, '62.5 / 32768'], + ], + }, + { + key: 'PPG_SR', + label: 'PPG Sample Rate', + desc: 'PPG sample rate', + kind: 'bit', + index: OP_IDX.PPG_MODE_CONFIG2, + shift: 2, + width: 3, + options: [ + [0, '50 Hz'], + [1, '100 Hz'], + [2, '200 Hz'], + [3, '400 Hz'], + [4, '800 Hz'], + [5, '1000 Hz'], + [6, '1600 Hz'], + [7, '3200 Hz'], + ], + }, + { + key: 'PPG_LED_PW', + label: 'PPG LED Pulse Width', + desc: '50/100/200/400 us', + kind: 'bit', + index: OP_IDX.PPG_MODE_CONFIG2, + shift: 0, + width: 2, + options: [ + [0, '50 us'], + [1, '100 us'], + [2, '200 us'], + [3, '400 us'], + ], + }, + { + key: 'PPG_MA_DEFAULT', + label: 'PPG MA Default', + desc: 'Default LED current (mA)', + kind: 'u8', + index: OP_IDX.PPG_MA_DEFAULT, + min: 0, + max: 255, + }, + { + key: 'PPG_MA_MAX_RED_IR', + label: 'PPG MA Max Red/IR', + desc: 'Max current for Red/IR (mA)', + kind: 'u8', + index: OP_IDX.PPG_MA_MAX_RED_IR, + min: 0, + max: 255, + }, + { + key: 'PPG_MA_MAX_GREEN_BLUE', + label: 'PPG MA Max Green/Blue', + desc: 'Max current for Green/Blue (mA)', + kind: 'u8', + index: OP_IDX.PPG_MA_MAX_GREEN_BLUE, + min: 0, + max: 255, + }, + { + key: 'PPG_AGC_TARGET_PERCENT_OF_RANGE', + label: 'PPG AGC Target %', + desc: 'AGC target percent of range', + kind: 'u8', + index: OP_IDX.PPG_AGC_TARGET_PERCENT_OF_RANGE, + min: 0, + max: 100, + }, + { + key: 'PPG_UNUSED_BYTE', + label: 'PPG Unused Byte', + desc: 'Reserved', + kind: 'u8', + index: 65, + min: 0, + max: 255, + }, + { + key: 'PPG_MA_LED_PILOT', + label: 'PPG MA LED Pilot', + desc: 'Pilot/proximity LED current', + kind: 'u8', + index: OP_IDX.PPG_MA_LED_PILOT, + min: 0, + max: 255, + }, + { + key: 'XTALK_DAC1', + label: 'PPG DAC1 Crosstalk', + desc: '5-bit value', + kind: 'u8', + index: OP_IDX.PPG_DAC1_CROSSTALK, + min: 0, + max: 31, + }, + { + key: 'XTALK_DAC2', + label: 'PPG DAC2 Crosstalk', + desc: '5-bit value', + kind: 'u8', + index: OP_IDX.PPG_DAC2_CROSSTALK, + min: 0, + max: 31, + }, + { + key: 'XTALK_DAC3', + label: 'PPG DAC3 Crosstalk', + desc: '5-bit value', + kind: 'u8', + index: OP_IDX.PPG_DAC3_CROSSTALK, + min: 0, + max: 31, + }, + { + key: 'XTALK_DAC4', + label: 'PPG DAC4 Crosstalk', + desc: '5-bit value', + kind: 'u8', + index: OP_IDX.PPG_DAC4_CROSSTALK, + min: 0, + max: 31, + }, + { + key: 'PROX_AGC_MODE', + label: 'Proximity/AGC Mode', + desc: '0 Disabled, 1 Driver approach, 2 Hybrid', + kind: 'u8', + index: OP_IDX.PROX_AGC_MODE, + options: [ + [0, 'AGC Off / Prox Off'], + [1, 'AGC On / Driver Prox'], + [2, 'AGC On / Hybrid Prox'], + ], + }, + // ------------------------------------------------------------------------- + // v9 second-generation sensor settings (light / skin-temp / algo-hub / LED) + // ------------------------------------------------------------------------- + // OP_CONFIG_VERSION (byte 9) is an internal layout marker, not a user setting. + // It is auto-stamped on serialize (see VERISENSE_OP_CONFIG_VERSION_V9 / + // createBlankVerisenseOperationalConfig), so it is intentionally NOT an + // editable field here. + // AMBIENT_LIGHT_EN / SKIN_TEMP_EN / ALGO_HUB_EN are sensor enables and are + // rendered as checkboxes (see VERISENSE_SENSOR_ENABLE_FIELDS), not here. + // GEN_CFG_3 bit 6 is reserved (was PPG_VIA_HUB): the MAX86176 is hardwired to + // the hub, so raw PPG always arrives under the PPG sensor id (4) when a PPG + // channel is enabled, and the algorithm output under id 8 when ALGO_HUB_EN is + // set - no routing bit is needed. + { + key: 'LIGHT_GAIN_INDEX', + label: 'Light Gain', + // Default index 0 = 1.0x, matching the VD6283 reference example + // (SetGain(..., 256), i.e. the 8.8 value 0x0100). + desc: 'VD6283 channel gain (default 1.0x)', + kind: 'u8', + index: OP_IDX.LIGHT_GAIN_INDEX, + min: 0, + max: 7, + options: [ + [0, '1.0x'], + [1, '1.67x'], + [2, '2.5x'], + [3, '5.0x'], + [4, '10.0x'], + [5, '25.0x'], + [6, '50.0x'], + [7, '66.67x'], + ], + }, + { + key: 'LIGHT_EXPOSURE_INDEX', + label: 'Light Exposure', + // Default index 0 = 100 ms (100000 us), matching the VD6283 reference + // example (SetExposureTime(..., 100000)). + desc: 'VD6283 exposure / integration time (default 100 ms). The chip cannot sample faster than it integrates, so the exposure caps the achievable sample rate at ~1/exposure (shown per option). Picking a higher sample rate therefore requires a shorter exposure.', + kind: 'u8', + index: OP_IDX.LIGHT_EXPOSURE_INDEX, + min: 0, + max: 7, + // Label suffix = max sample rate this exposure allows (≈ 1/exposure, capped + // at the 20 Hz poll ceiling). + options: [ + [0, '100 ms (max 10 Hz)'], + [1, '1.6 ms (max 20 Hz)'], + [2, '6.4 ms (max 20 Hz)'], + [3, '12.8 ms (max 20 Hz)'], + [4, '25.6 ms (max 20 Hz)'], + [5, '51.2 ms (max ~19 Hz)'], + [6, '102.4 ms (max ~9.8 Hz)'], + [7, '204.8 ms (max ~4.9 Hz)'], + ], + }, + // LIGHT_CONFIG bit 0 (continuous mode) is intentionally NOT exposed: the + // VD6283 must run in continuous mode for the timer-driven poll to read it, so + // the firmware hardcodes it. The op-config bit is left unused (free to + // repurpose). + { + key: 'LIGHT_DARK_ENABLE', + label: 'Light Dark Channel', + desc: 'Replace the visible/clear channel reading with the dark (covered-photodiode) baseline', + kind: 'bit', + index: OP_IDX.LIGHT_CONFIG, + shift: 1, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'LIGHT_FLICKER_EN', + label: 'Light Flicker Detect', + desc: 'RESERVED: VD6283 flicker detection (host PDM path pending nRF SDK v17 — not yet active)', + kind: 'bit', + index: OP_IDX.LIGHT_CONFIG, + shift: 2, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled (reserved)'], + ], + }, + { + key: 'LIGHT_SAMPLE_RATE_INDEX', + label: 'Light Sample Rate', + desc: 'Ambient-light sample rate. The firmware sets the VD6283 inter-measurement (continuous-mode) cadence to this period, so the sensor measures only as often as it is read and idles in between for lower power. The rate is limited by the exposure time (the chip cannot measure faster than it integrates): 20 Hz needs exposure ≤ 50 ms, 10 Hz needs ≤ 100 ms, etc. — see the Light Exposure options.', + kind: 'u8', + index: OP_IDX.LIGHT_SAMPLE_RATE_INDEX, + min: 0, + max: 6, + options: [ + [0, 'Off'], + [1, '0.5 Hz'], + [2, '1 Hz'], + [3, '2 Hz'], + [4, '5 Hz'], + [5, '10 Hz'], + [6, '20 Hz'], + ], + }, + { + key: 'SKIN_TEMP_MEAS_TYPE', + label: 'Skin Temp Mode', + desc: 'MLX90632 measurement type (default Medical for skin/body temperature)', + kind: 'bit', + index: OP_IDX.SKIN_TEMP_CONFIG, + shift: 0, + width: 1, + options: [ + [0, 'Medical (25–42.5 °C, ±0.2 °C)'], + [1, 'Extended (wider range, lower accuracy)'], + ], + }, + { + // Single skin-temp rate setting. Stored as the MLX90632 refresh-rate code + // (byte 76 bits 3:1); the firmware sets the chip refresh AND derives the read + // poll from it. Shown as the *medical* output rate (= refresh ÷ 2; extended + // mode is ÷ 3). The legacy poll field (byte 77) and power-mode bits (byte 76 + // bits 5:4) are now unused (free to repurpose) — continuous mode is required + // and set automatically. + key: 'SKIN_TEMP_SAMPLE_RATE', + label: 'Skin Temp Sample Rate', + desc: 'MLX90632 sample rate (medical output = chip refresh ÷2; extended ÷3). Drives both the chip refresh and the read poll.', + kind: 'bit', + index: OP_IDX.SKIN_TEMP_CONFIG, + shift: 1, + width: 3, + options: [ + [0, '0.25 Hz'], + [1, '0.5 Hz'], + [2, '1 Hz'], + [3, '2 Hz'], + [4, '4 Hz'], + [5, '8 Hz'], + [6, '16 Hz'], + [7, '32 Hz'], + ], + }, + { + key: 'ALGO_OP_MODE', + label: 'Algo Operation Mode', + desc: 'MAX32674 sensor-hub operation mode', + kind: 'u8', + index: OP_IDX.ALGO_OP_MODE, + min: 0, + max: 5, + options: [ + [0, 'Raw'], + [1, 'WHRM (HR)'], + [3, 'IRN'], + [4, 'HRV'], + [5, 'RR'], + ], + }, + { + key: 'ALGO_REPORT_MODE', + label: 'Algo Report Mode', + desc: 'Sensor-hub report mode', + kind: 'bit', + index: OP_IDX.ALGO_REPORT_MODE_RATE, + shift: 0, + width: 2, + options: [ + [1, 'Basic'], + [2, 'Extended'], + ], + }, + { + key: 'ALGO_REPORT_PERIOD', + label: 'Algo Report Period', + desc: 'Sensor-hub report period code', + kind: 'bit', + index: OP_IDX.ALGO_REPORT_MODE_RATE, + shift: 2, + width: 6, + }, + { + key: 'ALGO_AEC_ENABLE', + label: 'Algo Auto Exposure Control (AEC)', + desc: 'Enable the WHRM/SpO2 automatic exposure control (AEC) loop for the optical PPG AFE. Not related to ECG.', + kind: 'bit', + index: OP_IDX.ALGO_CONTROL, + shift: 0, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'ALGO_SCD_ENABLE', + label: 'Algo Skin Contact Detect', + desc: 'Enable skin-contact detection', + kind: 'bit', + index: OP_IDX.ALGO_CONTROL, + shift: 1, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'ALGO_AUTO_PD_ENABLE', + label: 'Algo Auto PD Current', + desc: 'Enable automatic photodiode current control', + kind: 'bit', + index: OP_IDX.ALGO_CONTROL, + shift: 2, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'ALGO_INITIAL_HR', + label: 'Algo Initial HR', + desc: 'Optional WHRM initial heart-rate seed (bpm, 0 = none)', + kind: 'u8', + index: OP_IDX.ALGO_INITIAL_HR, + min: 0, + max: 255, + }, + { + key: 'LED_AUTO_BRIGHTNESS_ENABLE', + label: 'LED Auto-Brightness', + desc: 'Drive RGB LED brightness from ambient light', + kind: 'bit', + index: OP_IDX.LED_AUTO_BRIGHTNESS_CFG, + shift: 0, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'LED_MAX_BRIGHTNESS', + label: 'LED Max Brightness', + desc: 'Ceiling for auto-brightness mode (0-255)', + kind: 'u8', + index: OP_IDX.LED_MAX_BRIGHTNESS, + min: 0, + max: 255, + }, + { + key: 'LED_LUX_THRESHOLD', + label: 'LED Lux Threshold', + desc: 'Below this ambient level the LED stays at max brightness', + kind: 'u16', + index: OP_IDX.LED_LUX_THRESHOLD, + min: 0, + max: 65535, + }, + { + key: 'PERSON_HEIGHT_CM', + label: 'Height', + desc: 'Subject height for the MAX32674 algorithm suite (cm)', + kind: 'u16', + index: OP_IDX.PERSON_HEIGHT_CM, + min: 50, + max: 250, + }, + { + key: 'PERSON_WEIGHT_KG', + label: 'Weight', + desc: 'Subject weight for the MAX32674 algorithm suite (kg)', + kind: 'u16', + index: OP_IDX.PERSON_WEIGHT_KG, + min: 10, + max: 300, + }, + { + key: 'PERSON_AGE', + label: 'Age', + desc: 'Subject age for the MAX32674 algorithm suite (years)', + kind: 'u8', + index: OP_IDX.PERSON_AGE, + min: 0, + max: 120, + }, + { + key: 'PERSON_GENDER', + label: 'Gender', + desc: 'Subject gender for the MAX32674 algorithm suite', + kind: 'u8', + index: OP_IDX.PERSON_GENDER, + min: 0, + max: 1, + options: [ + [0, 'Male'], + [1, 'Female'], + ], + }, +]; +const VERISENSE_OP_CONFIG_BYTE_SIZE = 92; +function createBlankVerisenseOperationalConfig(byteSize = VERISENSE_OP_CONFIG_BYTE_SIZE) { + const blank = new Uint8Array(byteSize); + blank[0] = 0x5a; + // Stamp the layout version so v9-sized configs are recognised as second-gen. + if (byteSize >= VERISENSE_OP_CONFIG_BYTE_SIZE) { + blank[OP_IDX.OP_CONFIG_VERSION] = OP_CONFIG_VERSION_V9; + // Seed the MAX32674 subject parameters with the Maxim algorithm defaults + // (height 175 cm, weight 78 kg, age 30 yr, gender Male) so the UI shows + // sane values rather than blanks. u16 fields are little-endian. + blank[OP_IDX.PERSON_HEIGHT_CM] = 175 & 0xff; + blank[OP_IDX.PERSON_HEIGHT_CM + 1] = (175 >> 8) & 0xff; + blank[OP_IDX.PERSON_WEIGHT_KG] = 78 & 0xff; + blank[OP_IDX.PERSON_WEIGHT_KG + 1] = (78 >> 8) & 0xff; + blank[OP_IDX.PERSON_AGE] = 30; + blank[OP_IDX.PERSON_GENDER] = 0; + } + return blank; +} +function clampInt(v, min, max) { + const n = Math.trunc(Number(v)); + if (!Number.isFinite(n)) + return min; + return Math.max(min, Math.min(max, n)); +} +function readVerisenseOperationalFieldValue(op, field) { + if (field.kind === 'bit') { + const width = field.width ?? 1; + const shift = field.shift ?? 0; + const mask = (1 << width) - 1; + return (op[field.index] >> shift) & mask; + } + if (field.kind === 'u8') + return op[field.index] & 0xff; + if (field.kind === 'u16') { + return (op[field.index] & 0xff) | ((op[field.index + 1] & 0xff) << 8); + } + if (field.kind === 'u32') { + return (((op[field.index] & 0xff) | + ((op[field.index + 1] & 0xff) << 8) | + ((op[field.index + 2] & 0xff) << 16) | + ((op[field.index + 3] & 0xff) << 24)) >>> + 0); + } + if (field.kind === 'inactiveResume') { + return op[field.index] & (0x01 << 6) ? 1 : 0; + } + if (field.kind === 'inactiveMinutes') { + return op[field.index] & 0x3f; + } + return 0; +} +function writeVerisenseOperationalFieldValue(op, field, rawValue) { + if (field.kind === 'bit') { + const width = field.width ?? 1; + const shift = field.shift ?? 0; + const mask = (1 << width) - 1; + const value = clampInt(rawValue, 0, mask); + op[field.index] = (op[field.index] & ~(mask << shift)) | ((value & mask) << shift); + return; + } + if (field.kind === 'u8') { + op[field.index] = clampInt(rawValue, field.min ?? 0, field.max ?? 255) & 0xff; + return; + } + if (field.kind === 'u16') { + const value = clampInt(rawValue, field.min ?? 0, field.max ?? 65535); + op[field.index] = value & 0xff; + op[field.index + 1] = (value >> 8) & 0xff; + return; + } + if (field.kind === 'u32') { + const value = clampInt(rawValue, field.min ?? 0, field.max ?? 4294967295) >>> 0; + op[field.index] = value & 0xff; + op[field.index + 1] = (value >> 8) & 0xff; + op[field.index + 2] = (value >> 16) & 0xff; + op[field.index + 3] = (value >> 24) & 0xff; + return; + } + if (field.kind === 'inactiveResume') { + const enabled = clampInt(rawValue, 0, 1) === 1; + op[field.index] = enabled ? op[field.index] | (0x01 << 6) : op[field.index] & -65; + return; + } + if (field.kind === 'inactiveMinutes') { + const minutes = clampInt(rawValue, field.min ?? 0, field.max ?? 63) & 0x3f; + op[field.index] = (op[field.index] & 0xc0) | minutes; + } +} +function setVerisenseOperationalBitRange(op, index, shift, width, rawValue) { + const mask = (1 << width) - 1; + const value = clampInt(rawValue, 0, mask); + op[index] = (op[index] & ~(mask << shift)) | ((value & mask) << shift); +} +/** GEN_CFG_0 bit masks for the two host comms channels (see byte map / firmware + * ASM_definitions.h). */ +const GEN_CFG_0_BLUETOOTH_EN_MASK = 1 << 4; +const GEN_CFG_0_USB_EN_MASK = 1 << 3; +/** + * Enforce the USB/Bluetooth comms-channel interlock on an operational-config + * buffer. + * + * A Verisense must never be configured with BOTH Bluetooth and USB disabled, or + * it becomes unreachable for reconfiguration (the radio is the only wireless way + * back in, and disabling USB removes the wired fallback). If a config has both + * `BLUETOOTH_EN` and `USB_EN` cleared, this forces BOTH back on. + * + * This mirrors the firmware safeguard (`enforceCommsChannelInterlock` in + * `ASM_Production/main.c`, applied on config write and parse). Enforcing it here + * in the SDK means any consuming application is protected — a device can't be + * stranded by a third-party tool writing 0/0. + * + * Mutates `op` in place. Returns `true` if a correction was applied. + */ +function enforceVerisenseCommsChannelInterlock(op) { + if (!op || op.length <= OP_IDX.GEN_CFG_0) + return false; + const genCfg0 = op[OP_IDX.GEN_CFG_0]; + const bothDisabled = (genCfg0 & GEN_CFG_0_BLUETOOTH_EN_MASK) === 0 && (genCfg0 & GEN_CFG_0_USB_EN_MASK) === 0; + if (!bothDisabled) + return false; + op[OP_IDX.GEN_CFG_0] = genCfg0 | GEN_CFG_0_BLUETOOTH_EN_MASK | GEN_CFG_0_USB_EN_MASK; + return true; +} +const VERISENSE_SENSOR_ENABLE_FIELDS = [ + { key: 'ACCEL_1_EN', index: OP_IDX.GEN_CFG_0, shift: 7 }, + { key: 'ACCEL_2_EN', index: OP_IDX.GEN_CFG_0, shift: 6 }, + { key: 'GYRO_EN', index: OP_IDX.GEN_CFG_0, shift: 5 }, + { key: 'MAG_EN', index: OP_IDX.GEN_CFG_3, shift: 2 }, + { key: 'GSR_EN', index: OP_IDX.GEN_CFG_1, shift: 7 }, + { key: 'PPG_GREEN_EN', index: OP_IDX.GEN_CFG_1, shift: 6 }, + { key: 'PPG_RED_EN', index: OP_IDX.GEN_CFG_1, shift: 5 }, + { key: 'PPG_IR_EN', index: OP_IDX.GEN_CFG_1, shift: 4 }, + { key: 'ECG_EN', index: OP_IDX.GEN_CFG_1, shift: 3 }, + { key: 'PPG_BLUE_EN', index: OP_IDX.GEN_CFG_1, shift: 2 }, + { key: 'VPROG_EN', index: OP_IDX.GEN_CFG_2, shift: 2 }, + { key: 'VBATT_EN', index: OP_IDX.GEN_CFG_2, shift: 1 }, + // v9 second-generation sensors. On 2nd-gen the raw PPG (id 4) is gated by the + // existing PPG channel enables above; ALGO_HUB_EN gates the algorithm (id 8). + { key: 'AMBIENT_LIGHT_EN', index: OP_IDX.GEN_CFG_3, shift: 3 }, + { key: 'SKIN_TEMP_EN', index: OP_IDX.GEN_CFG_3, shift: 4 }, + { key: 'ALGO_HUB_EN', index: OP_IDX.GEN_CFG_3, shift: 5 }, +]; +const VERISENSE_OPERATIONAL_FIELD_GROUPS = [ + { + id: 'gen', + title: 'General / Sensors', + openByDefault: false, + keys: [ + 'BLUETOOTH_EN', + 'USB_EN', + 'DEVICE_EN', + 'RECORDING_EN', + 'DATA_COMPRESSION_MODE', + 'HR_PPG_CHANNEL', + 'STEP_COUNT_EN', + 'LOW_BATT_AUTO_STOP_DISABLED', + 'BATT_TYPE', + 'MAG_EN', + 'LED_MODE', + 'BLE_TX_POWER', + ], + }, + { + id: 'accel1', + title: 'Accel1', + openByDefault: false, + keys: [ + 'ODR', + 'MODE', + 'LP_MODE', + 'BW_FILT', + 'FS', + 'FDS', + 'LOW_NOISE', + 'HP_REF_MODE', + 'FMode', + 'FTH', + ], + }, + { + id: 'gyro_accel2', + title: 'Gyro / Accel2', + openByDefault: false, + keys: [ + 'FTH_LSB', + 'TIMER_PEDO_FIFDO_EN', + 'TIMER_PEDO_FIFO_DRDY', + 'FTH_MSB', + 'DEC_FIFO_GYRO', + 'DEC_FIFO_XL', + 'ODR_FIFO', + 'FIFO_MODE', + 'ODR_XL', + 'FS_XL', + 'BW_XL', + 'ODR_G', + 'FS_G', + 'FS_125', + 'G_HM_MODE', + 'HP_G_EN', + 'HPCF_G', + 'HP_G_RST', + 'ROUNDING_STATUS', + 'LPF2_XL_EN', + 'HPCF_XL', + 'HP_SLOPE_XL_EN', + 'LOW_PASS_ON_6D', + ], + }, + { + id: 'lsm6dsv', + title: 'Accel / Gyro / Mag', + openByDefault: false, + keys: ['LSM6DSV_ODR_XL', 'LSM6DSV_FS_XL', 'LSM6DSV_ODR_G', 'LSM6DSV_FS_G', 'LIS2MDL_ODR'], + }, + { + id: 'recording_window', + title: 'Recording Window', + openByDefault: false, + keys: ['START_TIME', 'END_TIME'], + }, + { + id: 'inactivity', + title: 'Inactivity', + openByDefault: false, + keys: ['INACTIVE_TIMEOUT_MINUTES', 'RESUME_REC_ON_ACTIVITY'], + }, + { + id: 'ble_wake', + title: 'BLE Wake Schedule', + openByDefault: false, + keys: [ + 'PENDING_EVENTS_SCHEDULER_DISABLED', + 'BLE_CONNECTION_TRIES_PER_DAY', + 'ADAPTIVE_SCHEDULER_INTERVAL', + 'ADAPTIVE_SCHEDULER_FAILCOUNT_MAX', + 'BLE_DATA_TRANS_WKUP_INT_HOURS', + 'BLE_DATA_TRANS_WKUP_TIME', + 'BLE_DATA_TRANS_WKUP_DUR', + 'BLE_DATA_TRANS_RETRY_INT', + 'BLE_STATUS_WKUP_INT_HOURS', + 'BLE_STATUS_WKUP_TIME', + 'BLE_STATUS_WKUP_DUR', + 'BLE_STATUS_RETRY_INT', + 'BLE_RTC_SYNC_WKUP_INT_HOURS', + 'BLE_RTC_SYNC_WKUP_TIME', + 'BLE_RTC_SYNC_WKUP_DUR', + 'BLE_RTC_SYNC_RETRY_INT', + ], + // PENDING_EVENTS and BLE retry count stay ungrouped (rendered above the + // subpanels); the remaining fields cluster by purpose: data transfer, + // status, RTC sync, and the adaptive scheduler. + subgroups: [ + { + id: 'ble_data', + title: 'Data Transfer Schedule', + keys: [ + 'BLE_DATA_TRANS_WKUP_INT_HOURS', + 'BLE_DATA_TRANS_WKUP_TIME', + 'BLE_DATA_TRANS_WKUP_DUR', + 'BLE_DATA_TRANS_RETRY_INT', + ], + }, + { + id: 'ble_status', + title: 'Status Sync Schedule', + keys: [ + 'BLE_STATUS_WKUP_INT_HOURS', + 'BLE_STATUS_WKUP_TIME', + 'BLE_STATUS_WKUP_DUR', + 'BLE_STATUS_RETRY_INT', + ], + }, + { + id: 'ble_rtc_sync', + title: 'Time Sync Schedule', + keys: [ + 'BLE_RTC_SYNC_WKUP_INT_HOURS', + 'BLE_RTC_SYNC_WKUP_TIME', + 'BLE_RTC_SYNC_WKUP_DUR', + 'BLE_RTC_SYNC_RETRY_INT', + ], + }, + { + id: 'adaptive_scheduler', + title: 'Adaptive Scheduler (fallback)', + keys: ['ADAPTIVE_SCHEDULER_FAILCOUNT_MAX', 'ADAPTIVE_SCHEDULER_INTERVAL'], + }, + ], + }, + { + id: 'adc_gsr', + title: 'ADC / GSR', + openByDefault: false, + keys: ['ADC_SAMPLE_RATE', 'ADC_OVERSAMPLE_RATE', 'GSR_RANGE_SETTING'], + }, + { + id: 'ppg', + title: 'PPG', + openByDefault: false, + keys: [ + 'PPG_REC_DUR_SECS', + 'PPG_REC_INT_MINS', + 'SMP_AVE', + 'PPG_ADC_RGE', + 'PPG_SR', + 'PPG_LED_PW', + 'PPG_MA_DEFAULT', + 'PPG_MA_MAX_RED_IR', + 'PPG_MA_MAX_GREEN_BLUE', + 'PPG_AGC_TARGET_PERCENT_OF_RANGE', + 'PPG_UNUSED_BYTE', + 'PPG_MA_LED_PILOT', + 'XTALK_DAC1', + 'XTALK_DAC2', + 'XTALK_DAC3', + 'XTALK_DAC4', + 'PROX_AGC_MODE', + ], + }, + { + id: 'light', + title: 'Ambient Light', + openByDefault: false, + keys: [ + 'LIGHT_GAIN_INDEX', + 'LIGHT_EXPOSURE_INDEX', + 'LIGHT_DARK_ENABLE', + 'LIGHT_FLICKER_EN', + 'LIGHT_SAMPLE_RATE_INDEX', + ], + }, + { + id: 'skin_temp', + title: 'Skin Temperature', + openByDefault: false, + keys: ['SKIN_TEMP_MEAS_TYPE', 'SKIN_TEMP_SAMPLE_RATE'], + }, + { + id: 'algo', + title: 'Algorithm Hub', + openByDefault: false, + keys: [ + 'ALGO_OP_MODE', + 'ALGO_REPORT_MODE', + 'ALGO_REPORT_PERIOD', + 'ALGO_AEC_ENABLE', + 'ALGO_SCD_ENABLE', + 'ALGO_AUTO_PD_ENABLE', + 'ALGO_INITIAL_HR', + ], + }, + { + id: 'person', + title: 'Subject / Person Parameters', + openByDefault: false, + keys: ['PERSON_AGE', 'PERSON_HEIGHT_CM', 'PERSON_WEIGHT_KG', 'PERSON_GENDER'], + }, + { + id: 'led', + title: 'LED Auto-Brightness', + openByDefault: false, + keys: ['LED_AUTO_BRIGHTNESS_ENABLE', 'LED_MAX_BRIGHTNESS', 'LED_LUX_THRESHOLD'], + }, +]; +const VERISENSE_OPERATIONAL_FIELD_FALLBACK_GROUP_ID = 'gen'; +/** + * Maps each hardware-gated operational-config group id to the sensor block that + * gates it (see {@link VerisenseHardwareSensorSupport}). Group ids absent from + * this map (e.g. `gen`, `ble_wake`) configure behaviour that applies to + * every board and are always considered supported. + */ +const VERISENSE_OPERATIONAL_FIELD_GROUP_SENSOR = { + accel1: 'accel1', + gyro_accel2: 'gyroAccel2', + lsm6dsv: 'imuGen2', + adc_gsr: 'gsr', + ppg: 'ppg', + light: 'ambientLight', + skin_temp: 'skinTemperature', + algo: 'algorithmHub', + person: 'algorithmHub', + led: 'ledAutoBrightness', +}; +/** + * Returns the set of operational-config group ids (from + * {@link VERISENSE_OPERATIONAL_FIELD_GROUPS}) whose underlying sensor is present + * on the given hardware revision. A group is supported when it is not gated by a + * sensor block, or when its gating sensor is present. + * + * Returns `null` when the hardware revision is unknown so callers can fall back + * to showing every group. + */ +function getVerisenseSupportedOperationalFieldGroupIds(source) { + const hw = getVerisenseHardwareRevision(source); + if (!hw) + return null; + const support = getVerisenseHardwareSensorSupport(hw.major, hw.minor); + const supported = new Set(); + for (const group of VERISENSE_OPERATIONAL_FIELD_GROUPS) { + const sensorKey = VERISENSE_OPERATIONAL_FIELD_GROUP_SENSOR[group.id]; + if (!sensorKey || support[sensorKey]) + supported.add(group.id); + } + return supported; +} +/** LIGHT_CONFIG bit 1 is the VD6283 dark-channel select: when set, the shared + * visible/clear slot carries the dark (covered-photodiode) baseline instead of + * the visible reading. Returns false for empty/nullish config. */ +function isVerisenseLightDarkChannelEnabled(op) { + if (!op?.length) + return false; + return ((op[OP_IDX.LIGHT_CONFIG] ?? 0) & (1 << 1)) !== 0; +} +/** + * Pad an operational config authored at a legacy/shorter length onto a blank + * full-size (v9, {@link VERISENSE_OP_CONFIG_BYTE_SIZE}-byte) image so the + * working config is always canonical size — otherwise trailing v9 fields + * (e.g. the person-parameter bytes) would be absent. Configs already at or + * beyond full size are returned as-is. + */ +function padVerisenseOperationalConfig(bytes) { + const src = bytes instanceof Uint8Array ? bytes : new Uint8Array(Array.from(bytes)); + if (src.length >= VERISENSE_OP_CONFIG_BYTE_SIZE) + return src; + const full = createBlankVerisenseOperationalConfig(VERISENSE_OP_CONFIG_BYTE_SIZE); + full.set(src); + return full; +} +/** + * Firmware default rate/mode codes per sensor group, for config editors that + * auto-seed a rate when a sensor is first enabled and power it down when all + * of its enables are cleared. Editors should only seed the `on` default when + * the field currently holds the `off` (power-down) code, so a user-chosen + * rate is never clobbered. Sensors whose rate field has no power-down value + * (magnetometer LIS2MDL_ODR, PPG_SR) are omitted — their enable bit / channel + * toggles are the on/off control. Default ODR codes mirror the standard + * customer template (Accel1 = 50 Hz, ADC = 128 Hz). + */ +const VERISENSE_SENSOR_RATE_DEFAULT_GROUPS = [ + { enableKeys: ['ACCEL_1_EN'], fields: [{ key: 'ODR', on: 4, off: 0 }] }, + { + enableKeys: ['ACCEL_2_EN'], + fields: [{ keyByGen: { dsv: 'LSM6DSV_ODR_XL', ds3: 'ODR_XL' }, on: 3, off: 0 }], + }, + { + enableKeys: ['GYRO_EN'], + fields: [{ keyByGen: { dsv: 'LSM6DSV_ODR_G', ds3: 'ODR_G' }, on: 3, off: 0 }], + }, + { + enableKeys: ['GSR_EN', 'VBATT_EN', 'VPROG_EN'], + fields: [{ key: 'ADC_SAMPLE_RATE', on: 19, off: 0 }], + }, + { + enableKeys: ['AMBIENT_LIGHT_EN'], + fields: [{ key: 'LIGHT_SAMPLE_RATE_INDEX', on: 2, off: 0 }], + }, + { + enableKeys: ['SKIN_TEMP_EN'], + fields: [{ key: 'SKIN_TEMP_SAMPLE_RATE', on: 5, off: 0 }], + }, + { enableKeys: ['ALGO_HUB_EN'], fields: [{ key: 'ALGO_OP_MODE', on: 1, off: 0 }] }, +]; +/** Resolve a rate-default field to its concrete schema key for the given IMU + * generation, or null when the field has no key for that generation. */ +function resolveVerisenseSensorRateFieldKey(field, generation) { + return field.key ?? field.keyByGen?.[generation] ?? null; +} +/** + * The three firmware sync schedules (data transfer, status, RTC sync), each + * with wake-interval-hours / wake-time / active-duration / retry-interval + * fields. Interval semantics (from firmware `hal_rtc.c`): 0 = off, 24 = once + * daily at the wake time, 1-23 = every N hours. Wake time is + * minutes-since-midnight (device local time), duration is minutes 0-255, + * retry interval is minutes 0-1439. The number of connection attempts per + * window is the separate global `BLE_CONNECTION_TRIES_PER_DAY` field. + */ +const VERISENSE_BLE_SYNC_SCHEDULES = [ + { + id: 'data', + subgroupId: 'ble_data', + intervalKey: 'BLE_DATA_TRANS_WKUP_INT_HOURS', + timeKey: 'BLE_DATA_TRANS_WKUP_TIME', + durKey: 'BLE_DATA_TRANS_WKUP_DUR', + retryKey: 'BLE_DATA_TRANS_RETRY_INT', + }, + { + id: 'status', + subgroupId: 'ble_status', + intervalKey: 'BLE_STATUS_WKUP_INT_HOURS', + timeKey: 'BLE_STATUS_WKUP_TIME', + durKey: 'BLE_STATUS_WKUP_DUR', + retryKey: 'BLE_STATUS_RETRY_INT', + }, + { + id: 'rtcSync', + subgroupId: 'ble_rtc_sync', + intervalKey: 'BLE_RTC_SYNC_WKUP_INT_HOURS', + timeKey: 'BLE_RTC_SYNC_WKUP_TIME', + durKey: 'BLE_RTC_SYNC_WKUP_DUR', + retryKey: 'BLE_RTC_SYNC_RETRY_INT', + }, +]; +/** Value ranges for the BLE sync-schedule fields (clamp editor input to + * these before writing). */ +const VERISENSE_BLE_SCHEDULE_RANGES = Object.freeze({ + intervalHours: Object.freeze({ min: 0, max: 24 }), + timeMins: Object.freeze({ min: 0, max: 1439 }), + durMin: Object.freeze({ min: 0, max: 255 }), + retryIntMin: Object.freeze({ min: 0, max: 1439 }), +}); +/** + * Canonical schedule defaults: 01:00 daily, 10-minute window, 15-minute + * retry, 5 connection attempts per wake. Also the "reset" values applied + * when the pending-events scheduler is disabled, so a disabled config lands + * in a clean known state. + */ +const VERISENSE_BLE_SCHEDULE_DEFAULTS = Object.freeze({ + intervalHours: 24, + timeMins: 60, + durMin: 10, + retryIntMin: 15, + connectionTries: 5, +}); +/** Format minutes-since-midnight as `"HH:MM"`, or null when out of range. + * Fractional input is rounded to the nearest whole minute first, so the + * minutes component always stays in 0–59. */ +function minutesSinceMidnightToHHMM(mins) { + if (mins == null) + return null; + const v = Math.round(Number(mins)); + if (!Number.isFinite(v) || v < 0 || v > 1439) + return null; + const h = Math.floor(v / 60); + const m = v % 60; + return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`; +} +/** Parse `"HH:MM"` (or `"H:MM"`) into minutes-since-midnight, or null when + * malformed / out of range. */ +function hhmmToMinutesSinceMidnight(text) { + const m = /^(\d{1,2}):(\d{2})$/.exec(String(text ?? '').trim()); + if (!m) + return null; + const h = Number(m[1]); + const mm = Number(m[2]); + if (h < 0 || h > 23 || mm < 0 || mm > 59) + return null; + return h * 60 + mm; +} +/** + * The stream-packet sensor IDs a device will emit for a given set of sensor + * enables (see `VERISENSE_STREAM_SENSOR_LABELS` for the ID meanings). The + * IMU block splits by hardware generation: first-gen streams accel2+gyro as + * ID 3 (LSM6DS3); second-gen streams accel2+gyro+mag as ID 6 (LSM6DSV + + * LIS2MDL). Any enabled PPG channel produces the single PPG stream (ID 4). + */ +function expectedVerisenseStreamSensorIds(enables, opts) { + const ids = new Set(); + if (enables.gsr || enables.vbatt || enables.vprog) + ids.add(1); + if (enables.accel1) + ids.add(2); + if (enables.accel2 || enables.gyro || enables.mag) + ids.add(opts.secondGeneration ? 6 : 3); + if (enables.ppg) + ids.add(4); + if (enables.ambientLight) + ids.add(7); + if (enables.algoHub) + ids.add(8); + if (enables.skinTemp) + ids.add(9); + return ids; +} +const STREAM_ENABLE_BY_FIELD_KEY = { + ACCEL_1_EN: 'accel1', + ACCEL_2_EN: 'accel2', + GYRO_EN: 'gyro', + MAG_EN: 'mag', + GSR_EN: 'gsr', + PPG_GREEN_EN: 'ppg', + PPG_RED_EN: 'ppg', + PPG_IR_EN: 'ppg', + PPG_BLUE_EN: 'ppg', + VPROG_EN: 'vprog', + VBATT_EN: 'vbatt', + AMBIENT_LIGHT_EN: 'ambientLight', + SKIN_TEMP_EN: 'skinTemp', + ALGO_HUB_EN: 'algoHub', +}; +/** {@link expectedVerisenseStreamSensorIds} computed straight from op-config + * bytes via the sensor-enable bit schema. */ +function expectedVerisenseStreamSensorIdsFromConfig(op, opts) { + const enables = {}; + if (op?.length) { + for (const f of VERISENSE_SENSOR_ENABLE_FIELDS) { + const enableKey = STREAM_ENABLE_BY_FIELD_KEY[f.key]; + if (!enableKey) + continue; + if ((((op[f.index] ?? 0) >> f.shift) & 0x01) === 1) + enables[enableKey] = true; + } + } + return expectedVerisenseStreamSensorIds(enables, opts); +} + +/** + * Abstract base class for all Verisense sensor decoders. + * + * Provides: + * - Timestamp unwrapping (handles the 1-minute rollover at 32768 ticks/s). + * - System-time offset tracking for plotting calibrated wall-clock timestamps. + * - Per-sample time extrapolation based on sampling rate and last-sample tick. + */ +class SensorBase { + constructor() { + this.lastTicksUnwrapped = 0; + this.cycle = 0; + /** (system time) − (shimmer time) at first sample, in milliseconds. */ + this.systemOffsetFirstTime = null; + /** Sampling rate in Hz (used for per-sample time extrapolation). */ + this.samplingRateHz = null; + /** Whether this sensor is enabled in the operational config. */ + this.enabled = true; + /** + * Per-device calibration read from the sensor, or null when none is available + * (decoders then fall back to nominal full-scale/datasheet scaling). Set via + * {@link applyCalibration}; subclasses read it in their calibrate routines. + */ + this.calibration = null; + } + /** Supply (or clear) the device calibration set used by this decoder. */ + applyCalibration(set) { + this.calibration = set; + } + /** Reset all timestamp state (call on (re)connect or when streaming restarts). */ + resetTimestamps() { + this.lastTicksUnwrapped = 0; + this.cycle = 0; + this.systemOffsetFirstTime = null; + } + /** + * Unwrap a rolling 24-bit tick counter to a monotonically increasing value. + */ + unwrapTicks(ticks) { + let unwrapped = ticks + SensorBase.TICKS_MAX_VALUE * this.cycle; + if (this.lastTicksUnwrapped > unwrapped) { + this.cycle += 1; + unwrapped = ticks + SensorBase.TICKS_MAX_VALUE * this.cycle; + } + this.lastTicksUnwrapped = unwrapped; + return unwrapped; + } + /** Convert unwrapped ticks to milliseconds. */ + ticksToMillis(unwrappedTicks) { + return (unwrappedTicks / SensorBase.CLOCK_FREQ) * 1000.0; + } + /** + * Compute the calibrated shimmer timestamp for the *last* sample in a burst, + * and store the first-seen system-offset for later plotting. + * + * @param lastSampleTicksU24 24-bit tick counter from the packet header. + * @param systemMillis `Date.now()` at the time of packet receipt. + */ + getTimestampUnwrappedMillis(lastSampleTicksU24, systemMillis) { + const unwrappedTicks = this.unwrapTicks(lastSampleTicksU24); + const shimmerMillis = this.ticksToMillis(unwrappedTicks); + if (this.systemOffsetFirstTime == null) { + this.systemOffsetFirstTime = systemMillis - shimmerMillis; + } + return { shimmerMillis, systemOffsetFirstTime: this.systemOffsetFirstTime }; + } + /** + * Extrapolate the timestamp for sample `i` of `numSamples` in a burst, + * given the timestamp of the *last* sample and the sampling rate. + * + * @returns Object with `tsMillis`, `systemTsMillis`, and `systemTsPlotMillis`. + */ + extrapolateSampleTimes(opts) { + const sr = opts.samplingRateHz ?? this.samplingRateHz; + const { tsLastSampleMillis, systemTsLastSampleMillis, systemOffsetFirstTime } = opts; + if (!sr || sr <= 0) { + return { + tsMillis: tsLastSampleMillis, + systemTsMillis: systemTsLastSampleMillis, + systemTsPlotMillis: systemOffsetFirstTime != null + ? tsLastSampleMillis + systemOffsetFirstTime + : systemTsLastSampleMillis, + }; + } + const sampleOffsetSec = (opts.numSamples - opts.i - 1) / sr; + const tsMillis = tsLastSampleMillis - sampleOffsetSec * 1000; + const systemTsMillis = systemTsLastSampleMillis - sampleOffsetSec * 1000; + const systemTsPlotMillis = systemOffsetFirstTime != null ? tsMillis + systemOffsetFirstTime : systemTsMillis; + return { tsMillis, systemTsMillis, systemTsPlotMillis }; + } + /** + * Compute per-sample timestamps for a whole decoded burst. + * + * The base implementation treats every decoded sample as one evenly-spaced + * time step at `samplingRateHz` (correct when each decoded sample is a single + * combined time step). Sensors whose decoded array *interleaves* multiple + * streams at different cadences (e.g. the LSM6DSV tagged FIFO, which mixes + * accel / gyro / mag entries) override this to timestamp each stream on its + * own rate — otherwise the shared rate spreads each stream's samples too far + * back and consecutive blocks overlap on the time axis. + */ + computeSampleTimestamps(decodedSamples, block) { + const num = decodedSamples.length; + const out = new Array(num); + for (let i = 0; i < num; i++) { + out[i] = this.extrapolateSampleTimes({ + numSamples: num, + i, + samplingRateHz: this.samplingRateHz, + tsLastSampleMillis: block.tsLastSampleMillis, + systemTsLastSampleMillis: block.systemTsLastSampleMillis, + systemOffsetFirstTime: block.systemOffsetFirstTime, + }); + } + return out; + } + /** + * Turn a decoded + timestamped burst into one or more stream contributions + * for live throughput / packet-loss tracking. The default treats the sensor + * as a single stream; sensors whose decoded array interleaves several + * sub-streams at different cadences (e.g. the LSM6DSV tagged FIFO) override + * this to report one contribution per sub-stream so loss is tracked + * independently. + */ + getStreamContributions(samplesWithTime, sensorId) { + let first = null; + let last = null; + for (const s of samplesWithTime) { + const t = s?.timestamps?.tsMillis; + if (typeof t !== 'number') + continue; + if (first == null || t < first) + first = t; + if (last == null || t > last) + last = t; + } + return [ + { + key: String(sensorId), + label: `Sensor ${sensorId}`, + samplingRateHz: this.samplingRateHz, + sampleCount: samplesWithTime.length, + firstSampleMillis: first, + lastSampleMillis: last, + }, + ]; + } +} +/** Verisense clock frequency in ticks per second. */ +SensorBase.CLOCK_FREQ = 32768; +/** 1-minute rollover at 32768 ticks/s (matches C# Sensor.cs). */ +SensorBase.TICKS_MAX_VALUE = 60 * 32768; + +/** + * Decoder for grouped ADC channels (Verisense sensor id = 1). + * + * Includes GSR plus battery/ADC channels carried in the same packet source. + * Implements C# `SensorGSR.cs` including: + * - Per-hardware reference resistor selection (SR68 vs Shimmer3 resistors). + * - Auto-range decoding from the raw ADC value's upper bits. + * - Range-3 clamping threshold that differs by hardware. + * - Conductance (uS) output with connectivity detection. + */ +class SensorADC extends SensorBase { + constructor() { + super(); + this.LIMIT_MIN_VALID_USIEMENS = 0.03; + this.GSR_UNCAL_LIMIT_RANGE3_SR68 = 1134; + this.GSR_UNCAL_LIMIT_RANGE3_SR62 = 683; + this.SHIMMER3_REF_KOHMS = [40.2, 287.0, 1000.0, 3300.0]; + this.SR68_REF_KOHMS = [21.0, 150.0, 562.0, 1740.0]; + this.gsrEnabled = true; + this.battEnabled = false; + /** GSR range 0-3 (fixed) or 4 (auto-range). */ + this.gsrRangeSetting = 4; + this.hardwareIdentifier = 'VERISENSE_PULSE_PLUS'; + this.hwRevisionMajor = null; + this.hwRevisionMinor = null; + this.hwRevisionInternal = null; + // Decoded from opConfig for debug/display + this.gsrRateSettingRaw = 0; + this.gsrRangeSettingRaw = 0; + this.gsrOversamplingRateSettingRaw = 0; + this.samplingRateHz = 50; + } + setHardwareIdentifier(idStr) { + this.hardwareIdentifier = idStr; + } + setHardwareRevision(revHwMajor, revHwMinor, revHwInternal = 0) { + this.hwRevisionMajor = Number.isFinite(revHwMajor) ? Math.trunc(revHwMajor) : null; + this.hwRevisionMinor = Number.isFinite(revHwMinor) ? Math.trunc(revHwMinor) : null; + this.hwRevisionInternal = Number.isFinite(revHwInternal) ? Math.trunc(revHwInternal) : null; + } + setGsrRangeSetting(v) { + this.gsrRangeSetting = v; + } + getBatteryVoltageMultiplier() { + if (this.hwRevisionMajor != null && this.hwRevisionMinor != null) { + return getVerisenseStreamingBatteryVoltageMultiplier(this.hwRevisionMajor, this.hwRevisionMinor); + } + // Backward-compatible fallback when production config revision is unavailable. + if (this.hardwareIdentifier === 'VERISENSE_GSR_PLUS') + return 2.0; + return 1.0; + } + /** + * Whether this board uses the SR62 (Verisense GSR+) Shimmer3-style analog + * front end: 3.0 V SAADC reference, 40.2/287/1000/3300 kΩ GSR feedback + * resistors, 0.5 V GSR reference and range-3 uncal limit 683. Every other + * GSR-capable board (SR61 >= 5, SR68 >= 5 — firmware + * `ShimBrd_isGsrSupportedForHwVersion`) carries the second-generation DC + * front end: 1.8 V reference, 21/150/562/1740 kΩ, 0.4986 V, limit 1134. + * + * Mirrors the firmware's `selectFeedbackResistorsFromHwVersion` (hal_gsr.c), + * which keys the choice on the major revision alone (SR62 vs everything + * else). Prefers the production-config hardware revision; falls back to the + * caller-supplied hardware identifier when no revision has been read yet. + * Previously this was keyed only on the `VERISENSE_PULSE_PLUS` identifier + * string, so an SR61-5/6 presenting its true identity decoded ~1.91× high + * (DEV-874). + */ + usesSr62GsrFrontEnd() { + if (this.hwRevisionMajor != null) { + return this.hwRevisionMajor === 62; + } + return this.hardwareIdentifier === 'VERISENSE_GSR_PLUS'; + } + setEnabled(arg1, opConfigBytes) { + if (opConfigBytes != null) { + const desired = typeof arg1 === 'boolean' ? { gsr: arg1 } : arg1 && typeof arg1 === 'object' ? arg1 : {}; + return this._patchEnabled(desired, opConfigBytes); + } + const obj = typeof arg1 === 'boolean' ? { gsr: arg1 } : arg1 && typeof arg1 === 'object' ? arg1 : {}; + if (typeof obj.gsr === 'boolean') + this.gsrEnabled = obj.gsr; + if (typeof obj.batt === 'boolean') + this.battEnabled = obj.batt; + return { gsr: this.gsrEnabled, batt: this.battEnabled }; + } + _patchEnabled({ gsr, batt }, opConfigBytes) { + const op = normalizeOperationalConfig(opConfigBytes); + const out = new Uint8Array(op); + if (typeof gsr === 'boolean') { + const idx = OP_IDX.GEN_CFG_1; + out[idx] = gsr ? (out[idx] | 0x80) & 0xff : out[idx] & 0x7f & 0xff; + } + if (typeof batt === 'boolean') { + const idx = OP_IDX.GEN_CFG_2; + out[idx] = batt ? (out[idx] | 0x02) & 0xff : out[idx] & 0xfd & 0xff; + } + return out; + } + patchGsrRange(rangeCfg, op) { + const out = new Uint8Array(op); + const i = OP_IDX.ADC_CHANNEL_SETTINGS_1; + out[i] = (out[i] & 0b11111000) | (rangeCfg & 0x07); + return out; + } + patchGsrSamplingRate(rateCfg, op) { + const out = new Uint8Array(op); + const i = OP_IDX.ADC_CHANNEL_SETTINGS_0; + out[i] = (out[i] & 0b11000000) | (rateCfg & 0x3f); + return out; + } + patchGsrOversampling(overCfg, op) { + const out = new Uint8Array(op); + const i = OP_IDX.ADC_CHANNEL_SETTINGS_1; + out[i] = (out[i] & 0b00001111) | ((overCfg & 0x0f) << 4); + return out; + } + calibrateAdcToVolts(uncal12bit) { + const adcRange = 2 ** 12 - 1; + let refVoltage = 1.8 / 4.0; + if (this.usesSr62GsrFrontEnd()) { + refVoltage = 3.0 / 4.0; + } + const adcScaling = 1.0 / 4.0; + return (uncal12bit * refVoltage) / adcRange / adcScaling; + } + calibrateGsrToKOhmsUsingAmplifierEq(volts, range) { + let rFeedback = this.SR68_REF_KOHMS[range]; + let gsrRefVoltage = 0.4986; + if (this.usesSr62GsrFrontEnd()) { + rFeedback = this.SHIMMER3_REF_KOHMS[range]; + gsrRefVoltage = 0.5; + } + return rFeedback / (volts / gsrRefVoltage - 1.0); + } + nudgeGsrResistance(kOhms) { + const limitsByRange = { + 0: [8.0, 63.0], + 1: [63.0, 220.0], + 2: [220.0, 680.0], + 3: [680.0, 4700.0], + 4: [8.0, 4700.0], + }; + const lim = limitsByRange[this.gsrRangeSetting] ?? [8.0, 4700.0]; + return Math.min(Math.max(kOhms, lim[0]), lim[1]); + } + kOhmToUSiemens(kOhms) { + return 1000.0 / kOhms; + } + /** + * Convert the 6-bit ADC sample-rate code to the streamed output rate in Hz, + * or null for "Off"/unknown codes. Used for per-sample timestamp spacing. + */ + decodeAdcSampleRateHz(rateCode) { + const divisor = SensorADC.ADC_RATE_DIVISORS[rateCode]; + if (!divisor) + return null; + return SensorBase.CLOCK_FREQ / divisor; + } + parsePayload(sensorPayloadBytes) { + const bytesPerSample = this.gsrEnabled && this.battEnabled ? 4 : 2; + const n = Math.floor(sensorPayloadBytes.length / bytesPerSample); + const out = []; + for (let i = 0; i < n; i++) { + const base = i * bytesPerSample; + let batt = null; + let gsr = null; + const gsrStart = this.battEnabled && this.gsrEnabled ? 2 : 0; + if (this.gsrEnabled) { + const gsrraw = i16le(sensorPayloadBytes, base + gsrStart); + let adc12 = gsrraw & 0x0fff; + let currentRange = this.gsrRangeSetting; + if (currentRange === 4) + currentRange = (gsrraw >> 14) & 0x03; + if (currentRange === 3) { + const limit = this.usesSr62GsrFrontEnd() + ? this.GSR_UNCAL_LIMIT_RANGE3_SR62 + : this.GSR_UNCAL_LIMIT_RANGE3_SR68; + if (adc12 < limit) + adc12 = limit; + } + const volts = this.calibrateAdcToVolts(adc12); + let kOhms = this.calibrateGsrToKOhmsUsingAmplifierEq(volts, currentRange); + kOhms = this.nudgeGsrResistance(kOhms); + const uS = this.kOhmToUSiemens(kOhms); + const connectivity = uS > this.LIMIT_MIN_VALID_USIEMENS ? 'Connected' : 'Disconnected'; + gsr = { raw: gsrraw, adc12, range: currentRange, volts, kOhms, uS, connectivity }; + } + if (this.battEnabled) { + const raw16 = i16le(sensorPayloadBytes, base) & 0xffff; + const adc12 = raw16 & 0x0fff; + const usbPluggedIn = ((raw16 >> 15) & 0x01) === 1; + const chargerStatusBits = (raw16 >> 13) & 0x03; + let mv = this.calibrateAdcToVolts(adc12) * 1000.0; + mv *= this.getBatteryVoltageMultiplier(); + const chargerStatusMap = { + 0: 'Power-Down/Suspended', + 1: 'Charging', + 2: 'Charging Complete', + 3: 'Bad Battery/LDO', + }; + batt = { + raw16, + adc12, + mV: mv, + usbPluggedIn, + chargerStatusBits, + chargerStatus: chargerStatusMap[chargerStatusBits] ?? 'Unknown', + }; + } + out.push({ gsr, batt }); + } + return out; + } + applyOperationalConfig(op) { + const gen1 = op[OP_IDX.GEN_CFG_1] ?? 0; + const gen2 = op[OP_IDX.GEN_CFG_2] ?? 0; + this.gsrEnabled = ((gen1 >> 7) & 0x01) === 1; + this.battEnabled = (gen2 & 0b00000010) !== 0; + const rateCfg = (op[OP_IDX.ADC_CHANNEL_SETTINGS_0] ?? 0) & 0x3f; + const cfg1 = (op[OP_IDX.ADC_CHANNEL_SETTINGS_1] ?? 0) & 0xff; + const rangeCfg = cfg1 & 0x07; + const oversamplingCfg = (cfg1 >> 4) & 0x0f; + this.gsrRateSettingRaw = rateCfg; + this.gsrRangeSettingRaw = rangeCfg; + this.gsrOversamplingRateSettingRaw = oversamplingCfg; + // Drive per-sample timestamp spacing from the configured ADC rate. Without + // this, samplingRateHz stays at the constructor default (50 Hz); when the + // real rate differs, computeSampleTimestamps mis-spaces samples and + // consecutive blocks overlap on the time axis (the GSR "zigzag"). + const rateHz = this.decodeAdcSampleRateHz(rateCfg); + if (rateHz) + this.samplingRateHz = rateHz; + if (rangeCfg >= 0 && rangeCfg <= 4) { + this.gsrRangeSetting = rangeCfg; + } + } +} +/** + * ADC sample-rate code → divisor of the 32768 Hz clock. Mirrors the firmware + * `samplingRateInTicksArray` (hal_adc.c): the sampling timer fires every + * `divisor` ticks, producing one sample set per fire, so the streamed output + * rate = 32768 / divisor. Oversampling uses SAADC burst mode and therefore + * does NOT divide the output rate. Index 0 = "Off". + */ +SensorADC.ADC_RATE_DIVISORS = [ + 0, 1, 2, 4, 5, 8, 10, 16, 20, 25, 32, 40, 50, 64, 80, 100, 128, 160, 200, 256, 320, 400, 512, + 640, 800, 1024, 1280, 1600, 2048, 2560, 3200, 4096, 5120, 6400, 8192, 10240, 12800, 16384, + 20480, 25600, 32768, 40960, 51200, +]; + +/** + * Decoder for the LIS2DW12 low-power accelerometer (Verisense sensor id = 2). + * + * Sensitivity values are given in raw-LSB / (m/s²) per axis — matching + * the C# `SensorLIS2DW12.cs` implementation. + */ +class SensorLIS2DW12 extends SensorBase { + constructor() { + super(); + this.offset = [0, 0, 0]; + this.align = [ + [0, 0, 1], + [1, 0, 0], + [0, 1, 0], + ]; + this.sensitivityByRange = { + '2G': [1671.665922915, 1671.665922915, 1671.665922915], + '4G': [835.832961457, 835.832961457, 835.832961457], + '8G': [417.916480729, 417.916480729, 417.916480729], + '16G': [208.958240364, 208.958240364, 208.958240364], + }; + this.range = '2G'; + /** Numeric full-scale index (0=2G..3=16G) used to select the device calibration block. */ + this.rangeIndex = 0; + this.samplingRateHz = 50; + } + setRange(rangeStr) { + if (this.sensitivityByRange[rangeStr]) + this.range = rangeStr; + } + // --- Functional OpConfig helpers (returns new Uint8Array, does not mutate) --- + setEnabled(enabled, opConfigBytes) { + if (opConfigBytes == null) { + this.enabled = enabled; + return this.enabled; + } + const op = normalizeOperationalConfig(opConfigBytes); + const out = new Uint8Array(op); + const idx = OP_IDX.GEN_CFG_0; + out[idx] = enabled ? (out[idx] | 0x80) & 0xff : out[idx] & 0x7f & 0xff; + return out; + } + setAccelEnabled(enabled, opConfigBytes) { + return this.setEnabled(enabled, opConfigBytes); + } + patchAccelRange(rangeCfg, op) { + const out = new Uint8Array(op); + const i = OP_IDX.ACCEL1_CFG_1; + out[i] = (out[i] & 0b11001111) | ((rangeCfg & 0x03) << 4); + return out; + } + patchAccelSamplingRate(rateCfg, op) { + const out = new Uint8Array(op); + const i = OP_IDX.ACCEL1_CFG_0; + out[i] = (out[i] & 0b00001111) | ((rateCfg & 0x0f) << 4); + return out; + } + _calibrate(raw) { + // Prefer per-device calibration from the sensor when available for this range. + const dev = this.calibration?.getImu(CalibSensorId.LIS2DW12_ACCEL, this.rangeIndex); + if (dev) + return applyImuCalibration(raw, dev); + // Fallback: nominal offset / alignment / datasheet sensitivity. + const v = [ + raw[0] - this.offset[0], + raw[1] - this.offset[1], + raw[2] - this.offset[2], + ]; + const a = this.align; + const aligned = [ + a[0][0] * v[0] + a[0][1] * v[1] + a[0][2] * v[2], + a[1][0] * v[0] + a[1][1] * v[1] + a[1][2] * v[2], + a[2][0] * v[0] + a[2][1] * v[1] + a[2][2] * v[2], + ]; + const s = this.sensitivityByRange[this.range]; + return [aligned[0] / s[0], aligned[1] / s[1], aligned[2] / s[2]]; + } + parsePayload(sensorPayloadBytes) { + const BYTES_PER_SAMPLE = 6; + const n = Math.floor(sensorPayloadBytes.length / BYTES_PER_SAMPLE); + const out = []; + for (let i = 0; i < n; i++) { + const off = i * BYTES_PER_SAMPLE; + const raw = [ + i16le(sensorPayloadBytes, off + 0), + i16le(sensorPayloadBytes, off + 2), + i16le(sensorPayloadBytes, off + 4), + ]; + const cal = this._calibrate(raw); + out.push({ raw, cal, units: { cal: 'm/s^2' } }); + } + return out; + } + applyOperationalConfig(op) { + const gen0 = op[OP_IDX.GEN_CFG_0]; + const cfg0 = op[OP_IDX.ACCEL1_CFG_0]; + const cfg1 = op[OP_IDX.ACCEL1_CFG_1]; + if (gen0 == null || cfg0 == null || cfg1 == null) { + console.warn('[LIS2DW12] Missing required bytes; cannot apply config.'); + return; + } + this.enabled = ((gen0 >> 7) & 0x01) === 1; + const rangeSetting = (cfg1 >> 4) & 0x03; + const modeSetting = (cfg0 >> 2) & 0x03; + const rateSetting = (cfg0 >> 4) & 0x0f; + const rangeMap = { 0: '2G', 1: '4G', 2: '8G', 3: '16G' }; + this.setRange(rangeMap[rangeSetting] ?? '2G'); + this.rangeIndex = rangeSetting & 0x03; + const lowPowerHzByCfg = { + 1: 1.6, + 2: 12.5, + 3: 25, + 4: 50, + 5: 100, + 6: 200, + }; + const highPerfHzByCfg = { + 1: 12.5, + 3: 25, + 4: 50, + 5: 100, + 6: 200, + 7: 400, + 8: 800, + 9: 1600, + }; + const isLowPower = modeSetting === 0; + const hz = isLowPower ? lowPowerHzByCfg[rateSetting] : highPerfHzByCfg[rateSetting]; + if (hz) + this.samplingRateHz = hz; + } +} + +/** + * Decoder for the LSM6DS3 combined accelerometer + gyroscope (Verisense sensor id = 3). + * + * Sensitivity values mirror the C# `SensorLSM6DS3.cs` implementation. + */ +class SensorLSM6DS3 extends SensorBase { + constructor() { + super(); + this.offset = [0, 0, 0]; + // Applied directly as `physical = align · (raw − offset)` (no inversion), so this + // must be the *inverse* alignment R⁻¹ = Rᵀ — matching the Shimmer Java reference + // `UtilCalibration` (C = R⁻¹·K⁻¹·(U−B)) and the gen-1 calibration doc's R, which + // is the forward §8 rotation. (Previously stored the un-transposed R, which + // applied R instead of R⁻¹.) + this.align = [ + [0, -1, 0], + [0, 0, -1], + [1, 0, 0], + ]; + this.accSensByRange = { + '2G': [1671.665922915, 1671.665922915, 1671.665922915], + '4G': [835.832961457, 835.832961457, 835.832961457], + '8G': [417.916480729, 417.916480729, 417.916480729], + '16G': [208.958240364, 208.958240364, 208.958240364], + }; + this.gyroSensByRange = { + '250DPS': [114.285714286, 114.285714286, 114.285714286], + '500DPS': [57.142857143, 57.142857143, 57.142857143], + '1000DPS': [28.571428571, 28.571428571, 28.571428571], + '2000DPS': [14.285714286, 14.285714286, 14.285714286], + }; + this.accRange = '2G'; + this.gyroRange = '250DPS'; + this.accEnabled = true; + this.gyroEnabled = true; + this.samplingRateHz = 50; + } + setAccelEnabled(v) { + this.accEnabled = !!v; + } + setGyroEnabled(v) { + this.gyroEnabled = !!v; + } + setAccelRange(r) { + if (this.accSensByRange[r]) + this.accRange = r; + } + setGyroRange(r) { + if (this.gyroSensByRange[r]) + this.gyroRange = r; + } + _applyAlignAndOffset(raw3) { + const v = [ + raw3[0] - this.offset[0], + raw3[1] - this.offset[1], + raw3[2] - this.offset[2], + ]; + const a = this.align; + return [ + a[0][0] * v[0] + a[0][1] * v[1] + a[0][2] * v[2], + a[1][0] * v[0] + a[1][1] * v[1] + a[1][2] * v[2], + a[2][0] * v[0] + a[2][1] * v[1] + a[2][2] * v[2], + ]; + } + _calibrateAccel(raw) { + const dev = this.calibration?.getImu(CalibSensorId.LSM6DS3_ACCEL, SensorLSM6DS3.ACC_RANGE_CODE[this.accRange]); + if (dev) + return applyImuCalibration(raw, dev); + const aligned = this._applyAlignAndOffset(raw); + const s = this.accSensByRange[this.accRange]; + return [aligned[0] / s[0], aligned[1] / s[1], aligned[2] / s[2]]; + } + _calibrateGyro(raw) { + const dev = this.calibration?.getImu(CalibSensorId.LSM6DS3_GYRO, SensorLSM6DS3.GYRO_RANGE_CODE[this.gyroRange]); + if (dev) + return applyImuCalibration(raw, dev); + const aligned = this._applyAlignAndOffset(raw); + const s = this.gyroSensByRange[this.gyroRange]; + return [aligned[0] / s[0], aligned[1] / s[1], aligned[2] / s[2]]; + } + parsePayload(sensorPayloadBytes) { + let bytesPerSample = 6; + if (this.gyroEnabled && this.accEnabled) + bytesPerSample = 12; + const n = Math.floor(sensorPayloadBytes.length / bytesPerSample); + const out = []; + for (let i = 0; i < n; i++) { + const base = i * bytesPerSample; + let gyroRaw = null; + let accRaw = null; + if (this.gyroEnabled && this.accEnabled) { + gyroRaw = [ + i16le(sensorPayloadBytes, base + 0), + i16le(sensorPayloadBytes, base + 2), + i16le(sensorPayloadBytes, base + 4), + ]; + accRaw = [ + i16le(sensorPayloadBytes, base + 6), + i16le(sensorPayloadBytes, base + 8), + i16le(sensorPayloadBytes, base + 10), + ]; + } + else if (this.gyroEnabled) { + gyroRaw = [ + i16le(sensorPayloadBytes, base + 0), + i16le(sensorPayloadBytes, base + 2), + i16le(sensorPayloadBytes, base + 4), + ]; + } + else if (this.accEnabled) { + accRaw = [ + i16le(sensorPayloadBytes, base + 0), + i16le(sensorPayloadBytes, base + 2), + i16le(sensorPayloadBytes, base + 4), + ]; + } + let accCal = null; + let gyroCal = null; + if (accRaw) { + accCal = this._calibrateAccel(accRaw); + } + if (gyroRaw) { + gyroCal = this._calibrateGyro(gyroRaw); + } + out.push({ + accel: accRaw && accCal ? { raw: accRaw, cal: accCal, units: 'm/s^2' } : null, + gyro: gyroRaw && gyroCal ? { raw: gyroRaw, cal: gyroCal, units: 'deg/s' } : null, + }); + } + return out; + } + applyOperationalConfig(op) { + this.accEnabled = (op[OP_IDX.GEN_CFG_0] & 0b01000000) !== 0; + this.gyroEnabled = (op[OP_IDX.GEN_CFG_0] & 0b00100000) !== 0; + const cfg4 = op[OP_IDX.GYRO_ACCEL2_CFG_4]; + const accelRateCfg = (cfg4 >> 4) & 0x0f; + const cfg5 = op[OP_IDX.GYRO_ACCEL2_CFG_5]; + const accelRangeCfg = (cfg5 >> 2) & 0x03; + const gyroRangeCfg = (cfg5 >> 4) & 0x03; + const accelRangeMap = { 0: '2G', 1: '4G', 2: '8G', 3: '16G' }; + const gyroRangeMap = { + 0: '250DPS', + 1: '500DPS', + 2: '1000DPS', + 3: '2000DPS', + }; + this.setAccelRange(accelRangeMap[accelRangeCfg] ?? this.accRange); + this.setGyroRange(gyroRangeMap[gyroRangeCfg] ?? this.gyroRange); + const hzByCfg = { + 0: null, + 1: 12.5, + 2: 26, + 3: 52, + 4: 104, + 5: 208, + 6: 416, + 7: 833, + 8: 1660, + }; + const hz = hzByCfg[accelRateCfg]; + if (hz) + this.samplingRateHz = hz; + } +} +// Calibration-block range codes (must match getVerisenseCalibrationSensors gen-1). +SensorLSM6DS3.ACC_RANGE_CODE = { + '2G': 0, + '4G': 1, + '8G': 2, + '16G': 3, +}; +SensorLSM6DS3.GYRO_RANGE_CODE = { + '250DPS': 0, + '500DPS': 1, + '1000DPS': 2, + '2000DPS': 3, +}; + +class SensorLSM6DSV extends SensorBase { + constructor() { + super(); + this.accEnabled = true; + this.gyroEnabled = true; + this.magEnabled = true; + this.accelFsG = 2; + this.gyroFsDps = 2000; + // Numeric full-scale codes (register values) used to select the device + // calibration block: accel 0..3 (2/4/8/16 g), gyro 0..4 (125..2000 dps). + this.fsXlCode = 0; + this.fsGCode = 4; + // Configured per-stream rates (the FIFO interleaves accel/gyro/mag, so each + // stream is timestamped on its own rate — see computeSampleTimestamps). Public + // so the per-sub-stream loss tracking (getStreamContributions) can read each. + // accelHz/gyroHz are the configured LSM6DSV ODRs; magHz is the configured + // magnetometer output (sensor-hub) rate. The firmware FIFO-batches accel/gyro + // at their ODR, so they deliver at the configured rate; the mag is still + // bounded by the accel/gyro hub trigger, so a mag rate above the accel/gyro + // ODR delivers slower — which shows up as packet loss. + this.accelHz = 15; + this.gyroHz = 15; + this.magHz = 15; + this.samplingRateHz = 15; + } + decodeAccelFsG(code) { + switch (code) { + case 0: + return 2; + case 1: + return 4; + case 2: + return 8; + case 3: + return 16; + default: + return 2; + } + } + decodeGyroFsDps(code) { + // LSM6DSV FS_G datasheet register values. + switch (code) { + case 0: + return 125; + case 1: + return 250; + case 2: + return 500; + case 3: + return 1000; + case 4: + return 2000; + default: + return 2000; + } + } + decodeOdrHz(code) { + // LSM6DSV ODR_XL / ODR_G datasheet register values (normal mode). + switch (code) { + case 0: + return 0; // Off + case 1: + return 1.875; + case 2: + return 7.5; + case 3: + return 15; + case 4: + return 30; + case 5: + return 60; + case 6: + return 120; + case 7: + return 240; + case 8: + return 480; + case 9: + return 960; + case 10: + return 1920; + case 11: + return 3840; + case 12: + return 7680; + default: + return 15; + } + } + decodeMagOutputRateHz(code) { + // Magnetometer output (sensor-hub) rate code from op-config byte 20 bits 1:0. + // This is the rate mag samples reach the host; the firmware derives the + // underlying LIS2MDL ODR (20/50/100/100 Hz) to keep a fresh sample available. + switch (code) { + case 0: + return 15; + case 1: + return 30; + case 2: + return 60; + case 3: + return 120; + default: + return 15; + } + } + calibrateAccel(raw) { + const dev = this.calibration?.getImu(CalibSensorId.LSM6DSV_ACCEL, this.fsXlCode); + if (dev) + return applyImuCalibration(raw, dev); + const scale = (this.accelFsG / 32768) * 9.80665; + return [raw[0] * scale, raw[1] * scale, raw[2] * scale]; + } + calibrateGyro(raw) { + const dev = this.calibration?.getImu(CalibSensorId.LSM6DSV_GYRO, this.fsGCode); + if (dev) + return applyImuCalibration(raw, dev); + // ST angular-rate sensitivity: 4.375 mdps/LSB at ±125 dps, doubling per + // range (LSM6DSV datasheet §4.3; same spec as the gen-1 LSM6DS3 and the + // device calibration seed / calibrationDefaults GYRO_RANGES). Unlike the + // accel, the gyro does NOT span the full 16-bit range at nominal full + // scale, so a FS/32768 derivation reads ~12.8% low (DEV-874). + const scale = 0.004375 * (this.gyroFsDps / 125); + return [raw[0] * scale, raw[1] * scale, raw[2] * scale]; + } + calibrateMag(raw) { + const dev = this.calibration?.getImu(CalibSensorId.LIS2MDL_MAG, 0); + if (dev) + return applyImuCalibration(raw, dev); + // LIS2MDL nominal sensitivity is 1.5 mGauss/LSB (0.15 uT/LSB). + const scale = 0.15; + return [raw[0] * scale, raw[1] * scale, raw[2] * scale]; + } + parsePayload(sensorPayloadBytes) { + if (!sensorPayloadBytes?.length) + return []; + // Entry count is a 16-bit little-endian value (a full FIFO drain can return + // more than 255 samples), followed by `count` x 7-byte tagged entries. + const entryCount = ((sensorPayloadBytes[0] ?? 0) | ((sensorPayloadBytes[1] ?? 0) << 8)) >>> 0; + const maxEntriesByLength = Math.floor((sensorPayloadBytes.length - 2) / 7); + const n = Math.min(entryCount, maxEntriesByLength); + const out = []; + let offset = 2; + for (let i = 0; i < n; i++) { + const tagCnt = sensorPayloadBytes[offset]; + const tag = (tagCnt >> 3) & 0x1f; + const cnt = (tagCnt >> 1) & 0x03; + const x = i16le(sensorPayloadBytes, offset + 1); + const y = i16le(sensorPayloadBytes, offset + 3); + const z = i16le(sensorPayloadBytes, offset + 5); + const raw = [x, y, z]; + let accel = null; + let gyro = null; + let mag = null; + if (tag === SensorLSM6DSV.TAG_ACCEL && this.accEnabled) { + accel = { raw, cal: this.calibrateAccel(raw), units: 'm/s^2' }; + } + else if (tag === SensorLSM6DSV.TAG_GYRO && this.gyroEnabled) { + gyro = { raw, cal: this.calibrateGyro(raw), units: 'deg/s' }; + } + else if (tag === SensorLSM6DSV.TAG_SENSORHUB_SLAVE0 && this.magEnabled) { + mag = { raw, cal: this.calibrateMag(raw), units: 'uT' }; + } + if (accel || gyro || mag) { + out.push({ tag, cnt, accel, gyro, mag }); + } + offset += 7; + } + return out; + } + applyOperationalConfig(op) { + this.accEnabled = (op[OP_IDX.GEN_CFG_0] & 0b01000000) !== 0; + this.gyroEnabled = (op[OP_IDX.GEN_CFG_0] & 0b00100000) !== 0; + this.magEnabled = (op[OP_IDX.GEN_CFG_3] & 0b00000100) !== 0; + const cfg0 = op[OP_IDX.LSM6DSV_CFG_0] ?? 0; + const cfg1 = op[OP_IDX.LSM6DSV_CFG_1] ?? 0; + const cfg2 = op[OP_IDX.LSM6DSV_CFG_2] ?? 0; + const odrXl = cfg0 & 0x0f; + const fsXl = (cfg0 >> 4) & 0x03; + const odrG = cfg1 & 0x0f; + const fsG = (cfg1 >> 4) & 0x0f; + const odrMag = cfg2 & 0x03; + this.accelFsG = this.decodeAccelFsG(fsXl); + this.gyroFsDps = this.decodeGyroFsDps(fsG); + this.fsXlCode = fsXl; + this.fsGCode = fsG; + this.accelHz = this.accEnabled ? this.decodeOdrHz(odrXl) : 0; + this.gyroHz = this.gyroEnabled ? this.decodeOdrHz(odrG) : 0; + // Configured mag output rate (NOT capped at the accel/gyro trigger). Loss is + // measured against this, so when the accel/gyro that trigger the sensor hub + // are too slow to deliver it, the shortfall surfaces as mag loss. + this.magHz = this.magEnabled ? this.decodeMagOutputRateHz(odrMag) : 0; + this.samplingRateHz = Math.max(this.accelHz, this.gyroHz, this.magHz, 1); + } + /** + * Timestamp each stream (accel / gyro / mag) so all three cover the same block + * time window. The tagged FIFO interleaves the streams, so the generic + * global-index spacing spreads each stream by (#interleaved-streams)x too far + * back and makes consecutive blocks overlap on the time axis. + * + * Each stream's effective rate is derived from *this block*: the block's + * covered duration is taken from a directly-sampled reference stream (accel, + * else gyro) at its known ODR, and every stream is then spread evenly over + * that same duration by its own sample count. This is important for the mag + * (LIS2MDL), which is read via the LSM6DSV sensor hub — its entries land in + * the FIFO at the hub batch rate, NOT the LIS2MDL ODR, so a fixed mag ODR + * would mis-spread it (the zig-zag). Deriving the rate from the block keeps it + * aligned regardless of the hub rate. + */ + computeSampleTimestamps(decodedSamples, block) { + const samples = decodedSamples; + let accelTotal = 0; + let gyroTotal = 0; + let magTotal = 0; + for (const s of samples) { + if (s.accel) + accelTotal++; + else if (s.gyro) + gyroTotal++; + else if (s.mag) + magTotal++; + } + // Block duration (s) from a directly-sampled reference stream at a known ODR. + let blockPeriodSec = 0; + if (accelTotal > 0 && this.accelHz > 0) + blockPeriodSec = accelTotal / this.accelHz; + else if (gyroTotal > 0 && this.gyroHz > 0) + blockPeriodSec = gyroTotal / this.gyroHz; + else if (magTotal > 0 && this.magHz > 0) + blockPeriodSec = magTotal / this.magHz; + // Effective per-stream rate so each stream spans exactly blockPeriodSec. + const rateFor = (total) => blockPeriodSec > 0 && total > 0 ? total / blockPeriodSec : (this.samplingRateHz ?? 1); + const accelRate = rateFor(accelTotal); + const gyroRate = rateFor(gyroTotal); + const magRate = rateFor(magTotal); + let ai = 0; + let gi = 0; + let mi = 0; + return samples.map((s) => { + let numSamples = samples.length; + let i = 0; + let rate = this.samplingRateHz; + if (s.accel) { + numSamples = accelTotal; + i = ai++; + rate = accelRate; + } + else if (s.gyro) { + numSamples = gyroTotal; + i = gi++; + rate = gyroRate; + } + else if (s.mag) { + numSamples = magTotal; + i = mi++; + rate = magRate; + } + return this.extrapolateSampleTimes({ + numSamples, + i, + samplingRateHz: rate, + tsLastSampleMillis: block.tsLastSampleMillis, + systemTsLastSampleMillis: block.systemTsLastSampleMillis, + systemOffsetFirstTime: block.systemOffsetFirstTime, + }); + }); + } + /** + * Report up to three independent sub-streams (accel / gyro / mag) so loss is + * tracked per stream. Each sub-stream's expected rate is its configured rate + * (ODR for accel/gyro, output rate for mag); loss is measured against that, so + * the mag's hub-trigger bound — or any rate the firmware/link can't keep up + * with — surfaces as loss when a configured rate exceeds what's delivered. + */ + getStreamContributions(samplesWithTime, sensorId) { + const samples = samplesWithTime; + const subs = [ + { + key: `${sensorId}:accel`, + label: 'Accel', + rate: this.accelHz, + has: (s) => !!s.accel, + }, + { + key: `${sensorId}:gyro`, + label: 'Gyro', + rate: this.gyroHz, + has: (s) => !!s.gyro, + }, + // Mag enters the FIFO at its configured sensor-hub output rate (`magHz`). + { key: `${sensorId}:mag`, label: 'Mag', rate: this.magHz, has: (s) => !!s.mag }, + ]; + const out = []; + for (const sub of subs) { + let count = 0; + let first = null; + let last = null; + for (const s of samples) { + if (!sub.has(s)) + continue; + count++; + const t = s?.timestamps?.tsMillis; + if (typeof t !== 'number') + continue; + if (first == null || t < first) + first = t; + if (last == null || t > last) + last = t; + } + if (count === 0) + continue; // disabled or no samples in this burst + out.push({ + key: sub.key, + label: sub.label, + samplingRateHz: sub.rate > 0 ? sub.rate : null, + sampleCount: count, + firstSampleMillis: first, + lastSampleMillis: last, + }); + } + return out; + } +} +SensorLSM6DSV.TAG_GYRO = 0x01; +SensorLSM6DSV.TAG_ACCEL = 0x02; +SensorLSM6DSV.TAG_SENSORHUB_SLAVE0 = 0x0e; + +/** + * Decoder for the PPG sensor (Verisense sensor id = 4). + * + * Calibration constants mirror C# `SensorPPG.cs`. + */ +class SensorPPG extends SensorBase { + constructor() { + super(); + this.red = false; + this.ir = false; + this.green = false; + this.blue = false; + /** + * 2nd-gen hub mode: PPG arrives via the MAX32674 hub as a fixed block of 6 raw + * MAX86176 LED channels (6 x u24), independent of the RED/IR/GREEN/BLUE enable + * bits. Set from the connected device's hardware generation (see + * VerisenseClient). When false, the 1st-gen named-channel layout is used. + */ + this.hubMode = false; + this.adcLsb = [7.8125, 15.625, 31.25, 62.5]; + this.adcBitShift = [2 ** 7, 2 ** 6, 2 ** 5, 2 ** 4]; + this.adcResolutionIndex = 0; // 0..3 + /** PPG_SR code → base sampling rate in Hz (op byte PPG_MODE_CONFIG2 bits 4:2). */ + this.PPG_SR_HZ = [50, 100, 200, 400, 800, 1000, 1600, 3200]; + /** SMP_AVE code → FIFO sample-averaging factor (op byte PPG_FIFO_CONFIG bits 7:5). */ + this.SMP_AVE_FACTOR = [1, 2, 4, 8, 16, 32, 32, 32]; + this.samplingRateHz = 50; + } + setChannels(channels) { + if (typeof channels.RED === 'boolean') + this.red = channels.RED; + if (typeof channels.IR === 'boolean') + this.ir = channels.IR; + if (typeof channels.GREEN === 'boolean') + this.green = channels.GREEN; + if (typeof channels.BLUE === 'boolean') + this.blue = channels.BLUE; + } + setHubMode(enabled) { + this.hubMode = enabled; + } + setAdcResolutionIndex(i) { + if (i >= 0 && i <= 3) + this.adcResolutionIndex = i; + } + calibrateValue(uncalValue) { + const idx = this.adcResolutionIndex; + return ((uncalValue / this.adcBitShift[idx]) * this.adcLsb[idx]) / 1000.0; + } + /** + * 2nd-gen hub PPG block: N samples x (3 x u24 LED channels = green, IR, red), + * no count prefix (sample count derived from the block length, matching the + * firmware packer). + */ + parseHubPayload(sensorPayloadBytes) { + const bytesPerSample = 9; // 3 channels x 3 bytes + const n = Math.floor(sensorPayloadBytes.length / bytesPerSample); + const out = []; + for (let i = 0; i < n; i++) { + const base = i * bytesPerSample; + out.push({ + leds: [ + u24le(sensorPayloadBytes, base + 0), // green (LED1) + u24le(sensorPayloadBytes, base + 3), // IR (LED2) + u24le(sensorPayloadBytes, base + 6), // red (LED3) + ], + }); + } + return out; + } + parsePayload(sensorPayloadBytes) { + if (this.hubMode) { + return this.parseHubPayload(sensorPayloadBytes); + } + const enabled = []; + if (this.red) + enabled.push('RED'); + if (this.ir) + enabled.push('IR'); + if (this.green) + enabled.push('GREEN'); + if (this.blue) + enabled.push('BLUE'); + const bytesPerSample = enabled.length * 3; + if (bytesPerSample === 0) + return []; + const n = Math.floor(sensorPayloadBytes.length / bytesPerSample); + const out = []; + for (let i = 0; i < n; i++) { + const base = i * bytesPerSample; + let off = 0; + const sample = {}; + for (const ch of enabled) { + const b0 = sensorPayloadBytes[base + off + 0]; + const b1 = sensorPayloadBytes[base + off + 1]; + const b2 = sensorPayloadBytes[base + off + 2]; + off += 3; + let uncal = (b0 | (b1 << 8) | (b2 << 16)) >>> 0; + uncal &= 0x7ffff; + sample[ch] = { + raw: uncal, + cal: this.calibrateValue(uncal), + units: { raw: 'counts', cal: 'scaled' }, + }; + } + out.push(sample); + } + return out; + } + applyOperationalConfig(op) { + // PPG *channel* flags have a hardware-specific bit mapping (1st-gen named + // channels vs MAX86176 hub), so those are still left to setChannels(). The + // sample rate is a well-defined field, though, and it drives per-sample + // timestamp spacing: without it samplingRateHz stays at the 50 Hz default + // and any other configured rate makes consecutive blocks overlap on the + // time axis (the same "zigzag" fixed for GSR/IMU). + const norm = normalizeOperationalConfig(op); + if (!norm) + return; + const srCode = ((norm[OP_IDX.PPG_MODE_CONFIG2] ?? 0) >> 2) & 0x07; + const smpAveCode = ((norm[OP_IDX.PPG_FIFO_CONFIG] ?? 0) >> 5) & 0x07; + const baseHz = this.PPG_SR_HZ[srCode]; + const aveFactor = this.SMP_AVE_FACTOR[smpAveCode] ?? 1; + // The MAX86xxx averages SMP_AVE samples into one FIFO entry, so the streamed + // output rate is the base PPG_SR divided by the averaging factor. + if (baseHz) + this.samplingRateHz = baseHz / aveFactor; + } +} + +/** Slow-sensor sample-rate index -> Hz (matches firmware slowSensorRateMs). This + * is the configured (target) rate the firmware polls at; the sensor's exposure + * may prevent reaching it, which surfaces as packet loss against this rate. */ +const SLOW_SENSOR_RATE_HZ = [0, 0.5, 1, 2, 5, 10, 20]; +/** Op-config index -> exposure µs (matches firmware vd6283_exposureIndexToUs). */ +const EXPOSURE_US_TABLE = [100000, 1600, 6400, 12800, 25600, 51200, 102400, 204800]; +/** Op-config index -> 8.8 fixed-point gain (matches firmware vd6283_gainIndexToValue). */ +const GAIN_8P8_TABLE = [0x0100, 0x01ab, 0x0280, 0x0500, 0x0a00, 0x1900, 0x3200, 0x42ab]; +/** Reference exposure (firmware VD6283TX_DEFAULT_EXPO). */ +const DEFAULT_EXPO_US = 100800; +/** ALS-counts -> XYZ matrix (firmware App_vd6283tx.c). Rows are X, Y, Z. */ +const XYZ_MATRIX = [ + [0.20557, 0.4167, -0.143816], + [-0.028752, 0.506372, -0.120614], + [-0.552625, 0.335866, 0.494781], +]; +/** + * Decoder for the VD6283TX45 ambient light sensor (Verisense sensor id = 7). + * + * Data block payload = N samples x 18 bytes (6 channels x 24-bit LE counts). + * In addition to the raw channel counts, each sample carries the derived lux + * and CCT, computed from the RED/GREEN/BLUE channels with the configured gain + * and exposure (ported from firmware App_vd6283tx.c). + */ +class SensorVD6283 extends SensorBase { + constructor() { + super(); + this.exposureUs = EXPOSURE_US_TABLE[0]; + this.gain8p8 = GAIN_8P8_TABLE[0]; + /** Op-config dark-channel bit (LIGHT_CONFIG bit 1): when set the shared second + * slot carries the dark baseline (`DARK`) instead of the visible reading. */ + this.darkEnabled = false; + this.samplingRateHz = 1; + } + /** Normalise a raw channel count for the XYZ transform (gain + exposure). */ + normalizeForXyz(meas) { + const expoScale = DEFAULT_EXPO_US / this.exposureUs; + // Firmware divides by 256 (16.8 / 8.8 fixed-point); float division here is + // a touch more precise than the firmware's integer division. + return (expoScale * (meas / 256)) / (this.gain8p8 / 256 || 1); + } + /** Compute illuminance (lux) and CCT (K) from RED/GREEN/BLUE counts. */ + computeLuxCct(red, green, blue) { + const r = this.normalizeForXyz(red); + const g = this.normalizeForXyz(green); + const b = this.normalizeForXyz(blue); + const X = XYZ_MATRIX[0][0] * r + XYZ_MATRIX[0][1] * g + XYZ_MATRIX[0][2] * b; + const Y = XYZ_MATRIX[1][0] * r + XYZ_MATRIX[1][1] * g + XYZ_MATRIX[1][2] * b; + const Z = XYZ_MATRIX[2][0] * r + XYZ_MATRIX[2][1] * g + XYZ_MATRIX[2][2] * b; + const lux = Y < 0 ? 0 : Y; + const norm = X + Y + Z; + let cct = 0; + if (norm !== 0) { + const x = X / norm; + const y = Y / norm; + const n = (x - 0.332) / (0.1858 - y); + cct = 449 * n ** 3 + 3525 * n ** 2 + 6823.3 * n + 5520.33; + } + return { lux, cct }; + } + parsePayload(sensorPayloadBytes) { + if (!sensorPayloadBytes?.length) + return []; + const n = Math.floor(sensorPayloadBytes.length / SensorVD6283.BYTES_PER_SAMPLE); + const out = []; + for (let i = 0; i < n; i++) { + const base = i * SensorVD6283.BYTES_PER_SAMPLE; + const RED = u24le(sensorPayloadBytes, base + 0); + // Slot 1 is visible-or-dark depending on the configured dark-channel bit. + const slot1 = u24le(sensorPayloadBytes, base + 3); + const VISIBLE = this.darkEnabled ? null : slot1; + const DARK = this.darkEnabled ? slot1 : null; + const BLUE = u24le(sensorPayloadBytes, base + 6); + const GREEN = u24le(sensorPayloadBytes, base + 9); + const IR = u24le(sensorPayloadBytes, base + 12); + const CLEAR = u24le(sensorPayloadBytes, base + 15); + // lux/CCT derive from RED/GREEN/BLUE, so the dark-channel selection (which + // only affects slot 1) leaves them valid in either mode. + const { lux, cct } = this.computeLuxCct(RED, GREEN, BLUE); + out.push({ RED, VISIBLE, BLUE, GREEN, IR, CLEAR, DARK, lux, cct }); + } + return out; + } + applyOperationalConfig(op) { + this.enabled = (op[OP_IDX.GEN_CFG_3] & (1 << 3)) !== 0; + const rateIdx = op[OP_IDX.LIGHT_SAMPLE_RATE_INDEX] ?? 0; + // Report the configured rate; loss is measured against it so a long exposure + // (or any firmware/hardware shortfall) that prevents reaching it shows up. + this.samplingRateHz = SLOW_SENSOR_RATE_HZ[rateIdx] || 1; + const expoIdx = op[OP_IDX.LIGHT_EXPOSURE_INDEX] ?? 0; + const gainIdx = op[OP_IDX.LIGHT_GAIN_INDEX] ?? 0; + this.exposureUs = EXPOSURE_US_TABLE[expoIdx] ?? EXPOSURE_US_TABLE[0]; + this.gain8p8 = GAIN_8P8_TABLE[gainIdx] ?? GAIN_8P8_TABLE[0]; + // LIGHT_CONFIG bit 1 selects the dark channel on slot 1 (see VD6283Sample). + this.darkEnabled = isVerisenseLightDarkChannelEnabled(op); + } +} +SensorVD6283.NUM_CHANNELS = 6; +SensorVD6283.BYTES_PER_SAMPLE = 18; + +function u16le(bytes, off) { + return (bytes[off] & 0xff) | ((bytes[off + 1] & 0xff) << 8); +} +/** + * Decoder for the MAX32674 algorithm hub (Verisense sensor id = 8). + * + * Data block payload = [sampleCount:1] then sampleCount x 14 bytes: + * accel x,y,z : 3 x i16 (6) | hr u16 (2) | hr_conf u8 (1) | + * spo2 u16 (2) | spo2_conf u8 (1) | activity u8 (1) | scd_contact u8 (1) + * + * Raw PPG is reported separately under the PPG sensor id (4). + */ +class SensorMAX32674 extends SensorBase { + constructor() { + super(); + // Approximate; the hub reports at the configured algorithm report rate. + this.samplingRateHz = 25; + } + parsePayload(sensorPayloadBytes) { + if (!sensorPayloadBytes?.length) + return []; + const count = sensorPayloadBytes[0] ?? 0; + const maxByLength = Math.floor((sensorPayloadBytes.length - 1) / SensorMAX32674.BYTES_PER_SAMPLE); + const n = Math.min(count, maxByLength); + const out = []; + for (let i = 0; i < n; i++) { + const base = 1 + i * SensorMAX32674.BYTES_PER_SAMPLE; + out.push({ + accel: { + raw: [ + i16le(sensorPayloadBytes, base + 0), + i16le(sensorPayloadBytes, base + 2), + i16le(sensorPayloadBytes, base + 4), + ], + }, + hr: u16le(sensorPayloadBytes, base + 6), + hrConfidence: sensorPayloadBytes[base + 8] ?? 0, + spo2: u16le(sensorPayloadBytes, base + 9), + spo2Confidence: sensorPayloadBytes[base + 11] ?? 0, + activityClass: sensorPayloadBytes[base + 12] ?? 0, + scdContactState: sensorPayloadBytes[base + 13] ?? 0, + }); + } + return out; + } + applyOperationalConfig(op) { + this.enabled = (op[OP_IDX.GEN_CFG_3] & (1 << 5)) !== 0; + // samplingRateHz is left at its default; the hub report period mapping is + // hardware-specific and not derived from a single op-config byte. + } +} +SensorMAX32674.BYTES_PER_SAMPLE = 14; + +/** MLX90632 refresh-rate code (op-config byte 76 bits 3:1) -> refresh Hz. The + * single skin-temp rate setting is stored as this code; the output (sample) rate + * is refresh / sub-measurements (medical = 2, extended = 3). */ +const MLX_REFRESH_HZ = [0.5, 1, 2, 4, 8, 16, 32, 64]; +/** + * Decoder for the MLX90632 skin temperature sensor (Verisense sensor id = 9). + * + * Data block payload = N samples x 4 bytes: object int16 then ambient int16, + * each in centi-degrees Celsius (value / 100 = degrees C). + */ +class SensorMLX90632 extends SensorBase { + constructor() { + super(); + this.samplingRateHz = 1; + } + parsePayload(sensorPayloadBytes) { + if (!sensorPayloadBytes?.length) + return []; + const n = Math.floor(sensorPayloadBytes.length / SensorMLX90632.BYTES_PER_SAMPLE); + const out = []; + for (let i = 0; i < n; i++) { + const base = i * SensorMLX90632.BYTES_PER_SAMPLE; + const objRaw = i16le(sensorPayloadBytes, base + 0); + const ambRaw = i16le(sensorPayloadBytes, base + 2); + out.push({ + object: { raw: objRaw, cal: objRaw / 100, units: 'degC' }, + ambient: { raw: ambRaw, cal: ambRaw / 100, units: 'degC' }, + }); + } + return out; + } + applyOperationalConfig(op) { + this.enabled = (op[OP_IDX.GEN_CFG_3] & (1 << 4)) !== 0; + // Single skin-temp rate: stored as the MLX90632 refresh-rate code (byte 76 + // bits 3:1). The output (sample) rate the firmware delivers is the refresh + // rate divided by the sub-measurement count (medical = 2, extended = 3). + const cfg = op[OP_IDX.SKIN_TEMP_CONFIG] ?? 0; + const isExtended = (cfg & 0x01) !== 0; + const refreshCode = (cfg >> 1) & 0x07; + const refreshHz = MLX_REFRESH_HZ[refreshCode] ?? 16; + this.samplingRateHz = refreshHz / (isExtended ? 3 : 2); + } +} +SensorMLX90632.BYTES_PER_SAMPLE = 4; + +function defaultAcceptedCommands(command) { + if (command === ASM_COMMAND.READ) + return new Set([ASM_COMMAND.RESPONSE]); + if (command === ASM_COMMAND.WRITE) { + return new Set([ASM_COMMAND.ACK, ASM_COMMAND.ACK_NEXT_STAGE, ASM_COMMAND.RESPONSE]); + } + return new Set([ASM_COMMAND.ACK, ASM_COMMAND.ACK_NEXT_STAGE, ASM_COMMAND.RESPONSE]); +} +function toCommandResponse(msg) { + return { + header: msg.header, + command: msg.command, + property: msg.property, + payload: msg.payload, + }; +} +function validatePendingResponse(pending, msg) { + if (isNackCommand(msg.command)) { + return new Error(`Device returned NACK command=0x${msg.command.toString(16)} property=0x${msg.property.toString(16)}`); + } + if (pending.acceptedProperties?.size) { + if (!pending.acceptedProperties.has(msg.property)) { + return new Error(`Unexpected response property 0x${msg.property.toString(16)} (expected one of ${Array.from(pending.acceptedProperties) + .map((p) => `0x${p.toString(16)}`) + .join(', ')})`); + } + } + else if (msg.property !== pending.expectedProperty) { + return new Error(`Unexpected response property 0x${msg.property.toString(16)} (expected 0x${pending.expectedProperty.toString(16)})`); + } + if (!pending.acceptedCommands.has(msg.command)) { + return new Error(`Unexpected response command 0x${msg.command.toString(16)} for property 0x${msg.property.toString(16)}`); + } + return null; +} + +// Thrown by connectWithRetry() when disconnect() is called while a connect +// attempt is in flight. Must NOT match any of the retryable-error patterns +// (request timeout / gatt server is disconnected / unexpected response +// property) so it always aborts the retry loop. +const CONNECT_CANCELLED_MESSAGE = 'Connect cancelled: disconnect requested during connect attempt.'; +// --------------------------------------------------------------------------- +// VerisenseBleDevice +// --------------------------------------------------------------------------- +/** + * Web Bluetooth client for the Verisense sensor platform. + * + * Extends {@link BaseShimmerClient} and adds an event-emitter API + * (on/off/emit) for the richer event model the Verisense protocol needs. + * + * Supports: + * - BLE streaming (accel, ADC/GSR, gyro, PPG) + * - Web Serial (USB COM port) as an alternative transport + * - Logged-data download (`transferLoggedData`) + * - Operational config read/write + * + * Events: + * - `"connected"` — `{ name?: string; id?: string; kind?: string }` + * - `"disconnected"` — `{ kind: TransportKind }` + * - `"streaming"` — `{ on: boolean }` + * - `"streamPacket"` / `"data"` — `StreamPacket` + * - `"streamStats"` — `StreamStatsSnapshot` (throttled ~3 Hz live throughput/loss) + * - `"opConfig"` — `{ op: Uint8Array }` + * - `"productionConfig"` — `ProductionConfig` + * - `"commandPayload"` — `{ payload: Uint8Array }` + */ +class VerisenseBleDevice extends BaseShimmerClient { + on(ev, fn) { + if (!this._evMap.has(ev)) + this._evMap.set(ev, new Set()); + this._evMap.get(ev).add(fn); + return () => this.off(ev, fn); + } + off(ev, fn) { + this._evMap.get(ev)?.delete(fn); + } + emit(ev, data) { + const s = this._evMap.get(ev); + if (s) + for (const fn of s) + fn(data); + } + constructor(opts = {}) { + super({ debug: opts.debug ?? true }); + // Event emitter state + this._evMap = new Map(); + // Transport handles + this._transportKind = null; + this.device = null; + this.server = null; + this.service = null; + this.tx = null; + this.rx = null; + this.port = null; + this._serialAbort = null; + this._serialReader = null; + this._serialReadLoopTask = null; + this._onGattDisconnected = null; + this._suppressDisconnectedEvent = false; + // Protocol state + this._mode = 'idle'; + this._rxStreamBuf = new Uint8Array(0); + this._pending = null; + this._loggedChain = Promise.resolve(); + this._sync = null; + this._testReportMode = false; // Flag to capture raw streaming bytes for test reports + this._throughputTestMode = false; // Flag to count raw bytes during a BLE throughput test + this._bootstrapRequestTimeoutOverrideMs = null; + // Set by disconnect() so an in-flight connectWithRetry() loop stops instead + // of treating the resulting GATT teardown as a transient link drop. + this._connectCancelRequested = false; + this._isSecondGenerationHw = false; + // Live stream statistics (throughput / packet-loss). Reset on stream start. + this._streamStats = new StreamStatsTracker(); + this._lastStreamStatsEmitMillis = 0; + // Cached configs + this.operationalConfig = null; + this.productionConfig = null; + // Debug flags + this.debugSync = false; + this._syncRxCount = 0; + this._syncPayloadCount = 0; + /** Per-device calibration last read from the device, or null. */ + this._calibration = null; + this.hardwareIdentifier = opts.hardwareIdentifier ?? 'VERISENSE_PULSE_PLUS'; + this.stripStreamCrc = opts.stripStreamCrc ?? true; + this.sensors = { + 1: new SensorADC(), + 2: new SensorLIS2DW12(), + 3: new SensorLSM6DS3(), + 4: new SensorPPG(), + 6: new SensorLSM6DSV(), + 7: new SensorVD6283(), + 8: new SensorMAX32674(), + 9: new SensorMLX90632(), + }; + this.sensors[1].setHardwareIdentifier(this.hardwareIdentifier); + } + _log(...args) { + if (this.debug) + console.log('[Verisense]', ...args); + } + // Quick accessors + get adc() { + return this.sensors[1]; + } + get accel1() { + return this.sensors[2]; + } + get gyroAccel2() { + return this._isSecondGenerationHw ? this.sensors[6] : this.sensors[3]; + } + get gyroAccel2Lsm6ds3() { + return this.sensors[3]; + } + get gyroAccel2Lsm6dsv() { + return this.sensors[6]; + } + get ppg() { + return this.sensors[4]; + } + _setOperationalConfigErasedFallback(lengthHint) { + const fallbackLen = lengthHint ?? this.operationalConfig?.length ?? VERISENSE_OP_CONFIG_BYTE_SIZE; + const op = new Uint8Array(fallbackLen); + op.fill(0xff); + this.operationalConfig = op; + this.emit('opConfigErased', { raw: new Uint8Array(op) }); + this.emit('opConfig', { op: new Uint8Array(op), erased: true }); + return op; + } + async _bootstrapConfigsAfterConnect() { + await this.readProductionConfigFromDevice(); + try { + await this.readOpConfigFromDevice(); + } + catch (e) { + const msg = e instanceof Error ? e.message : String(e); + const invalidOp = /Invalid operational config returned from device/i.test(msg); + const productionErased = this._isUninitializedBlob(this.productionConfig); + if (invalidOp && productionErased) { + console.warn('[opcfg] invalid operational config during bootstrap; treating as erased because production config is uninitialized', { payloadLengthHint: this.operationalConfig?.length ?? VERISENSE_OP_CONFIG_BYTE_SIZE }); + this._setOperationalConfigErasedFallback(); + return; + } + throw e; + } + } + // --------------------------------------------------------------------------- + // BLE connect / disconnect + // --------------------------------------------------------------------------- + async connect(opts = {}) { + if (this._transportKind === 'serial' || this.port) { + try { + await this.disconnect(); + } + catch { + /* ignore */ + } + } + this._transportKind = 'ble'; + // A previous session's disconnect (including the internal teardown above) + // must not cancel this fresh connect attempt. + this._connectCancelRequested = false; + const requestOpts = { + filters: opts.filters ?? [{ services: [NUS_SERVICE] }], + // NORDIC_DFU_SERVICE must be granted at requestDevice() time so the + // buttonless DFU control point is reachable from rebootToDfuBootloader(). + optionalServices: opts.optionalServices ?? [NUS_SERVICE, NORDIC_DFU_SERVICE], + }; + this.device = opts.device ?? (await navigator.bluetooth.requestDevice(requestOpts)); + try { + if (this._onGattDisconnected && this.device) { + this.device.removeEventListener('gattserverdisconnected', this._onGattDisconnected); + } + } + catch { + /* ignore */ + } + this._onGattDisconnected = () => { + this._mode = 'idle'; + this._transportKind = null; + if (this._suppressDisconnectedEvent) + return; + this.emit('disconnected', { kind: 'ble' }); + }; + this.device.addEventListener('gattserverdisconnected', this._onGattDisconnected); + this.server = await this.device.gatt.connect(); + this.service = await this.server.getPrimaryService(NUS_SERVICE); + this.tx = await this.service.getCharacteristic(NUS_TX); + this.rx = await this.service.getCharacteristic(NUS_RX); + await this.rx.startNotifications(); + this.rx.addEventListener('characteristicvaluechanged', (ev) => { + const dv = ev.target?.value; + if (!dv) + return; + const bytes = new Uint8Array(dv.buffer.slice(dv.byteOffset, dv.byteOffset + dv.byteLength)); + this._feedStreamBytes(bytes); + }); + this._emitStatus(`Connected: ${this.device.name ?? 'Verisense'}`); + this.emit('connected', { name: this.device.name, id: this.device.id }); + await this._bootstrapConfigsAfterConnect(); + return true; + } + async _cleanupFailedBleConnectAttempt(retrySettleMs) { + this._suppressDisconnectedEvent = true; + try { + if (this._onGattDisconnected && this.device) { + this.device.removeEventListener('gattserverdisconnected', this._onGattDisconnected); + } + } + catch { + /* ignore */ + } + try { + if (this.device?.gatt?.connected) { + this.device.gatt.disconnect(); + } + } + catch { + /* ignore */ + } + this.tx = null; + this.rx = null; + this.service = null; + this.server = null; + this._pending = null; + this._mode = 'idle'; + this._transportKind = null; + await new Promise((resolve) => setTimeout(resolve, Math.max(0, retrySettleMs))); + this._suppressDisconnectedEvent = false; + } + async _retryBootstrapInPlaceWithBudget(totalBudgetMs, perAttemptTimeoutMs) { + const budgetMs = Math.max(1000, Math.trunc(totalBudgetMs)); + const attemptTimeoutBaseMs = Math.max(1000, Math.trunc(perAttemptTimeoutMs)); + const deadline = Date.now() + budgetMs; + while (Date.now() < deadline) { + if (this._connectCancelRequested) { + throw new Error(CONNECT_CANCELLED_MESSAGE); + } + const remainingMs = Math.max(1000, deadline - Date.now()); + this._bootstrapRequestTimeoutOverrideMs = Math.min(attemptTimeoutBaseMs, remainingMs); + try { + this._pending = null; + this._resetAssembler(); + await this._bootstrapConfigsAfterConnect(); + return true; + } + catch (e) { + const msg = e instanceof Error ? e.message : String(e); + const retryable = /Unexpected response property/i.test(msg) || + /A request is already pending/i.test(msg) || + /request timeout/i.test(msg); + if (!retryable || Date.now() + 100 >= deadline) { + throw e; + } + await new Promise((resolve) => setTimeout(resolve, 100)); + } + } + return false; + } + async connectWithRetry(opts = {}) { + const { bootstrapTimeoutMs = 3000, pairingBootstrapTimeoutMs = 45000, maxRetries = 2, retrySettleMs = 250, retryOnUnexpectedProperty = true, onRetry = null, ...connectOpts } = opts; + const clampedDefaultTimeoutMs = Math.max(1000, Math.trunc(bootstrapTimeoutMs)); + const clampedPairingTimeoutMs = Math.max(clampedDefaultTimeoutMs, Math.trunc(pairingBootstrapTimeoutMs)); + const clampedMaxRetries = Math.max(0, Math.trunc(maxRetries)); + let lastError = null; + this._connectCancelRequested = false; + for (let attempt = 0; attempt <= clampedMaxRetries; attempt += 1) { + if (this._connectCancelRequested) { + throw new Error(CONNECT_CANCELLED_MESSAGE); + } + const attemptTimeoutMs = clampedDefaultTimeoutMs; + this._bootstrapRequestTimeoutOverrideMs = attemptTimeoutMs; + try { + return await this.connect(connectOpts); + } + catch (e) { + lastError = e; + // An explicit disconnect() during the attempt is a user cancel, not a + // transient link drop — tear down and stop retrying. + if (this._connectCancelRequested) { + await this._cleanupFailedBleConnectAttempt(retrySettleMs); + throw new Error(CONNECT_CANCELLED_MESSAGE, { cause: e }); + } + const msg = e instanceof Error ? e.message : String(e); + const isRequestTimeout = /request timeout/i.test(msg); + const isGattDisconnected = /gatt server is disconnected/i.test(msg); + const isUnexpectedResponseProperty = retryOnUnexpectedProperty && /Unexpected response property/i.test(msg); + const shouldRetry = (isRequestTimeout || isGattDisconnected || isUnexpectedResponseProperty) && + attempt < clampedMaxRetries; + if (!shouldRetry) { + await this._cleanupFailedBleConnectAttempt(retrySettleMs); + throw e; + } + // If pairing/passkey entry is still in progress, a request timeout can occur + // while the BLE link itself remains up. In that case, retry bootstrap in-place + // first to avoid forcing a disconnect that interrupts Windows bonding UX. + if (isRequestTimeout && this.device?.gatt?.connected && this.tx && this.rx) { + onRetry?.({ + attempt, + maxRetries: clampedMaxRetries, + bootstrapTimeoutMs: attemptTimeoutMs, + nextBootstrapTimeoutMs: clampedPairingTimeoutMs, + reason: 'request-timeout', + error: msg, + }); + try { + await this._retryBootstrapInPlaceWithBudget(clampedPairingTimeoutMs, clampedDefaultTimeoutMs); + return true; + } + catch (bootstrapRetryError) { + if (this._connectCancelRequested) { + await this._cleanupFailedBleConnectAttempt(retrySettleMs); + throw new Error(CONNECT_CANCELLED_MESSAGE, { cause: bootstrapRetryError }); + } + lastError = bootstrapRetryError; + } + } + let reason; + if (isRequestTimeout) { + reason = 'request-timeout'; + } + else if (isGattDisconnected) { + reason = 'gatt-disconnected'; + } + else { + reason = 'unexpected-response-property'; + } + onRetry?.({ + attempt, + maxRetries: clampedMaxRetries, + bootstrapTimeoutMs: attemptTimeoutMs, + nextBootstrapTimeoutMs: clampedPairingTimeoutMs, + reason, + error: msg, + }); + await this._cleanupFailedBleConnectAttempt(retrySettleMs); + } + finally { + this._bootstrapRequestTimeoutOverrideMs = null; + } + } + throw lastError instanceof Error ? lastError : new Error('BLE connect failed'); + } + // --- Web Serial (USB COM port) connect --- + async connectSerial(opts = {}) { + if (!('serial' in navigator)) { + throw new Error('Web Serial not supported. Use Chrome/Edge on HTTPS or http://localhost.'); + } + if (this._transportKind === 'ble' && this.device?.gatt?.connected) { + await this.disconnect(); + } + else if (this._transportKind === 'serial' && this.port) { + await this.disconnect(); + } + this._transportKind = 'serial'; + this._mode = 'idle'; + this._resetAssembler(); + const serial = navigator.serial; + if (!opts.port) { + opts.port = await serial.requestPort(opts.filters ? { filters: opts.filters } : undefined); + } + this.port = opts.port; + await this.port.open({ + baudRate: opts.baudRate ?? 115200, + dataBits: opts.dataBits ?? 8, + stopBits: opts.stopBits ?? 1, + parity: opts.parity ?? 'none', + flowControl: opts.flowControl ?? 'none', + }); + this._serialAbort = new AbortController(); + this._startSerialReadLoop(this._serialAbort.signal); + this._emitStatus('Connected via USB Serial'); + this.emit('connected', { kind: 'serial' }); + await this._bootstrapConfigsAfterConnect(); + return true; + } + async _serialWrite(u8) { + const writable = this.port.writable; + if (!writable) + throw new Error('Not connected'); + const writer = writable.getWriter(); + try { + await writer.write(u8); + } + finally { + writer.releaseLock(); + } + } + _startSerialReadLoop(signal) { + const port = this.port; + this._serialReadLoopTask = (async () => { + let reader = null; + try { + const readable = port.readable; + if (!readable) + return; + reader = readable.getReader(); + this._serialReader = reader; + while (!signal.aborted) { + const { value, done } = await reader.read(); + if (done) + break; + if (value?.length) + this._feedStreamBytes(new Uint8Array(value)); + } + } + catch (e) { + if (!signal.aborted) + console.warn('[serial] read loop error:', e); + } + finally { + try { + reader?.releaseLock?.(); + } + catch { + /* ignore */ + } + if (this._serialReader === reader) + this._serialReader = null; + this._serialReadLoopTask = null; + if (!signal.aborted) { + this._mode = 'idle'; + this.emit('disconnected', { kind: 'serial' }); + } + } + })(); + } + async _serialDisconnect(reason = 'user') { + try { + this._serialAbort?.abort(); + } + catch { + /* ignore */ + } + const cancelActiveReader = async () => { + const r = this._serialReader; + if (!r) + return false; + try { + await r.cancel(); + } + catch { + /* ignore */ + } + try { + r.releaseLock(); + } + catch { + /* ignore */ + } + if (this._serialReader === r) + this._serialReader = null; + return true; + }; + await cancelActiveReader(); + const portReadableLocked = this.port + ?.readable?.locked; + if (portReadableLocked && !this._serialReader) { + for (let i = 0; i < 10; i++) { + await new Promise((r) => setTimeout(r, 20)); + if (await cancelActiveReader()) + break; + } + } + try { + const task = this._serialReadLoopTask; + if (task) + await Promise.race([task, new Promise((r) => setTimeout(r, 750))]); + } + catch { + /* ignore */ + } + try { + const writable = this.port?.writable; + if (writable?.locked) { + const w = writable.getWriter(); + try { + await w.abort?.(); + } + catch { + /* ignore */ + } + try { + w.releaseLock(); + } + catch { + /* ignore */ + } + } + } + catch { + /* ignore */ + } + try { + await this.port?.close?.(); + } + catch { + /* ignore */ + } + this.port = null; + this._serialAbort = null; + this._serialReader = null; + this._serialReadLoopTask = null; + console.warn(`[serial] disconnect done reason=${reason}`); + } + async disconnect(opts = {}) { + // If a connectWithRetry() loop is mid-attempt, this explicit disconnect + // must stop it from retrying with the same device. connect() clears the + // flag when the next fresh connect starts. + this._connectCancelRequested = true; + const kind = this._transportKind === 'serial' ? 'serial' : 'ble'; + if (this._mode === 'streaming') { + try { + await this.stopStreaming(); + } + catch { + /* ignore */ + } + } + if (this._sync) { + try { + this._abortSync(new Error(opts.reason ?? 'Disconnected')); + } + catch { + /* ignore */ + } + } + if (this._transportKind === 'serial') { + try { + await this._serialDisconnect(opts.reason ?? 'user'); + } + catch { + /* ignore */ + } + } + else { + // Best-effort courtesy notification; swallow the rejection when the BLE + // transport is not up (e.g. disconnect clicked mid-connect, tx not set). + void this.writeBytes(buildMessage(ASM_COMMAND.WRITE, ASM_PROPERTY.DEVICE_DISCONNECT), { + withResponse: false, + }).catch(() => { }); + try { + if (this.rx) + await this.rx.stopNotifications?.(); + } + catch { + /* ignore */ + } + try { + if (this._onGattDisconnected && this.device) { + this.device.removeEventListener('gattserverdisconnected', this._onGattDisconnected); + } + } + catch { + /* ignore */ + } + try { + if (this.device?.gatt?.connected) + this.device.gatt.disconnect(); + } + catch { + /* ignore */ + } + } + this._mode = 'idle'; + this._transportKind = null; + this.port = null; + this._serialAbort = null; + this.tx = this.rx = null; + this.service = this.server = this.device = null; + this.emit('disconnected', { kind }); + return true; + } + // --------------------------------------------------------------------------- + // Streaming + // --------------------------------------------------------------------------- + async startStreaming() { + // Clear live throughput / packet-loss stats for the new streaming session. + this._streamStats.reset(); + this._lastStreamStatsEmitMillis = 0; + await this.setStreamingMode(true); + this._mode = 'streaming'; + this.emit('streaming', { on: true }); + } + async stopStreaming() { + // Stop is best-effort. The application-level ACK for STREAM_MODE-disable rides + // on BLE notifications, which are unacknowledged and can be dropped under + // high-throughput streaming; the in-flight stream tail is also parsed by the + // command path (not the CRC-gated stream scanner) once we leave streaming + // mode, so the small ACK frame is easily lost or mis-framed. We confirm + // delivery of the disable command via a write-with-response, then reconcile + // local state regardless — a missing ACK must never leave the client wedged + // in 'streaming' (which locks the UI). This mirrors the best-effort stop used + // by Shimmer3RClient and the DEVICE_DISCONNECT path in disconnect(). + try { + await this.writeBytes(buildMessage(ASM_COMMAND.WRITE, ASM_PROPERTY.STREAM_MODE, [STREAM_MODE.DISABLE]), { withResponse: true }); + } + catch (e) { + this._log('stopStreaming: disable write failed; reconciling state anyway:', e); + } + finally { + this._mode = 'idle'; + this._resetAssembler(); + this.emit('streaming', { on: false }); + } + } + // --------------------------------------------------------------------------- + // Logged data transfer + // --------------------------------------------------------------------------- + async transferLoggedData(opts = {}) { + const { fileHandle = null, timeoutMs = 1000, maxNack = 5, maxCrcNack = 5, onProgress = null, } = opts; + const bleOk = !!(this.rx && this.tx); + const serOk = !!this.port; + if (!bleOk && !serOk) + throw new Error('Not connected'); + if (this._mode === 'streaming') + throw new Error('Stop streaming before TransferLoggedData'); + if (this._mode === 'logged') + throw new Error('Already syncing logged data'); + let writable = null; + const chunks = []; + if (fileHandle) + writable = await fileHandle.createWritable(); + this._mode = 'logged'; + this._resetAssembler(); + this._loggedChain = Promise.resolve(); + this._syncRxCount = 0; + this._syncPayloadCount = 0; + const sync = { + receiving: true, + lastReply: 'NONE', + emptyAckCount: 0, + nackCount: 0, + nackCrcCount: 0, + maxNack, + maxCrcNack, + lastRxAt: Date.now(), + timeoutMs, + bytesWritten: 0, + lastPayloadIndex: 0, + resolve: null, + reject: null, + timer: null, + writable, + chunks, + onProgress: onProgress ?? null, + }; + this._sync = sync; + const donePromise = new Promise((resolve, reject) => { + sync.resolve = resolve; + sync.reject = reject; + }); + let watchdogRunning = false; + sync.timer = setInterval(async () => { + if (watchdogRunning) + return; + watchdogRunning = true; + try { + if (!this._sync?.receiving) + return; + const age = Date.now() - this._sync.lastRxAt; + if (age < this._sync.timeoutMs) + return; + try { + if (this._sync.lastReply === 'NONE') { + await this.writeBytes(buildMessage(ASM_COMMAND.READ, ASM_PROPERTY.DATA), { + withResponse: true, + }); + } + else { + this._clearSyncRxBuffers('timeout-nack'); + await this.writeBytes(buildMessage(ASM_COMMAND.NACK_GENERIC, ASM_PROPERTY.DATA)); + this._sync.nackCount++; + this._sync.lastReply = 'NACK'; + if (this._sync.nackCount >= this._sync.maxNack) + throw new Error('Too many NACK timeouts'); + } + this._sync.lastRxAt = Date.now(); + } + catch (e) { + this._abortSync(e instanceof Error ? e : new Error(String(e))); + } + } + finally { + watchdogRunning = false; + } + }, Math.max(250, Math.floor(timeoutMs / 2))); + try { + await this.writeBytes(buildMessage(ASM_COMMAND.READ, ASM_PROPERTY.DATA), { + withResponse: true, + }); + const result = await donePromise; + await (this._loggedChain ?? Promise.resolve()); + if (!fileHandle) { + const blob = new Blob(chunks.map(toArrayBuffer), { type: 'application/octet-stream' }); + return { ...result, blob }; + } + return result; + } + finally { + if (sync.timer) { + clearInterval(sync.timer); + sync.timer = null; + } + if (writable) + await writable.close(); + } + } + // --------------------------------------------------------------------------- + // Request / response helpers + // --------------------------------------------------------------------------- + async writeBytes(bytes, opts = {}) { + const u8 = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes); + if (this._transportKind === 'serial') { + await this._serialWrite(u8); + return; + } + if (!this.tx) + throw new Error('Not connected'); + if (opts.withResponse) { + await this.tx.writeValue(toArrayBuffer(u8)); + return; + } + const txExt = this.tx; + if (txExt.writeValueWithoutResponse) { + await txExt.writeValueWithoutResponse(toArrayBuffer(u8)); + } + else { + await this.tx.writeValue(toArrayBuffer(u8)); + } + } + async _requestByCommand(command, property, payloadBytes = [], timeoutMs = 3000, acceptedCommands, acceptedProperties) { + if (this._pending) + throw new Error('A request is already pending'); + this._mode = 'command'; + this._resetAssembler(); + const req = buildMessage(command, property, payloadBytes); + const accepted = acceptedCommands ?? defaultAcceptedCommands(command); + const pendingPromise = new Promise((resolve, reject) => { + const t = setTimeout(() => { + this._pending = null; + reject(new Error('Request timeout')); + }, timeoutMs); + this._pending = { + expectedProperty: property, + acceptedCommands: accepted, + acceptedProperties, + resolve: (resp) => { + clearTimeout(t); + this._pending = null; + resolve(resp); + }, + reject: (e) => { + clearTimeout(t); + this._pending = null; + reject(e); + }, + }; + }); + await this.writeBytes(req); + return pendingPromise; + } + async readProperty(property, timeoutMs = 3000) { + return this._requestByCommand(ASM_COMMAND.READ, property, [], timeoutMs); + } + async writeProperty(property, payloadBytes = [], timeoutMs = 3000) { + return this._requestByCommand(ASM_COMMAND.WRITE, property, payloadBytes, timeoutMs); + } + async request(opcode, payloadBytes = [], timeoutMs = 3000) { + const { command, property } = parseHeader(opcode & 0xff); + const effectiveTimeoutMs = this._bootstrapRequestTimeoutOverrideMs != null && timeoutMs === 3000 + ? this._bootstrapRequestTimeoutOverrideMs + : timeoutMs; + const rsp = await this._requestByCommand(command, property, payloadBytes, effectiveTimeoutMs); + return { payload: rsp.payload }; + } + // Convenience command methods (all protocol properties) + readStatus() { + return this.request(ASM_COMMAND.READ | ASM_PROPERTY.STATUS1); + } + async readStatusParsed() { + const { payload } = await this.readStatus(); + return parseStatusPayload(payload, 'status1'); + } + readStatus2() { + return this.request(ASM_COMMAND.READ | ASM_PROPERTY.STATUS2); + } + async readStatus2Parsed() { + const { payload } = await this.readStatus2(); + return parseStatusPayload(payload, 'status2'); + } + readData() { + return this.request(ASM_COMMAND.READ | ASM_PROPERTY.DATA); + } + readProductionConfig() { + return this.request(ASM_COMMAND.READ | ASM_PROPERTY.PRODUCTION_CONFIGURATION); + } + readOperationalConfig() { + return this.request(ASM_COMMAND.READ | ASM_PROPERTY.OPERATIONAL_CONFIGURATION); + } + readTime() { + return this.request(ASM_COMMAND.READ | ASM_PROPERTY.TIME); + } + async readTimeUnixSeconds() { + const { payload } = await this.readTime(); + return asmRtcBytesToUnixSeconds(payload); + } + readPendingEvents() { + return this.request(ASM_COMMAND.READ | ASM_PROPERTY.PENDING_EVENTS); + } + async readPendingEventsParsed() { + const { payload } = await this.readPendingEvents(); + return parsePendingEvents(payload); + } + async writeProductionConfig(bytes) { + const payload = normalizeBytePayload(bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes)); + if (!payload || payload.length < 11 || payload.length > 56) { + throw new Error('writeProductionConfig: payload length must be between 11 and 56 bytes'); + } + await this.writeProperty(ASM_PROPERTY.PRODUCTION_CONFIGURATION, payload); + } + async writeOperationalConfig(bytes) { + const payload = normalizeBytePayload(bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes)); + if (!payload || payload.length < 50) { + throw new Error('writeOperationalConfig: payload length must be at least 50 bytes'); + } + // Safety interlock (mirrors firmware): never write a config with both + // Bluetooth and USB disabled, or the device becomes unreachable for + // reconfiguration. Apply to a copy so the caller's buffer is left untouched + // (normalizeBytePayload returns the input reference for a Uint8Array). + const corrected = new Uint8Array(payload); + enforceVerisenseCommsChannelInterlock(corrected); + await this.writeProperty(ASM_PROPERTY.OPERATIONAL_CONFIGURATION, corrected); + } + async writeTime(rtc7) { + const payload = normalizeBytePayload(rtc7 instanceof Uint8Array ? rtc7 : new Uint8Array(rtc7)); + if (!payload || payload.length !== 7) { + throw new Error('writeTime: payload must be exactly 7 bytes'); + } + await this.writeProperty(ASM_PROPERTY.TIME, payload); + } + async writeTimeUnixSeconds(unixSeconds) { + await this.writeTime(unixSecondsToAsmRtcBytes(unixSeconds)); + } + /** + * Request the Verisense firmware to expose the Nordic Secure DFU service. + * + * Writes the ASM `DFU_MODE` property. The firmware treats this as a request + * to enable the buttonless DFU service but does NOT reboot or expose the + * service immediately — it enables it on the next BLE disconnect. The host + * must therefore disconnect and reconnect before the Nordic DFU service (and + * {@link rebootToDfuBootloader}) become available on the connection. + */ + async enableDfuServiceOnNextDisconnect() { + await this.writeProperty(ASM_PROPERTY.DFU_MODE, []); + } + /** + * Reboot the device straight into the Nordic Secure DFU bootloader using the + * buttonless DFU service. + * + * Requires the Nordic DFU service to already be active on the current BLE + * connection — call {@link enableDfuServiceOnNextDisconnect}, then disconnect + * and reconnect first. Writes the "Enter Bootloader" op-code (0x01) to the + * buttonless DFU control-point characteristic; the device acknowledges via an + * indication, then disconnects and resets into the bootloader. + * + * @param options.waitForDisconnect Resolve only once the device drops the + * link (i.e. has begun rebooting). Default `true`. + * @param options.disconnectAfterCommand Force a local GATT disconnect if the + * device has not dropped the link itself. Default `true`. + * @param options.timeoutMs Max time to wait for the device to + * disconnect after the command. Default `10000`. + */ + async rebootToDfuBootloader(options = {}) { + const { waitForDisconnect = true, disconnectAfterCommand = true, timeoutMs = 10000 } = options; + if (this._transportKind !== 'ble' || !this.server || !this.device?.gatt?.connected) { + throw new Error('rebootToDfuBootloader: requires an active BLE connection'); + } + let dfuService; + try { + dfuService = await this.server.getPrimaryService(NORDIC_DFU_SERVICE); + } + catch { + throw new Error('rebootToDfuBootloader: Nordic DFU service is not present on this connection. ' + + 'Call enableDfuServiceOnNextDisconnect(), then disconnect and reconnect first.'); + } + // The buttonless control point lives under one of two UUIDs depending on + // whether the firmware shares its bonds with the bootloader. + let controlPoint = null; + for (const uuid of [NORDIC_DFU_BUTTONLESS_WITHOUT_BONDS, NORDIC_DFU_BUTTONLESS_WITH_BONDS]) { + try { + controlPoint = await dfuService.getCharacteristic(uuid); + break; + } + catch { + /* try the next variant */ + } + } + if (!controlPoint) { + throw new Error('rebootToDfuBootloader: buttonless DFU control-point characteristic not found'); + } + // Start watching for the disconnect before issuing the command so we never + // miss the event if the device reboots immediately. + const disconnected = waitForDisconnect ? this._waitForGattDisconnect(timeoutMs) : null; + // The buttonless control point delivers its response via indications; + // subscribe so the firmware sends it before resetting. Some stacks reject a + // duplicate subscription — the command write below still succeeds. + try { + await controlPoint.startNotifications(); + } + catch { + /* ignore — indication subscription is best-effort */ + } + const cp = controlPoint; + const payload = Uint8Array.from([NORDIC_DFU_OP_ENTER_BOOTLOADER]); + if (cp.writeValueWithResponse) { + await cp.writeValueWithResponse(toArrayBuffer(payload)); + } + else { + await cp.writeValue(toArrayBuffer(payload)); + } + if (disconnected) { + const didDisconnect = await disconnected; + if (!didDisconnect && disconnectAfterCommand && this.device?.gatt?.connected) { + try { + this.device.gatt.disconnect(); + } + catch { + /* ignore */ + } + } + } + else if (disconnectAfterCommand && this.device?.gatt?.connected) { + try { + this.device.gatt.disconnect(); + } + catch { + /* ignore */ + } + } + } + /** + * Resolve when the BLE link drops (`gattserverdisconnected`), or after + * `timeoutMs`. Resolves `true` if the device disconnected, `false` on timeout. + */ + _waitForGattDisconnect(timeoutMs) { + const device = this.device; + if (!device || !device.gatt?.connected) + return Promise.resolve(true); + return new Promise((resolve) => { + let settled = false; + const onDisconnect = () => finish(true); + const finish = (didDisconnect) => { + if (settled) + return; + settled = true; + clearTimeout(timer); + try { + device.removeEventListener('gattserverdisconnected', onDisconnect); + } + catch { + /* ignore */ + } + resolve(didDisconnect); + }; + const timer = setTimeout(() => finish(false), Math.max(0, timeoutMs)); + device.addEventListener('gattserverdisconnected', onDisconnect); + }); + } + async runTestMode(testPayload) { + const payload = normalizeBytePayload(testPayload instanceof Uint8Array ? testPayload : new Uint8Array(testPayload)); + if (!payload || payload.length < 2) { + throw new Error('runTestMode: payload must contain at least [testId, hwMajor]'); + } + await this.writeProperty(ASM_PROPERTY.TEST_MODE, payload); + } + async runHardwareTest(testId, hwMajor, hwMinor = 0, hwInternal = 0) { + const payload = new Uint8Array([ + testId & 0xff, + hwMajor & 0xff, + hwMinor & 0xff, + hwInternal & 0xff, + (hwInternal >> 8) & 0xff, + ]); + await this.runTestMode(payload); + } + /** + * Ask the device to stop/exit any running test, including an in-progress + * hardware test report (TEST_MODE "exit", id 0x00). The firmware acts on this + * from interrupt context, so it aborts the blocking report promptly instead of + * running it to completion against a connection no one is reading. Best-effort + * and safe to call when no test is running. + */ + async stopTestMode(hwMajor = 0, hwMinor = 0, hwInternal = 0) { + await this.runTestMode([ + 0x00, + hwMajor & 0xff, + hwMinor & 0xff, + hwInternal & 0xff, + (hwInternal >> 8) & 0xff, + ]); + } + async runHardwareTestReport(hwMajor, hwMinor = 0, hwInternal = 0, opts = {}) { + const timeoutMs = Math.max(1000, Math.trunc(opts.timeoutMs ?? 120000)); + const completionIdleMs = Math.max(100, Math.trunc(opts.completionIdleMs ?? 1200)); + const marker = String(opts.marker ?? '').trim(); + const endMarker = String(opts.endMarker ?? + (marker.includes('TEST START') ? marker.replace('TEST START', 'TEST END') : '')).trim(); + const factoryTestType = Math.max(0, Math.min(0xff, Math.trunc(opts.factoryTestType ?? 0))); + const abortSignal = opts.signal ?? null; + const onChunk = typeof opts.onChunk === 'function' ? opts.onChunk : null; + const TEST_REPORT_MODE_ID = 0xfe; + const payload = new Uint8Array([ + TEST_REPORT_MODE_ID, + hwMajor & 0xff, + hwMinor & 0xff, + hwInternal & 0xff, + (hwInternal >> 8) & 0xff, + factoryTestType & 0xff, + ]); + return new Promise((resolve, reject) => { + let done = false; + let aggregate = ''; + let decoder; + try { + decoder = new TextDecoder('latin1'); + } + catch { + decoder = new TextDecoder(); + } + let sawMarker = marker.length === 0; + const effectiveIdleMs = Math.max(completionIdleMs, 10000); + let idleTimer = null; + let timeoutTimer = null; + let off = null; + let onAbort = null; + const sanitizeChunk = (text) => { + // Drop control bytes that occasionally appear in factory stream noise + // while preserving CR/LF/TAB for report formatting. + // eslint-disable-next-line no-control-regex -- intentionally strips binary control bytes + return text.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]/g, ''); + }; + const cleanup = () => { + this._testReportMode = false; + if (off) { + try { + off(); + } + catch { + /* ignore */ + } + off = null; + } + if (idleTimer) { + clearTimeout(idleTimer); + idleTimer = null; + } + if (timeoutTimer) { + clearTimeout(timeoutTimer); + timeoutTimer = null; + } + if (abortSignal && onAbort) { + try { + abortSignal.removeEventListener('abort', onAbort); + } + catch { + /* ignore */ + } + onAbort = null; + } + }; + const finish = (err) => { + if (done) + return; + done = true; + cleanup(); + if (err) { + // Best-effort: tell the device to stop the in-progress test/report so it + // doesn't keep running a blocking suite against a connection no one is + // reading (dialog closed / aborted / timed out). The firmware acts on + // this from interrupt context, so the report aborts promptly. + void this.stopTestMode(hwMajor, hwMinor, hwInternal).catch(() => { }); + reject(err); + return; + } + const tail = decoder.decode(); + if (tail) { + aggregate += tail; + } + resolve(aggregate); + }; + const scheduleIdleFinish = () => { + if (idleTimer) + clearTimeout(idleTimer); + idleTimer = setTimeout(() => { + if (!sawMarker) + return; + finish(); + }, effectiveIdleMs); + }; + off = this.on('testReportChunk', (rawChunk) => { + if (done || !rawChunk?.length) + return; + const chunk = sanitizeChunk(decoder.decode(rawChunk, { stream: true })); + if (!chunk.length) + return; + aggregate += chunk; + if (!sawMarker && marker.length > 0 && aggregate.includes(marker)) { + sawMarker = true; + } + const sawEndMarker = (endMarker.length > 0 && aggregate.includes(endMarker)) || /TEST END/.test(aggregate); + if (sawEndMarker) { + finish(); + return; + } + if (onChunk) { + try { + onChunk(chunk, aggregate); + } + catch { + /* ignore callback errors */ + } + } + if (sawMarker) { + scheduleIdleFinish(); + } + }); + timeoutTimer = setTimeout(() => { + finish(new Error(`runHardwareTestReport timeout after ${timeoutMs} ms while waiting for report data`)); + }, timeoutMs); + if (abortSignal) { + if (abortSignal.aborted) { + finish(new Error('runHardwareTestReport aborted')); + return; + } + onAbort = () => finish(new Error('runHardwareTestReport aborted')); + abortSignal.addEventListener('abort', onAbort, { once: true }); + } + // Enable test report mode before sending command + this._testReportMode = true; + void this.runTestMode(payload).catch((e) => { + const msg = e instanceof Error ? e.message : String(e); + finish(new Error(`runHardwareTestReport failed to start test mode: ${msg}`)); + }); + }); + } + _buildDebugPayload(debugId, args = []) { + const argBytes = args instanceof Uint8Array ? args : new Uint8Array(args); + const payload = new Uint8Array(1 + argBytes.length); + payload[0] = debugId & 0xff; + payload.set(argBytes, 1); + return payload; + } + _debugIndexArgs(index) { + const i = Math.max(0, Math.min(0xff, Math.trunc(index))); + return i > 0 ? [i] : []; + } + _waitForDebugResponse(timeoutMs = 3000) { + return new Promise((resolve, reject) => { + let done = false; + let off = null; + let timer = null; + const cleanup = () => { + if (off) { + try { + off(); + } + catch { + /* ignore */ + } + off = null; + } + if (timer) { + clearTimeout(timer); + timer = null; + } + }; + off = this.on('commandPayload', (evt) => { + if (done || !evt) + return; + if (evt.command !== ASM_COMMAND.RESPONSE || evt.property !== ASM_PROPERTY.DEBUG_COMMAND) + return; + done = true; + cleanup(); + resolve({ payload: evt.payload ?? new Uint8Array(0) }); + }); + timer = setTimeout(() => { + if (done) + return; + done = true; + cleanup(); + reject(new Error('Debug response timeout')); + }, timeoutMs); + }); + } + async readDebugCommand(debugId, args = [], timeoutMs = 3000) { + const payload = this._buildDebugPayload(debugId, args); + const debugAcceptedProps = new Set([ASM_PROPERTY.DEBUG_COMMAND, 0]); + // Python flow: WRITE DEBUG command, optional empty/transient frame, then RESPONSE DEBUG payload. + const responsePromise = this._waitForDebugResponse(timeoutMs); + try { + await this._requestByCommand(ASM_COMMAND.WRITE, ASM_PROPERTY.DEBUG_COMMAND, payload, timeoutMs, undefined, debugAcceptedProps); + return await responsePromise; + } + catch (e) { + void responsePromise.catch(() => { }); + const msg = e instanceof Error ? e.message : String(e); + const isDebugNack = /NACK command=0x(?:50|60|70) property=0x9/i.test(msg); + const isDebugAckPropertyZero = /Unexpected response property 0x0 \(expected 0x9\)/i.test(msg); + if (isDebugNack || isDebugAckPropertyZero) { + return this._waitForDebugResponse(timeoutMs); + } + throw e; + } + } + async sendDebugCommand(debugId, args = [], timeoutMs = 3000) { + const rsp = await this._requestByCommand(ASM_COMMAND.WRITE, ASM_PROPERTY.DEBUG_COMMAND, this._buildDebugPayload(debugId, args), timeoutMs); + return { payload: rsp.payload }; + } + /** + * Stream a MAX32674C algorithm-hub firmware image (.msbl) to the device and + * flash it into the hub via the Maxim bootloader. This is a one-time factory + * operation: it blocks the device for ~1-2 minutes while the hub flash is + * erased and each page is written. Only SR68 Pulse+ hardware (the only board + * carrying the hub) accepts it — other hardware NACKs the BEGIN stage. + * + * @param msbl raw .msbl file bytes + * @param onProgress optional progress callback (pagesDone, totalPages) + * @returns the hub application firmware version string read back after flashing + */ + async uploadHubFirmware(msbl, onProgress) { + const img = msbl instanceof Uint8Array ? msbl : new Uint8Array(msbl); + if (img.length < MSBL.HEADER_SIZE) { + throw new Error('uploadHubFirmware: file is too small to be a valid .msbl'); + } + const numPages = img[MSBL.OFF_NUMPAGES] | (img[MSBL.OFF_NUMPAGES + 1] << 8); + const expectedLen = MSBL.HEADER_SIZE + numPages * MSBL.PAGE_FILE_BYTES; + if (numPages === 0 || img.length < expectedLen) { + throw new Error(`uploadHubFirmware: invalid .msbl (pages=${numPages}, length=${img.length}, expected>=${expectedLen})`); + } + // BEGIN: device enters bootloader, programs IV/auth/page-count, erases flash. + try { + await this._requestByCommand(ASM_COMMAND.WRITE, ASM_PROPERTY.DEBUG_COMMAND, this._buildHubUploadPayload(HUB_FW_UPLOAD_STAGE.BEGIN, img.subarray(0, MSBL.HEADER_SIZE)), 15000); + } + catch (e) { + throw new Error(`Hub FW upload BEGIN failed: ${e instanceof Error ? e.message : String(e)}`, { + cause: e, + }); + } + // Pages: stream each page in order, awaiting ACK_NEXT_STAGE (page flashed). + const MAX_PAGE_RETRIES = 5; + for (let page = 0; page < numPages; page++) { + const base = MSBL.HEADER_SIZE + page * MSBL.PAGE_FILE_BYTES; + const pageBytes = img.subarray(base, base + MSBL.PAGE_FILE_BYTES); + let attempt = 0; + for (;;) { + try { + await this._sendHubPage(page, pageBytes); + break; + } + catch (e) { + if (++attempt >= MAX_PAGE_RETRIES) { + await this._abortHubUpload(); + throw new Error(`Hub FW upload failed at page ${page + 1}/${numPages} after ${attempt} attempts: ${e instanceof Error ? e.message : String(e)}`, { cause: e }); + } + } + } + onProgress?.(page + 1, numPages); + } + // END: device resets the hub to application mode and returns its FW version. + const endRsp = await this._requestByCommand(ASM_COMMAND.WRITE, ASM_PROPERTY.DEBUG_COMMAND, this._buildHubUploadPayload(HUB_FW_UPLOAD_STAGE.END), 8000); + return new TextDecoder().decode(endRsp.payload).replace(/\0+$/, '').trim(); + } + /** Build a debug payload `[HUB_FW_UPLOAD, stage, ...stageArgs]`. */ + _buildHubUploadPayload(stage, stageArgs = []) { + const a = stageArgs instanceof Uint8Array ? stageArgs : new Uint8Array(stageArgs); + const staged = new Uint8Array(1 + a.length); + staged[0] = stage & 0xff; + staged.set(a, 1); + return this._buildDebugPayload(DEBUG_COMMAND_ID.HUB_FW_UPLOAD, staged); + } + /** Send one 8208-byte page as in-order <=64-byte chunks; await ACK_NEXT_STAGE. */ + async _sendHubPage(page, pageBytes) { + const CHUNK = 64; // keep each packet within the device's ~96-byte RX buffer + const total = pageBytes.length; + for (let off = 0; off < total; off += CHUNK) { + const end = Math.min(off + CHUNK, total); + const isFinal = end >= total; + const args = new Uint8Array(4 + (end - off)); + args[0] = page & 0xff; + args[1] = (page >> 8) & 0xff; + args[2] = off & 0xff; + args[3] = (off >> 8) & 0xff; + args.set(pageBytes.subarray(off, end), 4); + const payload = this._buildHubUploadPayload(HUB_FW_UPLOAD_STAGE.PAGE_CHUNK, args); + if (isFinal) { + // Final chunk completes the page; the device flashes it (~0.7 s) and + // replies ACK_NEXT_STAGE (or NACK on failure -> throws -> page retry). + await this._requestByCommand(ASM_COMMAND.WRITE, ASM_PROPERTY.DEBUG_COMMAND, payload, 6000); + } + else { + // Mid-page chunk: reliable, in-order delivery via write-with-response, + // with no application-level reply from the device. + await this.writeBytes(buildMessage(ASM_COMMAND.WRITE, ASM_PROPERTY.DEBUG_COMMAND, payload), { + withResponse: true, + }); + } + } + } + /** Best-effort abort: tell the device to reset the hub back to application mode. */ + async _abortHubUpload() { + try { + await this._requestByCommand(ASM_COMMAND.WRITE, ASM_PROPERTY.DEBUG_COMMAND, this._buildHubUploadPayload(HUB_FW_UPLOAD_STAGE.ABORT), 5000); + } + catch { + /* best effort */ + } + } + /** Read the flash lookup table. The read walks the whole flash on-device + * and can time out on busy sensors, so `retries` re-issues the command + * (total attempts = retries + 1) before giving up. Non-finite or negative + * `retries` is treated as 0; rejections are always `Error` instances. */ + async readFlashLookupTable(index = 0, timeoutMs = 12000, retries = 0) { + const extraAttempts = Number.isFinite(retries) ? Math.max(0, Math.trunc(retries)) : 0; + let lastError = null; + for (let attempt = 0; attempt <= extraAttempts; attempt++) { + try { + return await this.readDebugCommand(DEBUG_COMMAND_ID.FLASH_LOOKUP_TABLE_READ, this._debugIndexArgs(index), timeoutMs); + } + catch (e) { + lastError = e; + } + } + if (lastError instanceof Error) + throw lastError; + throw new Error(lastError == null ? 'readFlashLookupTable: read failed' : String(lastError)); + } + async readRealWorldClockScheduler(index = 0) { + return this.readDebugCommand(DEBUG_COMMAND_ID.RWC_SCHEDULER_READ, this._debugIndexArgs(index)); + } + async readRealWorldClockSchedulerParsed(index = 0) { + const { payload } = await this.readRealWorldClockScheduler(index); + return parseSchedulerDebugPayload(payload); + } + async loadTestLookupTable(index = 0) { + return this.readDebugCommand(DEBUG_COMMAND_ID.LOAD_TEST_LOOKUP_TABLE, this._debugIndexArgs(index)); + } + async checkPayloadCrcErrors(index = 0) { + return this.readDebugCommand(DEBUG_COMMAND_ID.CHECK_PAYLOAD_CRC_ERRORS, this._debugIndexArgs(index)); + } + async checkPayloadCrcErrorsParsed(index = 0) { + const { payload } = await this.checkPayloadCrcErrors(index); + return parsePayloadCrcErrorBankIndexes(payload); + } + async readEventLog(index = 0) { + return this.readDebugCommand(DEBUG_COMMAND_ID.READ_EVENT_LOG, this._debugIndexArgs(index)); + } + async readEventLogParsed(index = 0) { + const { payload } = await this.readEventLog(index); + return parseEventLogPayload(payload); + } + async readRecordBufferDetails(index = 0) { + return this.readDebugCommand(DEBUG_COMMAND_ID.READ_RECORD_BUFFER_DETAILS, this._debugIndexArgs(index)); + } + async readRecordBufferDetailsParsed(index = 0) { + const { payload } = await this.readRecordBufferDetails(index); + return parseRecordBufferDetailsPayload(payload); + } + async eraseOperationalConfig() { + await this.sendDebugCommand(DEBUG_COMMAND_ID.ERASE_OPERATIONAL_CONFIG); + } + async eraseProductionConfig() { + await this.sendDebugCommand(DEBUG_COMMAND_ID.ERASE_PRODUCTION_CONFIG); + } + async clearPendingEvents() { + await this.sendDebugCommand(DEBUG_COMMAND_ID.CLEAR_PENDING_EVENTS); + } + async eraseAllLoggedData(timeoutMs = 12000) { + await this.sendDebugCommand(DEBUG_COMMAND_ID.ERASE_FLASH_AND_LOOKUP_TABLE, [], timeoutMs); + } + /** + * Low-level: ask the device to saturate the BLE link with dummy data for + * `durationMs` milliseconds (debug command 0x0B). The device ACKs immediately + * and then blasts a fixed 244-byte buffer as fast as the link will accept it. + * + * This only starts the blast; it does not measure anything. Prefer + * {@link runBleThroughputTest}, which sends this command and measures the + * throughput actually received at the host. + * + * @param durationMs Blast duration in milliseconds (clamped to the protocol's 0..65535 range). + */ + async testDataTransferLoop(durationMs) { + const clamped = Math.max(0, Math.min(0xffff, Math.trunc(durationMs))); + await this.sendDebugCommand(DEBUG_COMMAND_ID.TEST_DATA_TRANSFER_LOOP, [ + clamped & 0xff, + (clamped >> 8) & 0xff, + ]); + } + /** + * Measure the maximum BLE link throughput, independent of sensor + * configuration. Asks the device to blast dummy data for `durationMs` + * (see {@link testDataTransferLoop}) and measures the goodput actually + * received at the host. + * + * The reported rate reflects device→host (notification) throughput and is + * governed by the negotiated PHY, connection interval, MTU and packets per + * connection interval — i.e. the real link, not any sensor's sample rate. + * + * The measurement finishes when the device falls silent for `idleMs` after + * the blast (or when the overall safety timeout elapses). + * + * @returns received byte/packet counts and the computed throughput. + */ + async runBleThroughputTest(opts = {}) { + const durationMs = Math.max(100, Math.min(60000, Math.trunc(opts.durationMs ?? 5000))); + const idleMs = Math.max(100, Math.min(5000, Math.trunc(opts.idleMs ?? 600))); + const overallTimeoutMs = Math.max(durationMs + 1000, Math.trunc(opts.timeoutMs ?? durationMs + 5000)); + const abortSignal = opts.signal ?? null; + const onProgress = typeof opts.onProgress === 'function' ? opts.onProgress : null; + return new Promise((resolve, reject) => { + let done = false; + let bytes = 0; + let packets = 0; + let firstByteMs = 0; + let lastByteMs = 0; + let idleTimer = null; + let timeoutTimer = null; + let off = null; + let onAbort = null; + const buildResult = () => { + const elapsedMs = packets > 1 && lastByteMs > firstByteMs ? lastByteMs - firstByteMs : durationMs; + const bps = elapsedMs > 0 ? (bytes * 1000) / elapsedMs : 0; + return { + bytesReceived: bytes, + packetsReceived: packets, + durationRequestedMs: durationMs, + elapsedMs, + throughputBytesPerSec: bps, + throughputKBps: bps / 1000, + throughputKbps: (bps * 8) / 1000, + }; + }; + const cleanup = () => { + this._throughputTestMode = false; + if (off) { + try { + off(); + } + catch { + /* ignore */ + } + off = null; + } + if (idleTimer) { + clearTimeout(idleTimer); + idleTimer = null; + } + if (timeoutTimer) { + clearTimeout(timeoutTimer); + timeoutTimer = null; + } + if (abortSignal && onAbort) { + try { + abortSignal.removeEventListener('abort', onAbort); + } + catch { + /* ignore */ + } + onAbort = null; + } + }; + const finish = (err) => { + if (done) + return; + done = true; + cleanup(); + if (err) + reject(err); + else + resolve(buildResult()); + }; + const scheduleIdleFinish = () => { + if (idleTimer) + clearTimeout(idleTimer); + idleTimer = setTimeout(() => { + // Only finish on idle once data has actually started arriving. + if (packets > 0) + finish(); + }, idleMs); + }; + off = this.on('throughputChunk', (len) => { + if (done || !len) + return; + const now = nowMillis(); + if (packets === 0) + firstByteMs = now; + lastByteMs = now; + bytes += len; + packets++; + if (onProgress) { + try { + onProgress(buildResult()); + } + catch { + /* ignore callback errors */ + } + } + scheduleIdleFinish(); + }); + // Safety net: the device stops after durationMs, so the idle gap should + // normally finish first. If it never does, finalize with what we have. + timeoutTimer = setTimeout(() => finish(), overallTimeoutMs); + if (abortSignal) { + if (abortSignal.aborted) { + finish(new Error('runBleThroughputTest aborted')); + return; + } + onAbort = () => finish(new Error('runBleThroughputTest aborted')); + abortSignal.addEventListener('abort', onAbort, { once: true }); + } + // Enable raw-count mode before sending so no blast bytes are missed. The + // ACK is consumed by the normal command path (while _pending is set); the + // dummy blast that follows is counted by the _feedStreamBytes branch. + this._throughputTestMode = true; + void this.testDataTransferLoop(durationMs).catch((e) => { + const msg = e instanceof Error ? e.message : String(e); + finish(new Error(`runBleThroughputTest failed to start: ${msg}`)); + }); + }); + } + async ledTest(ledIndex) { + await this.sendDebugCommand(DEBUG_COMMAND_ID.LED_TEST, [ledIndex & 0xff]); + } + async max86xxxLedTest(start) { + await this.sendDebugCommand(DEBUG_COMMAND_ID.MAX86XXX_LED_TEST, [start ? 0x01 : 0x00]); + } + async startPowerProfilerTest() { + await this.sendDebugCommand(DEBUG_COMMAND_ID.POWER_PROFILER_TEST); + } + async requestSystemReset() { + await this.sendDebugCommand(DEBUG_COMMAND_ID.SYSTEM_RESET); + } + async startIcPowerConsumptionTest(loopCount, stageIntervalMs) { + const clampedLoopCount = Math.max(0, Math.min(0xffff, Math.trunc(loopCount))); + const clampedStageInterval = Math.max(0, Math.min(0xffff, Math.trunc(stageIntervalMs))); + await this.sendDebugCommand(DEBUG_COMMAND_ID.IC_POWER_CONSUMPTION_TEST, [ + clampedLoopCount & 0xff, + (clampedLoopCount >> 8) & 0xff, + clampedStageInterval & 0xff, + (clampedStageInterval >> 8) & 0xff, + ]); + } + async deleteAllBonds() { + await this.sendDebugCommand(DEBUG_COMMAND_ID.DELETE_ALL_BONDS); + } + async _assertBleLinkDebugSupported() { + let parsed; + if (this.productionConfig?.length) { + if (this._isErasedBlob(this.productionConfig)) { + throw new Error('BLE link debug commands require firmware >= 1.4.23, but production config is erased.'); + } + parsed = parseProductionConfigPayload(this.productionConfig); + } + else { + parsed = await this.readProductionConfigFromDevice(); + if (this._isErasedBlob(this.productionConfig)) { + throw new Error('BLE link debug commands require firmware >= 1.4.23, but production config is erased.'); + } + } + const current = { + major: Number(parsed.revFwMajor), + minor: Number(parsed.revFwMinor), + internal: Number(parsed.revFwInternal), + }; + if (!Number.isFinite(current.major) || + !Number.isFinite(current.minor) || + !Number.isFinite(current.internal)) { + throw new Error('BLE link debug commands require firmware >= 1.4.23, but firmware version is unavailable.'); + } + const min = BLE_LINK_MIN_FW; + if (compareVerisenseFirmwareVersion(current, min) < 0) { + throw new Error(`BLE link debug commands require firmware >= ${formatVerisenseFirmwareVersion(min)} (current ${formatVerisenseFirmwareVersion(current)}).`); + } + } + async readBleLinkParams() { + await this._assertBleLinkDebugSupported(); + return this.readDebugCommand(DEBUG_COMMAND_ID.BLE_LINK_PARAMS_READ); + } + async readBleLinkParamsParsed() { + const { payload } = await this.readBleLinkParams(); + return parseBleLinkDebugPayload(payload); + } + async optimizeBleLink() { + await this._assertBleLinkDebugSupported(); + return this.readDebugCommand(DEBUG_COMMAND_ID.BLE_LINK_OPTIMIZE); + } + async optimizeBleLinkParsed() { + const { payload } = await this.optimizeBleLink(); + return parseBleLinkDebugPayload(payload); + } + _bleLinkSignature(parsed) { + return [ + parsed.attMtu, + parsed.maxDataLength, + parsed.connectionIntervalUnits, + parsed.txPhy, + parsed.rxPhy, + parsed.isConnected ? 1 : 0, + ].join('|'); + } + _bleLinkOptimizedEnough(parsed, { targetConnectionIntervalUnits, targetPhy, minDataLength, }) { + const intervalOk = parsed.connectionIntervalUnits <= targetConnectionIntervalUnits; + const phyOk = parsed.txPhy === targetPhy && parsed.rxPhy === targetPhy; + const mtuBoundDataLength = Math.max(20, (parsed.attMtu || 23) - 3); + const requiredDataLength = Math.min(minDataLength, mtuBoundDataLength); + const dataLenOk = parsed.maxDataLength >= requiredDataLength; + return intervalOk && phyOk && dataLenOk; + } + _isAbortError(error) { + if (error?.name === 'AbortError') + return true; + const msg = error instanceof Error ? error.message : String(error); + return /abort/i.test(msg); + } + _waitWithAbort(ms, signal) { + if (!Number.isFinite(ms) || ms <= 0) + return Promise.resolve(); + if (signal?.aborted) { + const err = new Error('Operation aborted'); + err.name = 'AbortError'; + return Promise.reject(err); + } + return new Promise((resolve, reject) => { + const timer = setTimeout(() => { + if (signal) + signal.removeEventListener('abort', onAbort); + resolve(); + }, ms); + const onAbort = () => { + clearTimeout(timer); + if (signal) + signal.removeEventListener('abort', onAbort); + const err = new Error('Operation aborted'); + err.name = 'AbortError'; + reject(err); + }; + if (signal) { + signal.addEventListener('abort', onAbort, { once: true }); + } + }); + } + async autoOptimizeBleLink(opts = {}) { + const startedAt = nowMillis(); + const pollIntervalMs = Math.max(100, Math.trunc(opts.pollIntervalMs ?? 700)); + const stableReadCount = Math.max(1, Math.trunc(opts.stableReadCount ?? 3)); + const maxDurationMs = Math.max(pollIntervalMs, Math.trunc(opts.maxDurationMs ?? 20000)); + const settleMode = opts.settleMode === 'stability' ? 'stability' : 'target-and-stability'; + const minSettleTimeMs = Math.max(0, Math.trunc(opts.minSettleTimeMs ?? (settleMode === 'stability' ? pollIntervalMs * 2 : 0))); + const forceOptimizeAttempts = Math.max(0, Math.trunc(opts.forceOptimizeAttempts ?? (settleMode === 'stability' ? 2 : 0))); + const targetConnectionIntervalUnits = Math.max(6, Math.trunc(opts.targetConnectionIntervalUnits ?? 6)); + const targetPhy = Math.max(1, Math.min(4, Math.trunc(opts.targetPhy ?? 2))); + const minDataLength = Math.max(20, Math.min(251, Math.trunc(opts.minDataLength ?? 251))); + const signal = opts.signal ?? null; + let iterations = 0; + let optimizeAttempts = 0; + let stableCount = 0; + let lastSignature = ''; + let lastParsed = null; + const finish = (reason) => ({ + reason, + iterations, + optimizeAttempts, + stableCount, + lastParsed, + durationMs: Math.max(0, nowMillis() - startedAt), + }); + if (this._transportKind !== 'ble') + return finish('not-ble'); + if (signal?.aborted) + return finish('aborted'); + while (nowMillis() - startedAt < maxDurationMs) { + if (signal?.aborted) + return finish('aborted'); + if (this._transportKind !== 'ble') + return finish('not-ble'); + let parsed; + try { + parsed = await this.readBleLinkParamsParsed(); + } + catch (error) { + if (this._isAbortError(error)) + return finish('aborted'); + const msg = error instanceof Error ? error.message : String(error); + if (/require firmware >=|unavailable on this firmware|firmware version is unavailable/i.test(msg)) { + return finish('unsupported'); + } + throw error; + } + iterations += 1; + lastParsed = parsed; + let signature = this._bleLinkSignature(parsed); + stableCount = signature === lastSignature ? stableCount + 1 : 1; + lastSignature = signature; + let optimizedEnough = this._bleLinkOptimizedEnough(parsed, { + targetConnectionIntervalUnits, + targetPhy, + minDataLength, + }); + if (typeof opts.onSample === 'function') { + opts.onSample({ + source: 'read', + iteration: iterations, + stableCount, + parsed, + signature, + optimizedEnough, + }); + } + const shouldOptimize = settleMode === 'stability' ? optimizeAttempts < forceOptimizeAttempts : !optimizedEnough; + if (shouldOptimize) { + try { + parsed = await this.optimizeBleLinkParsed(); + } + catch (error) { + if (this._isAbortError(error)) + return finish('aborted'); + throw error; + } + optimizeAttempts += 1; + lastParsed = parsed; + signature = this._bleLinkSignature(parsed); + stableCount = signature === lastSignature ? stableCount + 1 : 1; + lastSignature = signature; + optimizedEnough = this._bleLinkOptimizedEnough(parsed, { + targetConnectionIntervalUnits, + targetPhy, + minDataLength, + }); + if (typeof opts.onSample === 'function') { + opts.onSample({ + source: 'optimize', + iteration: iterations, + stableCount, + parsed, + signature, + optimizedEnough, + }); + } + } + const elapsedMs = Math.max(0, nowMillis() - startedAt); + const stableReady = stableCount >= stableReadCount && elapsedMs >= minSettleTimeMs; + const settleReady = settleMode === 'stability' ? stableReady : stableReady && optimizedEnough; + if (settleReady) { + return finish('stabilized'); + } + try { + await this._waitWithAbort(pollIntervalMs, signal); + } + catch (error) { + if (this._isAbortError(error)) + return finish('aborted'); + throw error; + } + } + return finish('timeout'); + } + async setStreamingMode(enabled) { + await this.writeProperty(ASM_PROPERTY.STREAM_MODE, [enabled ? STREAM_MODE.ENABLE : STREAM_MODE.DISABLE], 3000); + } + async disconnectRequest() { + try { + return await this.request(ASM_COMMAND.WRITE | ASM_PROPERTY.DEVICE_DISCONNECT, [], 1500); + } + catch (e) { + const msg = e instanceof Error ? e.message : String(e); + if (/timeout/i.test(msg)) + return { payload: new Uint8Array(0) }; + throw e; + } + } + // --------------------------------------------------------------------------- + // Operational config helpers + // --------------------------------------------------------------------------- + async getOpConfig() { + if (this.operationalConfig?.length) + return new Uint8Array(this.operationalConfig); + throw new Error('Operational config not cached. Call readOpConfigFromDevice() first.'); + } + _isErasedBlob(payload) { + return isUniformByteArray(payload, 0xff); + } + _isZeroBlob(payload) { + return isUniformByteArray(payload, 0x00); + } + _isUninitializedBlob(payload) { + return this._isErasedBlob(payload) || this._isZeroBlob(payload); + } + async readProductionConfigFromDevice() { + const rsp = await this.readProductionConfig(); + const prod = normalizeOperationalConfig(rsp?.payload); + if (!prod?.length) + throw new Error('Invalid production config returned from device'); + const erased = this._isErasedBlob(prod); + this.productionConfig = prod; + const parsed = parseProductionConfigPayload(prod); + if (!erased && typeof parsed.revHwMajor === 'number' && typeof parsed.revHwMinor === 'number') { + const hwIdentifier = parsed.revHwMajor === 62 ? 'VERISENSE_GSR_PLUS' : 'VERISENSE_PULSE_PLUS'; + this.adc.setHardwareIdentifier(hwIdentifier); + this.adc.setHardwareRevision(parsed.revHwMajor, parsed.revHwMinor, typeof parsed.revHwInternal === 'number' ? parsed.revHwInternal : 0); + this._isSecondGenerationHw = isVerisenseSecondGenerationHardware(parsed.revHwMajor, parsed.revHwMinor); + // On 2nd-gen hardware the raw PPG (id 4) is the 6-channel MAX86176 block + // drained from the hub, not the 1st-gen named-channel layout. + this.ppg.setHubMode(this._isSecondGenerationHw); + } + if (erased) { + this.emit('productionConfigErased', { raw: new Uint8Array(prod) }); + } + this.emit('productionConfig', parsed); + return parsed; + } + async readOpConfigFromDevice() { + const rsp = await this.readOperationalConfig(); + const op = normalizeOperationalConfig(rsp?.payload); + // Some firmware erase flows can return an empty payload for operational config. + // Treat this as erased (all 0xFF) instead of invalid. + if (!op?.length) { + return this._setOperationalConfigErasedFallback(); + } + if (this._isZeroBlob(op)) { + console.warn('[opcfg] operational config payload is all 0x00; treating as erased'); + return this._setOperationalConfigErasedFallback(op.length); + } + const erased = this._isErasedBlob(op); + if (!erased && op[0] !== 0x5a) { + throw new Error('Invalid operational config returned from device'); + } + this.operationalConfig = op; + if (!erased) { + try { + this.applyOperationalConfig(op); + } + catch (e) { + console.warn('[opcfg] apply after read failed:', e); + } + } + else { + this.emit('opConfigErased', { raw: new Uint8Array(op) }); + } + this.emit('opConfig', { op, erased }); + return new Uint8Array(op); + } + /** + * Push an operational config into every sensor decoder (rates, ranges, + * channel enables) and cache it as the client's working config. Used + * automatically after {@link readOpConfigFromDevice}; call it directly when + * loading a config from a template/file without a device round-trip. + */ + applyOperationalConfig(opConfigBytes) { + const op = opConfigBytes instanceof Uint8Array ? opConfigBytes : new Uint8Array(opConfigBytes); + this.operationalConfig = op; + this.accel1.applyOperationalConfig(op); + this.sensors[3].applyOperationalConfig(op); + this.sensors[6].applyOperationalConfig(op); + this.adc.applyOperationalConfig(op); + this.ppg.applyOperationalConfig(op); + this.sensors[7].applyOperationalConfig(op); + this.sensors[8].applyOperationalConfig(op); + this.sensors[9].applyOperationalConfig(op); + } + async writeOpConfig(opConfigBytes) { + const op = normalizeOperationalConfig(opConfigBytes instanceof Uint8Array ? opConfigBytes : new Uint8Array(opConfigBytes)); + if (!op || op.length < 4) + throw new Error('writeOpConfig: invalid opconfig'); + if (op[0] !== 0x5a) + throw new Error('writeOpConfig: opconfig must start with 0x5A'); + await this.writeOperationalConfig(op); + await this.readOpConfigFromDevice(); + } + /** The parsed calibration set last read via {@link readCalibrationParsed}, or null. */ + getCalibration() { + return this._calibration; + } + /** + * Read the raw calibration blob from the device (CMD_AR_CFG_CALIB). The whole + * blob (~1 KB) arrives in one response, reassembled across BLE/USB fragments. + * Requires FW v2.0.4+; older firmware NACKs or times out. + */ + async readCalibration(timeoutMs = 8000) { + const rsp = await this.readProperty(ASM_PROPERTY.CALIBRATION, timeoutMs); + const blob = rsp.payload; + if (!blob || blob.length < SC_GLOBAL_HEADER_BYTES) { + throw new Error('readCalibration: device returned no/short calibration blob'); + } + return new Uint8Array(blob); + } + /** + * Read + parse the calibration set, cache it, and push it into the IMU + * decoders so subsequent samples calibrate from per-device values. Call before + * a logged-data transfer and/or after connect (no-op on FW that lacks it — + * the call rejects and the decoders keep their full-scale fallback). + */ + async readCalibrationParsed() { + const blob = await this.readCalibration(); + const set = parseCalibrationBlob(blob); + this._calibration = set; + try { + this.accel1.applyCalibration(set); + this.sensors[6].applyCalibration(set); + } + catch (e) { + console.warn('[calib] apply after read failed:', e); + } + return set; + } + /** + * Write a calibration blob to the device (CMD_AR_CFG_CALIB), chunked in + * <=128-byte pieces as [offset_lo, offset_hi, ...chunk]. The device reassembles + * and commits on the final chunk. Requires FW v2.0.4+. + */ + async writeCalibration(blob, chunkSize = 128) { + if (!blob || blob.length < SC_GLOBAL_HEADER_BYTES) { + throw new Error('writeCalibration: invalid calibration blob'); + } + const step = Math.max(1, Math.min(chunkSize, 128)); // firmware ramWrite caps chunks at 128 + for (let offset = 0; offset < blob.length; offset += step) { + const chunk = blob.subarray(offset, Math.min(offset + step, blob.length)); + const payload = new Uint8Array(2 + chunk.length); + payload[0] = offset & 0xff; + payload[1] = (offset >> 8) & 0xff; + payload.set(chunk, 2); + await this.writeProperty(ASM_PROPERTY.CALIBRATION, payload); + } + } + getSensor(name) { + const k = String(name ?? '').toLowerCase(); + if (!k) + return null; + if (k.includes('lis2dw12') || k.includes('accel1') || k === '2') + return this.accel1; + if (k.includes('lsm6dsv') || k === '6') + return this.sensors[6]; + if (k.includes('lsm6') || k.includes('gyro') || k.includes('accel2') || k === '3') + return this.gyroAccel2; + if (k.includes('vbatt') || k.includes('batt') || k.includes('battery') || k.includes('adc')) + return this.adc; + if (k.includes('gsr') || k === '1') + return this.adc; + if (k.includes('ppg') || k === '4') + return this.ppg; + return null; + } + // --------------------------------------------------------------------------- + // RX assembly and dispatch + // --------------------------------------------------------------------------- + _abortSync(err) { + const s = this._sync; + if (!s) + return; + s.receiving = false; + if (s.timer) + clearInterval(s.timer); + this._sync = null; + this._mode = 'idle'; + s.reject(err); + } + _finishSync() { + const s = this._sync; + if (!s) + return; + s.receiving = false; + if (s.timer) + clearInterval(s.timer); + const bytesWritten = s.bytesWritten; + const payloadIndex = s.lastPayloadIndex; + this._sync = null; + this._mode = 'idle'; + s.resolve({ ok: true, bytesWritten, payloadIndex }); + } + async _handleLoggedPayload(payloadU8) { + this._syncPayloadCount++; + const s = this._sync; + if (!s) + return; + const computed = computeCrcLikeCSharp(payloadU8); + const original = getOriginalCrcLE(payloadU8); + const crcOk = computed === original; + const payloadIndex = u16le_at(payloadU8, 0); + if (!crcOk) { + s.lastReply = 'NACK'; + s.nackCrcCount++; + this._clearSyncRxBuffers('crc-nack'); + await this.writeBytes(buildMessage(ASM_COMMAND.NACK_GENERIC, ASM_PROPERTY.DATA)); + if (s.nackCrcCount >= s.maxCrcNack) + this._abortSync(new Error('Too many CRC failures')); + s.onProgress?.({ payloadIndex, bytesWritten: s.bytesWritten, crcOk: false }); + return; + } + s.lastPayloadIndex = payloadIndex; + if (s.writable) { + await s.writable.write(toArrayBuffer(payloadU8)); + } + else { + s.chunks.push(new Uint8Array(payloadU8)); + } + s.bytesWritten += payloadU8.length; + s.emptyAckCount = 0; + s.lastReply = 'ACK'; + s.nackCount = 0; + s.nackCrcCount = 0; + await this.writeBytes(buildMessage(ASM_COMMAND.ACK_NEXT_STAGE, ASM_PROPERTY.DATA), { + withResponse: true, + }); + s.onProgress?.({ payloadIndex, bytesWritten: s.bytesWritten, crcOk: true }); + } + _resetAssembler() { + this._rxStreamBuf = new Uint8Array(0); + } + _appendStreamBuf(chunk) { + const merged = new Uint8Array(this._rxStreamBuf.length + chunk.length); + merged.set(this._rxStreamBuf, 0); + merged.set(chunk, this._rxStreamBuf.length); + this._rxStreamBuf = merged; + } + _clearSyncRxBuffers(reason = '') { + this._rxStreamBuf = new Uint8Array(0); + this._resetAssembler(); + if (this.debugSync) + console.warn('[sync] cleared RX buffers', { reason }); + } + _isPlausibleHeaderByte(hdr) { + const command = hdr & 0xf0; + const property = hdr & 0x0f; + const validCommand = command === ASM_COMMAND.READ || + command === ASM_COMMAND.WRITE || + command === ASM_COMMAND.RESPONSE || + command === ASM_COMMAND.ACK || + command === ASM_COMMAND.NACK_BAD_HEADER_COMMAND || + command === ASM_COMMAND.NACK_BAD_HEADER_PROPERTY || + command === ASM_COMMAND.NACK_GENERIC || + command === ASM_COMMAND.ACK_NEXT_STAGE; + if (!validCommand) + return false; + // Known properties are 0x01..0x0D; keep 0x00 permissive for transient frames. + return (property === 0 || (property >= ASM_PROPERTY.STATUS1 && property <= ASM_PROPERTY.CALIBRATION)); + } + _isPlausibleFrameStart(hdr, len) { + // Logged sync frames can be large and should be length-gated like the working single-file implementation. + if (this._mode === 'logged') { + return len <= VerisenseBleDevice.MAX_FRAME_PAYLOAD_LEN; + } + if (!this._isPlausibleHeaderByte(hdr)) + return false; + // Debug responses may carry large blobs (for example flash lookup tables), + // while normal properties and streaming/logged payloads should stay bounded. + // DEBUG and CALIBRATION responses can be large (lookup tables / the ~1 KB + // calibration blob) and arrive across multiple fragments. + const expectsLargeResponse = this._mode === 'command' && + (this._pending?.expectedProperty === ASM_PROPERTY.DEBUG_COMMAND || + this._pending?.expectedProperty === ASM_PROPERTY.CALIBRATION); + const maxLen = expectsLargeResponse + ? VerisenseBleDevice.MAX_DEBUG_FRAME_PAYLOAD_LEN + : VerisenseBleDevice.MAX_FRAME_PAYLOAD_LEN; + return len <= maxLen; + } + _resolvePendingCommand(msg) { + const pending = this._pending; + if (pending) { + // Some firmware/transport paths emit a transient empty 0x00/0x00 frame + // immediately before the real command response; ignore and keep waiting. + if (msg.command === 0 && + msg.property === 0 && + msg.payload.length === 0) { + return; + } + const err = validatePendingResponse(pending, msg); + if (err) { + this._pending = null; + if (this._mode === 'command') + this._mode = 'idle'; + pending.reject(err); + } + else { + this._pending = null; + if (this._mode === 'command') + this._mode = 'idle'; + pending.resolve(toCommandResponse(msg)); + } + } + else { + this._pending = null; + if (this._mode === 'command') + this._mode = 'idle'; + } + this.emit('commandPayload', { + header: msg.header, + command: msg.command, + property: msg.property, + payload: msg.payload, + }); + } + _feedStreamBytes(chunk) { + if (this._mode === 'logged' && this._sync) + this._sync.lastRxAt = Date.now(); + // Test report data is streamed as raw text bytes after the initial ACK. + // Once the command pending state is cleared, bypass frame parsing entirely. + if (this._testReportMode && !this._pending) { + if (chunk?.length) + this.emit('testReportChunk', chunk); + return; + } + // Throughput-test data is raw dummy bytes streamed after the initial ACK. + // The ACK itself is consumed by the normal frame path while _pending is set; + // everything after is counted (not parsed) until the test finishes. + if (this._throughputTestMode && !this._pending) { + if (chunk?.length) + this.emit('throughputChunk', chunk.length); + return; + } + this._appendStreamBuf(chunk); + for (;;) { + // Streaming frames carry a CRC-16 trailer; use it to lock onto frame + // boundaries. A candidate is accepted only when its CRC validates, so + // after a weak link drops bytes we slide past the garbage and re-lock on + // the next genuine frame instead of emitting misaligned (wrong sensor-id) + // packets. Legacy firmware that streams without a CRC trailer + // (stripStreamCrc=false) falls through to the length-only path below. + if (this._mode === 'streaming' && this.stripStreamCrc) { + const scan = scanStreamFrame(this._rxStreamBuf); + if (scan.status === 'need-more') + return; + if (scan.status === 'invalid') { + if (this.debugSync) { + console.warn('[rx] stream resync: dropping byte', { + dropped: this._rxStreamBuf[0], + bufLen: this._rxStreamBuf.length, + }); + } + this._rxStreamBuf = this._rxStreamBuf.slice(1); + this._streamStats.recordResyncDrop(1); + continue; + } + this._rxStreamBuf = this._rxStreamBuf.slice(scan.consumed); + this._handleStreamingPayload(scan.payload); + continue; + } + if (this._rxStreamBuf.length < 3) + return; + const hdr = this._rxStreamBuf[0]; + const len = (this._rxStreamBuf[1] | (this._rxStreamBuf[2] << 8)) >>> 0; + if (!this._isPlausibleFrameStart(hdr, len)) { + if (this.debugSync) { + console.warn('[rx] resync: dropping byte', { + dropped: hdr, + nextLen: len, + bufLen: this._rxStreamBuf.length, + }); + } + this._rxStreamBuf = this._rxStreamBuf.slice(1); + continue; + } + if (len === 0) { + const header = hdr & 0xff; + const decodedHeader = parseHeader(header); + const msg = { + header, + command: decodedHeader.command, + property: decodedHeader.property, + payloadLength: 0, + payload: new Uint8Array(0), + }; + this._rxStreamBuf = this._rxStreamBuf.slice(3); + if (this._mode === 'logged' && hdr === buildHeader(ASM_COMMAND.ACK, ASM_PROPERTY.DATA)) { + const s = this._sync; + if (s && s.bytesWritten === 0 && s.emptyAckCount < 6) { + s.emptyAckCount++; + if (this.debugSync) + console.log('[sync] empty ACK before payload; requesting next DATA chunk.'); + void this.writeBytes(buildMessage(ASM_COMMAND.READ, ASM_PROPERTY.DATA), { + withResponse: true, + }).catch((e) => this._abortSync(e)); + continue; + } + if (this.debugSync) + console.log('[sync] EOS received. Finishing.'); + this._finishSync(); + continue; + } + if (this._mode === 'command') { + this._resolvePendingCommand(msg); + } + continue; + } + if (this._rxStreamBuf.length < 3 + len) + return; + const payload = this._rxStreamBuf.slice(3, 3 + len); + this._rxStreamBuf = this._rxStreamBuf.slice(3 + len); + const header = hdr & 0xff; + const decodedHeader = parseHeader(header); + const msg = { + header, + command: decodedHeader.command, + property: decodedHeader.property, + payloadLength: payload.length, + payload, + }; + if (this._mode === 'logged') { + this._loggedChain = (this._loggedChain ?? Promise.resolve()) + .then(() => this._handleLoggedPayload(msg.payload)) + .catch((e) => this._abortSync(e)); + continue; + } + if (this._mode === 'streaming') { + this._handleStreamingPayload(msg.payload); + continue; + } + this._resolvePendingCommand(msg); + } + } + _handleStreamingPayload(payload) { + if (payload.length < 4) + return; + let body = payload; + let crcOk = null; + if (this.stripStreamCrc && payload.length >= 6) { + // Reached only for frames the CRC-gated scanner already validated (see + // _feedStreamBytes), so the CRC is known good; just strip the 2-byte + // trailer before decoding. + body = payload.slice(0, payload.length - 2); + crcOk = true; + } + const sensorId = body[0]; + const tick = u24le(body, 1); + const sensorPayload = body.slice(4); + const sensor = this.sensors[sensorId]; + const systemTsLastSampleMillis = nowMillis(); + let tsInfo = null; + if (sensor) + tsInfo = sensor.getTimestampUnwrappedMillis(tick, systemTsLastSampleMillis); + let decodedSamples = null; + if (sensor) + decodedSamples = sensor.parsePayload(sensorPayload); + let samplesWithTime = decodedSamples; + if (sensor && Array.isArray(decodedSamples) && decodedSamples.length > 0 && tsInfo) { + // Per-stream-aware (sensors with interleaved FIFO streams override this). + const tsArray = sensor.computeSampleTimestamps(decodedSamples, { + tsLastSampleMillis: tsInfo.shimmerMillis, + systemTsLastSampleMillis, + systemOffsetFirstTime: tsInfo.systemOffsetFirstTime, + }); + samplesWithTime = decodedSamples.map((s, i) => ({ + ...s, + timestamps: tsArray[i], + })); + } + const packet = { + sensorId, + tick_u24: tick, + decoded: samplesWithTime, + rawPayload: sensorPayload, + crcOk, + }; + // Live throughput / packet-loss accounting. Loss is derived from gaps in the + // monotonic device clock (tsMillis) via getStreamContributions; throughput + // uses the full BLE frame size and host receive time. + const contributions = sensor && Array.isArray(samplesWithTime) && samplesWithTime.length + ? sensor.getStreamContributions(samplesWithTime, sensorId) + : []; + this._streamStats.recordPacket({ + sensorId, + byteLength: payload.length, + crcOk, + recvMillis: systemTsLastSampleMillis, + contributions, + }); + this.emit('streamPacket', packet); + this.emit('data', packet); + // Throttled stats push (~3 Hz) so the UI can subscribe instead of polling. + if (systemTsLastSampleMillis - this._lastStreamStatsEmitMillis >= 333) { + this._lastStreamStatsEmitMillis = systemTsLastSampleMillis; + this.emit('streamStats', this._streamStats.snapshot(systemTsLastSampleMillis)); + } + } + /** Snapshot of live stream statistics (throughput / packet-loss). */ + getStreamStats() { + return this._streamStats.snapshot(nowMillis()); + } +} +// Single source of truth for the max frame size, shared with the CRC-gated +// streaming scanner so both framing paths accept the same large (fragmented) +// payloads. See STREAM_FRAME_MAX_PAYLOAD. +VerisenseBleDevice.MAX_FRAME_PAYLOAD_LEN = STREAM_FRAME_MAX_PAYLOAD; +VerisenseBleDevice.MAX_DEBUG_FRAME_PAYLOAD_LEN = 0xffff; +// Static NUS UUIDs +VerisenseBleDevice.NUS_SERVICE = NUS_SERVICE; +VerisenseBleDevice.NUS_TX = NUS_TX; +VerisenseBleDevice.NUS_RX = NUS_RX; + +/** + * Verisense Nordic Secure-DFU flow helpers (DEV-845). + * + * The byte transport is Nordic's `web-bluetooth-dfu` library (`SecureDfu` + + * `SecureDfuPackage`, vendored by consuming apps); this module owns everything + * learned about running that library reliably against Verisense sensors over + * desktop Chrome/Edge Web Bluetooth: + * + * - classification of transient BLE-stack errors vs DFU protocol errors + * - a fix for the library's swallowed-rejection hang in `sendOperation` + * - bounded + retried `setDfuMode` (with a full GATT reset between attempts) + * - the two-phase combined-package update (SoftDevice/bootloader then + * application), including resume of an interrupted combined update + * - the bootloader device-picker filter and packet-pacing defaults + * + * The library objects are injected (structurally typed), so this module has no + * build-time dependency on the vendored scripts. All user-visible progress is + * reported through an `onStatus` callback; no DOM access happens here. + */ +/** + * Transient connection/BLE-stack errors worth retrying. "unknown reason" + * (NotSupportedError) is Chrome-on-Windows' generic wrapper for any GATT + * operation the OS stack fails without an ATT error code (DEV-845) — + * typically a startNotifications/write right after a (re)connect, or a + * link being torn down mid-encryption. Recoverable on retry; DFU protocol + * errors (wrong image, version too low, ...) never match. + */ +const VERISENSE_DFU_TRANSIENT_ERROR_REGEX = /unreachable|networkerror|gatt server|disconnected|no longer in range|connection|unknown reason|notsupportederror/i; +/** Total attempts (first try + retries) for the DFU connection-retry helpers. */ +const VERISENSE_DFU_CONNECT_ATTEMPTS = 3; +/** Delay between DFU connection retries, letting the device finish rebooting. */ +const VERISENSE_DFU_RETRY_DELAY_MS = 2000; +/** Time allowed for the base image's post-install reboot back into the bootloader. */ +const VERISENSE_DFU_REBOOT_DELAY_MS = 3000; +/** Bound on `setDfuMode` (connect + notifications + one write): the happy path + * completes in seconds, so a hit means a genuine stall — including the vendored + * library's swallowed-rejection case that {@link patchSecureDfuSendOperation} + * and {@link promiseWithTimeout} exist to catch. */ +const VERISENSE_DFU_SET_MODE_TIMEOUT_MS = 30000; +/** + * Per-packet pacing for the firmware transfer, in ms. The packet + * characteristic is written without response; over Web Bluetooth, Chrome + * drops packets if it outruns the device, so at 0 ms the first pass can fail + * object CRC validation and the library silently retries the WHOLE transfer + * at ~10 ms (the pass that succeeds). Pacing at 10 ms makes the first pass + * succeed outright. Pass 0 ("fast") for full speed on a known-clean link. + * (nRF Connect sidesteps this via a wired connectivity dongle rather than + * the OS BLE stack.) + */ +const VERISENSE_DFU_RELIABLE_PACKET_DELAY_MS = 10; +const VERISENSE_DFU_FAST_PACKET_DELAY_MS = 0; +/** + * The Verisense bootloader advertises as "Verisense-BL..."; app-mode sensors + * ("Verisense-..." without the -BL) are deliberately excluded from DFU device + * pickers to keep them unambiguous. The DFU service UUID is not advertised in + * app mode, so it cannot be used to widen the filter; it still needs to be + * granted via `optionalServices` for the GATT connection. + */ +const VERISENSE_DFU_BOOTLOADER_NAME_PREFIX = 'Verisense-BL'; +/** + * The library's routine object-retransmission notices (e.g. "object failed to + * validate"). Over Web Bluetooth, firmware packets are written without + * response and Chrome can drop one if it outruns the device; that makes a + * 4 KB object's CRC mismatch, so the library transparently re-creates and + * re-sends that object. The transfer still completes correctly (every object + * is CRC-checked before Execute, and the bootloader CRC/signature-checks the + * whole image), so these are non-issues that only alarm users. Real failures + * still surface via the promise rejection paths. + */ +const VERISENSE_DFU_ROUTINE_LOG_REGEX = /validat|crc|mismatch|retr|re-?send|re-?creat/i; +/** True for library log messages that are routine retransmission noise and + * should not be surfaced to end users (see {@link VERISENSE_DFU_ROUTINE_LOG_REGEX}). */ +function isRoutineVerisenseDfuLogMessage(message) { + return VERISENSE_DFU_ROUTINE_LOG_REGEX.test(String(message ?? '')); +} +/** "attempt N of M" wording for retry status lines. The retry helpers count + * attempts DOWN (remaining, including the one that just failed), so the + * attempt about to start is total - remaining + 2. */ +function verisenseDfuAttemptLabel(attemptsRemaining, totalAttempts = VERISENSE_DFU_CONNECT_ATTEMPTS) { + return `attempt ${totalAttempts - attemptsRemaining + 2} of ${totalAttempts}`; +} +/** + * Fix the swallowed-rejection hang in `web-bluetooth-dfu` v1.2.1 (DEV-845): + * upstream `SecureDfu.sendOperation` retries a failed control-point write once + * after 500 ms, but if the retry ALSO fails the rejection is dropped and the + * returned promise never settles — the transfer hangs forever. This replaces + * the method with the same logic as upstream, plus: a second write failure + * rejects the pending operation. + * + * Call once per page load with the vendored `SecureDfu` constructor before + * creating instances. Safe to call repeatedly (idempotent). + */ +function patchSecureDfuSendOperation(SecureDfuCtor) { + const patched = function (characteristic, operation, buffer) { + return new Promise((resolve, reject) => { + let size = operation.length; + if (buffer) + size += buffer.byteLength; + const value = new Uint8Array(size); + value.set(operation); + if (buffer) + value.set(new Uint8Array(buffer), operation.length); + this.notifyFns[operation[0]] = { resolve, reject }; + characteristic + .writeValue(value) + .catch((error) => { + this.log(error); + return this.delayPromise(500).then(() => characteristic.writeValue(value)); + }) + .catch((error) => { + delete this.notifyFns[operation[0]]; + reject(error); + }); + }); + }; + SecureDfuCtor.prototype.sendOperation = patched; +} +/** + * Classify known Bluetooth-stack failures seen during Verisense DFU (DEV-845). + * Two signatures of the same Windows pairing/GATT-cache failure loop: + * "unknown reason" (NotSupportedError) is the stack failing an operation on a + * live link, and "GATT Server is disconnected" (NetworkError) is the sensor + * tearing the link down mid-operation — on units without the firmware fix, + * typically its ~400 ms security request colliding with a stale pairing key. + * Unrecognised errors return `category: null` so their raw text passes + * through unchanged. + */ +function classifyVerisenseDfuError(error) { + const rawMessage = String(error); + const name = error && typeof error === 'object' && 'name' in error && typeof error.name === 'string' + ? error.name + : 'GATT error'; + let category = null; + let friendlyMessage = null; + if (/gatt server is disconnected/i.test(rawMessage)) { + category = 'device-disconnected'; + friendlyMessage = 'The sensor disconnected before the operation could complete'; + } + else if (/unknown reason|notsupportederror/i.test(rawMessage)) { + category = 'stack-operation-failed'; + friendlyMessage = 'The Bluetooth stack failed the operation unexpectedly'; + } + return { + category, + friendlyMessage, + transient: VERISENSE_DFU_TRANSIENT_ERROR_REGEX.test(rawMessage), + name, + rawMessage, + }; +} +/** + * Reject a promise that hasn't settled within `ms`. Used to guard + * `SecureDfu.setDfuMode()`: the library builds its buttonless branch as + * `new Promise((resolve, reject) => { startNotifications().then( + * ...sendOperation...).then(resolve) })` with NO `.catch(reject)`, so if + * startNotifications() or the button-command write fails the promise never + * settles. (The {@link patchSecureDfuSendOperation} override makes that write + * reject rather than hang, which this same missing catch would swallow.) + * The timeout message deliberately includes "connection" so it matches + * {@link VERISENSE_DFU_TRANSIENT_ERROR_REGEX} and drives the retry helpers. + * Kept as a timeout rather than re-implementing setDfuMode so the buttonless + * reboot logic isn't duplicated, and so it defends against any stall cause. + */ +function promiseWithTimeout(promise, ms, label) { + let timer; + const timeout = new Promise((_resolve, reject) => { + timer = setTimeout(() => { + reject(new Error(`${label} timed out after ${ms}ms (connection may have stalled)`)); + }, ms); + }); + return Promise.race([promise, timeout]).finally(() => clearTimeout(timer)); +} +/** A bundled firmware name must be a plain `.zip` filename — no path + * separators or traversal — so a malformed/hostile manifest can't make an app + * fetch outside its firmware folder. */ +function isSafeFirmwareArchiveName(name) { + return typeof name === 'string' && /^[^/\\]+\.zip$/i.test(name) && !name.includes('..'); +} +/** + * `navigator.bluetooth.requestDevice()` options for picking a Verisense + * bootloader (replaces the DFU library's `acceptAllDevices`; see + * {@link VERISENSE_DFU_BOOTLOADER_NAME_PREFIX} for why name-prefix only). + * Pass the vendored library's `SecureDfu.SERVICE_UUID`. + */ +function buildVerisenseDfuRequestDeviceOptions(dfuServiceUuid) { + return { + filters: [{ namePrefix: VERISENSE_DFU_BOOTLOADER_NAME_PREFIX }], + optionalServices: [dfuServiceUuid], + }; +} +function delay(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} +/** Normalize an `attempts` option to a finite integer >= 1 so the retry + * loops keep their documented "total attempts" semantics for 0/negative/NaN + * inputs. */ +function normalizeAttempts(attempts) { + const v = Number(attempts ?? VERISENSE_DFU_CONNECT_ATTEMPTS); + return Number.isFinite(v) ? Math.max(1, Math.trunc(v)) : VERISENSE_DFU_CONNECT_ATTEMPTS; +} +/** + * `SecureDfu.update()` with retries on connection-level errors. Combined + * (SoftDevice+bootloader+application) packages transfer in two parts with a + * device reset in between; the reconnect for part 2 can fail while the device + * is still rebooting, so transient errors retry after a settle delay. DFU + * protocol errors are not retried. + */ +async function updateVerisenseDfuImageWithRetry(dfu, device, image, options = {}) { + const totalAttempts = normalizeAttempts(options.attempts); + const retryDelayMs = options.retryDelayMs ?? VERISENSE_DFU_RETRY_DELAY_MS; + for (let attemptsRemaining = totalAttempts;; attemptsRemaining--) { + try { + await dfu.update(device, image.initData, image.imageData); + return; + } + catch (error) { + const transient = VERISENSE_DFU_TRANSIENT_ERROR_REGEX.test(String(error)); + if (attemptsRemaining <= 1 || !transient) + throw error; + const attemptLabel = verisenseDfuAttemptLabel(attemptsRemaining, totalAttempts); + options.onRetry?.({ stage: 'update', attemptsRemaining, attemptLabel, error }); + options.onStatus?.(`Reconnecting to bootloader (${attemptLabel})...`); + await delay(retryDelayMs); + } + } +} +/** + * `SecureDfu.setDfuMode()` bounded by a timeout and retried on transient + * errors (DEV-845). setDfuMode (connect + find the buttonless characteristic + * + startNotifications + write) is where Windows' BLE stack intermittently + * fails with "GATT operation failed for unknown reason", typically on the + * first GATT operation after a connect that follows a disconnect. Before each + * retry the GATT connection is fully torn down so the next attempt starts + * from a clean link. Protocol errors (e.g. "Unsupported device") are not + * retried. Resolves like setDfuMode: the device when it is already in + * bootloader mode, or null after the buttonless reboot command has been sent. + */ +async function setVerisenseDfuModeWithRetry(dfu, device, options = {}) { + const totalAttempts = normalizeAttempts(options.attempts); + const retryDelayMs = options.retryDelayMs ?? VERISENSE_DFU_RETRY_DELAY_MS; + const timeoutMs = options.setDfuModeTimeoutMs ?? VERISENSE_DFU_SET_MODE_TIMEOUT_MS; + for (let attemptsRemaining = totalAttempts;; attemptsRemaining--) { + try { + const result = await promiseWithTimeout(dfu.setDfuMode(device), timeoutMs, 'Enter DFU mode'); + return result ?? null; + } + catch (error) { + const transient = VERISENSE_DFU_TRANSIENT_ERROR_REGEX.test(String(error)); + if (attemptsRemaining <= 1 || !transient) + throw error; + const attemptLabel = verisenseDfuAttemptLabel(attemptsRemaining, totalAttempts); + options.onRetry?.({ stage: 'set-dfu-mode', attemptsRemaining, attemptLabel, error }); + options.onStatus?.(`Connection hiccup - retrying (${attemptLabel})...`); + // Full connection-state reset so the retry starts from a clean link. + if (device.gatt?.connected) { + device.gatt.disconnect(); + } + await delay(retryDelayMs); + } + } +} +/** + * Run a full Verisense DFU transfer from a loaded Nordic DFU package: base + * image (SoftDevice/bootloader) first when present, then the application + * image. Resumes interrupted combined updates: a bootloader only installs + * once per version number, so if a previous (interrupted) attempt already + * installed this base image the target rejects it with a firmware-version + * error — that is swallowed and the flow continues to the application image. + * + * Progress text is reported via `options.onStatus`; transfer byte progress + * comes from the `SecureDfu` instance's own "progress" events, which the app + * subscribes to directly. Rejects with the raw library error on failure (run + * it through {@link classifyVerisenseDfuError} for display). + */ +async function runVerisenseDfuUpdate(dfu, device, dfuPackage, options = {}) { + const rebootDelayMs = options.rebootDelayMs ?? VERISENSE_DFU_REBOOT_DELAY_MS; + const baseImage = await dfuPackage.getBaseImage(); + if (baseImage) { + options.onStatus?.(`Updating ${baseImage.type}: ${baseImage.imageFile}...`); + try { + await dfu.update(device, baseImage.initData, baseImage.imageData); + // The base image resets the target on completion; give it time to + // reboot back into the bootloader before part 2. + options.onStatus?.('SoftDevice/bootloader installed - device rebooting...'); + await delay(rebootDelayMs); + } + catch (error) { + if (!/firmware version is too low/i.test(String(error))) + throw error; + options.onStatus?.('SoftDevice/bootloader already up to date - continuing with application...'); + } + } + const appImage = await dfuPackage.getAppImage(); + if (appImage) { + options.onStatus?.(`Updating ${appImage.type}: ${appImage.imageFile}...`); + await updateVerisenseDfuImageWithRetry(dfu, device, appImage, options); + } +} + +/** + * Verisense calibration defaults, hardware/firmware gating, and timestamp helpers. + * + * The byte-level codec lives in `calibration.ts`; this module is the host-side + * single source of truth for the *default* calibration (the mirror of the + * firmware `AsmCalib_seedDefaults`) plus the small amount of domain logic the UI + * used to carry: which calibration blocks a board has, the minimum firmware that + * supports `CMD_AR_CFG_CALIB`, and the 8-byte timestamp encode/decode. + */ +/** Minimum firmware that implements the `CMD_AR_CFG_CALIB` (0x0D) command. */ +const VERISENSE_CALIBRATION_MIN_FW = { + major: 2, + minor: 0, + internal: 4, +}; +/** Whether the given firmware version supports the calibration command. */ +function supportsVerisenseCalibration(fw) { + if (!fw) + return false; + return compareVerisenseFirmwareVersion(fw, VERISENSE_CALIBRATION_MIN_FW) >= 0; +} +// --------------------------------------------------------------------------- +// 8-byte little-endian Unix-epoch-seconds timestamp (block header `ts` field). +// --------------------------------------------------------------------------- +/** Encode Unix-epoch seconds into the 8-byte little-endian calibration `ts`. */ +function unixSecondsToCalibTsBytes(unixSeconds) { + const out = new Uint8Array(SC_TS_BYTES); + let v = Math.max(0, Math.floor(Number(unixSeconds) || 0)); + for (let i = 0; i < SC_TS_BYTES; i++) { + out[i] = v & 0xff; + v = Math.floor(v / 256); + } + return out; +} +/** Decode the 8-byte little-endian calibration `ts` back to Unix-epoch seconds + * (0 = default/seeded). */ +function calibTsBytesToUnixSeconds(ts) { + if (!ts || ts.length < SC_TS_BYTES) + return 0; + let secs = 0; + for (let i = SC_TS_BYTES - 1; i >= 0; i--) + secs = secs * 256 + (ts[i] & 0xff); + return secs; +} +const ACCEL_RANGES = [ + { code: 0, label: '±2g', sens: 1671.665922915 }, + { code: 1, label: '±4g', sens: 835.832961457 }, + { code: 2, label: '±8g', sens: 417.916480729 }, + { code: 3, label: '±16g', sens: 208.958240364 }, +]; +// LSM6DSV gyro full-scale codes 0..4 (125/250/500/1000/2000 dps). +const GYRO_RANGES = [ + { code: 0, label: '±125dps', sens: 228.571428571 }, + { code: 1, label: '±250dps', sens: 114.285714286 }, + { code: 2, label: '±500dps', sens: 57.142857143 }, + { code: 3, label: '±1000dps', sens: 28.571428571 }, + { code: 4, label: '±2000dps', sens: 14.285714286 }, +]; +// LSM6DS3 gyro full-scale codes 0..3 (250/500/1000/2000 dps) — the gen-1 op-config +// gyro field is 2 bits, so 125 dps is not selectable via the standard range (see +// SensorLSM6DS3). Codes here match that field and the decoder lookup. +const LSM6DS3_GYRO_RANGES = [ + { code: 0, label: '±250dps', sens: 114.285714286 }, + { code: 1, label: '±500dps', sens: 57.142857143 }, + { code: 2, label: '±1000dps', sens: 28.571428571 }, + { code: 3, label: '±2000dps', sens: 14.285714286 }, +]; +/** + * 2nd-generation catalog (LSM6DSV accel+gyro, LIS2DW12, LIS2MDL). Alignment + * matrices derived from the ST datasheet axis figures + the SR68-10 pin-1 + * placement; common frame +X=strap, +Y=out of face, +Z=toward hand. LSM6DSV / + * LIS2DW12 are proper rotations (det +1); the LIS2MDL frame is left-handed + * (det −1, a reflection). Kept byte-for-byte in sync with the firmware seed + * (asm_calibration.c) and VERISENSE_CALIBRATION.md §4. + */ +const CALIBRATION_SENSORS_GEN2 = [ + { + id: CalibSensorId.LSM6DSV_ACCEL, + label: 'Accelerometer (LSM6DSV)', + unit: 'LSB/(m/s²)', + align: [0, -1, 0, 0, 0, 1, -1, 0, 0], + ranges: ACCEL_RANGES, + }, + { + id: CalibSensorId.LSM6DSV_GYRO, + label: 'Gyroscope (LSM6DSV)', + unit: 'LSB/dps', + align: [0, -1, 0, 0, 0, 1, -1, 0, 0], + ranges: GYRO_RANGES, + }, + { + id: CalibSensorId.LIS2DW12_ACCEL, + label: 'Accelerometer 2 (LIS2DW12)', + unit: 'LSB/(m/s²)', + align: [1, 0, 0, 0, 0, 1, 0, -1, 0], + ranges: ACCEL_RANGES, + }, + { + id: CalibSensorId.LIS2MDL_MAG, + label: 'Magnetometer (LIS2MDL)', + unit: 'LSB/Gauss', + align: [0, 1, 0, 0, 0, 1, -1, 0, 0], + ranges: [{ code: 0, label: '±49.152Ga', sens: 667 }], + }, +]; +/** + * 1st-generation catalog (LIS2DW12 + LSM6DS3 accel/gyro). Sensitivities and + * alignment from the gen-1 calibration document (ASM-DES §8). The doc states the + * forward rotation `R` (output = K·R·physical); the stored `align` is the applied + * sensor→common map = Rᵀ. Note the LIS2DW12 mounting differs from gen-2, so its + * alignment (id 39) is generation-specific. All proper rotations (det +1). + */ +const CALIBRATION_SENSORS_GEN1 = [ + { + id: CalibSensorId.LIS2DW12_ACCEL, + label: 'Accelerometer 1 (LIS2DW12)', + unit: 'LSB/(m/s²)', + align: [0, 1, 0, 0, 0, 1, 1, 0, 0], + ranges: ACCEL_RANGES, + }, + { + id: CalibSensorId.LSM6DS3_ACCEL, + label: 'Accelerometer 2 (LSM6DS3)', + unit: 'LSB/(m/s²)', + align: [0, -1, 0, 0, 0, -1, 1, 0, 0], + ranges: ACCEL_RANGES, + }, + { + id: CalibSensorId.LSM6DS3_GYRO, + label: 'Gyroscope (LSM6DS3)', + unit: 'LSB/dps', + align: [0, -1, 0, 0, 0, -1, 1, 0, 0], + ranges: LSM6DS3_GYRO_RANGES, + }, +]; +/** + * The calibration sensor catalog for a board: the 1st-generation set + * (LIS2DW12 + LSM6DS3) for 1st-gen hardware, otherwise the 2nd-generation set + * (LSM6DSV + LIS2DW12 + LIS2MDL). Unknown/offline (no revision) defaults to + * 2nd-gen. Note id 39 (LIS2DW12) appears in both with a generation-specific + * alignment, so the catalog must be resolved per hardware revision. + */ +function getVerisenseCalibrationSensors(revHwMajor, revHwMinor) { + if (revHwMajor != null && + revHwMinor != null && + !isVerisenseSecondGenerationHardware(revHwMajor, revHwMinor)) { + return CALIBRATION_SENSORS_GEN1; + } + return CALIBRATION_SENSORS_GEN2; +} +/** + * Build the default calibration set for a board (bias=0, default sensitivity, + * default alignment, ts=0). Host-side mirror of `AsmCalib_seedDefaults`; useful + * for "reset to defaults" and round-trip tests. + */ +function buildDefaultVerisenseCalibrationSet(opts) { + const sensors = getVerisenseCalibrationSensors(opts.hwVerMajor, opts.hwVerMinor); + const blocks = sensors.flatMap((s) => s.ranges.map((r) => ({ + sensorId: s.id, + range: r.code, + imu: { + bias: [0, 0, 0], + sens: [r.sens, r.sens, r.sens], + align: s.align.slice(), + }, + }))); + return { + hwVerMajor: opts.hwVerMajor, + hwVerMinor: opts.hwVerMinor, + fwVerMajor: opts.fwVerMajor, + fwVerMinor: opts.fwVerMinor, + fwVerPatch: opts.fwVerPatch, + blocks, + }; +} +/** + * Map each calibration-domain sensor id to whether it is present and usable on + * the connected hardware: + * - `enabled` — present and recorded from; show + allow edit. + * - `disabled` — physically present but not recorded from (LIS2DW12 routed to + * the algorithm hub on 2nd-gen SR68); show greyed. + * - `hidden` — not fitted on this hardware. + * + * `support` is the result of `getVerisenseHardwareSensorSupport`. A null/absent + * support object (offline / unknown hardware) reports every sensor `enabled`. + */ +function getVerisenseCalibrationSensorAvailability(support) { + const all = (v) => ({ + [CalibSensorId.LSM6DSV_ACCEL]: v, + [CalibSensorId.LSM6DSV_GYRO]: v, + [CalibSensorId.LIS2DW12_ACCEL]: v, + [CalibSensorId.LSM6DS3_ACCEL]: v, + [CalibSensorId.LSM6DS3_GYRO]: v, + [CalibSensorId.LIS2MDL_MAG]: v, + }); + if (!support) + return all('enabled'); + const imuGen2 = support.imuGen2 ? 'enabled' : 'hidden'; + const gen1Imu = support.gyroAccel2 ? 'enabled' : 'hidden'; + // LIS2DW12: recorded directly on 1st-gen (accel1); present-but-algo-hub-routed + // on 2nd-gen (imuGen2) so shown disabled; otherwise not fitted. + const lis2dw12 = support.accel1 + ? 'enabled' + : support.imuGen2 + ? 'disabled' + : 'hidden'; + return { + [CalibSensorId.LSM6DSV_ACCEL]: imuGen2, + [CalibSensorId.LSM6DSV_GYRO]: imuGen2, + [CalibSensorId.LIS2MDL_MAG]: imuGen2, + [CalibSensorId.LIS2DW12_ACCEL]: lis2dw12, + [CalibSensorId.LSM6DS3_ACCEL]: gen1Imu, + [CalibSensorId.LSM6DS3_GYRO]: gen1Imu, + }; +} + +exports.ASM_COMMAND = ASM_COMMAND; +exports.ASM_PROPERTY = ASM_PROPERTY; +exports.BLE_LINK_MIN_FW = BLE_LINK_MIN_FW; +exports.BaseShimmerClient = BaseShimmerClient; +exports.CHANNEL_FORMATS = CHANNEL_FORMATS; +exports.CalibQuality = CalibQuality; +exports.CalibSensorId = CalibSensorId; +exports.DEBUG_COMMAND_ID = DEBUG_COMMAND_ID; +exports.GSR_NAME = GSR_NAME; +exports.NORDIC_DFU_BUTTONLESS_WITHOUT_BONDS = NORDIC_DFU_BUTTONLESS_WITHOUT_BONDS; +exports.NORDIC_DFU_BUTTONLESS_WITH_BONDS = NORDIC_DFU_BUTTONLESS_WITH_BONDS; +exports.NORDIC_DFU_OP_ENTER_BOOTLOADER = NORDIC_DFU_OP_ENTER_BOOTLOADER; +exports.NORDIC_DFU_SERVICE = NORDIC_DFU_SERVICE; +exports.NUS_RX = NUS_RX; +exports.NUS_SERVICE = NUS_SERVICE; +exports.NUS_TX = NUS_TX; +exports.OPCODES = OPCODES; +exports.OP_IDX = OP_IDX; +exports.ObjectCluster = ObjectCluster; +exports.RtcDriftMonitor = RtcDriftMonitor; +exports.SC_CALIB_FORMAT_VERSION = SC_CALIB_FORMAT_VERSION; +exports.SC_CAL_QUALITY_MASK = SC_CAL_QUALITY_MASK; +exports.SC_CAL_QUALITY_SHIFT = SC_CAL_QUALITY_SHIFT; +exports.SC_CAL_RANGE_MASK = SC_CAL_RANGE_MASK; +exports.SC_DATA_LEN_IMU = SC_DATA_LEN_IMU; +exports.SC_GLOBAL_HEADER_BYTES = SC_GLOBAL_HEADER_BYTES; +exports.SHIMMER3R_DEFAULTS = SHIMMER3R_DEFAULTS; +exports.STREAM_MODE = STREAM_MODE; +exports.SensorADC = SensorADC; +exports.SensorBase = SensorBase; +exports.SensorBitmapShimmer3 = SensorBitmapShimmer3; +exports.SensorLIS2DW12 = SensorLIS2DW12; +exports.SensorLSM6DS3 = SensorLSM6DS3; +exports.SensorLSM6DSV = SensorLSM6DSV; +exports.SensorMAX32674 = SensorMAX32674; +exports.SensorMLX90632 = SensorMLX90632; +exports.SensorPPG = SensorPPG; +exports.SensorVD6283 = SensorVD6283; +exports.Shimmer3RClient = Shimmer3RClient; +exports.StreamStatsTracker = StreamStatsTracker; +exports.TEST_MODE_ID = TEST_MODE_ID; +exports.TIMESTAMP_FIELD = TIMESTAMP_FIELD; +exports.VERISENSE_BLE_SCHEDULE_DEFAULTS = VERISENSE_BLE_SCHEDULE_DEFAULTS; +exports.VERISENSE_BLE_SCHEDULE_RANGES = VERISENSE_BLE_SCHEDULE_RANGES; +exports.VERISENSE_BLE_SYNC_SCHEDULES = VERISENSE_BLE_SYNC_SCHEDULES; +exports.VERISENSE_CALIBRATION_MIN_FW = VERISENSE_CALIBRATION_MIN_FW; +exports.VERISENSE_DEFAULT_PASSKEY_BY_ID = VERISENSE_DEFAULT_PASSKEY_BY_ID; +exports.VERISENSE_DFU_BOOTLOADER_NAME_PREFIX = VERISENSE_DFU_BOOTLOADER_NAME_PREFIX; +exports.VERISENSE_DFU_CONNECT_ATTEMPTS = VERISENSE_DFU_CONNECT_ATTEMPTS; +exports.VERISENSE_DFU_FAST_PACKET_DELAY_MS = VERISENSE_DFU_FAST_PACKET_DELAY_MS; +exports.VERISENSE_DFU_REBOOT_DELAY_MS = VERISENSE_DFU_REBOOT_DELAY_MS; +exports.VERISENSE_DFU_RELIABLE_PACKET_DELAY_MS = VERISENSE_DFU_RELIABLE_PACKET_DELAY_MS; +exports.VERISENSE_DFU_RETRY_DELAY_MS = VERISENSE_DFU_RETRY_DELAY_MS; +exports.VERISENSE_DFU_ROUTINE_LOG_REGEX = VERISENSE_DFU_ROUTINE_LOG_REGEX; +exports.VERISENSE_DFU_SET_MODE_TIMEOUT_MS = VERISENSE_DFU_SET_MODE_TIMEOUT_MS; +exports.VERISENSE_DFU_TRANSIENT_ERROR_REGEX = VERISENSE_DFU_TRANSIENT_ERROR_REGEX; +exports.VERISENSE_HW_MAJOR_FRIENDLY_NAMES = VERISENSE_HW_MAJOR_FRIENDLY_NAMES; +exports.VERISENSE_MAX_PLAUSIBLE_UNIX_SECONDS = VERISENSE_MAX_PLAUSIBLE_UNIX_SECONDS; +exports.VERISENSE_OPERATIONAL_FIELD_FALLBACK_GROUP_ID = VERISENSE_OPERATIONAL_FIELD_FALLBACK_GROUP_ID; +exports.VERISENSE_OPERATIONAL_FIELD_GROUPS = VERISENSE_OPERATIONAL_FIELD_GROUPS; +exports.VERISENSE_OPERATIONAL_FIELD_GROUP_SENSOR = VERISENSE_OPERATIONAL_FIELD_GROUP_SENSOR; +exports.VERISENSE_OPERATIONAL_FIELD_SCHEMA = VERISENSE_OPERATIONAL_FIELD_SCHEMA; +exports.VERISENSE_OP_CONFIG_BYTE_SIZE = VERISENSE_OP_CONFIG_BYTE_SIZE; +exports.VERISENSE_SENSOR_ENABLE_FIELDS = VERISENSE_SENSOR_ENABLE_FIELDS; +exports.VERISENSE_SENSOR_RATE_DEFAULT_GROUPS = VERISENSE_SENSOR_RATE_DEFAULT_GROUPS; +exports.VERISENSE_STREAM_SENSOR_LABELS = VERISENSE_STREAM_SENSOR_LABELS; +exports.VerisenseBleDevice = VerisenseBleDevice; +exports.applyDuplicateSuffix = applyDuplicateSuffix; +exports.applyImuCalibration = applyImuCalibration; +exports.asmRtcBytesToUnixSeconds = asmRtcBytesToUnixSeconds; +exports.asmRtcMinutesBytesToUnixSeconds = asmRtcMinutesBytesToUnixSeconds; +exports.buildDefaultVerisenseCalibrationSet = buildDefaultVerisenseCalibrationSet; +exports.buildHeader = buildHeader; +exports.buildMessage = buildMessage; +exports.buildParsedCsvFileName = buildParsedCsvFileName; +exports.buildProductionConfigPayload = buildProductionConfigPayload; +exports.buildUploadBinaryFileName = buildUploadBinaryFileName; +exports.buildVerisenseAdvertisedName = buildVerisenseAdvertisedName; +exports.buildVerisenseDfuRequestDeviceOptions = buildVerisenseDfuRequestDeviceOptions; +exports.calibTsBytesToUnixSeconds = calibTsBytesToUnixSeconds; +exports.calibrateGsrDataToResistanceFromAmplifierEq = calibrateGsrDataToResistanceFromAmplifierEq; +exports.calibrateShimmer3RAdcChannel = calibrateShimmer3RAdcChannel; +exports.calibrateU12AdcValue = calibrateU12AdcValue; +exports.calibrationBlobCrc = calibrationBlobCrc; +exports.classifyVerisenseDfuError = classifyVerisenseDfuError; +exports.compareVerisenseFirmwareVersion = compareVerisenseFirmwareVersion; +exports.computeVerisensePairingPin = computeVerisensePairingPin; +exports.crc16_ccitt_false = crc16_ccitt_false; +exports.createBlankVerisenseOperationalConfig = createBlankVerisenseOperationalConfig; +exports.csvCell = csvCell; +exports.decodeVerisenseBleOptimizationResult = decodeVerisenseBleOptimizationResult; +exports.defaultVerisensePasskeyForId = defaultVerisensePasskeyForId; +exports.deriveVerisenseMacIdFromName = deriveVerisenseMacIdFromName; +exports.describeVerisenseChargerStatus = describeVerisenseChargerStatus; +exports.enforceVerisenseCommsChannelInterlock = enforceVerisenseCommsChannelInterlock; +exports.evaluateParsedFileSplit = evaluateParsedFileSplit; +exports.expectedVerisenseStreamSensorIds = expectedVerisenseStreamSensorIds; +exports.expectedVerisenseStreamSensorIdsFromConfig = expectedVerisenseStreamSensorIdsFromConfig; +exports.formatByteArrayAsHex = formatByteArrayAsHex; +exports.formatByteAsHex = formatByteAsHex; +exports.formatPendingEventProperties = formatPendingEventProperties; +exports.formatSchedulerPayloadForLog = formatSchedulerPayloadForLog; +exports.formatStatusPayloadForLog = formatStatusPayloadForLog; +exports.formatVerisenseChargerStatus = formatVerisenseChargerStatus; +exports.formatVerisenseFirmwareVersion = formatVerisenseFirmwareVersion; +exports.formatVerisenseHardwareRevision = formatVerisenseHardwareRevision; +exports.formatVerisenseUnixAndHuman = formatVerisenseUnixAndHuman; +exports.getFirstPayloadIndex = getFirstPayloadIndex; +exports.getOversamplingRatioADS1292R = getOversamplingRatioADS1292R; +exports.getVerisenseCalibrationSensorAvailability = getVerisenseCalibrationSensorAvailability; +exports.getVerisenseCalibrationSensors = getVerisenseCalibrationSensors; +exports.getVerisenseHardwareCapabilities = getVerisenseHardwareCapabilities; +exports.getVerisenseHardwareFriendlyName = getVerisenseHardwareFriendlyName; +exports.getVerisenseHardwareRevision = getVerisenseHardwareRevision; +exports.getVerisenseHardwareSensorSupport = getVerisenseHardwareSensorSupport; +exports.getVerisenseStreamSensorLabel = getVerisenseStreamSensorLabel; +exports.getVerisenseStreamingBatteryVoltageMultiplier = getVerisenseStreamingBatteryVoltageMultiplier; +exports.getVerisenseSupportedOperationalFieldGroupIds = getVerisenseSupportedOperationalFieldGroupIds; +exports.hhmmToMinutesSinceMidnight = hhmmToMinutesSinceMidnight; +exports.inferVerisenseChargerChipFamily = inferVerisenseChargerChipFamily; +exports.inferVerisenseLookupBankCount = inferVerisenseLookupBankCount; +exports.isAckCommand = isAckCommand; +exports.isNackCommand = isNackCommand; +exports.isRoutineVerisenseDfuLogMessage = isRoutineVerisenseDfuLogMessage; +exports.isSafeFirmwareArchiveName = isSafeFirmwareArchiveName; +exports.isUniformByteArray = isUniformByteArray; +exports.isVerisenseGsrSupportedHardware = isVerisenseGsrSupportedHardware; +exports.isVerisenseLightDarkChannelEnabled = isVerisenseLightDarkChannelEnabled; +exports.isVerisenseSecondGenerationHardware = isVerisenseSecondGenerationHardware; +exports.minutesSinceMidnightToHHMM = minutesSinceMidnightToHHMM; +exports.nextAvailableDuplicateFileName = nextAvailableDuplicateFileName; +exports.normalizeBytePayload = normalizeBytePayload; +exports.normalizeOperationalConfig = normalizeOperationalConfig; +exports.nudgeGsrResistance = nudgeGsrResistance; +exports.padVerisenseOperationalConfig = padVerisenseOperationalConfig; +exports.parseBleLinkDebugPayload = parseBleLinkDebugPayload; +exports.parseCalibrationBlob = parseCalibrationBlob; +exports.parseEventLogPayload = parseEventLogPayload; +exports.parseHeader = parseHeader; +exports.parseHexByteString = parseHexByteString; +exports.parseLookupTablePayload = parseLookupTablePayload; +exports.parseMessage = parseMessage; +exports.parsePayloadCrcErrorBankIndexes = parsePayloadCrcErrorBankIndexes; +exports.parsePendingEvents = parsePendingEvents; +exports.parseProductionConfigPayload = parseProductionConfigPayload; +exports.parseProductionConfigPayloadFull = parseProductionConfigPayloadFull; +exports.parseRecordBufferDetailsPayload = parseRecordBufferDetailsPayload; +exports.parseSchedulerDebugPayload = parseSchedulerDebugPayload; +exports.parseStatusPayload = parseStatusPayload; +exports.parseVerisenseAdvertisedName = parseVerisenseAdvertisedName; +exports.patchSecureDfuSendOperation = patchSecureDfuSendOperation; +exports.promiseWithTimeout = promiseWithTimeout; +exports.readVerisenseOperationalFieldValue = readVerisenseOperationalFieldValue; +exports.resolveVerisenseSensorRateFieldKey = resolveVerisenseSensorRateFieldKey; +exports.runVerisenseDfuUpdate = runVerisenseDfuUpdate; +exports.serializeCalibrationBlob = serializeCalibrationBlob; +exports.setVerisenseDfuModeWithRetry = setVerisenseDfuModeWithRetry; +exports.setVerisenseOperationalBitRange = setVerisenseOperationalBitRange; +exports.supportsVerisenseCalibration = supportsVerisenseCalibration; +exports.supportsVerisenseMagnetometer = supportsVerisenseMagnetometer; +exports.unixSecondsToAsmRtcBytes = unixSecondsToAsmRtcBytes; +exports.unixSecondsToCalibTsBytes = unixSecondsToCalibTsBytes; +exports.updateVerisenseDfuImageWithRetry = updateVerisenseDfuImageWithRetry; +exports.verisenseDeviceFileTag = verisenseDeviceFileTag; +exports.verisenseDfuAttemptLabel = verisenseDfuAttemptLabel; +exports.writeVerisenseOperationalFieldValue = writeVerisenseOperationalFieldValue; +//# sourceMappingURL=shimmer-web-sdk.cjs.map diff --git a/Verisense/vendor/shimmer-web-sdk.cjs.map b/Verisense/vendor/shimmer-web-sdk.cjs.map new file mode 100644 index 0000000..838b208 --- /dev/null +++ b/Verisense/vendor/shimmer-web-sdk.cjs.map @@ -0,0 +1 @@ +{"version":3,"file":"shimmer-web-sdk.cjs","sources":["../src/core/ObjectCluster.ts","../src/core/BaseShimmerClient.ts","../src/core/arrayBuffer.ts","../src/core/csv.ts","../src/core/RtcDriftMonitor.ts","../src/core/StreamStats.ts","../src/devices/shimmer3r/constants.ts","../src/devices/shimmer3r/SensorBitmap.ts","../src/devices/shimmer3r/channelFormats.ts","../src/devices/shimmer3r/calibration.ts","../src/devices/shimmer3r/protocol.ts","../src/devices/shimmer3r/Shimmer3RClient.ts","../src/devices/verisense/constants.ts","../src/devices/verisense/protocolUtils.ts","../src/devices/verisense/calibration.ts","../src/devices/verisense/protocolMessage.ts","../src/devices/verisense/protocolDataFlow.ts","../src/devices/verisense/hardwareModels.ts","../src/devices/verisense/operationalConfig.ts","../src/devices/verisense/sensors/SensorBase.ts","../src/devices/verisense/sensors/SensorADC.ts","../src/devices/verisense/sensors/SensorLIS2DW12.ts","../src/devices/verisense/sensors/SensorLSM6DS3.ts","../src/devices/verisense/sensors/SensorLSM6DSV.ts","../src/devices/verisense/sensors/SensorPPG.ts","../src/devices/verisense/sensors/SensorVD6283.ts","../src/devices/verisense/sensors/SensorMAX32674.ts","../src/devices/verisense/sensors/SensorMLX90632.ts","../src/devices/verisense/requestValidation.ts","../src/devices/verisense/VerisenseClient.ts","../src/devices/verisense/dfu.ts","../src/devices/verisense/calibrationDefaults.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"names":["u16le","u24le"],"mappings":"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"} \ No newline at end of file diff --git a/Verisense/vendor/shimmer-web-sdk.d.ts b/Verisense/vendor/shimmer-web-sdk.d.ts new file mode 100644 index 0000000..892d022 --- /dev/null +++ b/Verisense/vendor/shimmer-web-sdk.d.ts @@ -0,0 +1,3736 @@ +/** + * Discriminated kind tag for a data field in an ObjectCluster. + */ +type FieldKind = 'raw' | 'cal' | null; +/** + * A single named field stored inside an ObjectCluster. + */ +interface SensorField { + /** Signal name, e.g. 'GYRO_X', 'GSR', 'TIMESTAMP'. */ + name: string; + /** Numeric value. */ + value: number; + /** Optional unit string, e.g. 'deg/s', 'µS', 'ticks'. */ + unit: string | null; + /** Whether the value is raw ADC counts or calibrated engineering units. */ + kind: FieldKind; +} +/** + * Constructor options common to all Shimmer device clients. + */ +interface ShimmerClientOptions { + /** Enable verbose console logging. Defaults to `true`. */ + debug?: boolean; +} +/** + * Contract that every Shimmer device client must satisfy. + * + * Both `Shimmer3RClient` and `VerisenseBleDevice` implement this interface, + * allowing application code to remain device-agnostic for the common operations. + */ +interface IShimmerClient { + /** Open a BLE connection to the device (triggers the browser picker). */ + connect(...args: unknown[]): Promise; + /** Close the BLE connection. */ + disconnect(...args: unknown[]): Promise; + /** Start streaming sensor data. */ + startStreaming(): Promise; + /** Stop streaming sensor data. */ + stopStreaming(): Promise; + /** + * Called for every decoded data frame while streaming. + * For Shimmer3R this delivers an ObjectCluster; for Verisense it delivers + * a raw streaming packet (see `VerisenseBleDevice` for the exact shape). + */ + onStreamFrame: ((frame: ObjectCluster) => void) | null; + /** Called whenever the client emits a human-readable status message. */ + onStatus: ((msg: string) => void) | null; +} +/** + * Calibration parameters for a single inertial axis. + */ +interface InertialCalibration { + /** Zero-g or zero-rate offset. */ + offset: [number, number, number]; + /** 3×3 alignment/cross-axis correction matrix (row-major). */ + align: [[number, number, number], [number, number, number], [number, number, number]]; + /** Per-axis sensitivity in LSB/unit. */ + sensitivity: [number, number, number]; +} + +/** + * Container for a single decoded sensor frame. + * + * Mirrors the ObjectCluster concept from the Shimmer C# SDK: + * a named, typed bag of raw and calibrated signal values produced + * by parsing one data packet from a device. + * + * @example + * ```ts + * const oc = new ObjectCluster('MyShimmer3R'); + * oc.add('GYRO_X', rawVal, null, 'raw'); + * oc.add('GYRO_X', degPerSec, 'deg/s', 'cal'); + * + * const cal = oc.get('GYRO_X', 'cal'); + * console.log(cal?.value, cal?.unit); // e.g. 12.5 "deg/s" + * ``` + */ +declare class ObjectCluster { + /** Identifier of the source device (typically the BLE device name). */ + readonly deviceId: string; + /** All signal fields decoded from this frame. */ + readonly fields: SensorField[]; + /** + * The original unparsed byte array for this frame. + * Populated by protocol parsers that keep the raw bytes for debug purposes. + */ + raw: Uint8Array | null; + constructor(deviceId: string); + /** + * Append a named field to this cluster. + * + * @param name Signal name, e.g. `'GYRO_X'`. + * @param value Numeric value. + * @param unit Optional unit string, e.g. `'deg/s'`, `'µS'`, `'ticks'`. + * @param kind `'raw'` for ADC counts, `'cal'` for calibrated units, or `null`. + */ + add(name: string, value: number, unit?: string | null, kind?: FieldKind): void; + /** + * Look up a field by name and optional kind. + * + * When both a raw and a calibrated version exist for the same signal name, + * pass `kind` to disambiguate. + * + * @returns The matching field, or `null` if not found. + */ + get(name: string, kind?: FieldKind): SensorField | null; + /** + * Return all fields that match the given name (regardless of kind). + */ + getAll(name: string): SensorField[]; +} + +/** + * Abstract base class shared by all Shimmer device clients. + * + * Provides: + * - A `debug` flag and `_log` helper. + * - Stub implementations of `onStatus` and `onStreamFrame` callback properties. + * - Abstract stubs for `connect`, `disconnect`, `startStreaming`, and `stopStreaming` + * that concrete sub-classes must override. + * + * Sub-classes should call `this._emitStatus(msg)` to surface status strings to + * the application layer without depending on a particular event-emitter library. + */ +declare abstract class BaseShimmerClient implements IShimmerClient { + /** Enable verbose console logging. */ + debug: boolean; + /** + * Invoked whenever the client emits a human-readable status message + * (e.g. "GATT connected", "Sampling rate ACKed. Applied ≈ 51.200 Hz"). + */ + onStatus: ((msg: string) => void) | null; + /** + * Invoked for every fully-decoded sensor frame while streaming. + * The exact shape depends on the concrete sub-class: + * - `Shimmer3RClient` passes an {@link ObjectCluster}. + * - `VerisenseBleDevice` passes a streaming packet object (see that class). + */ + onStreamFrame: ((frame: ObjectCluster) => void) | null; + constructor(opts?: ShimmerClientOptions); + /** Log to console when debug is enabled. */ + protected _log(...args: unknown[]): void; + /** Emit a status message to `onStatus` and to the debug log. */ + protected _emitStatus(msg: string): void; + abstract connect(...args: unknown[]): Promise; + abstract disconnect(...args: unknown[]): Promise; + abstract startStreaming(): Promise; + abstract stopStreaming(): Promise; +} + +/** + * True if `bytes` is non-empty and every byte equals `value` (0–255). Useful for + * detecting uniform blobs such as erased flash (all `0xFF`) or zeroed regions. + * Returns false for empty or nullish input. + */ +declare function isUniformByteArray(bytes: ArrayLike | ArrayBuffer | null | undefined, value: number): boolean; + +/** + * Escape a value for a CSV cell (RFC 4180 style): whitespace runs — including + * newlines — collapse to a single space, then cells containing a quote or + * comma are quoted with internal quotes doubled. Null/undefined become the + * empty cell. + */ +declare function csvCell(text: unknown): string; + +/** + * Device RTC drift estimation over a live connection (DEV-844). + * + * Sample the device clock periodically against the host clock and fit a + * least-squares slope of (device − host) offset vs host time: the + * dimensionless slope × 1e6 is directly the crystal error in ppm, giving a + * usable estimate in hours instead of waiting days between connections. + * Device time resolves to 1/32768 s, so per-sample noise is just transport + * round-trip jitter (~tens of ms); the fit averages it out. Host timestamps + * should be taken at the midpoint of the read round-trip, bounding transport + * latency to ±rtt/2. + * + * Host clock steps (NTP corrections) are a measurement hazard: the wall + * clock jumping mid-series pollutes the least-squares slope while looking + * like device drift (seen live on DEV-844: a −1.4 s Windows NTP step bent + * the fit from 1020 to 1077 ppm). Each sample therefore also records a + * monotonic timestamp (`performance.now()`): wall-vs-monotonic divergence + * between samples attributes a jump to the HOST, which resets the fit + * baseline instead of counting as a device step. + * + * This class is pure bookkeeping — the caller owns the sampling timer, the + * device read, and any UI. Feed it one {@link RtcDriftSampleInput} per read. + */ +interface RtcDriftSampleInput { + /** Host wall-clock unix seconds at the midpoint of the device-time read. */ + hostSec: number; + /** Device clock in unix seconds, as read from the device. */ + devSec: number; + /** Read round-trip in ms (kept per sample so outliers are explainable). */ + rttMs: number; + /** Host monotonic clock (e.g. `performance.now()`) in ms at the read. */ + perfMs: number; +} +interface RtcDriftSample extends RtcDriftSampleInput { + /** Device-minus-host clock offset in seconds. */ + offsetSec: number; +} +/** What {@link RtcDriftMonitor.addSample} concluded about a new sample. */ +type RtcDriftSampleEvent = { + kind: 'sample'; + sample: RtcDriftSample; +} +/** The HOST wall clock stepped (NTP): the fit baseline was reset and the + * series restarted from this sample. */ + | { + kind: 'host-step'; + sample: RtcDriftSample; + hostStepSec: number; +} +/** The DEVICE clock stepped between samples. */ + | { + kind: 'device-step'; + sample: RtcDriftSample; + deltaSec: number; +}; +interface RtcDriftMonitorOptions { + /** Offset jump treated as a device clock step (default 1 s). */ + deviceStepThresholdSeconds?: number; + /** Wall-vs-monotonic divergence treated as a host clock step (default 0.5 s). */ + hostStepThresholdSeconds?: number; +} +declare class RtcDriftMonitor { + readonly samples: RtcDriftSample[]; + /** Device clock steps detected across the whole run (survives rebaselines). */ + deviceSteps: number; + /** Host (NTP) clock steps detected; each one rebaselines the fit. */ + hostSteps: number; + private readonly deviceStepThresholdSeconds; + private readonly hostStepThresholdSeconds; + constructor(options?: RtcDriftMonitorOptions); + /** Drop all samples and step counts (e.g. when starting a new run). */ + reset(): void; + /** + * Drop the samples but keep the step counters. Call when the device time is + * written: a time write moves the offset baseline, so every prior sample is + * invalid and the fit must not straddle the discontinuity. + */ + rebaseline(): void; + /** + * Record one device-time reading. Attributes any offset jump before + * recording it: wall-clock elapsed minus monotonic elapsed isolates host + * clock steps (NTP) from device steps. A host step resets the fit baseline + * (the fit must not straddle the discontinuity); a device step is counted + * and kept in-series. + */ + addSample(input: RtcDriftSampleInput): RtcDriftSampleEvent; + /** + * Least-squares slope of offset vs host time, in ppm (offset and time are + * both in seconds, so the dimensionless slope × 1e6 is directly ppm). + * Null until two samples spanning a non-zero interval exist. + */ + ppmFit(): number | null; + /** Elapsed span of the current sample series in minutes (0 when empty). */ + elapsedMinutes(): number; + /** + * CSV rows (header first) of the current series, matching the DEV-844 + * export format: host ISO time, host/device unix seconds, offset, rtt, + * monotonic seconds. + */ + toCsvRows(): string[]; +} + +/** + * Device-agnostic live stream statistics: throughput, packet rate and + * sample-gap-derived packet loss for a real-time sensor stream. + * + * The tracker is fed one call per received packet ({@link StreamStatsTracker.recordPacket}) + * and produces a {@link StreamStatsSnapshot} on demand ({@link StreamStatsTracker.snapshot}). + * + * Loss is derived from gaps in each sub-stream's *monotonic device clock* + * (`lastSampleMillis`), NOT host receive time — host BLE buffering bunches + * packets together and would otherwise create false gaps. Throughput and packet + * rate, by contrast, are measured over a sliding window of host receive time + * (`recvMillis`), which is what "bytes per wall-clock second" means. + */ +/** + * One sub-stream's contribution from a single decoded packet. A sensor that + * carries a single stream emits one of these per packet; a sensor whose FIFO + * interleaves multiple streams (e.g. the LSM6DSV accel/gyro/mag) emits one per + * active sub-stream. + */ +interface StreamContribution { + /** Unique key per sub-stream, e.g. `"2"` or `"6:accel"`. */ + key: string; + /** Human label, e.g. `"Accel"`. */ + label: string; + /** Configured/expected rate for this sub-stream, or null if unknown. */ + samplingRateHz: number | null; + /** Number of samples of this sub-stream in this packet. */ + sampleCount: number; + /** Min `tsMillis` (monotonic device clock) of this sub-stream in this packet. */ + firstSampleMillis: number | null; + /** Max `tsMillis` (monotonic device clock) of this sub-stream in this packet. */ + lastSampleMillis: number | null; +} +/** Per-sub-stream loss/rate accounting in a snapshot. */ +interface StreamLossStats { + key: string; + sensorId: number; + label: string; + samplingRateHz: number | null; + samples: number; + expectedSamples: number; + lostSamples: number; + lossPct: number; + /** Achieved sample rate over the sliding window (samples/sec). */ + windowSampleRateHz: number; + lastSampleMillis: number | null; +} +/** Per-sensor rollup in a snapshot. */ +interface SensorStreamStats { + sensorId: number; + packets: number; + bytes: number; + crcFails: number; + /** Windowed throughput for this sensor's frames (bytes/sec). */ + windowThroughputBps: number; + /** Windowed packet rate for this sensor (packets/sec). */ + windowPacketRateHz: number; + streams: StreamLossStats[]; +} +/** Full snapshot of stream statistics at a point in time. */ +interface StreamStatsSnapshot { + durationMillis: number; + totalPackets: number; + totalSamples: number; + totalBytes: number; + totalCrcFails: number; + /** + * Bytes discarded while re-locking onto frame boundaries after the stream lost + * sync (e.g. dropped bytes on a weak BLE link). 0 on a healthy stream; a rising + * count means data was lost on the wire but the parser is recovering cleanly. + */ + resyncDroppedBytes: number; + /** Overall windowed bytes/sec across all sensors. */ + throughputBps: number; + /** Aggregate lostSamples / expectedSamples * 100. */ + lossPct: number; + perSensor: Record; +} +/** + * Accumulates live statistics for one streaming session. Call {@link reset} on + * (re)start, {@link recordPacket} for every decoded packet, {@link recordCrcFail} + * for CRC failures, and {@link snapshot} to read the current numbers. + */ +declare class StreamStatsTracker { + private readonly windowMillis; + private sessionStartMillis; + private resyncDroppedBytes; + private readonly sensors; + private readonly streams; + constructor(opts?: { + windowMillis?: number; + }); + /** Clear all state. Call when streaming (re)starts. */ + reset(): void; + private getSensor; + private getStream; + /** Record one received (and decoded) streaming packet. */ + recordPacket(p: { + sensorId: number; + byteLength: number; + crcOk: boolean | null; + recvMillis: number; + contributions: StreamContribution[]; + }): void; + /** Record a CRC failure for a (possibly unknown) sensor. */ + recordCrcFail(sensorId?: number): void; + /** + * Record bytes discarded while re-synchronising the frame parser after the + * stream lost alignment (typically a flaky link dropping bytes mid-stream). + */ + recordResyncDrop(byteCount?: number): void; + private prune; + /** + * Cadence-relative stall test: a stream is "stalled" only if its newest packet + * is older than a multiple of its own observed packet interval (floored at the + * window). This keeps a stalled stream reading 0 while NOT zeroing a healthy + * stream that simply delivers less often than the window (big FIFO reads, slow + * sensors). Events carry a receive time `t`. + */ + private isStalled; + /** + * Achieved sample rate for a sub-stream's windowed events. + * + * Measured over the *device-clock* span of the samples — from the first + * sample of the oldest packet to the last sample of the newest packet (their + * tsMillis), not the host receive-time window. This is robust to bursty BLE + * delivery AND to large packets: one packet can carry hundreds of samples + * spanning several seconds (e.g. a high FIFO watermark), so dividing its count + * by the fixed receive window would over-report. Using the samples' own + * device-time span gives the true rate even from a single packet. A stream + * whose newest packet is older than a cadence-relative threshold reads 0 (see + * {@link isStalled}). + */ + private windowRateHz; + /** + * Windowed throughput (bytes/sec) and packet rate over the *actual* receive + * span of the retained events, robust to packets that arrive less often than + * the window. Bytes/packets are counted after the oldest event (the span's + * start point). Returns 0 if the stream is stalled (see {@link isStalled}). + */ + private windowThroughput; + /** Produce a snapshot of all statistics as of `nowMillis`. */ + snapshot(nowMillis: number): StreamStatsSnapshot; +} + +/** + * Shimmer3R BLE protocol opcodes. + * Values taken directly from the Shimmer3 firmware header. + */ +declare const OPCODES: Readonly<{ + readonly DATA_PACKET: 0; + readonly INQUIRY_COMMAND: 1; + readonly INQUIRY_RESPONSE: 2; + readonly GET_SAMPLING_RATE_COMMAND: 3; + readonly SAMPLING_RATE_RESPONSE: 4; + readonly SET_SAMPLING_RATE_COMMAND: 5; + readonly TOGGLE_LED_COMMAND: 6; + readonly START_STREAMING_COMMAND: 7; + readonly SET_SENSORS_COMMAND: 8; + readonly SET_WR_ACCEL_RANGE_COMMAND: 9; + readonly WR_ACCEL_RANGE_RESPONSE: 10; + readonly GET_WR_ACCEL_RANGE_COMMAND: 11; + readonly SET_CONFIG_SETUP_BYTES_COMMAND: 14; + readonly CONFIG_SETUP_BYTES_RESPONSE: 15; + readonly GET_CONFIG_SETUP_BYTES_COMMAND: 16; + readonly SET_LN_ACCEL_CALIBRATION_COMMAND: 17; + readonly LN_ACCEL_CALIBRATION_RESPONSE: 18; + readonly GET_LN_ACCEL_CALIBRATION_COMMAND: 19; + readonly SET_GYRO_CALIBRATION_COMMAND: 20; + readonly GYRO_CALIBRATION_RESPONSE: 21; + readonly GET_GYRO_CALIBRATION_COMMAND: 22; + readonly SET_MAG_CALIBRATION_COMMAND: 23; + readonly MAG_CALIBRATION_RESPONSE: 24; + readonly GET_MAG_CALIBRATION_COMMAND: 25; + readonly SET_WR_ACCEL_CALIBRATION_COMMAND: 26; + readonly WR_ACCEL_CALIBRATION_RESPONSE: 27; + readonly GET_WR_ACCEL_CALIBRATION_COMMAND: 28; + readonly STOP_STREAMING_COMMAND: 32; + readonly SET_GSR_RANGE_COMMAND: 33; + readonly GSR_RANGE_RESPONSE: 34; + readonly GET_GSR_RANGE_COMMAND: 35; + readonly DEVICE_VERSION_RESPONSE: 37; + readonly GET_ALL_CALIBRATION_COMMAND: 44; + readonly ALL_CALIBRATION_RESPONSE: 45; + readonly GET_FW_VERSION_COMMAND: 46; + readonly FW_VERSION_RESPONSE: 47; + readonly SET_CHARGE_STATUS_LED_COMMAND: 48; + readonly CHARGE_STATUS_LED_RESPONSE: 49; + readonly GET_CHARGE_STATUS_LED_COMMAND: 50; + readonly BUFFER_SIZE_RESPONSE: 53; + readonly GET_BUFFER_SIZE_COMMAND: 54; + readonly SET_MAG_GAIN_COMMAND: 55; + readonly MAG_GAIN_RESPONSE: 56; + readonly GET_MAG_GAIN_COMMAND: 57; + readonly SET_MAG_SAMPLING_RATE_COMMAND: 58; + readonly MAG_SAMPLING_RATE_RESPONSE: 59; + readonly GET_MAG_SAMPLING_RATE_COMMAND: 60; + readonly UNIQUE_SERIAL_RESPONSE: 61; + readonly GET_UNIQUE_SERIAL_COMMAND: 62; + readonly GET_DEVICE_VERSION_COMMAND: 63; + readonly SET_WR_ACCEL_SAMPLING_RATE_COMMAND: 64; + readonly WR_ACCEL_SAMPLING_RATE_RESPONSE: 65; + readonly GET_WR_ACCEL_SAMPLING_RATE_COMMAND: 66; + readonly SET_WR_ACCEL_LPMODE_COMMAND: 67; + readonly WR_ACCEL_LPMODE_RESPONSE: 68; + readonly GET_WR_ACCEL_LPMODE_COMMAND: 69; + readonly SET_WR_ACCEL_HRMODE_COMMAND: 70; + readonly WR_ACCEL_HRMODE_RESPONSE: 71; + readonly GET_WR_ACCEL_HRMODE_COMMAND: 72; + readonly SET_GYRO_RANGE_COMMAND: 73; + readonly GYRO_RANGE_RESPONSE: 74; + readonly GET_GYRO_RANGE_COMMAND: 75; + readonly SET_GYRO_SAMPLING_RATE_COMMAND: 76; + readonly GYRO_SAMPLING_RATE_RESPONSE: 77; + readonly GET_GYRO_SAMPLING_RATE_COMMAND: 78; + readonly SET_ALT_ACCEL_RANGE_COMMAND: 79; + readonly ALT_ACCEL_RANGE_RESPONSE: 80; + readonly GET_ALT_ACCEL_RANGE_COMMAND: 81; + readonly SET_PRESSURE_OVERSAMPLING_RATIO_COMMAND: 82; + readonly PRESSURE_OVERSAMPLING_RATIO_RESPONSE: 83; + readonly GET_PRESSURE_OVERSAMPLING_RATIO_COMMAND: 84; + readonly BMP180_CALIBRATION_COEFFICIENTS_RESPONSE: 88; + readonly GET_BMP180_CALIBRATION_COEFFICIENTS_COMMAND: 89; + readonly RESET_TO_DEFAULT_CONFIGURATION_COMMAND: 90; + readonly RESET_CALIBRATION_VALUE_COMMAND: 91; + readonly MPU9150_MAG_SENS_ADJ_VALS_RESPONSE: 92; + readonly GET_MPU9150_MAG_SENS_ADJ_VALS_COMMAND: 93; + readonly SET_INTERNAL_EXP_POWER_ENABLE_COMMAND: 94; + readonly INTERNAL_EXP_POWER_ENABLE_RESPONSE: 95; + readonly GET_INTERNAL_EXP_POWER_ENABLE_COMMAND: 96; + readonly SET_EXG_REGS_COMMAND: 97; + readonly EXG_REGS_RESPONSE: 98; + readonly GET_EXG_REGS_COMMAND: 99; + readonly SET_DAUGHTER_CARD_ID_COMMAND: 100; + readonly DAUGHTER_CARD_ID_RESPONSE: 101; + readonly GET_DAUGHTER_CARD_ID_COMMAND: 102; + readonly SET_DAUGHTER_CARD_MEM_COMMAND: 103; + readonly DAUGHTER_CARD_MEM_RESPONSE: 104; + readonly GET_DAUGHTER_CARD_MEM_COMMAND: 105; + readonly SET_DERIVED_CHANNEL_BYTES: 109; + readonly DERIVED_CHANNEL_BYTES_RESPONSE: 110; + readonly GET_DERIVED_CHANNEL_BYTES: 111; + readonly START_SDBT_COMMAND: 112; + readonly STATUS_RESPONSE: 113; + readonly GET_STATUS_COMMAND: 114; + readonly SET_TRIAL_CONFIG_COMMAND: 115; + readonly TRIAL_CONFIG_RESPONSE: 116; + readonly GET_TRIAL_CONFIG_COMMAND: 117; + readonly SET_CENTER_COMMAND: 118; + readonly CENTER_RESPONSE: 119; + readonly GET_CENTER_COMMAND: 120; + readonly SET_SHIMMERNAME_COMMAND: 121; + readonly SHIMMERNAME_RESPONSE: 122; + readonly GET_SHIMMERNAME_COMMAND: 123; + readonly SET_EXPID_COMMAND: 124; + readonly EXPID_RESPONSE: 125; + readonly GET_EXPID_COMMAND: 126; + readonly SET_MYID_COMMAND: 127; + readonly MYID_RESPONSE: 128; + readonly GET_MYID_COMMAND: 129; + readonly SET_NSHIMMER_COMMAND: 130; + readonly NSHIMMER_RESPONSE: 131; + readonly GET_NSHIMMER_COMMAND: 132; + readonly SET_CONFIGTIME_COMMAND: 133; + readonly CONFIGTIME_RESPONSE: 134; + readonly GET_CONFIGTIME_COMMAND: 135; + readonly DIR_RESPONSE: 136; + readonly GET_DIR_COMMAND: 137; + readonly INSTREAM_CMD_RESPONSE: 138; + readonly SET_CRC_COMMAND: 139; + readonly SET_INFOMEM_COMMAND: 140; + readonly INFOMEM_RESPONSE: 141; + readonly GET_INFOMEM_COMMAND: 142; + readonly SET_RWC_COMMAND: 143; + readonly RWC_RESPONSE: 144; + readonly GET_RWC_COMMAND: 145; + readonly START_LOGGING_COMMAND: 146; + readonly STOP_LOGGING_COMMAND: 147; + readonly VBATT_RESPONSE: 148; + readonly GET_VBATT_COMMAND: 149; + readonly TEST_CONNECTION_COMMAND: 150; + readonly STOP_SDBT_COMMAND: 151; + readonly SET_CALIB_DUMP_COMMAND: 152; + readonly RSP_CALIB_DUMP_COMMAND: 153; + readonly GET_CALIB_DUMP_COMMAND: 154; + readonly UPD_CALIB_DUMP_COMMAND: 155; + readonly UPD_SDLOG_CFG_COMMAND: 156; + readonly BMP280_CALIBRATION_COEFFICIENTS_RESPONSE: 159; + readonly GET_BMP280_CALIBRATION_COEFFICIENTS_COMMAND: 160; + readonly GET_BT_VERSION_STR_COMMAND: 161; + readonly BT_VERSION_STR_RESPONSE: 162; + readonly SET_INSTREAM_RESPONSE_ACK_PREFIX_STATE: 163; + readonly SET_DATA_RATE_TEST: 164; + readonly DATA_RATE_TEST_RESPONSE: 165; + readonly PRESSURE_CALIBRATION_COEFFICIENTS_RESPONSE: 166; + readonly GET_PRESSURE_CALIBRATION_COEFFICIENTS_COMMAND: 167; + readonly SET_FACTORY_TEST: 168; + readonly SET_ALT_ACCEL_CALIBRATION_COMMAND: 169; + readonly ALT_ACCEL_CALIBRATION_RESPONSE: 170; + readonly GET_ALT_ACCEL_CALIBRATION_COMMAND: 171; + readonly SET_ALT_ACCEL_SAMPLING_RATE_COMMAND: 172; + readonly ALT_ACCEL_SAMPLING_RATE_RESPONSE: 173; + readonly GET_ALT_ACCEL_SAMPLING_RATE_COMMAND: 174; + readonly SET_ALT_MAG_CALIBRATION_COMMAND: 175; + readonly ALT_MAG_CALIBRATION_RESPONSE: 176; + readonly GET_ALT_MAG_CALIBRATION_COMMAND: 177; + readonly SET_ALT_MAG_SAMPLING_RATE_COMMAND: 178; + readonly ALT_MAG_SAMPLING_RATE_RESPONSE: 179; + readonly GET_ALT_MAG_SAMPLING_RATE_COMMAND: 180; + readonly DUMMY_COMMAND: 181; + readonly RESET_BT_ERROR_COUNTS: 182; + readonly SET_FEATURE: 183; + readonly SET_SD_SYNC_COMMAND: 224; + readonly SD_SYNC_RESPONSE: 225; + readonly NACK_COMMAND_PROCESSED: 254; + readonly ACK_COMMAND_PROCESSED: 255; +}>; +type Opcode = (typeof OPCODES)[keyof typeof OPCODES]; +/** Default BLE service / characteristic UUIDs for Shimmer3R. */ +declare const SHIMMER3R_DEFAULTS: Readonly<{ + readonly SERVICE_UUID: "65333333-a115-11e2-9e9a-0800200ca100"; + /** Write characteristic (host → device). */ + readonly CHAR_RX_UUID: "65333333-a115-11e2-9e9a-0800200ca102"; + /** Notify characteristic (device → host). */ + readonly CHAR_TX_UUID: "65333333-a115-11e2-9e9a-0800200ca101"; +}>; +/** + * Timestamp field descriptors keyed by width. + * Shimmer3R firmware ≥ v1.0.22 always uses u24. + */ +declare const TIMESTAMP_FIELD: Readonly<{ + readonly u16: { + readonly name: "TIMESTAMP"; + readonly fmt: "u16"; + readonly endian: "le"; + readonly sizeBytes: 2; + }; + readonly u24: { + readonly name: "TIMESTAMP"; + readonly fmt: "u24"; + readonly endian: "le"; + readonly sizeBytes: 3; + }; +}>; +type TimestampFmt = 'u16' | 'u24'; +/** GSR signal name constant used in ObjectCluster fields. */ +declare const GSR_NAME = "GSR"; + +interface ChannelField { + id: number; + name: string; + fmt: string; + endian: string; + sizeBytes: number; +} +interface StreamSchema { + timestampFmt: TimestampFmt; + fields: ChannelField[]; + /** Total bytes per frame, including the 0x00 preamble byte. */ + frameBytes: number; + enabledSensors: number; + dataPreambleByte: number; +} +interface Shimmer3RClientOptions extends ShimmerClientOptions { + /** BLE service UUID override (default: Shimmer3R service UUID). */ + serviceUUID?: string; + /** Write characteristic UUID override. */ + rxUUID?: string; + /** Notify characteristic UUID override. */ + txUUID?: string; + /** + * Force a specific timestamp width. + * Shimmer3R firmware ≥ v1.0.22 uses 24-bit timestamps. + * @default 'u24' + */ + timestampFmt?: TimestampFmt; +} +/** + * Web Bluetooth client for the Shimmer3R sensor platform. + * + * Implements the ACK-first command flow used by Shimmer3R firmware ≥ v1.0.22: + * every configuration command awaits an ACK (0xFF) before resolving. + * Streaming data frames are framed with a DATA preamble (0x00). + * + * @example + * ```ts + * const client = new Shimmer3RClient({ timestampFmt: 'u24', debug: true }); + * client.onStatus = (msg) => console.log(msg); + * client.onStreamFrame = (oc) => { + * const gz = oc.get('GYRO_Z', 'raw')?.value; + * console.log('gz =', gz); + * }; + * + * await client.connect(); + * await client.setSamplingRate(51.2); + * await client.setSensors(SensorBitmapShimmer3.SENSOR_GYRO); + * await client.startStreaming(); + * ``` + */ +declare class Shimmer3RClient extends BaseShimmerClient { + private serviceUUID; + private rxUUID; + private txUUID; + device: BluetoothDevice | null; + private server; + private rx; + private tx; + private _rxBuf; + private _temps; + private schema; + private forceTimestampFmt; + private _lastAckRemainder; + private _expectingAck; + private _streaming; + private _lastTs; + enabledSensors: number; + samplingRateHz: number; + gsrRangeSetting: number; + ExpPower: number; + /** Minimum valid GSR conductance in µS (below this, connectivity = "Disconnected"). */ + readonly LIMIT_MIN_VALID_USIEMENS = 0.03; + onInquiry: ((info: ReturnType) => void) | null; + onExpPowerChanged: ((expPower: number) => void) | null; + constructor(opts?: Shimmer3RClientOptions); + protected _log(...args: unknown[]): void; + connect(): Promise; + disconnect(): Promise; + private _handleNotify; + /** + * Control the internal expansion power rail (required for ExG/EMG/ECG). + * @param expPower 0 = disable, 1 = enable. + */ + setInternalExpPower(expPower: 0 | 1): Promise<{ + expPower: number; + ackRemainder: Uint8Array | null; + }>; + /** + * Set the GSR measurement range. + * @param gsrRange 0 = 8–63 kΩ, 1 = 63–220 kΩ, 2 = 220–680 kΩ, 3 = 680–4700 kΩ, 4 = Auto. + */ + setGSRRange(gsrRange: number): Promise<{ + gsrRange: number; + ackRemainder: Uint8Array | null; + }>; + getInternalExpPower(): number; + getEnabledSensors(): number; + /** + * Enable sensors via a 24-bit bitmask. + * Automatically performs an Inquiry after ACK to rebuild the stream schema. + */ + setSensors(sensors: number): Promise<{ + sensors: number; + ackRemainder: Uint8Array | null; + enabledSensors: number; + }>; + /** + * Set the sampling rate. + * The firmware expects a 16-bit divisor: `divisor = floor(32768 / rateHz)`. + */ + setSamplingRate(rateHz: number): Promise<{ + requestedHz: number; + appliedHz: number; + divisor: number; + ackRemainder: Uint8Array | null; + }>; + /** Send INQUIRY_CMD and parse the response to build the stream schema. */ + inquiry(): Promise<{ + opcode: number; + adcRaw: number; + samplingRateHz: number; + numChannels: number; + bufferSize: number; + channelIds: number[]; + schema: StreamSchema; + bytes: Uint8Array; + }>; + /** Enable EMG (ADS1292R) in 16-bit mode on EXG1 & EXG2. */ + enableEMG16Bit(): Promise; + /** Enable EXG test signal in 16-bit mode (useful for verifying ExG hardware). */ + enableEXGTestSignal16Bit(): Promise; + /** Enable ECG in 16-bit mode on EXG1 & EXG2. */ + enableECG16Bit(): Promise; + private _writeExgPages; + startStreaming(): Promise; + stopStreaming(): Promise; + /** Start streaming AND SD card logging simultaneously. */ + startStreamingAndLogging(): Promise; + /** Stop streaming AND SD card logging. */ + stopStreamingAndLogging(): Promise; + private _interpretInquiryResponseShimmer3R; + private _buildSchemaFromChannels; + private _calibrateData; + private _parseBySchema; + private _write; + private _writeExpectingAck; + private _waitForAck; + private _waitForResponse; + private _onTemp; + private _offTemp; + private _emitTemp; +} + +/** + * Sensor enable bitmasks for Shimmer3 / Shimmer3R. + * + * Values are 24-bit integers sent as the payload of SET_SENSORS_CMD. + * Multiple sensors are ORed together. + * + * @example + * ```ts + * const mask = SensorBitmapShimmer3.SENSOR_GYRO | SensorBitmapShimmer3.SENSOR_A_ACCEL; + * await client.setSensors(mask); + * ``` + */ +declare const SensorBitmapShimmer3: Readonly<{ + readonly SENSOR_A_ACCEL: 128; + readonly SENSOR_GYRO: 64; + readonly SENSOR_MAG: 32; + readonly SENSOR_GSR: 4; + readonly SENSOR_VBATT: 8192; + readonly SENSOR_D_ACCEL: 4096; + readonly SENSOR_PRESSURE: 262144; + readonly SENSOR_EXG1_24BIT: 16; + readonly SENSOR_EXG2_24BIT: 8; + readonly SENSOR_EXG1_16BIT: 1048576; + readonly SENSOR_EXG2_16BIT: 524288; + readonly SENSOR_BRIDGE_AMP: 32768; + readonly SENSOR_ACCEL_ALT: 4194304; + readonly SENSOR_MAG_ALT: 2097152; + readonly SENSOR_EXT_A0: 2; + readonly SENSOR_EXT_A1: 1; + readonly SENSOR_EXT_A2: 2048; + readonly SENSOR_INT_A3: 1024; + readonly SENSOR_INT_A0: 512; + readonly SENSOR_INT_A1: 256; + readonly SENSOR_INT_A2: 8388608; +}>; +type SensorBitmapShimmer3Key = keyof typeof SensorBitmapShimmer3; + +/** + * Channel format descriptor for a single Shimmer3R data channel. + */ +interface ChannelFormat { + /** Human-readable signal name stored in ObjectCluster fields. */ + name: string; + /** Encoding format: i16, u16, i24, u24, i12*, u8. */ + fmt: 'i16' | 'u16' | 'i24' | 'u24' | 'i12*' | 'u8'; + /** Byte order for multi-byte values. */ + endian: 'le' | 'be'; + /** Number of bytes this channel occupies in the packet. */ + sizeBytes: number; +} +/** + * Mapping from Shimmer3R channel ID byte to its format descriptor. + * Channel IDs are reported in the INQUIRY_RSP payload. + */ +declare const CHANNEL_FORMATS: Readonly>; + +/** + * Convert a Shimmer3R 12-bit ADC value to millivolts. + * + * @param unCalData Raw 12-bit ADC sample. + * @param offset ADC offset (typically 0). + * @param vRefP Reference voltage in volts (typically 3 V for Shimmer3R). + * @param gain Amplifier gain (typically 1). + * @returns Calibrated voltage in millivolts. + */ +declare function calibrateU12AdcValue(unCalData: number, offset: number, vRefP: number, gain: number): number; +/** + * Convert a Shimmer3R ADC channel value to millivolts using the + * default Shimmer3R ADC parameters (Vref = 3 V, gain = 1, offset = 0). + * + * @param unCalData Raw 12-bit ADC sample. + * @returns Voltage in millivolts. + */ +declare function calibrateShimmer3RAdcChannel(unCalData: number): number; +/** + * Convert a raw GSR ADC sample to skin resistance (kΩ) using the + * Shimmer3R amplifier equation. + * + * Reference resistors per range (kΩ): [40.2, 287.0, 1000.0, 3300.0]. + * + * @param gsrUncalibratedData Raw 12-bit GSR ADC value. + * @param range Hardware range index 0–3. + * @returns Resistance in kΩ. + */ +declare function calibrateGsrDataToResistanceFromAmplifierEq(gsrUncalibratedData: number, range: number): number; +/** + * Clamp a GSR resistance value to the physical limits of a given range. + * + * When `gsrRangeSetting === 4` (auto-range) no clamping is applied. + * + * @param gsrResistanceKOhms Calibrated resistance in kΩ. + * @param gsrRangeSetting Range 0–3 (fixed) or 4 (auto). + * @returns Clamped resistance in kΩ. + */ +declare function nudgeGsrResistance(gsrResistanceKOhms: number, gsrRangeSetting: number): number; +/** + * Determine the ADS1292R oversampling ratio config byte for a given + * Shimmer3R sampling rate. + * + * This value is ORed into the lower 3 bits of ExG config byte index 4. + * + * @param samplingRate Shimmer3R sampling rate in Hz (must be ≥ 0). + * @returns Oversampling ratio index 0–6. + */ +declare function getOversamplingRatioADS1292R(samplingRate: number): number; + +/** NUS primary service UUID. */ +declare const NUS_SERVICE = "6e400001-b5a3-f393-e0a9-e50e24dcca9e"; +/** NUS TX characteristic UUID (host writes to this). */ +declare const NUS_TX = "6e400002-b5a3-f393-e0a9-e50e24dcca9e"; +/** NUS RX characteristic UUID (host subscribes to notifications from this). */ +declare const NUS_RX = "6e400003-b5a3-f393-e0a9-e50e24dcca9e"; +/** Nordic Secure DFU service UUID (buttonless DFU). */ +declare const NORDIC_DFU_SERVICE = "0000fe59-0000-1000-8000-00805f9b34fb"; +/** Nordic buttonless DFU control-point characteristic (without bond sharing). */ +declare const NORDIC_DFU_BUTTONLESS_WITHOUT_BONDS = "8ec90003-f315-4f60-9fb8-838830daea50"; +/** Nordic buttonless DFU control-point characteristic (with bond sharing). */ +declare const NORDIC_DFU_BUTTONLESS_WITH_BONDS = "8ec90004-f315-4f60-9fb8-838830daea50"; +/** Buttonless DFU control-point op-code that reboots the device into the bootloader. */ +declare const NORDIC_DFU_OP_ENTER_BOOTLOADER = 1; +/** Upper-nibble command classes used in protocol headers. */ +declare const ASM_COMMAND: Readonly<{ + readonly READ: 16; + readonly WRITE: 32; + readonly RESPONSE: 48; + readonly ACK: 64; + readonly NACK_BAD_HEADER_COMMAND: 80; + readonly NACK_BAD_HEADER_PROPERTY: 96; + readonly NACK_GENERIC: 112; + readonly ACK_NEXT_STAGE: 128; +}>; +type AsmCommand = (typeof ASM_COMMAND)[keyof typeof ASM_COMMAND]; +/** Lower-nibble property IDs used in protocol headers. */ +declare const ASM_PROPERTY: Readonly<{ + readonly STATUS1: 1; + readonly DATA: 2; + readonly PRODUCTION_CONFIGURATION: 3; + readonly OPERATIONAL_CONFIGURATION: 4; + readonly TIME: 5; + readonly DFU_MODE: 6; + readonly PENDING_EVENTS: 7; + readonly TEST_MODE: 8; + readonly DEBUG_COMMAND: 9; + readonly STREAM_MODE: 10; + readonly DEVICE_DISCONNECT: 11; + readonly STATUS2: 12; + readonly CALIBRATION: 13; +}>; +type AsmProperty = (typeof ASM_PROPERTY)[keyof typeof ASM_PROPERTY]; +/** Stream mode payload values. */ +declare const STREAM_MODE: Readonly<{ + readonly ENABLE: 1; + readonly DISABLE: 2; +}>; +/** Test mode IDs documented by Verisense firmware. */ +declare const TEST_MODE_ID: Readonly<{ + readonly STOP: 0; + readonly FLASH_8MB_1: 1; + readonly FLASH_8MB_2: 2; + readonly FLASH_128MB_512MB: 3; + readonly EEPROM: 4; + readonly ACCEL1_LIS2DW12: 5; + readonly BATTERY_VOLTAGE: 6; + readonly USB_POWER: 7; + readonly ACCEL2_GYRO_LSM6DS3: 8; + readonly PPG_MAX86XXX: 9; + readonly BIOZ_MAX30002: 11; + readonly ACCEL2_GYRO_LSM6DSV: 12; + readonly MAG_LIS2MDL: 13; + readonly ALL_TESTS: 255; +}>; +type TestModeId = (typeof TEST_MODE_ID)[keyof typeof TEST_MODE_ID]; +/** Debug command IDs documented by Verisense firmware. */ +declare const DEBUG_COMMAND_ID: Readonly<{ + readonly FLASH_LOOKUP_TABLE_READ: 1; + readonly FLASH_LOOKUP_TABLE_ERASE: 2; + readonly RWC_SCHEDULER_READ: 3; + readonly ERASE_128MB_512MB_FLASH: 4; + readonly ERASE_8MB_FLASH_1: 5; + readonly ERASE_8MB_FLASH_2: 6; + readonly ERASE_OPERATIONAL_CONFIG: 7; + readonly ERASE_PRODUCTION_CONFIG: 8; + readonly CLEAR_PENDING_EVENTS: 9; + readonly ERASE_FLASH_AND_LOOKUP_TABLE: 10; + readonly TEST_DATA_TRANSFER_LOOP: 11; + readonly LOAD_TEST_LOOKUP_TABLE: 12; + readonly LED_TEST: 13; + readonly MAX86XXX_LED_TEST: 14; + readonly CHECK_PAYLOAD_CRC_ERRORS: 15; + readonly READ_EVENT_LOG: 16; + readonly POWER_PROFILER_TEST: 17; + readonly READ_RECORD_BUFFER_DETAILS: 18; + readonly SYSTEM_RESET: 19; + readonly IC_POWER_CONSUMPTION_TEST: 20; + readonly DELETE_ALL_BONDS: 21; + readonly BLE_LINK_PARAMS_READ: 22; + readonly BLE_LINK_OPTIMIZE: 23; + /** Streamed MAX32674C algorithm-hub firmware (.msbl) upload (factory). The + * byte after this id is a HUB_FW_UPLOAD_STAGE sub-stage. */ + readonly HUB_FW_UPLOAD: 24; +}>; +type DebugCommandId = (typeof DEBUG_COMMAND_ID)[keyof typeof DEBUG_COMMAND_ID]; +/** + * Byte indices into the Verisense operational config blob (`op[OP_IDX.xxx]`). + * Index 0 is the config version byte (must be 0x5A for a valid config). + */ +declare const OP_IDX: Readonly<{ + readonly GEN_CFG_0: 1; + readonly GEN_CFG_1: 2; + readonly GEN_CFG_2: 3; + readonly GEN_CFG_3: 4; + readonly ACCEL1_CFG_0: 5; + readonly ACCEL1_CFG_1: 6; + readonly ACCEL1_CFG_2: 7; + readonly ACCEL1_CFG_3: 8; + readonly GYRO_ACCEL2_CFG_0: 10; + readonly GYRO_ACCEL2_CFG_1: 11; + readonly GYRO_ACCEL2_CFG_2: 12; + readonly GYRO_ACCEL2_CFG_3: 13; + readonly GYRO_ACCEL2_CFG_4: 14; + readonly GYRO_ACCEL2_CFG_5: 15; + readonly GYRO_ACCEL2_CFG_6: 16; + readonly GYRO_ACCEL2_CFG_7: 17; + readonly LSM6DSV_CFG_0: 18; + readonly LSM6DSV_CFG_1: 19; + readonly LSM6DSV_CFG_2: 20; + readonly START_TIME: 21; + readonly END_TIME: 25; + readonly INACTIVE_TIMEOUT: 29; + readonly BLE_RETRY_COUNT: 30; + readonly BLE_TX_POWER: 31; + readonly BLE_DATA_TRANS_WKUP_INT_HRS: 32; + readonly BLE_DATA_TRANS_WKUP_TIME: 33; + readonly BLE_DATA_TRANS_WKUP_DUR: 35; + readonly BLE_DATA_TRANS_RETRY_INT: 36; + readonly BLE_STATUS_WKUP_INT_HRS: 38; + readonly BLE_STATUS_WKUP_TIME: 39; + readonly BLE_STATUS_WKUP_DUR: 41; + readonly BLE_STATUS_RETRY_INT: 42; + readonly BLE_RTC_SYNC_WKUP_INT_HRS: 44; + readonly BLE_RTC_SYNC_WKUP_TIME: 45; + readonly BLE_RTC_SYNC_WKUP_DUR: 47; + readonly BLE_RTC_SYNC_RETRY_INT: 48; + readonly ADC_CHANNEL_SETTINGS_0: 50; + readonly ADC_CHANNEL_SETTINGS_1: 51; + readonly ADAPTIVE_SCHEDULER_INT: 52; + readonly ADAPTIVE_SCHEDULER_FAILCOUNT_MAX: 54; + readonly PPG_REC_DUR_SECS_LSB: 55; + readonly PPG_REC_DUR_SECS_MSB: 56; + readonly PPG_REC_INT_MINS_LSB: 57; + readonly PPG_REC_INT_MINS_MSB: 58; + readonly PPG_FIFO_CONFIG: 59; + readonly PPG_MODE_CONFIG2: 60; + readonly PPG_MA_DEFAULT: 61; + readonly PPG_MA_MAX_RED_IR: 62; + readonly PPG_MA_MAX_GREEN_BLUE: 63; + readonly PPG_AGC_TARGET_PERCENT_OF_RANGE: 64; + readonly PPG_MA_LED_PILOT: 66; + readonly PPG_DAC1_CROSSTALK: 67; + readonly PPG_DAC2_CROSSTALK: 68; + readonly PPG_DAC3_CROSSTALK: 69; + readonly PPG_DAC4_CROSSTALK: 70; + readonly PROX_AGC_MODE: 71; + readonly OP_CONFIG_VERSION: 9; + readonly LIGHT_GAIN_INDEX: 72; + readonly LIGHT_EXPOSURE_INDEX: 73; + readonly LIGHT_CONFIG: 74; + readonly LIGHT_SAMPLE_RATE_INDEX: 75; + readonly SKIN_TEMP_CONFIG: 76; + readonly SKIN_TEMP_SAMPLE_RATE_INDEX: 77; + readonly ALGO_OP_MODE: 78; + readonly ALGO_REPORT_MODE_RATE: 79; + readonly ALGO_CONTROL: 80; + readonly ALGO_INITIAL_HR: 81; + readonly LED_AUTO_BRIGHTNESS_CFG: 82; + readonly LED_MAX_BRIGHTNESS: 83; + readonly LED_LUX_THRESHOLD: 84; + readonly PERSON_HEIGHT_CM: 86; + readonly PERSON_WEIGHT_KG: 88; + readonly PERSON_AGE: 90; + readonly PERSON_GENDER: 91; +}>; +type OpIdx = keyof typeof OP_IDX; +/** Minimum firmware version that supports the BLE-link debug commands + * (read/optimize connection parameters). */ +declare const BLE_LINK_MIN_FW: Readonly<{ + major: 1; + minor: 4; + internal: 23; +}>; +/** Human-readable labels for Verisense stream-packet sensor IDs. Each ID maps to + * the device part(s) that produce that stream (some streams interleave several + * physical sensors, e.g. id 6 = LSM6DSV accel + gyro + mag). */ +declare const VERISENSE_STREAM_SENSOR_LABELS: Readonly<{ + readonly 1: "ADC (GSR / Battery)"; + readonly 2: "Accel 1 (LIS2DW12)"; + readonly 3: "Accel 2 + Gyro (LSM6DS3)"; + readonly 4: "PPG (MAX86xxx)"; + readonly 6: "Accel 2 + Gyro + Mag (LSM6DSV + LIS2MDL)"; + readonly 7: "Ambient Light (VD6283)"; + readonly 8: "Algo Hub (MAX32674 — HR + raw PPG)"; + readonly 9: "Skin Temperature (MLX90632)"; +}>; + +/** + * Verisense sensor-calibration TLV codec. + * + * Mirrors the firmware `asm_calibration.{c,h}` byte format. A calibration "blob" + * is a self-describing block of per-sensor calibration that the device persists, + * exposes over the `CALIBRATION` command, and stamps into every logged payload + * header via a CRC-16 version tag. + * + * Layout (all little-endian): + * + * Global header (12 bytes) + * 0 u16 totalLen (= blob.length - 2) + * 2 u8 calibFormatVersion + * 3 u8 hwVerMajor + * 4 u8 hwVerMinor + * 5 u8 fwVerMajor + * 6 u8 fwVerMinor + * 7 u16 fwVerPatch + * 9 u8 sensorBlockCount + * 10 u16 reserved + * + * Per-sensor block (12-byte header + payload) + * 0 u16 sensorId (calibration-domain id, see {@link CalibSensorId}) + * 2 u8 range/quality (bits[5:0] full-scale index; bits[7:6] calib quality) + * 3 u8 dataLen + * 4 u8[8] ts (0 = default/seeded; RTC time = real per-unit cal) + * 12 payload[dataLen] + * + * IMU payload (60 bytes, float32): bias[3] · sens[3] · align[9] (row-major 3x3) + * + * Calibration math (ASM-DES04 §8): output = K·R·physical + b, so the host + * recovers physical = R⁻¹·K⁻¹·(raw − b). K is the diagonal sensitivity, R the + * rotation into the common ASM axes, b the offset bias. + */ +declare const SC_CALIB_FORMAT_VERSION = 1; +declare const SC_GLOBAL_HEADER_BYTES = 12; +declare const SC_DATA_LEN_IMU = 60; +/** + * The per-block `range` byte packs the full-scale index in bits [5:0] and a 2-bit + * calibration-quality indicator in bits [7:6]. Lookups/comparisons must use only + * the index (`range & SC_CAL_RANGE_MASK`). Quality has no producer yet (always 0), + * so it is reserved without growing the blob or bumping the format version. + */ +declare const SC_CAL_RANGE_MASK = 63; +declare const SC_CAL_QUALITY_SHIFT = 6; +declare const SC_CAL_QUALITY_MASK = 3; +/** Calibration-quality indicator (ST MotionAC / Android sensor-accuracy convention). */ +declare const CalibQuality: { + readonly UNKNOWN: 0; + readonly POOR: 1; + readonly OK: 2; + readonly GOOD: 3; +}; +type CalibQuality = (typeof CalibQuality)[keyof typeof CalibQuality]; +/** + * Calibration-domain sensor IDs. Distinct from the data-stream sensor IDs + * (1=ADC, 2=LIS2DW12, 3=LSM6DS3, 4=PPG, 6=LSM6DSV, 7=VD6283, 8=MAX32674, + * 9=MLX90632). These reuse the Shimmer3 `SC_SENSOR_*` values where they exist, + * so accel/gyro/mag can each carry their own calibration even though one + * data-stream id (6) covers all three. + * + * Data-stream → calibration mapping: 6 → {37, 38, 42}, 2 → {39}, 3 → {40, 41}. + */ +declare const CalibSensorId: { + readonly LSM6DSV_ACCEL: 37; + readonly LSM6DSV_GYRO: 38; + readonly LIS2DW12_ACCEL: 39; + /** 1st-gen LSM6DS3 accel (data-stream id 3). */ + readonly LSM6DS3_ACCEL: 40; + /** 1st-gen LSM6DS3 gyro (data-stream id 3). */ + readonly LSM6DS3_GYRO: 41; + readonly LIS2MDL_MAG: 42; +}; +type CalibSensorId = (typeof CalibSensorId)[keyof typeof CalibSensorId]; +/** Per-unit IMU calibration: offset bias, diagonal sensitivity, and 3x3 rotation. */ +interface ImuCalibration { + /** Offset bias `b`, per axis (sensor LSB). */ + bias: [number, number, number]; + /** Diagonal sensitivity `K`, per axis (LSB per physical unit). */ + sens: [number, number, number]; + /** Rotation `R`, row-major 3x3 (length 9), mapping sensor axes to ASM axes. */ + align: number[]; +} +interface CalibrationBlock { + sensorId: number; + /** Full-scale index (the low 6 bits of the wire `range` byte). */ + range: number; + /** Calibration quality, bits [7:6] of the wire `range` byte (0 = unknown today). */ + quality: number; + dataLen: number; + /** 8-byte calibration timestamp; all-zero means default/seeded. */ + ts: Uint8Array; + isDefault: boolean; + payload: Uint8Array; + /** Decoded IMU calibration when the block is a 60-byte IMU payload. */ + imu?: ImuCalibration; +} +interface CalibrationSet { + formatVersion: number; + hwVerMajor: number; + hwVerMinor: number; + fwVerMajor: number; + fwVerMinor: number; + fwVerPatch: number; + reserved: number; + blocks: CalibrationBlock[]; + /** CRC-16/CCITT-FALSE over the whole blob — equals the payload-header version tag. */ + crc16: number; + /** Find the IMU calibration for a calibration-domain sensor id + range, else null. */ + getImu(sensorId: number, range: number): ImuCalibration | null; +} +/** Parse a calibration blob into a typed, indexable {@link CalibrationSet}. */ +declare function parseCalibrationBlob(blob: Uint8Array): CalibrationSet; +interface CalibrationBlockInput { + sensorId: number; + /** Full-scale index (only the low 6 bits are used). */ + range: number; + /** Calibration quality (0-3); defaults to 0 (unknown). Packed into range byte bits [7:6]. */ + quality?: number; + /** 8-byte timestamp; defaults to all-zero (a "default/seeded" marker). */ + ts?: Uint8Array | null; + imu?: ImuCalibration; + /** Raw payload override (used when `imu` is not supplied). */ + payload?: Uint8Array; +} +interface CalibrationSetInput { + formatVersion?: number; + hwVerMajor: number; + hwVerMinor: number; + fwVerMajor: number; + fwVerMinor: number; + fwVerPatch: number; + reserved?: number; + blocks: CalibrationBlockInput[]; +} +/** Serialize a calibration set into a blob (inverse of {@link parseCalibrationBlob}). */ +declare function serializeCalibrationBlob(input: CalibrationSetInput): Uint8Array; +/** CRC-16/CCITT-FALSE over a serialized blob — the value stamped into payload headers. */ +declare function calibrationBlobCrc(blob: Uint8Array): number; +/** + * Apply IMU calibration to a raw tri-axial sample. + * + * physical = align · (K⁻¹ · (raw − bias)) + * + * `bias` (b) is subtracted and `sens` (K, diagonal) divided per axis, then the + * `align` matrix (row-major 3x3) is applied directly to rotate the sensor frame + * into the common ASM frame. With identity `align` and zero `bias` this reduces + * to `raw / sens`. + * + * Convention note: `align` is the directly-applied sensor-frame → ASM-frame + * matrix (= R⁻¹ in ASM-DES04 §8's `output = K·R·physical + b` notation). This + * matches the cloud calibration CSV `rotation_*` columns one-to-one — the CSV + * stores the same applied matrix, row-major — so the sensor-calibration parser + * maps blob → CSV with NO transpose. (Confirmed against a LIS2DW12 sample CSV: + * offset→bias, sensitivity→sens, rotation→align.) + */ +declare function applyImuCalibration(raw: readonly [number, number, number], cal: ImuCalibration): [number, number, number]; + +interface VerisenseMessage { + header: number; + command: AsmCommand; + property: AsmProperty; + payloadLength: number; + payload: Uint8Array; +} +/** Build a protocol header byte from command/property nibbles. */ +declare function buildHeader(command: AsmCommand, property: AsmProperty): number; +/** Decode a protocol header byte into command/property fields. */ +declare function parseHeader(header: number): { + command: AsmCommand; + property: AsmProperty; +}; +/** Build a complete protocol message (header + 16-bit LE payload length + payload bytes). */ +declare function buildMessage(command: AsmCommand, property: AsmProperty, payloadBytes?: Uint8Array | number[]): Uint8Array; +/** Parse a complete protocol message into structured fields. */ +declare function parseMessage(msg: Uint8Array): VerisenseMessage; +declare function isAckCommand(command: AsmCommand): boolean; +declare function isNackCommand(command: AsmCommand): boolean; +/** Convert a pending-events payload (property IDs) into a typed array. */ +declare function parsePendingEvents(payload: Uint8Array): AsmProperty[]; + +/** Format a single byte as an uppercase `0xNN` string. */ +declare function formatByteAsHex(v: number): string; +/** Format bytes as `[0xAA, 0xBB, ...]`. */ +declare function formatByteArrayAsHex(bytes: ArrayLike | ArrayBuffer | null | undefined): string; +/** Parse text containing hex bytes like `0x5A, 00 12` into a Uint8Array. */ +declare function parseHexByteString(text: string): Uint8Array; +/** A Verisense firmware version triple (major.minor.internal). */ +interface VerisenseFirmwareVersion { + major: number; + minor: number; + internal: number; +} +/** + * Compare two firmware version triples. Returns a negative number if `a < b`, + * positive if `a > b`, and 0 if equal. Missing or non-numeric components are + * treated as 0. + */ +declare function compareVerisenseFirmwareVersion(a: Partial | null | undefined, b: Partial | null | undefined): number; +/** Format a firmware version triple as `"major.minor.internal"`, or `"unknown"` + * when the version is null/undefined. */ +declare function formatVerisenseFirmwareVersion(v: Partial | null | undefined): string; +/** Human-readable label for a Verisense stream-packet sensor ID, with a + * `"Sensor 0xNN"` hex fallback for unknown IDs. */ +declare function getVerisenseStreamSensorLabel(sensorId: number): string; +interface PendingEventPropertyLabel { + value: number; + hex: string; + property: string; +} +/** Label pending-event property values with both enum name and hex representation. */ +declare function formatPendingEventProperties(pendingProps: ArrayLike | null | undefined): PendingEventPropertyLabel[]; +/** + * Compute CRC-16/CCITT-FALSE over `bytes`. + * + * Parameters: poly=0x1021, init=0xFFFF, xorOut=0x0000. + * Matches the C# `ComputeCRC` implementation used by Verisense firmware. + */ +declare function crc16_ccitt_false(bytes: Uint8Array): number; +/** + * Convert any reasonable representation of an operational config to a + * `Uint8Array`. Throws if the input type is unrecognised. + */ +declare function normalizeOperationalConfig(payload: Uint8Array | ArrayBuffer | number[] | { + buffer: ArrayBuffer; + byteOffset?: number; + byteLength?: number; +} | null | undefined): Uint8Array | null; +/** Alias for arbitrary protocol byte payload normalization. */ +declare function normalizeBytePayload(payload: Uint8Array | ArrayBuffer | number[] | { + buffer: ArrayBuffer; + byteOffset?: number; + byteLength?: number; +} | null | undefined): Uint8Array | null; +/** + * Derive the 6-digit pairing PIN from a Verisense unique identifier. + * + * The PIN is built from digits 2, 4 and 6 (1-based) of the identifier, + * followed by the decimal value of the final byte padded to 3 digits. + */ +declare function computeVerisensePairingPin(uniqueId: string): string; +interface ProductionConfig { + hardware: string; + firmware: string; + asmid: string; + configHeader: number; + revHwMajor?: number; + revHwMinor?: number; + revHwInternal?: number; + revFwMajor?: number; + revFwMinor?: number; + revFwInternal?: number; +} +interface ProductionConfigBuildOptions { + manufacturingOrderNumberHex: string; + macIdHex: string; + revHwMajor: number; + revHwMinor: number; + revFwMajor: number; + revFwMinor: number; + revFwInternal?: number; + revHwInternal?: number; + passkeyId?: string; + passkey?: string; + advertisingNamePrefix?: string; + dfuEnabled?: boolean; +} +interface ProductionConfigFull extends ProductionConfig { + manufacturingOrderNumber: string; + macId: string; + uniqueIdentifier: string; + revHwMajor: number; + revHwMinor: number; + revHwInternal: number; + revFwMajor: number; + revFwMinor: number; + revFwInternal: number; + passkeyId: string; + passkey: string; + advertisingNamePrefix: string; + dfuEnabled: boolean; +} +interface VerisenseStatusFlags { + usbPluggedIn: boolean; + recordingPaused: boolean; + flashIsFull: boolean; + powerIsGood: boolean; + adaptiveSchedulerOn: boolean; + dfuServiceOn: boolean; + firstBoot: boolean; + repeatedBatteryMeasurement: boolean; +} +interface VerisenseStatusPayload { + uniqueIdentifier: string; + sourceStatusProperty: 'status1' | 'status2'; + statusTimestampSeconds: number; + batteryMilliVolts: number; + batteryPercent: number; + lastOkTransferSeconds: number; + lastFailTransferSeconds: number; + memoryFreeKb: number; + memoryCapacityKb: number | null; + memoryUsedKb: number | null; + /** kB of FULL (ready-to-sync) flash banks. Only populated for payloads >= 57 bytes. */ + memoryFullBanksKb: number | null; + /** kB of 2DEL (partially-deleted) flash banks. Only populated for payloads >= 57 bytes. */ + memoryTwoDelBanksKb: number | null; + /** kB of BAD flash banks. Only populated for payloads >= 57 bytes. */ + memoryBadBanksKb: number | null; + statusFlags: VerisenseStatusFlags | null; + batteryFallCounter: number | null; + /** Byte 64 bit0 (charger chip present). Null for legacy payloads (<65 bytes). */ + chargerPresent: boolean | null; + /** Byte 64 bits1..3 (BatteryChargerStatus_t). Null for legacy payloads (<65 bytes). */ + chargerStatusCode: number | null; + /** Decoded charger status enum label from chargerStatusCode. */ + chargerStatusName: 'CHARGER_STATUS_BAD_BATTERY' | 'CHARGER_STATUS_CHARGING' | 'CHARGER_STATUS_CHARGING_COMPLETE' | 'CHARGER_STATUS_POWER_DOWN' | 'CHARGER_STATUS_TRICKLE_CHARGING' | 'CHARGER_STATUS_NOT_READ' | 'CHARGER_STATUS_UNKNOWN' | null; +} +interface VerisenseUnixAndHumanTimestamp { + unix: number; + human: string; +} +interface VerisenseStatusPayloadForLog extends VerisenseStatusPayload { + statusTimestamp: VerisenseUnixAndHumanTimestamp; + lastOkTransfer: VerisenseUnixAndHumanTimestamp; + lastFailTransfer: VerisenseUnixAndHumanTimestamp; +} +type VerisenseChargerChipFamily = 'LM3658D' | 'LTC4123' | 'XC6803' | 'UNKNOWN'; +/** Infer charger chip family from hardware revision fields in production config. */ +declare function inferVerisenseChargerChipFamily(revHwMajor: number, revHwMinor: number, revHwInternal: number): VerisenseChargerChipFamily; +/** Return chip-specific charger status text for a parsed 3-bit status code. */ +declare function describeVerisenseChargerStatus(chipFamily: VerisenseChargerChipFamily, statusCode: number): string; +/** Format charger summary text for UIs, e.g. "XC6803: Charge completed". */ +declare function formatVerisenseChargerStatus(status: Pick, hw?: { + revHwMajor?: number; + revHwMinor?: number; + revHwInternal?: number; +}): string; +interface VerisenseSchedulerDebugPayload { + currentTimeUnixSeconds: number; + bleControlCounter: 'data-transfer' | 'status1' | 'rtc-sync' | 'status2' | 'never' | 'unknown'; + pendingDataTransferUnixSeconds: number; + pendingStatus1UnixSeconds: number; + pendingRtcSyncUnixSeconds: number; + pendingRetryUnixSeconds: number; + retryCount: number; + retryOperation: 'ble-off' | 'ble-on' | 'unknown'; + adaptiveScheduler?: { + nextUnixSeconds: number; + enabled: boolean; + syncFailCounter: number; + }; + ltfRetry?: { + nextUnixSeconds: number; + currentOperation: 'flash-write-retry-inactive' | 'short-flash-write-retry' | 'attempt-flash-write' | 'long-flash-write-retry' | 'sensor-paused-until-usb-plug-in' | 'unknown'; + failCounterShort: number; + failCounterLong: number; + }; + pendingStatus2UnixSeconds?: number; + ppgMeasurementUnixSeconds?: number; + stepCounterResetUnixSeconds?: number; + sensorInactivityUnixSeconds?: number; +} +interface VerisenseSchedulerDebugPayloadForLog extends VerisenseSchedulerDebugPayload { + currentTime: VerisenseUnixAndHumanTimestamp; + pendingDataTransfer: VerisenseUnixAndHumanTimestamp; + pendingStatus1: VerisenseUnixAndHumanTimestamp; + pendingRtcSync: VerisenseUnixAndHumanTimestamp; + pendingRetry: VerisenseUnixAndHumanTimestamp; + pendingStatus2?: VerisenseUnixAndHumanTimestamp; + ppgMeasurement?: VerisenseUnixAndHumanTimestamp; + stepCounterReset?: VerisenseUnixAndHumanTimestamp; + sensorInactivity?: VerisenseUnixAndHumanTimestamp; + adaptiveScheduler?: VerisenseSchedulerDebugPayload['adaptiveScheduler'] & { + nextTime: VerisenseUnixAndHumanTimestamp; + }; + ltfRetry?: VerisenseSchedulerDebugPayload['ltfRetry'] & { + nextTime: VerisenseUnixAndHumanTimestamp; + }; +} +interface VerisenseBleLinkDebugPayload { + attMtu: number; + maxDataLength: number; + connectionIntervalUnits: number; + connectionIntervalMs: number; + txPhy: number; + rxPhy: number; + optimizationResult: number; + isConnected: boolean; +} +interface VerisenseEventLogEntry { + index: number; + eventId: number; + eventName: string; + timestampUnixSeconds: number | null; + batteryMilliVolts: number | null; +} +/** Upper bound for a plausible device timestamp (2100-01-01 UTC in unix + * seconds). Values beyond this are uninitialised/garbage bytes, not dates. */ +declare const VERISENSE_MAX_PLAUSIBLE_UNIX_SECONDS = 4102444800; +/** Format unix seconds as raw + human-readable local datetime for logging. */ +declare function formatVerisenseUnixAndHuman(unixSeconds: number): VerisenseUnixAndHumanTimestamp; +/** Convert parsed status payload into an object with human-readable timestamps for logs. */ +declare function formatStatusPayloadForLog(status: VerisenseStatusPayload): VerisenseStatusPayloadForLog; +/** Convert parsed scheduler payload into an object with human-readable timestamps for logs. */ +declare function formatSchedulerPayloadForLog(parsed: VerisenseSchedulerDebugPayload): VerisenseSchedulerDebugPayloadForLog; +interface VerisenseRecordBufferDetails { + bufferIndex: number; + bufferState: number; + packagedPayloadIndex: number; + currentByteIndexForSensorData: number; + usedBufferLength: number; + fifoTicks: number; + dataTimestampRwcMinutes: number; + dataTimestampRwcTicks: number; + temperatureData: number; + dataTimestampUcClockMinutes: number | null; + dataTimestampUcClockTicks: number | null; +} +interface VerisenseLookupTableEntry { + bankIndex: number; + statusCode: number; + statusName: 'Full' | '2Del' | 'Emty' | 'Bad' | 'NUse' | 'Zero' | 'Unknown'; + pendingEepromWrite: boolean; + payloadIndex: number; +} +interface VerisenseLookupTablePayload { + head: number | null; + tail: number | null; + entries: VerisenseLookupTableEntry[]; +} +/** Convert unix seconds into Verisense 7-byte RTC payload (4-byte minutes + 3-byte ticks). */ +declare function unixSecondsToAsmRtcBytes(unixSeconds: number): Uint8Array; +/** Convert Verisense 7-byte RTC payload into unix seconds. */ +declare function asmRtcBytesToUnixSeconds(rtc7: Uint8Array): number; +/** Convert Verisense 8-byte minute counter payload into unix seconds. */ +declare function asmRtcMinutesBytesToUnixSeconds(minutes8: Uint8Array): number; +/** + * Build a production configuration payload (56 bytes) from structured options. + * This matches the Python tooling layout used by ASM_BLE.py / ASM_Device.py. + */ +declare function buildProductionConfigPayload(opts: ProductionConfigBuildOptions): Uint8Array; +/** Parse production configuration with optional passkey/name/flag fields. */ +declare function parseProductionConfigPayloadFull(response: Uint8Array): ProductionConfigFull; +/** + * Parse STATUS1/STATUS2 payload into a typed object. + * + * This ports the core byte parsing from ASM_Device.parse_status while keeping + * the output concise and UI-friendly. + */ +declare function parseStatusPayload(response: Uint8Array, sourceStatusProperty?: 'status1' | 'status2'): VerisenseStatusPayload; +/** Parse scheduler debug response payload from DEBUG_COMMAND_ID.RWC_SCHEDULER_READ. */ +declare function parseSchedulerDebugPayload(payload: Uint8Array): VerisenseSchedulerDebugPayload; +/** Decoded view of the BLE-link `optimizationResult` byte returned by the + * optimize debug command: bit 7 = device reports "not connected" (the other + * bits are then meaningless), bit 0 = a PHY change was requested, bit 1 = a + * connection-interval change was requested, bit 2 = a data-length change was + * requested. */ +interface VerisenseBleOptimizationResult { + notConnected: boolean; + phyRequested: boolean; + connIntervalRequested: boolean; + dataLengthRequested: boolean; + resultMask: number; +} +/** Decode the `optimizationResult` byte from {@link parseBleLinkDebugPayload} + * (see {@link VerisenseBleOptimizationResult} for the bit meanings). */ +declare function decodeVerisenseBleOptimizationResult(resultByte: number): VerisenseBleOptimizationResult; +/** Parse debug payload from BLE link read/optimize commands. */ +declare function parseBleLinkDebugPayload(payload: Uint8Array): VerisenseBleLinkDebugPayload; +/** Parse debug payload listing bank indexes with bad CRC (2-byte LE entries). */ +declare function parsePayloadCrcErrorBankIndexes(payload: Uint8Array): number[]; +/** Parse 8-byte debug event-log entries. */ +declare function parseEventLogPayload(payload: Uint8Array): VerisenseEventLogEntry[]; +/** Parse record-buffer details payload (26-byte current layout, 19-byte legacy layout). */ +declare function parseRecordBufferDetailsPayload(payload: Uint8Array): VerisenseRecordBufferDetails[]; +/** + * Infer the lookup-table bank count from a raw debug payload length. The payload + * is 3 bytes per bank, optionally prefixed with a 4-byte head/tail block. + * Returns 0 if the length matches neither layout. + */ +declare function inferVerisenseLookupBankCount(payloadLen: number): number; +/** + * Parse lookup-table debug payload entries (3 bytes per bank), with optional + * 4-byte tail/head prefix present in older firmware debug responses. When + * `totalBanks` is omitted it is inferred from the payload length via + * {@link inferVerisenseLookupBankCount}. + */ +declare function parseLookupTablePayload(payload: Uint8Array, totalBanks?: number): VerisenseLookupTablePayload; +/** + * Parse the production config response payload into a structured object. + */ +declare function parseProductionConfigPayload(response: Uint8Array): ProductionConfig; +/** + * Firmware default passkeys by passkey ID: a production config programmed + * with passkey ID "01" pairs with the fixed PIN "123456". Other IDs have no + * fixed default (ID "00" uses the per-device derived PIN — see + * {@link computeVerisensePairingPin}). + */ +declare const VERISENSE_DEFAULT_PASSKEY_BY_ID: Readonly>; +/** The fixed passkey for a passkey ID, or undefined when the ID has none + * (leave the passkey bytes unset in the production config). */ +declare function defaultVerisensePasskeyForId(passkeyId: string | null | undefined): string | undefined; +/** Component parts of a Verisense advertised BLE name. */ +interface VerisenseAdvertisedNameParts { + /** Name prefix from the production config (normally "Verisense"). */ + prefix: string; + /** 2-char passkey ID from the production config. */ + passkeyId: string; + /** 12-hex unique identifier (8-hex manufacturing order + 4-hex MAC ID). */ + uniqueId: string; +} +/** + * Build the name a Verisense sensor advertises over BLE: + * `--` (e.g. "Verisense-01-25112101B10F"). + * Returns null when any part is missing — matches how apps derive the name + * from a parsed production config that may be blank/erased. + */ +declare function buildVerisenseAdvertisedName(parts: Partial): string | null; +/** + * Split a Verisense advertised name back into its parts. The unique ID is the + * final `-`-separated token; the passkey ID the token before it; anything + * earlier (which may itself contain `-`) is the prefix. Returns null when the + * name does not have at least three tokens. + */ +declare function parseVerisenseAdvertisedName(name: string | null | undefined): VerisenseAdvertisedNameParts | null; +/** + * The 4-hex MAC ID from a Verisense advertised name (the advertised name ends + * with the unique ID = manufacturing order + MAC; its last 4 hex chars are + * the MAC ID). Returns null when the tail is not valid hex. + */ +declare function deriveVerisenseMacIdFromName(name: string | null | undefined): string | null; +/** + * Short device tag for file names (e.g. "…-B10F-…"): the last 4 hex chars of + * a device unique ID or advertised name. Returns "" when unknown so callers + * can omit it cleanly. + */ +declare function verisenseDeviceFileTag(idOrName: string | null | undefined): string; + +type ParsedSplitReason = 'midday-midnight-boundary' | 'config-change' | 'timestamp-discontinuity' | 'power-reset'; +interface EvaluateParsedSplitInput { + prevTimestampSec: number; + currTimestampSec: number; + expectedDeltaSec?: number; + timestampToleranceSec?: number; + prevConfigSignature?: string | null; + currConfigSignature?: string | null; + powerResetDetected?: boolean; +} +/** Build a binary upload file name: yyMMdd_HHmmss_00000.bin */ +declare function buildUploadBinaryFileName(uploadDate: Date, firstPayloadIndex: number): string; +/** Build parsed CSV file name: yyMMdd_HHmmss_DataSource_00000.csv */ +declare function buildParsedCsvFileName(startDate: Date, dataSource: string, firstPayloadIndex: number): string; +/** Add duplicate suffix like " (2)" before extension. */ +declare function applyDuplicateSuffix(fileName: string, duplicateIndex: number): string; +/** Return first non-colliding duplicate name for a target file name. */ +declare function nextAvailableDuplicateFileName(fileName: string, existingNames: Iterable): string; +/** Parse first payload index (uint16 LE) from a payload byte array. */ +declare function getFirstPayloadIndex(payload: Uint8Array): number; +/** + * Evaluate whether parsed CSV output should roll to a new file. + * Rules mirror ASM-DES08 split conditions. + */ +declare function evaluateParsedFileSplit(input: EvaluateParsedSplitInput): { + shouldSplit: boolean; + reasons: ParsedSplitReason[]; +}; + +type VerisenseHardwareFriendlyName = 'IMU' | 'GSR+' | 'SDK' | 'Pulse+'; +interface VerisenseHardwareCapabilities { + readonly secondGeneration: boolean; + readonly supportsMagnetometer: boolean; +} +interface VerisenseHardwareRevision { + readonly major: number; + readonly minor: number; + readonly internal: number; +} +interface VerisenseHardwareRevisionSource { + readonly revHwMajor?: number | null; + readonly revHwMinor?: number | null; + readonly revHwInternal?: number | null; +} +declare const VERISENSE_HW_MAJOR_FRIENDLY_NAMES: Readonly>; +declare function getVerisenseHardwareFriendlyName(revHwMajor: number): VerisenseHardwareFriendlyName | null; +/** + * Second-generation Verisense hardware is currently defined as: + * - SR61.5+ + * - SR68.9+ + * - Any future major revision above SR68 + */ +declare function isVerisenseSecondGenerationHardware(revHwMajor: number, revHwMinor: number): boolean; +declare function getVerisenseHardwareCapabilities(revHwMajor: number, revHwMinor: number): VerisenseHardwareCapabilities; +/** + * GSR-capable hardware. Mirrors the firmware's authoritative + * `ShimBrd_isGsrSupportedForHwVersion` (shimmer_boards.c): + * - SR62 (any revision) + * - SR61 minor >= 5 + * - SR68 minor >= 5 + * + * Deliberately NOT {@link isVerisenseSecondGenerationHardware}: that predicate + * requires SR68 >= 9, but GSR arrived on the SR68 at minor revision 5. + */ +declare function isVerisenseGsrSupportedHardware(revHwMajor: number, revHwMinor: number): boolean; +/** + * Which physical sensor blocks a Verisense board carries. Each flag lines up + * with an operational-config field group (see + * `getVerisenseSupportedOperationalFieldGroupIds`), so callers can decide which + * config groups are meaningful for the connected hardware. + * + * Derived from the firmware Model IC matrix + * (verisense-firmware/docs/VERISENSE_MODEL_IC_MATRIX.md). + */ +interface VerisenseHardwareSensorSupport { + /** 1st-gen low-power accel, LIS2DW12 (`accel1` group). */ + readonly accel1: boolean; + /** 1st-gen gyro + accel2, LSM6DS3 (`gyro_accel2` group). */ + readonly gyroAccel2: boolean; + /** 2nd-gen IMU + magnetometer, LSM6DSV + LIS2MDL (`lsm6dsv` group). */ + readonly imuGen2: boolean; + /** Galvanic skin response front-end (`adc_gsr` group). */ + readonly gsr: boolean; + /** Photoplethysmography front-end (`ppg` group). */ + readonly ppg: boolean; + /** Ambient light sensor, VD6283 (`light` group). */ + readonly ambientLight: boolean; + /** Skin temperature sensor, MLX90632 (`skin_temp` group). */ + readonly skinTemperature: boolean; + /** Algorithm hub, MAX32674 (`algo` group). */ + readonly algorithmHub: boolean; + /** 2xRGB status LEDs with auto-brightness (`led` group). */ + readonly ledAutoBrightness: boolean; +} +/** + * Resolves which sensor blocks a given Verisense hardware revision carries, + * derived from the firmware Model IC matrix + * (verisense-firmware/docs/VERISENSE_MODEL_IC_MATRIX.md). + * + * Unknown / development hardware (e.g. SR64, or any unrecognised major + * revision) reports every block as present so consumers never hide a setting + * they cannot confidently rule out. + */ +declare function getVerisenseHardwareSensorSupport(revHwMajor: number, revHwMinor: number): VerisenseHardwareSensorSupport; +declare function getVerisenseHardwareRevision(source: VerisenseHardwareRevisionSource | null | undefined): VerisenseHardwareRevision | null; +declare function supportsVerisenseMagnetometer(source: VerisenseHardwareRevisionSource | null | undefined): boolean; +declare function formatVerisenseHardwareRevision(revHwMajor: number, revHwMinor: number, revHwInternal?: number, opts?: { + prefix?: string; + includeFriendlyName?: boolean; +}): string; +/** + * Battery voltage scaling for streamed ADC battery samples. + * Status responses already contain firmware-scaled battery values and should not use this helper. + */ +declare function getVerisenseStreamingBatteryVoltageMultiplier(revHwMajor: number, revHwMinor: number): number; + +type VerisenseOperationalFieldKind = 'bit' | 'u8' | 'u16' | 'u32' | 'inactiveResume' | 'inactiveMinutes'; +type VerisenseOperationalFieldOption = readonly [number, string]; +interface VerisenseOperationalFieldDefinition { + readonly key: string; + readonly label: string; + readonly desc: string; + readonly kind: VerisenseOperationalFieldKind; + readonly index: number; + readonly shift?: number; + readonly width?: number; + readonly min?: number; + readonly max?: number; + readonly options?: readonly VerisenseOperationalFieldOption[]; +} +declare const VERISENSE_OPERATIONAL_FIELD_SCHEMA: ({ + key: string; + label: string; + desc: string; + kind: string; + index: 1; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 2; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 3; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 4; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 5; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 6; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 7; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 8; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 8; + shift: number; + width: number; + min: number; + max: number; + options?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 11; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 11; + shift: number; + width: number; + min: number; + max: number; + options?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 12; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 13; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 14; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 15; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 16; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 17; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 17; + shift: number; + width: number; + min: number; + max: number; + options?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 18; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 19; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 20; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 29; + options: (string | number)[][]; + shift?: undefined; + width?: undefined; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 31; + options: (string | number)[][]; + shift?: undefined; + width?: undefined; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 50; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 51; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 59; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 60; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: number; + min: number; + max: number; + shift?: undefined; + width?: undefined; + options?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 71; + options: (string | number)[][]; + shift?: undefined; + width?: undefined; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 72; + min: number; + max: number; + options: (string | number)[][]; + shift?: undefined; + width?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 73; + min: number; + max: number; + options: (string | number)[][]; + shift?: undefined; + width?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 74; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 75; + min: number; + max: number; + options: (string | number)[][]; + shift?: undefined; + width?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 76; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 78; + min: number; + max: number; + options: (string | number)[][]; + shift?: undefined; + width?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 79; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 79; + shift: number; + width: number; + options?: undefined; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 80; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 82; + shift: number; + width: number; + options: (string | number)[][]; + min?: undefined; + max?: undefined; +} | { + key: string; + label: string; + desc: string; + kind: string; + index: 91; + min: number; + max: number; + options: (string | number)[][]; + shift?: undefined; + width?: undefined; +})[]; +declare const VERISENSE_OP_CONFIG_BYTE_SIZE = 92; +type VerisenseOperationalField = VerisenseOperationalFieldDefinition; +declare function createBlankVerisenseOperationalConfig(byteSize?: number): Uint8Array; +declare function readVerisenseOperationalFieldValue(op: Uint8Array, field: VerisenseOperationalField): number; +declare function writeVerisenseOperationalFieldValue(op: Uint8Array, field: VerisenseOperationalField, rawValue: unknown): void; +declare function setVerisenseOperationalBitRange(op: Uint8Array, index: number, shift: number, width: number, rawValue: unknown): void; +/** + * Enforce the USB/Bluetooth comms-channel interlock on an operational-config + * buffer. + * + * A Verisense must never be configured with BOTH Bluetooth and USB disabled, or + * it becomes unreachable for reconfiguration (the radio is the only wireless way + * back in, and disabling USB removes the wired fallback). If a config has both + * `BLUETOOTH_EN` and `USB_EN` cleared, this forces BOTH back on. + * + * This mirrors the firmware safeguard (`enforceCommsChannelInterlock` in + * `ASM_Production/main.c`, applied on config write and parse). Enforcing it here + * in the SDK means any consuming application is protected — a device can't be + * stranded by a third-party tool writing 0/0. + * + * Mutates `op` in place. Returns `true` if a correction was applied. + */ +declare function enforceVerisenseCommsChannelInterlock(op: Uint8Array): boolean; +interface VerisenseOperationalSensorEnableField { + readonly key: string; + readonly index: number; + readonly shift: number; +} +declare const VERISENSE_SENSOR_ENABLE_FIELDS: readonly VerisenseOperationalSensorEnableField[]; +interface VerisenseOperationalFieldSubgroupDefinition { + readonly id: string; + readonly title: string; + readonly keys: readonly string[]; +} +interface VerisenseOperationalFieldGroupDefinition { + readonly id: string; + readonly title: string; + readonly openByDefault: boolean; + readonly keys: readonly string[]; + /** + * Optional presentational partition of {@link keys} into labelled subpanels + * rendered inside the group. Purely for layout: group membership, hardware + * support detection and field resolution all continue to use {@link keys}. + * Subgroups need not be exhaustive — any key in {@link keys} not covered by a + * subgroup is rendered above the subpanels, so nothing is ever hidden. + */ + readonly subgroups?: readonly VerisenseOperationalFieldSubgroupDefinition[]; +} +declare const VERISENSE_OPERATIONAL_FIELD_GROUPS: readonly VerisenseOperationalFieldGroupDefinition[]; +declare const VERISENSE_OPERATIONAL_FIELD_FALLBACK_GROUP_ID = "gen"; +/** + * Maps each hardware-gated operational-config group id to the sensor block that + * gates it (see {@link VerisenseHardwareSensorSupport}). Group ids absent from + * this map (e.g. `gen`, `ble_wake`) configure behaviour that applies to + * every board and are always considered supported. + */ +declare const VERISENSE_OPERATIONAL_FIELD_GROUP_SENSOR: Readonly>; +/** + * Returns the set of operational-config group ids (from + * {@link VERISENSE_OPERATIONAL_FIELD_GROUPS}) whose underlying sensor is present + * on the given hardware revision. A group is supported when it is not gated by a + * sensor block, or when its gating sensor is present. + * + * Returns `null` when the hardware revision is unknown so callers can fall back + * to showing every group. + */ +declare function getVerisenseSupportedOperationalFieldGroupIds(source: VerisenseHardwareRevisionSource | null | undefined): ReadonlySet | null; +/** LIGHT_CONFIG bit 1 is the VD6283 dark-channel select: when set, the shared + * visible/clear slot carries the dark (covered-photodiode) baseline instead of + * the visible reading. Returns false for empty/nullish config. */ +declare function isVerisenseLightDarkChannelEnabled(op: Uint8Array | null | undefined): boolean; +/** + * Pad an operational config authored at a legacy/shorter length onto a blank + * full-size (v9, {@link VERISENSE_OP_CONFIG_BYTE_SIZE}-byte) image so the + * working config is always canonical size — otherwise trailing v9 fields + * (e.g. the person-parameter bytes) would be absent. Configs already at or + * beyond full size are returned as-is. + */ +declare function padVerisenseOperationalConfig(bytes: Uint8Array | ArrayLike): Uint8Array; +/** Which IMU generation an op-config field key targets: 'ds3' = first-gen + * LSM6DS3, 'dsv' = second-gen LSM6DSV (+LIS2MDL mag). */ +type VerisenseImuGeneration = 'ds3' | 'dsv'; +interface VerisenseSensorRateDefaultField { + /** Field key in {@link VERISENSE_OPERATIONAL_FIELD_SCHEMA}, when the field + * is the same on both IMU generations. */ + readonly key?: string; + /** Generation-specific field keys (accel2/gyro ODR live in different + * fields on LSM6DS3 vs LSM6DSV configs). */ + readonly keyByGen?: Readonly>; + /** Default rate/mode code to seed when the sensor is enabled. */ + readonly on: number; + /** Power-down code to write when every enable in the group is off. */ + readonly off: number; +} +interface VerisenseSensorRateDefaultGroup { + /** Sensor-enable field keys (see {@link VERISENSE_SENSOR_ENABLE_FIELDS}) + * that share the rate/mode field(s) below. */ + readonly enableKeys: readonly string[]; + readonly fields: readonly VerisenseSensorRateDefaultField[]; +} +/** + * Firmware default rate/mode codes per sensor group, for config editors that + * auto-seed a rate when a sensor is first enabled and power it down when all + * of its enables are cleared. Editors should only seed the `on` default when + * the field currently holds the `off` (power-down) code, so a user-chosen + * rate is never clobbered. Sensors whose rate field has no power-down value + * (magnetometer LIS2MDL_ODR, PPG_SR) are omitted — their enable bit / channel + * toggles are the on/off control. Default ODR codes mirror the standard + * customer template (Accel1 = 50 Hz, ADC = 128 Hz). + */ +declare const VERISENSE_SENSOR_RATE_DEFAULT_GROUPS: readonly VerisenseSensorRateDefaultGroup[]; +/** Resolve a rate-default field to its concrete schema key for the given IMU + * generation, or null when the field has no key for that generation. */ +declare function resolveVerisenseSensorRateFieldKey(field: VerisenseSensorRateDefaultField, generation: VerisenseImuGeneration): string | null; +/** One of the three firmware BLE wake/sync schedules and its four op-config + * field keys (see the BLE Wake Schedule field group). */ +interface VerisenseBleSyncSchedule { + readonly id: 'data' | 'status' | 'rtcSync'; + /** Field-group subgroup id used by the operational field schema. */ + readonly subgroupId: string; + readonly intervalKey: string; + readonly timeKey: string; + readonly durKey: string; + readonly retryKey: string; +} +/** + * The three firmware sync schedules (data transfer, status, RTC sync), each + * with wake-interval-hours / wake-time / active-duration / retry-interval + * fields. Interval semantics (from firmware `hal_rtc.c`): 0 = off, 24 = once + * daily at the wake time, 1-23 = every N hours. Wake time is + * minutes-since-midnight (device local time), duration is minutes 0-255, + * retry interval is minutes 0-1439. The number of connection attempts per + * window is the separate global `BLE_CONNECTION_TRIES_PER_DAY` field. + */ +declare const VERISENSE_BLE_SYNC_SCHEDULES: readonly VerisenseBleSyncSchedule[]; +/** Value ranges for the BLE sync-schedule fields (clamp editor input to + * these before writing). */ +declare const VERISENSE_BLE_SCHEDULE_RANGES: Readonly<{ + intervalHours: Readonly<{ + min: 0; + max: 24; + }>; + timeMins: Readonly<{ + min: 0; + max: 1439; + }>; + durMin: Readonly<{ + min: 0; + max: 255; + }>; + retryIntMin: Readonly<{ + min: 0; + max: 1439; + }>; +}>; +/** + * Canonical schedule defaults: 01:00 daily, 10-minute window, 15-minute + * retry, 5 connection attempts per wake. Also the "reset" values applied + * when the pending-events scheduler is disabled, so a disabled config lands + * in a clean known state. + */ +declare const VERISENSE_BLE_SCHEDULE_DEFAULTS: Readonly<{ + intervalHours: 24; + timeMins: 60; + durMin: 10; + retryIntMin: 15; + connectionTries: 5; +}>; +/** Format minutes-since-midnight as `"HH:MM"`, or null when out of range. + * Fractional input is rounded to the nearest whole minute first, so the + * minutes component always stays in 0–59. */ +declare function minutesSinceMidnightToHHMM(mins: number | null | undefined): string | null; +/** Parse `"HH:MM"` (or `"H:MM"`) into minutes-since-midnight, or null when + * malformed / out of range. */ +declare function hhmmToMinutesSinceMidnight(text: string | null | undefined): number | null; +/** Boolean sensor enables used to predict which stream sensor IDs a config + * will produce (see {@link expectedVerisenseStreamSensorIds}). */ +interface VerisenseStreamSensorEnables { + gsr?: boolean; + vbatt?: boolean; + vprog?: boolean; + accel1?: boolean; + accel2?: boolean; + gyro?: boolean; + mag?: boolean; + ppg?: boolean; + ambientLight?: boolean; + skinTemp?: boolean; + algoHub?: boolean; +} +/** + * The stream-packet sensor IDs a device will emit for a given set of sensor + * enables (see `VERISENSE_STREAM_SENSOR_LABELS` for the ID meanings). The + * IMU block splits by hardware generation: first-gen streams accel2+gyro as + * ID 3 (LSM6DS3); second-gen streams accel2+gyro+mag as ID 6 (LSM6DSV + + * LIS2MDL). Any enabled PPG channel produces the single PPG stream (ID 4). + */ +declare function expectedVerisenseStreamSensorIds(enables: VerisenseStreamSensorEnables, opts: { + secondGeneration: boolean; +}): Set; +/** {@link expectedVerisenseStreamSensorIds} computed straight from op-config + * bytes via the sensor-enable bit schema. */ +declare function expectedVerisenseStreamSensorIdsFromConfig(op: Uint8Array | null | undefined, opts: { + secondGeneration: boolean; +}): Set; + +/** + * Abstract base class for all Verisense sensor decoders. + * + * Provides: + * - Timestamp unwrapping (handles the 1-minute rollover at 32768 ticks/s). + * - System-time offset tracking for plotting calibrated wall-clock timestamps. + * - Per-sample time extrapolation based on sampling rate and last-sample tick. + */ +declare abstract class SensorBase { + /** Verisense clock frequency in ticks per second. */ + static readonly CLOCK_FREQ = 32768; + /** 1-minute rollover at 32768 ticks/s (matches C# Sensor.cs). */ + static readonly TICKS_MAX_VALUE: number; + protected lastTicksUnwrapped: number; + protected cycle: number; + /** (system time) − (shimmer time) at first sample, in milliseconds. */ + systemOffsetFirstTime: number | null; + /** Sampling rate in Hz (used for per-sample time extrapolation). */ + samplingRateHz: number | null; + /** Whether this sensor is enabled in the operational config. */ + enabled: boolean; + /** + * Per-device calibration read from the sensor, or null when none is available + * (decoders then fall back to nominal full-scale/datasheet scaling). Set via + * {@link applyCalibration}; subclasses read it in their calibrate routines. + */ + protected calibration: CalibrationSet | null; + /** Supply (or clear) the device calibration set used by this decoder. */ + applyCalibration(set: CalibrationSet | null): void; + /** Reset all timestamp state (call on (re)connect or when streaming restarts). */ + resetTimestamps(): void; + /** + * Unwrap a rolling 24-bit tick counter to a monotonically increasing value. + */ + unwrapTicks(ticks: number): number; + /** Convert unwrapped ticks to milliseconds. */ + ticksToMillis(unwrappedTicks: number): number; + /** + * Compute the calibrated shimmer timestamp for the *last* sample in a burst, + * and store the first-seen system-offset for later plotting. + * + * @param lastSampleTicksU24 24-bit tick counter from the packet header. + * @param systemMillis `Date.now()` at the time of packet receipt. + */ + getTimestampUnwrappedMillis(lastSampleTicksU24: number, systemMillis: number): { + shimmerMillis: number; + systemOffsetFirstTime: number; + }; + /** + * Extrapolate the timestamp for sample `i` of `numSamples` in a burst, + * given the timestamp of the *last* sample and the sampling rate. + * + * @returns Object with `tsMillis`, `systemTsMillis`, and `systemTsPlotMillis`. + */ + extrapolateSampleTimes(opts: { + numSamples: number; + i: number; + samplingRateHz?: number | null; + tsLastSampleMillis: number; + systemTsLastSampleMillis: number; + systemOffsetFirstTime?: number | null; + }): { + tsMillis: number; + systemTsMillis: number; + systemTsPlotMillis: number; + }; + /** + * Compute per-sample timestamps for a whole decoded burst. + * + * The base implementation treats every decoded sample as one evenly-spaced + * time step at `samplingRateHz` (correct when each decoded sample is a single + * combined time step). Sensors whose decoded array *interleaves* multiple + * streams at different cadences (e.g. the LSM6DSV tagged FIFO, which mixes + * accel / gyro / mag entries) override this to timestamp each stream on its + * own rate — otherwise the shared rate spreads each stream's samples too far + * back and consecutive blocks overlap on the time axis. + */ + computeSampleTimestamps(decodedSamples: unknown[], block: { + tsLastSampleMillis: number; + systemTsLastSampleMillis: number; + systemOffsetFirstTime?: number | null; + }): Array<{ + tsMillis: number; + systemTsMillis: number; + systemTsPlotMillis: number; + }>; + /** + * Turn a decoded + timestamped burst into one or more stream contributions + * for live throughput / packet-loss tracking. The default treats the sensor + * as a single stream; sensors whose decoded array interleaves several + * sub-streams at different cadences (e.g. the LSM6DSV tagged FIFO) override + * this to report one contribution per sub-stream so loss is tracked + * independently. + */ + getStreamContributions(samplesWithTime: Array<{ + timestamps?: { + tsMillis: number; + }; + }>, sensorId: number): StreamContribution[]; + /** Parse a raw sensor payload byte array into decoded samples. */ + abstract parsePayload(sensorPayloadBytes: Uint8Array): unknown[]; + /** Apply the Verisense operational config blob to update decoder settings. */ + abstract applyOperationalConfig(op: Uint8Array): void; +} + +interface ADCGSRSample { + raw: number; + adc12: number; + range: number; + volts: number; + kOhms: number; + uS: number; + connectivity: 'Connected' | 'Disconnected'; +} +interface ADCBatterySample { + /** Full 16-bit packed ADC/flags word from payload. */ + raw16: number; + /** 12-bit ADC value extracted from `raw16`. */ + adc12: number; + mV: number; + usbPluggedIn: boolean; + chargerStatusBits: number; + chargerStatus: string; +} +interface ADCPayloadSample { + gsr: ADCGSRSample | null; + batt: ADCBatterySample | null; +} +type HardwareIdentifier = 'VERISENSE_PULSE_PLUS' | 'VERISENSE_GSR_PLUS' | string; +/** + * Decoder for grouped ADC channels (Verisense sensor id = 1). + * + * Includes GSR plus battery/ADC channels carried in the same packet source. + * Implements C# `SensorGSR.cs` including: + * - Per-hardware reference resistor selection (SR68 vs Shimmer3 resistors). + * - Auto-range decoding from the raw ADC value's upper bits. + * - Range-3 clamping threshold that differs by hardware. + * - Conductance (uS) output with connectivity detection. + */ +declare class SensorADC extends SensorBase { + readonly LIMIT_MIN_VALID_USIEMENS = 0.03; + readonly GSR_UNCAL_LIMIT_RANGE3_SR68 = 1134; + readonly GSR_UNCAL_LIMIT_RANGE3_SR62 = 683; + private readonly SHIMMER3_REF_KOHMS; + private readonly SR68_REF_KOHMS; + /** + * ADC sample-rate code → divisor of the 32768 Hz clock. Mirrors the firmware + * `samplingRateInTicksArray` (hal_adc.c): the sampling timer fires every + * `divisor` ticks, producing one sample set per fire, so the streamed output + * rate = 32768 / divisor. Oversampling uses SAADC burst mode and therefore + * does NOT divide the output rate. Index 0 = "Off". + */ + private static readonly ADC_RATE_DIVISORS; + gsrEnabled: boolean; + battEnabled: boolean; + /** GSR range 0-3 (fixed) or 4 (auto-range). */ + gsrRangeSetting: number; + hardwareIdentifier: HardwareIdentifier; + hwRevisionMajor: number | null; + hwRevisionMinor: number | null; + hwRevisionInternal: number | null; + gsrRateSettingRaw: number; + gsrRangeSettingRaw: number; + gsrOversamplingRateSettingRaw: number; + constructor(); + setHardwareIdentifier(idStr: HardwareIdentifier): void; + setHardwareRevision(revHwMajor: number, revHwMinor: number, revHwInternal?: number): void; + setGsrRangeSetting(v: number): void; + private getBatteryVoltageMultiplier; + /** + * Whether this board uses the SR62 (Verisense GSR+) Shimmer3-style analog + * front end: 3.0 V SAADC reference, 40.2/287/1000/3300 kΩ GSR feedback + * resistors, 0.5 V GSR reference and range-3 uncal limit 683. Every other + * GSR-capable board (SR61 >= 5, SR68 >= 5 — firmware + * `ShimBrd_isGsrSupportedForHwVersion`) carries the second-generation DC + * front end: 1.8 V reference, 21/150/562/1740 kΩ, 0.4986 V, limit 1134. + * + * Mirrors the firmware's `selectFeedbackResistorsFromHwVersion` (hal_gsr.c), + * which keys the choice on the major revision alone (SR62 vs everything + * else). Prefers the production-config hardware revision; falls back to the + * caller-supplied hardware identifier when no revision has been read yet. + * Previously this was keyed only on the `VERISENSE_PULSE_PLUS` identifier + * string, so an SR61-5/6 presenting its true identity decoded ~1.91× high + * (DEV-874). + */ + private usesSr62GsrFrontEnd; + setEnabled(arg1: boolean | { + gsr?: boolean; + batt?: boolean; + }, opConfigBytes?: Uint8Array | null): Uint8Array | Record; + private _patchEnabled; + patchGsrRange(rangeCfg: number, op: Uint8Array): Uint8Array; + patchGsrSamplingRate(rateCfg: number, op: Uint8Array): Uint8Array; + patchGsrOversampling(overCfg: number, op: Uint8Array): Uint8Array; + calibrateAdcToVolts(uncal12bit: number): number; + calibrateGsrToKOhmsUsingAmplifierEq(volts: number, range: number): number; + nudgeGsrResistance(kOhms: number): number; + kOhmToUSiemens(kOhms: number): number; + /** + * Convert the 6-bit ADC sample-rate code to the streamed output rate in Hz, + * or null for "Off"/unknown codes. Used for per-sample timestamp spacing. + */ + decodeAdcSampleRateHz(rateCode: number): number | null; + parsePayload(sensorPayloadBytes: Uint8Array): ADCPayloadSample[]; + applyOperationalConfig(op: Uint8Array): void; +} + +type AccelRange$1 = '2G' | '4G' | '8G' | '16G'; +interface LIS2DW12Sample { + raw: [number, number, number]; + cal: [number, number, number]; + units: { + cal: string; + }; +} +/** + * Decoder for the LIS2DW12 low-power accelerometer (Verisense sensor id = 2). + * + * Sensitivity values are given in raw-LSB / (m/s²) per axis — matching + * the C# `SensorLIS2DW12.cs` implementation. + */ +declare class SensorLIS2DW12 extends SensorBase { + offset: [number, number, number]; + align: [[number, number, number], [number, number, number], [number, number, number]]; + private readonly sensitivityByRange; + range: AccelRange$1; + /** Numeric full-scale index (0=2G..3=16G) used to select the device calibration block. */ + private rangeIndex; + constructor(); + setRange(rangeStr: AccelRange$1): void; + setEnabled(enabled: boolean, opConfigBytes?: Uint8Array | null): Uint8Array | boolean; + setAccelEnabled(enabled: boolean, opConfigBytes?: Uint8Array | null): Uint8Array | boolean; + patchAccelRange(rangeCfg: number, op: Uint8Array): Uint8Array; + patchAccelSamplingRate(rateCfg: number, op: Uint8Array): Uint8Array; + private _calibrate; + parsePayload(sensorPayloadBytes: Uint8Array): LIS2DW12Sample[]; + applyOperationalConfig(op: Uint8Array): void; +} + +type AccelRange = '2G' | '4G' | '8G' | '16G'; +type GyroRange = '250DPS' | '500DPS' | '1000DPS' | '2000DPS'; +interface LSM6DS3Sample { + accel: { + raw: [number, number, number]; + cal: [number, number, number]; + units: string; + } | null; + gyro: { + raw: [number, number, number]; + cal: [number, number, number]; + units: string; + } | null; +} +/** + * Decoder for the LSM6DS3 combined accelerometer + gyroscope (Verisense sensor id = 3). + * + * Sensitivity values mirror the C# `SensorLSM6DS3.cs` implementation. + */ +declare class SensorLSM6DS3 extends SensorBase { + offset: [number, number, number]; + align: [[number, number, number], [number, number, number], [number, number, number]]; + private readonly accSensByRange; + private readonly gyroSensByRange; + accRange: AccelRange; + gyroRange: GyroRange; + accEnabled: boolean; + gyroEnabled: boolean; + constructor(); + setAccelEnabled(v: boolean): void; + setGyroEnabled(v: boolean): void; + setAccelRange(r: AccelRange): void; + setGyroRange(r: GyroRange): void; + private _applyAlignAndOffset; + private static readonly ACC_RANGE_CODE; + private static readonly GYRO_RANGE_CODE; + private _calibrateAccel; + private _calibrateGyro; + parsePayload(sensorPayloadBytes: Uint8Array): LSM6DS3Sample[]; + applyOperationalConfig(op: Uint8Array): void; +} + +interface LSM6DSVSample { + tag: number; + cnt: number; + accel: { + raw: [number, number, number]; + cal: [number, number, number]; + units: string; + } | null; + gyro: { + raw: [number, number, number]; + cal: [number, number, number]; + units: string; + } | null; + mag: { + raw: [number, number, number]; + cal: [number, number, number]; + units: string; + } | null; +} +declare class SensorLSM6DSV extends SensorBase { + private static readonly TAG_GYRO; + private static readonly TAG_ACCEL; + private static readonly TAG_SENSORHUB_SLAVE0; + accEnabled: boolean; + gyroEnabled: boolean; + magEnabled: boolean; + private accelFsG; + private gyroFsDps; + private fsXlCode; + private fsGCode; + accelHz: number; + gyroHz: number; + magHz: number; + constructor(); + private decodeAccelFsG; + private decodeGyroFsDps; + private decodeOdrHz; + private decodeMagOutputRateHz; + private calibrateAccel; + private calibrateGyro; + private calibrateMag; + parsePayload(sensorPayloadBytes: Uint8Array): LSM6DSVSample[]; + applyOperationalConfig(op: Uint8Array): void; + /** + * Timestamp each stream (accel / gyro / mag) so all three cover the same block + * time window. The tagged FIFO interleaves the streams, so the generic + * global-index spacing spreads each stream by (#interleaved-streams)x too far + * back and makes consecutive blocks overlap on the time axis. + * + * Each stream's effective rate is derived from *this block*: the block's + * covered duration is taken from a directly-sampled reference stream (accel, + * else gyro) at its known ODR, and every stream is then spread evenly over + * that same duration by its own sample count. This is important for the mag + * (LIS2MDL), which is read via the LSM6DSV sensor hub — its entries land in + * the FIFO at the hub batch rate, NOT the LIS2MDL ODR, so a fixed mag ODR + * would mis-spread it (the zig-zag). Deriving the rate from the block keeps it + * aligned regardless of the hub rate. + */ + computeSampleTimestamps(decodedSamples: unknown[], block: { + tsLastSampleMillis: number; + systemTsLastSampleMillis: number; + systemOffsetFirstTime?: number | null; + }): Array<{ + tsMillis: number; + systemTsMillis: number; + systemTsPlotMillis: number; + }>; + /** + * Report up to three independent sub-streams (accel / gyro / mag) so loss is + * tracked per stream. Each sub-stream's expected rate is its configured rate + * (ODR for accel/gyro, output rate for mag); loss is measured against that, so + * the mag's hub-trigger bound — or any rate the firmware/link can't keep up + * with — surfaces as loss when a configured rate exceeds what's delivered. + */ + getStreamContributions(samplesWithTime: Array<{ + timestamps?: { + tsMillis: number; + }; + }>, sensorId: number): StreamContribution[]; +} + +interface PPGChannelSample { + raw: number; + cal: number; + units: { + raw: string; + cal: string; + }; +} +interface PPGSample { + RED?: PPGChannelSample; + IR?: PPGChannelSample; + GREEN?: PPGChannelSample; + BLUE?: PPGChannelSample; + /** + * 2nd-generation hub PPG: 3 raw MAX86176 LED channel counts (24-bit), in the + * order [green, IR, red] (LED1=green, LED2=IR, LED3=red per the board's LED + * driver wiring). The MAX86176 is reached only via the MAX32674 algorithm hub + * and measures these 3 LEDs on photodiode PD1 (its PD2 copies are not + * forwarded). + */ + leds?: [number, number, number]; +} +type PPGChannel = 'RED' | 'IR' | 'GREEN' | 'BLUE'; +/** + * Decoder for the PPG sensor (Verisense sensor id = 4). + * + * Calibration constants mirror C# `SensorPPG.cs`. + */ +declare class SensorPPG extends SensorBase { + red: boolean; + ir: boolean; + green: boolean; + blue: boolean; + /** + * 2nd-gen hub mode: PPG arrives via the MAX32674 hub as a fixed block of 6 raw + * MAX86176 LED channels (6 x u24), independent of the RED/IR/GREEN/BLUE enable + * bits. Set from the connected device's hardware generation (see + * VerisenseClient). When false, the 1st-gen named-channel layout is used. + */ + hubMode: boolean; + private readonly adcLsb; + private readonly adcBitShift; + adcResolutionIndex: number; + /** PPG_SR code → base sampling rate in Hz (op byte PPG_MODE_CONFIG2 bits 4:2). */ + private readonly PPG_SR_HZ; + /** SMP_AVE code → FIFO sample-averaging factor (op byte PPG_FIFO_CONFIG bits 7:5). */ + private readonly SMP_AVE_FACTOR; + constructor(); + setChannels(channels: Partial>): void; + setHubMode(enabled: boolean): void; + setAdcResolutionIndex(i: number): void; + calibrateValue(uncalValue: number): number; + /** + * 2nd-gen hub PPG block: N samples x (3 x u24 LED channels = green, IR, red), + * no count prefix (sample count derived from the block length, matching the + * firmware packer). + */ + private parseHubPayload; + parsePayload(sensorPayloadBytes: Uint8Array): PPGSample[]; + applyOperationalConfig(op: Uint8Array): void; +} + +/** Per-channel raw ambient-light counts (24-bit) plus the derived illuminance + * (lux) and correlated colour temperature (CCT, Kelvin). Channel order matches + * the firmware VD6283 AlsResults block: RED, VISIBLE, BLUE, GREEN, IR, CLEAR. + * + * The second slot is shared: the VD6283 routes EITHER the visible/clear reading + * OR the dark (covered-photodiode) baseline onto it, selected by the op-config + * dark-channel bit. They are mutually exclusive, so exactly one of `VISIBLE` / + * `DARK` is a number per sample and the other is `null`. */ +interface VD6283Sample { + RED: number; + /** Visible/clear channel count, or `null` when the dark channel is enabled + * (the chip then routes the dark baseline onto this slot — see `DARK`). */ + VISIBLE: number | null; + BLUE: number; + GREEN: number; + IR: number; + CLEAR: number; + /** Dark/covered-photodiode baseline count, or `null` when the dark channel is + * disabled (the slot then carries the visible reading — see `VISIBLE`). */ + DARK: number | null; + /** Illuminance in lux (XYZ Y component; clamped to >= 0). */ + lux: number; + /** Correlated colour temperature in Kelvin (0 if undefined). */ + cct: number; +} +/** + * Decoder for the VD6283TX45 ambient light sensor (Verisense sensor id = 7). + * + * Data block payload = N samples x 18 bytes (6 channels x 24-bit LE counts). + * In addition to the raw channel counts, each sample carries the derived lux + * and CCT, computed from the RED/GREEN/BLUE channels with the configured gain + * and exposure (ported from firmware App_vd6283tx.c). + */ +declare class SensorVD6283 extends SensorBase { + static readonly NUM_CHANNELS = 6; + static readonly BYTES_PER_SAMPLE = 18; + private exposureUs; + private gain8p8; + /** Op-config dark-channel bit (LIGHT_CONFIG bit 1): when set the shared second + * slot carries the dark baseline (`DARK`) instead of the visible reading. */ + private darkEnabled; + constructor(); + /** Normalise a raw channel count for the XYZ transform (gain + exposure). */ + private normalizeForXyz; + /** Compute illuminance (lux) and CCT (K) from RED/GREEN/BLUE counts. */ + private computeLuxCct; + parsePayload(sensorPayloadBytes: Uint8Array): VD6283Sample[]; + applyOperationalConfig(op: Uint8Array): void; +} + +/** + * One algorithm-hub sample: accel + WHRM algorithm output. The raw MAX86176 PPG + * is no longer carried here - it streams separately under the PPG sensor id (4), + * see SensorPPG hub mode. + */ +interface MAX32674Sample { + accel: { + raw: [number, number, number]; + }; + /** Heart rate (bpm) and confidence (0-100). */ + hr: number; + hrConfidence: number; + /** SpO2 (%) and confidence; 0 until SpO2 mode is enabled. */ + spo2: number; + spo2Confidence: number; + activityClass: number; + scdContactState: number; +} +/** + * Decoder for the MAX32674 algorithm hub (Verisense sensor id = 8). + * + * Data block payload = [sampleCount:1] then sampleCount x 14 bytes: + * accel x,y,z : 3 x i16 (6) | hr u16 (2) | hr_conf u8 (1) | + * spo2 u16 (2) | spo2_conf u8 (1) | activity u8 (1) | scd_contact u8 (1) + * + * Raw PPG is reported separately under the PPG sensor id (4). + */ +declare class SensorMAX32674 extends SensorBase { + static readonly BYTES_PER_SAMPLE = 14; + constructor(); + parsePayload(sensorPayloadBytes: Uint8Array): MAX32674Sample[]; + applyOperationalConfig(op: Uint8Array): void; +} + +/** One skin-temperature sample. Object = skin temperature, ambient = sensor + * ambient, both in degrees Celsius. */ +interface MLX90632Sample { + object: { + raw: number; + cal: number; + units: string; + }; + ambient: { + raw: number; + cal: number; + units: string; + }; +} +/** + * Decoder for the MLX90632 skin temperature sensor (Verisense sensor id = 9). + * + * Data block payload = N samples x 4 bytes: object int16 then ambient int16, + * each in centi-degrees Celsius (value / 100 = degrees C). + */ +declare class SensorMLX90632 extends SensorBase { + static readonly BYTES_PER_SAMPLE = 4; + constructor(); + parsePayload(sensorPayloadBytes: Uint8Array): MLX90632Sample[]; + applyOperationalConfig(op: Uint8Array): void; +} + +type TransportKind = 'ble' | 'serial' | null; +type DeviceMode = 'idle' | 'streaming' | 'command' | 'logged'; +interface SensorMap { + 1: SensorADC; + 2: SensorLIS2DW12; + 3: SensorLSM6DS3; + 4: SensorPPG; + 6: SensorLSM6DSV; + 7: SensorVD6283; + 8: SensorMAX32674; + 9: SensorMLX90632; +} +interface StreamPacket { + sensorId: number; + tick_u24: number; + decoded: unknown[] | null; + rawPayload: Uint8Array; + crcOk: boolean | null; +} +interface LoggedTransferProgressInfo { + payloadIndex: number; + bytesWritten: number; + crcOk: boolean; +} +interface TransferLoggedDataOptions { + fileHandle?: FileSystemFileHandle | null; + timeoutMs?: number; + maxNack?: number; + maxCrcNack?: number; + onProgress?: ((info: LoggedTransferProgressInfo) => void) | null; +} +interface TransferLoggedDataResult { + ok: boolean; + bytesWritten: number; + payloadIndex?: number; + blob?: Blob; +} +interface RunHardwareTestReportOptions { + timeoutMs?: number; + marker?: string; + endMarker?: string; + completionIdleMs?: number; + factoryTestType?: number; + signal?: AbortSignal | null; + onChunk?: ((chunk: string, aggregate: string) => void) | null; +} +interface VerisenseClientOptions { + hardwareIdentifier?: string; + /** + * Streaming frames carry a 2-byte CRC-16 trailer. When `true` (default) the + * trailer is used to lock onto frame boundaries — the parser accepts a frame + * only when its CRC validates, so a flaky link that drops bytes recovers + * cleanly instead of emitting misaligned packets — and is then stripped before + * decoding. Set to `false` only for legacy firmware that streams without a CRC + * trailer (falls back to length-only framing). + */ + stripStreamCrc?: boolean; + debug?: boolean; +} +interface BleThroughputTestOptions { + /** How long the device should saturate the link, in milliseconds. Clamped to [100, 60000]. Default 5000. */ + durationMs?: number; + /** + * Finish the measurement once no data has been received for this many + * milliseconds (the device falls silent when the blast ends). Default 600. + */ + idleMs?: number; + /** Overall safety timeout, in milliseconds. Defaults to `durationMs + 5000`. */ + timeoutMs?: number; + /** Abort the test early. */ + signal?: AbortSignal | null; + /** Called on every received chunk with the running result so far. */ + onProgress?: ((partial: BleThroughputTestResult) => void) | null; +} +interface BleThroughputTestResult { + /** Total bytes received from the device during the measurement window. */ + bytesReceived: number; + /** Number of BLE notification chunks received. */ + packetsReceived: number; + /** Duration requested of the device, in milliseconds. */ + durationRequestedMs: number; + /** Measured window from first to last received byte, in milliseconds. */ + elapsedMs: number; + /** Received goodput in bytes per second. */ + throughputBytesPerSec: number; + /** Received goodput in kilobytes per second (bytes/sec ÷ 1000). */ + throughputKBps: number; + /** Received goodput in kilobits per second (bytes/sec × 8 ÷ 1000). */ + throughputKbps: number; +} +type VerisenseConnectRetryReason = 'request-timeout' | 'gatt-disconnected' | 'unexpected-response-property'; +interface VerisenseConnectWithRetryOptions { + device?: BluetoothDevice | null; + filters?: BluetoothLEScanFilter[]; + optionalServices?: BluetoothServiceUUID[]; + bootstrapTimeoutMs?: number; + pairingBootstrapTimeoutMs?: number; + maxRetries?: number; + retrySettleMs?: number; + retryOnUnexpectedProperty?: boolean; + onRetry?: ((info: VerisenseConnectRetryInfo) => void) | null; +} +interface VerisenseConnectRetryInfo { + attempt: number; + maxRetries: number; + bootstrapTimeoutMs: number; + nextBootstrapTimeoutMs?: number; + reason: VerisenseConnectRetryReason; + error: string; +} +interface VerisenseCommandResponse { + header: number; + command: AsmCommand; + property: AsmProperty; + payload: Uint8Array; +} +type BleLinkAutoOptimizeStopReason = 'stabilized' | 'timeout' | 'aborted' | 'unsupported' | 'not-ble'; +interface BleLinkAutoOptimizeOptions { + pollIntervalMs?: number; + stableReadCount?: number; + maxDurationMs?: number; + settleMode?: 'target-and-stability' | 'stability'; + minSettleTimeMs?: number; + forceOptimizeAttempts?: number; + targetConnectionIntervalUnits?: number; + targetPhy?: number; + minDataLength?: number; + signal?: AbortSignal | null; + onSample?: ((sample: BleLinkAutoOptimizeSample) => void) | null; +} +interface BleLinkAutoOptimizeSample { + source: 'read' | 'optimize'; + iteration: number; + stableCount: number; + parsed: VerisenseBleLinkDebugPayload; + signature: string; + optimizedEnough: boolean; +} +interface BleLinkAutoOptimizeResult { + reason: BleLinkAutoOptimizeStopReason; + iterations: number; + optimizeAttempts: number; + stableCount: number; + lastParsed: VerisenseBleLinkDebugPayload | null; + durationMs: number; +} + +/** + * Web Bluetooth client for the Verisense sensor platform. + * + * Extends {@link BaseShimmerClient} and adds an event-emitter API + * (on/off/emit) for the richer event model the Verisense protocol needs. + * + * Supports: + * - BLE streaming (accel, ADC/GSR, gyro, PPG) + * - Web Serial (USB COM port) as an alternative transport + * - Logged-data download (`transferLoggedData`) + * - Operational config read/write + * + * Events: + * - `"connected"` — `{ name?: string; id?: string; kind?: string }` + * - `"disconnected"` — `{ kind: TransportKind }` + * - `"streaming"` — `{ on: boolean }` + * - `"streamPacket"` / `"data"` — `StreamPacket` + * - `"streamStats"` — `StreamStatsSnapshot` (throttled ~3 Hz live throughput/loss) + * - `"opConfig"` — `{ op: Uint8Array }` + * - `"productionConfig"` — `ProductionConfig` + * - `"commandPayload"` — `{ payload: Uint8Array }` + */ +declare class VerisenseBleDevice extends BaseShimmerClient { + private static readonly MAX_FRAME_PAYLOAD_LEN; + private static readonly MAX_DEBUG_FRAME_PAYLOAD_LEN; + static readonly NUS_SERVICE = "6e400001-b5a3-f393-e0a9-e50e24dcca9e"; + static readonly NUS_TX = "6e400002-b5a3-f393-e0a9-e50e24dcca9e"; + static readonly NUS_RX = "6e400003-b5a3-f393-e0a9-e50e24dcca9e"; + private readonly _evMap; + on(ev: string, fn: (data: T) => void): () => void; + off(ev: string, fn: (data: unknown) => void): void; + emit(ev: string, data?: unknown): void; + private _transportKind; + device: BluetoothDevice | null; + private server; + private service; + tx: BluetoothRemoteGATTCharacteristic | null; + rx: BluetoothRemoteGATTCharacteristic | null; + port: SerialPort | null; + private _serialAbort; + private _serialReader; + private _serialReadLoopTask; + private _onGattDisconnected; + private _suppressDisconnectedEvent; + private _mode; + private _rxStreamBuf; + private _pending; + private _loggedChain; + private _sync; + private _testReportMode; + private _throughputTestMode; + private _bootstrapRequestTimeoutOverrideMs; + private _connectCancelRequested; + private _isSecondGenerationHw; + private readonly _streamStats; + private _lastStreamStatsEmitMillis; + readonly stripStreamCrc: boolean; + readonly hardwareIdentifier: string; + readonly sensors: SensorMap; + operationalConfig: Uint8Array | null; + productionConfig: Uint8Array | null; + debugSync: boolean; + private _syncRxCount; + private _syncPayloadCount; + constructor(opts?: VerisenseClientOptions); + protected _log(...args: unknown[]): void; + get adc(): SensorADC; + get accel1(): SensorLIS2DW12; + get gyroAccel2(): SensorLSM6DS3 | SensorLSM6DSV; + get gyroAccel2Lsm6ds3(): SensorLSM6DS3; + get gyroAccel2Lsm6dsv(): SensorLSM6DSV; + get ppg(): SensorPPG; + private _setOperationalConfigErasedFallback; + private _bootstrapConfigsAfterConnect; + connect(opts?: { + device?: BluetoothDevice | null; + filters?: BluetoothLEScanFilter[]; + optionalServices?: BluetoothServiceUUID[]; + }): Promise; + private _cleanupFailedBleConnectAttempt; + private _retryBootstrapInPlaceWithBudget; + connectWithRetry(opts?: VerisenseConnectWithRetryOptions): Promise; + connectSerial(opts?: { + port?: SerialPort | null; + baudRate?: number; + dataBits?: number; + stopBits?: number; + parity?: ParityType; + flowControl?: FlowControlType; + filters?: SerialPortFilter[] | null; + }): Promise; + private _serialWrite; + private _startSerialReadLoop; + private _serialDisconnect; + disconnect(opts?: { + reason?: string; + }): Promise; + startStreaming(): Promise; + stopStreaming(): Promise; + transferLoggedData(opts?: TransferLoggedDataOptions): Promise; + writeBytes(bytes: Uint8Array | number[], opts?: { + withResponse?: boolean; + }): Promise; + private _requestByCommand; + readProperty(property: AsmProperty, timeoutMs?: number): Promise; + writeProperty(property: AsmProperty, payloadBytes?: number[] | Uint8Array, timeoutMs?: number): Promise; + request(opcode: number, payloadBytes?: number[] | Uint8Array, timeoutMs?: number): Promise<{ + payload: Uint8Array; + }>; + readStatus(): Promise<{ + payload: Uint8Array; + }>; + readStatusParsed(): Promise; + readStatus2(): Promise<{ + payload: Uint8Array; + }>; + readStatus2Parsed(): Promise; + readData(): Promise<{ + payload: Uint8Array; + }>; + readProductionConfig(): Promise<{ + payload: Uint8Array; + }>; + readOperationalConfig(): Promise<{ + payload: Uint8Array; + }>; + readTime(): Promise<{ + payload: Uint8Array; + }>; + readTimeUnixSeconds(): Promise; + readPendingEvents(): Promise<{ + payload: Uint8Array; + }>; + readPendingEventsParsed(): Promise; + writeProductionConfig(bytes: Uint8Array | number[]): Promise; + writeOperationalConfig(bytes: Uint8Array | number[]): Promise; + writeTime(rtc7: Uint8Array | number[]): Promise; + writeTimeUnixSeconds(unixSeconds: number): Promise; + /** + * Request the Verisense firmware to expose the Nordic Secure DFU service. + * + * Writes the ASM `DFU_MODE` property. The firmware treats this as a request + * to enable the buttonless DFU service but does NOT reboot or expose the + * service immediately — it enables it on the next BLE disconnect. The host + * must therefore disconnect and reconnect before the Nordic DFU service (and + * {@link rebootToDfuBootloader}) become available on the connection. + */ + enableDfuServiceOnNextDisconnect(): Promise; + /** + * Reboot the device straight into the Nordic Secure DFU bootloader using the + * buttonless DFU service. + * + * Requires the Nordic DFU service to already be active on the current BLE + * connection — call {@link enableDfuServiceOnNextDisconnect}, then disconnect + * and reconnect first. Writes the "Enter Bootloader" op-code (0x01) to the + * buttonless DFU control-point characteristic; the device acknowledges via an + * indication, then disconnects and resets into the bootloader. + * + * @param options.waitForDisconnect Resolve only once the device drops the + * link (i.e. has begun rebooting). Default `true`. + * @param options.disconnectAfterCommand Force a local GATT disconnect if the + * device has not dropped the link itself. Default `true`. + * @param options.timeoutMs Max time to wait for the device to + * disconnect after the command. Default `10000`. + */ + rebootToDfuBootloader(options?: { + waitForDisconnect?: boolean; + disconnectAfterCommand?: boolean; + timeoutMs?: number; + }): Promise; + /** + * Resolve when the BLE link drops (`gattserverdisconnected`), or after + * `timeoutMs`. Resolves `true` if the device disconnected, `false` on timeout. + */ + private _waitForGattDisconnect; + runTestMode(testPayload: Uint8Array | number[]): Promise; + runHardwareTest(testId: TestModeId, hwMajor: number, hwMinor?: number, hwInternal?: number): Promise; + /** + * Ask the device to stop/exit any running test, including an in-progress + * hardware test report (TEST_MODE "exit", id 0x00). The firmware acts on this + * from interrupt context, so it aborts the blocking report promptly instead of + * running it to completion against a connection no one is reading. Best-effort + * and safe to call when no test is running. + */ + stopTestMode(hwMajor?: number, hwMinor?: number, hwInternal?: number): Promise; + runHardwareTestReport(hwMajor: number, hwMinor?: number, hwInternal?: number, opts?: RunHardwareTestReportOptions): Promise; + private _buildDebugPayload; + private _debugIndexArgs; + private _waitForDebugResponse; + readDebugCommand(debugId: DebugCommandId, args?: Uint8Array | number[], timeoutMs?: number): Promise<{ + payload: Uint8Array; + }>; + sendDebugCommand(debugId: DebugCommandId, args?: Uint8Array | number[], timeoutMs?: number): Promise<{ + payload: Uint8Array; + }>; + /** + * Stream a MAX32674C algorithm-hub firmware image (.msbl) to the device and + * flash it into the hub via the Maxim bootloader. This is a one-time factory + * operation: it blocks the device for ~1-2 minutes while the hub flash is + * erased and each page is written. Only SR68 Pulse+ hardware (the only board + * carrying the hub) accepts it — other hardware NACKs the BEGIN stage. + * + * @param msbl raw .msbl file bytes + * @param onProgress optional progress callback (pagesDone, totalPages) + * @returns the hub application firmware version string read back after flashing + */ + uploadHubFirmware(msbl: Uint8Array | number[], onProgress?: (pagesDone: number, totalPages: number) => void): Promise; + /** Build a debug payload `[HUB_FW_UPLOAD, stage, ...stageArgs]`. */ + private _buildHubUploadPayload; + /** Send one 8208-byte page as in-order <=64-byte chunks; await ACK_NEXT_STAGE. */ + private _sendHubPage; + /** Best-effort abort: tell the device to reset the hub back to application mode. */ + private _abortHubUpload; + /** Read the flash lookup table. The read walks the whole flash on-device + * and can time out on busy sensors, so `retries` re-issues the command + * (total attempts = retries + 1) before giving up. Non-finite or negative + * `retries` is treated as 0; rejections are always `Error` instances. */ + readFlashLookupTable(index?: number, timeoutMs?: number, retries?: number): Promise<{ + payload: Uint8Array; + }>; + readRealWorldClockScheduler(index?: number): Promise<{ + payload: Uint8Array; + }>; + readRealWorldClockSchedulerParsed(index?: number): Promise; + loadTestLookupTable(index?: number): Promise<{ + payload: Uint8Array; + }>; + checkPayloadCrcErrors(index?: number): Promise<{ + payload: Uint8Array; + }>; + checkPayloadCrcErrorsParsed(index?: number): Promise; + readEventLog(index?: number): Promise<{ + payload: Uint8Array; + }>; + readEventLogParsed(index?: number): Promise; + readRecordBufferDetails(index?: number): Promise<{ + payload: Uint8Array; + }>; + readRecordBufferDetailsParsed(index?: number): Promise; + eraseOperationalConfig(): Promise; + eraseProductionConfig(): Promise; + clearPendingEvents(): Promise; + eraseAllLoggedData(timeoutMs?: number): Promise; + /** + * Low-level: ask the device to saturate the BLE link with dummy data for + * `durationMs` milliseconds (debug command 0x0B). The device ACKs immediately + * and then blasts a fixed 244-byte buffer as fast as the link will accept it. + * + * This only starts the blast; it does not measure anything. Prefer + * {@link runBleThroughputTest}, which sends this command and measures the + * throughput actually received at the host. + * + * @param durationMs Blast duration in milliseconds (clamped to the protocol's 0..65535 range). + */ + testDataTransferLoop(durationMs: number): Promise; + /** + * Measure the maximum BLE link throughput, independent of sensor + * configuration. Asks the device to blast dummy data for `durationMs` + * (see {@link testDataTransferLoop}) and measures the goodput actually + * received at the host. + * + * The reported rate reflects device→host (notification) throughput and is + * governed by the negotiated PHY, connection interval, MTU and packets per + * connection interval — i.e. the real link, not any sensor's sample rate. + * + * The measurement finishes when the device falls silent for `idleMs` after + * the blast (or when the overall safety timeout elapses). + * + * @returns received byte/packet counts and the computed throughput. + */ + runBleThroughputTest(opts?: BleThroughputTestOptions): Promise; + ledTest(ledIndex: number): Promise; + max86xxxLedTest(start: boolean): Promise; + startPowerProfilerTest(): Promise; + requestSystemReset(): Promise; + startIcPowerConsumptionTest(loopCount: number, stageIntervalMs: number): Promise; + deleteAllBonds(): Promise; + private _assertBleLinkDebugSupported; + readBleLinkParams(): Promise<{ + payload: Uint8Array; + }>; + readBleLinkParamsParsed(): Promise; + optimizeBleLink(): Promise<{ + payload: Uint8Array; + }>; + optimizeBleLinkParsed(): Promise; + private _bleLinkSignature; + private _bleLinkOptimizedEnough; + private _isAbortError; + private _waitWithAbort; + autoOptimizeBleLink(opts?: BleLinkAutoOptimizeOptions): Promise; + setStreamingMode(enabled: boolean): Promise; + disconnectRequest(): Promise<{ + payload: Uint8Array; + }>; + getOpConfig(): Promise; + private _isErasedBlob; + private _isZeroBlob; + private _isUninitializedBlob; + readProductionConfigFromDevice(): Promise; + readOpConfigFromDevice(): Promise; + /** + * Push an operational config into every sensor decoder (rates, ranges, + * channel enables) and cache it as the client's working config. Used + * automatically after {@link readOpConfigFromDevice}; call it directly when + * loading a config from a template/file without a device round-trip. + */ + applyOperationalConfig(opConfigBytes: Uint8Array | number[]): void; + writeOpConfig(opConfigBytes: Uint8Array | number[]): Promise; + /** Per-device calibration last read from the device, or null. */ + private _calibration; + /** The parsed calibration set last read via {@link readCalibrationParsed}, or null. */ + getCalibration(): CalibrationSet | null; + /** + * Read the raw calibration blob from the device (CMD_AR_CFG_CALIB). The whole + * blob (~1 KB) arrives in one response, reassembled across BLE/USB fragments. + * Requires FW v2.0.4+; older firmware NACKs or times out. + */ + readCalibration(timeoutMs?: number): Promise; + /** + * Read + parse the calibration set, cache it, and push it into the IMU + * decoders so subsequent samples calibrate from per-device values. Call before + * a logged-data transfer and/or after connect (no-op on FW that lacks it — + * the call rejects and the decoders keep their full-scale fallback). + */ + readCalibrationParsed(): Promise; + /** + * Write a calibration blob to the device (CMD_AR_CFG_CALIB), chunked in + * <=128-byte pieces as [offset_lo, offset_hi, ...chunk]. The device reassembles + * and commits on the final chunk. Requires FW v2.0.4+. + */ + writeCalibration(blob: Uint8Array, chunkSize?: number): Promise; + getSensor(name: string | number): SensorBase | null; + private _abortSync; + private _finishSync; + private _handleLoggedPayload; + private _resetAssembler; + private _appendStreamBuf; + private _clearSyncRxBuffers; + private _isPlausibleHeaderByte; + private _isPlausibleFrameStart; + private _resolvePendingCommand; + private _feedStreamBytes; + private _handleStreamingPayload; + /** Snapshot of live stream statistics (throughput / packet-loss). */ + getStreamStats(): StreamStatsSnapshot; +} + +/** + * Verisense Nordic Secure-DFU flow helpers (DEV-845). + * + * The byte transport is Nordic's `web-bluetooth-dfu` library (`SecureDfu` + + * `SecureDfuPackage`, vendored by consuming apps); this module owns everything + * learned about running that library reliably against Verisense sensors over + * desktop Chrome/Edge Web Bluetooth: + * + * - classification of transient BLE-stack errors vs DFU protocol errors + * - a fix for the library's swallowed-rejection hang in `sendOperation` + * - bounded + retried `setDfuMode` (with a full GATT reset between attempts) + * - the two-phase combined-package update (SoftDevice/bootloader then + * application), including resume of an interrupted combined update + * - the bootloader device-picker filter and packet-pacing defaults + * + * The library objects are injected (structurally typed), so this module has no + * build-time dependency on the vendored scripts. All user-visible progress is + * reported through an `onStatus` callback; no DOM access happens here. + */ +/** + * Transient connection/BLE-stack errors worth retrying. "unknown reason" + * (NotSupportedError) is Chrome-on-Windows' generic wrapper for any GATT + * operation the OS stack fails without an ATT error code (DEV-845) — + * typically a startNotifications/write right after a (re)connect, or a + * link being torn down mid-encryption. Recoverable on retry; DFU protocol + * errors (wrong image, version too low, ...) never match. + */ +declare const VERISENSE_DFU_TRANSIENT_ERROR_REGEX: RegExp; +/** Total attempts (first try + retries) for the DFU connection-retry helpers. */ +declare const VERISENSE_DFU_CONNECT_ATTEMPTS = 3; +/** Delay between DFU connection retries, letting the device finish rebooting. */ +declare const VERISENSE_DFU_RETRY_DELAY_MS = 2000; +/** Time allowed for the base image's post-install reboot back into the bootloader. */ +declare const VERISENSE_DFU_REBOOT_DELAY_MS = 3000; +/** Bound on `setDfuMode` (connect + notifications + one write): the happy path + * completes in seconds, so a hit means a genuine stall — including the vendored + * library's swallowed-rejection case that {@link patchSecureDfuSendOperation} + * and {@link promiseWithTimeout} exist to catch. */ +declare const VERISENSE_DFU_SET_MODE_TIMEOUT_MS = 30000; +/** + * Per-packet pacing for the firmware transfer, in ms. The packet + * characteristic is written without response; over Web Bluetooth, Chrome + * drops packets if it outruns the device, so at 0 ms the first pass can fail + * object CRC validation and the library silently retries the WHOLE transfer + * at ~10 ms (the pass that succeeds). Pacing at 10 ms makes the first pass + * succeed outright. Pass 0 ("fast") for full speed on a known-clean link. + * (nRF Connect sidesteps this via a wired connectivity dongle rather than + * the OS BLE stack.) + */ +declare const VERISENSE_DFU_RELIABLE_PACKET_DELAY_MS = 10; +declare const VERISENSE_DFU_FAST_PACKET_DELAY_MS = 0; +/** + * The Verisense bootloader advertises as "Verisense-BL..."; app-mode sensors + * ("Verisense-..." without the -BL) are deliberately excluded from DFU device + * pickers to keep them unambiguous. The DFU service UUID is not advertised in + * app mode, so it cannot be used to widen the filter; it still needs to be + * granted via `optionalServices` for the GATT connection. + */ +declare const VERISENSE_DFU_BOOTLOADER_NAME_PREFIX = "Verisense-BL"; +/** + * The library's routine object-retransmission notices (e.g. "object failed to + * validate"). Over Web Bluetooth, firmware packets are written without + * response and Chrome can drop one if it outruns the device; that makes a + * 4 KB object's CRC mismatch, so the library transparently re-creates and + * re-sends that object. The transfer still completes correctly (every object + * is CRC-checked before Execute, and the bootloader CRC/signature-checks the + * whole image), so these are non-issues that only alarm users. Real failures + * still surface via the promise rejection paths. + */ +declare const VERISENSE_DFU_ROUTINE_LOG_REGEX: RegExp; +/** True for library log messages that are routine retransmission noise and + * should not be surfaced to end users (see {@link VERISENSE_DFU_ROUTINE_LOG_REGEX}). */ +declare function isRoutineVerisenseDfuLogMessage(message: string): boolean; +/** "attempt N of M" wording for retry status lines. The retry helpers count + * attempts DOWN (remaining, including the one that just failed), so the + * attempt about to start is total - remaining + 2. */ +declare function verisenseDfuAttemptLabel(attemptsRemaining: number, totalAttempts?: number): string; +/** A firmware image entry from a Nordic DFU package (`SecureDfuPackage`). */ +interface VerisenseDfuImage { + type?: string; + initFile?: string; + imageFile?: string; + initData: ArrayBuffer; + imageData: ArrayBuffer; +} +/** Structural view of Nordic's `SecureDfuPackage` (base = SoftDevice / + * bootloader / both; app = application image). */ +interface VerisenseDfuPackage { + getBaseImage(): Promise; + getAppImage(): Promise; +} +/** Structural view of the `SecureDfu` instance methods this module drives. */ +interface SecureDfuLike { + /** Resolves with the device when it is already in bootloader mode, or + * null/undefined after the buttonless reboot command has been sent. */ + setDfuMode(device: BluetoothDevice): Promise; + update(device: BluetoothDevice, init: ArrayBuffer, image: ArrayBuffer): Promise; +} +interface SecureDfuSendOperationInternals { + notifyFns: Record void; + reject: (reason?: unknown) => void; + }>; + log(message: unknown): void; + delayPromise(ms: number): Promise; +} +type SecureDfuSendOperation = (this: SecureDfuSendOperationInternals, characteristic: { + writeValue(value: BufferSource): Promise; +}, operation: ArrayLike, buffer?: ArrayBuffer) => Promise; +/** + * Fix the swallowed-rejection hang in `web-bluetooth-dfu` v1.2.1 (DEV-845): + * upstream `SecureDfu.sendOperation` retries a failed control-point write once + * after 500 ms, but if the retry ALSO fails the rejection is dropped and the + * returned promise never settles — the transfer hangs forever. This replaces + * the method with the same logic as upstream, plus: a second write failure + * rejects the pending operation. + * + * Call once per page load with the vendored `SecureDfu` constructor before + * creating instances. Safe to call repeatedly (idempotent). + */ +declare function patchSecureDfuSendOperation(SecureDfuCtor: { + prototype: SecureDfuSendOperationInternals & { + sendOperation: SecureDfuSendOperation; + }; +}): void; +/** How a DFU-flow error should be presented / handled. */ +type VerisenseDfuErrorCategory = 'device-disconnected' | 'stack-operation-failed'; +interface VerisenseDfuErrorInfo { + /** Known Bluetooth-stack failure signature, or null for anything else + * (including genuine DFU protocol errors, which pass through untouched). */ + category: VerisenseDfuErrorCategory | null; + /** Plain-language, platform-neutral description for the category, or null. + * Apps typically append their own platform-specific remediation hint (e.g. + * "remove the sensor in Windows Bluetooth settings, then retry"). */ + friendlyMessage: string | null; + /** True when the error matches {@link VERISENSE_DFU_TRANSIENT_ERROR_REGEX} + * and is worth retrying. */ + transient: boolean; + /** DOMException/Error name when available, else "GATT error". */ + name: string; + rawMessage: string; +} +/** + * Classify known Bluetooth-stack failures seen during Verisense DFU (DEV-845). + * Two signatures of the same Windows pairing/GATT-cache failure loop: + * "unknown reason" (NotSupportedError) is the stack failing an operation on a + * live link, and "GATT Server is disconnected" (NetworkError) is the sensor + * tearing the link down mid-operation — on units without the firmware fix, + * typically its ~400 ms security request colliding with a stale pairing key. + * Unrecognised errors return `category: null` so their raw text passes + * through unchanged. + */ +declare function classifyVerisenseDfuError(error: unknown): VerisenseDfuErrorInfo; +/** + * Reject a promise that hasn't settled within `ms`. Used to guard + * `SecureDfu.setDfuMode()`: the library builds its buttonless branch as + * `new Promise((resolve, reject) => { startNotifications().then( + * ...sendOperation...).then(resolve) })` with NO `.catch(reject)`, so if + * startNotifications() or the button-command write fails the promise never + * settles. (The {@link patchSecureDfuSendOperation} override makes that write + * reject rather than hang, which this same missing catch would swallow.) + * The timeout message deliberately includes "connection" so it matches + * {@link VERISENSE_DFU_TRANSIENT_ERROR_REGEX} and drives the retry helpers. + * Kept as a timeout rather than re-implementing setDfuMode so the buttonless + * reboot logic isn't duplicated, and so it defends against any stall cause. + */ +declare function promiseWithTimeout(promise: Promise, ms: number, label: string): Promise; +/** A bundled firmware name must be a plain `.zip` filename — no path + * separators or traversal — so a malformed/hostile manifest can't make an app + * fetch outside its firmware folder. */ +declare function isSafeFirmwareArchiveName(name: unknown): name is string; +/** + * `navigator.bluetooth.requestDevice()` options for picking a Verisense + * bootloader (replaces the DFU library's `acceptAllDevices`; see + * {@link VERISENSE_DFU_BOOTLOADER_NAME_PREFIX} for why name-prefix only). + * Pass the vendored library's `SecureDfu.SERVICE_UUID`. + */ +declare function buildVerisenseDfuRequestDeviceOptions(dfuServiceUuid: string | number): { + filters: { + namePrefix: string; + }[]; + optionalServices: (string | number)[]; +}; +interface VerisenseDfuRetryInfo { + stage: 'set-dfu-mode' | 'update'; + /** Attempts left including the retry about to run. */ + attemptsRemaining: number; + /** Ready-made "attempt N of M" wording for status lines. */ + attemptLabel: string; + error: unknown; +} +interface VerisenseDfuFlowOptions { + /** Total attempts for connection-level retries (default + * {@link VERISENSE_DFU_CONNECT_ATTEMPTS}). */ + attempts?: number; + /** Delay between retries (default {@link VERISENSE_DFU_RETRY_DELAY_MS}). */ + retryDelayMs?: number; + /** Bound on setDfuMode (default {@link VERISENSE_DFU_SET_MODE_TIMEOUT_MS}). */ + setDfuModeTimeoutMs?: number; + /** Wait after the base image installs, for the reboot back into the + * bootloader (default {@link VERISENSE_DFU_REBOOT_DELAY_MS}). */ + rebootDelayMs?: number; + /** User-facing progress text (the same strings the Verisense console shows). */ + onStatus?: (message: string) => void; + /** Called before each connection-level retry; protocol errors never retry. */ + onRetry?: (info: VerisenseDfuRetryInfo) => void; +} +/** + * `SecureDfu.update()` with retries on connection-level errors. Combined + * (SoftDevice+bootloader+application) packages transfer in two parts with a + * device reset in between; the reconnect for part 2 can fail while the device + * is still rebooting, so transient errors retry after a settle delay. DFU + * protocol errors are not retried. + */ +declare function updateVerisenseDfuImageWithRetry(dfu: SecureDfuLike, device: BluetoothDevice, image: VerisenseDfuImage, options?: VerisenseDfuFlowOptions): Promise; +/** + * `SecureDfu.setDfuMode()` bounded by a timeout and retried on transient + * errors (DEV-845). setDfuMode (connect + find the buttonless characteristic + * + startNotifications + write) is where Windows' BLE stack intermittently + * fails with "GATT operation failed for unknown reason", typically on the + * first GATT operation after a connect that follows a disconnect. Before each + * retry the GATT connection is fully torn down so the next attempt starts + * from a clean link. Protocol errors (e.g. "Unsupported device") are not + * retried. Resolves like setDfuMode: the device when it is already in + * bootloader mode, or null after the buttonless reboot command has been sent. + */ +declare function setVerisenseDfuModeWithRetry(dfu: SecureDfuLike, device: BluetoothDevice, options?: VerisenseDfuFlowOptions): Promise; +/** + * Run a full Verisense DFU transfer from a loaded Nordic DFU package: base + * image (SoftDevice/bootloader) first when present, then the application + * image. Resumes interrupted combined updates: a bootloader only installs + * once per version number, so if a previous (interrupted) attempt already + * installed this base image the target rejects it with a firmware-version + * error — that is swallowed and the flow continues to the application image. + * + * Progress text is reported via `options.onStatus`; transfer byte progress + * comes from the `SecureDfu` instance's own "progress" events, which the app + * subscribes to directly. Rejects with the raw library error on failure (run + * it through {@link classifyVerisenseDfuError} for display). + */ +declare function runVerisenseDfuUpdate(dfu: SecureDfuLike, device: BluetoothDevice, dfuPackage: VerisenseDfuPackage, options?: VerisenseDfuFlowOptions): Promise; + +/** + * Verisense calibration defaults, hardware/firmware gating, and timestamp helpers. + * + * The byte-level codec lives in `calibration.ts`; this module is the host-side + * single source of truth for the *default* calibration (the mirror of the + * firmware `AsmCalib_seedDefaults`) plus the small amount of domain logic the UI + * used to carry: which calibration blocks a board has, the minimum firmware that + * supports `CMD_AR_CFG_CALIB`, and the 8-byte timestamp encode/decode. + */ + +/** Minimum firmware that implements the `CMD_AR_CFG_CALIB` (0x0D) command. */ +declare const VERISENSE_CALIBRATION_MIN_FW: VerisenseFirmwareVersion; +/** Whether the given firmware version supports the calibration command. */ +declare function supportsVerisenseCalibration(fw: Partial | null | undefined): boolean; +/** Encode Unix-epoch seconds into the 8-byte little-endian calibration `ts`. */ +declare function unixSecondsToCalibTsBytes(unixSeconds: number): Uint8Array; +/** Decode the 8-byte little-endian calibration `ts` back to Unix-epoch seconds + * (0 = default/seeded). */ +declare function calibTsBytesToUnixSeconds(ts: ArrayLike | null | undefined): number; +interface VerisenseCalibrationRange { + /** Full-scale index as stored in the block `range` byte (low 6 bits). */ + code: number; + /** Display label, e.g. "±2g" / "±250dps". */ + label: string; + /** Default sensitivity `K` (LSB per physical unit) for this range. */ + sens: number; +} +interface VerisenseCalibrationSensor { + /** Calibration-domain sensor id (see {@link CalibSensorId}). */ + id: number; + /** Display label, e.g. "Accelerometer (LSM6DSV)". */ + label: string; + /** Physical unit of the calibrated output. */ + unit: string; + /** Default sensor->ASM alignment `R` (row-major 3x3, applied as + * physical = align · sensor). See VERISENSE_CALIBRATION.md §4. */ + align: number[]; + ranges: VerisenseCalibrationRange[]; +} +/** + * The calibration sensor catalog for a board: the 1st-generation set + * (LIS2DW12 + LSM6DS3) for 1st-gen hardware, otherwise the 2nd-generation set + * (LSM6DSV + LIS2DW12 + LIS2MDL). Unknown/offline (no revision) defaults to + * 2nd-gen. Note id 39 (LIS2DW12) appears in both with a generation-specific + * alignment, so the catalog must be resolved per hardware revision. + */ +declare function getVerisenseCalibrationSensors(revHwMajor?: number, revHwMinor?: number): VerisenseCalibrationSensor[]; +/** + * Build the default calibration set for a board (bias=0, default sensitivity, + * default alignment, ts=0). Host-side mirror of `AsmCalib_seedDefaults`; useful + * for "reset to defaults" and round-trip tests. + */ +declare function buildDefaultVerisenseCalibrationSet(opts: { + hwVerMajor: number; + hwVerMinor: number; + fwVerMajor: number; + fwVerMinor: number; + fwVerPatch: number; +}): CalibrationSetInput; +type VerisenseCalibrationAvailability = 'enabled' | 'disabled' | 'hidden'; +/** + * Map each calibration-domain sensor id to whether it is present and usable on + * the connected hardware: + * - `enabled` — present and recorded from; show + allow edit. + * - `disabled` — physically present but not recorded from (LIS2DW12 routed to + * the algorithm hub on 2nd-gen SR68); show greyed. + * - `hidden` — not fitted on this hardware. + * + * `support` is the result of `getVerisenseHardwareSensorSupport`. A null/absent + * support object (offline / unknown hardware) reports every sensor `enabled`. + */ +declare function getVerisenseCalibrationSensorAvailability(support: VerisenseHardwareSensorSupport | null | undefined): Record; + +export { ASM_COMMAND, ASM_PROPERTY, BLE_LINK_MIN_FW, BaseShimmerClient, CHANNEL_FORMATS, CalibQuality, CalibSensorId, DEBUG_COMMAND_ID, GSR_NAME, NORDIC_DFU_BUTTONLESS_WITHOUT_BONDS, NORDIC_DFU_BUTTONLESS_WITH_BONDS, NORDIC_DFU_OP_ENTER_BOOTLOADER, NORDIC_DFU_SERVICE, NUS_RX, NUS_SERVICE, NUS_TX, OPCODES, OP_IDX, ObjectCluster, RtcDriftMonitor, SC_CALIB_FORMAT_VERSION, SC_CAL_QUALITY_MASK, SC_CAL_QUALITY_SHIFT, SC_CAL_RANGE_MASK, SC_DATA_LEN_IMU, SC_GLOBAL_HEADER_BYTES, SHIMMER3R_DEFAULTS, STREAM_MODE, SensorADC, SensorBase, SensorBitmapShimmer3, SensorLIS2DW12, SensorLSM6DS3, SensorLSM6DSV, SensorMAX32674, SensorMLX90632, SensorPPG, SensorVD6283, Shimmer3RClient, StreamStatsTracker, TEST_MODE_ID, TIMESTAMP_FIELD, VERISENSE_BLE_SCHEDULE_DEFAULTS, VERISENSE_BLE_SCHEDULE_RANGES, VERISENSE_BLE_SYNC_SCHEDULES, VERISENSE_CALIBRATION_MIN_FW, VERISENSE_DEFAULT_PASSKEY_BY_ID, VERISENSE_DFU_BOOTLOADER_NAME_PREFIX, VERISENSE_DFU_CONNECT_ATTEMPTS, VERISENSE_DFU_FAST_PACKET_DELAY_MS, VERISENSE_DFU_REBOOT_DELAY_MS, VERISENSE_DFU_RELIABLE_PACKET_DELAY_MS, VERISENSE_DFU_RETRY_DELAY_MS, VERISENSE_DFU_ROUTINE_LOG_REGEX, VERISENSE_DFU_SET_MODE_TIMEOUT_MS, VERISENSE_DFU_TRANSIENT_ERROR_REGEX, VERISENSE_HW_MAJOR_FRIENDLY_NAMES, VERISENSE_MAX_PLAUSIBLE_UNIX_SECONDS, VERISENSE_OPERATIONAL_FIELD_FALLBACK_GROUP_ID, VERISENSE_OPERATIONAL_FIELD_GROUPS, VERISENSE_OPERATIONAL_FIELD_GROUP_SENSOR, VERISENSE_OPERATIONAL_FIELD_SCHEMA, VERISENSE_OP_CONFIG_BYTE_SIZE, VERISENSE_SENSOR_ENABLE_FIELDS, VERISENSE_SENSOR_RATE_DEFAULT_GROUPS, VERISENSE_STREAM_SENSOR_LABELS, VerisenseBleDevice, applyDuplicateSuffix, applyImuCalibration, asmRtcBytesToUnixSeconds, asmRtcMinutesBytesToUnixSeconds, buildDefaultVerisenseCalibrationSet, buildHeader, buildMessage, buildParsedCsvFileName, buildProductionConfigPayload, buildUploadBinaryFileName, buildVerisenseAdvertisedName, buildVerisenseDfuRequestDeviceOptions, calibTsBytesToUnixSeconds, calibrateGsrDataToResistanceFromAmplifierEq, calibrateShimmer3RAdcChannel, calibrateU12AdcValue, calibrationBlobCrc, classifyVerisenseDfuError, compareVerisenseFirmwareVersion, computeVerisensePairingPin, crc16_ccitt_false, createBlankVerisenseOperationalConfig, csvCell, decodeVerisenseBleOptimizationResult, defaultVerisensePasskeyForId, deriveVerisenseMacIdFromName, describeVerisenseChargerStatus, enforceVerisenseCommsChannelInterlock, evaluateParsedFileSplit, expectedVerisenseStreamSensorIds, expectedVerisenseStreamSensorIdsFromConfig, formatByteArrayAsHex, formatByteAsHex, formatPendingEventProperties, formatSchedulerPayloadForLog, formatStatusPayloadForLog, formatVerisenseChargerStatus, formatVerisenseFirmwareVersion, formatVerisenseHardwareRevision, formatVerisenseUnixAndHuman, getFirstPayloadIndex, getOversamplingRatioADS1292R, getVerisenseCalibrationSensorAvailability, getVerisenseCalibrationSensors, getVerisenseHardwareCapabilities, getVerisenseHardwareFriendlyName, getVerisenseHardwareRevision, getVerisenseHardwareSensorSupport, getVerisenseStreamSensorLabel, getVerisenseStreamingBatteryVoltageMultiplier, getVerisenseSupportedOperationalFieldGroupIds, hhmmToMinutesSinceMidnight, inferVerisenseChargerChipFamily, inferVerisenseLookupBankCount, isAckCommand, isNackCommand, isRoutineVerisenseDfuLogMessage, isSafeFirmwareArchiveName, isUniformByteArray, isVerisenseGsrSupportedHardware, isVerisenseLightDarkChannelEnabled, isVerisenseSecondGenerationHardware, minutesSinceMidnightToHHMM, nextAvailableDuplicateFileName, normalizeBytePayload, normalizeOperationalConfig, nudgeGsrResistance, padVerisenseOperationalConfig, parseBleLinkDebugPayload, parseCalibrationBlob, parseEventLogPayload, parseHeader, parseHexByteString, parseLookupTablePayload, parseMessage, parsePayloadCrcErrorBankIndexes, parsePendingEvents, parseProductionConfigPayload, parseProductionConfigPayloadFull, parseRecordBufferDetailsPayload, parseSchedulerDebugPayload, parseStatusPayload, parseVerisenseAdvertisedName, patchSecureDfuSendOperation, promiseWithTimeout, readVerisenseOperationalFieldValue, resolveVerisenseSensorRateFieldKey, runVerisenseDfuUpdate, serializeCalibrationBlob, setVerisenseDfuModeWithRetry, setVerisenseOperationalBitRange, supportsVerisenseCalibration, supportsVerisenseMagnetometer, unixSecondsToAsmRtcBytes, unixSecondsToCalibTsBytes, updateVerisenseDfuImageWithRetry, verisenseDeviceFileTag, verisenseDfuAttemptLabel, writeVerisenseOperationalFieldValue }; +export type { ADCBatterySample, ADCGSRSample, ADCPayloadSample, AsmCommand, AsmProperty, BleLinkAutoOptimizeOptions, BleLinkAutoOptimizeResult, BleLinkAutoOptimizeSample, BleLinkAutoOptimizeStopReason, BleThroughputTestOptions, BleThroughputTestResult, CalibrationBlock, CalibrationBlockInput, CalibrationSet, CalibrationSetInput, ChannelFormat, DebugCommandId, DeviceMode, EvaluateParsedSplitInput, FieldKind, IShimmerClient, ImuCalibration, InertialCalibration, LIS2DW12Sample, LSM6DS3Sample, LSM6DSVSample, MAX32674Sample, MLX90632Sample, OpIdx, Opcode, PPGChannelSample, PPGSample, ParsedSplitReason, PendingEventPropertyLabel, ProductionConfig, ProductionConfigBuildOptions, ProductionConfigFull, RtcDriftMonitorOptions, RtcDriftSample, RtcDriftSampleEvent, RtcDriftSampleInput, RunHardwareTestReportOptions, SecureDfuLike, SensorBitmapShimmer3Key, SensorField, SensorMap, SensorStreamStats, Shimmer3RClientOptions, ShimmerClientOptions, StreamContribution, StreamLossStats, StreamPacket, StreamStatsSnapshot, TestModeId, TimestampFmt, TransferLoggedDataOptions, TransferLoggedDataResult, TransportKind, VD6283Sample, VerisenseAdvertisedNameParts, VerisenseBleLinkDebugPayload, VerisenseBleOptimizationResult, VerisenseBleSyncSchedule, VerisenseCalibrationAvailability, VerisenseCalibrationRange, VerisenseCalibrationSensor, VerisenseChargerChipFamily, VerisenseClientOptions, VerisenseCommandResponse, VerisenseConnectRetryInfo, VerisenseConnectWithRetryOptions, VerisenseDfuErrorCategory, VerisenseDfuErrorInfo, VerisenseDfuFlowOptions, VerisenseDfuImage, VerisenseDfuPackage, VerisenseDfuRetryInfo, VerisenseEventLogEntry, VerisenseFirmwareVersion, VerisenseHardwareCapabilities, VerisenseHardwareRevision, VerisenseHardwareRevisionSource, VerisenseHardwareSensorSupport, VerisenseImuGeneration, VerisenseLookupTableEntry, VerisenseLookupTablePayload, VerisenseMessage, VerisenseOperationalField, VerisenseOperationalFieldDefinition, VerisenseOperationalFieldGroupDefinition, VerisenseOperationalFieldKind, VerisenseOperationalFieldOption, VerisenseOperationalSensorEnableField, VerisenseRecordBufferDetails, VerisenseSchedulerDebugPayload, VerisenseSchedulerDebugPayloadForLog, VerisenseSensorRateDefaultField, VerisenseSensorRateDefaultGroup, VerisenseStatusPayload, VerisenseStatusPayloadForLog, VerisenseStreamSensorEnables, VerisenseUnixAndHumanTimestamp }; diff --git a/Verisense/vendor/shimmer-web-sdk.esm.js b/Verisense/vendor/shimmer-web-sdk.esm.js new file mode 100644 index 0000000..9c7fa70 --- /dev/null +++ b/Verisense/vendor/shimmer-web-sdk.esm.js @@ -0,0 +1,9863 @@ +/** + * Container for a single decoded sensor frame. + * + * Mirrors the ObjectCluster concept from the Shimmer C# SDK: + * a named, typed bag of raw and calibrated signal values produced + * by parsing one data packet from a device. + * + * @example + * ```ts + * const oc = new ObjectCluster('MyShimmer3R'); + * oc.add('GYRO_X', rawVal, null, 'raw'); + * oc.add('GYRO_X', degPerSec, 'deg/s', 'cal'); + * + * const cal = oc.get('GYRO_X', 'cal'); + * console.log(cal?.value, cal?.unit); // e.g. 12.5 "deg/s" + * ``` + */ +class ObjectCluster { + constructor(deviceId) { + this.deviceId = deviceId; + this.fields = []; + this.raw = null; + } + /** + * Append a named field to this cluster. + * + * @param name Signal name, e.g. `'GYRO_X'`. + * @param value Numeric value. + * @param unit Optional unit string, e.g. `'deg/s'`, `'µS'`, `'ticks'`. + * @param kind `'raw'` for ADC counts, `'cal'` for calibrated units, or `null`. + */ + add(name, value, unit = null, kind = null) { + this.fields.push({ name, value, unit, kind }); + } + /** + * Look up a field by name and optional kind. + * + * When both a raw and a calibrated version exist for the same signal name, + * pass `kind` to disambiguate. + * + * @returns The matching field, or `null` if not found. + */ + get(name, kind = null) { + return this.fields.find((f) => f.name === name && (kind === null || f.kind === kind)) ?? null; + } + /** + * Return all fields that match the given name (regardless of kind). + */ + getAll(name) { + return this.fields.filter((f) => f.name === name); + } +} + +/** + * Abstract base class shared by all Shimmer device clients. + * + * Provides: + * - A `debug` flag and `_log` helper. + * - Stub implementations of `onStatus` and `onStreamFrame` callback properties. + * - Abstract stubs for `connect`, `disconnect`, `startStreaming`, and `stopStreaming` + * that concrete sub-classes must override. + * + * Sub-classes should call `this._emitStatus(msg)` to surface status strings to + * the application layer without depending on a particular event-emitter library. + */ +class BaseShimmerClient { + constructor(opts = {}) { + /** + * Invoked whenever the client emits a human-readable status message + * (e.g. "GATT connected", "Sampling rate ACKed. Applied ≈ 51.200 Hz"). + */ + this.onStatus = null; + /** + * Invoked for every fully-decoded sensor frame while streaming. + * The exact shape depends on the concrete sub-class: + * - `Shimmer3RClient` passes an {@link ObjectCluster}. + * - `VerisenseBleDevice` passes a streaming packet object (see that class). + */ + this.onStreamFrame = null; + this.debug = opts.debug ?? true; + } + /** Log to console when debug is enabled. */ + _log(...args) { + if (this.debug) + console.log('[Shimmer]', ...args); + } + /** Emit a status message to `onStatus` and to the debug log. */ + _emitStatus(msg) { + this._log(msg); + this.onStatus?.(msg); + } +} + +function toArrayBuffer(u8) { + if (u8.buffer instanceof ArrayBuffer) { + if (u8.byteOffset === 0 && u8.byteLength === u8.buffer.byteLength) + return u8.buffer; + return u8.buffer.slice(u8.byteOffset, u8.byteOffset + u8.byteLength); + } + const out = new Uint8Array(u8.byteLength); + out.set(u8); + return out.buffer; +} +/** + * True if `bytes` is non-empty and every byte equals `value` (0–255). Useful for + * detecting uniform blobs such as erased flash (all `0xFF`) or zeroed regions. + * Returns false for empty or nullish input. + */ +function isUniformByteArray(bytes, value) { + const u8 = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes ?? []); + if (!u8.length) + return false; + const expected = value & 0xff; + for (let i = 0; i < u8.length; i++) { + if (u8[i] !== expected) + return false; + } + return true; +} + +/** + * Escape a value for a CSV cell (RFC 4180 style): whitespace runs — including + * newlines — collapse to a single space, then cells containing a quote or + * comma are quoted with internal quotes doubled. Null/undefined become the + * empty cell. + */ +function csvCell(text) { + const s = String(text ?? '') + .replace(/\s+/g, ' ') + .trim(); + return /[",]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s; +} + +/** + * Device RTC drift estimation over a live connection (DEV-844). + * + * Sample the device clock periodically against the host clock and fit a + * least-squares slope of (device − host) offset vs host time: the + * dimensionless slope × 1e6 is directly the crystal error in ppm, giving a + * usable estimate in hours instead of waiting days between connections. + * Device time resolves to 1/32768 s, so per-sample noise is just transport + * round-trip jitter (~tens of ms); the fit averages it out. Host timestamps + * should be taken at the midpoint of the read round-trip, bounding transport + * latency to ±rtt/2. + * + * Host clock steps (NTP corrections) are a measurement hazard: the wall + * clock jumping mid-series pollutes the least-squares slope while looking + * like device drift (seen live on DEV-844: a −1.4 s Windows NTP step bent + * the fit from 1020 to 1077 ppm). Each sample therefore also records a + * monotonic timestamp (`performance.now()`): wall-vs-monotonic divergence + * between samples attributes a jump to the HOST, which resets the fit + * baseline instead of counting as a device step. + * + * This class is pure bookkeeping — the caller owns the sampling timer, the + * device read, and any UI. Feed it one {@link RtcDriftSampleInput} per read. + */ +class RtcDriftMonitor { + constructor(options = {}) { + this.samples = []; + /** Device clock steps detected across the whole run (survives rebaselines). */ + this.deviceSteps = 0; + /** Host (NTP) clock steps detected; each one rebaselines the fit. */ + this.hostSteps = 0; + this.deviceStepThresholdSeconds = options.deviceStepThresholdSeconds ?? 1; + this.hostStepThresholdSeconds = options.hostStepThresholdSeconds ?? 0.5; + } + /** Drop all samples and step counts (e.g. when starting a new run). */ + reset() { + this.samples.length = 0; + this.deviceSteps = 0; + this.hostSteps = 0; + } + /** + * Drop the samples but keep the step counters. Call when the device time is + * written: a time write moves the offset baseline, so every prior sample is + * invalid and the fit must not straddle the discontinuity. + */ + rebaseline() { + this.samples.length = 0; + } + /** + * Record one device-time reading. Attributes any offset jump before + * recording it: wall-clock elapsed minus monotonic elapsed isolates host + * clock steps (NTP) from device steps. A host step resets the fit baseline + * (the fit must not straddle the discontinuity); a device step is counted + * and kept in-series. + */ + addSample(input) { + const sample = { ...input, offsetSec: input.devSec - input.hostSec }; + const prev = this.samples[this.samples.length - 1]; + const hostStepSec = prev + ? sample.hostSec - prev.hostSec - (sample.perfMs - prev.perfMs) / 1000 + : 0; + if (Math.abs(hostStepSec) > this.hostStepThresholdSeconds) { + this.hostSteps++; + this.samples.length = 0; + this.samples.push(sample); + return { kind: 'host-step', sample, hostStepSec }; + } + if (prev && Math.abs(sample.offsetSec - prev.offsetSec) > this.deviceStepThresholdSeconds) { + this.deviceSteps++; + this.samples.push(sample); + return { kind: 'device-step', sample, deltaSec: sample.offsetSec - prev.offsetSec }; + } + this.samples.push(sample); + return { kind: 'sample', sample }; + } + /** + * Least-squares slope of offset vs host time, in ppm (offset and time are + * both in seconds, so the dimensionless slope × 1e6 is directly ppm). + * Null until two samples spanning a non-zero interval exist. + */ + ppmFit() { + const s = this.samples; + if (s.length < 2) + return null; + const t0 = s[0].hostSec; + const y0 = s[0].offsetSec; + let sx = 0; + let sy = 0; + let sxx = 0; + let sxy = 0; + for (const p of s) { + const x = p.hostSec - t0; + const y = p.offsetSec - y0; + sx += x; + sy += y; + sxx += x * x; + sxy += x * y; + } + const n = s.length; + const denom = n * sxx - sx * sx; + if (denom === 0) + return null; + return ((n * sxy - sx * sy) / denom) * 1e6; + } + /** Elapsed span of the current sample series in minutes (0 when empty). */ + elapsedMinutes() { + const s = this.samples; + if (s.length < 2) + return 0; + return (s[s.length - 1].hostSec - s[0].hostSec) / 60; + } + /** + * CSV rows (header first) of the current series, matching the DEV-844 + * export format: host ISO time, host/device unix seconds, offset, rtt, + * monotonic seconds. + */ + toCsvRows() { + const rows = ['host_iso,host_unix_s,device_unix_s,offset_s,rtt_ms,perf_monotonic_s']; + for (const p of this.samples) { + rows.push(`${new Date(p.hostSec * 1000).toISOString()},${p.hostSec.toFixed(3)},${p.devSec.toFixed(5)},${p.offsetSec.toFixed(3)},${p.rttMs},${(p.perfMs / 1000).toFixed(3)}`); + } + return rows; + } +} + +/** + * Device-agnostic live stream statistics: throughput, packet rate and + * sample-gap-derived packet loss for a real-time sensor stream. + * + * The tracker is fed one call per received packet ({@link StreamStatsTracker.recordPacket}) + * and produces a {@link StreamStatsSnapshot} on demand ({@link StreamStatsTracker.snapshot}). + * + * Loss is derived from gaps in each sub-stream's *monotonic device clock* + * (`lastSampleMillis`), NOT host receive time — host BLE buffering bunches + * packets together and would otherwise create false gaps. Throughput and packet + * rate, by contrast, are measured over a sliding window of host receive time + * (`recvMillis`), which is what "bytes per wall-clock second" means. + */ +/** + * Drop ring events older than `cutoff` (by receive time), but always keep the + * last 2 so the rate/throughput still reflect the most recent delivery even when + * packets arrive less often than the window (big FIFO reads, slow sensors). + */ +function pruneRing(ring, cutoff) { + if (ring.length <= 2) + return ring; + let i = 0; + while (i < ring.length - 2 && ring[i].t < cutoff) + i++; + return i > 0 ? ring.slice(i) : ring; +} +/** + * Accumulates live statistics for one streaming session. Call {@link reset} on + * (re)start, {@link recordPacket} for every decoded packet, {@link recordCrcFail} + * for CRC failures, and {@link snapshot} to read the current numbers. + */ +class StreamStatsTracker { + constructor(opts) { + this.sessionStartMillis = null; + this.resyncDroppedBytes = 0; + this.sensors = new Map(); + this.streams = new Map(); + this.windowMillis = opts?.windowMillis ?? 2000; + } + /** Clear all state. Call when streaming (re)starts. */ + reset() { + this.sessionStartMillis = null; + this.resyncDroppedBytes = 0; + this.sensors.clear(); + this.streams.clear(); + } + getSensor(sensorId) { + let s = this.sensors.get(sensorId); + if (!s) { + s = { sensorId, packets: 0, bytes: 0, crcFails: 0, throughputRing: [] }; + this.sensors.set(sensorId, s); + } + return s; + } + getStream(key, sensorId, label) { + let st = this.streams.get(key); + if (!st) { + st = { + key, + sensorId, + label, + samplingRateHz: null, + samples: 0, + expectedSamples: 0, + lostSamples: 0, + lastSampleMillis: null, + started: false, + rateRing: [], + }; + this.streams.set(key, st); + } + return st; + } + /** Record one received (and decoded) streaming packet. */ + recordPacket(p) { + if (this.sessionStartMillis == null) + this.sessionStartMillis = p.recvMillis; + const sensor = this.getSensor(p.sensorId); + sensor.packets += 1; + sensor.bytes += p.byteLength; + sensor.throughputRing.push({ t: p.recvMillis, bytes: p.byteLength }); + // CRC failures, when a device reports them, are counted via recordCrcFail() + // rather than here, to avoid double-counting a packet also passed in here. + for (const c of p.contributions) { + const st = this.getStream(c.key, p.sensorId, c.label); + st.label = c.label; + st.samplingRateHz = c.samplingRateHz; + st.samples += c.sampleCount; + st.rateRing.push({ + t: p.recvMillis, + n: c.sampleCount, + devFirst: c.firstSampleMillis, + dev: c.lastSampleMillis, + }); + const prev = st.lastSampleMillis; + if (!st.started || + !c.samplingRateHz || + c.samplingRateHz <= 0 || + prev == null || + c.lastSampleMillis == null) { + // No measurable gap yet -> assume every sample we got was expected. + st.expectedSamples += c.sampleCount; + } + else { + const interval = 1000 / c.samplingRateHz; + const delta = c.lastSampleMillis - prev; + if (delta > 0) { + const expected = Math.round(delta / interval); + st.expectedSamples += expected; + st.lostSamples += Math.max(0, expected - c.sampleCount); + } + // delta <= 0 (reorder / duplicate): ignore for loss; still counted in samples. + } + st.started = true; + if (c.lastSampleMillis != null) + st.lastSampleMillis = c.lastSampleMillis; + } + } + /** Record a CRC failure for a (possibly unknown) sensor. */ + recordCrcFail(sensorId) { + const id = sensorId ?? -1; + this.getSensor(id).crcFails += 1; + } + /** + * Record bytes discarded while re-synchronising the frame parser after the + * stream lost alignment (typically a flaky link dropping bytes mid-stream). + */ + recordResyncDrop(byteCount = 1) { + if (byteCount > 0) + this.resyncDroppedBytes += byteCount; + } + prune(nowMillis) { + const cutoff = nowMillis - this.windowMillis; + for (const s of this.sensors.values()) { + s.throughputRing = pruneRing(s.throughputRing, cutoff); + } + for (const st of this.streams.values()) { + st.rateRing = pruneRing(st.rateRing, cutoff); + } + } + /** + * Cadence-relative stall test: a stream is "stalled" only if its newest packet + * is older than a multiple of its own observed packet interval (floored at the + * window). This keeps a stalled stream reading 0 while NOT zeroing a healthy + * stream that simply delivers less often than the window (big FIFO reads, slow + * sensors). Events carry a receive time `t`. + */ + isStalled(ring, nowMillis) { + if (ring.length === 0) + return true; + const newest = ring[ring.length - 1].t; + const avgIntervalMillis = ring.length >= 2 ? (newest - ring[0].t) / (ring.length - 1) : this.windowMillis; + const stallMillis = Math.max(this.windowMillis, 3 * avgIntervalMillis); + return nowMillis - newest > stallMillis; + } + /** + * Achieved sample rate for a sub-stream's windowed events. + * + * Measured over the *device-clock* span of the samples — from the first + * sample of the oldest packet to the last sample of the newest packet (their + * tsMillis), not the host receive-time window. This is robust to bursty BLE + * delivery AND to large packets: one packet can carry hundreds of samples + * spanning several seconds (e.g. a high FIFO watermark), so dividing its count + * by the fixed receive window would over-report. Using the samples' own + * device-time span gives the true rate even from a single packet. A stream + * whose newest packet is older than a cadence-relative threshold reads 0 (see + * {@link isStalled}). + */ + windowRateHz(ring, nowMillis) { + if (this.isStalled(ring, nowMillis)) + return 0; + let totalN = 0; + let oldestFirst = Infinity; + let newestLast = -Infinity; + for (const e of ring) { + totalN += e.n; + if (e.devFirst != null && e.devFirst < oldestFirst) + oldestFirst = e.devFirst; + if (e.dev != null && e.dev > newestLast) + newestLast = e.dev; + } + if (totalN <= 0) + return 0; + // N samples span N-1 intervals over the device-time window, so the rate is + // (N-1) / span. A single packet uses its own first->last sample span; a + // stream with no usable device span (1 sample / no timestamps) reads 0. + const spanMillis = newestLast - oldestFirst; + if (spanMillis > 0 && totalN > 1) + return ((totalN - 1) / spanMillis) * 1000; + return 0; + } + /** + * Windowed throughput (bytes/sec) and packet rate over the *actual* receive + * span of the retained events, robust to packets that arrive less often than + * the window. Bytes/packets are counted after the oldest event (the span's + * start point). Returns 0 if the stream is stalled (see {@link isStalled}). + */ + windowThroughput(ring, nowMillis) { + if (ring.length < 2 || this.isStalled(ring, nowMillis)) + return { bps: 0, packetRateHz: 0 }; + const spanMillis = ring[ring.length - 1].t - ring[0].t; + if (spanMillis <= 0) + return { bps: 0, packetRateHz: 0 }; + let bytesAfterOldest = 0; + for (let i = 1; i < ring.length; i++) + bytesAfterOldest += ring[i].bytes; + const spanSec = spanMillis / 1000; + return { bps: bytesAfterOldest / spanSec, packetRateHz: (ring.length - 1) / spanSec }; + } + /** Produce a snapshot of all statistics as of `nowMillis`. */ + snapshot(nowMillis) { + this.prune(nowMillis); + const perSensor = {}; + for (const s of this.sensors.values()) { + const tp = this.windowThroughput(s.throughputRing, nowMillis); + perSensor[s.sensorId] = { + sensorId: s.sensorId, + packets: s.packets, + bytes: s.bytes, + crcFails: s.crcFails, + windowThroughputBps: tp.bps, + windowPacketRateHz: tp.packetRateHz, + streams: [], + }; + } + let totalPackets = 0; + let totalBytes = 0; + let totalCrcFails = 0; + let totalSamples = 0; + let totalExpected = 0; + let totalLost = 0; + let throughputBps = 0; + for (const sid of Object.keys(perSensor)) { + const s = perSensor[Number(sid)]; + totalPackets += s.packets; + totalBytes += s.bytes; + totalCrcFails += s.crcFails; + throughputBps += s.windowThroughputBps; + } + const streamList = [...this.streams.values()].sort((a, b) => a.key.localeCompare(b.key)); + for (const st of streamList) { + const lossPct = st.expectedSamples > 0 ? (st.lostSamples / st.expectedSamples) * 100 : 0; + const row = { + key: st.key, + sensorId: st.sensorId, + label: st.label, + samplingRateHz: st.samplingRateHz, + samples: st.samples, + expectedSamples: st.expectedSamples, + lostSamples: st.lostSamples, + lossPct, + windowSampleRateHz: this.windowRateHz(st.rateRing, nowMillis), + lastSampleMillis: st.lastSampleMillis, + }; + totalSamples += st.samples; + totalExpected += st.expectedSamples; + totalLost += st.lostSamples; + // A stream's sensor row may not exist if recordPacket was never called for + // it (only possible via a stray CRC-fail id); guard defensively. + const sensorRow = perSensor[st.sensorId]; + if (sensorRow) + sensorRow.streams.push(row); + } + return { + durationMillis: this.sessionStartMillis != null ? Math.max(0, nowMillis - this.sessionStartMillis) : 0, + totalPackets, + totalSamples, + totalBytes, + totalCrcFails, + resyncDroppedBytes: this.resyncDroppedBytes, + throughputBps, + lossPct: totalExpected > 0 ? (totalLost / totalExpected) * 100 : 0, + perSensor, + }; + } +} + +/** + * Shimmer3R BLE protocol opcodes. + * Values taken directly from the Shimmer3 firmware header. + */ +const OPCODES = Object.freeze({ + DATA_PACKET: 0x00, + INQUIRY_COMMAND: 0x01, + INQUIRY_RESPONSE: 0x02, + GET_SAMPLING_RATE_COMMAND: 0x03, + SAMPLING_RATE_RESPONSE: 0x04, + SET_SAMPLING_RATE_COMMAND: 0x05, + TOGGLE_LED_COMMAND: 0x06, + START_STREAMING_COMMAND: 0x07, + SET_SENSORS_COMMAND: 0x08, + SET_WR_ACCEL_RANGE_COMMAND: 0x09, + WR_ACCEL_RANGE_RESPONSE: 0x0a, + GET_WR_ACCEL_RANGE_COMMAND: 0x0b, + SET_CONFIG_SETUP_BYTES_COMMAND: 0x0e, + CONFIG_SETUP_BYTES_RESPONSE: 0x0f, + GET_CONFIG_SETUP_BYTES_COMMAND: 0x10, + SET_LN_ACCEL_CALIBRATION_COMMAND: 0x11, + LN_ACCEL_CALIBRATION_RESPONSE: 0x12, + GET_LN_ACCEL_CALIBRATION_COMMAND: 0x13, + SET_GYRO_CALIBRATION_COMMAND: 0x14, + GYRO_CALIBRATION_RESPONSE: 0x15, + GET_GYRO_CALIBRATION_COMMAND: 0x16, + SET_MAG_CALIBRATION_COMMAND: 0x17, + MAG_CALIBRATION_RESPONSE: 0x18, + GET_MAG_CALIBRATION_COMMAND: 0x19, + SET_WR_ACCEL_CALIBRATION_COMMAND: 0x1a, + WR_ACCEL_CALIBRATION_RESPONSE: 0x1b, + GET_WR_ACCEL_CALIBRATION_COMMAND: 0x1c, + STOP_STREAMING_COMMAND: 0x20, + SET_GSR_RANGE_COMMAND: 0x21, + GSR_RANGE_RESPONSE: 0x22, + GET_GSR_RANGE_COMMAND: 0x23, + DEVICE_VERSION_RESPONSE: 0x25, + GET_ALL_CALIBRATION_COMMAND: 0x2c, + ALL_CALIBRATION_RESPONSE: 0x2d, + GET_FW_VERSION_COMMAND: 0x2e, + FW_VERSION_RESPONSE: 0x2f, + SET_CHARGE_STATUS_LED_COMMAND: 0x30, + CHARGE_STATUS_LED_RESPONSE: 0x31, + GET_CHARGE_STATUS_LED_COMMAND: 0x32, + BUFFER_SIZE_RESPONSE: 0x35, + GET_BUFFER_SIZE_COMMAND: 0x36, + SET_MAG_GAIN_COMMAND: 0x37, + MAG_GAIN_RESPONSE: 0x38, + GET_MAG_GAIN_COMMAND: 0x39, + SET_MAG_SAMPLING_RATE_COMMAND: 0x3a, + MAG_SAMPLING_RATE_RESPONSE: 0x3b, + GET_MAG_SAMPLING_RATE_COMMAND: 0x3c, + UNIQUE_SERIAL_RESPONSE: 0x3d, + GET_UNIQUE_SERIAL_COMMAND: 0x3e, + GET_DEVICE_VERSION_COMMAND: 0x3f, + SET_WR_ACCEL_SAMPLING_RATE_COMMAND: 0x40, + WR_ACCEL_SAMPLING_RATE_RESPONSE: 0x41, + GET_WR_ACCEL_SAMPLING_RATE_COMMAND: 0x42, + SET_WR_ACCEL_LPMODE_COMMAND: 0x43, + WR_ACCEL_LPMODE_RESPONSE: 0x44, + GET_WR_ACCEL_LPMODE_COMMAND: 0x45, + SET_WR_ACCEL_HRMODE_COMMAND: 0x46, + WR_ACCEL_HRMODE_RESPONSE: 0x47, + GET_WR_ACCEL_HRMODE_COMMAND: 0x48, + SET_GYRO_RANGE_COMMAND: 0x49, + GYRO_RANGE_RESPONSE: 0x4a, + GET_GYRO_RANGE_COMMAND: 0x4b, + SET_GYRO_SAMPLING_RATE_COMMAND: 0x4c, + GYRO_SAMPLING_RATE_RESPONSE: 0x4d, + GET_GYRO_SAMPLING_RATE_COMMAND: 0x4e, + SET_ALT_ACCEL_RANGE_COMMAND: 0x4f, + ALT_ACCEL_RANGE_RESPONSE: 0x50, + GET_ALT_ACCEL_RANGE_COMMAND: 0x51, + SET_PRESSURE_OVERSAMPLING_RATIO_COMMAND: 0x52, + PRESSURE_OVERSAMPLING_RATIO_RESPONSE: 0x53, + GET_PRESSURE_OVERSAMPLING_RATIO_COMMAND: 0x54, + BMP180_CALIBRATION_COEFFICIENTS_RESPONSE: 0x58, + GET_BMP180_CALIBRATION_COEFFICIENTS_COMMAND: 0x59, + RESET_TO_DEFAULT_CONFIGURATION_COMMAND: 0x5a, + RESET_CALIBRATION_VALUE_COMMAND: 0x5b, + MPU9150_MAG_SENS_ADJ_VALS_RESPONSE: 0x5c, + GET_MPU9150_MAG_SENS_ADJ_VALS_COMMAND: 0x5d, + SET_INTERNAL_EXP_POWER_ENABLE_COMMAND: 0x5e, + INTERNAL_EXP_POWER_ENABLE_RESPONSE: 0x5f, + GET_INTERNAL_EXP_POWER_ENABLE_COMMAND: 0x60, + SET_EXG_REGS_COMMAND: 0x61, + EXG_REGS_RESPONSE: 0x62, + GET_EXG_REGS_COMMAND: 0x63, + SET_DAUGHTER_CARD_ID_COMMAND: 0x64, + DAUGHTER_CARD_ID_RESPONSE: 0x65, + GET_DAUGHTER_CARD_ID_COMMAND: 0x66, + SET_DAUGHTER_CARD_MEM_COMMAND: 0x67, + DAUGHTER_CARD_MEM_RESPONSE: 0x68, + GET_DAUGHTER_CARD_MEM_COMMAND: 0x69, + SET_DERIVED_CHANNEL_BYTES: 0x6d, + DERIVED_CHANNEL_BYTES_RESPONSE: 0x6e, + GET_DERIVED_CHANNEL_BYTES: 0x6f, + START_SDBT_COMMAND: 0x70, + STATUS_RESPONSE: 0x71, + GET_STATUS_COMMAND: 0x72, + SET_TRIAL_CONFIG_COMMAND: 0x73, + TRIAL_CONFIG_RESPONSE: 0x74, + GET_TRIAL_CONFIG_COMMAND: 0x75, + SET_CENTER_COMMAND: 0x76, + CENTER_RESPONSE: 0x77, + GET_CENTER_COMMAND: 0x78, + SET_SHIMMERNAME_COMMAND: 0x79, + SHIMMERNAME_RESPONSE: 0x7a, + GET_SHIMMERNAME_COMMAND: 0x7b, + SET_EXPID_COMMAND: 0x7c, + EXPID_RESPONSE: 0x7d, + GET_EXPID_COMMAND: 0x7e, + SET_MYID_COMMAND: 0x7f, + MYID_RESPONSE: 0x80, + GET_MYID_COMMAND: 0x81, + SET_NSHIMMER_COMMAND: 0x82, + NSHIMMER_RESPONSE: 0x83, + GET_NSHIMMER_COMMAND: 0x84, + SET_CONFIGTIME_COMMAND: 0x85, + CONFIGTIME_RESPONSE: 0x86, + GET_CONFIGTIME_COMMAND: 0x87, + DIR_RESPONSE: 0x88, + GET_DIR_COMMAND: 0x89, + INSTREAM_CMD_RESPONSE: 0x8a, + SET_CRC_COMMAND: 0x8b, + SET_INFOMEM_COMMAND: 0x8c, + INFOMEM_RESPONSE: 0x8d, + GET_INFOMEM_COMMAND: 0x8e, + SET_RWC_COMMAND: 0x8f, + RWC_RESPONSE: 0x90, + GET_RWC_COMMAND: 0x91, + START_LOGGING_COMMAND: 0x92, + STOP_LOGGING_COMMAND: 0x93, + VBATT_RESPONSE: 0x94, + GET_VBATT_COMMAND: 0x95, + TEST_CONNECTION_COMMAND: 0x96, + STOP_SDBT_COMMAND: 0x97, + SET_CALIB_DUMP_COMMAND: 0x98, + RSP_CALIB_DUMP_COMMAND: 0x99, + GET_CALIB_DUMP_COMMAND: 0x9a, + UPD_CALIB_DUMP_COMMAND: 0x9b, + UPD_SDLOG_CFG_COMMAND: 0x9c, + BMP280_CALIBRATION_COEFFICIENTS_RESPONSE: 0x9f, + GET_BMP280_CALIBRATION_COEFFICIENTS_COMMAND: 0xa0, + GET_BT_VERSION_STR_COMMAND: 0xa1, + BT_VERSION_STR_RESPONSE: 0xa2, + SET_INSTREAM_RESPONSE_ACK_PREFIX_STATE: 0xa3, + SET_DATA_RATE_TEST: 0xa4, + DATA_RATE_TEST_RESPONSE: 0xa5, + PRESSURE_CALIBRATION_COEFFICIENTS_RESPONSE: 0xa6, + GET_PRESSURE_CALIBRATION_COEFFICIENTS_COMMAND: 0xa7, + SET_FACTORY_TEST: 0xa8, + SET_ALT_ACCEL_CALIBRATION_COMMAND: 0xa9, + ALT_ACCEL_CALIBRATION_RESPONSE: 0xaa, + GET_ALT_ACCEL_CALIBRATION_COMMAND: 0xab, + SET_ALT_ACCEL_SAMPLING_RATE_COMMAND: 0xac, + ALT_ACCEL_SAMPLING_RATE_RESPONSE: 0xad, + GET_ALT_ACCEL_SAMPLING_RATE_COMMAND: 0xae, + SET_ALT_MAG_CALIBRATION_COMMAND: 0xaf, + ALT_MAG_CALIBRATION_RESPONSE: 0xb0, + GET_ALT_MAG_CALIBRATION_COMMAND: 0xb1, + SET_ALT_MAG_SAMPLING_RATE_COMMAND: 0xb2, + ALT_MAG_SAMPLING_RATE_RESPONSE: 0xb3, + GET_ALT_MAG_SAMPLING_RATE_COMMAND: 0xb4, + DUMMY_COMMAND: 0xb5, + RESET_BT_ERROR_COUNTS: 0xb6, + SET_FEATURE: 0xb7, + SET_SD_SYNC_COMMAND: 0xe0, + SD_SYNC_RESPONSE: 0xe1, + NACK_COMMAND_PROCESSED: 0xfe, + ACK_COMMAND_PROCESSED: 0xff, +}); +/** Default BLE service / characteristic UUIDs for Shimmer3R. */ +const SHIMMER3R_DEFAULTS = Object.freeze({ + SERVICE_UUID: '65333333-a115-11e2-9e9a-0800200ca100', + /** Write characteristic (host → device). */ + CHAR_RX_UUID: '65333333-a115-11e2-9e9a-0800200ca102', + /** Notify characteristic (device → host). */ + CHAR_TX_UUID: '65333333-a115-11e2-9e9a-0800200ca101', +}); +/** + * Timestamp field descriptors keyed by width. + * Shimmer3R firmware ≥ v1.0.22 always uses u24. + */ +const TIMESTAMP_FIELD = Object.freeze({ + u16: { name: 'TIMESTAMP', fmt: 'u16', endian: 'le', sizeBytes: 2 }, + u24: { name: 'TIMESTAMP', fmt: 'u24', endian: 'le', sizeBytes: 3 }, +}); +/** GSR signal name constant used in ObjectCluster fields. */ +const GSR_NAME = 'GSR'; +/** ADC limit below which GSR range-3 calibration is clamped. */ +const GSR_UNCAL_LIMIT_RANGE3 = 683; +/** + * Shimmer3R GSR resistance min/max per hardware range (kΩ). + * Index 0 = range 0 (8–63 kΩ) … index 3 = range 3 (680–4700 kΩ). + */ +const SHIMMER3_GSR_RESISTANCE_MIN_MAX_KOHMS = [ + [8.0, 63.0], + [63.0, 220.0], + [220.0, 680.0], + [680.0, 4700.0], +]; + +/** + * Sensor enable bitmasks for Shimmer3 / Shimmer3R. + * + * Values are 24-bit integers sent as the payload of SET_SENSORS_CMD. + * Multiple sensors are ORed together. + * + * @example + * ```ts + * const mask = SensorBitmapShimmer3.SENSOR_GYRO | SensorBitmapShimmer3.SENSOR_A_ACCEL; + * await client.setSensors(mask); + * ``` + */ +const SensorBitmapShimmer3 = Object.freeze({ + SENSOR_A_ACCEL: 0x000080, + SENSOR_GYRO: 0x000040, + SENSOR_MAG: 0x000020, + SENSOR_GSR: 0x000004, + SENSOR_VBATT: 0x002000, + SENSOR_D_ACCEL: 0x001000, + SENSOR_PRESSURE: 0x040000, + SENSOR_EXG1_24BIT: 0x000010, + SENSOR_EXG2_24BIT: 0x000008, + SENSOR_EXG1_16BIT: 0x100000, + SENSOR_EXG2_16BIT: 0x080000, + SENSOR_BRIDGE_AMP: 0x008000, + SENSOR_ACCEL_ALT: 0x400000, + SENSOR_MAG_ALT: 0x200000, + SENSOR_EXT_A0: 0x000002, + SENSOR_EXT_A1: 0x000001, + SENSOR_EXT_A2: 0x000800, + SENSOR_INT_A3: 0x000400, + SENSOR_INT_A0: 0x000200, + SENSOR_INT_A1: 0x000100, + SENSOR_INT_A2: 0x800000, +}); + +/** + * Mapping from Shimmer3R channel ID byte to its format descriptor. + * Channel IDs are reported in the INQUIRY_RSP payload. + */ +const CHANNEL_FORMATS = Object.freeze({ + 0x00: { name: 'LN_ACCEL_X', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x01: { name: 'LN_ACCEL_Y', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x02: { name: 'LN_ACCEL_Z', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x04: { name: 'WR_ACCEL_X', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x05: { name: 'WR_ACCEL_Y', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x06: { name: 'WR_ACCEL_Z', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x14: { name: 'HG_ACCEL_X', fmt: 'i12*', endian: 'le', sizeBytes: 2 }, + 0x15: { name: 'HG_ACCEL_Y', fmt: 'i12*', endian: 'le', sizeBytes: 2 }, + 0x16: { name: 'HG_ACCEL_Z', fmt: 'i12*', endian: 'le', sizeBytes: 2 }, + 0x0a: { name: 'GYRO_X', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x0b: { name: 'GYRO_Y', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x0c: { name: 'GYRO_Z', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x07: { name: 'MAG_X', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x08: { name: 'MAG_Y', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x09: { name: 'MAG_Z', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x1d: { name: 'Exg1_Status', fmt: 'u8', endian: 'le', sizeBytes: 1 }, + 0x20: { name: 'Exg2_Status', fmt: 'u8', endian: 'le', sizeBytes: 1 }, + 0x1e: { name: 'Exg1_CH1_24Bit', fmt: 'i24', endian: 'be', sizeBytes: 3 }, + 0x1f: { name: 'Exg1_CH2_24Bit', fmt: 'i24', endian: 'be', sizeBytes: 3 }, + 0x21: { name: 'Exg2_CH1_24Bit', fmt: 'i24', endian: 'be', sizeBytes: 3 }, + 0x22: { name: 'Exg2_CH2_24Bit', fmt: 'i24', endian: 'be', sizeBytes: 3 }, + 0x23: { name: 'Exg1_CH1_16Bit', fmt: 'i16', endian: 'be', sizeBytes: 2 }, + 0x24: { name: 'Exg1_CH2_16Bit', fmt: 'i16', endian: 'be', sizeBytes: 2 }, + 0x25: { name: 'Exg2_CH1_16Bit', fmt: 'i16', endian: 'be', sizeBytes: 2 }, + 0x26: { name: 'Exg2_CH2_16Bit', fmt: 'i16', endian: 'be', sizeBytes: 2 }, + 0x12: { name: 'PPG', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x1c: { name: 'GSR', fmt: 'u16', endian: 'le', sizeBytes: 2 }, +}); + +// --------------------------------------------------------------------------- +// ADC helpers +// --------------------------------------------------------------------------- +/** + * Convert a Shimmer3R 12-bit ADC value to millivolts. + * + * @param unCalData Raw 12-bit ADC sample. + * @param offset ADC offset (typically 0). + * @param vRefP Reference voltage in volts (typically 3 V for Shimmer3R). + * @param gain Amplifier gain (typically 1). + * @returns Calibrated voltage in millivolts. + */ +function calibrateU12AdcValue(unCalData, offset, vRefP, gain) { + return (unCalData - offset) * ((vRefP * 1000) / gain / 4095); +} +/** + * Convert a Shimmer3R ADC channel value to millivolts using the + * default Shimmer3R ADC parameters (Vref = 3 V, gain = 1, offset = 0). + * + * @param unCalData Raw 12-bit ADC sample. + * @returns Voltage in millivolts. + */ +function calibrateShimmer3RAdcChannel(unCalData) { + return calibrateU12AdcValue(unCalData, 0, 3, 1); +} +// --------------------------------------------------------------------------- +// GSR calibration +// --------------------------------------------------------------------------- +/** + * Convert a raw GSR ADC sample to skin resistance (kΩ) using the + * Shimmer3R amplifier equation. + * + * Reference resistors per range (kΩ): [40.2, 287.0, 1000.0, 3300.0]. + * + * @param gsrUncalibratedData Raw 12-bit GSR ADC value. + * @param range Hardware range index 0–3. + * @returns Resistance in kΩ. + */ +function calibrateGsrDataToResistanceFromAmplifierEq(gsrUncalibratedData, range) { + const SHIMMER3_REF_KOHMS = [40.2, 287.0, 1000.0, 3300.0]; + const rFeedback = SHIMMER3_REF_KOHMS[range]; + const volts = calibrateShimmer3RAdcChannel(gsrUncalibratedData) / 1000.0; // mV → V + const rSource = rFeedback / (volts / 0.5 - 1.0); + return rSource; +} +/** + * Clamp a GSR resistance value to the physical limits of a given range. + * + * When `gsrRangeSetting === 4` (auto-range) no clamping is applied. + * + * @param gsrResistanceKOhms Calibrated resistance in kΩ. + * @param gsrRangeSetting Range 0–3 (fixed) or 4 (auto). + * @returns Clamped resistance in kΩ. + */ +function nudgeGsrResistance(gsrResistanceKOhms, gsrRangeSetting) { + if (gsrRangeSetting === 4) + return gsrResistanceKOhms; + const [minVal, maxVal] = SHIMMER3_GSR_RESISTANCE_MIN_MAX_KOHMS[gsrRangeSetting]; + return Math.max(minVal, Math.min(maxVal, gsrResistanceKOhms)); +} +// --------------------------------------------------------------------------- +// ExG (ADS1292R) oversampling ratio +// --------------------------------------------------------------------------- +/** + * Determine the ADS1292R oversampling ratio config byte for a given + * Shimmer3R sampling rate. + * + * This value is ORed into the lower 3 bits of ExG config byte index 4. + * + * @param samplingRate Shimmer3R sampling rate in Hz (must be ≥ 0). + * @returns Oversampling ratio index 0–6. + */ +function getOversamplingRatioADS1292R(samplingRate) { + if (!Number.isFinite(samplingRate)) { + throw new TypeError('samplingRate must be a finite number'); + } + if (samplingRate < 0) { + throw new RangeError('samplingRate must be non-negative'); + } + if (samplingRate < 125) + return 0; + if (samplingRate < 250) + return 1; + if (samplingRate < 500) + return 2; + if (samplingRate < 1000) + return 3; + if (samplingRate < 2000) + return 4; + if (samplingRate < 4000) + return 5; + return 6; // ≥ 4000 Hz +} + +/** + * Low-level byte-manipulation utilities used by the Shimmer3R protocol decoder. + * All functions are pure and have no side-effects, making them straightforward + * to unit-test without a BLE device. + */ +/** Concatenate two Uint8Arrays. */ +function concatU8(a, b) { + const out = new Uint8Array(a.length + b.length); + out.set(a); + out.set(b, a.length); + return out; +} +/** Read a 16-bit unsigned integer, little-endian. */ +function u16le$2(b, o) { + return (b[o] | (b[o + 1] << 8)) >>> 0; +} +/** Read a 16-bit unsigned integer, big-endian. */ +function u16be(b, o) { + return ((b[o] << 8) | b[o + 1]) >>> 0; +} +/** Read a 24-bit unsigned integer, little-endian. */ +function u24le$1(b, o) { + return (b[o] | (b[o + 1] << 8) | (b[o + 2] << 16)) >>> 0; +} +/** Read a 24-bit unsigned integer, big-endian. */ +function u24be(b, o) { + return ((b[o] << 16) | (b[o + 1] << 8) | b[o + 2]) >>> 0; +} +/** Sign-extend a 16-bit value to a signed integer. */ +function sign16(v) { + return v & 0x8000 ? v | 0xffff0000 : v; +} +/** Sign-extend a 24-bit value to a signed integer. */ +function sign24(v) { + return v & 0x800000 ? v | 0xff000000 : v; +} +/** Format a byte as a 2-digit uppercase hex string. */ +function hex2(v) { + return v.toString(16).padStart(2, '0').toUpperCase(); +} + +// --------------------------------------------------------------------------- +// Shimmer3RClient +// --------------------------------------------------------------------------- +/** + * Web Bluetooth client for the Shimmer3R sensor platform. + * + * Implements the ACK-first command flow used by Shimmer3R firmware ≥ v1.0.22: + * every configuration command awaits an ACK (0xFF) before resolving. + * Streaming data frames are framed with a DATA preamble (0x00). + * + * @example + * ```ts + * const client = new Shimmer3RClient({ timestampFmt: 'u24', debug: true }); + * client.onStatus = (msg) => console.log(msg); + * client.onStreamFrame = (oc) => { + * const gz = oc.get('GYRO_Z', 'raw')?.value; + * console.log('gz =', gz); + * }; + * + * await client.connect(); + * await client.setSamplingRate(51.2); + * await client.setSensors(SensorBitmapShimmer3.SENSOR_GYRO); + * await client.startStreaming(); + * ``` + */ +class Shimmer3RClient extends BaseShimmerClient { + constructor(opts = {}) { + super(opts); + this.device = null; + this.server = null; + this.rx = null; + this.tx = null; + // Protocol state + this._rxBuf = new Uint8Array(0); + this._temps = new Set(); + this.schema = null; + this._lastAckRemainder = null; + this._expectingAck = 0; + this._streaming = false; + this._lastTs = 0; + // Cached device configuration + this.enabledSensors = 0x000000; + this.samplingRateHz = 0; + this.gsrRangeSetting = 0; + this.ExpPower = 0; + /** Minimum valid GSR conductance in µS (below this, connectivity = "Disconnected"). */ + this.LIMIT_MIN_VALID_USIEMENS = 0.03; + // Callbacks + this.onInquiry = null; + this.onExpPowerChanged = null; + // --------------------------------------------------------------------------- + // BLE notify handler + // --------------------------------------------------------------------------- + this._handleNotify = (evt) => { + const chunk = new Uint8Array(evt.target.value.buffer); + this._log('Notify len=', chunk.length, 'data=', chunk); + // 1) Consume an expected ACK + if (chunk.length >= 1 && + chunk[0] === OPCODES.ACK_COMMAND_PROCESSED && + (this._expectingAck ?? 0) > 0) { + this._log('ACK detected at start of notify (expected)'); + this._expectingAck = Math.max(0, this._expectingAck - 1); + const remainder = chunk.slice(1); + this._lastAckRemainder = remainder.length ? remainder : null; + this._emitTemp(new Uint8Array([OPCODES.ACK_COMMAND_PROCESSED])); + if (this._lastAckRemainder) { + if (this._streaming && this._lastAckRemainder[0] === OPCODES.DATA_PACKET) { + this._log('Appending DATA remainder after ACK to stream buffer'); + this._rxBuf = concatU8(this._rxBuf, this._lastAckRemainder); + } + else { + this._log('Forwarding non-DATA remainder to control handlers'); + this._emitTemp(this._lastAckRemainder); + } + this._lastAckRemainder = null; + } + return; + } + // 2) During streaming, all bytes are data-plane + if (this._streaming) { + this._rxBuf = concatU8(this._rxBuf, chunk); + } + else { + this._emitTemp(chunk); + if (chunk.length && chunk[0] === OPCODES.DATA_PACKET) { + this._rxBuf = concatU8(this._rxBuf, chunk); + } + } + // 3) Try parsing if schema is available + if (this.schema) { + try { + this._parseBySchema(); + } + catch (e) { + this._log('parseBySchema error:', e); + } + } + }; + this.serviceUUID = opts.serviceUUID ?? SHIMMER3R_DEFAULTS.SERVICE_UUID; + this.rxUUID = opts.rxUUID ?? SHIMMER3R_DEFAULTS.CHAR_RX_UUID; + this.txUUID = opts.txUUID ?? SHIMMER3R_DEFAULTS.CHAR_TX_UUID; + this.forceTimestampFmt = opts.timestampFmt ?? 'u24'; + } + _log(...args) { + if (this.debug) + console.log('[Shimmer3R]', ...args); + } + // --------------------------------------------------------------------------- + // Connection management + // --------------------------------------------------------------------------- + async connect() { + this._emitStatus('Requesting Bluetooth device…'); + this.device = await navigator.bluetooth.requestDevice({ + filters: [{ services: [this.serviceUUID] }], + optionalServices: [this.serviceUUID], + }); + this._emitStatus(`Selected: ${this.device.name ?? 'Shimmer3R'}`); + this.server = await this.device.gatt.connect(); + this._emitStatus('GATT connected'); + const svc = await this.server.getPrimaryService(this.serviceUUID); + this.rx = await svc.getCharacteristic(this.rxUUID); + this.tx = await svc.getCharacteristic(this.txUUID); + this._emitStatus('RX/TX obtained'); + await this.tx.startNotifications(); + this.tx.addEventListener('characteristicvaluechanged', this._handleNotify); + this._emitStatus('Notifications started'); + } + async disconnect() { + try { + if (this.tx) { + try { + await this.tx.stopNotifications(); + } + catch { + /* ignore */ + } + this.tx.removeEventListener('characteristicvaluechanged', this._handleNotify); + } + if (this.device?.gatt?.connected) + this.device.gatt.disconnect(); + } + finally { + this.device = this.server = this.rx = this.tx = null; + this._rxBuf = new Uint8Array(0); + this.schema = null; + this._streaming = false; + this.ExpPower = 0; + this._emitStatus('Disconnected'); + } + } + // --------------------------------------------------------------------------- + // Configuration commands + // --------------------------------------------------------------------------- + /** + * Control the internal expansion power rail (required for ExG/EMG/ECG). + * @param expPower 0 = disable, 1 = enable. + */ + async setInternalExpPower(expPower) { + if (expPower !== 0 && expPower !== 1) + throw new Error('expPower must be 0 (off) or 1 (on)'); + if (!this.rx) + throw new Error('Not connected (RX missing)'); + const cmd = new Uint8Array([OPCODES.SET_INTERNAL_EXP_POWER_ENABLE_COMMAND, expPower]); + this._emitStatus(`SET_INTERNAL_EXP_POWER_ENABLE_CMD → ${expPower ? 'ON' : 'OFF'} waiting for ACK…`); + const ackRemainder = await this._writeExpectingAck(cmd, 1500); + this._emitStatus(`Expansion power ${expPower ? 'enabled' : 'disabled'} (ACK received).`); + this.ExpPower = expPower; + try { + this.onExpPowerChanged?.(expPower); + } + catch (e) { + this._log('onExpPowerChanged handler error', e); + } + return { expPower, ackRemainder }; + } + /** + * Set the GSR measurement range. + * @param gsrRange 0 = 8–63 kΩ, 1 = 63–220 kΩ, 2 = 220–680 kΩ, 3 = 680–4700 kΩ, 4 = Auto. + */ + async setGSRRange(gsrRange) { + if (!Number.isInteger(gsrRange) || gsrRange < 0 || gsrRange > 4) { + throw new Error('gsrRange must be 0–4'); + } + if (!this.rx) + throw new Error('Not connected (RX missing)'); + const cmd = new Uint8Array([OPCODES.SET_GSR_RANGE_COMMAND, gsrRange & 0xff]); + this._emitStatus('SET_GSR_RANGE → waiting for ACK…'); + const ackRemainder = await this._writeExpectingAck(cmd, 1500); + this._emitStatus('SET_GSR_RANGE (ACK received).'); + this.gsrRangeSetting = gsrRange; + return { gsrRange, ackRemainder }; + } + getInternalExpPower() { + return this.ExpPower; + } + getEnabledSensors() { + return this.enabledSensors; + } + /** + * Enable sensors via a 24-bit bitmask. + * Automatically performs an Inquiry after ACK to rebuild the stream schema. + */ + async setSensors(sensors) { + if (!Number.isFinite(sensors)) + throw new Error('sensors must be a finite number'); + if (!this.rx) + throw new Error('Not connected (RX missing)'); + sensors = (sensors >>> 0) & 0xffffff; + const b1 = sensors & 0xff; + const b2 = (sensors >>> 8) & 0xff; + const b3 = (sensors >>> 16) & 0xff; + const cmd = new Uint8Array([OPCODES.SET_SENSORS_COMMAND, b1, b2, b3]); + this._emitStatus(`SET_SENSORS_CMD → bitmask=0x${sensors.toString(16).toUpperCase().padStart(6, '0')} waiting for ACK…`); + const ackRemainder = await this._writeExpectingAck(cmd, 1500); + this._emitStatus(`Sensors ACK received. Bitmask 0x${sensors.toString(16).toUpperCase().padStart(6, '0')} applied.`); + try { + this._emitStatus('Performing automatic inquiry to refresh schema…'); + const info = await this.inquiry(); + this.enabledSensors = info.schema.enabledSensors; + this._emitStatus(`Inquiry complete. Enabled sensors: 0x${this.enabledSensors.toString(16).toUpperCase()}`); + } + catch (err) { + this._emitStatus(`Inquiry after setSensors failed: ${err.message}`); + } + return { sensors, ackRemainder, enabledSensors: this.enabledSensors }; + } + /** + * Set the sampling rate. + * The firmware expects a 16-bit divisor: `divisor = floor(32768 / rateHz)`. + */ + async setSamplingRate(rateHz) { + if (!Number.isFinite(rateHz) || rateHz <= 0) { + throw new Error('Sampling rate must be a positive number (Hz)'); + } + if (!this.rx) + throw new Error('Not connected (RX missing)'); + let divisor = Math.floor(32768 / rateHz); + divisor = Math.max(1, Math.min(0xffff, divisor)); + const lsb = divisor & 0xff; + const msb = (divisor >> 8) & 0xff; + const cmd = new Uint8Array([OPCODES.SET_SAMPLING_RATE_COMMAND, lsb, msb]); + this._emitStatus(`Set sampling rate → ${rateHz.toFixed(3)} Hz (divisor=${divisor}) — waiting for ACK…`); + const ackRemainder = await this._writeExpectingAck(cmd, 1500); + const appliedHz = 32768 / divisor; + this.samplingRateHz = appliedHz; + this._emitStatus(`Sampling rate ACKed. Applied ≈ ${this.samplingRateHz.toFixed(3)} Hz`); + return { requestedHz: rateHz, appliedHz, divisor, ackRemainder }; + } + // --------------------------------------------------------------------------- + // Inquiry + // --------------------------------------------------------------------------- + /** Send INQUIRY_CMD and parse the response to build the stream schema. */ + async inquiry() { + this._emitStatus('INQUIRY_CMD → waiting for ACK then RSP…'); + const remainder = await this._writeExpectingAck(new Uint8Array([OPCODES.INQUIRY_COMMAND]), 1500); + if (remainder && remainder[0] === OPCODES.INQUIRY_RESPONSE) { + this._log('Using post-ACK remainder as response'); + const info = this._interpretInquiryResponseShimmer3R(remainder); + this.onInquiry?.(info); + return info; + } + const rsp = await this._waitForResponse(OPCODES.INQUIRY_RESPONSE, 2000); + this._emitStatus(`Inquiry RSP (${rsp.length} bytes)`); + const info = this._interpretInquiryResponseShimmer3R(rsp); + this.onInquiry?.(info); + return info; + } + // --------------------------------------------------------------------------- + // ExG configuration helpers + // --------------------------------------------------------------------------- + /** Enable EMG (ADS1292R) in 16-bit mode on EXG1 & EXG2. */ + async enableEMG16Bit() { + if (!this.rx) + throw new Error('Not connected (RX missing)'); + await this._writeExgPages(new Uint8Array([ + 0x61, 0x00, 0x00, 0x0a, 0x02, 0xa8, 0x10, 0x69, 0x60, 0x20, 0x00, 0x00, 0x02, 0x03, + ]), new Uint8Array([ + 0x61, 0x01, 0x00, 0x0a, 0x02, 0xa0, 0x10, 0xe1, 0xe1, 0x00, 0x00, 0x00, 0x02, 0x01, + ])); + this._emitStatus('EMG 16-bit enabled on EXG1 & EXG2. Schema updated.'); + } + /** Enable EXG test signal in 16-bit mode (useful for verifying ExG hardware). */ + async enableEXGTestSignal16Bit() { + if (!this.rx) + throw new Error('Not connected (RX missing)'); + await this._writeExgPages(new Uint8Array([ + 0x61, 0x00, 0x00, 0x0a, 0x02, 0xab, 0x10, 0x15, 0x15, 0x00, 0x00, 0x00, 0x02, 0x01, + ]), new Uint8Array([ + 0x61, 0x01, 0x00, 0x0a, 0x02, 0xa3, 0x10, 0x15, 0x15, 0x00, 0x00, 0x00, 0x02, 0x01, + ])); + this._emitStatus('EXG test signal 16-bit enabled. Schema updated.'); + } + /** Enable ECG in 16-bit mode on EXG1 & EXG2. */ + async enableECG16Bit() { + if (!this.rx) + throw new Error('Not connected (RX missing)'); + await this._writeExgPages(new Uint8Array([ + 0x61, 0x00, 0x00, 0x0a, 0x02, 0xa8, 0x10, 0x40, 0x40, 0x2d, 0x00, 0x00, 0x02, 0x03, + ]), new Uint8Array([ + 0x61, 0x01, 0x00, 0x0a, 0x02, 0xa0, 0x10, 0x40, 0x47, 0x00, 0x00, 0x00, 0x02, 0x01, + ])); + this._emitStatus('ECG 16-bit enabled on EXG1 & EXG2. Schema updated.'); + } + async _writeExgPages(exg1, exg2) { + const oversamplingRatio = getOversamplingRatioADS1292R(this.samplingRateHz); + exg1 = new Uint8Array(exg1); + exg2 = new Uint8Array(exg2); + exg1[4] = (((exg1[4] >> 3) << 3) | oversamplingRatio) & 0xff; + exg2[4] = (((exg2[4] >> 3) << 3) | oversamplingRatio) & 0xff; + await this._write(exg1); + await new Promise((r) => setTimeout(r, 200)); + await this._write(exg2); + await new Promise((r) => setTimeout(r, 50)); + const targetBits = (SensorBitmapShimmer3.SENSOR_EXG1_16BIT | SensorBitmapShimmer3.SENSOR_EXG2_16BIT) >>> 0; + const newMask = ((this.enabledSensors >>> 0) | targetBits) & 0xffffff; + await this.setSensors(newMask); + } + // --------------------------------------------------------------------------- + // Streaming + // --------------------------------------------------------------------------- + async startStreaming() { + if (!this.schema) + this._emitStatus('Starting stream without schema (not recommended).'); + this._emitStatus('START_STREAM → waiting for ACK…'); + const remainder = await this._writeExpectingAck(new Uint8Array([OPCODES.START_STREAMING_COMMAND]), 1500); + this._streaming = true; + if (remainder?.length) { + if (remainder[0] === OPCODES.DATA_PACKET) { + this._rxBuf = concatU8(this._rxBuf, remainder); + } + else { + this._emitTemp(remainder); + } + } + this._emitStatus('START_STREAM ACK received; frames should follow'); + } + async stopStreaming() { + this._emitStatus('STOP_STREAM → sending (no ACK wait)…'); + try { + await this._write(new Uint8Array([OPCODES.STOP_STREAMING_COMMAND])); + this._emitStatus('STOP_STREAM command sent (skipped ACK wait).'); + } + catch (err) { + this._emitStatus(`STOP_STREAM write failed: ${err.message}`); + } + this._streaming = false; + this._rxBuf = new Uint8Array(0); + this._emitStatus('Streaming stopped.'); + } + /** Start streaming AND SD card logging simultaneously. */ + async startStreamingAndLogging() { + if (!this.schema) + this._emitStatus('Starting stream without schema (not recommended).'); + this._emitStatus('START_BT_STREAM_SD_LOGGING → waiting for ACK…'); + const remainder = await this._writeExpectingAck(new Uint8Array([OPCODES.START_SDBT_COMMAND]), 1500); + this._streaming = true; + if (remainder?.length) { + if (remainder[0] === OPCODES.DATA_PACKET) { + this._rxBuf = concatU8(this._rxBuf, remainder); + } + else { + this._emitTemp(remainder); + } + } + this._emitStatus('START_BT_STREAM_SD_LOGGING ACK received; frames should follow'); + } + /** Stop streaming AND SD card logging. */ + async stopStreamingAndLogging() { + this._emitStatus('STOP_BT_STREAM_SD_LOGGING → sending…'); + try { + await this._write(new Uint8Array([OPCODES.STOP_SDBT_COMMAND])); + } + catch (err) { + this._emitStatus(`STOP_BT_STREAM_SD_LOGGING write failed: ${err.message}`); + } + this._streaming = false; + this._rxBuf = new Uint8Array(0); + this._emitStatus('Streaming + logging stopped.'); + } + // --------------------------------------------------------------------------- + // Inquiry response / schema building + // --------------------------------------------------------------------------- + _interpretInquiryResponseShimmer3R(u8) { + let base = 0; + if (u8[0] === OPCODES.INQUIRY_RESPONSE && u8.length >= 2) + base = 1; + const adcRaw = u16le$2(u8, base + 0); + const samplingRateHz = 32768 / adcRaw; + this.samplingRateHz = samplingRateHz; + const cfg = BigInt(u8[base + 2]) | + (BigInt(u8[base + 3]) << 8n) | + (BigInt(u8[base + 4]) << 16n) | + (BigInt(u8[base + 5]) << 24n) | + (BigInt(u8[base + 6]) << 32n) | + (BigInt(u8[base + 7]) << 40n) | + (BigInt(u8[base + 8]) << 48n); + const internalExpPower = Number((cfg >> 24n) & 0x1n); + const gsrRange = Number((cfg >> 25n) & 0x7n); + this.ExpPower = internalExpPower; + this.gsrRangeSetting = gsrRange; + const numCh = u8[base + 9] ?? 0; + const bufSize = u8[base + 10] ?? 0; + const chStart = base + 11; + const channelIds = [...u8.slice(chStart, chStart + numCh)]; + const schema = this._buildSchemaFromChannels(channelIds, this.forceTimestampFmt ?? 'u24'); + this.schema = schema; + this._log(`Schema built: timestampFmt=${schema.timestampFmt}, fields=${schema.fields.length}, enabledSensors=0x${schema.enabledSensors.toString(16)}`); + this._emitStatus(`Expansion power ${this.ExpPower ? 'enabled' : 'disabled'} (ACK received).`); + return { + opcode: u8[0], + adcRaw, + samplingRateHz, + numChannels: numCh, + bufferSize: bufSize, + channelIds, + schema, + bytes: u8.slice(0), + }; + } + _buildSchemaFromChannels(channelIds, timestampFmt) { + const fields = []; + const ts = timestampFmt === 'u24' ? TIMESTAMP_FIELD.u24 : TIMESTAMP_FIELD.u16; + let packetSize = 1 + ts.sizeBytes; // 1 = preamble 0x00 + let enabledSensors = 0; + for (const id of channelIds) { + const fmt = CHANNEL_FORMATS[id]; + if (!fmt) { + fields.push({ id, name: `CH_${hex2(id)}`, fmt: 'i16', endian: 'le', sizeBytes: 2 }); + packetSize += 2; + continue; + } + fields.push({ id, ...fmt }); + packetSize += fmt.sizeBytes ?? 2; + switch (id) { + case 0x00: + case 0x01: + case 0x02: + enabledSensors |= SensorBitmapShimmer3.SENSOR_A_ACCEL; + break; + case 0x04: + case 0x05: + case 0x06: + enabledSensors |= SensorBitmapShimmer3.SENSOR_D_ACCEL; + break; + case 0x14: + case 0x15: + case 0x16: + enabledSensors |= SensorBitmapShimmer3.SENSOR_ACCEL_ALT; + break; + case 0x07: + case 0x08: + case 0x09: + enabledSensors |= SensorBitmapShimmer3.SENSOR_MAG; + break; + case 0x0a: + case 0x0b: + case 0x0c: + enabledSensors |= SensorBitmapShimmer3.SENSOR_GYRO; + break; + case 0x12: + enabledSensors |= SensorBitmapShimmer3.SENSOR_INT_A1; + break; + case 0x1c: + enabledSensors |= SensorBitmapShimmer3.SENSOR_GSR; + break; + case 0x23: + case 0x24: + enabledSensors |= SensorBitmapShimmer3.SENSOR_EXG1_16BIT; + break; + case 0x25: + case 0x26: + enabledSensors |= SensorBitmapShimmer3.SENSOR_EXG2_16BIT; + break; + case 0x1e: + case 0x1f: + enabledSensors |= SensorBitmapShimmer3.SENSOR_EXG1_24BIT; + break; + case 0x21: + case 0x22: + enabledSensors |= SensorBitmapShimmer3.SENSOR_EXG2_24BIT; + break; + default: + console.warn(`⚠️ Unmapped channel ID 0x${id.toString(16)} — added as generic i16.`); + } + } + this.enabledSensors = enabledSensors; + return { timestampFmt, fields, frameBytes: packetSize, enabledSensors, dataPreambleByte: 0x00 }; + } + // --------------------------------------------------------------------------- + // GSR calibration (applied inline during stream parsing) + // --------------------------------------------------------------------------- + _calibrateData(oc) { + const snapshot = [...oc.fields]; + for (const field of snapshot) { + if (field.name === GSR_NAME) { + const rawField = oc.get(GSR_NAME, 'raw'); + const gsrraw = rawField?.value ?? null; + if (gsrraw === null) + continue; + let adc12 = gsrraw & 0x0fff; + let currentRange = this.gsrRangeSetting; + if (currentRange === 4) { + currentRange = (gsrraw >> 14) & 0x03; + } + if (currentRange === 3 && adc12 < GSR_UNCAL_LIMIT_RANGE3) { + adc12 = GSR_UNCAL_LIMIT_RANGE3; + } + let gsrkOhm = calibrateGsrDataToResistanceFromAmplifierEq(adc12, currentRange); + gsrkOhm = nudgeGsrResistance(gsrkOhm, this.gsrRangeSetting); + const gsrConductanceUSiemens = (1.0 / gsrkOhm) * 1000; + oc.add(GSR_NAME, gsrConductanceUSiemens, 'uSiemens', 'cal'); + } + } + } + // --------------------------------------------------------------------------- + // Stream frame parser + // --------------------------------------------------------------------------- + _parseBySchema() { + const sch = this.schema; + const preamble = sch.dataPreambleByte; + const frameBytes = sch.frameBytes >>> 0; + const tsBytes = sch.timestampFmt === 'u16' ? 2 : 3; + const TS_MOD = tsBytes === 3 ? 16777216 : 65536; + let buf = this._rxBuf; + let frames = 0; + let drops = 0; + let anomalies = 0; + while (buf.length >= frameBytes * 2) { + if (buf[0] === preamble && buf[frameBytes] === preamble) { + let ts1, ts2; + try { + ts1 = tsBytes === 2 ? u16le$2(buf, 1) : u24le$1(buf, 1); + ts2 = tsBytes === 2 ? u16le$2(buf, frameBytes + 1) : u24le$1(buf, frameBytes + 1); + } + catch { + buf = buf.subarray(1); + drops++; + continue; + } + const dt = (((ts2 - ts1) % TS_MOD) + TS_MOD) % TS_MOD; + if (dt === 0) { + buf = buf.subarray(1); + drops++; + continue; + } + const frame = buf.subarray(0, frameBytes); + try { + let cursor = 1; + const oc = new ObjectCluster(this.device?.name ?? 'Shimmer3R'); + const ts = tsBytes === 2 ? u16le$2(frame, cursor) : u24le$1(frame, cursor); + cursor += tsBytes; + oc.add('TIMESTAMP', ts, 'ticks', 'raw'); + for (const f of sch.fields) { + if (cursor + f.sizeBytes > frame.length) { + throw new Error(`short frame: need ${f.sizeBytes} @${cursor}, have ${frame.length}`); + } + let v; + switch (f.fmt) { + case 'i16': + v = f.endian === 'be' ? sign16(u16be(frame, cursor)) : sign16(u16le$2(frame, cursor)); + break; + case 'u16': + v = f.endian === 'be' ? u16be(frame, cursor) : u16le$2(frame, cursor); + break; + case 'i24': + v = f.endian === 'be' ? sign24(u24be(frame, cursor)) : sign24(u24le$1(frame, cursor)); + break; + case 'u24': + v = f.endian === 'be' ? u24be(frame, cursor) : u24le$1(frame, cursor); + break; + case 'i12*': { + const msb = frame[cursor] & 0xff; + const lsb = frame[cursor + 1] & 0xff; + const raw12 = (msb << 4) | (lsb >> 4); + v = raw12 & 0x800 ? raw12 - 0x1000 : raw12; + break; + } + case 'u8': + v = frame[cursor]; + break; + default: + v = u16le$2(frame, cursor); + } + cursor += f.sizeBytes; + oc.add(f.name, v, null, 'raw'); + } + if (this._lastTs) { + const dLast = (((ts - this._lastTs) % TS_MOD) + TS_MOD) % TS_MOD; + if (dLast === 0) { + anomalies++; + this._log(`⚠️ Timestamp anomaly#${anomalies}: ts=${ts}, last=${this._lastTs}, Δ=0`); + } + } + this._lastTs = ts; + this._calibrateData(oc); + this.onStreamFrame?.(oc); + frames++; + buf = buf.subarray(frameBytes); + } + catch (e) { + this._log('⚠️ frame decode error → sliding 1 byte', e.message); + buf = buf.subarray(1); + drops++; + } + continue; + } + buf = buf.subarray(1); + drops++; + if (this.debug && drops % 64 === 1) { + this._log(`resync: dropped ${drops} byte(s) so far; bufLen=${buf.length}`); + } + } + this._rxBuf = buf; + if (drops && drops % 512 === 0) + this._lastTs = 0; + if (this.debug && (frames || drops)) { + this._log(`parse: frames=${frames}, drops=${drops}, leftover=${this._rxBuf.length}`); + } + } + // --------------------------------------------------------------------------- + // Low-level transport helpers + // --------------------------------------------------------------------------- + async _write(u8) { + if (!this.rx) + throw new Error('Not connected (RX missing)'); + this._log('Write', u8); + await this.rx.writeValue(toArrayBuffer(u8)); + } + async _writeExpectingAck(u8, ackTimeoutMs = 1000) { + this._expectingAck++; + try { + await this._write(u8); + return await this._waitForAck(ackTimeoutMs); + } + catch (e) { + this._expectingAck = Math.max(0, this._expectingAck - 1); + throw e; + } + } + _waitForAck(timeoutMs = 1000) { + return new Promise((resolve, reject) => { + const t = setTimeout(() => { + this._offTemp(handler); + reject(new Error('ACK timeout')); + }, timeoutMs); + const handler = (chunk) => { + if (!chunk || chunk.length === 0) + return; + if (chunk.length === 1 && chunk[0] === OPCODES.ACK_COMMAND_PROCESSED) { + clearTimeout(t); + this._offTemp(handler); + const rem = this._lastAckRemainder; + this._lastAckRemainder = null; + resolve(rem ?? null); + return; + } + if (chunk[0] === OPCODES.ACK_COMMAND_PROCESSED && chunk.length > 1) { + clearTimeout(t); + this._offTemp(handler); + resolve(chunk.slice(1)); + } + }; + this._onTemp(handler); + }); + } + _waitForResponse(expectedOpcode, timeoutMs = 1500) { + if (this._lastAckRemainder && this._lastAckRemainder[0] === expectedOpcode) { + const rem = this._lastAckRemainder; + this._lastAckRemainder = null; + return Promise.resolve(rem); + } + return new Promise((resolve, reject) => { + const t = setTimeout(() => { + this._offTemp(handler); + reject(new Error('Response timeout')); + }, timeoutMs); + const handler = (chunk) => { + if (!chunk || chunk.length === 0) + return; + if (chunk.length === 1 && chunk[0] === OPCODES.ACK_COMMAND_PROCESSED) + return; + if (chunk[0] === expectedOpcode) { + clearTimeout(t); + this._offTemp(handler); + resolve(chunk); + } + }; + this._onTemp(handler); + }); + } + _onTemp(fn) { + this._temps.add(fn); + } + _offTemp(fn) { + this._temps.delete(fn); + } + _emitTemp(buf) { + this._temps.forEach((fn) => { + try { + fn(buf); + } + catch (e) { + this._log('temp handler error', e); + } + }); + } +} + +// --------------------------------------------------------------------------- +// Nordic UART Service (NUS) UUIDs used by Verisense devices +// --------------------------------------------------------------------------- +/** NUS primary service UUID. */ +const NUS_SERVICE = '6e400001-b5a3-f393-e0a9-e50e24dcca9e'; +/** NUS TX characteristic UUID (host writes to this). */ +const NUS_TX = '6e400002-b5a3-f393-e0a9-e50e24dcca9e'; +/** NUS RX characteristic UUID (host subscribes to notifications from this). */ +const NUS_RX = '6e400003-b5a3-f393-e0a9-e50e24dcca9e'; +/** Nordic Secure DFU service UUID (buttonless DFU). */ +const NORDIC_DFU_SERVICE = '0000fe59-0000-1000-8000-00805f9b34fb'; +/** Nordic buttonless DFU control-point characteristic (without bond sharing). */ +const NORDIC_DFU_BUTTONLESS_WITHOUT_BONDS = '8ec90003-f315-4f60-9fb8-838830daea50'; +/** Nordic buttonless DFU control-point characteristic (with bond sharing). */ +const NORDIC_DFU_BUTTONLESS_WITH_BONDS = '8ec90004-f315-4f60-9fb8-838830daea50'; +/** Buttonless DFU control-point op-code that reboots the device into the bootloader. */ +const NORDIC_DFU_OP_ENTER_BOOTLOADER = 0x01; +// --------------------------------------------------------------------------- +// Verisense protocol command/property constants +// --------------------------------------------------------------------------- +/** Upper-nibble command classes used in protocol headers. */ +const ASM_COMMAND = Object.freeze({ + READ: 0x10, + WRITE: 0x20, + RESPONSE: 0x30, + ACK: 0x40, + NACK_BAD_HEADER_COMMAND: 0x50, + NACK_BAD_HEADER_PROPERTY: 0x60, + NACK_GENERIC: 0x70, + ACK_NEXT_STAGE: 0x80, +}); +/** Lower-nibble property IDs used in protocol headers. */ +const ASM_PROPERTY = Object.freeze({ + STATUS1: 0x01, + DATA: 0x02, + PRODUCTION_CONFIGURATION: 0x03, + OPERATIONAL_CONFIGURATION: 0x04, + TIME: 0x05, + DFU_MODE: 0x06, + PENDING_EVENTS: 0x07, + TEST_MODE: 0x08, + DEBUG_COMMAND: 0x09, + STREAM_MODE: 0x0a, + DEVICE_DISCONNECT: 0x0b, + STATUS2: 0x0c, + CALIBRATION: 0x0d, +}); +/** Stream mode payload values. */ +const STREAM_MODE = Object.freeze({ + ENABLE: 0x01, + DISABLE: 0x02, +}); +/** Test mode IDs documented by Verisense firmware. */ +const TEST_MODE_ID = Object.freeze({ + STOP: 0x00, + FLASH_8MB_1: 0x01, + FLASH_8MB_2: 0x02, + FLASH_128MB_512MB: 0x03, + EEPROM: 0x04, + ACCEL1_LIS2DW12: 0x05, + BATTERY_VOLTAGE: 0x06, + USB_POWER: 0x07, + ACCEL2_GYRO_LSM6DS3: 0x08, + PPG_MAX86XXX: 0x09, + BIOZ_MAX30002: 0x0b, + ACCEL2_GYRO_LSM6DSV: 0x0c, + MAG_LIS2MDL: 0x0d, + ALL_TESTS: 0xff, +}); +/** Debug command IDs documented by Verisense firmware. */ +const DEBUG_COMMAND_ID = Object.freeze({ + FLASH_LOOKUP_TABLE_READ: 0x01, + FLASH_LOOKUP_TABLE_ERASE: 0x02, + RWC_SCHEDULER_READ: 0x03, + ERASE_128MB_512MB_FLASH: 0x04, + ERASE_8MB_FLASH_1: 0x05, + ERASE_8MB_FLASH_2: 0x06, + ERASE_OPERATIONAL_CONFIG: 0x07, + ERASE_PRODUCTION_CONFIG: 0x08, + CLEAR_PENDING_EVENTS: 0x09, + ERASE_FLASH_AND_LOOKUP_TABLE: 0x0a, + TEST_DATA_TRANSFER_LOOP: 0x0b, + LOAD_TEST_LOOKUP_TABLE: 0x0c, + LED_TEST: 0x0d, + MAX86XXX_LED_TEST: 0x0e, + CHECK_PAYLOAD_CRC_ERRORS: 0x0f, + READ_EVENT_LOG: 0x10, + POWER_PROFILER_TEST: 0x11, + READ_RECORD_BUFFER_DETAILS: 0x12, + SYSTEM_RESET: 0x13, + IC_POWER_CONSUMPTION_TEST: 0x14, + DELETE_ALL_BONDS: 0x15, + BLE_LINK_PARAMS_READ: 0x16, + BLE_LINK_OPTIMIZE: 0x17, + /** Streamed MAX32674C algorithm-hub firmware (.msbl) upload (factory). The + * byte after this id is a HUB_FW_UPLOAD_STAGE sub-stage. */ + HUB_FW_UPLOAD: 0x18, +}); +/** Sub-stages for the streamed MAX32674C hub firmware upload, carried in the + * payload byte immediately after DEBUG_COMMAND_ID.HUB_FW_UPLOAD. */ +const HUB_FW_UPLOAD_STAGE = Object.freeze({ + BEGIN: 0x00, + PAGE_CHUNK: 0x01, + END: 0x02, + ABORT: 0x03, +}); +/** MAX32674C .msbl image geometry (mirrors firmware flashUpdater.h). A page on + * the wire is PAGE_PAYLOAD + PAGE_CRC bytes; HEADER_SIZE bytes precede page 0. */ +const MSBL = Object.freeze({ + HEADER_SIZE: 0x4c, + OFF_NUMPAGES: 0x44, + PAGE_PAYLOAD: 8192, + PAGE_CRC: 16, + PAGE_FILE_BYTES: 8208, +}); +// --------------------------------------------------------------------------- +// Operational config byte offsets +// --------------------------------------------------------------------------- +/** + * Byte indices into the Verisense operational config blob (`op[OP_IDX.xxx]`). + * Index 0 is the config version byte (must be 0x5A for a valid config). + */ +const OP_IDX = Object.freeze({ + GEN_CFG_0: 1, + GEN_CFG_1: 2, + GEN_CFG_2: 3, + GEN_CFG_3: 4, + ACCEL1_CFG_0: 5, + ACCEL1_CFG_1: 6, + ACCEL1_CFG_2: 7, + ACCEL1_CFG_3: 8, + GYRO_ACCEL2_CFG_0: 10, + GYRO_ACCEL2_CFG_1: 11, + GYRO_ACCEL2_CFG_2: 12, + GYRO_ACCEL2_CFG_3: 13, + GYRO_ACCEL2_CFG_4: 14, + GYRO_ACCEL2_CFG_5: 15, + GYRO_ACCEL2_CFG_6: 16, + GYRO_ACCEL2_CFG_7: 17, + LSM6DSV_CFG_0: 18, + LSM6DSV_CFG_1: 19, + LSM6DSV_CFG_2: 20, + START_TIME: 21, + END_TIME: 25, + INACTIVE_TIMEOUT: 29, + BLE_RETRY_COUNT: 30, + BLE_TX_POWER: 31, + BLE_DATA_TRANS_WKUP_INT_HRS: 32, + BLE_DATA_TRANS_WKUP_TIME: 33, + BLE_DATA_TRANS_WKUP_DUR: 35, + BLE_DATA_TRANS_RETRY_INT: 36, + BLE_STATUS_WKUP_INT_HRS: 38, + BLE_STATUS_WKUP_TIME: 39, + BLE_STATUS_WKUP_DUR: 41, + BLE_STATUS_RETRY_INT: 42, + BLE_RTC_SYNC_WKUP_INT_HRS: 44, + BLE_RTC_SYNC_WKUP_TIME: 45, + BLE_RTC_SYNC_WKUP_DUR: 47, + BLE_RTC_SYNC_RETRY_INT: 48, + ADC_CHANNEL_SETTINGS_0: 50, + ADC_CHANNEL_SETTINGS_1: 51, + ADAPTIVE_SCHEDULER_INT: 52, + ADAPTIVE_SCHEDULER_FAILCOUNT_MAX: 54, + PPG_REC_DUR_SECS_LSB: 55, + PPG_REC_DUR_SECS_MSB: 56, + PPG_REC_INT_MINS_LSB: 57, + PPG_REC_INT_MINS_MSB: 58, + PPG_FIFO_CONFIG: 59, + PPG_MODE_CONFIG2: 60, + PPG_MA_DEFAULT: 61, + PPG_MA_MAX_RED_IR: 62, + PPG_MA_MAX_GREEN_BLUE: 63, + PPG_AGC_TARGET_PERCENT_OF_RANGE: 64, + PPG_MA_LED_PILOT: 66, + PPG_DAC1_CROSSTALK: 67, + PPG_DAC2_CROSSTALK: 68, + PPG_DAC3_CROSSTALK: 69, + PPG_DAC4_CROSSTALK: 70, + PROX_AGC_MODE: 71, + // v9 second-generation sensor settings (only present when op[OP_CONFIG_VERSION] >= 9) + OP_CONFIG_VERSION: 9, + LIGHT_GAIN_INDEX: 72, + LIGHT_EXPOSURE_INDEX: 73, + LIGHT_CONFIG: 74, + LIGHT_SAMPLE_RATE_INDEX: 75, + SKIN_TEMP_CONFIG: 76, + SKIN_TEMP_SAMPLE_RATE_INDEX: 77, + ALGO_OP_MODE: 78, + ALGO_REPORT_MODE_RATE: 79, + ALGO_CONTROL: 80, + ALGO_INITIAL_HR: 81, + LED_AUTO_BRIGHTNESS_CFG: 82, + LED_MAX_BRIGHTNESS: 83, + LED_LUX_THRESHOLD: 84, + // MAX32674 algorithm-suite subject parameters (bytes 86-91) + PERSON_HEIGHT_CM: 86, // u16 LE, cm + PERSON_WEIGHT_KG: 88, // u16 LE, kg + PERSON_AGE: 90, // u8, years + PERSON_GENDER: 91, // u8, 0=Male, 1=Female +}); +/** Operational config layout version stored at OP_IDX.OP_CONFIG_VERSION (byte 9). + * 0 = legacy 72-byte layout; 9 = v9 layout with second-generation sensor settings. */ +const OP_CONFIG_VERSION_V9 = 9; +/** Minimum firmware version that supports the BLE-link debug commands + * (read/optimize connection parameters). */ +const BLE_LINK_MIN_FW = Object.freeze({ + major: 1, + minor: 4, + internal: 23, +}); +/** Human-readable labels for Verisense stream-packet sensor IDs. Each ID maps to + * the device part(s) that produce that stream (some streams interleave several + * physical sensors, e.g. id 6 = LSM6DSV accel + gyro + mag). */ +const VERISENSE_STREAM_SENSOR_LABELS = Object.freeze({ + 1: 'ADC (GSR / Battery)', + 2: 'Accel 1 (LIS2DW12)', + 3: 'Accel 2 + Gyro (LSM6DS3)', + 4: 'PPG (MAX86xxx)', + 6: 'Accel 2 + Gyro + Mag (LSM6DSV + LIS2MDL)', + 7: 'Ambient Light (VD6283)', + 8: 'Algo Hub (MAX32674 — HR + raw PPG)', + 9: 'Skin Temperature (MLX90632)', +}); + +/** Read a 16-bit unsigned integer, little-endian. */ +function u16le$1(b0, b1) { + return (b1 << 8) | b0; +} +/** Format a single byte as an uppercase `0xNN` string. */ +function formatByteAsHex(v) { + return `0x${(v & 0xff).toString(16).toUpperCase().padStart(2, '0')}`; +} +/** Format bytes as `[0xAA, 0xBB, ...]`. */ +function formatByteArrayAsHex(bytes) { + const u8 = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes ?? []); + return `[${Array.from(u8, (b) => formatByteAsHex(Number(b))).join(', ')}]`; +} +/** Parse text containing hex bytes like `0x5A, 00 12` into a Uint8Array. */ +function parseHexByteString(text) { + const matches = String(text ?? '').match(/[0-9a-fA-F]{2}/g) ?? []; + if (!matches.length) { + throw new Error('No hex bytes found. Example: 0x5A, 0x00, 0x12'); + } + return new Uint8Array(matches.map((h) => Number.parseInt(h, 16))); +} +/** + * Compare two firmware version triples. Returns a negative number if `a < b`, + * positive if `a > b`, and 0 if equal. Missing or non-numeric components are + * treated as 0. + */ +function compareVerisenseFirmwareVersion(a, b) { + const aMaj = Number(a?.major) || 0; + const aMin = Number(a?.minor) || 0; + const aInt = Number(a?.internal) || 0; + const bMaj = Number(b?.major) || 0; + const bMin = Number(b?.minor) || 0; + const bInt = Number(b?.internal) || 0; + if (aMaj !== bMaj) + return aMaj - bMaj; + if (aMin !== bMin) + return aMin - bMin; + return aInt - bInt; +} +/** Format a firmware version triple as `"major.minor.internal"`, or `"unknown"` + * when the version is null/undefined. */ +function formatVerisenseFirmwareVersion(v) { + if (!v) + return 'unknown'; + return `${Number(v.major) || 0}.${Number(v.minor) || 0}.${Number(v.internal) || 0}`; +} +/** Human-readable label for a Verisense stream-packet sensor ID, with a + * `"Sensor 0xNN"` hex fallback for unknown IDs. */ +function getVerisenseStreamSensorLabel(sensorId) { + const labels = VERISENSE_STREAM_SENSOR_LABELS; + return labels[sensorId] ?? `Sensor 0x${Number(sensorId).toString(16).toUpperCase()}`; +} +const ASM_PROPERTY_BY_VALUE = new Map(Object.entries(ASM_PROPERTY).map(([name, value]) => [Number(value), name])); +/** Label pending-event property values with both enum name and hex representation. */ +function formatPendingEventProperties(pendingProps) { + const list = Array.isArray(pendingProps) + ? pendingProps + : pendingProps == null + ? [] + : Array.from(pendingProps); + return list.map((prop) => { + const value = Number(prop) & 0xff; + return { + value, + hex: formatByteAsHex(value), + property: ASM_PROPERTY_BY_VALUE.get(value) ?? 'UNKNOWN_PROPERTY', + }; + }); +} +/** Read a signed 16-bit integer at byte offset `off`, little-endian. */ +function i16le(bytes, off) { + const v = bytes[off] | (bytes[off + 1] << 8); + return v & 0x8000 ? v - 0x10000 : v; +} +/** Read a 24-bit unsigned integer at byte offset `off`, little-endian. */ +function u24le(bytes, off) { + return (bytes[off] | (bytes[off + 1] << 8) | (bytes[off + 2] << 16)) >>> 0; +} +/** Read a 16-bit unsigned integer at byte offset `off`, little-endian (full-array form). */ +function u16le_at(bytes, off) { + return (bytes[off] | (bytes[off + 1] << 8)) >>> 0; +} +/** Read a 32-bit IEEE-754 float at byte offset `off`, little-endian. */ +function f32le(bytes, off) { + return new DataView(bytes.buffer, bytes.byteOffset + off, 4).getFloat32(0, true); +} +/** Return current time in milliseconds. */ +function nowMillis() { + return Date.now(); +} +/** + * Compute CRC-16/CCITT-FALSE over `bytes`. + * + * Parameters: poly=0x1021, init=0xFFFF, xorOut=0x0000. + * Matches the C# `ComputeCRC` implementation used by Verisense firmware. + */ +function crc16_ccitt_false(bytes) { + let crc = 0xffff; + for (let i = 0; i < bytes.length; i++) { + crc ^= bytes[i] << 8; + for (let b = 0; b < 8; b++) { + crc = crc & 0x8000 ? (crc << 1) ^ 0x1021 : crc << 1; + crc &= 0xffff; + } + } + return crc & 0xffff; +} +/** + * Extract the CRC that was appended to a logged payload (last 2 bytes, LE). + */ +function getOriginalCrcLE(payload) { + const n = payload.length; + return (payload[n - 2] | (payload[n - 1] << 8)) >>> 0; +} +/** + * Compute the CRC of a logged payload, excluding the trailing 2 CRC bytes, + * matching the C# `ComputeCRC(payload, 0, payload.Length - 2)` call. + */ +function computeCrcLikeCSharp(payload) { + return crc16_ccitt_false(payload.subarray(0, payload.length - 2)); +} +/** + * Convert any reasonable representation of an operational config to a + * `Uint8Array`. Throws if the input type is unrecognised. + */ +function normalizeOperationalConfig(payload) { + if (!payload) + return null; + if (payload instanceof Uint8Array) + return payload; + if (payload instanceof ArrayBuffer) + return new Uint8Array(payload); + if (Array.isArray(payload)) + return new Uint8Array(payload); + if (payload.buffer instanceof ArrayBuffer) { + const p = payload; + return new Uint8Array(p.buffer, p.byteOffset ?? 0, p.byteLength ?? p.buffer.byteLength); + } + throw new Error('normalizeOperationalConfig: unsupported payload type'); +} +/** Alias for arbitrary protocol byte payload normalization. */ +function normalizeBytePayload(payload) { + return normalizeOperationalConfig(payload); +} +/** + * Derive the 6-digit pairing PIN from a Verisense unique identifier. + * + * The PIN is built from digits 2, 4 and 6 (1-based) of the identifier, + * followed by the decimal value of the final byte padded to 3 digits. + */ +function computeVerisensePairingPin(uniqueId) { + const normalized = String(uniqueId ?? '') + .trim() + .replace(/^Verisense-/i, ''); + if (!/^[0-9a-fA-F]{8,}$/.test(normalized)) { + throw new Error('computeVerisensePairingPin: uniqueId must be a hex identifier string'); + } + if (normalized.length < 6) { + throw new Error('computeVerisensePairingPin: uniqueId must be at least 6 hex characters'); + } + const prefix = `${normalized[1]}${normalized[3]}${normalized[5]}`; + const suffixHex = normalized.slice(-2); + const suffixDec = Number.parseInt(suffixHex, 16); + return `${prefix}${suffixDec.toString().padStart(3, '0')}`; +} +/** Infer charger chip family from hardware revision fields in production config. */ +function inferVerisenseChargerChipFamily(revHwMajor, revHwMinor, revHwInternal) { + const major = Number(revHwMajor); + const minor = Number(revHwMinor); + const internal = Number(revHwInternal); + if ((major === 68 && minor === 7 && internal === 1) || (major === 68 && minor === 8)) { + return 'LTC4123'; + } + if (major === 62) { + return 'LM3658D'; + } + if ((major === 68 && minor >= 9) || (major === 61 && minor >= 5)) { + return 'XC6803'; + } + return 'UNKNOWN'; +} +/** Return chip-specific charger status text for a parsed 3-bit status code. */ +function describeVerisenseChargerStatus(chipFamily, statusCode) { + if (statusCode === 7) { + return 'Not read yet'; + } + if (chipFamily === 'LTC4123') { + if (statusCode === 0) { + return 'Zinc-air/reverse polarity/temp out-of-range/UVCL at start of charge cycle'; + } + if (statusCode === 1) { + return 'Powered on/charging'; + } + if (statusCode === 2) { + return 'Charge completed'; + } + if (statusCode === 3) { + return 'No power/not charging'; + } + } + if (chipFamily === 'LM3658D') { + if (statusCode === 0 || statusCode === 3) { + return 'Power-down, charging suspended or interrupted'; + } + if (statusCode === 1) { + return 'Pre-qualification, CC/CV charging, or top-off mode'; + } + if (statusCode === 2) { + return 'Charge completed'; + } + } + if (chipFamily === 'XC6803') { + if (statusCode === 0) { + return 'Fault (overvoltage, overcurrent, shorted battery, etc.)'; + } + if (statusCode === 1) { + return 'Pre-qualification, CC/CV charging, or top-off mode'; + } + if (statusCode === 2) { + return 'Charge completed'; + } + if (statusCode === 3) { + return 'Power-down, charging suspended or interrupted'; + } + if (statusCode === 4) { + return 'Trickle charging'; + } + } + return 'Unknown'; +} +/** Format charger summary text for UIs, e.g. "XC6803: Charge completed". */ +function formatVerisenseChargerStatus(status, hw) { + if (status.chargerPresent == null || + status.chargerStatusCode == null || + !status.chargerStatusName) { + return '-'; + } + if (!status.chargerPresent) { + return 'Not present'; + } + const chipFamily = inferVerisenseChargerChipFamily(hw?.revHwMajor ?? Number.NaN, hw?.revHwMinor ?? Number.NaN, hw?.revHwInternal ?? Number.NaN); + const text = describeVerisenseChargerStatus(chipFamily, Number(status.chargerStatusCode)); + return chipFamily === 'UNKNOWN' ? text : `${chipFamily}: ${text}`; +} +/** Upper bound for a plausible device timestamp (2100-01-01 UTC in unix + * seconds). Values beyond this are uninitialised/garbage bytes, not dates. */ +const VERISENSE_MAX_PLAUSIBLE_UNIX_SECONDS = 4102444800; +/** Format unix seconds as raw + human-readable local datetime for logging. */ +function formatVerisenseUnixAndHuman(unixSeconds) { + const unix = Number(unixSeconds); + if (!Number.isFinite(unix)) { + return { unix, human: 'invalid' }; + } + if (unix <= 0) { + return { unix, human: '1970-01-01 00:00:00 (epoch)' }; + } + if (unix > VERISENSE_MAX_PLAUSIBLE_UNIX_SECONDS) { + return { unix, human: 'not-valid' }; + } + const d = new Date(unix * 1000); + const yyyy = d.getFullYear(); + const mm = String(d.getMonth() + 1).padStart(2, '0'); + const dd = String(d.getDate()).padStart(2, '0'); + const HH = String(d.getHours()).padStart(2, '0'); + const MM = String(d.getMinutes()).padStart(2, '0'); + const SS = String(d.getSeconds()).padStart(2, '0'); + return { + unix, + human: `${yyyy}-${mm}-${dd} ${HH}:${MM}:${SS}`, + }; +} +/** Convert parsed status payload into an object with human-readable timestamps for logs. */ +function formatStatusPayloadForLog(status) { + return { + ...status, + statusTimestamp: formatVerisenseUnixAndHuman(status.statusTimestampSeconds), + lastOkTransfer: formatVerisenseUnixAndHuman(status.lastOkTransferSeconds), + lastFailTransfer: formatVerisenseUnixAndHuman(status.lastFailTransferSeconds), + }; +} +/** Convert parsed scheduler payload into an object with human-readable timestamps for logs. */ +function formatSchedulerPayloadForLog(parsed) { + const out = { + ...parsed, + adaptiveScheduler: undefined, + ltfRetry: undefined, + currentTime: formatVerisenseUnixAndHuman(parsed.currentTimeUnixSeconds), + pendingDataTransfer: formatVerisenseUnixAndHuman(parsed.pendingDataTransferUnixSeconds), + pendingStatus1: formatVerisenseUnixAndHuman(parsed.pendingStatus1UnixSeconds), + pendingRtcSync: formatVerisenseUnixAndHuman(parsed.pendingRtcSyncUnixSeconds), + pendingRetry: formatVerisenseUnixAndHuman(parsed.pendingRetryUnixSeconds), + }; + if (typeof parsed.pendingStatus2UnixSeconds === 'number') { + out.pendingStatus2 = formatVerisenseUnixAndHuman(parsed.pendingStatus2UnixSeconds); + } + if (typeof parsed.ppgMeasurementUnixSeconds === 'number') { + out.ppgMeasurement = formatVerisenseUnixAndHuman(parsed.ppgMeasurementUnixSeconds); + } + if (typeof parsed.stepCounterResetUnixSeconds === 'number') { + out.stepCounterReset = formatVerisenseUnixAndHuman(parsed.stepCounterResetUnixSeconds); + } + if (typeof parsed.sensorInactivityUnixSeconds === 'number') { + out.sensorInactivity = formatVerisenseUnixAndHuman(parsed.sensorInactivityUnixSeconds); + } + if (parsed.adaptiveScheduler) { + out.adaptiveScheduler = { + ...parsed.adaptiveScheduler, + nextTime: formatVerisenseUnixAndHuman(parsed.adaptiveScheduler.nextUnixSeconds), + }; + } + if (parsed.ltfRetry) { + out.ltfRetry = { + ...parsed.ltfRetry, + nextTime: formatVerisenseUnixAndHuman(parsed.ltfRetry.nextUnixSeconds), + }; + } + return out; +} +const PROD_CONFIG_FLAG_DFU_ENABLED = 1 << 0; +const LOG_EVENT_NAMES = { + 0: 'NONE', + 1: 'BATTERY_FALL', + 2: 'BATTERY_RECOVER', + 3: 'WRITE_TO_FLASH_SUCCESS', + 4: 'WRITE_TO_FLASH_FAIL_GENERAL', + 5: 'WRITE_TO_FLASH_FULL', + 6: 'WRITE_TO_FLASH_FAIL_CHECK_ADDR_FREE', + 7: 'WRITE_TO_FLASH_FAIL_LOW_BATT_CHECK_ADDR_FREE', + 8: 'WRITE_TO_FLASH_FAIL_LOW_BATT_FLASH_ON', + 9: 'WRITE_TO_FLASH_FAIL_LOW_BATT_FLASH_WRITE', + 10: 'WRITE_TO_FLASH_FAIL_LOW_BATT_BEFORE_START', + 11: 'USB_PLUGGED_IN_SOFT_DEVICE', + 12: 'USB_PLUGGED_OUT_SOFT_DEVICE', + 13: 'RECORDING_PAUSED', + 14: 'RECORDING_RESUMED', + 15: 'BATTERY_RECOVER_IN_BATT_CHECK_TIMER', + 16: 'TSK_FREE_UP_FLASH', + 17: 'FREE_UP_FLASH_FAIL_LOW_BATT', + 18: 'PAYLOAD_PACKAGING_TASK_SET', + 19: 'PAYLOAD_PACKAGING_FUNCTION_CALL', + 20: 'BATTERY_VOLTAGE', + 21: 'TSK_WRITE_LOOKUP_TBL_CHANGES_TO_EEPROM', + 22: 'LPCOMP_ON', + 23: 'LPCOMP_ON_ALREADY', + 24: 'LPCOMP_OFF', + 25: 'LPCOMP_TRIED_BUT_BATT_LOW', + 26: 'BLE_CONNECTED', + 27: 'BLE_DISCONNECTED', + 28: 'TSK_WRITE_FLASH', + 29: 'PPG_TIMER_START', + 30: 'PAYLOAD_OVERSHOT', + 31: 'ADVERTISING_START', + 32: 'ADVERTISING_STOP', + 33: 'NIMH_BATT_PPG_BLOCKED_BLE_RETRY', + 34: 'NIMH_BATT_PPG_BLOCKED_BLE_ADAPT_SCH', + 35: 'NIMH_BATT_PPG_BLOCKED_BLE_PENDING_EVENTS', + 36: 'NIMH_BATT_BLE_BLOCKED_PPG', + 37: 'USB_PORT_OPEN', + 38: 'USB_PORT_CLOSED', + 39: 'FIFO_INT_SAFETY_CHECK_EVENT_ACCEL1', + 40: 'FIFO_INT_SAFETY_CHECK_EVENT_ACCEL2GYRO', + 41: 'FIFO_INT_SAFETY_CHECK_EVENT_MAX86XXX', + 42: 'FIFO_INT_SAFETY_CHECK_EVENT_MAX3000X', + 43: 'FIFO_INT_SAFETY_CHECK_EVENT_ADC', + 44: 'USB_PLUGGED_IN_PIN_HANDLER', + 45: 'USB_PLUGGED_OUT_PIN_HANDLER', + 46: 'BATTERY_CHARGER_STATUS_BAD_BATTERY', + 47: 'BATTERY_CHARGER_STATUS_CHARGING', + 48: 'BATTERY_CHARGER_STATUS_CHARGING_COMPLETE', + 49: 'BATTERY_CHARGER_STATUS_POWER_DOWN', + 50: 'LTC4123_RECOVERY_ATTEMPT', + 51: 'LTC4123_RECOVERY_GAVE_UP', + 52: 'LTC4123_CHRG_COMPLETE_OVERRIDDEN_BAD_BATT', + // DEV-790 USB enumeration debug events + 53: 'USB_POWER_READY_EVT', + 54: 'USB_USBD_ENABLE_CALLED', + 55: 'USB_USBD_START_CALLED', + 56: 'USB_COM_PORT_DISABLED_ON_DETECT', + 57: 'USB_USBD_STOPPED_EVT', +}; +const LOOKUP_STATUS_NAMES = { + 0: 'Zero', + 1: 'Full', + 2: '2Del', + 3: 'Emty', + 4: 'Bad', + 5: 'NUse', +}; +function u32le_at(bytes, off) { + return (((bytes[off] ?? 0) | + ((bytes[off + 1] ?? 0) << 8) | + ((bytes[off + 2] ?? 0) << 16) | + ((bytes[off + 3] ?? 0) << 24)) >>> + 0); +} +function decodeAsciiTrimFF(bytes) { + let end = bytes.length; + while (end > 0 && bytes[end - 1] === 0xff) + end--; + if (end === 0) + return ''; + return new TextDecoder().decode(bytes.slice(0, end)); +} +/** Convert unix seconds into Verisense 7-byte RTC payload (4-byte minutes + 3-byte ticks). */ +function unixSecondsToAsmRtcBytes(unixSeconds) { + if (!Number.isFinite(unixSeconds) || unixSeconds < 0) { + throw new Error('unixSecondsToAsmRtcBytes: unixSeconds must be a finite positive number'); + } + const minutes = Math.floor(unixSeconds / 60); + const secondsInMinute = unixSeconds - minutes * 60; + const ticks = Math.floor(secondsInMinute * 32768); + return new Uint8Array([ + minutes & 0xff, + (minutes >> 8) & 0xff, + (minutes >> 16) & 0xff, + (minutes >> 24) & 0xff, + ticks & 0xff, + (ticks >> 8) & 0xff, + (ticks >> 16) & 0xff, + ]); +} +/** Convert Verisense 7-byte RTC payload into unix seconds. */ +function asmRtcBytesToUnixSeconds(rtc7) { + if (rtc7.length !== 7) { + throw new Error('asmRtcBytesToUnixSeconds: payload must be exactly 7 bytes'); + } + const minutes = u32le_at(rtc7, 0); + const ticks = u24le(rtc7, 4); + return minutes * 60 + ticks / 32768.0; +} +/** Convert Verisense 8-byte minute counter payload into unix seconds. */ +function asmRtcMinutesBytesToUnixSeconds(minutes8) { + if (minutes8.length !== 8) { + throw new Error('asmRtcMinutesBytesToUnixSeconds: payload must be exactly 8 bytes'); + } + let minutes = 0n; + for (let i = 0; i < 8; i++) { + minutes |= BigInt(minutes8[i]) << BigInt(i * 8); + } + return Number(minutes) * 60; +} +/** + * Build a production configuration payload (56 bytes) from structured options. + * This matches the Python tooling layout used by ASM_BLE.py / ASM_Device.py. + */ +function buildProductionConfigPayload(opts) { + const mo = String(opts.manufacturingOrderNumberHex ?? '').trim(); + const mac = String(opts.macIdHex ?? '').trim(); + if (!/^[0-9a-fA-F]{8}$/.test(mo)) { + throw new Error('buildProductionConfigPayload: manufacturingOrderNumberHex must be 8 hex chars'); + } + if (!/^[0-9a-fA-F]{4}$/.test(mac)) { + throw new Error('buildProductionConfigPayload: macIdHex must be 4 hex chars'); + } + const uniqueBytes = new Uint8Array(6); + uniqueBytes.set(new Uint8Array(mo.match(/../g).map((h) => Number.parseInt(h, 16))), 0); + uniqueBytes.set(new Uint8Array(mac.match(/../g).map((h) => Number.parseInt(h, 16))), 4); + uniqueBytes.reverse(); + const revHwInternal = (opts.revHwInternal ?? 0) & 0xffff; + const revFwInternal = (opts.revFwInternal ?? 0) & 0xffff; + const out = new Uint8Array(56); + out[0] = 0x5a; + out.set(uniqueBytes, 1); + out[7] = opts.revHwMajor & 0xff; + out[8] = opts.revHwMinor & 0xff; + out[9] = opts.revFwMajor & 0xff; + out[10] = opts.revFwMinor & 0xff; + out[11] = revFwInternal & 0xff; + out[12] = (revFwInternal >> 8) & 0xff; + out[13] = revHwInternal & 0xff; + out[14] = (revHwInternal >> 8) & 0xff; + // 0xFF is the "unset" sentinel for the passkey/advertising-name region + // (bytes 15..54). The configFlags byte (55) must NOT be left as 0xFF — its + // bit 0 is PROD_CONFIG_FLAG_DFU_ENABLED, so 0xFF reads as "DFU enabled" and + // disabling DFU would silently have no effect. It is set explicitly below. + out.fill(0xff, 15, 55); + const passkeyId = opts.passkeyId ?? ''; + if (passkeyId.length > 0) { + if (passkeyId.length !== 2) { + throw new Error('buildProductionConfigPayload: passkeyId must be 2 chars when provided'); + } + out.set(new TextEncoder().encode(passkeyId), 15); + } + const passkey = opts.passkey ?? ''; + if (passkey.length > 0) { + if (passkey.length !== 6) { + throw new Error('buildProductionConfigPayload: passkey must be 6 chars when provided'); + } + out.set(new TextEncoder().encode(passkey), 17); + } + const advPrefix = opts.advertisingNamePrefix ?? ''; + if (advPrefix.length > 32) { + throw new Error('buildProductionConfigPayload: advertisingNamePrefix must be <= 32 chars'); + } + if (advPrefix.length > 0) { + out.set(new TextEncoder().encode(advPrefix), 23); + } + // Always set configFlags explicitly (0x01 = DFU enabled on boot, 0x00 = + // disabled). Matches the firmware reference encoding in ASM_Device.py. + out[55] = (opts.dfuEnabled ?? true) ? PROD_CONFIG_FLAG_DFU_ENABLED : 0; + return out; +} +/** Parse production configuration with optional passkey/name/flag fields. */ +function parseProductionConfigPayloadFull(response) { + if (response.length < 11) { + throw new Error('parseProductionConfigPayloadFull: payload must be at least 11 bytes'); + } + const base = parseProductionConfigPayload(response); + const uniqueIdentifier = [...response.slice(1, 7)] + .reverse() + .map((b) => b.toString(16).padStart(2, '0')) + .join('') + .toUpperCase(); + const revHwMajor = response[7] ?? 0; + const revHwMinor = response[8] ?? 0; + const revFwMajor = response[9] ?? 0; + const revFwMinor = response[10] ?? 0; + const revFwInternal = response.length >= 13 ? u16le_at(response, 11) : 0; + const revHwInternal = response.length >= 15 ? u16le_at(response, 13) : 0; + const passkeyId = response.length >= 17 ? decodeAsciiTrimFF(response.slice(15, 17)) : ''; + const passkey = response.length >= 23 ? decodeAsciiTrimFF(response.slice(17, 23)) : ''; + const advertisingNamePrefix = response.length >= 55 ? decodeAsciiTrimFF(response.slice(23, 55)) : ''; + const dfuEnabled = response.length >= 56 ? !!(response[55] & PROD_CONFIG_FLAG_DFU_ENABLED) : true; + return { + ...base, + manufacturingOrderNumber: uniqueIdentifier.slice(0, 8), + macId: uniqueIdentifier.slice(8, 12), + uniqueIdentifier, + revHwMajor, + revHwMinor, + revHwInternal, + revFwMajor, + revFwMinor, + revFwInternal, + passkeyId, + passkey, + advertisingNamePrefix, + dfuEnabled, + }; +} +/** + * Parse STATUS1/STATUS2 payload into a typed object. + * + * This ports the core byte parsing from ASM_Device.parse_status while keeping + * the output concise and UI-friendly. + */ +function parseStatusPayload(response, sourceStatusProperty = 'status1') { + if (response.length < 24) { + throw new Error('parseStatusPayload: payload must be at least 24 bytes'); + } + const uniqueIdentifier = [...response.slice(0, 6)] + .reverse() + .map((b) => b.toString(16).padStart(2, '0')) + .join('') + .toUpperCase(); + const hasTickFields = response.length >= 56; + const hasExtendedCapacity = response.length >= 65; + const statusTimestampSeconds = hasTickFields + ? asmRtcBytesToUnixSeconds(new Uint8Array([...response.slice(6, 10), ...response.slice(34, 37)])) + : u32le_at(response, 6) * 60; + const batteryMilliVolts = u16le_at(response, 10); + const batteryPercent = response[12] ?? 0; + const lastOkTransferSeconds = hasTickFields + ? asmRtcBytesToUnixSeconds(new Uint8Array([...response.slice(13, 17), ...response.slice(37, 40)])) + : u32le_at(response, 13) * 60; + const lastFailTransferSeconds = hasTickFields + ? asmRtcBytesToUnixSeconds(new Uint8Array([...response.slice(17, 21), ...response.slice(40, 43)])) + : u32le_at(response, 17) * 60; + const memoryFreeKb = hasExtendedCapacity + ? (response[21] | (response[22] << 8) | (response[23] << 16) | (response[57] << 24)) >>> 0 + : (response[21] | (response[22] << 8) | (response[23] << 16)) >>> 0; + const memoryCapacityKb = hasExtendedCapacity ? u32le_at(response, 60) : null; + const memoryUsedKb = memoryCapacityKb == null ? null : Math.max(0, memoryCapacityKb - memoryFreeKb); + // Bank breakdown: FULL=syncable data, 2DEL=partially-deleted, BAD=unusable flash. + // Ported from ASM_Device.parse_status. Present in payloads >= 56 bytes. In the + // extended (fw v1.02.102+, payload >= 65 bytes) format the FULL and 2DEL totals + // are split: 3 low bytes at 47-49 / 50-52 plus a high byte appended at offset + // 58 / 59 respectively (mirroring the free-memory split to byte 57). + const hasBankData = response.length >= 56; + let memoryFullBanksKb = null; + let memoryTwoDelBanksKb = null; + let memoryBadBanksKb = null; + if (hasBankData) { + if (hasExtendedCapacity) { + memoryFullBanksKb = + (response[47] | (response[48] << 8) | (response[49] << 16) | (response[58] << 24)) >>> 0; + memoryTwoDelBanksKb = + (response[50] | (response[51] << 8) | (response[52] << 16) | (response[59] << 24)) >>> 0; + memoryBadBanksKb = u32le_at(response, 53); // bytes 53-56 + } + else { + memoryFullBanksKb = (response[47] | (response[48] << 8) | (response[49] << 16)) >>> 0; + memoryTwoDelBanksKb = (response[50] | (response[51] << 8) | (response[52] << 16)) >>> 0; + memoryBadBanksKb = (response[53] | (response[54] << 8) | (response[55] << 16)) >>> 0; + } + } + const batteryFallCounter = response.length >= 26 ? u16le_at(response, 24) : null; + let statusFlags = null; + if (response.length >= 34) { + const f = response[26]; + statusFlags = { + usbPluggedIn: (f & 0x01) !== 0, + recordingPaused: (f & 0x02) !== 0, + flashIsFull: (f & 0x04) !== 0, + powerIsGood: (f & 0x08) !== 0, + adaptiveSchedulerOn: (f & 0x10) !== 0, + dfuServiceOn: (f & 0x20) !== 0, + firstBoot: (f & 0x40) !== 0, + repeatedBatteryMeasurement: (f & 0x80) !== 0, + }; + } + let chargerPresent = null; + let chargerStatusCode = null; + let chargerStatusName = null; + if (hasExtendedCapacity) { + const chargerStatusByte = response[64] ?? 0; + chargerPresent = (chargerStatusByte & 0x01) !== 0; + chargerStatusCode = (chargerStatusByte >> 1) & 0x07; + chargerStatusName = + chargerStatusCode === 0 + ? 'CHARGER_STATUS_BAD_BATTERY' + : chargerStatusCode === 1 + ? 'CHARGER_STATUS_CHARGING' + : chargerStatusCode === 2 + ? 'CHARGER_STATUS_CHARGING_COMPLETE' + : chargerStatusCode === 3 + ? 'CHARGER_STATUS_POWER_DOWN' + : chargerStatusCode === 4 + ? 'CHARGER_STATUS_TRICKLE_CHARGING' + : chargerStatusCode === 7 + ? 'CHARGER_STATUS_NOT_READ' + : 'CHARGER_STATUS_UNKNOWN'; + } + return { + uniqueIdentifier, + sourceStatusProperty, + statusTimestampSeconds, + batteryMilliVolts, + batteryPercent, + lastOkTransferSeconds, + lastFailTransferSeconds, + memoryFreeKb, + memoryCapacityKb, + memoryUsedKb, + memoryFullBanksKb, + memoryTwoDelBanksKb, + memoryBadBanksKb, + statusFlags, + batteryFallCounter, + chargerPresent, + chargerStatusCode, + chargerStatusName, + }; +} +/** Parse scheduler debug response payload from DEBUG_COMMAND_ID.RWC_SCHEDULER_READ. */ +function parseSchedulerDebugPayload(payload) { + if (payload.length < 42) { + throw new Error('parseSchedulerDebugPayload: payload is too short'); + } + let idx = 0; + const currentTimeUnixSeconds = asmRtcBytesToUnixSeconds(payload.slice(idx, idx + 7)); + idx += 7; + const bleControlByte = payload[idx++] ?? 0xff; + const bleControlCounter = bleControlByte === 0x00 + ? 'data-transfer' + : bleControlByte === 0x01 + ? 'status1' + : bleControlByte === 0x02 + ? 'rtc-sync' + : bleControlByte === 0x03 + ? 'status2' + : bleControlByte === 0xff + ? 'never' + : 'unknown'; + const next8 = () => { + const v = asmRtcMinutesBytesToUnixSeconds(payload.slice(idx, idx + 8)); + idx += 8; + return v; + }; + const out = { + currentTimeUnixSeconds, + bleControlCounter, + pendingDataTransferUnixSeconds: next8(), + pendingStatus1UnixSeconds: next8(), + pendingRtcSyncUnixSeconds: next8(), + pendingRetryUnixSeconds: next8(), + retryCount: payload[idx++] ?? 0, + retryOperation: (payload[idx++] ?? 0) === 1 ? 'ble-on' : 'ble-off', + }; + if (payload.length >= idx + 10) { + out.adaptiveScheduler = { + nextUnixSeconds: next8(), + enabled: (payload[idx++] ?? 0) === 1, + syncFailCounter: payload[idx++] ?? 0, + }; + } + if (payload.length >= idx + 11) { + const nextUnixSeconds = next8(); + const op = payload[idx++] ?? 0; + out.ltfRetry = { + nextUnixSeconds, + currentOperation: op === 0 + ? 'flash-write-retry-inactive' + : op === 1 + ? 'short-flash-write-retry' + : op === 2 + ? 'attempt-flash-write' + : op === 3 + ? 'long-flash-write-retry' + : op === 4 + ? 'sensor-paused-until-usb-plug-in' + : 'unknown', + failCounterShort: payload[idx++] ?? 0, + failCounterLong: payload[idx++] ?? 0, + }; + } + if (payload.length >= idx + 8) { + out.pendingStatus2UnixSeconds = next8(); + } + if (payload.length >= idx + 8) { + out.ppgMeasurementUnixSeconds = next8(); + } + if (payload.length >= idx + 8) { + out.stepCounterResetUnixSeconds = next8(); + } + if (payload.length >= idx + 8) { + out.sensorInactivityUnixSeconds = next8(); + } + return out; +} +/** Decode the `optimizationResult` byte from {@link parseBleLinkDebugPayload} + * (see {@link VerisenseBleOptimizationResult} for the bit meanings). */ +function decodeVerisenseBleOptimizationResult(resultByte) { + const mask = Number(resultByte ?? 0) & 0xff; + return { + notConnected: (mask & 0x80) !== 0, + phyRequested: (mask & 0x01) !== 0, + connIntervalRequested: (mask & 0x02) !== 0, + dataLengthRequested: (mask & 0x04) !== 0, + resultMask: mask, + }; +} +/** Parse debug payload from BLE link read/optimize commands. */ +function parseBleLinkDebugPayload(payload) { + if (payload.length < 10) { + throw new Error('parseBleLinkDebugPayload: payload is too short'); + } + const connectionIntervalUnits = u16le_at(payload, 4); + return { + attMtu: u16le_at(payload, 0), + maxDataLength: u16le_at(payload, 2), + connectionIntervalUnits, + connectionIntervalMs: connectionIntervalUnits * 1.25, + txPhy: payload[6] ?? 0, + rxPhy: payload[7] ?? 0, + optimizationResult: payload[8] ?? 0, + isConnected: (payload[9] ?? 0) !== 0, + }; +} +/** Parse debug payload listing bank indexes with bad CRC (2-byte LE entries). */ +function parsePayloadCrcErrorBankIndexes(payload) { + if (payload.length % 2 !== 0) { + throw new Error('parsePayloadCrcErrorBankIndexes: payload length must be even'); + } + const out = []; + for (let i = 0; i < payload.length; i += 2) + out.push(u16le_at(payload, i)); + return out; +} +/** Parse 8-byte debug event-log entries. */ +function parseEventLogPayload(payload) { + if (payload.length % 8 !== 0) { + throw new Error('parseEventLogPayload: payload length must be a multiple of 8'); + } + const out = []; + for (let i = 0; i < payload.length; i += 8) { + const entry = payload.slice(i, i + 8); + const eventId = entry[7]; + if (eventId === 0) + continue; + out.push({ + index: i / 8, + eventId, + eventName: LOG_EVENT_NAMES[eventId] ?? `EVENT_${eventId}`, + timestampUnixSeconds: eventId === 20 ? null : asmRtcBytesToUnixSeconds(entry.slice(0, 7)), + batteryMilliVolts: eventId === 20 ? u24le(entry, 0) : null, + }); + } + return out; +} +/** Parse record-buffer details payload (26-byte current layout, 19-byte legacy layout). */ +function parseRecordBufferDetailsPayload(payload) { + const bytesPerBuffer = payload.length % 26 === 0 ? 26 : payload.length % 19 === 0 ? 19 : 0; + if (!bytesPerBuffer) { + throw new Error('parseRecordBufferDetailsPayload: unsupported payload length'); + } + const out = []; + for (let i = 0; i < payload.length; i += bytesPerBuffer) { + const row = payload.slice(i, i + bytesPerBuffer); + out.push({ + bufferIndex: row[0], + bufferState: row[1], + packagedPayloadIndex: u16le_at(row, 2), + currentByteIndexForSensorData: u16le_at(row, 4), + usedBufferLength: u16le_at(row, 6), + fifoTicks: u16le_at(row, 8), + dataTimestampRwcMinutes: u32le_at(row, 10), + dataTimestampRwcTicks: u24le(row, 14), + temperatureData: u16le_at(row, 17), + dataTimestampUcClockMinutes: bytesPerBuffer >= 23 ? u32le_at(row, 19) : null, + dataTimestampUcClockTicks: bytesPerBuffer >= 26 ? u24le(row, 23) : null, + }); + } + return out; +} +/** + * Infer the lookup-table bank count from a raw debug payload length. The payload + * is 3 bytes per bank, optionally prefixed with a 4-byte head/tail block. + * Returns 0 if the length matches neither layout. + */ +function inferVerisenseLookupBankCount(payloadLen) { + if (!Number.isFinite(payloadLen) || payloadLen <= 0) + return 0; + if (payloadLen >= 4 && (payloadLen - 4) % 3 === 0) + return Math.floor((payloadLen - 4) / 3); + if (payloadLen % 3 === 0) + return Math.floor(payloadLen / 3); + return 0; +} +/** + * Parse lookup-table debug payload entries (3 bytes per bank), with optional + * 4-byte tail/head prefix present in older firmware debug responses. When + * `totalBanks` is omitted it is inferred from the payload length via + * {@link inferVerisenseLookupBankCount}. + */ +function parseLookupTablePayload(payload, totalBanks) { + const bytesPerBank = 3; + const banks = totalBanks ?? inferVerisenseLookupBankCount(payload.length); + const expectedNoHeadTail = banks * bytesPerBank; + const expectedWithHeadTail = expectedNoHeadTail + 4; + let data = payload; + let head = null; + let tail = null; + if (payload.length === expectedWithHeadTail) { + tail = u16le_at(payload, 0); + head = u16le_at(payload, 2); + data = payload.slice(4); + } + else if (payload.length !== expectedNoHeadTail) { + throw new Error(`parseLookupTablePayload: payload length ${payload.length} does not match expected ${expectedNoHeadTail} or ${expectedWithHeadTail}`); + } + const entries = []; + for (let bankIndex = 0; bankIndex < banks; bankIndex++) { + const off = bankIndex * bytesPerBank; + const statusByte = data[off]; + const pendingEepromWrite = (statusByte & 0x80) !== 0; + const statusCode = statusByte & 0x7f; + entries.push({ + bankIndex, + statusCode, + statusName: LOOKUP_STATUS_NAMES[statusCode] ?? 'Unknown', + pendingEepromWrite, + payloadIndex: u16le_at(data, off + 1), + }); + } + return { head, tail, entries }; +} +/** + * Parse the production config response payload into a structured object. + */ +function parseProductionConfigPayload(response) { + const configHeader = response[0]; + const asmid = [...response.slice(1, 7)] + .reverse() + .map((b) => b.toString(16).padStart(2, '0')) + .join(''); + const revHwMajor = response[7]; + const revHwMinor = response[8]; + const revFwMajor = response[9]; + const revFwMinor = response[10]; + const fwInternalArray = response.slice(11, 13); + const revFwInternal = fwInternalArray[0] | (fwInternalArray[1] << 8); + let revHwInternal = 0; + if (response.length >= 15) { + const hwInternalArray = response.slice(13, 15); + if (!isUniformByteArray(hwInternalArray, 0xff)) { + revHwInternal = hwInternalArray[0] | (hwInternalArray[1] << 8); + } + } + return { + hardware: `${revHwMajor}.${revHwMinor}.${revHwInternal}`, + firmware: `${revFwMajor}.${revFwMinor}.${revFwInternal}`, + asmid: asmid.toUpperCase(), + configHeader, + revHwMajor, + revHwMinor, + revHwInternal, + revFwMajor, + revFwMinor, + revFwInternal, + }; +} +/** + * Firmware default passkeys by passkey ID: a production config programmed + * with passkey ID "01" pairs with the fixed PIN "123456". Other IDs have no + * fixed default (ID "00" uses the per-device derived PIN — see + * {@link computeVerisensePairingPin}). + */ +const VERISENSE_DEFAULT_PASSKEY_BY_ID = Object.freeze({ + '01': '123456', +}); +/** The fixed passkey for a passkey ID, or undefined when the ID has none + * (leave the passkey bytes unset in the production config). */ +function defaultVerisensePasskeyForId(passkeyId) { + return VERISENSE_DEFAULT_PASSKEY_BY_ID[String(passkeyId ?? '').trim()]; +} +/** + * Build the name a Verisense sensor advertises over BLE: + * `--` (e.g. "Verisense-01-25112101B10F"). + * Returns null when any part is missing — matches how apps derive the name + * from a parsed production config that may be blank/erased. + */ +function buildVerisenseAdvertisedName(parts) { + const prefix = String(parts.prefix ?? '').trim(); + const passkeyId = String(parts.passkeyId ?? '').trim(); + const uniqueId = String(parts.uniqueId ?? '').trim(); + if (!prefix || !passkeyId || !uniqueId) + return null; + return `${prefix}-${passkeyId}-${uniqueId}`; +} +/** + * Split a Verisense advertised name back into its parts. The unique ID is the + * final `-`-separated token; the passkey ID the token before it; anything + * earlier (which may itself contain `-`) is the prefix. Returns null when the + * name does not have at least three tokens. + */ +function parseVerisenseAdvertisedName(name) { + const tokens = String(name ?? '') + .trim() + .split('-'); + if (tokens.length < 3) + return null; + const uniqueId = tokens[tokens.length - 1]; + const passkeyId = tokens[tokens.length - 2]; + const prefix = tokens.slice(0, -2).join('-'); + if (!prefix || !passkeyId || !uniqueId) + return null; + return { prefix, passkeyId, uniqueId }; +} +/** + * The 4-hex MAC ID from a Verisense advertised name (the advertised name ends + * with the unique ID = manufacturing order + MAC; its last 4 hex chars are + * the MAC ID). Returns null when the tail is not valid hex. + */ +function deriveVerisenseMacIdFromName(name) { + const tail = (String(name ?? '') + .trim() + .split('-') + .pop() ?? '') + .replace(/[^0-9A-Fa-f]/g, '') + .toUpperCase() + .slice(-4); + return /^[0-9A-F]{4}$/.test(tail) ? tail : null; +} +/** + * Short device tag for file names (e.g. "…-B10F-…"): the last 4 hex chars of + * a device unique ID or advertised name. Returns "" when unknown so callers + * can omit it cleanly. + */ +function verisenseDeviceFileTag(idOrName) { + const hex = String(idOrName ?? '').replace(/[^0-9A-Fa-f]/g, ''); + return hex.length >= 4 ? hex.slice(-4).toUpperCase() : ''; +} + +/** + * Verisense sensor-calibration TLV codec. + * + * Mirrors the firmware `asm_calibration.{c,h}` byte format. A calibration "blob" + * is a self-describing block of per-sensor calibration that the device persists, + * exposes over the `CALIBRATION` command, and stamps into every logged payload + * header via a CRC-16 version tag. + * + * Layout (all little-endian): + * + * Global header (12 bytes) + * 0 u16 totalLen (= blob.length - 2) + * 2 u8 calibFormatVersion + * 3 u8 hwVerMajor + * 4 u8 hwVerMinor + * 5 u8 fwVerMajor + * 6 u8 fwVerMinor + * 7 u16 fwVerPatch + * 9 u8 sensorBlockCount + * 10 u16 reserved + * + * Per-sensor block (12-byte header + payload) + * 0 u16 sensorId (calibration-domain id, see {@link CalibSensorId}) + * 2 u8 range/quality (bits[5:0] full-scale index; bits[7:6] calib quality) + * 3 u8 dataLen + * 4 u8[8] ts (0 = default/seeded; RTC time = real per-unit cal) + * 12 payload[dataLen] + * + * IMU payload (60 bytes, float32): bias[3] · sens[3] · align[9] (row-major 3x3) + * + * Calibration math (ASM-DES04 §8): output = K·R·physical + b, so the host + * recovers physical = R⁻¹·K⁻¹·(raw − b). K is the diagonal sensitivity, R the + * rotation into the common ASM axes, b the offset bias. + */ +const SC_CALIB_FORMAT_VERSION = 1; +const SC_GLOBAL_HEADER_BYTES = 12; +const SC_BLOCK_HEADER_BYTES = 12; +const SC_TS_BYTES = 8; +const SC_DATA_LEN_IMU = 60; +/** + * The per-block `range` byte packs the full-scale index in bits [5:0] and a 2-bit + * calibration-quality indicator in bits [7:6]. Lookups/comparisons must use only + * the index (`range & SC_CAL_RANGE_MASK`). Quality has no producer yet (always 0), + * so it is reserved without growing the blob or bumping the format version. + */ +const SC_CAL_RANGE_MASK = 0x3f; +const SC_CAL_QUALITY_SHIFT = 6; +const SC_CAL_QUALITY_MASK = 0x03; +/** Calibration-quality indicator (ST MotionAC / Android sensor-accuracy convention). */ +const CalibQuality = { + UNKNOWN: 0, + POOR: 1, + OK: 2, + GOOD: 3, +}; +/** + * Calibration-domain sensor IDs. Distinct from the data-stream sensor IDs + * (1=ADC, 2=LIS2DW12, 3=LSM6DS3, 4=PPG, 6=LSM6DSV, 7=VD6283, 8=MAX32674, + * 9=MLX90632). These reuse the Shimmer3 `SC_SENSOR_*` values where they exist, + * so accel/gyro/mag can each carry their own calibration even though one + * data-stream id (6) covers all three. + * + * Data-stream → calibration mapping: 6 → {37, 38, 42}, 2 → {39}, 3 → {40, 41}. + */ +const CalibSensorId = { + LSM6DSV_ACCEL: 37, + LSM6DSV_GYRO: 38, + LIS2DW12_ACCEL: 39, + /** 1st-gen LSM6DS3 accel (data-stream id 3). */ + LSM6DS3_ACCEL: 40, + /** 1st-gen LSM6DS3 gyro (data-stream id 3). */ + LSM6DS3_GYRO: 41, + LIS2MDL_MAG: 42, +}; +function parseImuPayload(p) { + return { + bias: [f32le(p, 0), f32le(p, 4), f32le(p, 8)], + sens: [f32le(p, 12), f32le(p, 16), f32le(p, 20)], + align: [ + f32le(p, 24), + f32le(p, 28), + f32le(p, 32), + f32le(p, 36), + f32le(p, 40), + f32le(p, 44), + f32le(p, 48), + f32le(p, 52), + f32le(p, 56), + ], + }; +} +/** Parse a calibration blob into a typed, indexable {@link CalibrationSet}. */ +function parseCalibrationBlob(blob) { + if (blob.length < SC_GLOBAL_HEADER_BYTES) { + throw new Error(`parseCalibrationBlob: blob too short (${blob.length} < ${SC_GLOBAL_HEADER_BYTES})`); + } + const totalLen = u16le_at(blob, 0); + if (totalLen + 2 !== blob.length) { + throw new Error(`parseCalibrationBlob: totalLen ${totalLen} does not match blob.length-2 ${blob.length - 2}`); + } + const formatVersion = blob[2]; + const hwVerMajor = blob[3]; + const hwVerMinor = blob[4]; + const fwVerMajor = blob[5]; + const fwVerMinor = blob[6]; + const fwVerPatch = u16le_at(blob, 7); + const blockCount = blob[9]; + const reserved = u16le_at(blob, 10); + const blocks = []; + let off = SC_GLOBAL_HEADER_BYTES; + for (let i = 0; i < blockCount; i++) { + if (off + SC_BLOCK_HEADER_BYTES > blob.length) { + throw new Error(`parseCalibrationBlob: block ${i} header out of range`); + } + const sensorId = u16le_at(blob, off); + const rangeByte = blob[off + 2]; + const range = rangeByte & SC_CAL_RANGE_MASK; + const quality = (rangeByte >> SC_CAL_QUALITY_SHIFT) & SC_CAL_QUALITY_MASK; + const dataLen = blob[off + 3]; + const ts = blob.slice(off + 4, off + 4 + SC_TS_BYTES); + const payloadStart = off + SC_BLOCK_HEADER_BYTES; + if (payloadStart + dataLen > blob.length) { + throw new Error(`parseCalibrationBlob: block ${i} payload out of range`); + } + const payload = blob.slice(payloadStart, payloadStart + dataLen); + const isDefault = ts.every((b) => b === 0); + const block = { sensorId, range, quality, dataLen, ts, isDefault, payload }; + if (dataLen === SC_DATA_LEN_IMU) { + block.imu = parseImuPayload(payload); + } + blocks.push(block); + off = payloadStart + dataLen; + } + const crc16 = crc16_ccitt_false(blob); + return { + formatVersion, + hwVerMajor, + hwVerMinor, + fwVerMajor, + fwVerMinor, + fwVerPatch, + reserved, + blocks, + crc16, + getImu(sensorId, range) { + const b = blocks.find((x) => x.sensorId === sensorId && x.range === range && x.imu); + return b?.imu ?? null; + }, + }; +} +function serializeImuPayload(imu) { + const out = new Uint8Array(SC_DATA_LEN_IMU); + const dv = new DataView(out.buffer); + for (let i = 0; i < 3; i++) + dv.setFloat32(i * 4, imu.bias[i] ?? 0, true); + for (let i = 0; i < 3; i++) + dv.setFloat32(12 + i * 4, imu.sens[i] ?? 0, true); + for (let i = 0; i < 9; i++) + dv.setFloat32(24 + i * 4, imu.align[i] ?? 0, true); + return out; +} +/** Serialize a calibration set into a blob (inverse of {@link parseCalibrationBlob}). */ +function serializeCalibrationBlob(input) { + const payloads = input.blocks.map((b) => { + if (b.payload) + return b.payload; + if (b.imu) + return serializeImuPayload(b.imu); + throw new Error('serializeCalibrationBlob: each block needs imu or payload'); + }); + let total = SC_GLOBAL_HEADER_BYTES; + for (const p of payloads) + total += SC_BLOCK_HEADER_BYTES + p.length; + const out = new Uint8Array(total); + const dv = new DataView(out.buffer); + dv.setUint16(0, total - 2, true); + out[2] = input.formatVersion ?? SC_CALIB_FORMAT_VERSION; + out[3] = input.hwVerMajor & 0xff; + out[4] = input.hwVerMinor & 0xff; + out[5] = input.fwVerMajor & 0xff; + out[6] = input.fwVerMinor & 0xff; + dv.setUint16(7, input.fwVerPatch & 0xffff, true); + out[9] = input.blocks.length & 0xff; + dv.setUint16(10, (input.reserved ?? 0) & 0xffff, true); + let off = SC_GLOBAL_HEADER_BYTES; + input.blocks.forEach((b, i) => { + const payload = payloads[i]; + dv.setUint16(off, b.sensorId & 0xffff, true); + out[off + 2] = + (b.range & SC_CAL_RANGE_MASK) | + (((b.quality ?? 0) & SC_CAL_QUALITY_MASK) << SC_CAL_QUALITY_SHIFT); + out[off + 3] = payload.length & 0xff; + if (b.ts) + out.set(b.ts.subarray(0, SC_TS_BYTES), off + 4); // else leave zero (default) + out.set(payload, off + SC_BLOCK_HEADER_BYTES); + off += SC_BLOCK_HEADER_BYTES + payload.length; + }); + return out; +} +/** CRC-16/CCITT-FALSE over a serialized blob — the value stamped into payload headers. */ +function calibrationBlobCrc(blob) { + return crc16_ccitt_false(blob); +} +/** + * Apply IMU calibration to a raw tri-axial sample. + * + * physical = align · (K⁻¹ · (raw − bias)) + * + * `bias` (b) is subtracted and `sens` (K, diagonal) divided per axis, then the + * `align` matrix (row-major 3x3) is applied directly to rotate the sensor frame + * into the common ASM frame. With identity `align` and zero `bias` this reduces + * to `raw / sens`. + * + * Convention note: `align` is the directly-applied sensor-frame → ASM-frame + * matrix (= R⁻¹ in ASM-DES04 §8's `output = K·R·physical + b` notation). This + * matches the cloud calibration CSV `rotation_*` columns one-to-one — the CSV + * stores the same applied matrix, row-major — so the sensor-calibration parser + * maps blob → CSV with NO transpose. (Confirmed against a LIS2DW12 sample CSV: + * offset→bias, sensitivity→sens, rotation→align.) + */ +function applyImuCalibration(raw, cal) { + const v0 = (raw[0] - cal.bias[0]) / cal.sens[0]; + const v1 = (raw[1] - cal.bias[1]) / cal.sens[1]; + const v2 = (raw[2] - cal.bias[2]) / cal.sens[2]; + const a = cal.align; + return [ + a[0] * v0 + a[1] * v1 + a[2] * v2, + a[3] * v0 + a[4] * v1 + a[5] * v2, + a[6] * v0 + a[7] * v1 + a[8] * v2, + ]; +} + +/** Build a protocol header byte from command/property nibbles. */ +function buildHeader(command, property) { + return ((command & 0xf0) | (property & 0x0f)) & 0xff; +} +/** Decode a protocol header byte into command/property fields. */ +function parseHeader(header) { + return { + command: (header & 0xf0), + property: (header & 0x0f), + }; +} +/** Build a complete protocol message (header + 16-bit LE payload length + payload bytes). */ +function buildMessage(command, property, payloadBytes = []) { + const payload = payloadBytes instanceof Uint8Array ? payloadBytes : new Uint8Array(payloadBytes); + const out = new Uint8Array(3 + payload.length); + out[0] = buildHeader(command, property); + out[1] = payload.length & 0xff; + out[2] = (payload.length >> 8) & 0xff; + out.set(payload, 3); + return out; +} +// --------------------------------------------------------------------------- +// Streaming-frame framing / resynchronisation +// --------------------------------------------------------------------------- +/** + * Header byte that prefixes every streaming data frame: + * `RESPONSE (0x30) | STREAM_MODE (0x0a) === 0x3A`. + */ +const STREAM_FRAME_HEADER = buildHeader(ASM_COMMAND.RESPONSE, ASM_PROPERTY.STREAM_MODE); +/** Smallest valid streaming payload: sensorId(1) + tick(3) + CRC16(2). */ +const STREAM_FRAME_MIN_PAYLOAD = 6; +/** + * Largest streaming payload we will accept. The firmware packages multi-sample + * sensor records into a single logical frame that is frequently much larger + * than one BLE notification (e.g. ~1.8 kB for an LSM6DSV accel/gyro/mag burst) + * and fragments it across several notifications; the host reassembles them in + * its receive buffer before this scanner runs. The ceiling must therefore cover + * the firmware's largest packaged payload — it mirrors the length-only path's + * `MAX_FRAME_PAYLOAD_LEN` (see VerisenseClient) — not the BLE MTU. It still + * bounds how far a corrupt length field can run before the CRC rejects it + * during resync. + * + * WARNING: do NOT shrink this to an MTU-sized value. A small ceiling silently + * drops every large frame (accel/gyro/mag), because their length exceeds the + * cap and the CRC trailer is never reached — the stream just looks dead. + */ +const STREAM_FRAME_MAX_PAYLOAD = 40000; +const STREAM_SCAN_NEED_MORE = { status: 'need-more' }; +const STREAM_SCAN_INVALID = { status: 'invalid' }; +/** + * Try to read one CRC-validated streaming frame from the front of `buf`. + * + * On the wire a streaming frame is: + * + * ``` + * [0x3A][ len LE (2) ][ sensorId(1) | tick(3) | samples… | CRC16(2) ] + * ``` + * + * where `len` is the payload length **including** the trailing 2-byte CRC, and + * the CRC-16/CCITT-FALSE covers the payload up to (but not including) those last + * 2 bytes — matching the firmware's `crc16_ccitt(buf + 3, len - 2)`. + * + * The framing has no start/sync marker, so the CRC is what makes + * resynchronisation reliable: after a flaky link drops bytes and knocks the + * stream out of alignment, the caller slides one byte at a time and accepts a + * boundary only when its CRC checks out, so misaligned/garbage data can no + * longer masquerade as a valid (but wrong sensor-id) packet. + * + * Returns: + * - `need-more` — too few bytes buffered to decide; wait for the next chunk. + * - `invalid` — the front of the buffer is not a valid frame start; the + * caller should drop one byte and try again. + * - `frame` — a CRC-valid frame; `payload` is the `len`-byte payload (CRC + * trailer included) and `consumed` is `3 + len` bytes to remove. + */ +function scanStreamFrame(buf) { + if (buf.length < 3) + return STREAM_SCAN_NEED_MORE; + if (buf[0] !== STREAM_FRAME_HEADER) + return STREAM_SCAN_INVALID; + const len = (buf[1] | (buf[2] << 8)) >>> 0; + if (len < STREAM_FRAME_MIN_PAYLOAD || len > STREAM_FRAME_MAX_PAYLOAD) { + return STREAM_SCAN_INVALID; + } + if (buf.length < 3 + len) + return STREAM_SCAN_NEED_MORE; + // CRC trailer is the last 2 payload bytes (LE); it covers the payload before it. + const crcAt = 3 + len - 2; + const claimed = (buf[crcAt] | (buf[crcAt + 1] << 8)) >>> 0; + const calc = crc16_ccitt_false(buf.subarray(3, crcAt)); + if (calc !== claimed) + return STREAM_SCAN_INVALID; + return { status: 'frame', payload: buf.slice(3, 3 + len), consumed: 3 + len }; +} +/** Parse a complete protocol message into structured fields. */ +function parseMessage(msg) { + if (msg.length < 3) + throw new Error('Invalid Verisense message: header is incomplete'); + const header = msg[0]; + const payloadLength = u16le$1(msg[1], msg[2]); + if (msg.length !== payloadLength + 3) { + throw new Error(`Invalid Verisense message: length=${payloadLength}, actualPayload=${Math.max(0, msg.length - 3)}`); + } + const { command, property } = parseHeader(header); + return { + header, + command, + property, + payloadLength, + payload: msg.slice(3), + }; +} +function isAckCommand(command) { + return command === ASM_COMMAND.ACK || command === ASM_COMMAND.ACK_NEXT_STAGE; +} +function isNackCommand(command) { + return (command === ASM_COMMAND.NACK_BAD_HEADER_COMMAND || + command === ASM_COMMAND.NACK_BAD_HEADER_PROPERTY || + command === ASM_COMMAND.NACK_GENERIC); +} +/** Convert a pending-events payload (property IDs) into a typed array. */ +function parsePendingEvents(payload) { + const out = []; + for (let i = 0; i < payload.length; i++) + out.push((payload[i] & 0x0f)); + return out; +} + +function pad2(n) { + return Math.trunc(n).toString().padStart(2, '0'); +} +function pad5(n) { + return Math.trunc(n).toString().padStart(5, '0'); +} +function dateToYyMMddHHmmss(date) { + const yy = pad2(date.getUTCFullYear() % 100); + const mm = pad2(date.getUTCMonth() + 1); + const dd = pad2(date.getUTCDate()); + const hh = pad2(date.getUTCHours()); + const min = pad2(date.getUTCMinutes()); + const ss = pad2(date.getUTCSeconds()); + return `${yy}${mm}${dd}_${hh}${min}${ss}`; +} +/** Build a binary upload file name: yyMMdd_HHmmss_00000.bin */ +function buildUploadBinaryFileName(uploadDate, firstPayloadIndex) { + if (!Number.isFinite(firstPayloadIndex) || firstPayloadIndex < 0 || firstPayloadIndex > 0xffff) { + throw new Error('buildUploadBinaryFileName: firstPayloadIndex must be in range 0..65535'); + } + return `${dateToYyMMddHHmmss(uploadDate)}_${pad5(firstPayloadIndex)}.bin`; +} +/** Build parsed CSV file name: yyMMdd_HHmmss_DataSource_00000.csv */ +function buildParsedCsvFileName(startDate, dataSource, firstPayloadIndex) { + if (!dataSource || !String(dataSource).trim()) { + throw new Error('buildParsedCsvFileName: dataSource must be a non-empty string'); + } + if (!Number.isFinite(firstPayloadIndex) || firstPayloadIndex < 0 || firstPayloadIndex > 0xffff) { + throw new Error('buildParsedCsvFileName: firstPayloadIndex must be in range 0..65535'); + } + return `${dateToYyMMddHHmmss(startDate)}_${String(dataSource).trim()}_${pad5(firstPayloadIndex)}.csv`; +} +/** Add duplicate suffix like " (2)" before extension. */ +function applyDuplicateSuffix(fileName, duplicateIndex) { + if (duplicateIndex < 2) { + throw new Error('applyDuplicateSuffix: duplicateIndex must be >= 2'); + } + const idx = fileName.lastIndexOf('.'); + if (idx <= 0) + return `${fileName} (${duplicateIndex})`; + const stem = fileName.slice(0, idx); + const ext = fileName.slice(idx); + return `${stem} (${duplicateIndex})${ext}`; +} +/** Return first non-colliding duplicate name for a target file name. */ +function nextAvailableDuplicateFileName(fileName, existingNames) { + const existing = new Set(existingNames); + if (!existing.has(fileName)) + return fileName; + let i = 2; + while (true) { + const candidate = applyDuplicateSuffix(fileName, i); + if (!existing.has(candidate)) + return candidate; + i++; + } +} +/** Parse first payload index (uint16 LE) from a payload byte array. */ +function getFirstPayloadIndex(payload) { + if (payload.length < 2) { + throw new Error('getFirstPayloadIndex: payload must contain at least 2 bytes'); + } + return u16le_at(payload, 0); +} +/** + * Evaluate whether parsed CSV output should roll to a new file. + * Rules mirror ASM-DES08 split conditions. + */ +function evaluateParsedFileSplit(input) { + const reasons = []; + const prev = input.prevTimestampSec; + const curr = input.currTimestampSec; + // Split when crossing 12:00am or 12:00pm boundaries. + const prevHalfDay = Math.floor(prev / (12 * 60 * 60)); + const currHalfDay = Math.floor(curr / (12 * 60 * 60)); + if (currHalfDay !== prevHalfDay) + reasons.push('midday-midnight-boundary'); + if ((input.prevConfigSignature ?? null) !== (input.currConfigSignature ?? null)) { + reasons.push('config-change'); + } + if (input.expectedDeltaSec != null) { + const tol = Math.max(0, input.timestampToleranceSec ?? 0); + const delta = curr - prev; + if (Math.abs(delta - input.expectedDeltaSec) > tol) { + reasons.push('timestamp-discontinuity'); + } + } + if (input.powerResetDetected) { + reasons.push('power-reset'); + } + return { shouldSplit: reasons.length > 0, reasons }; +} + +const VERISENSE_HW_MAJOR_FRIENDLY_NAMES = { + 61: 'IMU', + 62: 'GSR+', + 64: 'SDK', + 68: 'Pulse+', +}; +function getVerisenseHardwareFriendlyName(revHwMajor) { + return VERISENSE_HW_MAJOR_FRIENDLY_NAMES[revHwMajor] ?? null; +} +/** + * Second-generation Verisense hardware is currently defined as: + * - SR61.5+ + * - SR68.9+ + * - Any future major revision above SR68 + */ +function isVerisenseSecondGenerationHardware(revHwMajor, revHwMinor) { + const major = Number(revHwMajor); + const minor = Number(revHwMinor); + if (!Number.isFinite(major) || !Number.isFinite(minor)) + return false; + if (major > 68) + return true; + if (major === 61 && minor >= 5) + return true; + if (major === 68 && minor >= 9) + return true; + return false; +} +function getVerisenseHardwareCapabilities(revHwMajor, revHwMinor) { + const secondGeneration = isVerisenseSecondGenerationHardware(revHwMajor, revHwMinor); + return { + secondGeneration, + supportsMagnetometer: secondGeneration, + }; +} +/** + * GSR-capable hardware. Mirrors the firmware's authoritative + * `ShimBrd_isGsrSupportedForHwVersion` (shimmer_boards.c): + * - SR62 (any revision) + * - SR61 minor >= 5 + * - SR68 minor >= 5 + * + * Deliberately NOT {@link isVerisenseSecondGenerationHardware}: that predicate + * requires SR68 >= 9, but GSR arrived on the SR68 at minor revision 5. + */ +function isVerisenseGsrSupportedHardware(revHwMajor, revHwMinor) { + const major = Number(revHwMajor); + const minor = Number(revHwMinor); + if (!Number.isFinite(major) || !Number.isFinite(minor)) + return false; + return major === 62 || ((major === 61 || major === 68) && minor >= 5); +} +const VERISENSE_SENSOR_SUPPORT_NONE = { + accel1: false, + gyroAccel2: false, + imuGen2: false, + gsr: false, + ppg: false, + ambientLight: false, + skinTemperature: false, + algorithmHub: false, + ledAutoBrightness: false, +}; +const VERISENSE_SENSOR_SUPPORT_ALL = { + accel1: true, + gyroAccel2: true, + imuGen2: true, + gsr: true, + ppg: true, + ambientLight: true, + skinTemperature: true, + algorithmHub: true, + ledAutoBrightness: true, +}; +/** + * Resolves which sensor blocks a given Verisense hardware revision carries, + * derived from the firmware Model IC matrix + * (verisense-firmware/docs/VERISENSE_MODEL_IC_MATRIX.md). + * + * Unknown / development hardware (e.g. SR64, or any unrecognised major + * revision) reports every block as present so consumers never hide a setting + * they cannot confidently rule out. + */ +function getVerisenseHardwareSensorSupport(revHwMajor, revHwMinor) { + const major = Number(revHwMajor); + const minor = Number(revHwMinor); + if (!Number.isFinite(major) || !Number.isFinite(minor)) { + return { ...VERISENSE_SENSOR_SUPPORT_ALL }; + } + const gen2 = isVerisenseSecondGenerationHardware(major, minor); + switch (major) { + case 61: // Verisense IMU + return gen2 + ? // SR61.5+: LSM6DSV + LIS2MDL, GSR, ambient light, 2xRGB LEDs. + { + ...VERISENSE_SENSOR_SUPPORT_NONE, + imuGen2: true, + gsr: true, + ambientLight: true, + ledAutoBrightness: true, + } + : // SR61.1-4: LIS2DW12 + LSM6DS3 only. + { ...VERISENSE_SENSOR_SUPPORT_NONE, accel1: true, gyroAccel2: true }; + case 62: // Verisense GSR+: LIS2DW12 + LSM6DS3, GSR, analog PPG. + return { + ...VERISENSE_SENSOR_SUPPORT_NONE, + accel1: true, + gyroAccel2: true, + gsr: true, + ppg: true, + }; + case 63: // Verisense PPG: LIS2DW12 + LSM6DS3 + PPG. + return { ...VERISENSE_SENSOR_SUPPORT_NONE, accel1: true, gyroAccel2: true, ppg: true }; + case 68: // Verisense Pulse+ + return gen2 + ? // SR68.9+: full 2nd-gen stack. The LIS2DW12 (accel1) is physically + // present but routed to the algorithm hub and not recorded from, so + // it is treated as unsupported for operational-config purposes. + { + ...VERISENSE_SENSOR_SUPPORT_NONE, + imuGen2: true, + gsr: true, + ppg: true, + ambientLight: true, + skinTemperature: true, + algorithmHub: true, + ledAutoBrightness: true, + } + : // SR68.1-8: LIS2DW12 + PPG; GSR added from SR68.5 (Model IC matrix + + // firmware ShimBrd_isGsrSupportedForHwVersion); skin temperature from + // SR68.7. + { + ...VERISENSE_SENSOR_SUPPORT_NONE, + accel1: true, + ppg: true, + gsr: isVerisenseGsrSupportedHardware(major, minor), + skinTemperature: minor >= 7, + }; + default: + // SR64 (dev board) and any future/unknown major: assume everything. + return { ...VERISENSE_SENSOR_SUPPORT_ALL }; + } +} +function getVerisenseHardwareRevision(source) { + if (!source) + return null; + const major = Number(source.revHwMajor); + const minor = Number(source.revHwMinor); + const internal = Number(source.revHwInternal); + if (!Number.isFinite(major) || !Number.isFinite(minor) || !Number.isFinite(internal)) { + return null; + } + if (major <= 0 || major > 255 || minor < 0 || minor > 255 || internal < 0 || internal > 65535) { + return null; + } + return { + major: Math.trunc(major), + minor: Math.trunc(minor), + internal: Math.trunc(internal), + }; +} +function supportsVerisenseMagnetometer(source) { + const hw = getVerisenseHardwareRevision(source); + if (!hw) + return false; + return getVerisenseHardwareCapabilities(hw.major, hw.minor).supportsMagnetometer; +} +function formatVerisenseHardwareRevision(revHwMajor, revHwMinor, revHwInternal = 0, opts = {}) { + const prefix = opts.prefix ?? 'SR'; + const base = `${prefix}${revHwMajor}.${revHwMinor}.${revHwInternal}`; + if (!opts.includeFriendlyName) + return base; + const friendly = getVerisenseHardwareFriendlyName(revHwMajor); + return friendly ? `${base} (${friendly})` : base; +} +/** + * Battery voltage scaling for streamed ADC battery samples. + * Status responses already contain firmware-scaled battery values and should not use this helper. + */ +function getVerisenseStreamingBatteryVoltageMultiplier(revHwMajor, revHwMinor) { + // SR62 + if (revHwMajor === 62) + return 2.0; + // SR61.5+, SR68.9+, and newer major revisions. + if (isVerisenseSecondGenerationHardware(revHwMajor, revHwMinor)) { + return 2.469; + } + return 1.0; +} + +const VERISENSE_OPERATIONAL_FIELD_SCHEMA = [ + // GEN_CFG_0 + { + key: 'BLUETOOTH_EN', + label: 'Bluetooth', + desc: 'Enable BLE', + kind: 'bit', + index: OP_IDX.GEN_CFG_0, + shift: 4, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'USB_EN', + label: 'USB', + desc: 'Enable USB interface', + kind: 'bit', + index: OP_IDX.GEN_CFG_0, + shift: 3, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + // GEN_CFG_0 bit 2 is unused (was PRIORITISE_LONG_TERM_FLASH, removed in + // DEV-806): never used and never read by the firmware. The bit is left unused + // in the byte layout (free to repurpose); older configs that set it are simply + // ignored. + { + key: 'DEVICE_EN', + label: 'Device', + desc: 'Master device enable', + kind: 'bit', + index: OP_IDX.GEN_CFG_0, + shift: 1, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'RECORDING_EN', + label: 'Recording', + desc: 'Enable recording', + kind: 'bit', + index: OP_IDX.GEN_CFG_0, + shift: 0, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + // GEN_CFG_1 + { + key: 'DATA_COMPRESSION_MODE', + label: 'Data Compression', + desc: '0: Off, 1: ZLIB (future), 2: XZ (future), 3: Reserved', + kind: 'bit', + index: OP_IDX.GEN_CFG_1, + shift: 0, + width: 2, + options: [ + [0, 'Off'], + [1, 'ZLIB (future)'], + [2, 'XZ (future)'], + [3, 'Reserved'], + ], + }, + // GEN_CFG_2/3 + { + key: 'HR_PPG_CHANNEL', + label: 'HR PPG Channel', + desc: 'Default HR channel', + kind: 'bit', + index: OP_IDX.GEN_CFG_2, + shift: 6, + width: 2, + options: [ + [0, 'IR'], + [1, 'RED'], + [2, 'GREEN'], + [3, 'BLUE'], + ], + }, + { + key: 'STEP_COUNT_EN', + label: 'Step Counter', + desc: 'Enable step counter', + kind: 'bit', + index: OP_IDX.GEN_CFG_2, + shift: 5, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'PENDING_EVENTS_SCHEDULER_DISABLED', + label: 'Pending Events Scheduler', + desc: 'Enable/disable pending events scheduler', + kind: 'bit', + index: OP_IDX.GEN_CFG_2, + shift: 4, + width: 1, + options: [ + [0, 'Enabled'], + [1, 'Disabled'], + ], + }, + { + key: 'LOW_BATT_AUTO_STOP_DISABLED', + label: 'Low-Power Auto-Stop', + desc: 'Stop recording and BLE data transfers when the battery drops below the low-power threshold. Disabling keeps the device recording until the battery is exhausted, at the risk of data loss from brown-out.', + kind: 'bit', + index: OP_IDX.GEN_CFG_2, + shift: 3, + width: 1, + options: [ + [0, 'Enabled'], + [1, 'Disabled'], + ], + }, + { + key: 'BATT_TYPE', + label: 'Battery Type', + desc: 'Battery chemistry', + kind: 'bit', + index: OP_IDX.GEN_CFG_2, + shift: 0, + width: 1, + options: [ + [0, 'Zinc-Air'], + [1, 'NiMH'], + ], + }, + { + key: 'MAG_EN', + label: 'Magnetometer', + desc: 'Enable LIS2MDL magnetometer (second-generation hardware)', + kind: 'bit', + index: OP_IDX.GEN_CFG_3, + shift: 2, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'LED_MODE', + label: 'LED Mode', + desc: '0 Off, 1 On, 2 Low-power', + kind: 'bit', + index: OP_IDX.GEN_CFG_3, + shift: 0, + width: 2, + options: [ + [0, 'Off'], + [1, 'On'], + [2, 'Low-power'], + [3, 'Reserved'], + ], + }, + // ACCEL1 + { + key: 'ODR', + label: 'Accel1 ODR', + desc: 'Accel1 sampling rate mode', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_0, + shift: 4, + width: 4, + options: [ + [0, 'Power-down'], + [1, '12.5/1.6 Hz'], + [2, '12.5 Hz'], + [3, '25 Hz'], + [4, '50 Hz'], + [5, '100 Hz'], + [6, '200 Hz'], + [7, '400/200 Hz'], + [8, '800/200 Hz'], + [9, '1600/200 Hz'], + ], + }, + { + key: 'MODE', + label: 'Accel1 Mode', + desc: 'Operating mode', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_0, + shift: 2, + width: 2, + options: [ + [0, 'Low-Power'], + [1, 'High-Performance'], + [2, 'Single conversion'], + [3, 'Reserved'], + ], + }, + { + key: 'LP_MODE', + label: 'Accel1 LP Mode', + desc: 'Low-power sub-mode', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_0, + shift: 0, + width: 2, + options: [ + [0, 'LP1'], + [1, 'LP2'], + [2, 'LP3'], + [3, 'LP4'], + ], + }, + { + key: 'BW_FILT', + label: 'Accel1 BW Filter', + desc: '00 ODR/2, 01 ODR/4, 10 ODR/10, 11 ODR/20', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_1, + shift: 6, + width: 2, + options: [ + [0, 'ODR/2'], + [1, 'ODR/4'], + [2, 'ODR/10'], + [3, 'ODR/20'], + ], + }, + { + key: 'FS', + label: 'Accel1 Range', + desc: 'Full-scale range', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_1, + shift: 4, + width: 2, + options: [ + [0, '+-2g'], + [1, '+-4g'], + [2, '+-8g'], + [3, '+-16g'], + ], + }, + { + key: 'FDS', + label: 'Accel1 FDS', + desc: 'Filtered data selection', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_1, + shift: 3, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'LOW_NOISE', + label: 'Accel1 Low Noise', + desc: 'Low-noise mode', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_1, + shift: 2, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'HP_REF_MODE', + label: 'Accel1 HP Ref Mode', + desc: 'High-pass reference mode', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_2, + shift: 1, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'FMode', + label: 'Accel1 FIFO Mode', + desc: 'LIS2DW12 FIFO mode', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_3, + shift: 5, + width: 3, + options: [ + [0, 'Bypass'], + [1, 'FIFO'], + [2, 'Reserved'], + [3, 'Continuous-to-FIFO'], + [4, 'Bypass-to-Continuous'], + [5, 'Reserved'], + [6, 'Continuous'], + [7, 'Reserved'], + ], + }, + { + key: 'FTH', + label: 'Accel1 FIFO Threshold', + desc: '5-bit threshold (0-31)', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_3, + shift: 0, + width: 5, + min: 0, + max: 31, + }, + // ACCEL2/GYRO + { + key: 'FTH_LSB', + label: 'LSM FIFO Threshold LSB', + desc: 'Lower 8 bits of LSM FIFO threshold', + kind: 'u8', + index: OP_IDX.GYRO_ACCEL2_CFG_0, + min: 0, + max: 255, + }, + { + key: 'TIMER_PEDO_FIFDO_EN', + label: 'Timer/Pedo FIFO Dataset', + desc: 'Include step/timestamp as 4th dataset', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_1, + shift: 7, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'TIMER_PEDO_FIFO_DRDY', + label: 'Timer/Pedo FIFO DRDY', + desc: '0 write by DRDY, 1 disable write at each step', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_1, + shift: 6, + width: 1, + options: [ + [0, 'DRDY'], + [1, 'Step detect'], + ], + }, + { + key: 'FTH_MSB', + label: 'LSM FIFO Threshold MSB', + desc: 'Upper 4 bits of LSM FIFO threshold', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_1, + shift: 0, + width: 4, + min: 0, + max: 15, + }, + { + key: 'DEC_FIFO_GYRO', + label: 'Gyro FIFO Decimation', + desc: 'Decimation factor for gyro', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_2, + shift: 3, + width: 3, + options: [ + [0, 'Not in FIFO'], + [1, 'No decimation'], + [2, 'x2'], + [3, 'x3'], + [4, 'x4'], + [5, 'x8'], + [6, 'x16'], + [7, 'x32'], + ], + }, + { + key: 'DEC_FIFO_XL', + label: 'Accel2 FIFO Decimation', + desc: 'Decimation factor for accel2', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_2, + shift: 0, + width: 3, + options: [ + [0, 'Not in FIFO'], + [1, 'No decimation'], + [2, 'x2'], + [3, 'x3'], + [4, 'x4'], + [5, 'x8'], + [6, 'x16'], + [7, 'x32'], + ], + }, + { + key: 'ODR_FIFO', + label: 'LSM FIFO ODR', + desc: 'FIFO sampling rate', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_3, + shift: 3, + width: 4, + options: [ + [0, 'Disabled'], + [1, '12.5 Hz'], + [2, '26 Hz'], + [3, '52 Hz'], + [4, '104 Hz'], + [5, '208 Hz'], + [6, '416 Hz'], + [7, '833 Hz'], + [8, '1.66 kHz'], + [9, '3.33 kHz'], + [10, '6.66 kHz'], + ], + }, + { + key: 'FIFO_MODE', + label: 'LSM FIFO Mode', + desc: 'FIFO behavior', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_3, + shift: 0, + width: 3, + options: [ + [0, 'Bypass'], + [1, 'FIFO'], + [2, 'Reserved'], + [3, 'Continuous-to-FIFO'], + [4, 'Bypass-to-Continuous'], + [5, 'Reserved'], + [6, 'Continuous'], + [7, 'Reserved'], + ], + }, + { + key: 'ODR_XL', + label: 'Accel2 ODR', + desc: 'Accel2 sampling rate', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_4, + shift: 4, + width: 4, + options: [ + [0, 'Power-down'], + [1, '12.5 Hz'], + [2, '26 Hz'], + [3, '52 Hz'], + [4, '104 Hz'], + [5, '208 Hz'], + [6, '416 Hz'], + [7, '833 Hz'], + [8, '1.66 kHz'], + [9, '3.33 kHz'], + [10, '6.66 kHz'], + ], + }, + { + key: 'FS_XL', + label: 'Accel2 Range', + desc: '00 +-2g, 01 +-16g, 10 +-4g, 11 +-8g', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_4, + shift: 2, + width: 2, + options: [ + [0, '+-2g'], + [1, '+-16g'], + [2, '+-4g'], + [3, '+-8g'], + ], + }, + { + key: 'BW_XL', + label: 'Accel2 BW', + desc: 'Anti-alias filter bandwidth', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_4, + shift: 0, + width: 2, + options: [ + [0, '400 Hz'], + [1, '200 Hz'], + [2, '100 Hz'], + [3, '50 Hz'], + ], + }, + { + key: 'ODR_G', + label: 'Gyro ODR', + desc: 'Gyro sampling rate', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_5, + shift: 4, + width: 4, + options: [ + [0, 'Power-down'], + [1, '12.5 Hz'], + [2, '26 Hz'], + [3, '52 Hz'], + [4, '104 Hz'], + [5, '208 Hz'], + [6, '416 Hz'], + [7, '833 Hz'], + [8, '1.66 kHz'], + ], + }, + { + key: 'FS_G', + label: 'Gyro Range', + desc: 'Gyro full-scale', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_5, + shift: 2, + width: 2, + options: [ + [0, '250 dps'], + [1, '500 dps'], + [2, '1000 dps'], + [3, '2000 dps'], + ], + }, + { + key: 'FS_125', + label: 'Gyro 125 dps', + desc: 'Enable 125 dps full-scale', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_5, + shift: 1, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'G_HM_MODE', + label: 'Gyro High-Performance Mode', + desc: '0 HP enabled, 1 HP disabled', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_6, + shift: 7, + width: 1, + options: [ + [0, 'Enabled'], + [1, 'Disabled'], + ], + }, + { + key: 'HP_G_EN', + label: 'Gyro HPF', + desc: 'Gyro high-pass filter', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_6, + shift: 6, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'HPCF_G', + label: 'Gyro HPF Cutoff', + desc: 'Gyro HPF cutoff frequency', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_6, + shift: 4, + width: 2, + options: [ + [0, '0.0081 Hz'], + [1, '0.0324 Hz'], + [2, '2.07 Hz'], + [3, '16.32 Hz'], + ], + }, + { + key: 'HP_G_RST', + label: 'Gyro HPF Reset', + desc: 'Reset digital HPF', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_6, + shift: 3, + width: 1, + options: [ + [0, 'Off'], + [1, 'On'], + ], + }, + { + key: 'ROUNDING_STATUS', + label: 'Rounding Status', + desc: 'Source register rounding', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_6, + shift: 2, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'LPF2_XL_EN', + label: 'Accel2 LPF2', + desc: 'LPF2 selection', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_7, + shift: 7, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'HPCF_XL', + label: 'Accel2 HP/Slope Cutoff', + desc: 'HPCF_XL bits', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_7, + shift: 5, + width: 2, + min: 0, + max: 3, + }, + { + key: 'HP_SLOPE_XL_EN', + label: 'Accel2 HP/Slope Enable', + desc: 'HP/slope filter selection', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_7, + shift: 2, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'LOW_PASS_ON_6D', + label: 'Low-pass on 6D', + desc: 'Low-pass filter on 6D function', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_7, + shift: 0, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + // LSM6DSV explicit host fields (bytes 18..20) + { + key: 'LSM6DSV_ODR_XL', + label: 'LSM6DSV Accel ODR', + desc: 'Accel ODR (LSM6DSV ODR_XL datasheet register value)', + kind: 'bit', + index: OP_IDX.LSM6DSV_CFG_0, + shift: 0, + width: 4, + options: [ + [0, 'Off'], + [1, '1.875 Hz'], + [2, '7.5 Hz'], + [3, '15 Hz'], + [4, '30 Hz'], + [5, '60 Hz'], + [6, '120 Hz'], + [7, '240 Hz'], + [8, '480 Hz'], + [9, '960 Hz'], + [10, '1920 Hz'], + [11, '3840 Hz'], + [12, '7680 Hz'], + ], + }, + { + key: 'LSM6DSV_FS_XL', + label: 'LSM6DSV Accel Range', + desc: 'Second-gen accel range code', + kind: 'bit', + index: OP_IDX.LSM6DSV_CFG_0, + shift: 4, + width: 2, + options: [ + [0, '+-2g'], + [1, '+-4g'], + [2, '+-8g'], + [3, '+-16g'], + ], + }, + { + key: 'LSM6DSV_ODR_G', + label: 'LSM6DSV Gyro ODR', + desc: 'Gyro ODR (LSM6DSV ODR_G datasheet register value)', + kind: 'bit', + index: OP_IDX.LSM6DSV_CFG_1, + shift: 0, + width: 4, + options: [ + [0, 'Off'], + [1, '1.875 Hz'], + [2, '7.5 Hz'], + [3, '15 Hz'], + [4, '30 Hz'], + [5, '60 Hz'], + [6, '120 Hz'], + [7, '240 Hz'], + [8, '480 Hz'], + [9, '960 Hz'], + [10, '1920 Hz'], + [11, '3840 Hz'], + [12, '7680 Hz'], + ], + }, + { + key: 'LSM6DSV_FS_G', + label: 'LSM6DSV Gyro Range', + desc: 'Gyro range (LSM6DSV FS_G datasheet register value)', + kind: 'bit', + index: OP_IDX.LSM6DSV_CFG_1, + shift: 4, + width: 4, + options: [ + [0, '125 dps'], + [1, '250 dps'], + [2, '500 dps'], + [3, '1000 dps'], + [4, '2000 dps'], + ], + }, + { + key: 'LIS2MDL_ODR', + label: 'Mag Output Rate', + desc: 'Magnetometer output (sensor-hub) rate. Firmware derives the LIS2MDL ODR to keep a fresh sample available. Bounded by the accel/gyro ODR (the sensor-hub trigger).', + kind: 'bit', + index: OP_IDX.LSM6DSV_CFG_2, + shift: 0, + width: 2, + options: [ + [0, '15 Hz (LIS2MDL 20 Hz)'], + [1, '30 Hz (LIS2MDL 50 Hz)'], + [2, '60 Hz (LIS2MDL 100 Hz)'], + [3, '120 Hz (LIS2MDL 100 Hz)'], + ], + }, + // Timing and BLE scheduler + { + key: 'START_TIME', + label: 'Start Time', + desc: '32-bit start time', + kind: 'u32', + index: OP_IDX.START_TIME, + min: 0, + max: 4294967295, + }, + { + key: 'END_TIME', + label: 'End Time', + desc: '32-bit end time', + kind: 'u32', + index: OP_IDX.END_TIME, + min: 0, + max: 4294967295, + }, + { + key: 'INACTIVE_TIMEOUT_MINUTES', + label: 'Inactive Timeout (minutes)', + desc: 'Minutes of no activity before the device stops recording and sleeps. 0 disables inactivity detection.', + kind: 'inactiveMinutes', + index: OP_IDX.INACTIVE_TIMEOUT, + min: 0, + max: 63, + }, + { + key: 'RESUME_REC_ON_ACTIVITY', + label: 'Resume Rec On Activity', + desc: 'Automatically resume recording when activity is detected after an inactivity sleep. Only has an effect when Logging is enabled and the inactive timeout is above 0.', + kind: 'inactiveResume', + index: OP_IDX.INACTIVE_TIMEOUT, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'BLE_CONNECTION_TRIES_PER_DAY', + label: 'Connection Attempts per Wake', + desc: 'Number of connection attempts the device makes each time a sync window opens (applies to all schedules).', + kind: 'u8', + index: OP_IDX.BLE_RETRY_COUNT, + min: 0, + max: 255, + }, + { + key: 'BLE_TX_POWER', + label: 'BLE TX Power', + desc: 'Radio TX power', + kind: 'u8', + index: OP_IDX.BLE_TX_POWER, + options: [ + [0x08, '+8 dBm'], + [0x07, '+7 dBm'], + [0x06, '+6 dBm'], + [0x05, '+5 dBm'], + [0x04, '+4 dBm'], + [0x03, '+3 dBm'], + [0x02, '+2 dBm'], + [0x00, '+0 dBm'], + [0xfc, '-4 dBm'], + [0xf8, '-8 dBm'], + [0xf4, '-12 dBm'], + [0xf0, '-16 dBm'], + [0xec, '-20 dBm'], + [0xd8, '-40 dBm'], + ], + }, + { + key: 'BLE_DATA_TRANS_WKUP_INT_HOURS', + label: 'Data Transfer Wake Interval (hrs)', + desc: 'How often the data-transfer sync runs: 0 = off, 24 = once daily at the sync time, 1–23 = every N hours.', + kind: 'u8', + index: OP_IDX.BLE_DATA_TRANS_WKUP_INT_HRS, + min: 0, + max: 24, + }, + { + key: 'BLE_DATA_TRANS_WKUP_TIME', + label: 'Data Transfer Sync Time', + desc: 'Time of day for the data-transfer sync (minutes since midnight, 0–1439).', + kind: 'u16', + index: OP_IDX.BLE_DATA_TRANS_WKUP_TIME, + min: 0, + max: 1439, + }, + { + key: 'BLE_DATA_TRANS_WKUP_DUR', + label: 'Data Transfer Active Duration (minutes)', + desc: 'Minutes Bluetooth stays active during the data-transfer sync window.', + kind: 'u8', + index: OP_IDX.BLE_DATA_TRANS_WKUP_DUR, + min: 0, + max: 255, + }, + { + key: 'BLE_DATA_TRANS_RETRY_INT', + label: 'Data Transfer Retry Interval (minutes)', + desc: 'Minutes between connection attempts within the data-transfer sync window.', + kind: 'u16', + index: OP_IDX.BLE_DATA_TRANS_RETRY_INT, + min: 0, + max: 1439, + }, + { + key: 'BLE_STATUS_WKUP_INT_HOURS', + label: 'Status Wake Interval (hrs)', + desc: 'How often the status sync runs: 0 = off, 24 = once daily at the sync time, 1–23 = every N hours.', + kind: 'u8', + index: OP_IDX.BLE_STATUS_WKUP_INT_HRS, + min: 0, + max: 24, + }, + { + key: 'BLE_STATUS_WKUP_TIME', + label: 'Status Sync Time', + desc: 'Time of day for the status sync (minutes since midnight, 0–1439).', + kind: 'u16', + index: OP_IDX.BLE_STATUS_WKUP_TIME, + min: 0, + max: 1439, + }, + { + key: 'BLE_STATUS_WKUP_DUR', + label: 'Status Active Duration (minutes)', + desc: 'Minutes Bluetooth stays active during the status sync window.', + kind: 'u8', + index: OP_IDX.BLE_STATUS_WKUP_DUR, + min: 0, + max: 255, + }, + { + key: 'BLE_STATUS_RETRY_INT', + label: 'Status Retry Interval (minutes)', + desc: 'Minutes between connection attempts within the status sync window.', + kind: 'u16', + index: OP_IDX.BLE_STATUS_RETRY_INT, + min: 0, + max: 1439, + }, + { + key: 'BLE_RTC_SYNC_WKUP_INT_HOURS', + label: 'Time Sync Wake Interval (hrs)', + desc: 'How often the time (RTC) sync runs: 0 = off, 24 = once daily at the sync time, 1–23 = every N hours.', + kind: 'u8', + index: OP_IDX.BLE_RTC_SYNC_WKUP_INT_HRS, + min: 0, + max: 24, + }, + { + key: 'BLE_RTC_SYNC_WKUP_TIME', + label: 'Time Sync Time', + desc: 'Time of day for the time (RTC) sync (minutes since midnight, 0–1439).', + kind: 'u16', + index: OP_IDX.BLE_RTC_SYNC_WKUP_TIME, + min: 0, + max: 1439, + }, + { + key: 'BLE_RTC_SYNC_WKUP_DUR', + label: 'Time Sync Active Duration (minutes)', + desc: 'Minutes Bluetooth stays active during the time (RTC) sync window.', + kind: 'u8', + index: OP_IDX.BLE_RTC_SYNC_WKUP_DUR, + min: 0, + max: 255, + }, + { + key: 'BLE_RTC_SYNC_RETRY_INT', + label: 'Time Sync Retry Interval (minutes)', + desc: 'Minutes between connection attempts within the time (RTC) sync window.', + kind: 'u16', + index: OP_IDX.BLE_RTC_SYNC_RETRY_INT, + min: 0, + max: 1439, + }, + // ADC/PPG + { + key: 'ADC_SAMPLE_RATE', + label: 'ADC Sample Rate', + desc: 'ADC sample rate code', + kind: 'bit', + index: OP_IDX.ADC_CHANNEL_SETTINGS_0, + shift: 0, + width: 6, + options: [ + [0, 'Off'], + [1, '32768.0 Hz'], + [2, '16384.0 Hz'], + [3, '8192.0 Hz'], + [4, '6553.6 Hz'], + [5, '4096.0 Hz'], + [6, '3276.8 Hz'], + [7, '2048.0 Hz'], + [8, '1638.4 Hz'], + [9, '1310.72 Hz'], + [10, '1024.0 Hz'], + [11, '819.2 Hz'], + [12, '655.36 Hz'], + [13, '512.0 Hz'], + [14, '409.6 Hz'], + [15, '327.68 Hz'], + [16, '256.0 Hz'], + [17, '204.8 Hz'], + [18, '163.84 Hz'], + [19, '128.0 Hz'], + [20, '102.4 Hz'], + [21, '81.92 Hz'], + [22, '64.0 Hz'], + [23, '51.2 Hz'], + [24, '40.96 Hz'], + [25, '32.0 Hz'], + [26, '25.6 Hz'], + [27, '20.48 Hz'], + [28, '16.0 Hz'], + [29, '12.8 Hz'], + [30, '10.24 Hz'], + [31, '8.0 Hz'], + [32, '6.4 Hz'], + [33, '5.12 Hz'], + [34, '4.0 Hz'], + [35, '3.2 Hz'], + [36, '2.56 Hz'], + [37, '2.0 Hz'], + [38, '1.6 Hz'], + [39, '1.28 Hz'], + [40, '1.0 Hz'], + [41, '0.8 Hz'], + [42, '0.64 Hz'], + ], + }, + { + key: 'ADC_OVERSAMPLE_RATE', + label: 'ADC Oversample', + desc: 'ADC oversampling', + kind: 'bit', + index: OP_IDX.ADC_CHANNEL_SETTINGS_1, + shift: 4, + width: 4, + options: [ + [0, 'Disabled'], + [1, '2x'], + [2, '4x'], + [3, '8x'], + [4, '16x'], + [5, '32x'], + [6, '64x'], + [7, '128x'], + [8, '256x'], + ], + }, + { + key: 'GSR_RANGE_SETTING', + label: 'GSR Range', + desc: 'Selectable GSR range setting', + kind: 'bit', + index: OP_IDX.ADC_CHANNEL_SETTINGS_1, + shift: 0, + width: 3, + options: [ + [0, 'Range 0 (8k-63k or 125uS-15.87uS)'], + [1, 'Range 1 (63k-220k or 15.87uS-4.5uS)'], + [2, 'Range 2 (220k-680k or 4.5uS-1.47uS)'], + [3, 'Range 3 (680k-4.7M or 1.47uS-0.21uS)'], + [4, 'Auto-Range'], + ], + }, + { + key: 'ADAPTIVE_SCHEDULER_FAILCOUNT_MAX', + label: 'Fallback Trigger (missed syncs)', + desc: 'Consecutive missed sync windows before the adaptive fallback turns on and starts retrying more often. Typical 2–3. 0 disables the fallback.', + kind: 'u8', + // Max is the full u8 range: the firmware disabled sentinel is 0xFF, and the + // encoder clamps to max — a tighter cap would corrupt a disabled config. + index: OP_IDX.ADAPTIVE_SCHEDULER_FAILCOUNT_MAX, + min: 0, + max: 255, + }, + { + key: 'ADAPTIVE_SCHEDULER_INTERVAL', + label: 'Fallback Retry Interval (minutes)', + desc: 'Once the fallback is on, minutes between extra BLE retry wakes. Typical ≈426 (about 7 hours). 0 (or 65535) disables the fallback.', + kind: 'u16', + // Max is the full u16 range: the firmware disabled sentinel is 0xFFFF, and + // the encoder clamps to max — a tighter cap would corrupt a disabled config. + index: OP_IDX.ADAPTIVE_SCHEDULER_INT, + min: 0, + max: 65535, + }, + { + key: 'PPG_REC_DUR_SECS', + label: 'PPG Record Duration (s)', + desc: '0 = always on', + kind: 'u16', + index: OP_IDX.PPG_REC_DUR_SECS_LSB, + min: 0, + max: 65535, + }, + { + key: 'PPG_REC_INT_MINS', + label: 'PPG Record Interval (minutes)', + desc: '0 = always on', + kind: 'u16', + index: OP_IDX.PPG_REC_INT_MINS_LSB, + min: 0, + max: 65535, + }, + { + key: 'SMP_AVE', + label: 'PPG Sample Averaging', + desc: 'FIFO sample averaging', + kind: 'bit', + index: OP_IDX.PPG_FIFO_CONFIG, + shift: 5, + width: 3, + options: [ + [0, '1'], + [1, '2'], + [2, '4'], + [3, '8'], + [4, '16'], + [5, '32'], + [6, '32'], + [7, '32'], + ], + }, + { + key: 'PPG_ADC_RGE', + label: 'PPG ADC Range', + desc: 'ADC range / full-scale', + kind: 'bit', + index: OP_IDX.PPG_MODE_CONFIG2, + shift: 5, + width: 2, + options: [ + [0, '7.8125 / 4096'], + [1, '15.625 / 8192'], + [2, '31.25 / 16384'], + [3, '62.5 / 32768'], + ], + }, + { + key: 'PPG_SR', + label: 'PPG Sample Rate', + desc: 'PPG sample rate', + kind: 'bit', + index: OP_IDX.PPG_MODE_CONFIG2, + shift: 2, + width: 3, + options: [ + [0, '50 Hz'], + [1, '100 Hz'], + [2, '200 Hz'], + [3, '400 Hz'], + [4, '800 Hz'], + [5, '1000 Hz'], + [6, '1600 Hz'], + [7, '3200 Hz'], + ], + }, + { + key: 'PPG_LED_PW', + label: 'PPG LED Pulse Width', + desc: '50/100/200/400 us', + kind: 'bit', + index: OP_IDX.PPG_MODE_CONFIG2, + shift: 0, + width: 2, + options: [ + [0, '50 us'], + [1, '100 us'], + [2, '200 us'], + [3, '400 us'], + ], + }, + { + key: 'PPG_MA_DEFAULT', + label: 'PPG MA Default', + desc: 'Default LED current (mA)', + kind: 'u8', + index: OP_IDX.PPG_MA_DEFAULT, + min: 0, + max: 255, + }, + { + key: 'PPG_MA_MAX_RED_IR', + label: 'PPG MA Max Red/IR', + desc: 'Max current for Red/IR (mA)', + kind: 'u8', + index: OP_IDX.PPG_MA_MAX_RED_IR, + min: 0, + max: 255, + }, + { + key: 'PPG_MA_MAX_GREEN_BLUE', + label: 'PPG MA Max Green/Blue', + desc: 'Max current for Green/Blue (mA)', + kind: 'u8', + index: OP_IDX.PPG_MA_MAX_GREEN_BLUE, + min: 0, + max: 255, + }, + { + key: 'PPG_AGC_TARGET_PERCENT_OF_RANGE', + label: 'PPG AGC Target %', + desc: 'AGC target percent of range', + kind: 'u8', + index: OP_IDX.PPG_AGC_TARGET_PERCENT_OF_RANGE, + min: 0, + max: 100, + }, + { + key: 'PPG_UNUSED_BYTE', + label: 'PPG Unused Byte', + desc: 'Reserved', + kind: 'u8', + index: 65, + min: 0, + max: 255, + }, + { + key: 'PPG_MA_LED_PILOT', + label: 'PPG MA LED Pilot', + desc: 'Pilot/proximity LED current', + kind: 'u8', + index: OP_IDX.PPG_MA_LED_PILOT, + min: 0, + max: 255, + }, + { + key: 'XTALK_DAC1', + label: 'PPG DAC1 Crosstalk', + desc: '5-bit value', + kind: 'u8', + index: OP_IDX.PPG_DAC1_CROSSTALK, + min: 0, + max: 31, + }, + { + key: 'XTALK_DAC2', + label: 'PPG DAC2 Crosstalk', + desc: '5-bit value', + kind: 'u8', + index: OP_IDX.PPG_DAC2_CROSSTALK, + min: 0, + max: 31, + }, + { + key: 'XTALK_DAC3', + label: 'PPG DAC3 Crosstalk', + desc: '5-bit value', + kind: 'u8', + index: OP_IDX.PPG_DAC3_CROSSTALK, + min: 0, + max: 31, + }, + { + key: 'XTALK_DAC4', + label: 'PPG DAC4 Crosstalk', + desc: '5-bit value', + kind: 'u8', + index: OP_IDX.PPG_DAC4_CROSSTALK, + min: 0, + max: 31, + }, + { + key: 'PROX_AGC_MODE', + label: 'Proximity/AGC Mode', + desc: '0 Disabled, 1 Driver approach, 2 Hybrid', + kind: 'u8', + index: OP_IDX.PROX_AGC_MODE, + options: [ + [0, 'AGC Off / Prox Off'], + [1, 'AGC On / Driver Prox'], + [2, 'AGC On / Hybrid Prox'], + ], + }, + // ------------------------------------------------------------------------- + // v9 second-generation sensor settings (light / skin-temp / algo-hub / LED) + // ------------------------------------------------------------------------- + // OP_CONFIG_VERSION (byte 9) is an internal layout marker, not a user setting. + // It is auto-stamped on serialize (see VERISENSE_OP_CONFIG_VERSION_V9 / + // createBlankVerisenseOperationalConfig), so it is intentionally NOT an + // editable field here. + // AMBIENT_LIGHT_EN / SKIN_TEMP_EN / ALGO_HUB_EN are sensor enables and are + // rendered as checkboxes (see VERISENSE_SENSOR_ENABLE_FIELDS), not here. + // GEN_CFG_3 bit 6 is reserved (was PPG_VIA_HUB): the MAX86176 is hardwired to + // the hub, so raw PPG always arrives under the PPG sensor id (4) when a PPG + // channel is enabled, and the algorithm output under id 8 when ALGO_HUB_EN is + // set - no routing bit is needed. + { + key: 'LIGHT_GAIN_INDEX', + label: 'Light Gain', + // Default index 0 = 1.0x, matching the VD6283 reference example + // (SetGain(..., 256), i.e. the 8.8 value 0x0100). + desc: 'VD6283 channel gain (default 1.0x)', + kind: 'u8', + index: OP_IDX.LIGHT_GAIN_INDEX, + min: 0, + max: 7, + options: [ + [0, '1.0x'], + [1, '1.67x'], + [2, '2.5x'], + [3, '5.0x'], + [4, '10.0x'], + [5, '25.0x'], + [6, '50.0x'], + [7, '66.67x'], + ], + }, + { + key: 'LIGHT_EXPOSURE_INDEX', + label: 'Light Exposure', + // Default index 0 = 100 ms (100000 us), matching the VD6283 reference + // example (SetExposureTime(..., 100000)). + desc: 'VD6283 exposure / integration time (default 100 ms). The chip cannot sample faster than it integrates, so the exposure caps the achievable sample rate at ~1/exposure (shown per option). Picking a higher sample rate therefore requires a shorter exposure.', + kind: 'u8', + index: OP_IDX.LIGHT_EXPOSURE_INDEX, + min: 0, + max: 7, + // Label suffix = max sample rate this exposure allows (≈ 1/exposure, capped + // at the 20 Hz poll ceiling). + options: [ + [0, '100 ms (max 10 Hz)'], + [1, '1.6 ms (max 20 Hz)'], + [2, '6.4 ms (max 20 Hz)'], + [3, '12.8 ms (max 20 Hz)'], + [4, '25.6 ms (max 20 Hz)'], + [5, '51.2 ms (max ~19 Hz)'], + [6, '102.4 ms (max ~9.8 Hz)'], + [7, '204.8 ms (max ~4.9 Hz)'], + ], + }, + // LIGHT_CONFIG bit 0 (continuous mode) is intentionally NOT exposed: the + // VD6283 must run in continuous mode for the timer-driven poll to read it, so + // the firmware hardcodes it. The op-config bit is left unused (free to + // repurpose). + { + key: 'LIGHT_DARK_ENABLE', + label: 'Light Dark Channel', + desc: 'Replace the visible/clear channel reading with the dark (covered-photodiode) baseline', + kind: 'bit', + index: OP_IDX.LIGHT_CONFIG, + shift: 1, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'LIGHT_FLICKER_EN', + label: 'Light Flicker Detect', + desc: 'RESERVED: VD6283 flicker detection (host PDM path pending nRF SDK v17 — not yet active)', + kind: 'bit', + index: OP_IDX.LIGHT_CONFIG, + shift: 2, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled (reserved)'], + ], + }, + { + key: 'LIGHT_SAMPLE_RATE_INDEX', + label: 'Light Sample Rate', + desc: 'Ambient-light sample rate. The firmware sets the VD6283 inter-measurement (continuous-mode) cadence to this period, so the sensor measures only as often as it is read and idles in between for lower power. The rate is limited by the exposure time (the chip cannot measure faster than it integrates): 20 Hz needs exposure ≤ 50 ms, 10 Hz needs ≤ 100 ms, etc. — see the Light Exposure options.', + kind: 'u8', + index: OP_IDX.LIGHT_SAMPLE_RATE_INDEX, + min: 0, + max: 6, + options: [ + [0, 'Off'], + [1, '0.5 Hz'], + [2, '1 Hz'], + [3, '2 Hz'], + [4, '5 Hz'], + [5, '10 Hz'], + [6, '20 Hz'], + ], + }, + { + key: 'SKIN_TEMP_MEAS_TYPE', + label: 'Skin Temp Mode', + desc: 'MLX90632 measurement type (default Medical for skin/body temperature)', + kind: 'bit', + index: OP_IDX.SKIN_TEMP_CONFIG, + shift: 0, + width: 1, + options: [ + [0, 'Medical (25–42.5 °C, ±0.2 °C)'], + [1, 'Extended (wider range, lower accuracy)'], + ], + }, + { + // Single skin-temp rate setting. Stored as the MLX90632 refresh-rate code + // (byte 76 bits 3:1); the firmware sets the chip refresh AND derives the read + // poll from it. Shown as the *medical* output rate (= refresh ÷ 2; extended + // mode is ÷ 3). The legacy poll field (byte 77) and power-mode bits (byte 76 + // bits 5:4) are now unused (free to repurpose) — continuous mode is required + // and set automatically. + key: 'SKIN_TEMP_SAMPLE_RATE', + label: 'Skin Temp Sample Rate', + desc: 'MLX90632 sample rate (medical output = chip refresh ÷2; extended ÷3). Drives both the chip refresh and the read poll.', + kind: 'bit', + index: OP_IDX.SKIN_TEMP_CONFIG, + shift: 1, + width: 3, + options: [ + [0, '0.25 Hz'], + [1, '0.5 Hz'], + [2, '1 Hz'], + [3, '2 Hz'], + [4, '4 Hz'], + [5, '8 Hz'], + [6, '16 Hz'], + [7, '32 Hz'], + ], + }, + { + key: 'ALGO_OP_MODE', + label: 'Algo Operation Mode', + desc: 'MAX32674 sensor-hub operation mode', + kind: 'u8', + index: OP_IDX.ALGO_OP_MODE, + min: 0, + max: 5, + options: [ + [0, 'Raw'], + [1, 'WHRM (HR)'], + [3, 'IRN'], + [4, 'HRV'], + [5, 'RR'], + ], + }, + { + key: 'ALGO_REPORT_MODE', + label: 'Algo Report Mode', + desc: 'Sensor-hub report mode', + kind: 'bit', + index: OP_IDX.ALGO_REPORT_MODE_RATE, + shift: 0, + width: 2, + options: [ + [1, 'Basic'], + [2, 'Extended'], + ], + }, + { + key: 'ALGO_REPORT_PERIOD', + label: 'Algo Report Period', + desc: 'Sensor-hub report period code', + kind: 'bit', + index: OP_IDX.ALGO_REPORT_MODE_RATE, + shift: 2, + width: 6, + }, + { + key: 'ALGO_AEC_ENABLE', + label: 'Algo Auto Exposure Control (AEC)', + desc: 'Enable the WHRM/SpO2 automatic exposure control (AEC) loop for the optical PPG AFE. Not related to ECG.', + kind: 'bit', + index: OP_IDX.ALGO_CONTROL, + shift: 0, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'ALGO_SCD_ENABLE', + label: 'Algo Skin Contact Detect', + desc: 'Enable skin-contact detection', + kind: 'bit', + index: OP_IDX.ALGO_CONTROL, + shift: 1, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'ALGO_AUTO_PD_ENABLE', + label: 'Algo Auto PD Current', + desc: 'Enable automatic photodiode current control', + kind: 'bit', + index: OP_IDX.ALGO_CONTROL, + shift: 2, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'ALGO_INITIAL_HR', + label: 'Algo Initial HR', + desc: 'Optional WHRM initial heart-rate seed (bpm, 0 = none)', + kind: 'u8', + index: OP_IDX.ALGO_INITIAL_HR, + min: 0, + max: 255, + }, + { + key: 'LED_AUTO_BRIGHTNESS_ENABLE', + label: 'LED Auto-Brightness', + desc: 'Drive RGB LED brightness from ambient light', + kind: 'bit', + index: OP_IDX.LED_AUTO_BRIGHTNESS_CFG, + shift: 0, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'LED_MAX_BRIGHTNESS', + label: 'LED Max Brightness', + desc: 'Ceiling for auto-brightness mode (0-255)', + kind: 'u8', + index: OP_IDX.LED_MAX_BRIGHTNESS, + min: 0, + max: 255, + }, + { + key: 'LED_LUX_THRESHOLD', + label: 'LED Lux Threshold', + desc: 'Below this ambient level the LED stays at max brightness', + kind: 'u16', + index: OP_IDX.LED_LUX_THRESHOLD, + min: 0, + max: 65535, + }, + { + key: 'PERSON_HEIGHT_CM', + label: 'Height', + desc: 'Subject height for the MAX32674 algorithm suite (cm)', + kind: 'u16', + index: OP_IDX.PERSON_HEIGHT_CM, + min: 50, + max: 250, + }, + { + key: 'PERSON_WEIGHT_KG', + label: 'Weight', + desc: 'Subject weight for the MAX32674 algorithm suite (kg)', + kind: 'u16', + index: OP_IDX.PERSON_WEIGHT_KG, + min: 10, + max: 300, + }, + { + key: 'PERSON_AGE', + label: 'Age', + desc: 'Subject age for the MAX32674 algorithm suite (years)', + kind: 'u8', + index: OP_IDX.PERSON_AGE, + min: 0, + max: 120, + }, + { + key: 'PERSON_GENDER', + label: 'Gender', + desc: 'Subject gender for the MAX32674 algorithm suite', + kind: 'u8', + index: OP_IDX.PERSON_GENDER, + min: 0, + max: 1, + options: [ + [0, 'Male'], + [1, 'Female'], + ], + }, +]; +const VERISENSE_OP_CONFIG_BYTE_SIZE = 92; +function createBlankVerisenseOperationalConfig(byteSize = VERISENSE_OP_CONFIG_BYTE_SIZE) { + const blank = new Uint8Array(byteSize); + blank[0] = 0x5a; + // Stamp the layout version so v9-sized configs are recognised as second-gen. + if (byteSize >= VERISENSE_OP_CONFIG_BYTE_SIZE) { + blank[OP_IDX.OP_CONFIG_VERSION] = OP_CONFIG_VERSION_V9; + // Seed the MAX32674 subject parameters with the Maxim algorithm defaults + // (height 175 cm, weight 78 kg, age 30 yr, gender Male) so the UI shows + // sane values rather than blanks. u16 fields are little-endian. + blank[OP_IDX.PERSON_HEIGHT_CM] = 175 & 0xff; + blank[OP_IDX.PERSON_HEIGHT_CM + 1] = (175 >> 8) & 0xff; + blank[OP_IDX.PERSON_WEIGHT_KG] = 78 & 0xff; + blank[OP_IDX.PERSON_WEIGHT_KG + 1] = (78 >> 8) & 0xff; + blank[OP_IDX.PERSON_AGE] = 30; + blank[OP_IDX.PERSON_GENDER] = 0; + } + return blank; +} +function clampInt(v, min, max) { + const n = Math.trunc(Number(v)); + if (!Number.isFinite(n)) + return min; + return Math.max(min, Math.min(max, n)); +} +function readVerisenseOperationalFieldValue(op, field) { + if (field.kind === 'bit') { + const width = field.width ?? 1; + const shift = field.shift ?? 0; + const mask = (1 << width) - 1; + return (op[field.index] >> shift) & mask; + } + if (field.kind === 'u8') + return op[field.index] & 0xff; + if (field.kind === 'u16') { + return (op[field.index] & 0xff) | ((op[field.index + 1] & 0xff) << 8); + } + if (field.kind === 'u32') { + return (((op[field.index] & 0xff) | + ((op[field.index + 1] & 0xff) << 8) | + ((op[field.index + 2] & 0xff) << 16) | + ((op[field.index + 3] & 0xff) << 24)) >>> + 0); + } + if (field.kind === 'inactiveResume') { + return op[field.index] & (0x01 << 6) ? 1 : 0; + } + if (field.kind === 'inactiveMinutes') { + return op[field.index] & 0x3f; + } + return 0; +} +function writeVerisenseOperationalFieldValue(op, field, rawValue) { + if (field.kind === 'bit') { + const width = field.width ?? 1; + const shift = field.shift ?? 0; + const mask = (1 << width) - 1; + const value = clampInt(rawValue, 0, mask); + op[field.index] = (op[field.index] & ~(mask << shift)) | ((value & mask) << shift); + return; + } + if (field.kind === 'u8') { + op[field.index] = clampInt(rawValue, field.min ?? 0, field.max ?? 255) & 0xff; + return; + } + if (field.kind === 'u16') { + const value = clampInt(rawValue, field.min ?? 0, field.max ?? 65535); + op[field.index] = value & 0xff; + op[field.index + 1] = (value >> 8) & 0xff; + return; + } + if (field.kind === 'u32') { + const value = clampInt(rawValue, field.min ?? 0, field.max ?? 4294967295) >>> 0; + op[field.index] = value & 0xff; + op[field.index + 1] = (value >> 8) & 0xff; + op[field.index + 2] = (value >> 16) & 0xff; + op[field.index + 3] = (value >> 24) & 0xff; + return; + } + if (field.kind === 'inactiveResume') { + const enabled = clampInt(rawValue, 0, 1) === 1; + op[field.index] = enabled ? op[field.index] | (0x01 << 6) : op[field.index] & -65; + return; + } + if (field.kind === 'inactiveMinutes') { + const minutes = clampInt(rawValue, field.min ?? 0, field.max ?? 63) & 0x3f; + op[field.index] = (op[field.index] & 0xc0) | minutes; + } +} +function setVerisenseOperationalBitRange(op, index, shift, width, rawValue) { + const mask = (1 << width) - 1; + const value = clampInt(rawValue, 0, mask); + op[index] = (op[index] & ~(mask << shift)) | ((value & mask) << shift); +} +/** GEN_CFG_0 bit masks for the two host comms channels (see byte map / firmware + * ASM_definitions.h). */ +const GEN_CFG_0_BLUETOOTH_EN_MASK = 1 << 4; +const GEN_CFG_0_USB_EN_MASK = 1 << 3; +/** + * Enforce the USB/Bluetooth comms-channel interlock on an operational-config + * buffer. + * + * A Verisense must never be configured with BOTH Bluetooth and USB disabled, or + * it becomes unreachable for reconfiguration (the radio is the only wireless way + * back in, and disabling USB removes the wired fallback). If a config has both + * `BLUETOOTH_EN` and `USB_EN` cleared, this forces BOTH back on. + * + * This mirrors the firmware safeguard (`enforceCommsChannelInterlock` in + * `ASM_Production/main.c`, applied on config write and parse). Enforcing it here + * in the SDK means any consuming application is protected — a device can't be + * stranded by a third-party tool writing 0/0. + * + * Mutates `op` in place. Returns `true` if a correction was applied. + */ +function enforceVerisenseCommsChannelInterlock(op) { + if (!op || op.length <= OP_IDX.GEN_CFG_0) + return false; + const genCfg0 = op[OP_IDX.GEN_CFG_0]; + const bothDisabled = (genCfg0 & GEN_CFG_0_BLUETOOTH_EN_MASK) === 0 && (genCfg0 & GEN_CFG_0_USB_EN_MASK) === 0; + if (!bothDisabled) + return false; + op[OP_IDX.GEN_CFG_0] = genCfg0 | GEN_CFG_0_BLUETOOTH_EN_MASK | GEN_CFG_0_USB_EN_MASK; + return true; +} +const VERISENSE_SENSOR_ENABLE_FIELDS = [ + { key: 'ACCEL_1_EN', index: OP_IDX.GEN_CFG_0, shift: 7 }, + { key: 'ACCEL_2_EN', index: OP_IDX.GEN_CFG_0, shift: 6 }, + { key: 'GYRO_EN', index: OP_IDX.GEN_CFG_0, shift: 5 }, + { key: 'MAG_EN', index: OP_IDX.GEN_CFG_3, shift: 2 }, + { key: 'GSR_EN', index: OP_IDX.GEN_CFG_1, shift: 7 }, + { key: 'PPG_GREEN_EN', index: OP_IDX.GEN_CFG_1, shift: 6 }, + { key: 'PPG_RED_EN', index: OP_IDX.GEN_CFG_1, shift: 5 }, + { key: 'PPG_IR_EN', index: OP_IDX.GEN_CFG_1, shift: 4 }, + { key: 'ECG_EN', index: OP_IDX.GEN_CFG_1, shift: 3 }, + { key: 'PPG_BLUE_EN', index: OP_IDX.GEN_CFG_1, shift: 2 }, + { key: 'VPROG_EN', index: OP_IDX.GEN_CFG_2, shift: 2 }, + { key: 'VBATT_EN', index: OP_IDX.GEN_CFG_2, shift: 1 }, + // v9 second-generation sensors. On 2nd-gen the raw PPG (id 4) is gated by the + // existing PPG channel enables above; ALGO_HUB_EN gates the algorithm (id 8). + { key: 'AMBIENT_LIGHT_EN', index: OP_IDX.GEN_CFG_3, shift: 3 }, + { key: 'SKIN_TEMP_EN', index: OP_IDX.GEN_CFG_3, shift: 4 }, + { key: 'ALGO_HUB_EN', index: OP_IDX.GEN_CFG_3, shift: 5 }, +]; +const VERISENSE_OPERATIONAL_FIELD_GROUPS = [ + { + id: 'gen', + title: 'General / Sensors', + openByDefault: false, + keys: [ + 'BLUETOOTH_EN', + 'USB_EN', + 'DEVICE_EN', + 'RECORDING_EN', + 'DATA_COMPRESSION_MODE', + 'HR_PPG_CHANNEL', + 'STEP_COUNT_EN', + 'LOW_BATT_AUTO_STOP_DISABLED', + 'BATT_TYPE', + 'MAG_EN', + 'LED_MODE', + 'BLE_TX_POWER', + ], + }, + { + id: 'accel1', + title: 'Accel1', + openByDefault: false, + keys: [ + 'ODR', + 'MODE', + 'LP_MODE', + 'BW_FILT', + 'FS', + 'FDS', + 'LOW_NOISE', + 'HP_REF_MODE', + 'FMode', + 'FTH', + ], + }, + { + id: 'gyro_accel2', + title: 'Gyro / Accel2', + openByDefault: false, + keys: [ + 'FTH_LSB', + 'TIMER_PEDO_FIFDO_EN', + 'TIMER_PEDO_FIFO_DRDY', + 'FTH_MSB', + 'DEC_FIFO_GYRO', + 'DEC_FIFO_XL', + 'ODR_FIFO', + 'FIFO_MODE', + 'ODR_XL', + 'FS_XL', + 'BW_XL', + 'ODR_G', + 'FS_G', + 'FS_125', + 'G_HM_MODE', + 'HP_G_EN', + 'HPCF_G', + 'HP_G_RST', + 'ROUNDING_STATUS', + 'LPF2_XL_EN', + 'HPCF_XL', + 'HP_SLOPE_XL_EN', + 'LOW_PASS_ON_6D', + ], + }, + { + id: 'lsm6dsv', + title: 'Accel / Gyro / Mag', + openByDefault: false, + keys: ['LSM6DSV_ODR_XL', 'LSM6DSV_FS_XL', 'LSM6DSV_ODR_G', 'LSM6DSV_FS_G', 'LIS2MDL_ODR'], + }, + { + id: 'recording_window', + title: 'Recording Window', + openByDefault: false, + keys: ['START_TIME', 'END_TIME'], + }, + { + id: 'inactivity', + title: 'Inactivity', + openByDefault: false, + keys: ['INACTIVE_TIMEOUT_MINUTES', 'RESUME_REC_ON_ACTIVITY'], + }, + { + id: 'ble_wake', + title: 'BLE Wake Schedule', + openByDefault: false, + keys: [ + 'PENDING_EVENTS_SCHEDULER_DISABLED', + 'BLE_CONNECTION_TRIES_PER_DAY', + 'ADAPTIVE_SCHEDULER_INTERVAL', + 'ADAPTIVE_SCHEDULER_FAILCOUNT_MAX', + 'BLE_DATA_TRANS_WKUP_INT_HOURS', + 'BLE_DATA_TRANS_WKUP_TIME', + 'BLE_DATA_TRANS_WKUP_DUR', + 'BLE_DATA_TRANS_RETRY_INT', + 'BLE_STATUS_WKUP_INT_HOURS', + 'BLE_STATUS_WKUP_TIME', + 'BLE_STATUS_WKUP_DUR', + 'BLE_STATUS_RETRY_INT', + 'BLE_RTC_SYNC_WKUP_INT_HOURS', + 'BLE_RTC_SYNC_WKUP_TIME', + 'BLE_RTC_SYNC_WKUP_DUR', + 'BLE_RTC_SYNC_RETRY_INT', + ], + // PENDING_EVENTS and BLE retry count stay ungrouped (rendered above the + // subpanels); the remaining fields cluster by purpose: data transfer, + // status, RTC sync, and the adaptive scheduler. + subgroups: [ + { + id: 'ble_data', + title: 'Data Transfer Schedule', + keys: [ + 'BLE_DATA_TRANS_WKUP_INT_HOURS', + 'BLE_DATA_TRANS_WKUP_TIME', + 'BLE_DATA_TRANS_WKUP_DUR', + 'BLE_DATA_TRANS_RETRY_INT', + ], + }, + { + id: 'ble_status', + title: 'Status Sync Schedule', + keys: [ + 'BLE_STATUS_WKUP_INT_HOURS', + 'BLE_STATUS_WKUP_TIME', + 'BLE_STATUS_WKUP_DUR', + 'BLE_STATUS_RETRY_INT', + ], + }, + { + id: 'ble_rtc_sync', + title: 'Time Sync Schedule', + keys: [ + 'BLE_RTC_SYNC_WKUP_INT_HOURS', + 'BLE_RTC_SYNC_WKUP_TIME', + 'BLE_RTC_SYNC_WKUP_DUR', + 'BLE_RTC_SYNC_RETRY_INT', + ], + }, + { + id: 'adaptive_scheduler', + title: 'Adaptive Scheduler (fallback)', + keys: ['ADAPTIVE_SCHEDULER_FAILCOUNT_MAX', 'ADAPTIVE_SCHEDULER_INTERVAL'], + }, + ], + }, + { + id: 'adc_gsr', + title: 'ADC / GSR', + openByDefault: false, + keys: ['ADC_SAMPLE_RATE', 'ADC_OVERSAMPLE_RATE', 'GSR_RANGE_SETTING'], + }, + { + id: 'ppg', + title: 'PPG', + openByDefault: false, + keys: [ + 'PPG_REC_DUR_SECS', + 'PPG_REC_INT_MINS', + 'SMP_AVE', + 'PPG_ADC_RGE', + 'PPG_SR', + 'PPG_LED_PW', + 'PPG_MA_DEFAULT', + 'PPG_MA_MAX_RED_IR', + 'PPG_MA_MAX_GREEN_BLUE', + 'PPG_AGC_TARGET_PERCENT_OF_RANGE', + 'PPG_UNUSED_BYTE', + 'PPG_MA_LED_PILOT', + 'XTALK_DAC1', + 'XTALK_DAC2', + 'XTALK_DAC3', + 'XTALK_DAC4', + 'PROX_AGC_MODE', + ], + }, + { + id: 'light', + title: 'Ambient Light', + openByDefault: false, + keys: [ + 'LIGHT_GAIN_INDEX', + 'LIGHT_EXPOSURE_INDEX', + 'LIGHT_DARK_ENABLE', + 'LIGHT_FLICKER_EN', + 'LIGHT_SAMPLE_RATE_INDEX', + ], + }, + { + id: 'skin_temp', + title: 'Skin Temperature', + openByDefault: false, + keys: ['SKIN_TEMP_MEAS_TYPE', 'SKIN_TEMP_SAMPLE_RATE'], + }, + { + id: 'algo', + title: 'Algorithm Hub', + openByDefault: false, + keys: [ + 'ALGO_OP_MODE', + 'ALGO_REPORT_MODE', + 'ALGO_REPORT_PERIOD', + 'ALGO_AEC_ENABLE', + 'ALGO_SCD_ENABLE', + 'ALGO_AUTO_PD_ENABLE', + 'ALGO_INITIAL_HR', + ], + }, + { + id: 'person', + title: 'Subject / Person Parameters', + openByDefault: false, + keys: ['PERSON_AGE', 'PERSON_HEIGHT_CM', 'PERSON_WEIGHT_KG', 'PERSON_GENDER'], + }, + { + id: 'led', + title: 'LED Auto-Brightness', + openByDefault: false, + keys: ['LED_AUTO_BRIGHTNESS_ENABLE', 'LED_MAX_BRIGHTNESS', 'LED_LUX_THRESHOLD'], + }, +]; +const VERISENSE_OPERATIONAL_FIELD_FALLBACK_GROUP_ID = 'gen'; +/** + * Maps each hardware-gated operational-config group id to the sensor block that + * gates it (see {@link VerisenseHardwareSensorSupport}). Group ids absent from + * this map (e.g. `gen`, `ble_wake`) configure behaviour that applies to + * every board and are always considered supported. + */ +const VERISENSE_OPERATIONAL_FIELD_GROUP_SENSOR = { + accel1: 'accel1', + gyro_accel2: 'gyroAccel2', + lsm6dsv: 'imuGen2', + adc_gsr: 'gsr', + ppg: 'ppg', + light: 'ambientLight', + skin_temp: 'skinTemperature', + algo: 'algorithmHub', + person: 'algorithmHub', + led: 'ledAutoBrightness', +}; +/** + * Returns the set of operational-config group ids (from + * {@link VERISENSE_OPERATIONAL_FIELD_GROUPS}) whose underlying sensor is present + * on the given hardware revision. A group is supported when it is not gated by a + * sensor block, or when its gating sensor is present. + * + * Returns `null` when the hardware revision is unknown so callers can fall back + * to showing every group. + */ +function getVerisenseSupportedOperationalFieldGroupIds(source) { + const hw = getVerisenseHardwareRevision(source); + if (!hw) + return null; + const support = getVerisenseHardwareSensorSupport(hw.major, hw.minor); + const supported = new Set(); + for (const group of VERISENSE_OPERATIONAL_FIELD_GROUPS) { + const sensorKey = VERISENSE_OPERATIONAL_FIELD_GROUP_SENSOR[group.id]; + if (!sensorKey || support[sensorKey]) + supported.add(group.id); + } + return supported; +} +/** LIGHT_CONFIG bit 1 is the VD6283 dark-channel select: when set, the shared + * visible/clear slot carries the dark (covered-photodiode) baseline instead of + * the visible reading. Returns false for empty/nullish config. */ +function isVerisenseLightDarkChannelEnabled(op) { + if (!op?.length) + return false; + return ((op[OP_IDX.LIGHT_CONFIG] ?? 0) & (1 << 1)) !== 0; +} +/** + * Pad an operational config authored at a legacy/shorter length onto a blank + * full-size (v9, {@link VERISENSE_OP_CONFIG_BYTE_SIZE}-byte) image so the + * working config is always canonical size — otherwise trailing v9 fields + * (e.g. the person-parameter bytes) would be absent. Configs already at or + * beyond full size are returned as-is. + */ +function padVerisenseOperationalConfig(bytes) { + const src = bytes instanceof Uint8Array ? bytes : new Uint8Array(Array.from(bytes)); + if (src.length >= VERISENSE_OP_CONFIG_BYTE_SIZE) + return src; + const full = createBlankVerisenseOperationalConfig(VERISENSE_OP_CONFIG_BYTE_SIZE); + full.set(src); + return full; +} +/** + * Firmware default rate/mode codes per sensor group, for config editors that + * auto-seed a rate when a sensor is first enabled and power it down when all + * of its enables are cleared. Editors should only seed the `on` default when + * the field currently holds the `off` (power-down) code, so a user-chosen + * rate is never clobbered. Sensors whose rate field has no power-down value + * (magnetometer LIS2MDL_ODR, PPG_SR) are omitted — their enable bit / channel + * toggles are the on/off control. Default ODR codes mirror the standard + * customer template (Accel1 = 50 Hz, ADC = 128 Hz). + */ +const VERISENSE_SENSOR_RATE_DEFAULT_GROUPS = [ + { enableKeys: ['ACCEL_1_EN'], fields: [{ key: 'ODR', on: 4, off: 0 }] }, + { + enableKeys: ['ACCEL_2_EN'], + fields: [{ keyByGen: { dsv: 'LSM6DSV_ODR_XL', ds3: 'ODR_XL' }, on: 3, off: 0 }], + }, + { + enableKeys: ['GYRO_EN'], + fields: [{ keyByGen: { dsv: 'LSM6DSV_ODR_G', ds3: 'ODR_G' }, on: 3, off: 0 }], + }, + { + enableKeys: ['GSR_EN', 'VBATT_EN', 'VPROG_EN'], + fields: [{ key: 'ADC_SAMPLE_RATE', on: 19, off: 0 }], + }, + { + enableKeys: ['AMBIENT_LIGHT_EN'], + fields: [{ key: 'LIGHT_SAMPLE_RATE_INDEX', on: 2, off: 0 }], + }, + { + enableKeys: ['SKIN_TEMP_EN'], + fields: [{ key: 'SKIN_TEMP_SAMPLE_RATE', on: 5, off: 0 }], + }, + { enableKeys: ['ALGO_HUB_EN'], fields: [{ key: 'ALGO_OP_MODE', on: 1, off: 0 }] }, +]; +/** Resolve a rate-default field to its concrete schema key for the given IMU + * generation, or null when the field has no key for that generation. */ +function resolveVerisenseSensorRateFieldKey(field, generation) { + return field.key ?? field.keyByGen?.[generation] ?? null; +} +/** + * The three firmware sync schedules (data transfer, status, RTC sync), each + * with wake-interval-hours / wake-time / active-duration / retry-interval + * fields. Interval semantics (from firmware `hal_rtc.c`): 0 = off, 24 = once + * daily at the wake time, 1-23 = every N hours. Wake time is + * minutes-since-midnight (device local time), duration is minutes 0-255, + * retry interval is minutes 0-1439. The number of connection attempts per + * window is the separate global `BLE_CONNECTION_TRIES_PER_DAY` field. + */ +const VERISENSE_BLE_SYNC_SCHEDULES = [ + { + id: 'data', + subgroupId: 'ble_data', + intervalKey: 'BLE_DATA_TRANS_WKUP_INT_HOURS', + timeKey: 'BLE_DATA_TRANS_WKUP_TIME', + durKey: 'BLE_DATA_TRANS_WKUP_DUR', + retryKey: 'BLE_DATA_TRANS_RETRY_INT', + }, + { + id: 'status', + subgroupId: 'ble_status', + intervalKey: 'BLE_STATUS_WKUP_INT_HOURS', + timeKey: 'BLE_STATUS_WKUP_TIME', + durKey: 'BLE_STATUS_WKUP_DUR', + retryKey: 'BLE_STATUS_RETRY_INT', + }, + { + id: 'rtcSync', + subgroupId: 'ble_rtc_sync', + intervalKey: 'BLE_RTC_SYNC_WKUP_INT_HOURS', + timeKey: 'BLE_RTC_SYNC_WKUP_TIME', + durKey: 'BLE_RTC_SYNC_WKUP_DUR', + retryKey: 'BLE_RTC_SYNC_RETRY_INT', + }, +]; +/** Value ranges for the BLE sync-schedule fields (clamp editor input to + * these before writing). */ +const VERISENSE_BLE_SCHEDULE_RANGES = Object.freeze({ + intervalHours: Object.freeze({ min: 0, max: 24 }), + timeMins: Object.freeze({ min: 0, max: 1439 }), + durMin: Object.freeze({ min: 0, max: 255 }), + retryIntMin: Object.freeze({ min: 0, max: 1439 }), +}); +/** + * Canonical schedule defaults: 01:00 daily, 10-minute window, 15-minute + * retry, 5 connection attempts per wake. Also the "reset" values applied + * when the pending-events scheduler is disabled, so a disabled config lands + * in a clean known state. + */ +const VERISENSE_BLE_SCHEDULE_DEFAULTS = Object.freeze({ + intervalHours: 24, + timeMins: 60, + durMin: 10, + retryIntMin: 15, + connectionTries: 5, +}); +/** Format minutes-since-midnight as `"HH:MM"`, or null when out of range. + * Fractional input is rounded to the nearest whole minute first, so the + * minutes component always stays in 0–59. */ +function minutesSinceMidnightToHHMM(mins) { + if (mins == null) + return null; + const v = Math.round(Number(mins)); + if (!Number.isFinite(v) || v < 0 || v > 1439) + return null; + const h = Math.floor(v / 60); + const m = v % 60; + return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`; +} +/** Parse `"HH:MM"` (or `"H:MM"`) into minutes-since-midnight, or null when + * malformed / out of range. */ +function hhmmToMinutesSinceMidnight(text) { + const m = /^(\d{1,2}):(\d{2})$/.exec(String(text ?? '').trim()); + if (!m) + return null; + const h = Number(m[1]); + const mm = Number(m[2]); + if (h < 0 || h > 23 || mm < 0 || mm > 59) + return null; + return h * 60 + mm; +} +/** + * The stream-packet sensor IDs a device will emit for a given set of sensor + * enables (see `VERISENSE_STREAM_SENSOR_LABELS` for the ID meanings). The + * IMU block splits by hardware generation: first-gen streams accel2+gyro as + * ID 3 (LSM6DS3); second-gen streams accel2+gyro+mag as ID 6 (LSM6DSV + + * LIS2MDL). Any enabled PPG channel produces the single PPG stream (ID 4). + */ +function expectedVerisenseStreamSensorIds(enables, opts) { + const ids = new Set(); + if (enables.gsr || enables.vbatt || enables.vprog) + ids.add(1); + if (enables.accel1) + ids.add(2); + if (enables.accel2 || enables.gyro || enables.mag) + ids.add(opts.secondGeneration ? 6 : 3); + if (enables.ppg) + ids.add(4); + if (enables.ambientLight) + ids.add(7); + if (enables.algoHub) + ids.add(8); + if (enables.skinTemp) + ids.add(9); + return ids; +} +const STREAM_ENABLE_BY_FIELD_KEY = { + ACCEL_1_EN: 'accel1', + ACCEL_2_EN: 'accel2', + GYRO_EN: 'gyro', + MAG_EN: 'mag', + GSR_EN: 'gsr', + PPG_GREEN_EN: 'ppg', + PPG_RED_EN: 'ppg', + PPG_IR_EN: 'ppg', + PPG_BLUE_EN: 'ppg', + VPROG_EN: 'vprog', + VBATT_EN: 'vbatt', + AMBIENT_LIGHT_EN: 'ambientLight', + SKIN_TEMP_EN: 'skinTemp', + ALGO_HUB_EN: 'algoHub', +}; +/** {@link expectedVerisenseStreamSensorIds} computed straight from op-config + * bytes via the sensor-enable bit schema. */ +function expectedVerisenseStreamSensorIdsFromConfig(op, opts) { + const enables = {}; + if (op?.length) { + for (const f of VERISENSE_SENSOR_ENABLE_FIELDS) { + const enableKey = STREAM_ENABLE_BY_FIELD_KEY[f.key]; + if (!enableKey) + continue; + if ((((op[f.index] ?? 0) >> f.shift) & 0x01) === 1) + enables[enableKey] = true; + } + } + return expectedVerisenseStreamSensorIds(enables, opts); +} + +/** + * Abstract base class for all Verisense sensor decoders. + * + * Provides: + * - Timestamp unwrapping (handles the 1-minute rollover at 32768 ticks/s). + * - System-time offset tracking for plotting calibrated wall-clock timestamps. + * - Per-sample time extrapolation based on sampling rate and last-sample tick. + */ +class SensorBase { + constructor() { + this.lastTicksUnwrapped = 0; + this.cycle = 0; + /** (system time) − (shimmer time) at first sample, in milliseconds. */ + this.systemOffsetFirstTime = null; + /** Sampling rate in Hz (used for per-sample time extrapolation). */ + this.samplingRateHz = null; + /** Whether this sensor is enabled in the operational config. */ + this.enabled = true; + /** + * Per-device calibration read from the sensor, or null when none is available + * (decoders then fall back to nominal full-scale/datasheet scaling). Set via + * {@link applyCalibration}; subclasses read it in their calibrate routines. + */ + this.calibration = null; + } + /** Supply (or clear) the device calibration set used by this decoder. */ + applyCalibration(set) { + this.calibration = set; + } + /** Reset all timestamp state (call on (re)connect or when streaming restarts). */ + resetTimestamps() { + this.lastTicksUnwrapped = 0; + this.cycle = 0; + this.systemOffsetFirstTime = null; + } + /** + * Unwrap a rolling 24-bit tick counter to a monotonically increasing value. + */ + unwrapTicks(ticks) { + let unwrapped = ticks + SensorBase.TICKS_MAX_VALUE * this.cycle; + if (this.lastTicksUnwrapped > unwrapped) { + this.cycle += 1; + unwrapped = ticks + SensorBase.TICKS_MAX_VALUE * this.cycle; + } + this.lastTicksUnwrapped = unwrapped; + return unwrapped; + } + /** Convert unwrapped ticks to milliseconds. */ + ticksToMillis(unwrappedTicks) { + return (unwrappedTicks / SensorBase.CLOCK_FREQ) * 1000.0; + } + /** + * Compute the calibrated shimmer timestamp for the *last* sample in a burst, + * and store the first-seen system-offset for later plotting. + * + * @param lastSampleTicksU24 24-bit tick counter from the packet header. + * @param systemMillis `Date.now()` at the time of packet receipt. + */ + getTimestampUnwrappedMillis(lastSampleTicksU24, systemMillis) { + const unwrappedTicks = this.unwrapTicks(lastSampleTicksU24); + const shimmerMillis = this.ticksToMillis(unwrappedTicks); + if (this.systemOffsetFirstTime == null) { + this.systemOffsetFirstTime = systemMillis - shimmerMillis; + } + return { shimmerMillis, systemOffsetFirstTime: this.systemOffsetFirstTime }; + } + /** + * Extrapolate the timestamp for sample `i` of `numSamples` in a burst, + * given the timestamp of the *last* sample and the sampling rate. + * + * @returns Object with `tsMillis`, `systemTsMillis`, and `systemTsPlotMillis`. + */ + extrapolateSampleTimes(opts) { + const sr = opts.samplingRateHz ?? this.samplingRateHz; + const { tsLastSampleMillis, systemTsLastSampleMillis, systemOffsetFirstTime } = opts; + if (!sr || sr <= 0) { + return { + tsMillis: tsLastSampleMillis, + systemTsMillis: systemTsLastSampleMillis, + systemTsPlotMillis: systemOffsetFirstTime != null + ? tsLastSampleMillis + systemOffsetFirstTime + : systemTsLastSampleMillis, + }; + } + const sampleOffsetSec = (opts.numSamples - opts.i - 1) / sr; + const tsMillis = tsLastSampleMillis - sampleOffsetSec * 1000; + const systemTsMillis = systemTsLastSampleMillis - sampleOffsetSec * 1000; + const systemTsPlotMillis = systemOffsetFirstTime != null ? tsMillis + systemOffsetFirstTime : systemTsMillis; + return { tsMillis, systemTsMillis, systemTsPlotMillis }; + } + /** + * Compute per-sample timestamps for a whole decoded burst. + * + * The base implementation treats every decoded sample as one evenly-spaced + * time step at `samplingRateHz` (correct when each decoded sample is a single + * combined time step). Sensors whose decoded array *interleaves* multiple + * streams at different cadences (e.g. the LSM6DSV tagged FIFO, which mixes + * accel / gyro / mag entries) override this to timestamp each stream on its + * own rate — otherwise the shared rate spreads each stream's samples too far + * back and consecutive blocks overlap on the time axis. + */ + computeSampleTimestamps(decodedSamples, block) { + const num = decodedSamples.length; + const out = new Array(num); + for (let i = 0; i < num; i++) { + out[i] = this.extrapolateSampleTimes({ + numSamples: num, + i, + samplingRateHz: this.samplingRateHz, + tsLastSampleMillis: block.tsLastSampleMillis, + systemTsLastSampleMillis: block.systemTsLastSampleMillis, + systemOffsetFirstTime: block.systemOffsetFirstTime, + }); + } + return out; + } + /** + * Turn a decoded + timestamped burst into one or more stream contributions + * for live throughput / packet-loss tracking. The default treats the sensor + * as a single stream; sensors whose decoded array interleaves several + * sub-streams at different cadences (e.g. the LSM6DSV tagged FIFO) override + * this to report one contribution per sub-stream so loss is tracked + * independently. + */ + getStreamContributions(samplesWithTime, sensorId) { + let first = null; + let last = null; + for (const s of samplesWithTime) { + const t = s?.timestamps?.tsMillis; + if (typeof t !== 'number') + continue; + if (first == null || t < first) + first = t; + if (last == null || t > last) + last = t; + } + return [ + { + key: String(sensorId), + label: `Sensor ${sensorId}`, + samplingRateHz: this.samplingRateHz, + sampleCount: samplesWithTime.length, + firstSampleMillis: first, + lastSampleMillis: last, + }, + ]; + } +} +/** Verisense clock frequency in ticks per second. */ +SensorBase.CLOCK_FREQ = 32768; +/** 1-minute rollover at 32768 ticks/s (matches C# Sensor.cs). */ +SensorBase.TICKS_MAX_VALUE = 60 * 32768; + +/** + * Decoder for grouped ADC channels (Verisense sensor id = 1). + * + * Includes GSR plus battery/ADC channels carried in the same packet source. + * Implements C# `SensorGSR.cs` including: + * - Per-hardware reference resistor selection (SR68 vs Shimmer3 resistors). + * - Auto-range decoding from the raw ADC value's upper bits. + * - Range-3 clamping threshold that differs by hardware. + * - Conductance (uS) output with connectivity detection. + */ +class SensorADC extends SensorBase { + constructor() { + super(); + this.LIMIT_MIN_VALID_USIEMENS = 0.03; + this.GSR_UNCAL_LIMIT_RANGE3_SR68 = 1134; + this.GSR_UNCAL_LIMIT_RANGE3_SR62 = 683; + this.SHIMMER3_REF_KOHMS = [40.2, 287.0, 1000.0, 3300.0]; + this.SR68_REF_KOHMS = [21.0, 150.0, 562.0, 1740.0]; + this.gsrEnabled = true; + this.battEnabled = false; + /** GSR range 0-3 (fixed) or 4 (auto-range). */ + this.gsrRangeSetting = 4; + this.hardwareIdentifier = 'VERISENSE_PULSE_PLUS'; + this.hwRevisionMajor = null; + this.hwRevisionMinor = null; + this.hwRevisionInternal = null; + // Decoded from opConfig for debug/display + this.gsrRateSettingRaw = 0; + this.gsrRangeSettingRaw = 0; + this.gsrOversamplingRateSettingRaw = 0; + this.samplingRateHz = 50; + } + setHardwareIdentifier(idStr) { + this.hardwareIdentifier = idStr; + } + setHardwareRevision(revHwMajor, revHwMinor, revHwInternal = 0) { + this.hwRevisionMajor = Number.isFinite(revHwMajor) ? Math.trunc(revHwMajor) : null; + this.hwRevisionMinor = Number.isFinite(revHwMinor) ? Math.trunc(revHwMinor) : null; + this.hwRevisionInternal = Number.isFinite(revHwInternal) ? Math.trunc(revHwInternal) : null; + } + setGsrRangeSetting(v) { + this.gsrRangeSetting = v; + } + getBatteryVoltageMultiplier() { + if (this.hwRevisionMajor != null && this.hwRevisionMinor != null) { + return getVerisenseStreamingBatteryVoltageMultiplier(this.hwRevisionMajor, this.hwRevisionMinor); + } + // Backward-compatible fallback when production config revision is unavailable. + if (this.hardwareIdentifier === 'VERISENSE_GSR_PLUS') + return 2.0; + return 1.0; + } + /** + * Whether this board uses the SR62 (Verisense GSR+) Shimmer3-style analog + * front end: 3.0 V SAADC reference, 40.2/287/1000/3300 kΩ GSR feedback + * resistors, 0.5 V GSR reference and range-3 uncal limit 683. Every other + * GSR-capable board (SR61 >= 5, SR68 >= 5 — firmware + * `ShimBrd_isGsrSupportedForHwVersion`) carries the second-generation DC + * front end: 1.8 V reference, 21/150/562/1740 kΩ, 0.4986 V, limit 1134. + * + * Mirrors the firmware's `selectFeedbackResistorsFromHwVersion` (hal_gsr.c), + * which keys the choice on the major revision alone (SR62 vs everything + * else). Prefers the production-config hardware revision; falls back to the + * caller-supplied hardware identifier when no revision has been read yet. + * Previously this was keyed only on the `VERISENSE_PULSE_PLUS` identifier + * string, so an SR61-5/6 presenting its true identity decoded ~1.91× high + * (DEV-874). + */ + usesSr62GsrFrontEnd() { + if (this.hwRevisionMajor != null) { + return this.hwRevisionMajor === 62; + } + return this.hardwareIdentifier === 'VERISENSE_GSR_PLUS'; + } + setEnabled(arg1, opConfigBytes) { + if (opConfigBytes != null) { + const desired = typeof arg1 === 'boolean' ? { gsr: arg1 } : arg1 && typeof arg1 === 'object' ? arg1 : {}; + return this._patchEnabled(desired, opConfigBytes); + } + const obj = typeof arg1 === 'boolean' ? { gsr: arg1 } : arg1 && typeof arg1 === 'object' ? arg1 : {}; + if (typeof obj.gsr === 'boolean') + this.gsrEnabled = obj.gsr; + if (typeof obj.batt === 'boolean') + this.battEnabled = obj.batt; + return { gsr: this.gsrEnabled, batt: this.battEnabled }; + } + _patchEnabled({ gsr, batt }, opConfigBytes) { + const op = normalizeOperationalConfig(opConfigBytes); + const out = new Uint8Array(op); + if (typeof gsr === 'boolean') { + const idx = OP_IDX.GEN_CFG_1; + out[idx] = gsr ? (out[idx] | 0x80) & 0xff : out[idx] & 0x7f & 0xff; + } + if (typeof batt === 'boolean') { + const idx = OP_IDX.GEN_CFG_2; + out[idx] = batt ? (out[idx] | 0x02) & 0xff : out[idx] & 0xfd & 0xff; + } + return out; + } + patchGsrRange(rangeCfg, op) { + const out = new Uint8Array(op); + const i = OP_IDX.ADC_CHANNEL_SETTINGS_1; + out[i] = (out[i] & 0b11111000) | (rangeCfg & 0x07); + return out; + } + patchGsrSamplingRate(rateCfg, op) { + const out = new Uint8Array(op); + const i = OP_IDX.ADC_CHANNEL_SETTINGS_0; + out[i] = (out[i] & 0b11000000) | (rateCfg & 0x3f); + return out; + } + patchGsrOversampling(overCfg, op) { + const out = new Uint8Array(op); + const i = OP_IDX.ADC_CHANNEL_SETTINGS_1; + out[i] = (out[i] & 0b00001111) | ((overCfg & 0x0f) << 4); + return out; + } + calibrateAdcToVolts(uncal12bit) { + const adcRange = 2 ** 12 - 1; + let refVoltage = 1.8 / 4.0; + if (this.usesSr62GsrFrontEnd()) { + refVoltage = 3.0 / 4.0; + } + const adcScaling = 1.0 / 4.0; + return (uncal12bit * refVoltage) / adcRange / adcScaling; + } + calibrateGsrToKOhmsUsingAmplifierEq(volts, range) { + let rFeedback = this.SR68_REF_KOHMS[range]; + let gsrRefVoltage = 0.4986; + if (this.usesSr62GsrFrontEnd()) { + rFeedback = this.SHIMMER3_REF_KOHMS[range]; + gsrRefVoltage = 0.5; + } + return rFeedback / (volts / gsrRefVoltage - 1.0); + } + nudgeGsrResistance(kOhms) { + const limitsByRange = { + 0: [8.0, 63.0], + 1: [63.0, 220.0], + 2: [220.0, 680.0], + 3: [680.0, 4700.0], + 4: [8.0, 4700.0], + }; + const lim = limitsByRange[this.gsrRangeSetting] ?? [8.0, 4700.0]; + return Math.min(Math.max(kOhms, lim[0]), lim[1]); + } + kOhmToUSiemens(kOhms) { + return 1000.0 / kOhms; + } + /** + * Convert the 6-bit ADC sample-rate code to the streamed output rate in Hz, + * or null for "Off"/unknown codes. Used for per-sample timestamp spacing. + */ + decodeAdcSampleRateHz(rateCode) { + const divisor = SensorADC.ADC_RATE_DIVISORS[rateCode]; + if (!divisor) + return null; + return SensorBase.CLOCK_FREQ / divisor; + } + parsePayload(sensorPayloadBytes) { + const bytesPerSample = this.gsrEnabled && this.battEnabled ? 4 : 2; + const n = Math.floor(sensorPayloadBytes.length / bytesPerSample); + const out = []; + for (let i = 0; i < n; i++) { + const base = i * bytesPerSample; + let batt = null; + let gsr = null; + const gsrStart = this.battEnabled && this.gsrEnabled ? 2 : 0; + if (this.gsrEnabled) { + const gsrraw = i16le(sensorPayloadBytes, base + gsrStart); + let adc12 = gsrraw & 0x0fff; + let currentRange = this.gsrRangeSetting; + if (currentRange === 4) + currentRange = (gsrraw >> 14) & 0x03; + if (currentRange === 3) { + const limit = this.usesSr62GsrFrontEnd() + ? this.GSR_UNCAL_LIMIT_RANGE3_SR62 + : this.GSR_UNCAL_LIMIT_RANGE3_SR68; + if (adc12 < limit) + adc12 = limit; + } + const volts = this.calibrateAdcToVolts(adc12); + let kOhms = this.calibrateGsrToKOhmsUsingAmplifierEq(volts, currentRange); + kOhms = this.nudgeGsrResistance(kOhms); + const uS = this.kOhmToUSiemens(kOhms); + const connectivity = uS > this.LIMIT_MIN_VALID_USIEMENS ? 'Connected' : 'Disconnected'; + gsr = { raw: gsrraw, adc12, range: currentRange, volts, kOhms, uS, connectivity }; + } + if (this.battEnabled) { + const raw16 = i16le(sensorPayloadBytes, base) & 0xffff; + const adc12 = raw16 & 0x0fff; + const usbPluggedIn = ((raw16 >> 15) & 0x01) === 1; + const chargerStatusBits = (raw16 >> 13) & 0x03; + let mv = this.calibrateAdcToVolts(adc12) * 1000.0; + mv *= this.getBatteryVoltageMultiplier(); + const chargerStatusMap = { + 0: 'Power-Down/Suspended', + 1: 'Charging', + 2: 'Charging Complete', + 3: 'Bad Battery/LDO', + }; + batt = { + raw16, + adc12, + mV: mv, + usbPluggedIn, + chargerStatusBits, + chargerStatus: chargerStatusMap[chargerStatusBits] ?? 'Unknown', + }; + } + out.push({ gsr, batt }); + } + return out; + } + applyOperationalConfig(op) { + const gen1 = op[OP_IDX.GEN_CFG_1] ?? 0; + const gen2 = op[OP_IDX.GEN_CFG_2] ?? 0; + this.gsrEnabled = ((gen1 >> 7) & 0x01) === 1; + this.battEnabled = (gen2 & 0b00000010) !== 0; + const rateCfg = (op[OP_IDX.ADC_CHANNEL_SETTINGS_0] ?? 0) & 0x3f; + const cfg1 = (op[OP_IDX.ADC_CHANNEL_SETTINGS_1] ?? 0) & 0xff; + const rangeCfg = cfg1 & 0x07; + const oversamplingCfg = (cfg1 >> 4) & 0x0f; + this.gsrRateSettingRaw = rateCfg; + this.gsrRangeSettingRaw = rangeCfg; + this.gsrOversamplingRateSettingRaw = oversamplingCfg; + // Drive per-sample timestamp spacing from the configured ADC rate. Without + // this, samplingRateHz stays at the constructor default (50 Hz); when the + // real rate differs, computeSampleTimestamps mis-spaces samples and + // consecutive blocks overlap on the time axis (the GSR "zigzag"). + const rateHz = this.decodeAdcSampleRateHz(rateCfg); + if (rateHz) + this.samplingRateHz = rateHz; + if (rangeCfg >= 0 && rangeCfg <= 4) { + this.gsrRangeSetting = rangeCfg; + } + } +} +/** + * ADC sample-rate code → divisor of the 32768 Hz clock. Mirrors the firmware + * `samplingRateInTicksArray` (hal_adc.c): the sampling timer fires every + * `divisor` ticks, producing one sample set per fire, so the streamed output + * rate = 32768 / divisor. Oversampling uses SAADC burst mode and therefore + * does NOT divide the output rate. Index 0 = "Off". + */ +SensorADC.ADC_RATE_DIVISORS = [ + 0, 1, 2, 4, 5, 8, 10, 16, 20, 25, 32, 40, 50, 64, 80, 100, 128, 160, 200, 256, 320, 400, 512, + 640, 800, 1024, 1280, 1600, 2048, 2560, 3200, 4096, 5120, 6400, 8192, 10240, 12800, 16384, + 20480, 25600, 32768, 40960, 51200, +]; + +/** + * Decoder for the LIS2DW12 low-power accelerometer (Verisense sensor id = 2). + * + * Sensitivity values are given in raw-LSB / (m/s²) per axis — matching + * the C# `SensorLIS2DW12.cs` implementation. + */ +class SensorLIS2DW12 extends SensorBase { + constructor() { + super(); + this.offset = [0, 0, 0]; + this.align = [ + [0, 0, 1], + [1, 0, 0], + [0, 1, 0], + ]; + this.sensitivityByRange = { + '2G': [1671.665922915, 1671.665922915, 1671.665922915], + '4G': [835.832961457, 835.832961457, 835.832961457], + '8G': [417.916480729, 417.916480729, 417.916480729], + '16G': [208.958240364, 208.958240364, 208.958240364], + }; + this.range = '2G'; + /** Numeric full-scale index (0=2G..3=16G) used to select the device calibration block. */ + this.rangeIndex = 0; + this.samplingRateHz = 50; + } + setRange(rangeStr) { + if (this.sensitivityByRange[rangeStr]) + this.range = rangeStr; + } + // --- Functional OpConfig helpers (returns new Uint8Array, does not mutate) --- + setEnabled(enabled, opConfigBytes) { + if (opConfigBytes == null) { + this.enabled = enabled; + return this.enabled; + } + const op = normalizeOperationalConfig(opConfigBytes); + const out = new Uint8Array(op); + const idx = OP_IDX.GEN_CFG_0; + out[idx] = enabled ? (out[idx] | 0x80) & 0xff : out[idx] & 0x7f & 0xff; + return out; + } + setAccelEnabled(enabled, opConfigBytes) { + return this.setEnabled(enabled, opConfigBytes); + } + patchAccelRange(rangeCfg, op) { + const out = new Uint8Array(op); + const i = OP_IDX.ACCEL1_CFG_1; + out[i] = (out[i] & 0b11001111) | ((rangeCfg & 0x03) << 4); + return out; + } + patchAccelSamplingRate(rateCfg, op) { + const out = new Uint8Array(op); + const i = OP_IDX.ACCEL1_CFG_0; + out[i] = (out[i] & 0b00001111) | ((rateCfg & 0x0f) << 4); + return out; + } + _calibrate(raw) { + // Prefer per-device calibration from the sensor when available for this range. + const dev = this.calibration?.getImu(CalibSensorId.LIS2DW12_ACCEL, this.rangeIndex); + if (dev) + return applyImuCalibration(raw, dev); + // Fallback: nominal offset / alignment / datasheet sensitivity. + const v = [ + raw[0] - this.offset[0], + raw[1] - this.offset[1], + raw[2] - this.offset[2], + ]; + const a = this.align; + const aligned = [ + a[0][0] * v[0] + a[0][1] * v[1] + a[0][2] * v[2], + a[1][0] * v[0] + a[1][1] * v[1] + a[1][2] * v[2], + a[2][0] * v[0] + a[2][1] * v[1] + a[2][2] * v[2], + ]; + const s = this.sensitivityByRange[this.range]; + return [aligned[0] / s[0], aligned[1] / s[1], aligned[2] / s[2]]; + } + parsePayload(sensorPayloadBytes) { + const BYTES_PER_SAMPLE = 6; + const n = Math.floor(sensorPayloadBytes.length / BYTES_PER_SAMPLE); + const out = []; + for (let i = 0; i < n; i++) { + const off = i * BYTES_PER_SAMPLE; + const raw = [ + i16le(sensorPayloadBytes, off + 0), + i16le(sensorPayloadBytes, off + 2), + i16le(sensorPayloadBytes, off + 4), + ]; + const cal = this._calibrate(raw); + out.push({ raw, cal, units: { cal: 'm/s^2' } }); + } + return out; + } + applyOperationalConfig(op) { + const gen0 = op[OP_IDX.GEN_CFG_0]; + const cfg0 = op[OP_IDX.ACCEL1_CFG_0]; + const cfg1 = op[OP_IDX.ACCEL1_CFG_1]; + if (gen0 == null || cfg0 == null || cfg1 == null) { + console.warn('[LIS2DW12] Missing required bytes; cannot apply config.'); + return; + } + this.enabled = ((gen0 >> 7) & 0x01) === 1; + const rangeSetting = (cfg1 >> 4) & 0x03; + const modeSetting = (cfg0 >> 2) & 0x03; + const rateSetting = (cfg0 >> 4) & 0x0f; + const rangeMap = { 0: '2G', 1: '4G', 2: '8G', 3: '16G' }; + this.setRange(rangeMap[rangeSetting] ?? '2G'); + this.rangeIndex = rangeSetting & 0x03; + const lowPowerHzByCfg = { + 1: 1.6, + 2: 12.5, + 3: 25, + 4: 50, + 5: 100, + 6: 200, + }; + const highPerfHzByCfg = { + 1: 12.5, + 3: 25, + 4: 50, + 5: 100, + 6: 200, + 7: 400, + 8: 800, + 9: 1600, + }; + const isLowPower = modeSetting === 0; + const hz = isLowPower ? lowPowerHzByCfg[rateSetting] : highPerfHzByCfg[rateSetting]; + if (hz) + this.samplingRateHz = hz; + } +} + +/** + * Decoder for the LSM6DS3 combined accelerometer + gyroscope (Verisense sensor id = 3). + * + * Sensitivity values mirror the C# `SensorLSM6DS3.cs` implementation. + */ +class SensorLSM6DS3 extends SensorBase { + constructor() { + super(); + this.offset = [0, 0, 0]; + // Applied directly as `physical = align · (raw − offset)` (no inversion), so this + // must be the *inverse* alignment R⁻¹ = Rᵀ — matching the Shimmer Java reference + // `UtilCalibration` (C = R⁻¹·K⁻¹·(U−B)) and the gen-1 calibration doc's R, which + // is the forward §8 rotation. (Previously stored the un-transposed R, which + // applied R instead of R⁻¹.) + this.align = [ + [0, -1, 0], + [0, 0, -1], + [1, 0, 0], + ]; + this.accSensByRange = { + '2G': [1671.665922915, 1671.665922915, 1671.665922915], + '4G': [835.832961457, 835.832961457, 835.832961457], + '8G': [417.916480729, 417.916480729, 417.916480729], + '16G': [208.958240364, 208.958240364, 208.958240364], + }; + this.gyroSensByRange = { + '250DPS': [114.285714286, 114.285714286, 114.285714286], + '500DPS': [57.142857143, 57.142857143, 57.142857143], + '1000DPS': [28.571428571, 28.571428571, 28.571428571], + '2000DPS': [14.285714286, 14.285714286, 14.285714286], + }; + this.accRange = '2G'; + this.gyroRange = '250DPS'; + this.accEnabled = true; + this.gyroEnabled = true; + this.samplingRateHz = 50; + } + setAccelEnabled(v) { + this.accEnabled = !!v; + } + setGyroEnabled(v) { + this.gyroEnabled = !!v; + } + setAccelRange(r) { + if (this.accSensByRange[r]) + this.accRange = r; + } + setGyroRange(r) { + if (this.gyroSensByRange[r]) + this.gyroRange = r; + } + _applyAlignAndOffset(raw3) { + const v = [ + raw3[0] - this.offset[0], + raw3[1] - this.offset[1], + raw3[2] - this.offset[2], + ]; + const a = this.align; + return [ + a[0][0] * v[0] + a[0][1] * v[1] + a[0][2] * v[2], + a[1][0] * v[0] + a[1][1] * v[1] + a[1][2] * v[2], + a[2][0] * v[0] + a[2][1] * v[1] + a[2][2] * v[2], + ]; + } + _calibrateAccel(raw) { + const dev = this.calibration?.getImu(CalibSensorId.LSM6DS3_ACCEL, SensorLSM6DS3.ACC_RANGE_CODE[this.accRange]); + if (dev) + return applyImuCalibration(raw, dev); + const aligned = this._applyAlignAndOffset(raw); + const s = this.accSensByRange[this.accRange]; + return [aligned[0] / s[0], aligned[1] / s[1], aligned[2] / s[2]]; + } + _calibrateGyro(raw) { + const dev = this.calibration?.getImu(CalibSensorId.LSM6DS3_GYRO, SensorLSM6DS3.GYRO_RANGE_CODE[this.gyroRange]); + if (dev) + return applyImuCalibration(raw, dev); + const aligned = this._applyAlignAndOffset(raw); + const s = this.gyroSensByRange[this.gyroRange]; + return [aligned[0] / s[0], aligned[1] / s[1], aligned[2] / s[2]]; + } + parsePayload(sensorPayloadBytes) { + let bytesPerSample = 6; + if (this.gyroEnabled && this.accEnabled) + bytesPerSample = 12; + const n = Math.floor(sensorPayloadBytes.length / bytesPerSample); + const out = []; + for (let i = 0; i < n; i++) { + const base = i * bytesPerSample; + let gyroRaw = null; + let accRaw = null; + if (this.gyroEnabled && this.accEnabled) { + gyroRaw = [ + i16le(sensorPayloadBytes, base + 0), + i16le(sensorPayloadBytes, base + 2), + i16le(sensorPayloadBytes, base + 4), + ]; + accRaw = [ + i16le(sensorPayloadBytes, base + 6), + i16le(sensorPayloadBytes, base + 8), + i16le(sensorPayloadBytes, base + 10), + ]; + } + else if (this.gyroEnabled) { + gyroRaw = [ + i16le(sensorPayloadBytes, base + 0), + i16le(sensorPayloadBytes, base + 2), + i16le(sensorPayloadBytes, base + 4), + ]; + } + else if (this.accEnabled) { + accRaw = [ + i16le(sensorPayloadBytes, base + 0), + i16le(sensorPayloadBytes, base + 2), + i16le(sensorPayloadBytes, base + 4), + ]; + } + let accCal = null; + let gyroCal = null; + if (accRaw) { + accCal = this._calibrateAccel(accRaw); + } + if (gyroRaw) { + gyroCal = this._calibrateGyro(gyroRaw); + } + out.push({ + accel: accRaw && accCal ? { raw: accRaw, cal: accCal, units: 'm/s^2' } : null, + gyro: gyroRaw && gyroCal ? { raw: gyroRaw, cal: gyroCal, units: 'deg/s' } : null, + }); + } + return out; + } + applyOperationalConfig(op) { + this.accEnabled = (op[OP_IDX.GEN_CFG_0] & 0b01000000) !== 0; + this.gyroEnabled = (op[OP_IDX.GEN_CFG_0] & 0b00100000) !== 0; + const cfg4 = op[OP_IDX.GYRO_ACCEL2_CFG_4]; + const accelRateCfg = (cfg4 >> 4) & 0x0f; + const cfg5 = op[OP_IDX.GYRO_ACCEL2_CFG_5]; + const accelRangeCfg = (cfg5 >> 2) & 0x03; + const gyroRangeCfg = (cfg5 >> 4) & 0x03; + const accelRangeMap = { 0: '2G', 1: '4G', 2: '8G', 3: '16G' }; + const gyroRangeMap = { + 0: '250DPS', + 1: '500DPS', + 2: '1000DPS', + 3: '2000DPS', + }; + this.setAccelRange(accelRangeMap[accelRangeCfg] ?? this.accRange); + this.setGyroRange(gyroRangeMap[gyroRangeCfg] ?? this.gyroRange); + const hzByCfg = { + 0: null, + 1: 12.5, + 2: 26, + 3: 52, + 4: 104, + 5: 208, + 6: 416, + 7: 833, + 8: 1660, + }; + const hz = hzByCfg[accelRateCfg]; + if (hz) + this.samplingRateHz = hz; + } +} +// Calibration-block range codes (must match getVerisenseCalibrationSensors gen-1). +SensorLSM6DS3.ACC_RANGE_CODE = { + '2G': 0, + '4G': 1, + '8G': 2, + '16G': 3, +}; +SensorLSM6DS3.GYRO_RANGE_CODE = { + '250DPS': 0, + '500DPS': 1, + '1000DPS': 2, + '2000DPS': 3, +}; + +class SensorLSM6DSV extends SensorBase { + constructor() { + super(); + this.accEnabled = true; + this.gyroEnabled = true; + this.magEnabled = true; + this.accelFsG = 2; + this.gyroFsDps = 2000; + // Numeric full-scale codes (register values) used to select the device + // calibration block: accel 0..3 (2/4/8/16 g), gyro 0..4 (125..2000 dps). + this.fsXlCode = 0; + this.fsGCode = 4; + // Configured per-stream rates (the FIFO interleaves accel/gyro/mag, so each + // stream is timestamped on its own rate — see computeSampleTimestamps). Public + // so the per-sub-stream loss tracking (getStreamContributions) can read each. + // accelHz/gyroHz are the configured LSM6DSV ODRs; magHz is the configured + // magnetometer output (sensor-hub) rate. The firmware FIFO-batches accel/gyro + // at their ODR, so they deliver at the configured rate; the mag is still + // bounded by the accel/gyro hub trigger, so a mag rate above the accel/gyro + // ODR delivers slower — which shows up as packet loss. + this.accelHz = 15; + this.gyroHz = 15; + this.magHz = 15; + this.samplingRateHz = 15; + } + decodeAccelFsG(code) { + switch (code) { + case 0: + return 2; + case 1: + return 4; + case 2: + return 8; + case 3: + return 16; + default: + return 2; + } + } + decodeGyroFsDps(code) { + // LSM6DSV FS_G datasheet register values. + switch (code) { + case 0: + return 125; + case 1: + return 250; + case 2: + return 500; + case 3: + return 1000; + case 4: + return 2000; + default: + return 2000; + } + } + decodeOdrHz(code) { + // LSM6DSV ODR_XL / ODR_G datasheet register values (normal mode). + switch (code) { + case 0: + return 0; // Off + case 1: + return 1.875; + case 2: + return 7.5; + case 3: + return 15; + case 4: + return 30; + case 5: + return 60; + case 6: + return 120; + case 7: + return 240; + case 8: + return 480; + case 9: + return 960; + case 10: + return 1920; + case 11: + return 3840; + case 12: + return 7680; + default: + return 15; + } + } + decodeMagOutputRateHz(code) { + // Magnetometer output (sensor-hub) rate code from op-config byte 20 bits 1:0. + // This is the rate mag samples reach the host; the firmware derives the + // underlying LIS2MDL ODR (20/50/100/100 Hz) to keep a fresh sample available. + switch (code) { + case 0: + return 15; + case 1: + return 30; + case 2: + return 60; + case 3: + return 120; + default: + return 15; + } + } + calibrateAccel(raw) { + const dev = this.calibration?.getImu(CalibSensorId.LSM6DSV_ACCEL, this.fsXlCode); + if (dev) + return applyImuCalibration(raw, dev); + const scale = (this.accelFsG / 32768) * 9.80665; + return [raw[0] * scale, raw[1] * scale, raw[2] * scale]; + } + calibrateGyro(raw) { + const dev = this.calibration?.getImu(CalibSensorId.LSM6DSV_GYRO, this.fsGCode); + if (dev) + return applyImuCalibration(raw, dev); + // ST angular-rate sensitivity: 4.375 mdps/LSB at ±125 dps, doubling per + // range (LSM6DSV datasheet §4.3; same spec as the gen-1 LSM6DS3 and the + // device calibration seed / calibrationDefaults GYRO_RANGES). Unlike the + // accel, the gyro does NOT span the full 16-bit range at nominal full + // scale, so a FS/32768 derivation reads ~12.8% low (DEV-874). + const scale = 0.004375 * (this.gyroFsDps / 125); + return [raw[0] * scale, raw[1] * scale, raw[2] * scale]; + } + calibrateMag(raw) { + const dev = this.calibration?.getImu(CalibSensorId.LIS2MDL_MAG, 0); + if (dev) + return applyImuCalibration(raw, dev); + // LIS2MDL nominal sensitivity is 1.5 mGauss/LSB (0.15 uT/LSB). + const scale = 0.15; + return [raw[0] * scale, raw[1] * scale, raw[2] * scale]; + } + parsePayload(sensorPayloadBytes) { + if (!sensorPayloadBytes?.length) + return []; + // Entry count is a 16-bit little-endian value (a full FIFO drain can return + // more than 255 samples), followed by `count` x 7-byte tagged entries. + const entryCount = ((sensorPayloadBytes[0] ?? 0) | ((sensorPayloadBytes[1] ?? 0) << 8)) >>> 0; + const maxEntriesByLength = Math.floor((sensorPayloadBytes.length - 2) / 7); + const n = Math.min(entryCount, maxEntriesByLength); + const out = []; + let offset = 2; + for (let i = 0; i < n; i++) { + const tagCnt = sensorPayloadBytes[offset]; + const tag = (tagCnt >> 3) & 0x1f; + const cnt = (tagCnt >> 1) & 0x03; + const x = i16le(sensorPayloadBytes, offset + 1); + const y = i16le(sensorPayloadBytes, offset + 3); + const z = i16le(sensorPayloadBytes, offset + 5); + const raw = [x, y, z]; + let accel = null; + let gyro = null; + let mag = null; + if (tag === SensorLSM6DSV.TAG_ACCEL && this.accEnabled) { + accel = { raw, cal: this.calibrateAccel(raw), units: 'm/s^2' }; + } + else if (tag === SensorLSM6DSV.TAG_GYRO && this.gyroEnabled) { + gyro = { raw, cal: this.calibrateGyro(raw), units: 'deg/s' }; + } + else if (tag === SensorLSM6DSV.TAG_SENSORHUB_SLAVE0 && this.magEnabled) { + mag = { raw, cal: this.calibrateMag(raw), units: 'uT' }; + } + if (accel || gyro || mag) { + out.push({ tag, cnt, accel, gyro, mag }); + } + offset += 7; + } + return out; + } + applyOperationalConfig(op) { + this.accEnabled = (op[OP_IDX.GEN_CFG_0] & 0b01000000) !== 0; + this.gyroEnabled = (op[OP_IDX.GEN_CFG_0] & 0b00100000) !== 0; + this.magEnabled = (op[OP_IDX.GEN_CFG_3] & 0b00000100) !== 0; + const cfg0 = op[OP_IDX.LSM6DSV_CFG_0] ?? 0; + const cfg1 = op[OP_IDX.LSM6DSV_CFG_1] ?? 0; + const cfg2 = op[OP_IDX.LSM6DSV_CFG_2] ?? 0; + const odrXl = cfg0 & 0x0f; + const fsXl = (cfg0 >> 4) & 0x03; + const odrG = cfg1 & 0x0f; + const fsG = (cfg1 >> 4) & 0x0f; + const odrMag = cfg2 & 0x03; + this.accelFsG = this.decodeAccelFsG(fsXl); + this.gyroFsDps = this.decodeGyroFsDps(fsG); + this.fsXlCode = fsXl; + this.fsGCode = fsG; + this.accelHz = this.accEnabled ? this.decodeOdrHz(odrXl) : 0; + this.gyroHz = this.gyroEnabled ? this.decodeOdrHz(odrG) : 0; + // Configured mag output rate (NOT capped at the accel/gyro trigger). Loss is + // measured against this, so when the accel/gyro that trigger the sensor hub + // are too slow to deliver it, the shortfall surfaces as mag loss. + this.magHz = this.magEnabled ? this.decodeMagOutputRateHz(odrMag) : 0; + this.samplingRateHz = Math.max(this.accelHz, this.gyroHz, this.magHz, 1); + } + /** + * Timestamp each stream (accel / gyro / mag) so all three cover the same block + * time window. The tagged FIFO interleaves the streams, so the generic + * global-index spacing spreads each stream by (#interleaved-streams)x too far + * back and makes consecutive blocks overlap on the time axis. + * + * Each stream's effective rate is derived from *this block*: the block's + * covered duration is taken from a directly-sampled reference stream (accel, + * else gyro) at its known ODR, and every stream is then spread evenly over + * that same duration by its own sample count. This is important for the mag + * (LIS2MDL), which is read via the LSM6DSV sensor hub — its entries land in + * the FIFO at the hub batch rate, NOT the LIS2MDL ODR, so a fixed mag ODR + * would mis-spread it (the zig-zag). Deriving the rate from the block keeps it + * aligned regardless of the hub rate. + */ + computeSampleTimestamps(decodedSamples, block) { + const samples = decodedSamples; + let accelTotal = 0; + let gyroTotal = 0; + let magTotal = 0; + for (const s of samples) { + if (s.accel) + accelTotal++; + else if (s.gyro) + gyroTotal++; + else if (s.mag) + magTotal++; + } + // Block duration (s) from a directly-sampled reference stream at a known ODR. + let blockPeriodSec = 0; + if (accelTotal > 0 && this.accelHz > 0) + blockPeriodSec = accelTotal / this.accelHz; + else if (gyroTotal > 0 && this.gyroHz > 0) + blockPeriodSec = gyroTotal / this.gyroHz; + else if (magTotal > 0 && this.magHz > 0) + blockPeriodSec = magTotal / this.magHz; + // Effective per-stream rate so each stream spans exactly blockPeriodSec. + const rateFor = (total) => blockPeriodSec > 0 && total > 0 ? total / blockPeriodSec : (this.samplingRateHz ?? 1); + const accelRate = rateFor(accelTotal); + const gyroRate = rateFor(gyroTotal); + const magRate = rateFor(magTotal); + let ai = 0; + let gi = 0; + let mi = 0; + return samples.map((s) => { + let numSamples = samples.length; + let i = 0; + let rate = this.samplingRateHz; + if (s.accel) { + numSamples = accelTotal; + i = ai++; + rate = accelRate; + } + else if (s.gyro) { + numSamples = gyroTotal; + i = gi++; + rate = gyroRate; + } + else if (s.mag) { + numSamples = magTotal; + i = mi++; + rate = magRate; + } + return this.extrapolateSampleTimes({ + numSamples, + i, + samplingRateHz: rate, + tsLastSampleMillis: block.tsLastSampleMillis, + systemTsLastSampleMillis: block.systemTsLastSampleMillis, + systemOffsetFirstTime: block.systemOffsetFirstTime, + }); + }); + } + /** + * Report up to three independent sub-streams (accel / gyro / mag) so loss is + * tracked per stream. Each sub-stream's expected rate is its configured rate + * (ODR for accel/gyro, output rate for mag); loss is measured against that, so + * the mag's hub-trigger bound — or any rate the firmware/link can't keep up + * with — surfaces as loss when a configured rate exceeds what's delivered. + */ + getStreamContributions(samplesWithTime, sensorId) { + const samples = samplesWithTime; + const subs = [ + { + key: `${sensorId}:accel`, + label: 'Accel', + rate: this.accelHz, + has: (s) => !!s.accel, + }, + { + key: `${sensorId}:gyro`, + label: 'Gyro', + rate: this.gyroHz, + has: (s) => !!s.gyro, + }, + // Mag enters the FIFO at its configured sensor-hub output rate (`magHz`). + { key: `${sensorId}:mag`, label: 'Mag', rate: this.magHz, has: (s) => !!s.mag }, + ]; + const out = []; + for (const sub of subs) { + let count = 0; + let first = null; + let last = null; + for (const s of samples) { + if (!sub.has(s)) + continue; + count++; + const t = s?.timestamps?.tsMillis; + if (typeof t !== 'number') + continue; + if (first == null || t < first) + first = t; + if (last == null || t > last) + last = t; + } + if (count === 0) + continue; // disabled or no samples in this burst + out.push({ + key: sub.key, + label: sub.label, + samplingRateHz: sub.rate > 0 ? sub.rate : null, + sampleCount: count, + firstSampleMillis: first, + lastSampleMillis: last, + }); + } + return out; + } +} +SensorLSM6DSV.TAG_GYRO = 0x01; +SensorLSM6DSV.TAG_ACCEL = 0x02; +SensorLSM6DSV.TAG_SENSORHUB_SLAVE0 = 0x0e; + +/** + * Decoder for the PPG sensor (Verisense sensor id = 4). + * + * Calibration constants mirror C# `SensorPPG.cs`. + */ +class SensorPPG extends SensorBase { + constructor() { + super(); + this.red = false; + this.ir = false; + this.green = false; + this.blue = false; + /** + * 2nd-gen hub mode: PPG arrives via the MAX32674 hub as a fixed block of 6 raw + * MAX86176 LED channels (6 x u24), independent of the RED/IR/GREEN/BLUE enable + * bits. Set from the connected device's hardware generation (see + * VerisenseClient). When false, the 1st-gen named-channel layout is used. + */ + this.hubMode = false; + this.adcLsb = [7.8125, 15.625, 31.25, 62.5]; + this.adcBitShift = [2 ** 7, 2 ** 6, 2 ** 5, 2 ** 4]; + this.adcResolutionIndex = 0; // 0..3 + /** PPG_SR code → base sampling rate in Hz (op byte PPG_MODE_CONFIG2 bits 4:2). */ + this.PPG_SR_HZ = [50, 100, 200, 400, 800, 1000, 1600, 3200]; + /** SMP_AVE code → FIFO sample-averaging factor (op byte PPG_FIFO_CONFIG bits 7:5). */ + this.SMP_AVE_FACTOR = [1, 2, 4, 8, 16, 32, 32, 32]; + this.samplingRateHz = 50; + } + setChannels(channels) { + if (typeof channels.RED === 'boolean') + this.red = channels.RED; + if (typeof channels.IR === 'boolean') + this.ir = channels.IR; + if (typeof channels.GREEN === 'boolean') + this.green = channels.GREEN; + if (typeof channels.BLUE === 'boolean') + this.blue = channels.BLUE; + } + setHubMode(enabled) { + this.hubMode = enabled; + } + setAdcResolutionIndex(i) { + if (i >= 0 && i <= 3) + this.adcResolutionIndex = i; + } + calibrateValue(uncalValue) { + const idx = this.adcResolutionIndex; + return ((uncalValue / this.adcBitShift[idx]) * this.adcLsb[idx]) / 1000.0; + } + /** + * 2nd-gen hub PPG block: N samples x (3 x u24 LED channels = green, IR, red), + * no count prefix (sample count derived from the block length, matching the + * firmware packer). + */ + parseHubPayload(sensorPayloadBytes) { + const bytesPerSample = 9; // 3 channels x 3 bytes + const n = Math.floor(sensorPayloadBytes.length / bytesPerSample); + const out = []; + for (let i = 0; i < n; i++) { + const base = i * bytesPerSample; + out.push({ + leds: [ + u24le(sensorPayloadBytes, base + 0), // green (LED1) + u24le(sensorPayloadBytes, base + 3), // IR (LED2) + u24le(sensorPayloadBytes, base + 6), // red (LED3) + ], + }); + } + return out; + } + parsePayload(sensorPayloadBytes) { + if (this.hubMode) { + return this.parseHubPayload(sensorPayloadBytes); + } + const enabled = []; + if (this.red) + enabled.push('RED'); + if (this.ir) + enabled.push('IR'); + if (this.green) + enabled.push('GREEN'); + if (this.blue) + enabled.push('BLUE'); + const bytesPerSample = enabled.length * 3; + if (bytesPerSample === 0) + return []; + const n = Math.floor(sensorPayloadBytes.length / bytesPerSample); + const out = []; + for (let i = 0; i < n; i++) { + const base = i * bytesPerSample; + let off = 0; + const sample = {}; + for (const ch of enabled) { + const b0 = sensorPayloadBytes[base + off + 0]; + const b1 = sensorPayloadBytes[base + off + 1]; + const b2 = sensorPayloadBytes[base + off + 2]; + off += 3; + let uncal = (b0 | (b1 << 8) | (b2 << 16)) >>> 0; + uncal &= 0x7ffff; + sample[ch] = { + raw: uncal, + cal: this.calibrateValue(uncal), + units: { raw: 'counts', cal: 'scaled' }, + }; + } + out.push(sample); + } + return out; + } + applyOperationalConfig(op) { + // PPG *channel* flags have a hardware-specific bit mapping (1st-gen named + // channels vs MAX86176 hub), so those are still left to setChannels(). The + // sample rate is a well-defined field, though, and it drives per-sample + // timestamp spacing: without it samplingRateHz stays at the 50 Hz default + // and any other configured rate makes consecutive blocks overlap on the + // time axis (the same "zigzag" fixed for GSR/IMU). + const norm = normalizeOperationalConfig(op); + if (!norm) + return; + const srCode = ((norm[OP_IDX.PPG_MODE_CONFIG2] ?? 0) >> 2) & 0x07; + const smpAveCode = ((norm[OP_IDX.PPG_FIFO_CONFIG] ?? 0) >> 5) & 0x07; + const baseHz = this.PPG_SR_HZ[srCode]; + const aveFactor = this.SMP_AVE_FACTOR[smpAveCode] ?? 1; + // The MAX86xxx averages SMP_AVE samples into one FIFO entry, so the streamed + // output rate is the base PPG_SR divided by the averaging factor. + if (baseHz) + this.samplingRateHz = baseHz / aveFactor; + } +} + +/** Slow-sensor sample-rate index -> Hz (matches firmware slowSensorRateMs). This + * is the configured (target) rate the firmware polls at; the sensor's exposure + * may prevent reaching it, which surfaces as packet loss against this rate. */ +const SLOW_SENSOR_RATE_HZ = [0, 0.5, 1, 2, 5, 10, 20]; +/** Op-config index -> exposure µs (matches firmware vd6283_exposureIndexToUs). */ +const EXPOSURE_US_TABLE = [100000, 1600, 6400, 12800, 25600, 51200, 102400, 204800]; +/** Op-config index -> 8.8 fixed-point gain (matches firmware vd6283_gainIndexToValue). */ +const GAIN_8P8_TABLE = [0x0100, 0x01ab, 0x0280, 0x0500, 0x0a00, 0x1900, 0x3200, 0x42ab]; +/** Reference exposure (firmware VD6283TX_DEFAULT_EXPO). */ +const DEFAULT_EXPO_US = 100800; +/** ALS-counts -> XYZ matrix (firmware App_vd6283tx.c). Rows are X, Y, Z. */ +const XYZ_MATRIX = [ + [0.20557, 0.4167, -0.143816], + [-0.028752, 0.506372, -0.120614], + [-0.552625, 0.335866, 0.494781], +]; +/** + * Decoder for the VD6283TX45 ambient light sensor (Verisense sensor id = 7). + * + * Data block payload = N samples x 18 bytes (6 channels x 24-bit LE counts). + * In addition to the raw channel counts, each sample carries the derived lux + * and CCT, computed from the RED/GREEN/BLUE channels with the configured gain + * and exposure (ported from firmware App_vd6283tx.c). + */ +class SensorVD6283 extends SensorBase { + constructor() { + super(); + this.exposureUs = EXPOSURE_US_TABLE[0]; + this.gain8p8 = GAIN_8P8_TABLE[0]; + /** Op-config dark-channel bit (LIGHT_CONFIG bit 1): when set the shared second + * slot carries the dark baseline (`DARK`) instead of the visible reading. */ + this.darkEnabled = false; + this.samplingRateHz = 1; + } + /** Normalise a raw channel count for the XYZ transform (gain + exposure). */ + normalizeForXyz(meas) { + const expoScale = DEFAULT_EXPO_US / this.exposureUs; + // Firmware divides by 256 (16.8 / 8.8 fixed-point); float division here is + // a touch more precise than the firmware's integer division. + return (expoScale * (meas / 256)) / (this.gain8p8 / 256 || 1); + } + /** Compute illuminance (lux) and CCT (K) from RED/GREEN/BLUE counts. */ + computeLuxCct(red, green, blue) { + const r = this.normalizeForXyz(red); + const g = this.normalizeForXyz(green); + const b = this.normalizeForXyz(blue); + const X = XYZ_MATRIX[0][0] * r + XYZ_MATRIX[0][1] * g + XYZ_MATRIX[0][2] * b; + const Y = XYZ_MATRIX[1][0] * r + XYZ_MATRIX[1][1] * g + XYZ_MATRIX[1][2] * b; + const Z = XYZ_MATRIX[2][0] * r + XYZ_MATRIX[2][1] * g + XYZ_MATRIX[2][2] * b; + const lux = Y < 0 ? 0 : Y; + const norm = X + Y + Z; + let cct = 0; + if (norm !== 0) { + const x = X / norm; + const y = Y / norm; + const n = (x - 0.332) / (0.1858 - y); + cct = 449 * n ** 3 + 3525 * n ** 2 + 6823.3 * n + 5520.33; + } + return { lux, cct }; + } + parsePayload(sensorPayloadBytes) { + if (!sensorPayloadBytes?.length) + return []; + const n = Math.floor(sensorPayloadBytes.length / SensorVD6283.BYTES_PER_SAMPLE); + const out = []; + for (let i = 0; i < n; i++) { + const base = i * SensorVD6283.BYTES_PER_SAMPLE; + const RED = u24le(sensorPayloadBytes, base + 0); + // Slot 1 is visible-or-dark depending on the configured dark-channel bit. + const slot1 = u24le(sensorPayloadBytes, base + 3); + const VISIBLE = this.darkEnabled ? null : slot1; + const DARK = this.darkEnabled ? slot1 : null; + const BLUE = u24le(sensorPayloadBytes, base + 6); + const GREEN = u24le(sensorPayloadBytes, base + 9); + const IR = u24le(sensorPayloadBytes, base + 12); + const CLEAR = u24le(sensorPayloadBytes, base + 15); + // lux/CCT derive from RED/GREEN/BLUE, so the dark-channel selection (which + // only affects slot 1) leaves them valid in either mode. + const { lux, cct } = this.computeLuxCct(RED, GREEN, BLUE); + out.push({ RED, VISIBLE, BLUE, GREEN, IR, CLEAR, DARK, lux, cct }); + } + return out; + } + applyOperationalConfig(op) { + this.enabled = (op[OP_IDX.GEN_CFG_3] & (1 << 3)) !== 0; + const rateIdx = op[OP_IDX.LIGHT_SAMPLE_RATE_INDEX] ?? 0; + // Report the configured rate; loss is measured against it so a long exposure + // (or any firmware/hardware shortfall) that prevents reaching it shows up. + this.samplingRateHz = SLOW_SENSOR_RATE_HZ[rateIdx] || 1; + const expoIdx = op[OP_IDX.LIGHT_EXPOSURE_INDEX] ?? 0; + const gainIdx = op[OP_IDX.LIGHT_GAIN_INDEX] ?? 0; + this.exposureUs = EXPOSURE_US_TABLE[expoIdx] ?? EXPOSURE_US_TABLE[0]; + this.gain8p8 = GAIN_8P8_TABLE[gainIdx] ?? GAIN_8P8_TABLE[0]; + // LIGHT_CONFIG bit 1 selects the dark channel on slot 1 (see VD6283Sample). + this.darkEnabled = isVerisenseLightDarkChannelEnabled(op); + } +} +SensorVD6283.NUM_CHANNELS = 6; +SensorVD6283.BYTES_PER_SAMPLE = 18; + +function u16le(bytes, off) { + return (bytes[off] & 0xff) | ((bytes[off + 1] & 0xff) << 8); +} +/** + * Decoder for the MAX32674 algorithm hub (Verisense sensor id = 8). + * + * Data block payload = [sampleCount:1] then sampleCount x 14 bytes: + * accel x,y,z : 3 x i16 (6) | hr u16 (2) | hr_conf u8 (1) | + * spo2 u16 (2) | spo2_conf u8 (1) | activity u8 (1) | scd_contact u8 (1) + * + * Raw PPG is reported separately under the PPG sensor id (4). + */ +class SensorMAX32674 extends SensorBase { + constructor() { + super(); + // Approximate; the hub reports at the configured algorithm report rate. + this.samplingRateHz = 25; + } + parsePayload(sensorPayloadBytes) { + if (!sensorPayloadBytes?.length) + return []; + const count = sensorPayloadBytes[0] ?? 0; + const maxByLength = Math.floor((sensorPayloadBytes.length - 1) / SensorMAX32674.BYTES_PER_SAMPLE); + const n = Math.min(count, maxByLength); + const out = []; + for (let i = 0; i < n; i++) { + const base = 1 + i * SensorMAX32674.BYTES_PER_SAMPLE; + out.push({ + accel: { + raw: [ + i16le(sensorPayloadBytes, base + 0), + i16le(sensorPayloadBytes, base + 2), + i16le(sensorPayloadBytes, base + 4), + ], + }, + hr: u16le(sensorPayloadBytes, base + 6), + hrConfidence: sensorPayloadBytes[base + 8] ?? 0, + spo2: u16le(sensorPayloadBytes, base + 9), + spo2Confidence: sensorPayloadBytes[base + 11] ?? 0, + activityClass: sensorPayloadBytes[base + 12] ?? 0, + scdContactState: sensorPayloadBytes[base + 13] ?? 0, + }); + } + return out; + } + applyOperationalConfig(op) { + this.enabled = (op[OP_IDX.GEN_CFG_3] & (1 << 5)) !== 0; + // samplingRateHz is left at its default; the hub report period mapping is + // hardware-specific and not derived from a single op-config byte. + } +} +SensorMAX32674.BYTES_PER_SAMPLE = 14; + +/** MLX90632 refresh-rate code (op-config byte 76 bits 3:1) -> refresh Hz. The + * single skin-temp rate setting is stored as this code; the output (sample) rate + * is refresh / sub-measurements (medical = 2, extended = 3). */ +const MLX_REFRESH_HZ = [0.5, 1, 2, 4, 8, 16, 32, 64]; +/** + * Decoder for the MLX90632 skin temperature sensor (Verisense sensor id = 9). + * + * Data block payload = N samples x 4 bytes: object int16 then ambient int16, + * each in centi-degrees Celsius (value / 100 = degrees C). + */ +class SensorMLX90632 extends SensorBase { + constructor() { + super(); + this.samplingRateHz = 1; + } + parsePayload(sensorPayloadBytes) { + if (!sensorPayloadBytes?.length) + return []; + const n = Math.floor(sensorPayloadBytes.length / SensorMLX90632.BYTES_PER_SAMPLE); + const out = []; + for (let i = 0; i < n; i++) { + const base = i * SensorMLX90632.BYTES_PER_SAMPLE; + const objRaw = i16le(sensorPayloadBytes, base + 0); + const ambRaw = i16le(sensorPayloadBytes, base + 2); + out.push({ + object: { raw: objRaw, cal: objRaw / 100, units: 'degC' }, + ambient: { raw: ambRaw, cal: ambRaw / 100, units: 'degC' }, + }); + } + return out; + } + applyOperationalConfig(op) { + this.enabled = (op[OP_IDX.GEN_CFG_3] & (1 << 4)) !== 0; + // Single skin-temp rate: stored as the MLX90632 refresh-rate code (byte 76 + // bits 3:1). The output (sample) rate the firmware delivers is the refresh + // rate divided by the sub-measurement count (medical = 2, extended = 3). + const cfg = op[OP_IDX.SKIN_TEMP_CONFIG] ?? 0; + const isExtended = (cfg & 0x01) !== 0; + const refreshCode = (cfg >> 1) & 0x07; + const refreshHz = MLX_REFRESH_HZ[refreshCode] ?? 16; + this.samplingRateHz = refreshHz / (isExtended ? 3 : 2); + } +} +SensorMLX90632.BYTES_PER_SAMPLE = 4; + +function defaultAcceptedCommands(command) { + if (command === ASM_COMMAND.READ) + return new Set([ASM_COMMAND.RESPONSE]); + if (command === ASM_COMMAND.WRITE) { + return new Set([ASM_COMMAND.ACK, ASM_COMMAND.ACK_NEXT_STAGE, ASM_COMMAND.RESPONSE]); + } + return new Set([ASM_COMMAND.ACK, ASM_COMMAND.ACK_NEXT_STAGE, ASM_COMMAND.RESPONSE]); +} +function toCommandResponse(msg) { + return { + header: msg.header, + command: msg.command, + property: msg.property, + payload: msg.payload, + }; +} +function validatePendingResponse(pending, msg) { + if (isNackCommand(msg.command)) { + return new Error(`Device returned NACK command=0x${msg.command.toString(16)} property=0x${msg.property.toString(16)}`); + } + if (pending.acceptedProperties?.size) { + if (!pending.acceptedProperties.has(msg.property)) { + return new Error(`Unexpected response property 0x${msg.property.toString(16)} (expected one of ${Array.from(pending.acceptedProperties) + .map((p) => `0x${p.toString(16)}`) + .join(', ')})`); + } + } + else if (msg.property !== pending.expectedProperty) { + return new Error(`Unexpected response property 0x${msg.property.toString(16)} (expected 0x${pending.expectedProperty.toString(16)})`); + } + if (!pending.acceptedCommands.has(msg.command)) { + return new Error(`Unexpected response command 0x${msg.command.toString(16)} for property 0x${msg.property.toString(16)}`); + } + return null; +} + +// Thrown by connectWithRetry() when disconnect() is called while a connect +// attempt is in flight. Must NOT match any of the retryable-error patterns +// (request timeout / gatt server is disconnected / unexpected response +// property) so it always aborts the retry loop. +const CONNECT_CANCELLED_MESSAGE = 'Connect cancelled: disconnect requested during connect attempt.'; +// --------------------------------------------------------------------------- +// VerisenseBleDevice +// --------------------------------------------------------------------------- +/** + * Web Bluetooth client for the Verisense sensor platform. + * + * Extends {@link BaseShimmerClient} and adds an event-emitter API + * (on/off/emit) for the richer event model the Verisense protocol needs. + * + * Supports: + * - BLE streaming (accel, ADC/GSR, gyro, PPG) + * - Web Serial (USB COM port) as an alternative transport + * - Logged-data download (`transferLoggedData`) + * - Operational config read/write + * + * Events: + * - `"connected"` — `{ name?: string; id?: string; kind?: string }` + * - `"disconnected"` — `{ kind: TransportKind }` + * - `"streaming"` — `{ on: boolean }` + * - `"streamPacket"` / `"data"` — `StreamPacket` + * - `"streamStats"` — `StreamStatsSnapshot` (throttled ~3 Hz live throughput/loss) + * - `"opConfig"` — `{ op: Uint8Array }` + * - `"productionConfig"` — `ProductionConfig` + * - `"commandPayload"` — `{ payload: Uint8Array }` + */ +class VerisenseBleDevice extends BaseShimmerClient { + on(ev, fn) { + if (!this._evMap.has(ev)) + this._evMap.set(ev, new Set()); + this._evMap.get(ev).add(fn); + return () => this.off(ev, fn); + } + off(ev, fn) { + this._evMap.get(ev)?.delete(fn); + } + emit(ev, data) { + const s = this._evMap.get(ev); + if (s) + for (const fn of s) + fn(data); + } + constructor(opts = {}) { + super({ debug: opts.debug ?? true }); + // Event emitter state + this._evMap = new Map(); + // Transport handles + this._transportKind = null; + this.device = null; + this.server = null; + this.service = null; + this.tx = null; + this.rx = null; + this.port = null; + this._serialAbort = null; + this._serialReader = null; + this._serialReadLoopTask = null; + this._onGattDisconnected = null; + this._suppressDisconnectedEvent = false; + // Protocol state + this._mode = 'idle'; + this._rxStreamBuf = new Uint8Array(0); + this._pending = null; + this._loggedChain = Promise.resolve(); + this._sync = null; + this._testReportMode = false; // Flag to capture raw streaming bytes for test reports + this._throughputTestMode = false; // Flag to count raw bytes during a BLE throughput test + this._bootstrapRequestTimeoutOverrideMs = null; + // Set by disconnect() so an in-flight connectWithRetry() loop stops instead + // of treating the resulting GATT teardown as a transient link drop. + this._connectCancelRequested = false; + this._isSecondGenerationHw = false; + // Live stream statistics (throughput / packet-loss). Reset on stream start. + this._streamStats = new StreamStatsTracker(); + this._lastStreamStatsEmitMillis = 0; + // Cached configs + this.operationalConfig = null; + this.productionConfig = null; + // Debug flags + this.debugSync = false; + this._syncRxCount = 0; + this._syncPayloadCount = 0; + /** Per-device calibration last read from the device, or null. */ + this._calibration = null; + this.hardwareIdentifier = opts.hardwareIdentifier ?? 'VERISENSE_PULSE_PLUS'; + this.stripStreamCrc = opts.stripStreamCrc ?? true; + this.sensors = { + 1: new SensorADC(), + 2: new SensorLIS2DW12(), + 3: new SensorLSM6DS3(), + 4: new SensorPPG(), + 6: new SensorLSM6DSV(), + 7: new SensorVD6283(), + 8: new SensorMAX32674(), + 9: new SensorMLX90632(), + }; + this.sensors[1].setHardwareIdentifier(this.hardwareIdentifier); + } + _log(...args) { + if (this.debug) + console.log('[Verisense]', ...args); + } + // Quick accessors + get adc() { + return this.sensors[1]; + } + get accel1() { + return this.sensors[2]; + } + get gyroAccel2() { + return this._isSecondGenerationHw ? this.sensors[6] : this.sensors[3]; + } + get gyroAccel2Lsm6ds3() { + return this.sensors[3]; + } + get gyroAccel2Lsm6dsv() { + return this.sensors[6]; + } + get ppg() { + return this.sensors[4]; + } + _setOperationalConfigErasedFallback(lengthHint) { + const fallbackLen = lengthHint ?? this.operationalConfig?.length ?? VERISENSE_OP_CONFIG_BYTE_SIZE; + const op = new Uint8Array(fallbackLen); + op.fill(0xff); + this.operationalConfig = op; + this.emit('opConfigErased', { raw: new Uint8Array(op) }); + this.emit('opConfig', { op: new Uint8Array(op), erased: true }); + return op; + } + async _bootstrapConfigsAfterConnect() { + await this.readProductionConfigFromDevice(); + try { + await this.readOpConfigFromDevice(); + } + catch (e) { + const msg = e instanceof Error ? e.message : String(e); + const invalidOp = /Invalid operational config returned from device/i.test(msg); + const productionErased = this._isUninitializedBlob(this.productionConfig); + if (invalidOp && productionErased) { + console.warn('[opcfg] invalid operational config during bootstrap; treating as erased because production config is uninitialized', { payloadLengthHint: this.operationalConfig?.length ?? VERISENSE_OP_CONFIG_BYTE_SIZE }); + this._setOperationalConfigErasedFallback(); + return; + } + throw e; + } + } + // --------------------------------------------------------------------------- + // BLE connect / disconnect + // --------------------------------------------------------------------------- + async connect(opts = {}) { + if (this._transportKind === 'serial' || this.port) { + try { + await this.disconnect(); + } + catch { + /* ignore */ + } + } + this._transportKind = 'ble'; + // A previous session's disconnect (including the internal teardown above) + // must not cancel this fresh connect attempt. + this._connectCancelRequested = false; + const requestOpts = { + filters: opts.filters ?? [{ services: [NUS_SERVICE] }], + // NORDIC_DFU_SERVICE must be granted at requestDevice() time so the + // buttonless DFU control point is reachable from rebootToDfuBootloader(). + optionalServices: opts.optionalServices ?? [NUS_SERVICE, NORDIC_DFU_SERVICE], + }; + this.device = opts.device ?? (await navigator.bluetooth.requestDevice(requestOpts)); + try { + if (this._onGattDisconnected && this.device) { + this.device.removeEventListener('gattserverdisconnected', this._onGattDisconnected); + } + } + catch { + /* ignore */ + } + this._onGattDisconnected = () => { + this._mode = 'idle'; + this._transportKind = null; + if (this._suppressDisconnectedEvent) + return; + this.emit('disconnected', { kind: 'ble' }); + }; + this.device.addEventListener('gattserverdisconnected', this._onGattDisconnected); + this.server = await this.device.gatt.connect(); + this.service = await this.server.getPrimaryService(NUS_SERVICE); + this.tx = await this.service.getCharacteristic(NUS_TX); + this.rx = await this.service.getCharacteristic(NUS_RX); + await this.rx.startNotifications(); + this.rx.addEventListener('characteristicvaluechanged', (ev) => { + const dv = ev.target?.value; + if (!dv) + return; + const bytes = new Uint8Array(dv.buffer.slice(dv.byteOffset, dv.byteOffset + dv.byteLength)); + this._feedStreamBytes(bytes); + }); + this._emitStatus(`Connected: ${this.device.name ?? 'Verisense'}`); + this.emit('connected', { name: this.device.name, id: this.device.id }); + await this._bootstrapConfigsAfterConnect(); + return true; + } + async _cleanupFailedBleConnectAttempt(retrySettleMs) { + this._suppressDisconnectedEvent = true; + try { + if (this._onGattDisconnected && this.device) { + this.device.removeEventListener('gattserverdisconnected', this._onGattDisconnected); + } + } + catch { + /* ignore */ + } + try { + if (this.device?.gatt?.connected) { + this.device.gatt.disconnect(); + } + } + catch { + /* ignore */ + } + this.tx = null; + this.rx = null; + this.service = null; + this.server = null; + this._pending = null; + this._mode = 'idle'; + this._transportKind = null; + await new Promise((resolve) => setTimeout(resolve, Math.max(0, retrySettleMs))); + this._suppressDisconnectedEvent = false; + } + async _retryBootstrapInPlaceWithBudget(totalBudgetMs, perAttemptTimeoutMs) { + const budgetMs = Math.max(1000, Math.trunc(totalBudgetMs)); + const attemptTimeoutBaseMs = Math.max(1000, Math.trunc(perAttemptTimeoutMs)); + const deadline = Date.now() + budgetMs; + while (Date.now() < deadline) { + if (this._connectCancelRequested) { + throw new Error(CONNECT_CANCELLED_MESSAGE); + } + const remainingMs = Math.max(1000, deadline - Date.now()); + this._bootstrapRequestTimeoutOverrideMs = Math.min(attemptTimeoutBaseMs, remainingMs); + try { + this._pending = null; + this._resetAssembler(); + await this._bootstrapConfigsAfterConnect(); + return true; + } + catch (e) { + const msg = e instanceof Error ? e.message : String(e); + const retryable = /Unexpected response property/i.test(msg) || + /A request is already pending/i.test(msg) || + /request timeout/i.test(msg); + if (!retryable || Date.now() + 100 >= deadline) { + throw e; + } + await new Promise((resolve) => setTimeout(resolve, 100)); + } + } + return false; + } + async connectWithRetry(opts = {}) { + const { bootstrapTimeoutMs = 3000, pairingBootstrapTimeoutMs = 45000, maxRetries = 2, retrySettleMs = 250, retryOnUnexpectedProperty = true, onRetry = null, ...connectOpts } = opts; + const clampedDefaultTimeoutMs = Math.max(1000, Math.trunc(bootstrapTimeoutMs)); + const clampedPairingTimeoutMs = Math.max(clampedDefaultTimeoutMs, Math.trunc(pairingBootstrapTimeoutMs)); + const clampedMaxRetries = Math.max(0, Math.trunc(maxRetries)); + let lastError = null; + this._connectCancelRequested = false; + for (let attempt = 0; attempt <= clampedMaxRetries; attempt += 1) { + if (this._connectCancelRequested) { + throw new Error(CONNECT_CANCELLED_MESSAGE); + } + const attemptTimeoutMs = clampedDefaultTimeoutMs; + this._bootstrapRequestTimeoutOverrideMs = attemptTimeoutMs; + try { + return await this.connect(connectOpts); + } + catch (e) { + lastError = e; + // An explicit disconnect() during the attempt is a user cancel, not a + // transient link drop — tear down and stop retrying. + if (this._connectCancelRequested) { + await this._cleanupFailedBleConnectAttempt(retrySettleMs); + throw new Error(CONNECT_CANCELLED_MESSAGE, { cause: e }); + } + const msg = e instanceof Error ? e.message : String(e); + const isRequestTimeout = /request timeout/i.test(msg); + const isGattDisconnected = /gatt server is disconnected/i.test(msg); + const isUnexpectedResponseProperty = retryOnUnexpectedProperty && /Unexpected response property/i.test(msg); + const shouldRetry = (isRequestTimeout || isGattDisconnected || isUnexpectedResponseProperty) && + attempt < clampedMaxRetries; + if (!shouldRetry) { + await this._cleanupFailedBleConnectAttempt(retrySettleMs); + throw e; + } + // If pairing/passkey entry is still in progress, a request timeout can occur + // while the BLE link itself remains up. In that case, retry bootstrap in-place + // first to avoid forcing a disconnect that interrupts Windows bonding UX. + if (isRequestTimeout && this.device?.gatt?.connected && this.tx && this.rx) { + onRetry?.({ + attempt, + maxRetries: clampedMaxRetries, + bootstrapTimeoutMs: attemptTimeoutMs, + nextBootstrapTimeoutMs: clampedPairingTimeoutMs, + reason: 'request-timeout', + error: msg, + }); + try { + await this._retryBootstrapInPlaceWithBudget(clampedPairingTimeoutMs, clampedDefaultTimeoutMs); + return true; + } + catch (bootstrapRetryError) { + if (this._connectCancelRequested) { + await this._cleanupFailedBleConnectAttempt(retrySettleMs); + throw new Error(CONNECT_CANCELLED_MESSAGE, { cause: bootstrapRetryError }); + } + lastError = bootstrapRetryError; + } + } + let reason; + if (isRequestTimeout) { + reason = 'request-timeout'; + } + else if (isGattDisconnected) { + reason = 'gatt-disconnected'; + } + else { + reason = 'unexpected-response-property'; + } + onRetry?.({ + attempt, + maxRetries: clampedMaxRetries, + bootstrapTimeoutMs: attemptTimeoutMs, + nextBootstrapTimeoutMs: clampedPairingTimeoutMs, + reason, + error: msg, + }); + await this._cleanupFailedBleConnectAttempt(retrySettleMs); + } + finally { + this._bootstrapRequestTimeoutOverrideMs = null; + } + } + throw lastError instanceof Error ? lastError : new Error('BLE connect failed'); + } + // --- Web Serial (USB COM port) connect --- + async connectSerial(opts = {}) { + if (!('serial' in navigator)) { + throw new Error('Web Serial not supported. Use Chrome/Edge on HTTPS or http://localhost.'); + } + if (this._transportKind === 'ble' && this.device?.gatt?.connected) { + await this.disconnect(); + } + else if (this._transportKind === 'serial' && this.port) { + await this.disconnect(); + } + this._transportKind = 'serial'; + this._mode = 'idle'; + this._resetAssembler(); + const serial = navigator.serial; + if (!opts.port) { + opts.port = await serial.requestPort(opts.filters ? { filters: opts.filters } : undefined); + } + this.port = opts.port; + await this.port.open({ + baudRate: opts.baudRate ?? 115200, + dataBits: opts.dataBits ?? 8, + stopBits: opts.stopBits ?? 1, + parity: opts.parity ?? 'none', + flowControl: opts.flowControl ?? 'none', + }); + this._serialAbort = new AbortController(); + this._startSerialReadLoop(this._serialAbort.signal); + this._emitStatus('Connected via USB Serial'); + this.emit('connected', { kind: 'serial' }); + await this._bootstrapConfigsAfterConnect(); + return true; + } + async _serialWrite(u8) { + const writable = this.port.writable; + if (!writable) + throw new Error('Not connected'); + const writer = writable.getWriter(); + try { + await writer.write(u8); + } + finally { + writer.releaseLock(); + } + } + _startSerialReadLoop(signal) { + const port = this.port; + this._serialReadLoopTask = (async () => { + let reader = null; + try { + const readable = port.readable; + if (!readable) + return; + reader = readable.getReader(); + this._serialReader = reader; + while (!signal.aborted) { + const { value, done } = await reader.read(); + if (done) + break; + if (value?.length) + this._feedStreamBytes(new Uint8Array(value)); + } + } + catch (e) { + if (!signal.aborted) + console.warn('[serial] read loop error:', e); + } + finally { + try { + reader?.releaseLock?.(); + } + catch { + /* ignore */ + } + if (this._serialReader === reader) + this._serialReader = null; + this._serialReadLoopTask = null; + if (!signal.aborted) { + this._mode = 'idle'; + this.emit('disconnected', { kind: 'serial' }); + } + } + })(); + } + async _serialDisconnect(reason = 'user') { + try { + this._serialAbort?.abort(); + } + catch { + /* ignore */ + } + const cancelActiveReader = async () => { + const r = this._serialReader; + if (!r) + return false; + try { + await r.cancel(); + } + catch { + /* ignore */ + } + try { + r.releaseLock(); + } + catch { + /* ignore */ + } + if (this._serialReader === r) + this._serialReader = null; + return true; + }; + await cancelActiveReader(); + const portReadableLocked = this.port + ?.readable?.locked; + if (portReadableLocked && !this._serialReader) { + for (let i = 0; i < 10; i++) { + await new Promise((r) => setTimeout(r, 20)); + if (await cancelActiveReader()) + break; + } + } + try { + const task = this._serialReadLoopTask; + if (task) + await Promise.race([task, new Promise((r) => setTimeout(r, 750))]); + } + catch { + /* ignore */ + } + try { + const writable = this.port?.writable; + if (writable?.locked) { + const w = writable.getWriter(); + try { + await w.abort?.(); + } + catch { + /* ignore */ + } + try { + w.releaseLock(); + } + catch { + /* ignore */ + } + } + } + catch { + /* ignore */ + } + try { + await this.port?.close?.(); + } + catch { + /* ignore */ + } + this.port = null; + this._serialAbort = null; + this._serialReader = null; + this._serialReadLoopTask = null; + console.warn(`[serial] disconnect done reason=${reason}`); + } + async disconnect(opts = {}) { + // If a connectWithRetry() loop is mid-attempt, this explicit disconnect + // must stop it from retrying with the same device. connect() clears the + // flag when the next fresh connect starts. + this._connectCancelRequested = true; + const kind = this._transportKind === 'serial' ? 'serial' : 'ble'; + if (this._mode === 'streaming') { + try { + await this.stopStreaming(); + } + catch { + /* ignore */ + } + } + if (this._sync) { + try { + this._abortSync(new Error(opts.reason ?? 'Disconnected')); + } + catch { + /* ignore */ + } + } + if (this._transportKind === 'serial') { + try { + await this._serialDisconnect(opts.reason ?? 'user'); + } + catch { + /* ignore */ + } + } + else { + // Best-effort courtesy notification; swallow the rejection when the BLE + // transport is not up (e.g. disconnect clicked mid-connect, tx not set). + void this.writeBytes(buildMessage(ASM_COMMAND.WRITE, ASM_PROPERTY.DEVICE_DISCONNECT), { + withResponse: false, + }).catch(() => { }); + try { + if (this.rx) + await this.rx.stopNotifications?.(); + } + catch { + /* ignore */ + } + try { + if (this._onGattDisconnected && this.device) { + this.device.removeEventListener('gattserverdisconnected', this._onGattDisconnected); + } + } + catch { + /* ignore */ + } + try { + if (this.device?.gatt?.connected) + this.device.gatt.disconnect(); + } + catch { + /* ignore */ + } + } + this._mode = 'idle'; + this._transportKind = null; + this.port = null; + this._serialAbort = null; + this.tx = this.rx = null; + this.service = this.server = this.device = null; + this.emit('disconnected', { kind }); + return true; + } + // --------------------------------------------------------------------------- + // Streaming + // --------------------------------------------------------------------------- + async startStreaming() { + // Clear live throughput / packet-loss stats for the new streaming session. + this._streamStats.reset(); + this._lastStreamStatsEmitMillis = 0; + await this.setStreamingMode(true); + this._mode = 'streaming'; + this.emit('streaming', { on: true }); + } + async stopStreaming() { + // Stop is best-effort. The application-level ACK for STREAM_MODE-disable rides + // on BLE notifications, which are unacknowledged and can be dropped under + // high-throughput streaming; the in-flight stream tail is also parsed by the + // command path (not the CRC-gated stream scanner) once we leave streaming + // mode, so the small ACK frame is easily lost or mis-framed. We confirm + // delivery of the disable command via a write-with-response, then reconcile + // local state regardless — a missing ACK must never leave the client wedged + // in 'streaming' (which locks the UI). This mirrors the best-effort stop used + // by Shimmer3RClient and the DEVICE_DISCONNECT path in disconnect(). + try { + await this.writeBytes(buildMessage(ASM_COMMAND.WRITE, ASM_PROPERTY.STREAM_MODE, [STREAM_MODE.DISABLE]), { withResponse: true }); + } + catch (e) { + this._log('stopStreaming: disable write failed; reconciling state anyway:', e); + } + finally { + this._mode = 'idle'; + this._resetAssembler(); + this.emit('streaming', { on: false }); + } + } + // --------------------------------------------------------------------------- + // Logged data transfer + // --------------------------------------------------------------------------- + async transferLoggedData(opts = {}) { + const { fileHandle = null, timeoutMs = 1000, maxNack = 5, maxCrcNack = 5, onProgress = null, } = opts; + const bleOk = !!(this.rx && this.tx); + const serOk = !!this.port; + if (!bleOk && !serOk) + throw new Error('Not connected'); + if (this._mode === 'streaming') + throw new Error('Stop streaming before TransferLoggedData'); + if (this._mode === 'logged') + throw new Error('Already syncing logged data'); + let writable = null; + const chunks = []; + if (fileHandle) + writable = await fileHandle.createWritable(); + this._mode = 'logged'; + this._resetAssembler(); + this._loggedChain = Promise.resolve(); + this._syncRxCount = 0; + this._syncPayloadCount = 0; + const sync = { + receiving: true, + lastReply: 'NONE', + emptyAckCount: 0, + nackCount: 0, + nackCrcCount: 0, + maxNack, + maxCrcNack, + lastRxAt: Date.now(), + timeoutMs, + bytesWritten: 0, + lastPayloadIndex: 0, + resolve: null, + reject: null, + timer: null, + writable, + chunks, + onProgress: onProgress ?? null, + }; + this._sync = sync; + const donePromise = new Promise((resolve, reject) => { + sync.resolve = resolve; + sync.reject = reject; + }); + let watchdogRunning = false; + sync.timer = setInterval(async () => { + if (watchdogRunning) + return; + watchdogRunning = true; + try { + if (!this._sync?.receiving) + return; + const age = Date.now() - this._sync.lastRxAt; + if (age < this._sync.timeoutMs) + return; + try { + if (this._sync.lastReply === 'NONE') { + await this.writeBytes(buildMessage(ASM_COMMAND.READ, ASM_PROPERTY.DATA), { + withResponse: true, + }); + } + else { + this._clearSyncRxBuffers('timeout-nack'); + await this.writeBytes(buildMessage(ASM_COMMAND.NACK_GENERIC, ASM_PROPERTY.DATA)); + this._sync.nackCount++; + this._sync.lastReply = 'NACK'; + if (this._sync.nackCount >= this._sync.maxNack) + throw new Error('Too many NACK timeouts'); + } + this._sync.lastRxAt = Date.now(); + } + catch (e) { + this._abortSync(e instanceof Error ? e : new Error(String(e))); + } + } + finally { + watchdogRunning = false; + } + }, Math.max(250, Math.floor(timeoutMs / 2))); + try { + await this.writeBytes(buildMessage(ASM_COMMAND.READ, ASM_PROPERTY.DATA), { + withResponse: true, + }); + const result = await donePromise; + await (this._loggedChain ?? Promise.resolve()); + if (!fileHandle) { + const blob = new Blob(chunks.map(toArrayBuffer), { type: 'application/octet-stream' }); + return { ...result, blob }; + } + return result; + } + finally { + if (sync.timer) { + clearInterval(sync.timer); + sync.timer = null; + } + if (writable) + await writable.close(); + } + } + // --------------------------------------------------------------------------- + // Request / response helpers + // --------------------------------------------------------------------------- + async writeBytes(bytes, opts = {}) { + const u8 = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes); + if (this._transportKind === 'serial') { + await this._serialWrite(u8); + return; + } + if (!this.tx) + throw new Error('Not connected'); + if (opts.withResponse) { + await this.tx.writeValue(toArrayBuffer(u8)); + return; + } + const txExt = this.tx; + if (txExt.writeValueWithoutResponse) { + await txExt.writeValueWithoutResponse(toArrayBuffer(u8)); + } + else { + await this.tx.writeValue(toArrayBuffer(u8)); + } + } + async _requestByCommand(command, property, payloadBytes = [], timeoutMs = 3000, acceptedCommands, acceptedProperties) { + if (this._pending) + throw new Error('A request is already pending'); + this._mode = 'command'; + this._resetAssembler(); + const req = buildMessage(command, property, payloadBytes); + const accepted = acceptedCommands ?? defaultAcceptedCommands(command); + const pendingPromise = new Promise((resolve, reject) => { + const t = setTimeout(() => { + this._pending = null; + reject(new Error('Request timeout')); + }, timeoutMs); + this._pending = { + expectedProperty: property, + acceptedCommands: accepted, + acceptedProperties, + resolve: (resp) => { + clearTimeout(t); + this._pending = null; + resolve(resp); + }, + reject: (e) => { + clearTimeout(t); + this._pending = null; + reject(e); + }, + }; + }); + await this.writeBytes(req); + return pendingPromise; + } + async readProperty(property, timeoutMs = 3000) { + return this._requestByCommand(ASM_COMMAND.READ, property, [], timeoutMs); + } + async writeProperty(property, payloadBytes = [], timeoutMs = 3000) { + return this._requestByCommand(ASM_COMMAND.WRITE, property, payloadBytes, timeoutMs); + } + async request(opcode, payloadBytes = [], timeoutMs = 3000) { + const { command, property } = parseHeader(opcode & 0xff); + const effectiveTimeoutMs = this._bootstrapRequestTimeoutOverrideMs != null && timeoutMs === 3000 + ? this._bootstrapRequestTimeoutOverrideMs + : timeoutMs; + const rsp = await this._requestByCommand(command, property, payloadBytes, effectiveTimeoutMs); + return { payload: rsp.payload }; + } + // Convenience command methods (all protocol properties) + readStatus() { + return this.request(ASM_COMMAND.READ | ASM_PROPERTY.STATUS1); + } + async readStatusParsed() { + const { payload } = await this.readStatus(); + return parseStatusPayload(payload, 'status1'); + } + readStatus2() { + return this.request(ASM_COMMAND.READ | ASM_PROPERTY.STATUS2); + } + async readStatus2Parsed() { + const { payload } = await this.readStatus2(); + return parseStatusPayload(payload, 'status2'); + } + readData() { + return this.request(ASM_COMMAND.READ | ASM_PROPERTY.DATA); + } + readProductionConfig() { + return this.request(ASM_COMMAND.READ | ASM_PROPERTY.PRODUCTION_CONFIGURATION); + } + readOperationalConfig() { + return this.request(ASM_COMMAND.READ | ASM_PROPERTY.OPERATIONAL_CONFIGURATION); + } + readTime() { + return this.request(ASM_COMMAND.READ | ASM_PROPERTY.TIME); + } + async readTimeUnixSeconds() { + const { payload } = await this.readTime(); + return asmRtcBytesToUnixSeconds(payload); + } + readPendingEvents() { + return this.request(ASM_COMMAND.READ | ASM_PROPERTY.PENDING_EVENTS); + } + async readPendingEventsParsed() { + const { payload } = await this.readPendingEvents(); + return parsePendingEvents(payload); + } + async writeProductionConfig(bytes) { + const payload = normalizeBytePayload(bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes)); + if (!payload || payload.length < 11 || payload.length > 56) { + throw new Error('writeProductionConfig: payload length must be between 11 and 56 bytes'); + } + await this.writeProperty(ASM_PROPERTY.PRODUCTION_CONFIGURATION, payload); + } + async writeOperationalConfig(bytes) { + const payload = normalizeBytePayload(bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes)); + if (!payload || payload.length < 50) { + throw new Error('writeOperationalConfig: payload length must be at least 50 bytes'); + } + // Safety interlock (mirrors firmware): never write a config with both + // Bluetooth and USB disabled, or the device becomes unreachable for + // reconfiguration. Apply to a copy so the caller's buffer is left untouched + // (normalizeBytePayload returns the input reference for a Uint8Array). + const corrected = new Uint8Array(payload); + enforceVerisenseCommsChannelInterlock(corrected); + await this.writeProperty(ASM_PROPERTY.OPERATIONAL_CONFIGURATION, corrected); + } + async writeTime(rtc7) { + const payload = normalizeBytePayload(rtc7 instanceof Uint8Array ? rtc7 : new Uint8Array(rtc7)); + if (!payload || payload.length !== 7) { + throw new Error('writeTime: payload must be exactly 7 bytes'); + } + await this.writeProperty(ASM_PROPERTY.TIME, payload); + } + async writeTimeUnixSeconds(unixSeconds) { + await this.writeTime(unixSecondsToAsmRtcBytes(unixSeconds)); + } + /** + * Request the Verisense firmware to expose the Nordic Secure DFU service. + * + * Writes the ASM `DFU_MODE` property. The firmware treats this as a request + * to enable the buttonless DFU service but does NOT reboot or expose the + * service immediately — it enables it on the next BLE disconnect. The host + * must therefore disconnect and reconnect before the Nordic DFU service (and + * {@link rebootToDfuBootloader}) become available on the connection. + */ + async enableDfuServiceOnNextDisconnect() { + await this.writeProperty(ASM_PROPERTY.DFU_MODE, []); + } + /** + * Reboot the device straight into the Nordic Secure DFU bootloader using the + * buttonless DFU service. + * + * Requires the Nordic DFU service to already be active on the current BLE + * connection — call {@link enableDfuServiceOnNextDisconnect}, then disconnect + * and reconnect first. Writes the "Enter Bootloader" op-code (0x01) to the + * buttonless DFU control-point characteristic; the device acknowledges via an + * indication, then disconnects and resets into the bootloader. + * + * @param options.waitForDisconnect Resolve only once the device drops the + * link (i.e. has begun rebooting). Default `true`. + * @param options.disconnectAfterCommand Force a local GATT disconnect if the + * device has not dropped the link itself. Default `true`. + * @param options.timeoutMs Max time to wait for the device to + * disconnect after the command. Default `10000`. + */ + async rebootToDfuBootloader(options = {}) { + const { waitForDisconnect = true, disconnectAfterCommand = true, timeoutMs = 10000 } = options; + if (this._transportKind !== 'ble' || !this.server || !this.device?.gatt?.connected) { + throw new Error('rebootToDfuBootloader: requires an active BLE connection'); + } + let dfuService; + try { + dfuService = await this.server.getPrimaryService(NORDIC_DFU_SERVICE); + } + catch { + throw new Error('rebootToDfuBootloader: Nordic DFU service is not present on this connection. ' + + 'Call enableDfuServiceOnNextDisconnect(), then disconnect and reconnect first.'); + } + // The buttonless control point lives under one of two UUIDs depending on + // whether the firmware shares its bonds with the bootloader. + let controlPoint = null; + for (const uuid of [NORDIC_DFU_BUTTONLESS_WITHOUT_BONDS, NORDIC_DFU_BUTTONLESS_WITH_BONDS]) { + try { + controlPoint = await dfuService.getCharacteristic(uuid); + break; + } + catch { + /* try the next variant */ + } + } + if (!controlPoint) { + throw new Error('rebootToDfuBootloader: buttonless DFU control-point characteristic not found'); + } + // Start watching for the disconnect before issuing the command so we never + // miss the event if the device reboots immediately. + const disconnected = waitForDisconnect ? this._waitForGattDisconnect(timeoutMs) : null; + // The buttonless control point delivers its response via indications; + // subscribe so the firmware sends it before resetting. Some stacks reject a + // duplicate subscription — the command write below still succeeds. + try { + await controlPoint.startNotifications(); + } + catch { + /* ignore — indication subscription is best-effort */ + } + const cp = controlPoint; + const payload = Uint8Array.from([NORDIC_DFU_OP_ENTER_BOOTLOADER]); + if (cp.writeValueWithResponse) { + await cp.writeValueWithResponse(toArrayBuffer(payload)); + } + else { + await cp.writeValue(toArrayBuffer(payload)); + } + if (disconnected) { + const didDisconnect = await disconnected; + if (!didDisconnect && disconnectAfterCommand && this.device?.gatt?.connected) { + try { + this.device.gatt.disconnect(); + } + catch { + /* ignore */ + } + } + } + else if (disconnectAfterCommand && this.device?.gatt?.connected) { + try { + this.device.gatt.disconnect(); + } + catch { + /* ignore */ + } + } + } + /** + * Resolve when the BLE link drops (`gattserverdisconnected`), or after + * `timeoutMs`. Resolves `true` if the device disconnected, `false` on timeout. + */ + _waitForGattDisconnect(timeoutMs) { + const device = this.device; + if (!device || !device.gatt?.connected) + return Promise.resolve(true); + return new Promise((resolve) => { + let settled = false; + const onDisconnect = () => finish(true); + const finish = (didDisconnect) => { + if (settled) + return; + settled = true; + clearTimeout(timer); + try { + device.removeEventListener('gattserverdisconnected', onDisconnect); + } + catch { + /* ignore */ + } + resolve(didDisconnect); + }; + const timer = setTimeout(() => finish(false), Math.max(0, timeoutMs)); + device.addEventListener('gattserverdisconnected', onDisconnect); + }); + } + async runTestMode(testPayload) { + const payload = normalizeBytePayload(testPayload instanceof Uint8Array ? testPayload : new Uint8Array(testPayload)); + if (!payload || payload.length < 2) { + throw new Error('runTestMode: payload must contain at least [testId, hwMajor]'); + } + await this.writeProperty(ASM_PROPERTY.TEST_MODE, payload); + } + async runHardwareTest(testId, hwMajor, hwMinor = 0, hwInternal = 0) { + const payload = new Uint8Array([ + testId & 0xff, + hwMajor & 0xff, + hwMinor & 0xff, + hwInternal & 0xff, + (hwInternal >> 8) & 0xff, + ]); + await this.runTestMode(payload); + } + /** + * Ask the device to stop/exit any running test, including an in-progress + * hardware test report (TEST_MODE "exit", id 0x00). The firmware acts on this + * from interrupt context, so it aborts the blocking report promptly instead of + * running it to completion against a connection no one is reading. Best-effort + * and safe to call when no test is running. + */ + async stopTestMode(hwMajor = 0, hwMinor = 0, hwInternal = 0) { + await this.runTestMode([ + 0x00, + hwMajor & 0xff, + hwMinor & 0xff, + hwInternal & 0xff, + (hwInternal >> 8) & 0xff, + ]); + } + async runHardwareTestReport(hwMajor, hwMinor = 0, hwInternal = 0, opts = {}) { + const timeoutMs = Math.max(1000, Math.trunc(opts.timeoutMs ?? 120000)); + const completionIdleMs = Math.max(100, Math.trunc(opts.completionIdleMs ?? 1200)); + const marker = String(opts.marker ?? '').trim(); + const endMarker = String(opts.endMarker ?? + (marker.includes('TEST START') ? marker.replace('TEST START', 'TEST END') : '')).trim(); + const factoryTestType = Math.max(0, Math.min(0xff, Math.trunc(opts.factoryTestType ?? 0))); + const abortSignal = opts.signal ?? null; + const onChunk = typeof opts.onChunk === 'function' ? opts.onChunk : null; + const TEST_REPORT_MODE_ID = 0xfe; + const payload = new Uint8Array([ + TEST_REPORT_MODE_ID, + hwMajor & 0xff, + hwMinor & 0xff, + hwInternal & 0xff, + (hwInternal >> 8) & 0xff, + factoryTestType & 0xff, + ]); + return new Promise((resolve, reject) => { + let done = false; + let aggregate = ''; + let decoder; + try { + decoder = new TextDecoder('latin1'); + } + catch { + decoder = new TextDecoder(); + } + let sawMarker = marker.length === 0; + const effectiveIdleMs = Math.max(completionIdleMs, 10000); + let idleTimer = null; + let timeoutTimer = null; + let off = null; + let onAbort = null; + const sanitizeChunk = (text) => { + // Drop control bytes that occasionally appear in factory stream noise + // while preserving CR/LF/TAB for report formatting. + // eslint-disable-next-line no-control-regex -- intentionally strips binary control bytes + return text.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]/g, ''); + }; + const cleanup = () => { + this._testReportMode = false; + if (off) { + try { + off(); + } + catch { + /* ignore */ + } + off = null; + } + if (idleTimer) { + clearTimeout(idleTimer); + idleTimer = null; + } + if (timeoutTimer) { + clearTimeout(timeoutTimer); + timeoutTimer = null; + } + if (abortSignal && onAbort) { + try { + abortSignal.removeEventListener('abort', onAbort); + } + catch { + /* ignore */ + } + onAbort = null; + } + }; + const finish = (err) => { + if (done) + return; + done = true; + cleanup(); + if (err) { + // Best-effort: tell the device to stop the in-progress test/report so it + // doesn't keep running a blocking suite against a connection no one is + // reading (dialog closed / aborted / timed out). The firmware acts on + // this from interrupt context, so the report aborts promptly. + void this.stopTestMode(hwMajor, hwMinor, hwInternal).catch(() => { }); + reject(err); + return; + } + const tail = decoder.decode(); + if (tail) { + aggregate += tail; + } + resolve(aggregate); + }; + const scheduleIdleFinish = () => { + if (idleTimer) + clearTimeout(idleTimer); + idleTimer = setTimeout(() => { + if (!sawMarker) + return; + finish(); + }, effectiveIdleMs); + }; + off = this.on('testReportChunk', (rawChunk) => { + if (done || !rawChunk?.length) + return; + const chunk = sanitizeChunk(decoder.decode(rawChunk, { stream: true })); + if (!chunk.length) + return; + aggregate += chunk; + if (!sawMarker && marker.length > 0 && aggregate.includes(marker)) { + sawMarker = true; + } + const sawEndMarker = (endMarker.length > 0 && aggregate.includes(endMarker)) || /TEST END/.test(aggregate); + if (sawEndMarker) { + finish(); + return; + } + if (onChunk) { + try { + onChunk(chunk, aggregate); + } + catch { + /* ignore callback errors */ + } + } + if (sawMarker) { + scheduleIdleFinish(); + } + }); + timeoutTimer = setTimeout(() => { + finish(new Error(`runHardwareTestReport timeout after ${timeoutMs} ms while waiting for report data`)); + }, timeoutMs); + if (abortSignal) { + if (abortSignal.aborted) { + finish(new Error('runHardwareTestReport aborted')); + return; + } + onAbort = () => finish(new Error('runHardwareTestReport aborted')); + abortSignal.addEventListener('abort', onAbort, { once: true }); + } + // Enable test report mode before sending command + this._testReportMode = true; + void this.runTestMode(payload).catch((e) => { + const msg = e instanceof Error ? e.message : String(e); + finish(new Error(`runHardwareTestReport failed to start test mode: ${msg}`)); + }); + }); + } + _buildDebugPayload(debugId, args = []) { + const argBytes = args instanceof Uint8Array ? args : new Uint8Array(args); + const payload = new Uint8Array(1 + argBytes.length); + payload[0] = debugId & 0xff; + payload.set(argBytes, 1); + return payload; + } + _debugIndexArgs(index) { + const i = Math.max(0, Math.min(0xff, Math.trunc(index))); + return i > 0 ? [i] : []; + } + _waitForDebugResponse(timeoutMs = 3000) { + return new Promise((resolve, reject) => { + let done = false; + let off = null; + let timer = null; + const cleanup = () => { + if (off) { + try { + off(); + } + catch { + /* ignore */ + } + off = null; + } + if (timer) { + clearTimeout(timer); + timer = null; + } + }; + off = this.on('commandPayload', (evt) => { + if (done || !evt) + return; + if (evt.command !== ASM_COMMAND.RESPONSE || evt.property !== ASM_PROPERTY.DEBUG_COMMAND) + return; + done = true; + cleanup(); + resolve({ payload: evt.payload ?? new Uint8Array(0) }); + }); + timer = setTimeout(() => { + if (done) + return; + done = true; + cleanup(); + reject(new Error('Debug response timeout')); + }, timeoutMs); + }); + } + async readDebugCommand(debugId, args = [], timeoutMs = 3000) { + const payload = this._buildDebugPayload(debugId, args); + const debugAcceptedProps = new Set([ASM_PROPERTY.DEBUG_COMMAND, 0]); + // Python flow: WRITE DEBUG command, optional empty/transient frame, then RESPONSE DEBUG payload. + const responsePromise = this._waitForDebugResponse(timeoutMs); + try { + await this._requestByCommand(ASM_COMMAND.WRITE, ASM_PROPERTY.DEBUG_COMMAND, payload, timeoutMs, undefined, debugAcceptedProps); + return await responsePromise; + } + catch (e) { + void responsePromise.catch(() => { }); + const msg = e instanceof Error ? e.message : String(e); + const isDebugNack = /NACK command=0x(?:50|60|70) property=0x9/i.test(msg); + const isDebugAckPropertyZero = /Unexpected response property 0x0 \(expected 0x9\)/i.test(msg); + if (isDebugNack || isDebugAckPropertyZero) { + return this._waitForDebugResponse(timeoutMs); + } + throw e; + } + } + async sendDebugCommand(debugId, args = [], timeoutMs = 3000) { + const rsp = await this._requestByCommand(ASM_COMMAND.WRITE, ASM_PROPERTY.DEBUG_COMMAND, this._buildDebugPayload(debugId, args), timeoutMs); + return { payload: rsp.payload }; + } + /** + * Stream a MAX32674C algorithm-hub firmware image (.msbl) to the device and + * flash it into the hub via the Maxim bootloader. This is a one-time factory + * operation: it blocks the device for ~1-2 minutes while the hub flash is + * erased and each page is written. Only SR68 Pulse+ hardware (the only board + * carrying the hub) accepts it — other hardware NACKs the BEGIN stage. + * + * @param msbl raw .msbl file bytes + * @param onProgress optional progress callback (pagesDone, totalPages) + * @returns the hub application firmware version string read back after flashing + */ + async uploadHubFirmware(msbl, onProgress) { + const img = msbl instanceof Uint8Array ? msbl : new Uint8Array(msbl); + if (img.length < MSBL.HEADER_SIZE) { + throw new Error('uploadHubFirmware: file is too small to be a valid .msbl'); + } + const numPages = img[MSBL.OFF_NUMPAGES] | (img[MSBL.OFF_NUMPAGES + 1] << 8); + const expectedLen = MSBL.HEADER_SIZE + numPages * MSBL.PAGE_FILE_BYTES; + if (numPages === 0 || img.length < expectedLen) { + throw new Error(`uploadHubFirmware: invalid .msbl (pages=${numPages}, length=${img.length}, expected>=${expectedLen})`); + } + // BEGIN: device enters bootloader, programs IV/auth/page-count, erases flash. + try { + await this._requestByCommand(ASM_COMMAND.WRITE, ASM_PROPERTY.DEBUG_COMMAND, this._buildHubUploadPayload(HUB_FW_UPLOAD_STAGE.BEGIN, img.subarray(0, MSBL.HEADER_SIZE)), 15000); + } + catch (e) { + throw new Error(`Hub FW upload BEGIN failed: ${e instanceof Error ? e.message : String(e)}`, { + cause: e, + }); + } + // Pages: stream each page in order, awaiting ACK_NEXT_STAGE (page flashed). + const MAX_PAGE_RETRIES = 5; + for (let page = 0; page < numPages; page++) { + const base = MSBL.HEADER_SIZE + page * MSBL.PAGE_FILE_BYTES; + const pageBytes = img.subarray(base, base + MSBL.PAGE_FILE_BYTES); + let attempt = 0; + for (;;) { + try { + await this._sendHubPage(page, pageBytes); + break; + } + catch (e) { + if (++attempt >= MAX_PAGE_RETRIES) { + await this._abortHubUpload(); + throw new Error(`Hub FW upload failed at page ${page + 1}/${numPages} after ${attempt} attempts: ${e instanceof Error ? e.message : String(e)}`, { cause: e }); + } + } + } + onProgress?.(page + 1, numPages); + } + // END: device resets the hub to application mode and returns its FW version. + const endRsp = await this._requestByCommand(ASM_COMMAND.WRITE, ASM_PROPERTY.DEBUG_COMMAND, this._buildHubUploadPayload(HUB_FW_UPLOAD_STAGE.END), 8000); + return new TextDecoder().decode(endRsp.payload).replace(/\0+$/, '').trim(); + } + /** Build a debug payload `[HUB_FW_UPLOAD, stage, ...stageArgs]`. */ + _buildHubUploadPayload(stage, stageArgs = []) { + const a = stageArgs instanceof Uint8Array ? stageArgs : new Uint8Array(stageArgs); + const staged = new Uint8Array(1 + a.length); + staged[0] = stage & 0xff; + staged.set(a, 1); + return this._buildDebugPayload(DEBUG_COMMAND_ID.HUB_FW_UPLOAD, staged); + } + /** Send one 8208-byte page as in-order <=64-byte chunks; await ACK_NEXT_STAGE. */ + async _sendHubPage(page, pageBytes) { + const CHUNK = 64; // keep each packet within the device's ~96-byte RX buffer + const total = pageBytes.length; + for (let off = 0; off < total; off += CHUNK) { + const end = Math.min(off + CHUNK, total); + const isFinal = end >= total; + const args = new Uint8Array(4 + (end - off)); + args[0] = page & 0xff; + args[1] = (page >> 8) & 0xff; + args[2] = off & 0xff; + args[3] = (off >> 8) & 0xff; + args.set(pageBytes.subarray(off, end), 4); + const payload = this._buildHubUploadPayload(HUB_FW_UPLOAD_STAGE.PAGE_CHUNK, args); + if (isFinal) { + // Final chunk completes the page; the device flashes it (~0.7 s) and + // replies ACK_NEXT_STAGE (or NACK on failure -> throws -> page retry). + await this._requestByCommand(ASM_COMMAND.WRITE, ASM_PROPERTY.DEBUG_COMMAND, payload, 6000); + } + else { + // Mid-page chunk: reliable, in-order delivery via write-with-response, + // with no application-level reply from the device. + await this.writeBytes(buildMessage(ASM_COMMAND.WRITE, ASM_PROPERTY.DEBUG_COMMAND, payload), { + withResponse: true, + }); + } + } + } + /** Best-effort abort: tell the device to reset the hub back to application mode. */ + async _abortHubUpload() { + try { + await this._requestByCommand(ASM_COMMAND.WRITE, ASM_PROPERTY.DEBUG_COMMAND, this._buildHubUploadPayload(HUB_FW_UPLOAD_STAGE.ABORT), 5000); + } + catch { + /* best effort */ + } + } + /** Read the flash lookup table. The read walks the whole flash on-device + * and can time out on busy sensors, so `retries` re-issues the command + * (total attempts = retries + 1) before giving up. Non-finite or negative + * `retries` is treated as 0; rejections are always `Error` instances. */ + async readFlashLookupTable(index = 0, timeoutMs = 12000, retries = 0) { + const extraAttempts = Number.isFinite(retries) ? Math.max(0, Math.trunc(retries)) : 0; + let lastError = null; + for (let attempt = 0; attempt <= extraAttempts; attempt++) { + try { + return await this.readDebugCommand(DEBUG_COMMAND_ID.FLASH_LOOKUP_TABLE_READ, this._debugIndexArgs(index), timeoutMs); + } + catch (e) { + lastError = e; + } + } + if (lastError instanceof Error) + throw lastError; + throw new Error(lastError == null ? 'readFlashLookupTable: read failed' : String(lastError)); + } + async readRealWorldClockScheduler(index = 0) { + return this.readDebugCommand(DEBUG_COMMAND_ID.RWC_SCHEDULER_READ, this._debugIndexArgs(index)); + } + async readRealWorldClockSchedulerParsed(index = 0) { + const { payload } = await this.readRealWorldClockScheduler(index); + return parseSchedulerDebugPayload(payload); + } + async loadTestLookupTable(index = 0) { + return this.readDebugCommand(DEBUG_COMMAND_ID.LOAD_TEST_LOOKUP_TABLE, this._debugIndexArgs(index)); + } + async checkPayloadCrcErrors(index = 0) { + return this.readDebugCommand(DEBUG_COMMAND_ID.CHECK_PAYLOAD_CRC_ERRORS, this._debugIndexArgs(index)); + } + async checkPayloadCrcErrorsParsed(index = 0) { + const { payload } = await this.checkPayloadCrcErrors(index); + return parsePayloadCrcErrorBankIndexes(payload); + } + async readEventLog(index = 0) { + return this.readDebugCommand(DEBUG_COMMAND_ID.READ_EVENT_LOG, this._debugIndexArgs(index)); + } + async readEventLogParsed(index = 0) { + const { payload } = await this.readEventLog(index); + return parseEventLogPayload(payload); + } + async readRecordBufferDetails(index = 0) { + return this.readDebugCommand(DEBUG_COMMAND_ID.READ_RECORD_BUFFER_DETAILS, this._debugIndexArgs(index)); + } + async readRecordBufferDetailsParsed(index = 0) { + const { payload } = await this.readRecordBufferDetails(index); + return parseRecordBufferDetailsPayload(payload); + } + async eraseOperationalConfig() { + await this.sendDebugCommand(DEBUG_COMMAND_ID.ERASE_OPERATIONAL_CONFIG); + } + async eraseProductionConfig() { + await this.sendDebugCommand(DEBUG_COMMAND_ID.ERASE_PRODUCTION_CONFIG); + } + async clearPendingEvents() { + await this.sendDebugCommand(DEBUG_COMMAND_ID.CLEAR_PENDING_EVENTS); + } + async eraseAllLoggedData(timeoutMs = 12000) { + await this.sendDebugCommand(DEBUG_COMMAND_ID.ERASE_FLASH_AND_LOOKUP_TABLE, [], timeoutMs); + } + /** + * Low-level: ask the device to saturate the BLE link with dummy data for + * `durationMs` milliseconds (debug command 0x0B). The device ACKs immediately + * and then blasts a fixed 244-byte buffer as fast as the link will accept it. + * + * This only starts the blast; it does not measure anything. Prefer + * {@link runBleThroughputTest}, which sends this command and measures the + * throughput actually received at the host. + * + * @param durationMs Blast duration in milliseconds (clamped to the protocol's 0..65535 range). + */ + async testDataTransferLoop(durationMs) { + const clamped = Math.max(0, Math.min(0xffff, Math.trunc(durationMs))); + await this.sendDebugCommand(DEBUG_COMMAND_ID.TEST_DATA_TRANSFER_LOOP, [ + clamped & 0xff, + (clamped >> 8) & 0xff, + ]); + } + /** + * Measure the maximum BLE link throughput, independent of sensor + * configuration. Asks the device to blast dummy data for `durationMs` + * (see {@link testDataTransferLoop}) and measures the goodput actually + * received at the host. + * + * The reported rate reflects device→host (notification) throughput and is + * governed by the negotiated PHY, connection interval, MTU and packets per + * connection interval — i.e. the real link, not any sensor's sample rate. + * + * The measurement finishes when the device falls silent for `idleMs` after + * the blast (or when the overall safety timeout elapses). + * + * @returns received byte/packet counts and the computed throughput. + */ + async runBleThroughputTest(opts = {}) { + const durationMs = Math.max(100, Math.min(60000, Math.trunc(opts.durationMs ?? 5000))); + const idleMs = Math.max(100, Math.min(5000, Math.trunc(opts.idleMs ?? 600))); + const overallTimeoutMs = Math.max(durationMs + 1000, Math.trunc(opts.timeoutMs ?? durationMs + 5000)); + const abortSignal = opts.signal ?? null; + const onProgress = typeof opts.onProgress === 'function' ? opts.onProgress : null; + return new Promise((resolve, reject) => { + let done = false; + let bytes = 0; + let packets = 0; + let firstByteMs = 0; + let lastByteMs = 0; + let idleTimer = null; + let timeoutTimer = null; + let off = null; + let onAbort = null; + const buildResult = () => { + const elapsedMs = packets > 1 && lastByteMs > firstByteMs ? lastByteMs - firstByteMs : durationMs; + const bps = elapsedMs > 0 ? (bytes * 1000) / elapsedMs : 0; + return { + bytesReceived: bytes, + packetsReceived: packets, + durationRequestedMs: durationMs, + elapsedMs, + throughputBytesPerSec: bps, + throughputKBps: bps / 1000, + throughputKbps: (bps * 8) / 1000, + }; + }; + const cleanup = () => { + this._throughputTestMode = false; + if (off) { + try { + off(); + } + catch { + /* ignore */ + } + off = null; + } + if (idleTimer) { + clearTimeout(idleTimer); + idleTimer = null; + } + if (timeoutTimer) { + clearTimeout(timeoutTimer); + timeoutTimer = null; + } + if (abortSignal && onAbort) { + try { + abortSignal.removeEventListener('abort', onAbort); + } + catch { + /* ignore */ + } + onAbort = null; + } + }; + const finish = (err) => { + if (done) + return; + done = true; + cleanup(); + if (err) + reject(err); + else + resolve(buildResult()); + }; + const scheduleIdleFinish = () => { + if (idleTimer) + clearTimeout(idleTimer); + idleTimer = setTimeout(() => { + // Only finish on idle once data has actually started arriving. + if (packets > 0) + finish(); + }, idleMs); + }; + off = this.on('throughputChunk', (len) => { + if (done || !len) + return; + const now = nowMillis(); + if (packets === 0) + firstByteMs = now; + lastByteMs = now; + bytes += len; + packets++; + if (onProgress) { + try { + onProgress(buildResult()); + } + catch { + /* ignore callback errors */ + } + } + scheduleIdleFinish(); + }); + // Safety net: the device stops after durationMs, so the idle gap should + // normally finish first. If it never does, finalize with what we have. + timeoutTimer = setTimeout(() => finish(), overallTimeoutMs); + if (abortSignal) { + if (abortSignal.aborted) { + finish(new Error('runBleThroughputTest aborted')); + return; + } + onAbort = () => finish(new Error('runBleThroughputTest aborted')); + abortSignal.addEventListener('abort', onAbort, { once: true }); + } + // Enable raw-count mode before sending so no blast bytes are missed. The + // ACK is consumed by the normal command path (while _pending is set); the + // dummy blast that follows is counted by the _feedStreamBytes branch. + this._throughputTestMode = true; + void this.testDataTransferLoop(durationMs).catch((e) => { + const msg = e instanceof Error ? e.message : String(e); + finish(new Error(`runBleThroughputTest failed to start: ${msg}`)); + }); + }); + } + async ledTest(ledIndex) { + await this.sendDebugCommand(DEBUG_COMMAND_ID.LED_TEST, [ledIndex & 0xff]); + } + async max86xxxLedTest(start) { + await this.sendDebugCommand(DEBUG_COMMAND_ID.MAX86XXX_LED_TEST, [start ? 0x01 : 0x00]); + } + async startPowerProfilerTest() { + await this.sendDebugCommand(DEBUG_COMMAND_ID.POWER_PROFILER_TEST); + } + async requestSystemReset() { + await this.sendDebugCommand(DEBUG_COMMAND_ID.SYSTEM_RESET); + } + async startIcPowerConsumptionTest(loopCount, stageIntervalMs) { + const clampedLoopCount = Math.max(0, Math.min(0xffff, Math.trunc(loopCount))); + const clampedStageInterval = Math.max(0, Math.min(0xffff, Math.trunc(stageIntervalMs))); + await this.sendDebugCommand(DEBUG_COMMAND_ID.IC_POWER_CONSUMPTION_TEST, [ + clampedLoopCount & 0xff, + (clampedLoopCount >> 8) & 0xff, + clampedStageInterval & 0xff, + (clampedStageInterval >> 8) & 0xff, + ]); + } + async deleteAllBonds() { + await this.sendDebugCommand(DEBUG_COMMAND_ID.DELETE_ALL_BONDS); + } + async _assertBleLinkDebugSupported() { + let parsed; + if (this.productionConfig?.length) { + if (this._isErasedBlob(this.productionConfig)) { + throw new Error('BLE link debug commands require firmware >= 1.4.23, but production config is erased.'); + } + parsed = parseProductionConfigPayload(this.productionConfig); + } + else { + parsed = await this.readProductionConfigFromDevice(); + if (this._isErasedBlob(this.productionConfig)) { + throw new Error('BLE link debug commands require firmware >= 1.4.23, but production config is erased.'); + } + } + const current = { + major: Number(parsed.revFwMajor), + minor: Number(parsed.revFwMinor), + internal: Number(parsed.revFwInternal), + }; + if (!Number.isFinite(current.major) || + !Number.isFinite(current.minor) || + !Number.isFinite(current.internal)) { + throw new Error('BLE link debug commands require firmware >= 1.4.23, but firmware version is unavailable.'); + } + const min = BLE_LINK_MIN_FW; + if (compareVerisenseFirmwareVersion(current, min) < 0) { + throw new Error(`BLE link debug commands require firmware >= ${formatVerisenseFirmwareVersion(min)} (current ${formatVerisenseFirmwareVersion(current)}).`); + } + } + async readBleLinkParams() { + await this._assertBleLinkDebugSupported(); + return this.readDebugCommand(DEBUG_COMMAND_ID.BLE_LINK_PARAMS_READ); + } + async readBleLinkParamsParsed() { + const { payload } = await this.readBleLinkParams(); + return parseBleLinkDebugPayload(payload); + } + async optimizeBleLink() { + await this._assertBleLinkDebugSupported(); + return this.readDebugCommand(DEBUG_COMMAND_ID.BLE_LINK_OPTIMIZE); + } + async optimizeBleLinkParsed() { + const { payload } = await this.optimizeBleLink(); + return parseBleLinkDebugPayload(payload); + } + _bleLinkSignature(parsed) { + return [ + parsed.attMtu, + parsed.maxDataLength, + parsed.connectionIntervalUnits, + parsed.txPhy, + parsed.rxPhy, + parsed.isConnected ? 1 : 0, + ].join('|'); + } + _bleLinkOptimizedEnough(parsed, { targetConnectionIntervalUnits, targetPhy, minDataLength, }) { + const intervalOk = parsed.connectionIntervalUnits <= targetConnectionIntervalUnits; + const phyOk = parsed.txPhy === targetPhy && parsed.rxPhy === targetPhy; + const mtuBoundDataLength = Math.max(20, (parsed.attMtu || 23) - 3); + const requiredDataLength = Math.min(minDataLength, mtuBoundDataLength); + const dataLenOk = parsed.maxDataLength >= requiredDataLength; + return intervalOk && phyOk && dataLenOk; + } + _isAbortError(error) { + if (error?.name === 'AbortError') + return true; + const msg = error instanceof Error ? error.message : String(error); + return /abort/i.test(msg); + } + _waitWithAbort(ms, signal) { + if (!Number.isFinite(ms) || ms <= 0) + return Promise.resolve(); + if (signal?.aborted) { + const err = new Error('Operation aborted'); + err.name = 'AbortError'; + return Promise.reject(err); + } + return new Promise((resolve, reject) => { + const timer = setTimeout(() => { + if (signal) + signal.removeEventListener('abort', onAbort); + resolve(); + }, ms); + const onAbort = () => { + clearTimeout(timer); + if (signal) + signal.removeEventListener('abort', onAbort); + const err = new Error('Operation aborted'); + err.name = 'AbortError'; + reject(err); + }; + if (signal) { + signal.addEventListener('abort', onAbort, { once: true }); + } + }); + } + async autoOptimizeBleLink(opts = {}) { + const startedAt = nowMillis(); + const pollIntervalMs = Math.max(100, Math.trunc(opts.pollIntervalMs ?? 700)); + const stableReadCount = Math.max(1, Math.trunc(opts.stableReadCount ?? 3)); + const maxDurationMs = Math.max(pollIntervalMs, Math.trunc(opts.maxDurationMs ?? 20000)); + const settleMode = opts.settleMode === 'stability' ? 'stability' : 'target-and-stability'; + const minSettleTimeMs = Math.max(0, Math.trunc(opts.minSettleTimeMs ?? (settleMode === 'stability' ? pollIntervalMs * 2 : 0))); + const forceOptimizeAttempts = Math.max(0, Math.trunc(opts.forceOptimizeAttempts ?? (settleMode === 'stability' ? 2 : 0))); + const targetConnectionIntervalUnits = Math.max(6, Math.trunc(opts.targetConnectionIntervalUnits ?? 6)); + const targetPhy = Math.max(1, Math.min(4, Math.trunc(opts.targetPhy ?? 2))); + const minDataLength = Math.max(20, Math.min(251, Math.trunc(opts.minDataLength ?? 251))); + const signal = opts.signal ?? null; + let iterations = 0; + let optimizeAttempts = 0; + let stableCount = 0; + let lastSignature = ''; + let lastParsed = null; + const finish = (reason) => ({ + reason, + iterations, + optimizeAttempts, + stableCount, + lastParsed, + durationMs: Math.max(0, nowMillis() - startedAt), + }); + if (this._transportKind !== 'ble') + return finish('not-ble'); + if (signal?.aborted) + return finish('aborted'); + while (nowMillis() - startedAt < maxDurationMs) { + if (signal?.aborted) + return finish('aborted'); + if (this._transportKind !== 'ble') + return finish('not-ble'); + let parsed; + try { + parsed = await this.readBleLinkParamsParsed(); + } + catch (error) { + if (this._isAbortError(error)) + return finish('aborted'); + const msg = error instanceof Error ? error.message : String(error); + if (/require firmware >=|unavailable on this firmware|firmware version is unavailable/i.test(msg)) { + return finish('unsupported'); + } + throw error; + } + iterations += 1; + lastParsed = parsed; + let signature = this._bleLinkSignature(parsed); + stableCount = signature === lastSignature ? stableCount + 1 : 1; + lastSignature = signature; + let optimizedEnough = this._bleLinkOptimizedEnough(parsed, { + targetConnectionIntervalUnits, + targetPhy, + minDataLength, + }); + if (typeof opts.onSample === 'function') { + opts.onSample({ + source: 'read', + iteration: iterations, + stableCount, + parsed, + signature, + optimizedEnough, + }); + } + const shouldOptimize = settleMode === 'stability' ? optimizeAttempts < forceOptimizeAttempts : !optimizedEnough; + if (shouldOptimize) { + try { + parsed = await this.optimizeBleLinkParsed(); + } + catch (error) { + if (this._isAbortError(error)) + return finish('aborted'); + throw error; + } + optimizeAttempts += 1; + lastParsed = parsed; + signature = this._bleLinkSignature(parsed); + stableCount = signature === lastSignature ? stableCount + 1 : 1; + lastSignature = signature; + optimizedEnough = this._bleLinkOptimizedEnough(parsed, { + targetConnectionIntervalUnits, + targetPhy, + minDataLength, + }); + if (typeof opts.onSample === 'function') { + opts.onSample({ + source: 'optimize', + iteration: iterations, + stableCount, + parsed, + signature, + optimizedEnough, + }); + } + } + const elapsedMs = Math.max(0, nowMillis() - startedAt); + const stableReady = stableCount >= stableReadCount && elapsedMs >= minSettleTimeMs; + const settleReady = settleMode === 'stability' ? stableReady : stableReady && optimizedEnough; + if (settleReady) { + return finish('stabilized'); + } + try { + await this._waitWithAbort(pollIntervalMs, signal); + } + catch (error) { + if (this._isAbortError(error)) + return finish('aborted'); + throw error; + } + } + return finish('timeout'); + } + async setStreamingMode(enabled) { + await this.writeProperty(ASM_PROPERTY.STREAM_MODE, [enabled ? STREAM_MODE.ENABLE : STREAM_MODE.DISABLE], 3000); + } + async disconnectRequest() { + try { + return await this.request(ASM_COMMAND.WRITE | ASM_PROPERTY.DEVICE_DISCONNECT, [], 1500); + } + catch (e) { + const msg = e instanceof Error ? e.message : String(e); + if (/timeout/i.test(msg)) + return { payload: new Uint8Array(0) }; + throw e; + } + } + // --------------------------------------------------------------------------- + // Operational config helpers + // --------------------------------------------------------------------------- + async getOpConfig() { + if (this.operationalConfig?.length) + return new Uint8Array(this.operationalConfig); + throw new Error('Operational config not cached. Call readOpConfigFromDevice() first.'); + } + _isErasedBlob(payload) { + return isUniformByteArray(payload, 0xff); + } + _isZeroBlob(payload) { + return isUniformByteArray(payload, 0x00); + } + _isUninitializedBlob(payload) { + return this._isErasedBlob(payload) || this._isZeroBlob(payload); + } + async readProductionConfigFromDevice() { + const rsp = await this.readProductionConfig(); + const prod = normalizeOperationalConfig(rsp?.payload); + if (!prod?.length) + throw new Error('Invalid production config returned from device'); + const erased = this._isErasedBlob(prod); + this.productionConfig = prod; + const parsed = parseProductionConfigPayload(prod); + if (!erased && typeof parsed.revHwMajor === 'number' && typeof parsed.revHwMinor === 'number') { + const hwIdentifier = parsed.revHwMajor === 62 ? 'VERISENSE_GSR_PLUS' : 'VERISENSE_PULSE_PLUS'; + this.adc.setHardwareIdentifier(hwIdentifier); + this.adc.setHardwareRevision(parsed.revHwMajor, parsed.revHwMinor, typeof parsed.revHwInternal === 'number' ? parsed.revHwInternal : 0); + this._isSecondGenerationHw = isVerisenseSecondGenerationHardware(parsed.revHwMajor, parsed.revHwMinor); + // On 2nd-gen hardware the raw PPG (id 4) is the 6-channel MAX86176 block + // drained from the hub, not the 1st-gen named-channel layout. + this.ppg.setHubMode(this._isSecondGenerationHw); + } + if (erased) { + this.emit('productionConfigErased', { raw: new Uint8Array(prod) }); + } + this.emit('productionConfig', parsed); + return parsed; + } + async readOpConfigFromDevice() { + const rsp = await this.readOperationalConfig(); + const op = normalizeOperationalConfig(rsp?.payload); + // Some firmware erase flows can return an empty payload for operational config. + // Treat this as erased (all 0xFF) instead of invalid. + if (!op?.length) { + return this._setOperationalConfigErasedFallback(); + } + if (this._isZeroBlob(op)) { + console.warn('[opcfg] operational config payload is all 0x00; treating as erased'); + return this._setOperationalConfigErasedFallback(op.length); + } + const erased = this._isErasedBlob(op); + if (!erased && op[0] !== 0x5a) { + throw new Error('Invalid operational config returned from device'); + } + this.operationalConfig = op; + if (!erased) { + try { + this.applyOperationalConfig(op); + } + catch (e) { + console.warn('[opcfg] apply after read failed:', e); + } + } + else { + this.emit('opConfigErased', { raw: new Uint8Array(op) }); + } + this.emit('opConfig', { op, erased }); + return new Uint8Array(op); + } + /** + * Push an operational config into every sensor decoder (rates, ranges, + * channel enables) and cache it as the client's working config. Used + * automatically after {@link readOpConfigFromDevice}; call it directly when + * loading a config from a template/file without a device round-trip. + */ + applyOperationalConfig(opConfigBytes) { + const op = opConfigBytes instanceof Uint8Array ? opConfigBytes : new Uint8Array(opConfigBytes); + this.operationalConfig = op; + this.accel1.applyOperationalConfig(op); + this.sensors[3].applyOperationalConfig(op); + this.sensors[6].applyOperationalConfig(op); + this.adc.applyOperationalConfig(op); + this.ppg.applyOperationalConfig(op); + this.sensors[7].applyOperationalConfig(op); + this.sensors[8].applyOperationalConfig(op); + this.sensors[9].applyOperationalConfig(op); + } + async writeOpConfig(opConfigBytes) { + const op = normalizeOperationalConfig(opConfigBytes instanceof Uint8Array ? opConfigBytes : new Uint8Array(opConfigBytes)); + if (!op || op.length < 4) + throw new Error('writeOpConfig: invalid opconfig'); + if (op[0] !== 0x5a) + throw new Error('writeOpConfig: opconfig must start with 0x5A'); + await this.writeOperationalConfig(op); + await this.readOpConfigFromDevice(); + } + /** The parsed calibration set last read via {@link readCalibrationParsed}, or null. */ + getCalibration() { + return this._calibration; + } + /** + * Read the raw calibration blob from the device (CMD_AR_CFG_CALIB). The whole + * blob (~1 KB) arrives in one response, reassembled across BLE/USB fragments. + * Requires FW v2.0.4+; older firmware NACKs or times out. + */ + async readCalibration(timeoutMs = 8000) { + const rsp = await this.readProperty(ASM_PROPERTY.CALIBRATION, timeoutMs); + const blob = rsp.payload; + if (!blob || blob.length < SC_GLOBAL_HEADER_BYTES) { + throw new Error('readCalibration: device returned no/short calibration blob'); + } + return new Uint8Array(blob); + } + /** + * Read + parse the calibration set, cache it, and push it into the IMU + * decoders so subsequent samples calibrate from per-device values. Call before + * a logged-data transfer and/or after connect (no-op on FW that lacks it — + * the call rejects and the decoders keep their full-scale fallback). + */ + async readCalibrationParsed() { + const blob = await this.readCalibration(); + const set = parseCalibrationBlob(blob); + this._calibration = set; + try { + this.accel1.applyCalibration(set); + this.sensors[6].applyCalibration(set); + } + catch (e) { + console.warn('[calib] apply after read failed:', e); + } + return set; + } + /** + * Write a calibration blob to the device (CMD_AR_CFG_CALIB), chunked in + * <=128-byte pieces as [offset_lo, offset_hi, ...chunk]. The device reassembles + * and commits on the final chunk. Requires FW v2.0.4+. + */ + async writeCalibration(blob, chunkSize = 128) { + if (!blob || blob.length < SC_GLOBAL_HEADER_BYTES) { + throw new Error('writeCalibration: invalid calibration blob'); + } + const step = Math.max(1, Math.min(chunkSize, 128)); // firmware ramWrite caps chunks at 128 + for (let offset = 0; offset < blob.length; offset += step) { + const chunk = blob.subarray(offset, Math.min(offset + step, blob.length)); + const payload = new Uint8Array(2 + chunk.length); + payload[0] = offset & 0xff; + payload[1] = (offset >> 8) & 0xff; + payload.set(chunk, 2); + await this.writeProperty(ASM_PROPERTY.CALIBRATION, payload); + } + } + getSensor(name) { + const k = String(name ?? '').toLowerCase(); + if (!k) + return null; + if (k.includes('lis2dw12') || k.includes('accel1') || k === '2') + return this.accel1; + if (k.includes('lsm6dsv') || k === '6') + return this.sensors[6]; + if (k.includes('lsm6') || k.includes('gyro') || k.includes('accel2') || k === '3') + return this.gyroAccel2; + if (k.includes('vbatt') || k.includes('batt') || k.includes('battery') || k.includes('adc')) + return this.adc; + if (k.includes('gsr') || k === '1') + return this.adc; + if (k.includes('ppg') || k === '4') + return this.ppg; + return null; + } + // --------------------------------------------------------------------------- + // RX assembly and dispatch + // --------------------------------------------------------------------------- + _abortSync(err) { + const s = this._sync; + if (!s) + return; + s.receiving = false; + if (s.timer) + clearInterval(s.timer); + this._sync = null; + this._mode = 'idle'; + s.reject(err); + } + _finishSync() { + const s = this._sync; + if (!s) + return; + s.receiving = false; + if (s.timer) + clearInterval(s.timer); + const bytesWritten = s.bytesWritten; + const payloadIndex = s.lastPayloadIndex; + this._sync = null; + this._mode = 'idle'; + s.resolve({ ok: true, bytesWritten, payloadIndex }); + } + async _handleLoggedPayload(payloadU8) { + this._syncPayloadCount++; + const s = this._sync; + if (!s) + return; + const computed = computeCrcLikeCSharp(payloadU8); + const original = getOriginalCrcLE(payloadU8); + const crcOk = computed === original; + const payloadIndex = u16le_at(payloadU8, 0); + if (!crcOk) { + s.lastReply = 'NACK'; + s.nackCrcCount++; + this._clearSyncRxBuffers('crc-nack'); + await this.writeBytes(buildMessage(ASM_COMMAND.NACK_GENERIC, ASM_PROPERTY.DATA)); + if (s.nackCrcCount >= s.maxCrcNack) + this._abortSync(new Error('Too many CRC failures')); + s.onProgress?.({ payloadIndex, bytesWritten: s.bytesWritten, crcOk: false }); + return; + } + s.lastPayloadIndex = payloadIndex; + if (s.writable) { + await s.writable.write(toArrayBuffer(payloadU8)); + } + else { + s.chunks.push(new Uint8Array(payloadU8)); + } + s.bytesWritten += payloadU8.length; + s.emptyAckCount = 0; + s.lastReply = 'ACK'; + s.nackCount = 0; + s.nackCrcCount = 0; + await this.writeBytes(buildMessage(ASM_COMMAND.ACK_NEXT_STAGE, ASM_PROPERTY.DATA), { + withResponse: true, + }); + s.onProgress?.({ payloadIndex, bytesWritten: s.bytesWritten, crcOk: true }); + } + _resetAssembler() { + this._rxStreamBuf = new Uint8Array(0); + } + _appendStreamBuf(chunk) { + const merged = new Uint8Array(this._rxStreamBuf.length + chunk.length); + merged.set(this._rxStreamBuf, 0); + merged.set(chunk, this._rxStreamBuf.length); + this._rxStreamBuf = merged; + } + _clearSyncRxBuffers(reason = '') { + this._rxStreamBuf = new Uint8Array(0); + this._resetAssembler(); + if (this.debugSync) + console.warn('[sync] cleared RX buffers', { reason }); + } + _isPlausibleHeaderByte(hdr) { + const command = hdr & 0xf0; + const property = hdr & 0x0f; + const validCommand = command === ASM_COMMAND.READ || + command === ASM_COMMAND.WRITE || + command === ASM_COMMAND.RESPONSE || + command === ASM_COMMAND.ACK || + command === ASM_COMMAND.NACK_BAD_HEADER_COMMAND || + command === ASM_COMMAND.NACK_BAD_HEADER_PROPERTY || + command === ASM_COMMAND.NACK_GENERIC || + command === ASM_COMMAND.ACK_NEXT_STAGE; + if (!validCommand) + return false; + // Known properties are 0x01..0x0D; keep 0x00 permissive for transient frames. + return (property === 0 || (property >= ASM_PROPERTY.STATUS1 && property <= ASM_PROPERTY.CALIBRATION)); + } + _isPlausibleFrameStart(hdr, len) { + // Logged sync frames can be large and should be length-gated like the working single-file implementation. + if (this._mode === 'logged') { + return len <= VerisenseBleDevice.MAX_FRAME_PAYLOAD_LEN; + } + if (!this._isPlausibleHeaderByte(hdr)) + return false; + // Debug responses may carry large blobs (for example flash lookup tables), + // while normal properties and streaming/logged payloads should stay bounded. + // DEBUG and CALIBRATION responses can be large (lookup tables / the ~1 KB + // calibration blob) and arrive across multiple fragments. + const expectsLargeResponse = this._mode === 'command' && + (this._pending?.expectedProperty === ASM_PROPERTY.DEBUG_COMMAND || + this._pending?.expectedProperty === ASM_PROPERTY.CALIBRATION); + const maxLen = expectsLargeResponse + ? VerisenseBleDevice.MAX_DEBUG_FRAME_PAYLOAD_LEN + : VerisenseBleDevice.MAX_FRAME_PAYLOAD_LEN; + return len <= maxLen; + } + _resolvePendingCommand(msg) { + const pending = this._pending; + if (pending) { + // Some firmware/transport paths emit a transient empty 0x00/0x00 frame + // immediately before the real command response; ignore and keep waiting. + if (msg.command === 0 && + msg.property === 0 && + msg.payload.length === 0) { + return; + } + const err = validatePendingResponse(pending, msg); + if (err) { + this._pending = null; + if (this._mode === 'command') + this._mode = 'idle'; + pending.reject(err); + } + else { + this._pending = null; + if (this._mode === 'command') + this._mode = 'idle'; + pending.resolve(toCommandResponse(msg)); + } + } + else { + this._pending = null; + if (this._mode === 'command') + this._mode = 'idle'; + } + this.emit('commandPayload', { + header: msg.header, + command: msg.command, + property: msg.property, + payload: msg.payload, + }); + } + _feedStreamBytes(chunk) { + if (this._mode === 'logged' && this._sync) + this._sync.lastRxAt = Date.now(); + // Test report data is streamed as raw text bytes after the initial ACK. + // Once the command pending state is cleared, bypass frame parsing entirely. + if (this._testReportMode && !this._pending) { + if (chunk?.length) + this.emit('testReportChunk', chunk); + return; + } + // Throughput-test data is raw dummy bytes streamed after the initial ACK. + // The ACK itself is consumed by the normal frame path while _pending is set; + // everything after is counted (not parsed) until the test finishes. + if (this._throughputTestMode && !this._pending) { + if (chunk?.length) + this.emit('throughputChunk', chunk.length); + return; + } + this._appendStreamBuf(chunk); + for (;;) { + // Streaming frames carry a CRC-16 trailer; use it to lock onto frame + // boundaries. A candidate is accepted only when its CRC validates, so + // after a weak link drops bytes we slide past the garbage and re-lock on + // the next genuine frame instead of emitting misaligned (wrong sensor-id) + // packets. Legacy firmware that streams without a CRC trailer + // (stripStreamCrc=false) falls through to the length-only path below. + if (this._mode === 'streaming' && this.stripStreamCrc) { + const scan = scanStreamFrame(this._rxStreamBuf); + if (scan.status === 'need-more') + return; + if (scan.status === 'invalid') { + if (this.debugSync) { + console.warn('[rx] stream resync: dropping byte', { + dropped: this._rxStreamBuf[0], + bufLen: this._rxStreamBuf.length, + }); + } + this._rxStreamBuf = this._rxStreamBuf.slice(1); + this._streamStats.recordResyncDrop(1); + continue; + } + this._rxStreamBuf = this._rxStreamBuf.slice(scan.consumed); + this._handleStreamingPayload(scan.payload); + continue; + } + if (this._rxStreamBuf.length < 3) + return; + const hdr = this._rxStreamBuf[0]; + const len = (this._rxStreamBuf[1] | (this._rxStreamBuf[2] << 8)) >>> 0; + if (!this._isPlausibleFrameStart(hdr, len)) { + if (this.debugSync) { + console.warn('[rx] resync: dropping byte', { + dropped: hdr, + nextLen: len, + bufLen: this._rxStreamBuf.length, + }); + } + this._rxStreamBuf = this._rxStreamBuf.slice(1); + continue; + } + if (len === 0) { + const header = hdr & 0xff; + const decodedHeader = parseHeader(header); + const msg = { + header, + command: decodedHeader.command, + property: decodedHeader.property, + payloadLength: 0, + payload: new Uint8Array(0), + }; + this._rxStreamBuf = this._rxStreamBuf.slice(3); + if (this._mode === 'logged' && hdr === buildHeader(ASM_COMMAND.ACK, ASM_PROPERTY.DATA)) { + const s = this._sync; + if (s && s.bytesWritten === 0 && s.emptyAckCount < 6) { + s.emptyAckCount++; + if (this.debugSync) + console.log('[sync] empty ACK before payload; requesting next DATA chunk.'); + void this.writeBytes(buildMessage(ASM_COMMAND.READ, ASM_PROPERTY.DATA), { + withResponse: true, + }).catch((e) => this._abortSync(e)); + continue; + } + if (this.debugSync) + console.log('[sync] EOS received. Finishing.'); + this._finishSync(); + continue; + } + if (this._mode === 'command') { + this._resolvePendingCommand(msg); + } + continue; + } + if (this._rxStreamBuf.length < 3 + len) + return; + const payload = this._rxStreamBuf.slice(3, 3 + len); + this._rxStreamBuf = this._rxStreamBuf.slice(3 + len); + const header = hdr & 0xff; + const decodedHeader = parseHeader(header); + const msg = { + header, + command: decodedHeader.command, + property: decodedHeader.property, + payloadLength: payload.length, + payload, + }; + if (this._mode === 'logged') { + this._loggedChain = (this._loggedChain ?? Promise.resolve()) + .then(() => this._handleLoggedPayload(msg.payload)) + .catch((e) => this._abortSync(e)); + continue; + } + if (this._mode === 'streaming') { + this._handleStreamingPayload(msg.payload); + continue; + } + this._resolvePendingCommand(msg); + } + } + _handleStreamingPayload(payload) { + if (payload.length < 4) + return; + let body = payload; + let crcOk = null; + if (this.stripStreamCrc && payload.length >= 6) { + // Reached only for frames the CRC-gated scanner already validated (see + // _feedStreamBytes), so the CRC is known good; just strip the 2-byte + // trailer before decoding. + body = payload.slice(0, payload.length - 2); + crcOk = true; + } + const sensorId = body[0]; + const tick = u24le(body, 1); + const sensorPayload = body.slice(4); + const sensor = this.sensors[sensorId]; + const systemTsLastSampleMillis = nowMillis(); + let tsInfo = null; + if (sensor) + tsInfo = sensor.getTimestampUnwrappedMillis(tick, systemTsLastSampleMillis); + let decodedSamples = null; + if (sensor) + decodedSamples = sensor.parsePayload(sensorPayload); + let samplesWithTime = decodedSamples; + if (sensor && Array.isArray(decodedSamples) && decodedSamples.length > 0 && tsInfo) { + // Per-stream-aware (sensors with interleaved FIFO streams override this). + const tsArray = sensor.computeSampleTimestamps(decodedSamples, { + tsLastSampleMillis: tsInfo.shimmerMillis, + systemTsLastSampleMillis, + systemOffsetFirstTime: tsInfo.systemOffsetFirstTime, + }); + samplesWithTime = decodedSamples.map((s, i) => ({ + ...s, + timestamps: tsArray[i], + })); + } + const packet = { + sensorId, + tick_u24: tick, + decoded: samplesWithTime, + rawPayload: sensorPayload, + crcOk, + }; + // Live throughput / packet-loss accounting. Loss is derived from gaps in the + // monotonic device clock (tsMillis) via getStreamContributions; throughput + // uses the full BLE frame size and host receive time. + const contributions = sensor && Array.isArray(samplesWithTime) && samplesWithTime.length + ? sensor.getStreamContributions(samplesWithTime, sensorId) + : []; + this._streamStats.recordPacket({ + sensorId, + byteLength: payload.length, + crcOk, + recvMillis: systemTsLastSampleMillis, + contributions, + }); + this.emit('streamPacket', packet); + this.emit('data', packet); + // Throttled stats push (~3 Hz) so the UI can subscribe instead of polling. + if (systemTsLastSampleMillis - this._lastStreamStatsEmitMillis >= 333) { + this._lastStreamStatsEmitMillis = systemTsLastSampleMillis; + this.emit('streamStats', this._streamStats.snapshot(systemTsLastSampleMillis)); + } + } + /** Snapshot of live stream statistics (throughput / packet-loss). */ + getStreamStats() { + return this._streamStats.snapshot(nowMillis()); + } +} +// Single source of truth for the max frame size, shared with the CRC-gated +// streaming scanner so both framing paths accept the same large (fragmented) +// payloads. See STREAM_FRAME_MAX_PAYLOAD. +VerisenseBleDevice.MAX_FRAME_PAYLOAD_LEN = STREAM_FRAME_MAX_PAYLOAD; +VerisenseBleDevice.MAX_DEBUG_FRAME_PAYLOAD_LEN = 0xffff; +// Static NUS UUIDs +VerisenseBleDevice.NUS_SERVICE = NUS_SERVICE; +VerisenseBleDevice.NUS_TX = NUS_TX; +VerisenseBleDevice.NUS_RX = NUS_RX; + +/** + * Verisense Nordic Secure-DFU flow helpers (DEV-845). + * + * The byte transport is Nordic's `web-bluetooth-dfu` library (`SecureDfu` + + * `SecureDfuPackage`, vendored by consuming apps); this module owns everything + * learned about running that library reliably against Verisense sensors over + * desktop Chrome/Edge Web Bluetooth: + * + * - classification of transient BLE-stack errors vs DFU protocol errors + * - a fix for the library's swallowed-rejection hang in `sendOperation` + * - bounded + retried `setDfuMode` (with a full GATT reset between attempts) + * - the two-phase combined-package update (SoftDevice/bootloader then + * application), including resume of an interrupted combined update + * - the bootloader device-picker filter and packet-pacing defaults + * + * The library objects are injected (structurally typed), so this module has no + * build-time dependency on the vendored scripts. All user-visible progress is + * reported through an `onStatus` callback; no DOM access happens here. + */ +/** + * Transient connection/BLE-stack errors worth retrying. "unknown reason" + * (NotSupportedError) is Chrome-on-Windows' generic wrapper for any GATT + * operation the OS stack fails without an ATT error code (DEV-845) — + * typically a startNotifications/write right after a (re)connect, or a + * link being torn down mid-encryption. Recoverable on retry; DFU protocol + * errors (wrong image, version too low, ...) never match. + */ +const VERISENSE_DFU_TRANSIENT_ERROR_REGEX = /unreachable|networkerror|gatt server|disconnected|no longer in range|connection|unknown reason|notsupportederror/i; +/** Total attempts (first try + retries) for the DFU connection-retry helpers. */ +const VERISENSE_DFU_CONNECT_ATTEMPTS = 3; +/** Delay between DFU connection retries, letting the device finish rebooting. */ +const VERISENSE_DFU_RETRY_DELAY_MS = 2000; +/** Time allowed for the base image's post-install reboot back into the bootloader. */ +const VERISENSE_DFU_REBOOT_DELAY_MS = 3000; +/** Bound on `setDfuMode` (connect + notifications + one write): the happy path + * completes in seconds, so a hit means a genuine stall — including the vendored + * library's swallowed-rejection case that {@link patchSecureDfuSendOperation} + * and {@link promiseWithTimeout} exist to catch. */ +const VERISENSE_DFU_SET_MODE_TIMEOUT_MS = 30000; +/** + * Per-packet pacing for the firmware transfer, in ms. The packet + * characteristic is written without response; over Web Bluetooth, Chrome + * drops packets if it outruns the device, so at 0 ms the first pass can fail + * object CRC validation and the library silently retries the WHOLE transfer + * at ~10 ms (the pass that succeeds). Pacing at 10 ms makes the first pass + * succeed outright. Pass 0 ("fast") for full speed on a known-clean link. + * (nRF Connect sidesteps this via a wired connectivity dongle rather than + * the OS BLE stack.) + */ +const VERISENSE_DFU_RELIABLE_PACKET_DELAY_MS = 10; +const VERISENSE_DFU_FAST_PACKET_DELAY_MS = 0; +/** + * The Verisense bootloader advertises as "Verisense-BL..."; app-mode sensors + * ("Verisense-..." without the -BL) are deliberately excluded from DFU device + * pickers to keep them unambiguous. The DFU service UUID is not advertised in + * app mode, so it cannot be used to widen the filter; it still needs to be + * granted via `optionalServices` for the GATT connection. + */ +const VERISENSE_DFU_BOOTLOADER_NAME_PREFIX = 'Verisense-BL'; +/** + * The library's routine object-retransmission notices (e.g. "object failed to + * validate"). Over Web Bluetooth, firmware packets are written without + * response and Chrome can drop one if it outruns the device; that makes a + * 4 KB object's CRC mismatch, so the library transparently re-creates and + * re-sends that object. The transfer still completes correctly (every object + * is CRC-checked before Execute, and the bootloader CRC/signature-checks the + * whole image), so these are non-issues that only alarm users. Real failures + * still surface via the promise rejection paths. + */ +const VERISENSE_DFU_ROUTINE_LOG_REGEX = /validat|crc|mismatch|retr|re-?send|re-?creat/i; +/** True for library log messages that are routine retransmission noise and + * should not be surfaced to end users (see {@link VERISENSE_DFU_ROUTINE_LOG_REGEX}). */ +function isRoutineVerisenseDfuLogMessage(message) { + return VERISENSE_DFU_ROUTINE_LOG_REGEX.test(String(message ?? '')); +} +/** "attempt N of M" wording for retry status lines. The retry helpers count + * attempts DOWN (remaining, including the one that just failed), so the + * attempt about to start is total - remaining + 2. */ +function verisenseDfuAttemptLabel(attemptsRemaining, totalAttempts = VERISENSE_DFU_CONNECT_ATTEMPTS) { + return `attempt ${totalAttempts - attemptsRemaining + 2} of ${totalAttempts}`; +} +/** + * Fix the swallowed-rejection hang in `web-bluetooth-dfu` v1.2.1 (DEV-845): + * upstream `SecureDfu.sendOperation` retries a failed control-point write once + * after 500 ms, but if the retry ALSO fails the rejection is dropped and the + * returned promise never settles — the transfer hangs forever. This replaces + * the method with the same logic as upstream, plus: a second write failure + * rejects the pending operation. + * + * Call once per page load with the vendored `SecureDfu` constructor before + * creating instances. Safe to call repeatedly (idempotent). + */ +function patchSecureDfuSendOperation(SecureDfuCtor) { + const patched = function (characteristic, operation, buffer) { + return new Promise((resolve, reject) => { + let size = operation.length; + if (buffer) + size += buffer.byteLength; + const value = new Uint8Array(size); + value.set(operation); + if (buffer) + value.set(new Uint8Array(buffer), operation.length); + this.notifyFns[operation[0]] = { resolve, reject }; + characteristic + .writeValue(value) + .catch((error) => { + this.log(error); + return this.delayPromise(500).then(() => characteristic.writeValue(value)); + }) + .catch((error) => { + delete this.notifyFns[operation[0]]; + reject(error); + }); + }); + }; + SecureDfuCtor.prototype.sendOperation = patched; +} +/** + * Classify known Bluetooth-stack failures seen during Verisense DFU (DEV-845). + * Two signatures of the same Windows pairing/GATT-cache failure loop: + * "unknown reason" (NotSupportedError) is the stack failing an operation on a + * live link, and "GATT Server is disconnected" (NetworkError) is the sensor + * tearing the link down mid-operation — on units without the firmware fix, + * typically its ~400 ms security request colliding with a stale pairing key. + * Unrecognised errors return `category: null` so their raw text passes + * through unchanged. + */ +function classifyVerisenseDfuError(error) { + const rawMessage = String(error); + const name = error && typeof error === 'object' && 'name' in error && typeof error.name === 'string' + ? error.name + : 'GATT error'; + let category = null; + let friendlyMessage = null; + if (/gatt server is disconnected/i.test(rawMessage)) { + category = 'device-disconnected'; + friendlyMessage = 'The sensor disconnected before the operation could complete'; + } + else if (/unknown reason|notsupportederror/i.test(rawMessage)) { + category = 'stack-operation-failed'; + friendlyMessage = 'The Bluetooth stack failed the operation unexpectedly'; + } + return { + category, + friendlyMessage, + transient: VERISENSE_DFU_TRANSIENT_ERROR_REGEX.test(rawMessage), + name, + rawMessage, + }; +} +/** + * Reject a promise that hasn't settled within `ms`. Used to guard + * `SecureDfu.setDfuMode()`: the library builds its buttonless branch as + * `new Promise((resolve, reject) => { startNotifications().then( + * ...sendOperation...).then(resolve) })` with NO `.catch(reject)`, so if + * startNotifications() or the button-command write fails the promise never + * settles. (The {@link patchSecureDfuSendOperation} override makes that write + * reject rather than hang, which this same missing catch would swallow.) + * The timeout message deliberately includes "connection" so it matches + * {@link VERISENSE_DFU_TRANSIENT_ERROR_REGEX} and drives the retry helpers. + * Kept as a timeout rather than re-implementing setDfuMode so the buttonless + * reboot logic isn't duplicated, and so it defends against any stall cause. + */ +function promiseWithTimeout(promise, ms, label) { + let timer; + const timeout = new Promise((_resolve, reject) => { + timer = setTimeout(() => { + reject(new Error(`${label} timed out after ${ms}ms (connection may have stalled)`)); + }, ms); + }); + return Promise.race([promise, timeout]).finally(() => clearTimeout(timer)); +} +/** A bundled firmware name must be a plain `.zip` filename — no path + * separators or traversal — so a malformed/hostile manifest can't make an app + * fetch outside its firmware folder. */ +function isSafeFirmwareArchiveName(name) { + return typeof name === 'string' && /^[^/\\]+\.zip$/i.test(name) && !name.includes('..'); +} +/** + * `navigator.bluetooth.requestDevice()` options for picking a Verisense + * bootloader (replaces the DFU library's `acceptAllDevices`; see + * {@link VERISENSE_DFU_BOOTLOADER_NAME_PREFIX} for why name-prefix only). + * Pass the vendored library's `SecureDfu.SERVICE_UUID`. + */ +function buildVerisenseDfuRequestDeviceOptions(dfuServiceUuid) { + return { + filters: [{ namePrefix: VERISENSE_DFU_BOOTLOADER_NAME_PREFIX }], + optionalServices: [dfuServiceUuid], + }; +} +function delay(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); +} +/** Normalize an `attempts` option to a finite integer >= 1 so the retry + * loops keep their documented "total attempts" semantics for 0/negative/NaN + * inputs. */ +function normalizeAttempts(attempts) { + const v = Number(attempts ?? VERISENSE_DFU_CONNECT_ATTEMPTS); + return Number.isFinite(v) ? Math.max(1, Math.trunc(v)) : VERISENSE_DFU_CONNECT_ATTEMPTS; +} +/** + * `SecureDfu.update()` with retries on connection-level errors. Combined + * (SoftDevice+bootloader+application) packages transfer in two parts with a + * device reset in between; the reconnect for part 2 can fail while the device + * is still rebooting, so transient errors retry after a settle delay. DFU + * protocol errors are not retried. + */ +async function updateVerisenseDfuImageWithRetry(dfu, device, image, options = {}) { + const totalAttempts = normalizeAttempts(options.attempts); + const retryDelayMs = options.retryDelayMs ?? VERISENSE_DFU_RETRY_DELAY_MS; + for (let attemptsRemaining = totalAttempts;; attemptsRemaining--) { + try { + await dfu.update(device, image.initData, image.imageData); + return; + } + catch (error) { + const transient = VERISENSE_DFU_TRANSIENT_ERROR_REGEX.test(String(error)); + if (attemptsRemaining <= 1 || !transient) + throw error; + const attemptLabel = verisenseDfuAttemptLabel(attemptsRemaining, totalAttempts); + options.onRetry?.({ stage: 'update', attemptsRemaining, attemptLabel, error }); + options.onStatus?.(`Reconnecting to bootloader (${attemptLabel})...`); + await delay(retryDelayMs); + } + } +} +/** + * `SecureDfu.setDfuMode()` bounded by a timeout and retried on transient + * errors (DEV-845). setDfuMode (connect + find the buttonless characteristic + * + startNotifications + write) is where Windows' BLE stack intermittently + * fails with "GATT operation failed for unknown reason", typically on the + * first GATT operation after a connect that follows a disconnect. Before each + * retry the GATT connection is fully torn down so the next attempt starts + * from a clean link. Protocol errors (e.g. "Unsupported device") are not + * retried. Resolves like setDfuMode: the device when it is already in + * bootloader mode, or null after the buttonless reboot command has been sent. + */ +async function setVerisenseDfuModeWithRetry(dfu, device, options = {}) { + const totalAttempts = normalizeAttempts(options.attempts); + const retryDelayMs = options.retryDelayMs ?? VERISENSE_DFU_RETRY_DELAY_MS; + const timeoutMs = options.setDfuModeTimeoutMs ?? VERISENSE_DFU_SET_MODE_TIMEOUT_MS; + for (let attemptsRemaining = totalAttempts;; attemptsRemaining--) { + try { + const result = await promiseWithTimeout(dfu.setDfuMode(device), timeoutMs, 'Enter DFU mode'); + return result ?? null; + } + catch (error) { + const transient = VERISENSE_DFU_TRANSIENT_ERROR_REGEX.test(String(error)); + if (attemptsRemaining <= 1 || !transient) + throw error; + const attemptLabel = verisenseDfuAttemptLabel(attemptsRemaining, totalAttempts); + options.onRetry?.({ stage: 'set-dfu-mode', attemptsRemaining, attemptLabel, error }); + options.onStatus?.(`Connection hiccup - retrying (${attemptLabel})...`); + // Full connection-state reset so the retry starts from a clean link. + if (device.gatt?.connected) { + device.gatt.disconnect(); + } + await delay(retryDelayMs); + } + } +} +/** + * Run a full Verisense DFU transfer from a loaded Nordic DFU package: base + * image (SoftDevice/bootloader) first when present, then the application + * image. Resumes interrupted combined updates: a bootloader only installs + * once per version number, so if a previous (interrupted) attempt already + * installed this base image the target rejects it with a firmware-version + * error — that is swallowed and the flow continues to the application image. + * + * Progress text is reported via `options.onStatus`; transfer byte progress + * comes from the `SecureDfu` instance's own "progress" events, which the app + * subscribes to directly. Rejects with the raw library error on failure (run + * it through {@link classifyVerisenseDfuError} for display). + */ +async function runVerisenseDfuUpdate(dfu, device, dfuPackage, options = {}) { + const rebootDelayMs = options.rebootDelayMs ?? VERISENSE_DFU_REBOOT_DELAY_MS; + const baseImage = await dfuPackage.getBaseImage(); + if (baseImage) { + options.onStatus?.(`Updating ${baseImage.type}: ${baseImage.imageFile}...`); + try { + await dfu.update(device, baseImage.initData, baseImage.imageData); + // The base image resets the target on completion; give it time to + // reboot back into the bootloader before part 2. + options.onStatus?.('SoftDevice/bootloader installed - device rebooting...'); + await delay(rebootDelayMs); + } + catch (error) { + if (!/firmware version is too low/i.test(String(error))) + throw error; + options.onStatus?.('SoftDevice/bootloader already up to date - continuing with application...'); + } + } + const appImage = await dfuPackage.getAppImage(); + if (appImage) { + options.onStatus?.(`Updating ${appImage.type}: ${appImage.imageFile}...`); + await updateVerisenseDfuImageWithRetry(dfu, device, appImage, options); + } +} + +/** + * Verisense calibration defaults, hardware/firmware gating, and timestamp helpers. + * + * The byte-level codec lives in `calibration.ts`; this module is the host-side + * single source of truth for the *default* calibration (the mirror of the + * firmware `AsmCalib_seedDefaults`) plus the small amount of domain logic the UI + * used to carry: which calibration blocks a board has, the minimum firmware that + * supports `CMD_AR_CFG_CALIB`, and the 8-byte timestamp encode/decode. + */ +/** Minimum firmware that implements the `CMD_AR_CFG_CALIB` (0x0D) command. */ +const VERISENSE_CALIBRATION_MIN_FW = { + major: 2, + minor: 0, + internal: 4, +}; +/** Whether the given firmware version supports the calibration command. */ +function supportsVerisenseCalibration(fw) { + if (!fw) + return false; + return compareVerisenseFirmwareVersion(fw, VERISENSE_CALIBRATION_MIN_FW) >= 0; +} +// --------------------------------------------------------------------------- +// 8-byte little-endian Unix-epoch-seconds timestamp (block header `ts` field). +// --------------------------------------------------------------------------- +/** Encode Unix-epoch seconds into the 8-byte little-endian calibration `ts`. */ +function unixSecondsToCalibTsBytes(unixSeconds) { + const out = new Uint8Array(SC_TS_BYTES); + let v = Math.max(0, Math.floor(Number(unixSeconds) || 0)); + for (let i = 0; i < SC_TS_BYTES; i++) { + out[i] = v & 0xff; + v = Math.floor(v / 256); + } + return out; +} +/** Decode the 8-byte little-endian calibration `ts` back to Unix-epoch seconds + * (0 = default/seeded). */ +function calibTsBytesToUnixSeconds(ts) { + if (!ts || ts.length < SC_TS_BYTES) + return 0; + let secs = 0; + for (let i = SC_TS_BYTES - 1; i >= 0; i--) + secs = secs * 256 + (ts[i] & 0xff); + return secs; +} +const ACCEL_RANGES = [ + { code: 0, label: '±2g', sens: 1671.665922915 }, + { code: 1, label: '±4g', sens: 835.832961457 }, + { code: 2, label: '±8g', sens: 417.916480729 }, + { code: 3, label: '±16g', sens: 208.958240364 }, +]; +// LSM6DSV gyro full-scale codes 0..4 (125/250/500/1000/2000 dps). +const GYRO_RANGES = [ + { code: 0, label: '±125dps', sens: 228.571428571 }, + { code: 1, label: '±250dps', sens: 114.285714286 }, + { code: 2, label: '±500dps', sens: 57.142857143 }, + { code: 3, label: '±1000dps', sens: 28.571428571 }, + { code: 4, label: '±2000dps', sens: 14.285714286 }, +]; +// LSM6DS3 gyro full-scale codes 0..3 (250/500/1000/2000 dps) — the gen-1 op-config +// gyro field is 2 bits, so 125 dps is not selectable via the standard range (see +// SensorLSM6DS3). Codes here match that field and the decoder lookup. +const LSM6DS3_GYRO_RANGES = [ + { code: 0, label: '±250dps', sens: 114.285714286 }, + { code: 1, label: '±500dps', sens: 57.142857143 }, + { code: 2, label: '±1000dps', sens: 28.571428571 }, + { code: 3, label: '±2000dps', sens: 14.285714286 }, +]; +/** + * 2nd-generation catalog (LSM6DSV accel+gyro, LIS2DW12, LIS2MDL). Alignment + * matrices derived from the ST datasheet axis figures + the SR68-10 pin-1 + * placement; common frame +X=strap, +Y=out of face, +Z=toward hand. LSM6DSV / + * LIS2DW12 are proper rotations (det +1); the LIS2MDL frame is left-handed + * (det −1, a reflection). Kept byte-for-byte in sync with the firmware seed + * (asm_calibration.c) and VERISENSE_CALIBRATION.md §4. + */ +const CALIBRATION_SENSORS_GEN2 = [ + { + id: CalibSensorId.LSM6DSV_ACCEL, + label: 'Accelerometer (LSM6DSV)', + unit: 'LSB/(m/s²)', + align: [0, -1, 0, 0, 0, 1, -1, 0, 0], + ranges: ACCEL_RANGES, + }, + { + id: CalibSensorId.LSM6DSV_GYRO, + label: 'Gyroscope (LSM6DSV)', + unit: 'LSB/dps', + align: [0, -1, 0, 0, 0, 1, -1, 0, 0], + ranges: GYRO_RANGES, + }, + { + id: CalibSensorId.LIS2DW12_ACCEL, + label: 'Accelerometer 2 (LIS2DW12)', + unit: 'LSB/(m/s²)', + align: [1, 0, 0, 0, 0, 1, 0, -1, 0], + ranges: ACCEL_RANGES, + }, + { + id: CalibSensorId.LIS2MDL_MAG, + label: 'Magnetometer (LIS2MDL)', + unit: 'LSB/Gauss', + align: [0, 1, 0, 0, 0, 1, -1, 0, 0], + ranges: [{ code: 0, label: '±49.152Ga', sens: 667 }], + }, +]; +/** + * 1st-generation catalog (LIS2DW12 + LSM6DS3 accel/gyro). Sensitivities and + * alignment from the gen-1 calibration document (ASM-DES §8). The doc states the + * forward rotation `R` (output = K·R·physical); the stored `align` is the applied + * sensor→common map = Rᵀ. Note the LIS2DW12 mounting differs from gen-2, so its + * alignment (id 39) is generation-specific. All proper rotations (det +1). + */ +const CALIBRATION_SENSORS_GEN1 = [ + { + id: CalibSensorId.LIS2DW12_ACCEL, + label: 'Accelerometer 1 (LIS2DW12)', + unit: 'LSB/(m/s²)', + align: [0, 1, 0, 0, 0, 1, 1, 0, 0], + ranges: ACCEL_RANGES, + }, + { + id: CalibSensorId.LSM6DS3_ACCEL, + label: 'Accelerometer 2 (LSM6DS3)', + unit: 'LSB/(m/s²)', + align: [0, -1, 0, 0, 0, -1, 1, 0, 0], + ranges: ACCEL_RANGES, + }, + { + id: CalibSensorId.LSM6DS3_GYRO, + label: 'Gyroscope (LSM6DS3)', + unit: 'LSB/dps', + align: [0, -1, 0, 0, 0, -1, 1, 0, 0], + ranges: LSM6DS3_GYRO_RANGES, + }, +]; +/** + * The calibration sensor catalog for a board: the 1st-generation set + * (LIS2DW12 + LSM6DS3) for 1st-gen hardware, otherwise the 2nd-generation set + * (LSM6DSV + LIS2DW12 + LIS2MDL). Unknown/offline (no revision) defaults to + * 2nd-gen. Note id 39 (LIS2DW12) appears in both with a generation-specific + * alignment, so the catalog must be resolved per hardware revision. + */ +function getVerisenseCalibrationSensors(revHwMajor, revHwMinor) { + if (revHwMajor != null && + revHwMinor != null && + !isVerisenseSecondGenerationHardware(revHwMajor, revHwMinor)) { + return CALIBRATION_SENSORS_GEN1; + } + return CALIBRATION_SENSORS_GEN2; +} +/** + * Build the default calibration set for a board (bias=0, default sensitivity, + * default alignment, ts=0). Host-side mirror of `AsmCalib_seedDefaults`; useful + * for "reset to defaults" and round-trip tests. + */ +function buildDefaultVerisenseCalibrationSet(opts) { + const sensors = getVerisenseCalibrationSensors(opts.hwVerMajor, opts.hwVerMinor); + const blocks = sensors.flatMap((s) => s.ranges.map((r) => ({ + sensorId: s.id, + range: r.code, + imu: { + bias: [0, 0, 0], + sens: [r.sens, r.sens, r.sens], + align: s.align.slice(), + }, + }))); + return { + hwVerMajor: opts.hwVerMajor, + hwVerMinor: opts.hwVerMinor, + fwVerMajor: opts.fwVerMajor, + fwVerMinor: opts.fwVerMinor, + fwVerPatch: opts.fwVerPatch, + blocks, + }; +} +/** + * Map each calibration-domain sensor id to whether it is present and usable on + * the connected hardware: + * - `enabled` — present and recorded from; show + allow edit. + * - `disabled` — physically present but not recorded from (LIS2DW12 routed to + * the algorithm hub on 2nd-gen SR68); show greyed. + * - `hidden` — not fitted on this hardware. + * + * `support` is the result of `getVerisenseHardwareSensorSupport`. A null/absent + * support object (offline / unknown hardware) reports every sensor `enabled`. + */ +function getVerisenseCalibrationSensorAvailability(support) { + const all = (v) => ({ + [CalibSensorId.LSM6DSV_ACCEL]: v, + [CalibSensorId.LSM6DSV_GYRO]: v, + [CalibSensorId.LIS2DW12_ACCEL]: v, + [CalibSensorId.LSM6DS3_ACCEL]: v, + [CalibSensorId.LSM6DS3_GYRO]: v, + [CalibSensorId.LIS2MDL_MAG]: v, + }); + if (!support) + return all('enabled'); + const imuGen2 = support.imuGen2 ? 'enabled' : 'hidden'; + const gen1Imu = support.gyroAccel2 ? 'enabled' : 'hidden'; + // LIS2DW12: recorded directly on 1st-gen (accel1); present-but-algo-hub-routed + // on 2nd-gen (imuGen2) so shown disabled; otherwise not fitted. + const lis2dw12 = support.accel1 + ? 'enabled' + : support.imuGen2 + ? 'disabled' + : 'hidden'; + return { + [CalibSensorId.LSM6DSV_ACCEL]: imuGen2, + [CalibSensorId.LSM6DSV_GYRO]: imuGen2, + [CalibSensorId.LIS2MDL_MAG]: imuGen2, + [CalibSensorId.LIS2DW12_ACCEL]: lis2dw12, + [CalibSensorId.LSM6DS3_ACCEL]: gen1Imu, + [CalibSensorId.LSM6DS3_GYRO]: gen1Imu, + }; +} + +export { ASM_COMMAND, ASM_PROPERTY, BLE_LINK_MIN_FW, BaseShimmerClient, CHANNEL_FORMATS, CalibQuality, CalibSensorId, DEBUG_COMMAND_ID, GSR_NAME, NORDIC_DFU_BUTTONLESS_WITHOUT_BONDS, NORDIC_DFU_BUTTONLESS_WITH_BONDS, NORDIC_DFU_OP_ENTER_BOOTLOADER, NORDIC_DFU_SERVICE, NUS_RX, NUS_SERVICE, NUS_TX, OPCODES, OP_IDX, ObjectCluster, RtcDriftMonitor, SC_CALIB_FORMAT_VERSION, SC_CAL_QUALITY_MASK, SC_CAL_QUALITY_SHIFT, SC_CAL_RANGE_MASK, SC_DATA_LEN_IMU, SC_GLOBAL_HEADER_BYTES, SHIMMER3R_DEFAULTS, STREAM_MODE, SensorADC, SensorBase, SensorBitmapShimmer3, SensorLIS2DW12, SensorLSM6DS3, SensorLSM6DSV, SensorMAX32674, SensorMLX90632, SensorPPG, SensorVD6283, Shimmer3RClient, StreamStatsTracker, TEST_MODE_ID, TIMESTAMP_FIELD, VERISENSE_BLE_SCHEDULE_DEFAULTS, VERISENSE_BLE_SCHEDULE_RANGES, VERISENSE_BLE_SYNC_SCHEDULES, VERISENSE_CALIBRATION_MIN_FW, VERISENSE_DEFAULT_PASSKEY_BY_ID, VERISENSE_DFU_BOOTLOADER_NAME_PREFIX, VERISENSE_DFU_CONNECT_ATTEMPTS, VERISENSE_DFU_FAST_PACKET_DELAY_MS, VERISENSE_DFU_REBOOT_DELAY_MS, VERISENSE_DFU_RELIABLE_PACKET_DELAY_MS, VERISENSE_DFU_RETRY_DELAY_MS, VERISENSE_DFU_ROUTINE_LOG_REGEX, VERISENSE_DFU_SET_MODE_TIMEOUT_MS, VERISENSE_DFU_TRANSIENT_ERROR_REGEX, VERISENSE_HW_MAJOR_FRIENDLY_NAMES, VERISENSE_MAX_PLAUSIBLE_UNIX_SECONDS, VERISENSE_OPERATIONAL_FIELD_FALLBACK_GROUP_ID, VERISENSE_OPERATIONAL_FIELD_GROUPS, VERISENSE_OPERATIONAL_FIELD_GROUP_SENSOR, VERISENSE_OPERATIONAL_FIELD_SCHEMA, VERISENSE_OP_CONFIG_BYTE_SIZE, VERISENSE_SENSOR_ENABLE_FIELDS, VERISENSE_SENSOR_RATE_DEFAULT_GROUPS, VERISENSE_STREAM_SENSOR_LABELS, VerisenseBleDevice, applyDuplicateSuffix, applyImuCalibration, asmRtcBytesToUnixSeconds, asmRtcMinutesBytesToUnixSeconds, buildDefaultVerisenseCalibrationSet, buildHeader, buildMessage, buildParsedCsvFileName, buildProductionConfigPayload, buildUploadBinaryFileName, buildVerisenseAdvertisedName, buildVerisenseDfuRequestDeviceOptions, calibTsBytesToUnixSeconds, calibrateGsrDataToResistanceFromAmplifierEq, calibrateShimmer3RAdcChannel, calibrateU12AdcValue, calibrationBlobCrc, classifyVerisenseDfuError, compareVerisenseFirmwareVersion, computeVerisensePairingPin, crc16_ccitt_false, createBlankVerisenseOperationalConfig, csvCell, decodeVerisenseBleOptimizationResult, defaultVerisensePasskeyForId, deriveVerisenseMacIdFromName, describeVerisenseChargerStatus, enforceVerisenseCommsChannelInterlock, evaluateParsedFileSplit, expectedVerisenseStreamSensorIds, expectedVerisenseStreamSensorIdsFromConfig, formatByteArrayAsHex, formatByteAsHex, formatPendingEventProperties, formatSchedulerPayloadForLog, formatStatusPayloadForLog, formatVerisenseChargerStatus, formatVerisenseFirmwareVersion, formatVerisenseHardwareRevision, formatVerisenseUnixAndHuman, getFirstPayloadIndex, getOversamplingRatioADS1292R, getVerisenseCalibrationSensorAvailability, getVerisenseCalibrationSensors, getVerisenseHardwareCapabilities, getVerisenseHardwareFriendlyName, getVerisenseHardwareRevision, getVerisenseHardwareSensorSupport, getVerisenseStreamSensorLabel, getVerisenseStreamingBatteryVoltageMultiplier, getVerisenseSupportedOperationalFieldGroupIds, hhmmToMinutesSinceMidnight, inferVerisenseChargerChipFamily, inferVerisenseLookupBankCount, isAckCommand, isNackCommand, isRoutineVerisenseDfuLogMessage, isSafeFirmwareArchiveName, isUniformByteArray, isVerisenseGsrSupportedHardware, isVerisenseLightDarkChannelEnabled, isVerisenseSecondGenerationHardware, minutesSinceMidnightToHHMM, nextAvailableDuplicateFileName, normalizeBytePayload, normalizeOperationalConfig, nudgeGsrResistance, padVerisenseOperationalConfig, parseBleLinkDebugPayload, parseCalibrationBlob, parseEventLogPayload, parseHeader, parseHexByteString, parseLookupTablePayload, parseMessage, parsePayloadCrcErrorBankIndexes, parsePendingEvents, parseProductionConfigPayload, parseProductionConfigPayloadFull, parseRecordBufferDetailsPayload, parseSchedulerDebugPayload, parseStatusPayload, parseVerisenseAdvertisedName, patchSecureDfuSendOperation, promiseWithTimeout, readVerisenseOperationalFieldValue, resolveVerisenseSensorRateFieldKey, runVerisenseDfuUpdate, serializeCalibrationBlob, setVerisenseDfuModeWithRetry, setVerisenseOperationalBitRange, supportsVerisenseCalibration, supportsVerisenseMagnetometer, unixSecondsToAsmRtcBytes, unixSecondsToCalibTsBytes, updateVerisenseDfuImageWithRetry, verisenseDeviceFileTag, verisenseDfuAttemptLabel, writeVerisenseOperationalFieldValue }; +//# sourceMappingURL=shimmer-web-sdk.esm.js.map diff --git a/Verisense/vendor/shimmer-web-sdk.esm.js.map b/Verisense/vendor/shimmer-web-sdk.esm.js.map new file mode 100644 index 0000000..980d47e --- /dev/null +++ b/Verisense/vendor/shimmer-web-sdk.esm.js.map @@ -0,0 +1 @@ +{"version":3,"file":"shimmer-web-sdk.esm.js","sources":["../src/core/ObjectCluster.ts","../src/core/BaseShimmerClient.ts","../src/core/arrayBuffer.ts","../src/core/csv.ts","../src/core/RtcDriftMonitor.ts","../src/core/StreamStats.ts","../src/devices/shimmer3r/constants.ts","../src/devices/shimmer3r/SensorBitmap.ts","../src/devices/shimmer3r/channelFormats.ts","../src/devices/shimmer3r/calibration.ts","../src/devices/shimmer3r/protocol.ts","../src/devices/shimmer3r/Shimmer3RClient.ts","../src/devices/verisense/constants.ts","../src/devices/verisense/protocolUtils.ts","../src/devices/verisense/calibration.ts","../src/devices/verisense/protocolMessage.ts","../src/devices/verisense/protocolDataFlow.ts","../src/devices/verisense/hardwareModels.ts","../src/devices/verisense/operationalConfig.ts","../src/devices/verisense/sensors/SensorBase.ts","../src/devices/verisense/sensors/SensorADC.ts","../src/devices/verisense/sensors/SensorLIS2DW12.ts","../src/devices/verisense/sensors/SensorLSM6DS3.ts","../src/devices/verisense/sensors/SensorLSM6DSV.ts","../src/devices/verisense/sensors/SensorPPG.ts","../src/devices/verisense/sensors/SensorVD6283.ts","../src/devices/verisense/sensors/SensorMAX32674.ts","../src/devices/verisense/sensors/SensorMLX90632.ts","../src/devices/verisense/requestValidation.ts","../src/devices/verisense/VerisenseClient.ts","../src/devices/verisense/dfu.ts","../src/devices/verisense/calibrationDefaults.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"names":["u16le","u24le"],"mappings":"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"} \ No newline at end of file diff --git a/Verisense/vendor/shimmer-web-sdk.umd.js b/Verisense/vendor/shimmer-web-sdk.umd.js new file mode 100644 index 0000000..c3289da --- /dev/null +++ b/Verisense/vendor/shimmer-web-sdk.umd.js @@ -0,0 +1,10036 @@ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.ShimmerBLE = {})); +})(this, (function (exports) { 'use strict'; + + /** + * Container for a single decoded sensor frame. + * + * Mirrors the ObjectCluster concept from the Shimmer C# SDK: + * a named, typed bag of raw and calibrated signal values produced + * by parsing one data packet from a device. + * + * @example + * ```ts + * const oc = new ObjectCluster('MyShimmer3R'); + * oc.add('GYRO_X', rawVal, null, 'raw'); + * oc.add('GYRO_X', degPerSec, 'deg/s', 'cal'); + * + * const cal = oc.get('GYRO_X', 'cal'); + * console.log(cal?.value, cal?.unit); // e.g. 12.5 "deg/s" + * ``` + */ + class ObjectCluster { + constructor(deviceId) { + this.deviceId = deviceId; + this.fields = []; + this.raw = null; + } + /** + * Append a named field to this cluster. + * + * @param name Signal name, e.g. `'GYRO_X'`. + * @param value Numeric value. + * @param unit Optional unit string, e.g. `'deg/s'`, `'µS'`, `'ticks'`. + * @param kind `'raw'` for ADC counts, `'cal'` for calibrated units, or `null`. + */ + add(name, value, unit = null, kind = null) { + this.fields.push({ name, value, unit, kind }); + } + /** + * Look up a field by name and optional kind. + * + * When both a raw and a calibrated version exist for the same signal name, + * pass `kind` to disambiguate. + * + * @returns The matching field, or `null` if not found. + */ + get(name, kind = null) { + return this.fields.find((f) => f.name === name && (kind === null || f.kind === kind)) ?? null; + } + /** + * Return all fields that match the given name (regardless of kind). + */ + getAll(name) { + return this.fields.filter((f) => f.name === name); + } + } + + /** + * Abstract base class shared by all Shimmer device clients. + * + * Provides: + * - A `debug` flag and `_log` helper. + * - Stub implementations of `onStatus` and `onStreamFrame` callback properties. + * - Abstract stubs for `connect`, `disconnect`, `startStreaming`, and `stopStreaming` + * that concrete sub-classes must override. + * + * Sub-classes should call `this._emitStatus(msg)` to surface status strings to + * the application layer without depending on a particular event-emitter library. + */ + class BaseShimmerClient { + constructor(opts = {}) { + /** + * Invoked whenever the client emits a human-readable status message + * (e.g. "GATT connected", "Sampling rate ACKed. Applied ≈ 51.200 Hz"). + */ + this.onStatus = null; + /** + * Invoked for every fully-decoded sensor frame while streaming. + * The exact shape depends on the concrete sub-class: + * - `Shimmer3RClient` passes an {@link ObjectCluster}. + * - `VerisenseBleDevice` passes a streaming packet object (see that class). + */ + this.onStreamFrame = null; + this.debug = opts.debug ?? true; + } + /** Log to console when debug is enabled. */ + _log(...args) { + if (this.debug) + console.log('[Shimmer]', ...args); + } + /** Emit a status message to `onStatus` and to the debug log. */ + _emitStatus(msg) { + this._log(msg); + this.onStatus?.(msg); + } + } + + function toArrayBuffer(u8) { + if (u8.buffer instanceof ArrayBuffer) { + if (u8.byteOffset === 0 && u8.byteLength === u8.buffer.byteLength) + return u8.buffer; + return u8.buffer.slice(u8.byteOffset, u8.byteOffset + u8.byteLength); + } + const out = new Uint8Array(u8.byteLength); + out.set(u8); + return out.buffer; + } + /** + * True if `bytes` is non-empty and every byte equals `value` (0–255). Useful for + * detecting uniform blobs such as erased flash (all `0xFF`) or zeroed regions. + * Returns false for empty or nullish input. + */ + function isUniformByteArray(bytes, value) { + const u8 = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes ?? []); + if (!u8.length) + return false; + const expected = value & 0xff; + for (let i = 0; i < u8.length; i++) { + if (u8[i] !== expected) + return false; + } + return true; + } + + /** + * Escape a value for a CSV cell (RFC 4180 style): whitespace runs — including + * newlines — collapse to a single space, then cells containing a quote or + * comma are quoted with internal quotes doubled. Null/undefined become the + * empty cell. + */ + function csvCell(text) { + const s = String(text ?? '') + .replace(/\s+/g, ' ') + .trim(); + return /[",]/.test(s) ? `"${s.replace(/"/g, '""')}"` : s; + } + + /** + * Device RTC drift estimation over a live connection (DEV-844). + * + * Sample the device clock periodically against the host clock and fit a + * least-squares slope of (device − host) offset vs host time: the + * dimensionless slope × 1e6 is directly the crystal error in ppm, giving a + * usable estimate in hours instead of waiting days between connections. + * Device time resolves to 1/32768 s, so per-sample noise is just transport + * round-trip jitter (~tens of ms); the fit averages it out. Host timestamps + * should be taken at the midpoint of the read round-trip, bounding transport + * latency to ±rtt/2. + * + * Host clock steps (NTP corrections) are a measurement hazard: the wall + * clock jumping mid-series pollutes the least-squares slope while looking + * like device drift (seen live on DEV-844: a −1.4 s Windows NTP step bent + * the fit from 1020 to 1077 ppm). Each sample therefore also records a + * monotonic timestamp (`performance.now()`): wall-vs-monotonic divergence + * between samples attributes a jump to the HOST, which resets the fit + * baseline instead of counting as a device step. + * + * This class is pure bookkeeping — the caller owns the sampling timer, the + * device read, and any UI. Feed it one {@link RtcDriftSampleInput} per read. + */ + class RtcDriftMonitor { + constructor(options = {}) { + this.samples = []; + /** Device clock steps detected across the whole run (survives rebaselines). */ + this.deviceSteps = 0; + /** Host (NTP) clock steps detected; each one rebaselines the fit. */ + this.hostSteps = 0; + this.deviceStepThresholdSeconds = options.deviceStepThresholdSeconds ?? 1; + this.hostStepThresholdSeconds = options.hostStepThresholdSeconds ?? 0.5; + } + /** Drop all samples and step counts (e.g. when starting a new run). */ + reset() { + this.samples.length = 0; + this.deviceSteps = 0; + this.hostSteps = 0; + } + /** + * Drop the samples but keep the step counters. Call when the device time is + * written: a time write moves the offset baseline, so every prior sample is + * invalid and the fit must not straddle the discontinuity. + */ + rebaseline() { + this.samples.length = 0; + } + /** + * Record one device-time reading. Attributes any offset jump before + * recording it: wall-clock elapsed minus monotonic elapsed isolates host + * clock steps (NTP) from device steps. A host step resets the fit baseline + * (the fit must not straddle the discontinuity); a device step is counted + * and kept in-series. + */ + addSample(input) { + const sample = { ...input, offsetSec: input.devSec - input.hostSec }; + const prev = this.samples[this.samples.length - 1]; + const hostStepSec = prev + ? sample.hostSec - prev.hostSec - (sample.perfMs - prev.perfMs) / 1000 + : 0; + if (Math.abs(hostStepSec) > this.hostStepThresholdSeconds) { + this.hostSteps++; + this.samples.length = 0; + this.samples.push(sample); + return { kind: 'host-step', sample, hostStepSec }; + } + if (prev && Math.abs(sample.offsetSec - prev.offsetSec) > this.deviceStepThresholdSeconds) { + this.deviceSteps++; + this.samples.push(sample); + return { kind: 'device-step', sample, deltaSec: sample.offsetSec - prev.offsetSec }; + } + this.samples.push(sample); + return { kind: 'sample', sample }; + } + /** + * Least-squares slope of offset vs host time, in ppm (offset and time are + * both in seconds, so the dimensionless slope × 1e6 is directly ppm). + * Null until two samples spanning a non-zero interval exist. + */ + ppmFit() { + const s = this.samples; + if (s.length < 2) + return null; + const t0 = s[0].hostSec; + const y0 = s[0].offsetSec; + let sx = 0; + let sy = 0; + let sxx = 0; + let sxy = 0; + for (const p of s) { + const x = p.hostSec - t0; + const y = p.offsetSec - y0; + sx += x; + sy += y; + sxx += x * x; + sxy += x * y; + } + const n = s.length; + const denom = n * sxx - sx * sx; + if (denom === 0) + return null; + return ((n * sxy - sx * sy) / denom) * 1e6; + } + /** Elapsed span of the current sample series in minutes (0 when empty). */ + elapsedMinutes() { + const s = this.samples; + if (s.length < 2) + return 0; + return (s[s.length - 1].hostSec - s[0].hostSec) / 60; + } + /** + * CSV rows (header first) of the current series, matching the DEV-844 + * export format: host ISO time, host/device unix seconds, offset, rtt, + * monotonic seconds. + */ + toCsvRows() { + const rows = ['host_iso,host_unix_s,device_unix_s,offset_s,rtt_ms,perf_monotonic_s']; + for (const p of this.samples) { + rows.push(`${new Date(p.hostSec * 1000).toISOString()},${p.hostSec.toFixed(3)},${p.devSec.toFixed(5)},${p.offsetSec.toFixed(3)},${p.rttMs},${(p.perfMs / 1000).toFixed(3)}`); + } + return rows; + } + } + + /** + * Device-agnostic live stream statistics: throughput, packet rate and + * sample-gap-derived packet loss for a real-time sensor stream. + * + * The tracker is fed one call per received packet ({@link StreamStatsTracker.recordPacket}) + * and produces a {@link StreamStatsSnapshot} on demand ({@link StreamStatsTracker.snapshot}). + * + * Loss is derived from gaps in each sub-stream's *monotonic device clock* + * (`lastSampleMillis`), NOT host receive time — host BLE buffering bunches + * packets together and would otherwise create false gaps. Throughput and packet + * rate, by contrast, are measured over a sliding window of host receive time + * (`recvMillis`), which is what "bytes per wall-clock second" means. + */ + /** + * Drop ring events older than `cutoff` (by receive time), but always keep the + * last 2 so the rate/throughput still reflect the most recent delivery even when + * packets arrive less often than the window (big FIFO reads, slow sensors). + */ + function pruneRing(ring, cutoff) { + if (ring.length <= 2) + return ring; + let i = 0; + while (i < ring.length - 2 && ring[i].t < cutoff) + i++; + return i > 0 ? ring.slice(i) : ring; + } + /** + * Accumulates live statistics for one streaming session. Call {@link reset} on + * (re)start, {@link recordPacket} for every decoded packet, {@link recordCrcFail} + * for CRC failures, and {@link snapshot} to read the current numbers. + */ + class StreamStatsTracker { + constructor(opts) { + this.sessionStartMillis = null; + this.resyncDroppedBytes = 0; + this.sensors = new Map(); + this.streams = new Map(); + this.windowMillis = opts?.windowMillis ?? 2000; + } + /** Clear all state. Call when streaming (re)starts. */ + reset() { + this.sessionStartMillis = null; + this.resyncDroppedBytes = 0; + this.sensors.clear(); + this.streams.clear(); + } + getSensor(sensorId) { + let s = this.sensors.get(sensorId); + if (!s) { + s = { sensorId, packets: 0, bytes: 0, crcFails: 0, throughputRing: [] }; + this.sensors.set(sensorId, s); + } + return s; + } + getStream(key, sensorId, label) { + let st = this.streams.get(key); + if (!st) { + st = { + key, + sensorId, + label, + samplingRateHz: null, + samples: 0, + expectedSamples: 0, + lostSamples: 0, + lastSampleMillis: null, + started: false, + rateRing: [], + }; + this.streams.set(key, st); + } + return st; + } + /** Record one received (and decoded) streaming packet. */ + recordPacket(p) { + if (this.sessionStartMillis == null) + this.sessionStartMillis = p.recvMillis; + const sensor = this.getSensor(p.sensorId); + sensor.packets += 1; + sensor.bytes += p.byteLength; + sensor.throughputRing.push({ t: p.recvMillis, bytes: p.byteLength }); + // CRC failures, when a device reports them, are counted via recordCrcFail() + // rather than here, to avoid double-counting a packet also passed in here. + for (const c of p.contributions) { + const st = this.getStream(c.key, p.sensorId, c.label); + st.label = c.label; + st.samplingRateHz = c.samplingRateHz; + st.samples += c.sampleCount; + st.rateRing.push({ + t: p.recvMillis, + n: c.sampleCount, + devFirst: c.firstSampleMillis, + dev: c.lastSampleMillis, + }); + const prev = st.lastSampleMillis; + if (!st.started || + !c.samplingRateHz || + c.samplingRateHz <= 0 || + prev == null || + c.lastSampleMillis == null) { + // No measurable gap yet -> assume every sample we got was expected. + st.expectedSamples += c.sampleCount; + } + else { + const interval = 1000 / c.samplingRateHz; + const delta = c.lastSampleMillis - prev; + if (delta > 0) { + const expected = Math.round(delta / interval); + st.expectedSamples += expected; + st.lostSamples += Math.max(0, expected - c.sampleCount); + } + // delta <= 0 (reorder / duplicate): ignore for loss; still counted in samples. + } + st.started = true; + if (c.lastSampleMillis != null) + st.lastSampleMillis = c.lastSampleMillis; + } + } + /** Record a CRC failure for a (possibly unknown) sensor. */ + recordCrcFail(sensorId) { + const id = sensorId ?? -1; + this.getSensor(id).crcFails += 1; + } + /** + * Record bytes discarded while re-synchronising the frame parser after the + * stream lost alignment (typically a flaky link dropping bytes mid-stream). + */ + recordResyncDrop(byteCount = 1) { + if (byteCount > 0) + this.resyncDroppedBytes += byteCount; + } + prune(nowMillis) { + const cutoff = nowMillis - this.windowMillis; + for (const s of this.sensors.values()) { + s.throughputRing = pruneRing(s.throughputRing, cutoff); + } + for (const st of this.streams.values()) { + st.rateRing = pruneRing(st.rateRing, cutoff); + } + } + /** + * Cadence-relative stall test: a stream is "stalled" only if its newest packet + * is older than a multiple of its own observed packet interval (floored at the + * window). This keeps a stalled stream reading 0 while NOT zeroing a healthy + * stream that simply delivers less often than the window (big FIFO reads, slow + * sensors). Events carry a receive time `t`. + */ + isStalled(ring, nowMillis) { + if (ring.length === 0) + return true; + const newest = ring[ring.length - 1].t; + const avgIntervalMillis = ring.length >= 2 ? (newest - ring[0].t) / (ring.length - 1) : this.windowMillis; + const stallMillis = Math.max(this.windowMillis, 3 * avgIntervalMillis); + return nowMillis - newest > stallMillis; + } + /** + * Achieved sample rate for a sub-stream's windowed events. + * + * Measured over the *device-clock* span of the samples — from the first + * sample of the oldest packet to the last sample of the newest packet (their + * tsMillis), not the host receive-time window. This is robust to bursty BLE + * delivery AND to large packets: one packet can carry hundreds of samples + * spanning several seconds (e.g. a high FIFO watermark), so dividing its count + * by the fixed receive window would over-report. Using the samples' own + * device-time span gives the true rate even from a single packet. A stream + * whose newest packet is older than a cadence-relative threshold reads 0 (see + * {@link isStalled}). + */ + windowRateHz(ring, nowMillis) { + if (this.isStalled(ring, nowMillis)) + return 0; + let totalN = 0; + let oldestFirst = Infinity; + let newestLast = -Infinity; + for (const e of ring) { + totalN += e.n; + if (e.devFirst != null && e.devFirst < oldestFirst) + oldestFirst = e.devFirst; + if (e.dev != null && e.dev > newestLast) + newestLast = e.dev; + } + if (totalN <= 0) + return 0; + // N samples span N-1 intervals over the device-time window, so the rate is + // (N-1) / span. A single packet uses its own first->last sample span; a + // stream with no usable device span (1 sample / no timestamps) reads 0. + const spanMillis = newestLast - oldestFirst; + if (spanMillis > 0 && totalN > 1) + return ((totalN - 1) / spanMillis) * 1000; + return 0; + } + /** + * Windowed throughput (bytes/sec) and packet rate over the *actual* receive + * span of the retained events, robust to packets that arrive less often than + * the window. Bytes/packets are counted after the oldest event (the span's + * start point). Returns 0 if the stream is stalled (see {@link isStalled}). + */ + windowThroughput(ring, nowMillis) { + if (ring.length < 2 || this.isStalled(ring, nowMillis)) + return { bps: 0, packetRateHz: 0 }; + const spanMillis = ring[ring.length - 1].t - ring[0].t; + if (spanMillis <= 0) + return { bps: 0, packetRateHz: 0 }; + let bytesAfterOldest = 0; + for (let i = 1; i < ring.length; i++) + bytesAfterOldest += ring[i].bytes; + const spanSec = spanMillis / 1000; + return { bps: bytesAfterOldest / spanSec, packetRateHz: (ring.length - 1) / spanSec }; + } + /** Produce a snapshot of all statistics as of `nowMillis`. */ + snapshot(nowMillis) { + this.prune(nowMillis); + const perSensor = {}; + for (const s of this.sensors.values()) { + const tp = this.windowThroughput(s.throughputRing, nowMillis); + perSensor[s.sensorId] = { + sensorId: s.sensorId, + packets: s.packets, + bytes: s.bytes, + crcFails: s.crcFails, + windowThroughputBps: tp.bps, + windowPacketRateHz: tp.packetRateHz, + streams: [], + }; + } + let totalPackets = 0; + let totalBytes = 0; + let totalCrcFails = 0; + let totalSamples = 0; + let totalExpected = 0; + let totalLost = 0; + let throughputBps = 0; + for (const sid of Object.keys(perSensor)) { + const s = perSensor[Number(sid)]; + totalPackets += s.packets; + totalBytes += s.bytes; + totalCrcFails += s.crcFails; + throughputBps += s.windowThroughputBps; + } + const streamList = [...this.streams.values()].sort((a, b) => a.key.localeCompare(b.key)); + for (const st of streamList) { + const lossPct = st.expectedSamples > 0 ? (st.lostSamples / st.expectedSamples) * 100 : 0; + const row = { + key: st.key, + sensorId: st.sensorId, + label: st.label, + samplingRateHz: st.samplingRateHz, + samples: st.samples, + expectedSamples: st.expectedSamples, + lostSamples: st.lostSamples, + lossPct, + windowSampleRateHz: this.windowRateHz(st.rateRing, nowMillis), + lastSampleMillis: st.lastSampleMillis, + }; + totalSamples += st.samples; + totalExpected += st.expectedSamples; + totalLost += st.lostSamples; + // A stream's sensor row may not exist if recordPacket was never called for + // it (only possible via a stray CRC-fail id); guard defensively. + const sensorRow = perSensor[st.sensorId]; + if (sensorRow) + sensorRow.streams.push(row); + } + return { + durationMillis: this.sessionStartMillis != null ? Math.max(0, nowMillis - this.sessionStartMillis) : 0, + totalPackets, + totalSamples, + totalBytes, + totalCrcFails, + resyncDroppedBytes: this.resyncDroppedBytes, + throughputBps, + lossPct: totalExpected > 0 ? (totalLost / totalExpected) * 100 : 0, + perSensor, + }; + } + } + + /** + * Shimmer3R BLE protocol opcodes. + * Values taken directly from the Shimmer3 firmware header. + */ + const OPCODES = Object.freeze({ + DATA_PACKET: 0x00, + INQUIRY_COMMAND: 0x01, + INQUIRY_RESPONSE: 0x02, + GET_SAMPLING_RATE_COMMAND: 0x03, + SAMPLING_RATE_RESPONSE: 0x04, + SET_SAMPLING_RATE_COMMAND: 0x05, + TOGGLE_LED_COMMAND: 0x06, + START_STREAMING_COMMAND: 0x07, + SET_SENSORS_COMMAND: 0x08, + SET_WR_ACCEL_RANGE_COMMAND: 0x09, + WR_ACCEL_RANGE_RESPONSE: 0x0a, + GET_WR_ACCEL_RANGE_COMMAND: 0x0b, + SET_CONFIG_SETUP_BYTES_COMMAND: 0x0e, + CONFIG_SETUP_BYTES_RESPONSE: 0x0f, + GET_CONFIG_SETUP_BYTES_COMMAND: 0x10, + SET_LN_ACCEL_CALIBRATION_COMMAND: 0x11, + LN_ACCEL_CALIBRATION_RESPONSE: 0x12, + GET_LN_ACCEL_CALIBRATION_COMMAND: 0x13, + SET_GYRO_CALIBRATION_COMMAND: 0x14, + GYRO_CALIBRATION_RESPONSE: 0x15, + GET_GYRO_CALIBRATION_COMMAND: 0x16, + SET_MAG_CALIBRATION_COMMAND: 0x17, + MAG_CALIBRATION_RESPONSE: 0x18, + GET_MAG_CALIBRATION_COMMAND: 0x19, + SET_WR_ACCEL_CALIBRATION_COMMAND: 0x1a, + WR_ACCEL_CALIBRATION_RESPONSE: 0x1b, + GET_WR_ACCEL_CALIBRATION_COMMAND: 0x1c, + STOP_STREAMING_COMMAND: 0x20, + SET_GSR_RANGE_COMMAND: 0x21, + GSR_RANGE_RESPONSE: 0x22, + GET_GSR_RANGE_COMMAND: 0x23, + DEVICE_VERSION_RESPONSE: 0x25, + GET_ALL_CALIBRATION_COMMAND: 0x2c, + ALL_CALIBRATION_RESPONSE: 0x2d, + GET_FW_VERSION_COMMAND: 0x2e, + FW_VERSION_RESPONSE: 0x2f, + SET_CHARGE_STATUS_LED_COMMAND: 0x30, + CHARGE_STATUS_LED_RESPONSE: 0x31, + GET_CHARGE_STATUS_LED_COMMAND: 0x32, + BUFFER_SIZE_RESPONSE: 0x35, + GET_BUFFER_SIZE_COMMAND: 0x36, + SET_MAG_GAIN_COMMAND: 0x37, + MAG_GAIN_RESPONSE: 0x38, + GET_MAG_GAIN_COMMAND: 0x39, + SET_MAG_SAMPLING_RATE_COMMAND: 0x3a, + MAG_SAMPLING_RATE_RESPONSE: 0x3b, + GET_MAG_SAMPLING_RATE_COMMAND: 0x3c, + UNIQUE_SERIAL_RESPONSE: 0x3d, + GET_UNIQUE_SERIAL_COMMAND: 0x3e, + GET_DEVICE_VERSION_COMMAND: 0x3f, + SET_WR_ACCEL_SAMPLING_RATE_COMMAND: 0x40, + WR_ACCEL_SAMPLING_RATE_RESPONSE: 0x41, + GET_WR_ACCEL_SAMPLING_RATE_COMMAND: 0x42, + SET_WR_ACCEL_LPMODE_COMMAND: 0x43, + WR_ACCEL_LPMODE_RESPONSE: 0x44, + GET_WR_ACCEL_LPMODE_COMMAND: 0x45, + SET_WR_ACCEL_HRMODE_COMMAND: 0x46, + WR_ACCEL_HRMODE_RESPONSE: 0x47, + GET_WR_ACCEL_HRMODE_COMMAND: 0x48, + SET_GYRO_RANGE_COMMAND: 0x49, + GYRO_RANGE_RESPONSE: 0x4a, + GET_GYRO_RANGE_COMMAND: 0x4b, + SET_GYRO_SAMPLING_RATE_COMMAND: 0x4c, + GYRO_SAMPLING_RATE_RESPONSE: 0x4d, + GET_GYRO_SAMPLING_RATE_COMMAND: 0x4e, + SET_ALT_ACCEL_RANGE_COMMAND: 0x4f, + ALT_ACCEL_RANGE_RESPONSE: 0x50, + GET_ALT_ACCEL_RANGE_COMMAND: 0x51, + SET_PRESSURE_OVERSAMPLING_RATIO_COMMAND: 0x52, + PRESSURE_OVERSAMPLING_RATIO_RESPONSE: 0x53, + GET_PRESSURE_OVERSAMPLING_RATIO_COMMAND: 0x54, + BMP180_CALIBRATION_COEFFICIENTS_RESPONSE: 0x58, + GET_BMP180_CALIBRATION_COEFFICIENTS_COMMAND: 0x59, + RESET_TO_DEFAULT_CONFIGURATION_COMMAND: 0x5a, + RESET_CALIBRATION_VALUE_COMMAND: 0x5b, + MPU9150_MAG_SENS_ADJ_VALS_RESPONSE: 0x5c, + GET_MPU9150_MAG_SENS_ADJ_VALS_COMMAND: 0x5d, + SET_INTERNAL_EXP_POWER_ENABLE_COMMAND: 0x5e, + INTERNAL_EXP_POWER_ENABLE_RESPONSE: 0x5f, + GET_INTERNAL_EXP_POWER_ENABLE_COMMAND: 0x60, + SET_EXG_REGS_COMMAND: 0x61, + EXG_REGS_RESPONSE: 0x62, + GET_EXG_REGS_COMMAND: 0x63, + SET_DAUGHTER_CARD_ID_COMMAND: 0x64, + DAUGHTER_CARD_ID_RESPONSE: 0x65, + GET_DAUGHTER_CARD_ID_COMMAND: 0x66, + SET_DAUGHTER_CARD_MEM_COMMAND: 0x67, + DAUGHTER_CARD_MEM_RESPONSE: 0x68, + GET_DAUGHTER_CARD_MEM_COMMAND: 0x69, + SET_DERIVED_CHANNEL_BYTES: 0x6d, + DERIVED_CHANNEL_BYTES_RESPONSE: 0x6e, + GET_DERIVED_CHANNEL_BYTES: 0x6f, + START_SDBT_COMMAND: 0x70, + STATUS_RESPONSE: 0x71, + GET_STATUS_COMMAND: 0x72, + SET_TRIAL_CONFIG_COMMAND: 0x73, + TRIAL_CONFIG_RESPONSE: 0x74, + GET_TRIAL_CONFIG_COMMAND: 0x75, + SET_CENTER_COMMAND: 0x76, + CENTER_RESPONSE: 0x77, + GET_CENTER_COMMAND: 0x78, + SET_SHIMMERNAME_COMMAND: 0x79, + SHIMMERNAME_RESPONSE: 0x7a, + GET_SHIMMERNAME_COMMAND: 0x7b, + SET_EXPID_COMMAND: 0x7c, + EXPID_RESPONSE: 0x7d, + GET_EXPID_COMMAND: 0x7e, + SET_MYID_COMMAND: 0x7f, + MYID_RESPONSE: 0x80, + GET_MYID_COMMAND: 0x81, + SET_NSHIMMER_COMMAND: 0x82, + NSHIMMER_RESPONSE: 0x83, + GET_NSHIMMER_COMMAND: 0x84, + SET_CONFIGTIME_COMMAND: 0x85, + CONFIGTIME_RESPONSE: 0x86, + GET_CONFIGTIME_COMMAND: 0x87, + DIR_RESPONSE: 0x88, + GET_DIR_COMMAND: 0x89, + INSTREAM_CMD_RESPONSE: 0x8a, + SET_CRC_COMMAND: 0x8b, + SET_INFOMEM_COMMAND: 0x8c, + INFOMEM_RESPONSE: 0x8d, + GET_INFOMEM_COMMAND: 0x8e, + SET_RWC_COMMAND: 0x8f, + RWC_RESPONSE: 0x90, + GET_RWC_COMMAND: 0x91, + START_LOGGING_COMMAND: 0x92, + STOP_LOGGING_COMMAND: 0x93, + VBATT_RESPONSE: 0x94, + GET_VBATT_COMMAND: 0x95, + TEST_CONNECTION_COMMAND: 0x96, + STOP_SDBT_COMMAND: 0x97, + SET_CALIB_DUMP_COMMAND: 0x98, + RSP_CALIB_DUMP_COMMAND: 0x99, + GET_CALIB_DUMP_COMMAND: 0x9a, + UPD_CALIB_DUMP_COMMAND: 0x9b, + UPD_SDLOG_CFG_COMMAND: 0x9c, + BMP280_CALIBRATION_COEFFICIENTS_RESPONSE: 0x9f, + GET_BMP280_CALIBRATION_COEFFICIENTS_COMMAND: 0xa0, + GET_BT_VERSION_STR_COMMAND: 0xa1, + BT_VERSION_STR_RESPONSE: 0xa2, + SET_INSTREAM_RESPONSE_ACK_PREFIX_STATE: 0xa3, + SET_DATA_RATE_TEST: 0xa4, + DATA_RATE_TEST_RESPONSE: 0xa5, + PRESSURE_CALIBRATION_COEFFICIENTS_RESPONSE: 0xa6, + GET_PRESSURE_CALIBRATION_COEFFICIENTS_COMMAND: 0xa7, + SET_FACTORY_TEST: 0xa8, + SET_ALT_ACCEL_CALIBRATION_COMMAND: 0xa9, + ALT_ACCEL_CALIBRATION_RESPONSE: 0xaa, + GET_ALT_ACCEL_CALIBRATION_COMMAND: 0xab, + SET_ALT_ACCEL_SAMPLING_RATE_COMMAND: 0xac, + ALT_ACCEL_SAMPLING_RATE_RESPONSE: 0xad, + GET_ALT_ACCEL_SAMPLING_RATE_COMMAND: 0xae, + SET_ALT_MAG_CALIBRATION_COMMAND: 0xaf, + ALT_MAG_CALIBRATION_RESPONSE: 0xb0, + GET_ALT_MAG_CALIBRATION_COMMAND: 0xb1, + SET_ALT_MAG_SAMPLING_RATE_COMMAND: 0xb2, + ALT_MAG_SAMPLING_RATE_RESPONSE: 0xb3, + GET_ALT_MAG_SAMPLING_RATE_COMMAND: 0xb4, + DUMMY_COMMAND: 0xb5, + RESET_BT_ERROR_COUNTS: 0xb6, + SET_FEATURE: 0xb7, + SET_SD_SYNC_COMMAND: 0xe0, + SD_SYNC_RESPONSE: 0xe1, + NACK_COMMAND_PROCESSED: 0xfe, + ACK_COMMAND_PROCESSED: 0xff, + }); + /** Default BLE service / characteristic UUIDs for Shimmer3R. */ + const SHIMMER3R_DEFAULTS = Object.freeze({ + SERVICE_UUID: '65333333-a115-11e2-9e9a-0800200ca100', + /** Write characteristic (host → device). */ + CHAR_RX_UUID: '65333333-a115-11e2-9e9a-0800200ca102', + /** Notify characteristic (device → host). */ + CHAR_TX_UUID: '65333333-a115-11e2-9e9a-0800200ca101', + }); + /** + * Timestamp field descriptors keyed by width. + * Shimmer3R firmware ≥ v1.0.22 always uses u24. + */ + const TIMESTAMP_FIELD = Object.freeze({ + u16: { name: 'TIMESTAMP', fmt: 'u16', endian: 'le', sizeBytes: 2 }, + u24: { name: 'TIMESTAMP', fmt: 'u24', endian: 'le', sizeBytes: 3 }, + }); + /** GSR signal name constant used in ObjectCluster fields. */ + const GSR_NAME = 'GSR'; + /** ADC limit below which GSR range-3 calibration is clamped. */ + const GSR_UNCAL_LIMIT_RANGE3 = 683; + /** + * Shimmer3R GSR resistance min/max per hardware range (kΩ). + * Index 0 = range 0 (8–63 kΩ) … index 3 = range 3 (680–4700 kΩ). + */ + const SHIMMER3_GSR_RESISTANCE_MIN_MAX_KOHMS = [ + [8.0, 63.0], + [63.0, 220.0], + [220.0, 680.0], + [680.0, 4700.0], + ]; + + /** + * Sensor enable bitmasks for Shimmer3 / Shimmer3R. + * + * Values are 24-bit integers sent as the payload of SET_SENSORS_CMD. + * Multiple sensors are ORed together. + * + * @example + * ```ts + * const mask = SensorBitmapShimmer3.SENSOR_GYRO | SensorBitmapShimmer3.SENSOR_A_ACCEL; + * await client.setSensors(mask); + * ``` + */ + const SensorBitmapShimmer3 = Object.freeze({ + SENSOR_A_ACCEL: 0x000080, + SENSOR_GYRO: 0x000040, + SENSOR_MAG: 0x000020, + SENSOR_GSR: 0x000004, + SENSOR_VBATT: 0x002000, + SENSOR_D_ACCEL: 0x001000, + SENSOR_PRESSURE: 0x040000, + SENSOR_EXG1_24BIT: 0x000010, + SENSOR_EXG2_24BIT: 0x000008, + SENSOR_EXG1_16BIT: 0x100000, + SENSOR_EXG2_16BIT: 0x080000, + SENSOR_BRIDGE_AMP: 0x008000, + SENSOR_ACCEL_ALT: 0x400000, + SENSOR_MAG_ALT: 0x200000, + SENSOR_EXT_A0: 0x000002, + SENSOR_EXT_A1: 0x000001, + SENSOR_EXT_A2: 0x000800, + SENSOR_INT_A3: 0x000400, + SENSOR_INT_A0: 0x000200, + SENSOR_INT_A1: 0x000100, + SENSOR_INT_A2: 0x800000, + }); + + /** + * Mapping from Shimmer3R channel ID byte to its format descriptor. + * Channel IDs are reported in the INQUIRY_RSP payload. + */ + const CHANNEL_FORMATS = Object.freeze({ + 0x00: { name: 'LN_ACCEL_X', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x01: { name: 'LN_ACCEL_Y', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x02: { name: 'LN_ACCEL_Z', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x04: { name: 'WR_ACCEL_X', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x05: { name: 'WR_ACCEL_Y', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x06: { name: 'WR_ACCEL_Z', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x14: { name: 'HG_ACCEL_X', fmt: 'i12*', endian: 'le', sizeBytes: 2 }, + 0x15: { name: 'HG_ACCEL_Y', fmt: 'i12*', endian: 'le', sizeBytes: 2 }, + 0x16: { name: 'HG_ACCEL_Z', fmt: 'i12*', endian: 'le', sizeBytes: 2 }, + 0x0a: { name: 'GYRO_X', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x0b: { name: 'GYRO_Y', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x0c: { name: 'GYRO_Z', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x07: { name: 'MAG_X', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x08: { name: 'MAG_Y', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x09: { name: 'MAG_Z', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x1d: { name: 'Exg1_Status', fmt: 'u8', endian: 'le', sizeBytes: 1 }, + 0x20: { name: 'Exg2_Status', fmt: 'u8', endian: 'le', sizeBytes: 1 }, + 0x1e: { name: 'Exg1_CH1_24Bit', fmt: 'i24', endian: 'be', sizeBytes: 3 }, + 0x1f: { name: 'Exg1_CH2_24Bit', fmt: 'i24', endian: 'be', sizeBytes: 3 }, + 0x21: { name: 'Exg2_CH1_24Bit', fmt: 'i24', endian: 'be', sizeBytes: 3 }, + 0x22: { name: 'Exg2_CH2_24Bit', fmt: 'i24', endian: 'be', sizeBytes: 3 }, + 0x23: { name: 'Exg1_CH1_16Bit', fmt: 'i16', endian: 'be', sizeBytes: 2 }, + 0x24: { name: 'Exg1_CH2_16Bit', fmt: 'i16', endian: 'be', sizeBytes: 2 }, + 0x25: { name: 'Exg2_CH1_16Bit', fmt: 'i16', endian: 'be', sizeBytes: 2 }, + 0x26: { name: 'Exg2_CH2_16Bit', fmt: 'i16', endian: 'be', sizeBytes: 2 }, + 0x12: { name: 'PPG', fmt: 'i16', endian: 'le', sizeBytes: 2 }, + 0x1c: { name: 'GSR', fmt: 'u16', endian: 'le', sizeBytes: 2 }, + }); + + // --------------------------------------------------------------------------- + // ADC helpers + // --------------------------------------------------------------------------- + /** + * Convert a Shimmer3R 12-bit ADC value to millivolts. + * + * @param unCalData Raw 12-bit ADC sample. + * @param offset ADC offset (typically 0). + * @param vRefP Reference voltage in volts (typically 3 V for Shimmer3R). + * @param gain Amplifier gain (typically 1). + * @returns Calibrated voltage in millivolts. + */ + function calibrateU12AdcValue(unCalData, offset, vRefP, gain) { + return (unCalData - offset) * ((vRefP * 1000) / gain / 4095); + } + /** + * Convert a Shimmer3R ADC channel value to millivolts using the + * default Shimmer3R ADC parameters (Vref = 3 V, gain = 1, offset = 0). + * + * @param unCalData Raw 12-bit ADC sample. + * @returns Voltage in millivolts. + */ + function calibrateShimmer3RAdcChannel(unCalData) { + return calibrateU12AdcValue(unCalData, 0, 3, 1); + } + // --------------------------------------------------------------------------- + // GSR calibration + // --------------------------------------------------------------------------- + /** + * Convert a raw GSR ADC sample to skin resistance (kΩ) using the + * Shimmer3R amplifier equation. + * + * Reference resistors per range (kΩ): [40.2, 287.0, 1000.0, 3300.0]. + * + * @param gsrUncalibratedData Raw 12-bit GSR ADC value. + * @param range Hardware range index 0–3. + * @returns Resistance in kΩ. + */ + function calibrateGsrDataToResistanceFromAmplifierEq(gsrUncalibratedData, range) { + const SHIMMER3_REF_KOHMS = [40.2, 287.0, 1000.0, 3300.0]; + const rFeedback = SHIMMER3_REF_KOHMS[range]; + const volts = calibrateShimmer3RAdcChannel(gsrUncalibratedData) / 1000.0; // mV → V + const rSource = rFeedback / (volts / 0.5 - 1.0); + return rSource; + } + /** + * Clamp a GSR resistance value to the physical limits of a given range. + * + * When `gsrRangeSetting === 4` (auto-range) no clamping is applied. + * + * @param gsrResistanceKOhms Calibrated resistance in kΩ. + * @param gsrRangeSetting Range 0–3 (fixed) or 4 (auto). + * @returns Clamped resistance in kΩ. + */ + function nudgeGsrResistance(gsrResistanceKOhms, gsrRangeSetting) { + if (gsrRangeSetting === 4) + return gsrResistanceKOhms; + const [minVal, maxVal] = SHIMMER3_GSR_RESISTANCE_MIN_MAX_KOHMS[gsrRangeSetting]; + return Math.max(minVal, Math.min(maxVal, gsrResistanceKOhms)); + } + // --------------------------------------------------------------------------- + // ExG (ADS1292R) oversampling ratio + // --------------------------------------------------------------------------- + /** + * Determine the ADS1292R oversampling ratio config byte for a given + * Shimmer3R sampling rate. + * + * This value is ORed into the lower 3 bits of ExG config byte index 4. + * + * @param samplingRate Shimmer3R sampling rate in Hz (must be ≥ 0). + * @returns Oversampling ratio index 0–6. + */ + function getOversamplingRatioADS1292R(samplingRate) { + if (!Number.isFinite(samplingRate)) { + throw new TypeError('samplingRate must be a finite number'); + } + if (samplingRate < 0) { + throw new RangeError('samplingRate must be non-negative'); + } + if (samplingRate < 125) + return 0; + if (samplingRate < 250) + return 1; + if (samplingRate < 500) + return 2; + if (samplingRate < 1000) + return 3; + if (samplingRate < 2000) + return 4; + if (samplingRate < 4000) + return 5; + return 6; // ≥ 4000 Hz + } + + /** + * Low-level byte-manipulation utilities used by the Shimmer3R protocol decoder. + * All functions are pure and have no side-effects, making them straightforward + * to unit-test without a BLE device. + */ + /** Concatenate two Uint8Arrays. */ + function concatU8(a, b) { + const out = new Uint8Array(a.length + b.length); + out.set(a); + out.set(b, a.length); + return out; + } + /** Read a 16-bit unsigned integer, little-endian. */ + function u16le$2(b, o) { + return (b[o] | (b[o + 1] << 8)) >>> 0; + } + /** Read a 16-bit unsigned integer, big-endian. */ + function u16be(b, o) { + return ((b[o] << 8) | b[o + 1]) >>> 0; + } + /** Read a 24-bit unsigned integer, little-endian. */ + function u24le$1(b, o) { + return (b[o] | (b[o + 1] << 8) | (b[o + 2] << 16)) >>> 0; + } + /** Read a 24-bit unsigned integer, big-endian. */ + function u24be(b, o) { + return ((b[o] << 16) | (b[o + 1] << 8) | b[o + 2]) >>> 0; + } + /** Sign-extend a 16-bit value to a signed integer. */ + function sign16(v) { + return v & 0x8000 ? v | 0xffff0000 : v; + } + /** Sign-extend a 24-bit value to a signed integer. */ + function sign24(v) { + return v & 0x800000 ? v | 0xff000000 : v; + } + /** Format a byte as a 2-digit uppercase hex string. */ + function hex2(v) { + return v.toString(16).padStart(2, '0').toUpperCase(); + } + + // --------------------------------------------------------------------------- + // Shimmer3RClient + // --------------------------------------------------------------------------- + /** + * Web Bluetooth client for the Shimmer3R sensor platform. + * + * Implements the ACK-first command flow used by Shimmer3R firmware ≥ v1.0.22: + * every configuration command awaits an ACK (0xFF) before resolving. + * Streaming data frames are framed with a DATA preamble (0x00). + * + * @example + * ```ts + * const client = new Shimmer3RClient({ timestampFmt: 'u24', debug: true }); + * client.onStatus = (msg) => console.log(msg); + * client.onStreamFrame = (oc) => { + * const gz = oc.get('GYRO_Z', 'raw')?.value; + * console.log('gz =', gz); + * }; + * + * await client.connect(); + * await client.setSamplingRate(51.2); + * await client.setSensors(SensorBitmapShimmer3.SENSOR_GYRO); + * await client.startStreaming(); + * ``` + */ + class Shimmer3RClient extends BaseShimmerClient { + constructor(opts = {}) { + super(opts); + this.device = null; + this.server = null; + this.rx = null; + this.tx = null; + // Protocol state + this._rxBuf = new Uint8Array(0); + this._temps = new Set(); + this.schema = null; + this._lastAckRemainder = null; + this._expectingAck = 0; + this._streaming = false; + this._lastTs = 0; + // Cached device configuration + this.enabledSensors = 0x000000; + this.samplingRateHz = 0; + this.gsrRangeSetting = 0; + this.ExpPower = 0; + /** Minimum valid GSR conductance in µS (below this, connectivity = "Disconnected"). */ + this.LIMIT_MIN_VALID_USIEMENS = 0.03; + // Callbacks + this.onInquiry = null; + this.onExpPowerChanged = null; + // --------------------------------------------------------------------------- + // BLE notify handler + // --------------------------------------------------------------------------- + this._handleNotify = (evt) => { + const chunk = new Uint8Array(evt.target.value.buffer); + this._log('Notify len=', chunk.length, 'data=', chunk); + // 1) Consume an expected ACK + if (chunk.length >= 1 && + chunk[0] === OPCODES.ACK_COMMAND_PROCESSED && + (this._expectingAck ?? 0) > 0) { + this._log('ACK detected at start of notify (expected)'); + this._expectingAck = Math.max(0, this._expectingAck - 1); + const remainder = chunk.slice(1); + this._lastAckRemainder = remainder.length ? remainder : null; + this._emitTemp(new Uint8Array([OPCODES.ACK_COMMAND_PROCESSED])); + if (this._lastAckRemainder) { + if (this._streaming && this._lastAckRemainder[0] === OPCODES.DATA_PACKET) { + this._log('Appending DATA remainder after ACK to stream buffer'); + this._rxBuf = concatU8(this._rxBuf, this._lastAckRemainder); + } + else { + this._log('Forwarding non-DATA remainder to control handlers'); + this._emitTemp(this._lastAckRemainder); + } + this._lastAckRemainder = null; + } + return; + } + // 2) During streaming, all bytes are data-plane + if (this._streaming) { + this._rxBuf = concatU8(this._rxBuf, chunk); + } + else { + this._emitTemp(chunk); + if (chunk.length && chunk[0] === OPCODES.DATA_PACKET) { + this._rxBuf = concatU8(this._rxBuf, chunk); + } + } + // 3) Try parsing if schema is available + if (this.schema) { + try { + this._parseBySchema(); + } + catch (e) { + this._log('parseBySchema error:', e); + } + } + }; + this.serviceUUID = opts.serviceUUID ?? SHIMMER3R_DEFAULTS.SERVICE_UUID; + this.rxUUID = opts.rxUUID ?? SHIMMER3R_DEFAULTS.CHAR_RX_UUID; + this.txUUID = opts.txUUID ?? SHIMMER3R_DEFAULTS.CHAR_TX_UUID; + this.forceTimestampFmt = opts.timestampFmt ?? 'u24'; + } + _log(...args) { + if (this.debug) + console.log('[Shimmer3R]', ...args); + } + // --------------------------------------------------------------------------- + // Connection management + // --------------------------------------------------------------------------- + async connect() { + this._emitStatus('Requesting Bluetooth device…'); + this.device = await navigator.bluetooth.requestDevice({ + filters: [{ services: [this.serviceUUID] }], + optionalServices: [this.serviceUUID], + }); + this._emitStatus(`Selected: ${this.device.name ?? 'Shimmer3R'}`); + this.server = await this.device.gatt.connect(); + this._emitStatus('GATT connected'); + const svc = await this.server.getPrimaryService(this.serviceUUID); + this.rx = await svc.getCharacteristic(this.rxUUID); + this.tx = await svc.getCharacteristic(this.txUUID); + this._emitStatus('RX/TX obtained'); + await this.tx.startNotifications(); + this.tx.addEventListener('characteristicvaluechanged', this._handleNotify); + this._emitStatus('Notifications started'); + } + async disconnect() { + try { + if (this.tx) { + try { + await this.tx.stopNotifications(); + } + catch { + /* ignore */ + } + this.tx.removeEventListener('characteristicvaluechanged', this._handleNotify); + } + if (this.device?.gatt?.connected) + this.device.gatt.disconnect(); + } + finally { + this.device = this.server = this.rx = this.tx = null; + this._rxBuf = new Uint8Array(0); + this.schema = null; + this._streaming = false; + this.ExpPower = 0; + this._emitStatus('Disconnected'); + } + } + // --------------------------------------------------------------------------- + // Configuration commands + // --------------------------------------------------------------------------- + /** + * Control the internal expansion power rail (required for ExG/EMG/ECG). + * @param expPower 0 = disable, 1 = enable. + */ + async setInternalExpPower(expPower) { + if (expPower !== 0 && expPower !== 1) + throw new Error('expPower must be 0 (off) or 1 (on)'); + if (!this.rx) + throw new Error('Not connected (RX missing)'); + const cmd = new Uint8Array([OPCODES.SET_INTERNAL_EXP_POWER_ENABLE_COMMAND, expPower]); + this._emitStatus(`SET_INTERNAL_EXP_POWER_ENABLE_CMD → ${expPower ? 'ON' : 'OFF'} waiting for ACK…`); + const ackRemainder = await this._writeExpectingAck(cmd, 1500); + this._emitStatus(`Expansion power ${expPower ? 'enabled' : 'disabled'} (ACK received).`); + this.ExpPower = expPower; + try { + this.onExpPowerChanged?.(expPower); + } + catch (e) { + this._log('onExpPowerChanged handler error', e); + } + return { expPower, ackRemainder }; + } + /** + * Set the GSR measurement range. + * @param gsrRange 0 = 8–63 kΩ, 1 = 63–220 kΩ, 2 = 220–680 kΩ, 3 = 680–4700 kΩ, 4 = Auto. + */ + async setGSRRange(gsrRange) { + if (!Number.isInteger(gsrRange) || gsrRange < 0 || gsrRange > 4) { + throw new Error('gsrRange must be 0–4'); + } + if (!this.rx) + throw new Error('Not connected (RX missing)'); + const cmd = new Uint8Array([OPCODES.SET_GSR_RANGE_COMMAND, gsrRange & 0xff]); + this._emitStatus('SET_GSR_RANGE → waiting for ACK…'); + const ackRemainder = await this._writeExpectingAck(cmd, 1500); + this._emitStatus('SET_GSR_RANGE (ACK received).'); + this.gsrRangeSetting = gsrRange; + return { gsrRange, ackRemainder }; + } + getInternalExpPower() { + return this.ExpPower; + } + getEnabledSensors() { + return this.enabledSensors; + } + /** + * Enable sensors via a 24-bit bitmask. + * Automatically performs an Inquiry after ACK to rebuild the stream schema. + */ + async setSensors(sensors) { + if (!Number.isFinite(sensors)) + throw new Error('sensors must be a finite number'); + if (!this.rx) + throw new Error('Not connected (RX missing)'); + sensors = (sensors >>> 0) & 0xffffff; + const b1 = sensors & 0xff; + const b2 = (sensors >>> 8) & 0xff; + const b3 = (sensors >>> 16) & 0xff; + const cmd = new Uint8Array([OPCODES.SET_SENSORS_COMMAND, b1, b2, b3]); + this._emitStatus(`SET_SENSORS_CMD → bitmask=0x${sensors.toString(16).toUpperCase().padStart(6, '0')} waiting for ACK…`); + const ackRemainder = await this._writeExpectingAck(cmd, 1500); + this._emitStatus(`Sensors ACK received. Bitmask 0x${sensors.toString(16).toUpperCase().padStart(6, '0')} applied.`); + try { + this._emitStatus('Performing automatic inquiry to refresh schema…'); + const info = await this.inquiry(); + this.enabledSensors = info.schema.enabledSensors; + this._emitStatus(`Inquiry complete. Enabled sensors: 0x${this.enabledSensors.toString(16).toUpperCase()}`); + } + catch (err) { + this._emitStatus(`Inquiry after setSensors failed: ${err.message}`); + } + return { sensors, ackRemainder, enabledSensors: this.enabledSensors }; + } + /** + * Set the sampling rate. + * The firmware expects a 16-bit divisor: `divisor = floor(32768 / rateHz)`. + */ + async setSamplingRate(rateHz) { + if (!Number.isFinite(rateHz) || rateHz <= 0) { + throw new Error('Sampling rate must be a positive number (Hz)'); + } + if (!this.rx) + throw new Error('Not connected (RX missing)'); + let divisor = Math.floor(32768 / rateHz); + divisor = Math.max(1, Math.min(0xffff, divisor)); + const lsb = divisor & 0xff; + const msb = (divisor >> 8) & 0xff; + const cmd = new Uint8Array([OPCODES.SET_SAMPLING_RATE_COMMAND, lsb, msb]); + this._emitStatus(`Set sampling rate → ${rateHz.toFixed(3)} Hz (divisor=${divisor}) — waiting for ACK…`); + const ackRemainder = await this._writeExpectingAck(cmd, 1500); + const appliedHz = 32768 / divisor; + this.samplingRateHz = appliedHz; + this._emitStatus(`Sampling rate ACKed. Applied ≈ ${this.samplingRateHz.toFixed(3)} Hz`); + return { requestedHz: rateHz, appliedHz, divisor, ackRemainder }; + } + // --------------------------------------------------------------------------- + // Inquiry + // --------------------------------------------------------------------------- + /** Send INQUIRY_CMD and parse the response to build the stream schema. */ + async inquiry() { + this._emitStatus('INQUIRY_CMD → waiting for ACK then RSP…'); + const remainder = await this._writeExpectingAck(new Uint8Array([OPCODES.INQUIRY_COMMAND]), 1500); + if (remainder && remainder[0] === OPCODES.INQUIRY_RESPONSE) { + this._log('Using post-ACK remainder as response'); + const info = this._interpretInquiryResponseShimmer3R(remainder); + this.onInquiry?.(info); + return info; + } + const rsp = await this._waitForResponse(OPCODES.INQUIRY_RESPONSE, 2000); + this._emitStatus(`Inquiry RSP (${rsp.length} bytes)`); + const info = this._interpretInquiryResponseShimmer3R(rsp); + this.onInquiry?.(info); + return info; + } + // --------------------------------------------------------------------------- + // ExG configuration helpers + // --------------------------------------------------------------------------- + /** Enable EMG (ADS1292R) in 16-bit mode on EXG1 & EXG2. */ + async enableEMG16Bit() { + if (!this.rx) + throw new Error('Not connected (RX missing)'); + await this._writeExgPages(new Uint8Array([ + 0x61, 0x00, 0x00, 0x0a, 0x02, 0xa8, 0x10, 0x69, 0x60, 0x20, 0x00, 0x00, 0x02, 0x03, + ]), new Uint8Array([ + 0x61, 0x01, 0x00, 0x0a, 0x02, 0xa0, 0x10, 0xe1, 0xe1, 0x00, 0x00, 0x00, 0x02, 0x01, + ])); + this._emitStatus('EMG 16-bit enabled on EXG1 & EXG2. Schema updated.'); + } + /** Enable EXG test signal in 16-bit mode (useful for verifying ExG hardware). */ + async enableEXGTestSignal16Bit() { + if (!this.rx) + throw new Error('Not connected (RX missing)'); + await this._writeExgPages(new Uint8Array([ + 0x61, 0x00, 0x00, 0x0a, 0x02, 0xab, 0x10, 0x15, 0x15, 0x00, 0x00, 0x00, 0x02, 0x01, + ]), new Uint8Array([ + 0x61, 0x01, 0x00, 0x0a, 0x02, 0xa3, 0x10, 0x15, 0x15, 0x00, 0x00, 0x00, 0x02, 0x01, + ])); + this._emitStatus('EXG test signal 16-bit enabled. Schema updated.'); + } + /** Enable ECG in 16-bit mode on EXG1 & EXG2. */ + async enableECG16Bit() { + if (!this.rx) + throw new Error('Not connected (RX missing)'); + await this._writeExgPages(new Uint8Array([ + 0x61, 0x00, 0x00, 0x0a, 0x02, 0xa8, 0x10, 0x40, 0x40, 0x2d, 0x00, 0x00, 0x02, 0x03, + ]), new Uint8Array([ + 0x61, 0x01, 0x00, 0x0a, 0x02, 0xa0, 0x10, 0x40, 0x47, 0x00, 0x00, 0x00, 0x02, 0x01, + ])); + this._emitStatus('ECG 16-bit enabled on EXG1 & EXG2. Schema updated.'); + } + async _writeExgPages(exg1, exg2) { + const oversamplingRatio = getOversamplingRatioADS1292R(this.samplingRateHz); + exg1 = new Uint8Array(exg1); + exg2 = new Uint8Array(exg2); + exg1[4] = (((exg1[4] >> 3) << 3) | oversamplingRatio) & 0xff; + exg2[4] = (((exg2[4] >> 3) << 3) | oversamplingRatio) & 0xff; + await this._write(exg1); + await new Promise((r) => setTimeout(r, 200)); + await this._write(exg2); + await new Promise((r) => setTimeout(r, 50)); + const targetBits = (SensorBitmapShimmer3.SENSOR_EXG1_16BIT | SensorBitmapShimmer3.SENSOR_EXG2_16BIT) >>> 0; + const newMask = ((this.enabledSensors >>> 0) | targetBits) & 0xffffff; + await this.setSensors(newMask); + } + // --------------------------------------------------------------------------- + // Streaming + // --------------------------------------------------------------------------- + async startStreaming() { + if (!this.schema) + this._emitStatus('Starting stream without schema (not recommended).'); + this._emitStatus('START_STREAM → waiting for ACK…'); + const remainder = await this._writeExpectingAck(new Uint8Array([OPCODES.START_STREAMING_COMMAND]), 1500); + this._streaming = true; + if (remainder?.length) { + if (remainder[0] === OPCODES.DATA_PACKET) { + this._rxBuf = concatU8(this._rxBuf, remainder); + } + else { + this._emitTemp(remainder); + } + } + this._emitStatus('START_STREAM ACK received; frames should follow'); + } + async stopStreaming() { + this._emitStatus('STOP_STREAM → sending (no ACK wait)…'); + try { + await this._write(new Uint8Array([OPCODES.STOP_STREAMING_COMMAND])); + this._emitStatus('STOP_STREAM command sent (skipped ACK wait).'); + } + catch (err) { + this._emitStatus(`STOP_STREAM write failed: ${err.message}`); + } + this._streaming = false; + this._rxBuf = new Uint8Array(0); + this._emitStatus('Streaming stopped.'); + } + /** Start streaming AND SD card logging simultaneously. */ + async startStreamingAndLogging() { + if (!this.schema) + this._emitStatus('Starting stream without schema (not recommended).'); + this._emitStatus('START_BT_STREAM_SD_LOGGING → waiting for ACK…'); + const remainder = await this._writeExpectingAck(new Uint8Array([OPCODES.START_SDBT_COMMAND]), 1500); + this._streaming = true; + if (remainder?.length) { + if (remainder[0] === OPCODES.DATA_PACKET) { + this._rxBuf = concatU8(this._rxBuf, remainder); + } + else { + this._emitTemp(remainder); + } + } + this._emitStatus('START_BT_STREAM_SD_LOGGING ACK received; frames should follow'); + } + /** Stop streaming AND SD card logging. */ + async stopStreamingAndLogging() { + this._emitStatus('STOP_BT_STREAM_SD_LOGGING → sending…'); + try { + await this._write(new Uint8Array([OPCODES.STOP_SDBT_COMMAND])); + } + catch (err) { + this._emitStatus(`STOP_BT_STREAM_SD_LOGGING write failed: ${err.message}`); + } + this._streaming = false; + this._rxBuf = new Uint8Array(0); + this._emitStatus('Streaming + logging stopped.'); + } + // --------------------------------------------------------------------------- + // Inquiry response / schema building + // --------------------------------------------------------------------------- + _interpretInquiryResponseShimmer3R(u8) { + let base = 0; + if (u8[0] === OPCODES.INQUIRY_RESPONSE && u8.length >= 2) + base = 1; + const adcRaw = u16le$2(u8, base + 0); + const samplingRateHz = 32768 / adcRaw; + this.samplingRateHz = samplingRateHz; + const cfg = BigInt(u8[base + 2]) | + (BigInt(u8[base + 3]) << 8n) | + (BigInt(u8[base + 4]) << 16n) | + (BigInt(u8[base + 5]) << 24n) | + (BigInt(u8[base + 6]) << 32n) | + (BigInt(u8[base + 7]) << 40n) | + (BigInt(u8[base + 8]) << 48n); + const internalExpPower = Number((cfg >> 24n) & 0x1n); + const gsrRange = Number((cfg >> 25n) & 0x7n); + this.ExpPower = internalExpPower; + this.gsrRangeSetting = gsrRange; + const numCh = u8[base + 9] ?? 0; + const bufSize = u8[base + 10] ?? 0; + const chStart = base + 11; + const channelIds = [...u8.slice(chStart, chStart + numCh)]; + const schema = this._buildSchemaFromChannels(channelIds, this.forceTimestampFmt ?? 'u24'); + this.schema = schema; + this._log(`Schema built: timestampFmt=${schema.timestampFmt}, fields=${schema.fields.length}, enabledSensors=0x${schema.enabledSensors.toString(16)}`); + this._emitStatus(`Expansion power ${this.ExpPower ? 'enabled' : 'disabled'} (ACK received).`); + return { + opcode: u8[0], + adcRaw, + samplingRateHz, + numChannels: numCh, + bufferSize: bufSize, + channelIds, + schema, + bytes: u8.slice(0), + }; + } + _buildSchemaFromChannels(channelIds, timestampFmt) { + const fields = []; + const ts = timestampFmt === 'u24' ? TIMESTAMP_FIELD.u24 : TIMESTAMP_FIELD.u16; + let packetSize = 1 + ts.sizeBytes; // 1 = preamble 0x00 + let enabledSensors = 0; + for (const id of channelIds) { + const fmt = CHANNEL_FORMATS[id]; + if (!fmt) { + fields.push({ id, name: `CH_${hex2(id)}`, fmt: 'i16', endian: 'le', sizeBytes: 2 }); + packetSize += 2; + continue; + } + fields.push({ id, ...fmt }); + packetSize += fmt.sizeBytes ?? 2; + switch (id) { + case 0x00: + case 0x01: + case 0x02: + enabledSensors |= SensorBitmapShimmer3.SENSOR_A_ACCEL; + break; + case 0x04: + case 0x05: + case 0x06: + enabledSensors |= SensorBitmapShimmer3.SENSOR_D_ACCEL; + break; + case 0x14: + case 0x15: + case 0x16: + enabledSensors |= SensorBitmapShimmer3.SENSOR_ACCEL_ALT; + break; + case 0x07: + case 0x08: + case 0x09: + enabledSensors |= SensorBitmapShimmer3.SENSOR_MAG; + break; + case 0x0a: + case 0x0b: + case 0x0c: + enabledSensors |= SensorBitmapShimmer3.SENSOR_GYRO; + break; + case 0x12: + enabledSensors |= SensorBitmapShimmer3.SENSOR_INT_A1; + break; + case 0x1c: + enabledSensors |= SensorBitmapShimmer3.SENSOR_GSR; + break; + case 0x23: + case 0x24: + enabledSensors |= SensorBitmapShimmer3.SENSOR_EXG1_16BIT; + break; + case 0x25: + case 0x26: + enabledSensors |= SensorBitmapShimmer3.SENSOR_EXG2_16BIT; + break; + case 0x1e: + case 0x1f: + enabledSensors |= SensorBitmapShimmer3.SENSOR_EXG1_24BIT; + break; + case 0x21: + case 0x22: + enabledSensors |= SensorBitmapShimmer3.SENSOR_EXG2_24BIT; + break; + default: + console.warn(`⚠️ Unmapped channel ID 0x${id.toString(16)} — added as generic i16.`); + } + } + this.enabledSensors = enabledSensors; + return { timestampFmt, fields, frameBytes: packetSize, enabledSensors, dataPreambleByte: 0x00 }; + } + // --------------------------------------------------------------------------- + // GSR calibration (applied inline during stream parsing) + // --------------------------------------------------------------------------- + _calibrateData(oc) { + const snapshot = [...oc.fields]; + for (const field of snapshot) { + if (field.name === GSR_NAME) { + const rawField = oc.get(GSR_NAME, 'raw'); + const gsrraw = rawField?.value ?? null; + if (gsrraw === null) + continue; + let adc12 = gsrraw & 0x0fff; + let currentRange = this.gsrRangeSetting; + if (currentRange === 4) { + currentRange = (gsrraw >> 14) & 0x03; + } + if (currentRange === 3 && adc12 < GSR_UNCAL_LIMIT_RANGE3) { + adc12 = GSR_UNCAL_LIMIT_RANGE3; + } + let gsrkOhm = calibrateGsrDataToResistanceFromAmplifierEq(adc12, currentRange); + gsrkOhm = nudgeGsrResistance(gsrkOhm, this.gsrRangeSetting); + const gsrConductanceUSiemens = (1.0 / gsrkOhm) * 1000; + oc.add(GSR_NAME, gsrConductanceUSiemens, 'uSiemens', 'cal'); + } + } + } + // --------------------------------------------------------------------------- + // Stream frame parser + // --------------------------------------------------------------------------- + _parseBySchema() { + const sch = this.schema; + const preamble = sch.dataPreambleByte; + const frameBytes = sch.frameBytes >>> 0; + const tsBytes = sch.timestampFmt === 'u16' ? 2 : 3; + const TS_MOD = tsBytes === 3 ? 16777216 : 65536; + let buf = this._rxBuf; + let frames = 0; + let drops = 0; + let anomalies = 0; + while (buf.length >= frameBytes * 2) { + if (buf[0] === preamble && buf[frameBytes] === preamble) { + let ts1, ts2; + try { + ts1 = tsBytes === 2 ? u16le$2(buf, 1) : u24le$1(buf, 1); + ts2 = tsBytes === 2 ? u16le$2(buf, frameBytes + 1) : u24le$1(buf, frameBytes + 1); + } + catch { + buf = buf.subarray(1); + drops++; + continue; + } + const dt = (((ts2 - ts1) % TS_MOD) + TS_MOD) % TS_MOD; + if (dt === 0) { + buf = buf.subarray(1); + drops++; + continue; + } + const frame = buf.subarray(0, frameBytes); + try { + let cursor = 1; + const oc = new ObjectCluster(this.device?.name ?? 'Shimmer3R'); + const ts = tsBytes === 2 ? u16le$2(frame, cursor) : u24le$1(frame, cursor); + cursor += tsBytes; + oc.add('TIMESTAMP', ts, 'ticks', 'raw'); + for (const f of sch.fields) { + if (cursor + f.sizeBytes > frame.length) { + throw new Error(`short frame: need ${f.sizeBytes} @${cursor}, have ${frame.length}`); + } + let v; + switch (f.fmt) { + case 'i16': + v = f.endian === 'be' ? sign16(u16be(frame, cursor)) : sign16(u16le$2(frame, cursor)); + break; + case 'u16': + v = f.endian === 'be' ? u16be(frame, cursor) : u16le$2(frame, cursor); + break; + case 'i24': + v = f.endian === 'be' ? sign24(u24be(frame, cursor)) : sign24(u24le$1(frame, cursor)); + break; + case 'u24': + v = f.endian === 'be' ? u24be(frame, cursor) : u24le$1(frame, cursor); + break; + case 'i12*': { + const msb = frame[cursor] & 0xff; + const lsb = frame[cursor + 1] & 0xff; + const raw12 = (msb << 4) | (lsb >> 4); + v = raw12 & 0x800 ? raw12 - 0x1000 : raw12; + break; + } + case 'u8': + v = frame[cursor]; + break; + default: + v = u16le$2(frame, cursor); + } + cursor += f.sizeBytes; + oc.add(f.name, v, null, 'raw'); + } + if (this._lastTs) { + const dLast = (((ts - this._lastTs) % TS_MOD) + TS_MOD) % TS_MOD; + if (dLast === 0) { + anomalies++; + this._log(`⚠️ Timestamp anomaly#${anomalies}: ts=${ts}, last=${this._lastTs}, Δ=0`); + } + } + this._lastTs = ts; + this._calibrateData(oc); + this.onStreamFrame?.(oc); + frames++; + buf = buf.subarray(frameBytes); + } + catch (e) { + this._log('⚠️ frame decode error → sliding 1 byte', e.message); + buf = buf.subarray(1); + drops++; + } + continue; + } + buf = buf.subarray(1); + drops++; + if (this.debug && drops % 64 === 1) { + this._log(`resync: dropped ${drops} byte(s) so far; bufLen=${buf.length}`); + } + } + this._rxBuf = buf; + if (drops && drops % 512 === 0) + this._lastTs = 0; + if (this.debug && (frames || drops)) { + this._log(`parse: frames=${frames}, drops=${drops}, leftover=${this._rxBuf.length}`); + } + } + // --------------------------------------------------------------------------- + // Low-level transport helpers + // --------------------------------------------------------------------------- + async _write(u8) { + if (!this.rx) + throw new Error('Not connected (RX missing)'); + this._log('Write', u8); + await this.rx.writeValue(toArrayBuffer(u8)); + } + async _writeExpectingAck(u8, ackTimeoutMs = 1000) { + this._expectingAck++; + try { + await this._write(u8); + return await this._waitForAck(ackTimeoutMs); + } + catch (e) { + this._expectingAck = Math.max(0, this._expectingAck - 1); + throw e; + } + } + _waitForAck(timeoutMs = 1000) { + return new Promise((resolve, reject) => { + const t = setTimeout(() => { + this._offTemp(handler); + reject(new Error('ACK timeout')); + }, timeoutMs); + const handler = (chunk) => { + if (!chunk || chunk.length === 0) + return; + if (chunk.length === 1 && chunk[0] === OPCODES.ACK_COMMAND_PROCESSED) { + clearTimeout(t); + this._offTemp(handler); + const rem = this._lastAckRemainder; + this._lastAckRemainder = null; + resolve(rem ?? null); + return; + } + if (chunk[0] === OPCODES.ACK_COMMAND_PROCESSED && chunk.length > 1) { + clearTimeout(t); + this._offTemp(handler); + resolve(chunk.slice(1)); + } + }; + this._onTemp(handler); + }); + } + _waitForResponse(expectedOpcode, timeoutMs = 1500) { + if (this._lastAckRemainder && this._lastAckRemainder[0] === expectedOpcode) { + const rem = this._lastAckRemainder; + this._lastAckRemainder = null; + return Promise.resolve(rem); + } + return new Promise((resolve, reject) => { + const t = setTimeout(() => { + this._offTemp(handler); + reject(new Error('Response timeout')); + }, timeoutMs); + const handler = (chunk) => { + if (!chunk || chunk.length === 0) + return; + if (chunk.length === 1 && chunk[0] === OPCODES.ACK_COMMAND_PROCESSED) + return; + if (chunk[0] === expectedOpcode) { + clearTimeout(t); + this._offTemp(handler); + resolve(chunk); + } + }; + this._onTemp(handler); + }); + } + _onTemp(fn) { + this._temps.add(fn); + } + _offTemp(fn) { + this._temps.delete(fn); + } + _emitTemp(buf) { + this._temps.forEach((fn) => { + try { + fn(buf); + } + catch (e) { + this._log('temp handler error', e); + } + }); + } + } + + // --------------------------------------------------------------------------- + // Nordic UART Service (NUS) UUIDs used by Verisense devices + // --------------------------------------------------------------------------- + /** NUS primary service UUID. */ + const NUS_SERVICE = '6e400001-b5a3-f393-e0a9-e50e24dcca9e'; + /** NUS TX characteristic UUID (host writes to this). */ + const NUS_TX = '6e400002-b5a3-f393-e0a9-e50e24dcca9e'; + /** NUS RX characteristic UUID (host subscribes to notifications from this). */ + const NUS_RX = '6e400003-b5a3-f393-e0a9-e50e24dcca9e'; + /** Nordic Secure DFU service UUID (buttonless DFU). */ + const NORDIC_DFU_SERVICE = '0000fe59-0000-1000-8000-00805f9b34fb'; + /** Nordic buttonless DFU control-point characteristic (without bond sharing). */ + const NORDIC_DFU_BUTTONLESS_WITHOUT_BONDS = '8ec90003-f315-4f60-9fb8-838830daea50'; + /** Nordic buttonless DFU control-point characteristic (with bond sharing). */ + const NORDIC_DFU_BUTTONLESS_WITH_BONDS = '8ec90004-f315-4f60-9fb8-838830daea50'; + /** Buttonless DFU control-point op-code that reboots the device into the bootloader. */ + const NORDIC_DFU_OP_ENTER_BOOTLOADER = 0x01; + // --------------------------------------------------------------------------- + // Verisense protocol command/property constants + // --------------------------------------------------------------------------- + /** Upper-nibble command classes used in protocol headers. */ + const ASM_COMMAND = Object.freeze({ + READ: 0x10, + WRITE: 0x20, + RESPONSE: 0x30, + ACK: 0x40, + NACK_BAD_HEADER_COMMAND: 0x50, + NACK_BAD_HEADER_PROPERTY: 0x60, + NACK_GENERIC: 0x70, + ACK_NEXT_STAGE: 0x80, + }); + /** Lower-nibble property IDs used in protocol headers. */ + const ASM_PROPERTY = Object.freeze({ + STATUS1: 0x01, + DATA: 0x02, + PRODUCTION_CONFIGURATION: 0x03, + OPERATIONAL_CONFIGURATION: 0x04, + TIME: 0x05, + DFU_MODE: 0x06, + PENDING_EVENTS: 0x07, + TEST_MODE: 0x08, + DEBUG_COMMAND: 0x09, + STREAM_MODE: 0x0a, + DEVICE_DISCONNECT: 0x0b, + STATUS2: 0x0c, + CALIBRATION: 0x0d, + }); + /** Stream mode payload values. */ + const STREAM_MODE = Object.freeze({ + ENABLE: 0x01, + DISABLE: 0x02, + }); + /** Test mode IDs documented by Verisense firmware. */ + const TEST_MODE_ID = Object.freeze({ + STOP: 0x00, + FLASH_8MB_1: 0x01, + FLASH_8MB_2: 0x02, + FLASH_128MB_512MB: 0x03, + EEPROM: 0x04, + ACCEL1_LIS2DW12: 0x05, + BATTERY_VOLTAGE: 0x06, + USB_POWER: 0x07, + ACCEL2_GYRO_LSM6DS3: 0x08, + PPG_MAX86XXX: 0x09, + BIOZ_MAX30002: 0x0b, + ACCEL2_GYRO_LSM6DSV: 0x0c, + MAG_LIS2MDL: 0x0d, + ALL_TESTS: 0xff, + }); + /** Debug command IDs documented by Verisense firmware. */ + const DEBUG_COMMAND_ID = Object.freeze({ + FLASH_LOOKUP_TABLE_READ: 0x01, + FLASH_LOOKUP_TABLE_ERASE: 0x02, + RWC_SCHEDULER_READ: 0x03, + ERASE_128MB_512MB_FLASH: 0x04, + ERASE_8MB_FLASH_1: 0x05, + ERASE_8MB_FLASH_2: 0x06, + ERASE_OPERATIONAL_CONFIG: 0x07, + ERASE_PRODUCTION_CONFIG: 0x08, + CLEAR_PENDING_EVENTS: 0x09, + ERASE_FLASH_AND_LOOKUP_TABLE: 0x0a, + TEST_DATA_TRANSFER_LOOP: 0x0b, + LOAD_TEST_LOOKUP_TABLE: 0x0c, + LED_TEST: 0x0d, + MAX86XXX_LED_TEST: 0x0e, + CHECK_PAYLOAD_CRC_ERRORS: 0x0f, + READ_EVENT_LOG: 0x10, + POWER_PROFILER_TEST: 0x11, + READ_RECORD_BUFFER_DETAILS: 0x12, + SYSTEM_RESET: 0x13, + IC_POWER_CONSUMPTION_TEST: 0x14, + DELETE_ALL_BONDS: 0x15, + BLE_LINK_PARAMS_READ: 0x16, + BLE_LINK_OPTIMIZE: 0x17, + /** Streamed MAX32674C algorithm-hub firmware (.msbl) upload (factory). The + * byte after this id is a HUB_FW_UPLOAD_STAGE sub-stage. */ + HUB_FW_UPLOAD: 0x18, + }); + /** Sub-stages for the streamed MAX32674C hub firmware upload, carried in the + * payload byte immediately after DEBUG_COMMAND_ID.HUB_FW_UPLOAD. */ + const HUB_FW_UPLOAD_STAGE = Object.freeze({ + BEGIN: 0x00, + PAGE_CHUNK: 0x01, + END: 0x02, + ABORT: 0x03, + }); + /** MAX32674C .msbl image geometry (mirrors firmware flashUpdater.h). A page on + * the wire is PAGE_PAYLOAD + PAGE_CRC bytes; HEADER_SIZE bytes precede page 0. */ + const MSBL = Object.freeze({ + HEADER_SIZE: 0x4c, + OFF_NUMPAGES: 0x44, + PAGE_PAYLOAD: 8192, + PAGE_CRC: 16, + PAGE_FILE_BYTES: 8208, + }); + // --------------------------------------------------------------------------- + // Operational config byte offsets + // --------------------------------------------------------------------------- + /** + * Byte indices into the Verisense operational config blob (`op[OP_IDX.xxx]`). + * Index 0 is the config version byte (must be 0x5A for a valid config). + */ + const OP_IDX = Object.freeze({ + GEN_CFG_0: 1, + GEN_CFG_1: 2, + GEN_CFG_2: 3, + GEN_CFG_3: 4, + ACCEL1_CFG_0: 5, + ACCEL1_CFG_1: 6, + ACCEL1_CFG_2: 7, + ACCEL1_CFG_3: 8, + GYRO_ACCEL2_CFG_0: 10, + GYRO_ACCEL2_CFG_1: 11, + GYRO_ACCEL2_CFG_2: 12, + GYRO_ACCEL2_CFG_3: 13, + GYRO_ACCEL2_CFG_4: 14, + GYRO_ACCEL2_CFG_5: 15, + GYRO_ACCEL2_CFG_6: 16, + GYRO_ACCEL2_CFG_7: 17, + LSM6DSV_CFG_0: 18, + LSM6DSV_CFG_1: 19, + LSM6DSV_CFG_2: 20, + START_TIME: 21, + END_TIME: 25, + INACTIVE_TIMEOUT: 29, + BLE_RETRY_COUNT: 30, + BLE_TX_POWER: 31, + BLE_DATA_TRANS_WKUP_INT_HRS: 32, + BLE_DATA_TRANS_WKUP_TIME: 33, + BLE_DATA_TRANS_WKUP_DUR: 35, + BLE_DATA_TRANS_RETRY_INT: 36, + BLE_STATUS_WKUP_INT_HRS: 38, + BLE_STATUS_WKUP_TIME: 39, + BLE_STATUS_WKUP_DUR: 41, + BLE_STATUS_RETRY_INT: 42, + BLE_RTC_SYNC_WKUP_INT_HRS: 44, + BLE_RTC_SYNC_WKUP_TIME: 45, + BLE_RTC_SYNC_WKUP_DUR: 47, + BLE_RTC_SYNC_RETRY_INT: 48, + ADC_CHANNEL_SETTINGS_0: 50, + ADC_CHANNEL_SETTINGS_1: 51, + ADAPTIVE_SCHEDULER_INT: 52, + ADAPTIVE_SCHEDULER_FAILCOUNT_MAX: 54, + PPG_REC_DUR_SECS_LSB: 55, + PPG_REC_DUR_SECS_MSB: 56, + PPG_REC_INT_MINS_LSB: 57, + PPG_REC_INT_MINS_MSB: 58, + PPG_FIFO_CONFIG: 59, + PPG_MODE_CONFIG2: 60, + PPG_MA_DEFAULT: 61, + PPG_MA_MAX_RED_IR: 62, + PPG_MA_MAX_GREEN_BLUE: 63, + PPG_AGC_TARGET_PERCENT_OF_RANGE: 64, + PPG_MA_LED_PILOT: 66, + PPG_DAC1_CROSSTALK: 67, + PPG_DAC2_CROSSTALK: 68, + PPG_DAC3_CROSSTALK: 69, + PPG_DAC4_CROSSTALK: 70, + PROX_AGC_MODE: 71, + // v9 second-generation sensor settings (only present when op[OP_CONFIG_VERSION] >= 9) + OP_CONFIG_VERSION: 9, + LIGHT_GAIN_INDEX: 72, + LIGHT_EXPOSURE_INDEX: 73, + LIGHT_CONFIG: 74, + LIGHT_SAMPLE_RATE_INDEX: 75, + SKIN_TEMP_CONFIG: 76, + SKIN_TEMP_SAMPLE_RATE_INDEX: 77, + ALGO_OP_MODE: 78, + ALGO_REPORT_MODE_RATE: 79, + ALGO_CONTROL: 80, + ALGO_INITIAL_HR: 81, + LED_AUTO_BRIGHTNESS_CFG: 82, + LED_MAX_BRIGHTNESS: 83, + LED_LUX_THRESHOLD: 84, + // MAX32674 algorithm-suite subject parameters (bytes 86-91) + PERSON_HEIGHT_CM: 86, // u16 LE, cm + PERSON_WEIGHT_KG: 88, // u16 LE, kg + PERSON_AGE: 90, // u8, years + PERSON_GENDER: 91, // u8, 0=Male, 1=Female + }); + /** Operational config layout version stored at OP_IDX.OP_CONFIG_VERSION (byte 9). + * 0 = legacy 72-byte layout; 9 = v9 layout with second-generation sensor settings. */ + const OP_CONFIG_VERSION_V9 = 9; + /** Minimum firmware version that supports the BLE-link debug commands + * (read/optimize connection parameters). */ + const BLE_LINK_MIN_FW = Object.freeze({ + major: 1, + minor: 4, + internal: 23, + }); + /** Human-readable labels for Verisense stream-packet sensor IDs. Each ID maps to + * the device part(s) that produce that stream (some streams interleave several + * physical sensors, e.g. id 6 = LSM6DSV accel + gyro + mag). */ + const VERISENSE_STREAM_SENSOR_LABELS = Object.freeze({ + 1: 'ADC (GSR / Battery)', + 2: 'Accel 1 (LIS2DW12)', + 3: 'Accel 2 + Gyro (LSM6DS3)', + 4: 'PPG (MAX86xxx)', + 6: 'Accel 2 + Gyro + Mag (LSM6DSV + LIS2MDL)', + 7: 'Ambient Light (VD6283)', + 8: 'Algo Hub (MAX32674 — HR + raw PPG)', + 9: 'Skin Temperature (MLX90632)', + }); + + /** Read a 16-bit unsigned integer, little-endian. */ + function u16le$1(b0, b1) { + return (b1 << 8) | b0; + } + /** Format a single byte as an uppercase `0xNN` string. */ + function formatByteAsHex(v) { + return `0x${(v & 0xff).toString(16).toUpperCase().padStart(2, '0')}`; + } + /** Format bytes as `[0xAA, 0xBB, ...]`. */ + function formatByteArrayAsHex(bytes) { + const u8 = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes ?? []); + return `[${Array.from(u8, (b) => formatByteAsHex(Number(b))).join(', ')}]`; + } + /** Parse text containing hex bytes like `0x5A, 00 12` into a Uint8Array. */ + function parseHexByteString(text) { + const matches = String(text ?? '').match(/[0-9a-fA-F]{2}/g) ?? []; + if (!matches.length) { + throw new Error('No hex bytes found. Example: 0x5A, 0x00, 0x12'); + } + return new Uint8Array(matches.map((h) => Number.parseInt(h, 16))); + } + /** + * Compare two firmware version triples. Returns a negative number if `a < b`, + * positive if `a > b`, and 0 if equal. Missing or non-numeric components are + * treated as 0. + */ + function compareVerisenseFirmwareVersion(a, b) { + const aMaj = Number(a?.major) || 0; + const aMin = Number(a?.minor) || 0; + const aInt = Number(a?.internal) || 0; + const bMaj = Number(b?.major) || 0; + const bMin = Number(b?.minor) || 0; + const bInt = Number(b?.internal) || 0; + if (aMaj !== bMaj) + return aMaj - bMaj; + if (aMin !== bMin) + return aMin - bMin; + return aInt - bInt; + } + /** Format a firmware version triple as `"major.minor.internal"`, or `"unknown"` + * when the version is null/undefined. */ + function formatVerisenseFirmwareVersion(v) { + if (!v) + return 'unknown'; + return `${Number(v.major) || 0}.${Number(v.minor) || 0}.${Number(v.internal) || 0}`; + } + /** Human-readable label for a Verisense stream-packet sensor ID, with a + * `"Sensor 0xNN"` hex fallback for unknown IDs. */ + function getVerisenseStreamSensorLabel(sensorId) { + const labels = VERISENSE_STREAM_SENSOR_LABELS; + return labels[sensorId] ?? `Sensor 0x${Number(sensorId).toString(16).toUpperCase()}`; + } + const ASM_PROPERTY_BY_VALUE = new Map(Object.entries(ASM_PROPERTY).map(([name, value]) => [Number(value), name])); + /** Label pending-event property values with both enum name and hex representation. */ + function formatPendingEventProperties(pendingProps) { + const list = Array.isArray(pendingProps) + ? pendingProps + : pendingProps == null + ? [] + : Array.from(pendingProps); + return list.map((prop) => { + const value = Number(prop) & 0xff; + return { + value, + hex: formatByteAsHex(value), + property: ASM_PROPERTY_BY_VALUE.get(value) ?? 'UNKNOWN_PROPERTY', + }; + }); + } + /** Read a signed 16-bit integer at byte offset `off`, little-endian. */ + function i16le(bytes, off) { + const v = bytes[off] | (bytes[off + 1] << 8); + return v & 0x8000 ? v - 0x10000 : v; + } + /** Read a 24-bit unsigned integer at byte offset `off`, little-endian. */ + function u24le(bytes, off) { + return (bytes[off] | (bytes[off + 1] << 8) | (bytes[off + 2] << 16)) >>> 0; + } + /** Read a 16-bit unsigned integer at byte offset `off`, little-endian (full-array form). */ + function u16le_at(bytes, off) { + return (bytes[off] | (bytes[off + 1] << 8)) >>> 0; + } + /** Read a 32-bit IEEE-754 float at byte offset `off`, little-endian. */ + function f32le(bytes, off) { + return new DataView(bytes.buffer, bytes.byteOffset + off, 4).getFloat32(0, true); + } + /** Return current time in milliseconds. */ + function nowMillis() { + return Date.now(); + } + /** + * Compute CRC-16/CCITT-FALSE over `bytes`. + * + * Parameters: poly=0x1021, init=0xFFFF, xorOut=0x0000. + * Matches the C# `ComputeCRC` implementation used by Verisense firmware. + */ + function crc16_ccitt_false(bytes) { + let crc = 0xffff; + for (let i = 0; i < bytes.length; i++) { + crc ^= bytes[i] << 8; + for (let b = 0; b < 8; b++) { + crc = crc & 0x8000 ? (crc << 1) ^ 0x1021 : crc << 1; + crc &= 0xffff; + } + } + return crc & 0xffff; + } + /** + * Extract the CRC that was appended to a logged payload (last 2 bytes, LE). + */ + function getOriginalCrcLE(payload) { + const n = payload.length; + return (payload[n - 2] | (payload[n - 1] << 8)) >>> 0; + } + /** + * Compute the CRC of a logged payload, excluding the trailing 2 CRC bytes, + * matching the C# `ComputeCRC(payload, 0, payload.Length - 2)` call. + */ + function computeCrcLikeCSharp(payload) { + return crc16_ccitt_false(payload.subarray(0, payload.length - 2)); + } + /** + * Convert any reasonable representation of an operational config to a + * `Uint8Array`. Throws if the input type is unrecognised. + */ + function normalizeOperationalConfig(payload) { + if (!payload) + return null; + if (payload instanceof Uint8Array) + return payload; + if (payload instanceof ArrayBuffer) + return new Uint8Array(payload); + if (Array.isArray(payload)) + return new Uint8Array(payload); + if (payload.buffer instanceof ArrayBuffer) { + const p = payload; + return new Uint8Array(p.buffer, p.byteOffset ?? 0, p.byteLength ?? p.buffer.byteLength); + } + throw new Error('normalizeOperationalConfig: unsupported payload type'); + } + /** Alias for arbitrary protocol byte payload normalization. */ + function normalizeBytePayload(payload) { + return normalizeOperationalConfig(payload); + } + /** + * Derive the 6-digit pairing PIN from a Verisense unique identifier. + * + * The PIN is built from digits 2, 4 and 6 (1-based) of the identifier, + * followed by the decimal value of the final byte padded to 3 digits. + */ + function computeVerisensePairingPin(uniqueId) { + const normalized = String(uniqueId ?? '') + .trim() + .replace(/^Verisense-/i, ''); + if (!/^[0-9a-fA-F]{8,}$/.test(normalized)) { + throw new Error('computeVerisensePairingPin: uniqueId must be a hex identifier string'); + } + if (normalized.length < 6) { + throw new Error('computeVerisensePairingPin: uniqueId must be at least 6 hex characters'); + } + const prefix = `${normalized[1]}${normalized[3]}${normalized[5]}`; + const suffixHex = normalized.slice(-2); + const suffixDec = Number.parseInt(suffixHex, 16); + return `${prefix}${suffixDec.toString().padStart(3, '0')}`; + } + /** Infer charger chip family from hardware revision fields in production config. */ + function inferVerisenseChargerChipFamily(revHwMajor, revHwMinor, revHwInternal) { + const major = Number(revHwMajor); + const minor = Number(revHwMinor); + const internal = Number(revHwInternal); + if ((major === 68 && minor === 7 && internal === 1) || (major === 68 && minor === 8)) { + return 'LTC4123'; + } + if (major === 62) { + return 'LM3658D'; + } + if ((major === 68 && minor >= 9) || (major === 61 && minor >= 5)) { + return 'XC6803'; + } + return 'UNKNOWN'; + } + /** Return chip-specific charger status text for a parsed 3-bit status code. */ + function describeVerisenseChargerStatus(chipFamily, statusCode) { + if (statusCode === 7) { + return 'Not read yet'; + } + if (chipFamily === 'LTC4123') { + if (statusCode === 0) { + return 'Zinc-air/reverse polarity/temp out-of-range/UVCL at start of charge cycle'; + } + if (statusCode === 1) { + return 'Powered on/charging'; + } + if (statusCode === 2) { + return 'Charge completed'; + } + if (statusCode === 3) { + return 'No power/not charging'; + } + } + if (chipFamily === 'LM3658D') { + if (statusCode === 0 || statusCode === 3) { + return 'Power-down, charging suspended or interrupted'; + } + if (statusCode === 1) { + return 'Pre-qualification, CC/CV charging, or top-off mode'; + } + if (statusCode === 2) { + return 'Charge completed'; + } + } + if (chipFamily === 'XC6803') { + if (statusCode === 0) { + return 'Fault (overvoltage, overcurrent, shorted battery, etc.)'; + } + if (statusCode === 1) { + return 'Pre-qualification, CC/CV charging, or top-off mode'; + } + if (statusCode === 2) { + return 'Charge completed'; + } + if (statusCode === 3) { + return 'Power-down, charging suspended or interrupted'; + } + if (statusCode === 4) { + return 'Trickle charging'; + } + } + return 'Unknown'; + } + /** Format charger summary text for UIs, e.g. "XC6803: Charge completed". */ + function formatVerisenseChargerStatus(status, hw) { + if (status.chargerPresent == null || + status.chargerStatusCode == null || + !status.chargerStatusName) { + return '-'; + } + if (!status.chargerPresent) { + return 'Not present'; + } + const chipFamily = inferVerisenseChargerChipFamily(hw?.revHwMajor ?? Number.NaN, hw?.revHwMinor ?? Number.NaN, hw?.revHwInternal ?? Number.NaN); + const text = describeVerisenseChargerStatus(chipFamily, Number(status.chargerStatusCode)); + return chipFamily === 'UNKNOWN' ? text : `${chipFamily}: ${text}`; + } + /** Upper bound for a plausible device timestamp (2100-01-01 UTC in unix + * seconds). Values beyond this are uninitialised/garbage bytes, not dates. */ + const VERISENSE_MAX_PLAUSIBLE_UNIX_SECONDS = 4102444800; + /** Format unix seconds as raw + human-readable local datetime for logging. */ + function formatVerisenseUnixAndHuman(unixSeconds) { + const unix = Number(unixSeconds); + if (!Number.isFinite(unix)) { + return { unix, human: 'invalid' }; + } + if (unix <= 0) { + return { unix, human: '1970-01-01 00:00:00 (epoch)' }; + } + if (unix > VERISENSE_MAX_PLAUSIBLE_UNIX_SECONDS) { + return { unix, human: 'not-valid' }; + } + const d = new Date(unix * 1000); + const yyyy = d.getFullYear(); + const mm = String(d.getMonth() + 1).padStart(2, '0'); + const dd = String(d.getDate()).padStart(2, '0'); + const HH = String(d.getHours()).padStart(2, '0'); + const MM = String(d.getMinutes()).padStart(2, '0'); + const SS = String(d.getSeconds()).padStart(2, '0'); + return { + unix, + human: `${yyyy}-${mm}-${dd} ${HH}:${MM}:${SS}`, + }; + } + /** Convert parsed status payload into an object with human-readable timestamps for logs. */ + function formatStatusPayloadForLog(status) { + return { + ...status, + statusTimestamp: formatVerisenseUnixAndHuman(status.statusTimestampSeconds), + lastOkTransfer: formatVerisenseUnixAndHuman(status.lastOkTransferSeconds), + lastFailTransfer: formatVerisenseUnixAndHuman(status.lastFailTransferSeconds), + }; + } + /** Convert parsed scheduler payload into an object with human-readable timestamps for logs. */ + function formatSchedulerPayloadForLog(parsed) { + const out = { + ...parsed, + adaptiveScheduler: undefined, + ltfRetry: undefined, + currentTime: formatVerisenseUnixAndHuman(parsed.currentTimeUnixSeconds), + pendingDataTransfer: formatVerisenseUnixAndHuman(parsed.pendingDataTransferUnixSeconds), + pendingStatus1: formatVerisenseUnixAndHuman(parsed.pendingStatus1UnixSeconds), + pendingRtcSync: formatVerisenseUnixAndHuman(parsed.pendingRtcSyncUnixSeconds), + pendingRetry: formatVerisenseUnixAndHuman(parsed.pendingRetryUnixSeconds), + }; + if (typeof parsed.pendingStatus2UnixSeconds === 'number') { + out.pendingStatus2 = formatVerisenseUnixAndHuman(parsed.pendingStatus2UnixSeconds); + } + if (typeof parsed.ppgMeasurementUnixSeconds === 'number') { + out.ppgMeasurement = formatVerisenseUnixAndHuman(parsed.ppgMeasurementUnixSeconds); + } + if (typeof parsed.stepCounterResetUnixSeconds === 'number') { + out.stepCounterReset = formatVerisenseUnixAndHuman(parsed.stepCounterResetUnixSeconds); + } + if (typeof parsed.sensorInactivityUnixSeconds === 'number') { + out.sensorInactivity = formatVerisenseUnixAndHuman(parsed.sensorInactivityUnixSeconds); + } + if (parsed.adaptiveScheduler) { + out.adaptiveScheduler = { + ...parsed.adaptiveScheduler, + nextTime: formatVerisenseUnixAndHuman(parsed.adaptiveScheduler.nextUnixSeconds), + }; + } + if (parsed.ltfRetry) { + out.ltfRetry = { + ...parsed.ltfRetry, + nextTime: formatVerisenseUnixAndHuman(parsed.ltfRetry.nextUnixSeconds), + }; + } + return out; + } + const PROD_CONFIG_FLAG_DFU_ENABLED = 1 << 0; + const LOG_EVENT_NAMES = { + 0: 'NONE', + 1: 'BATTERY_FALL', + 2: 'BATTERY_RECOVER', + 3: 'WRITE_TO_FLASH_SUCCESS', + 4: 'WRITE_TO_FLASH_FAIL_GENERAL', + 5: 'WRITE_TO_FLASH_FULL', + 6: 'WRITE_TO_FLASH_FAIL_CHECK_ADDR_FREE', + 7: 'WRITE_TO_FLASH_FAIL_LOW_BATT_CHECK_ADDR_FREE', + 8: 'WRITE_TO_FLASH_FAIL_LOW_BATT_FLASH_ON', + 9: 'WRITE_TO_FLASH_FAIL_LOW_BATT_FLASH_WRITE', + 10: 'WRITE_TO_FLASH_FAIL_LOW_BATT_BEFORE_START', + 11: 'USB_PLUGGED_IN_SOFT_DEVICE', + 12: 'USB_PLUGGED_OUT_SOFT_DEVICE', + 13: 'RECORDING_PAUSED', + 14: 'RECORDING_RESUMED', + 15: 'BATTERY_RECOVER_IN_BATT_CHECK_TIMER', + 16: 'TSK_FREE_UP_FLASH', + 17: 'FREE_UP_FLASH_FAIL_LOW_BATT', + 18: 'PAYLOAD_PACKAGING_TASK_SET', + 19: 'PAYLOAD_PACKAGING_FUNCTION_CALL', + 20: 'BATTERY_VOLTAGE', + 21: 'TSK_WRITE_LOOKUP_TBL_CHANGES_TO_EEPROM', + 22: 'LPCOMP_ON', + 23: 'LPCOMP_ON_ALREADY', + 24: 'LPCOMP_OFF', + 25: 'LPCOMP_TRIED_BUT_BATT_LOW', + 26: 'BLE_CONNECTED', + 27: 'BLE_DISCONNECTED', + 28: 'TSK_WRITE_FLASH', + 29: 'PPG_TIMER_START', + 30: 'PAYLOAD_OVERSHOT', + 31: 'ADVERTISING_START', + 32: 'ADVERTISING_STOP', + 33: 'NIMH_BATT_PPG_BLOCKED_BLE_RETRY', + 34: 'NIMH_BATT_PPG_BLOCKED_BLE_ADAPT_SCH', + 35: 'NIMH_BATT_PPG_BLOCKED_BLE_PENDING_EVENTS', + 36: 'NIMH_BATT_BLE_BLOCKED_PPG', + 37: 'USB_PORT_OPEN', + 38: 'USB_PORT_CLOSED', + 39: 'FIFO_INT_SAFETY_CHECK_EVENT_ACCEL1', + 40: 'FIFO_INT_SAFETY_CHECK_EVENT_ACCEL2GYRO', + 41: 'FIFO_INT_SAFETY_CHECK_EVENT_MAX86XXX', + 42: 'FIFO_INT_SAFETY_CHECK_EVENT_MAX3000X', + 43: 'FIFO_INT_SAFETY_CHECK_EVENT_ADC', + 44: 'USB_PLUGGED_IN_PIN_HANDLER', + 45: 'USB_PLUGGED_OUT_PIN_HANDLER', + 46: 'BATTERY_CHARGER_STATUS_BAD_BATTERY', + 47: 'BATTERY_CHARGER_STATUS_CHARGING', + 48: 'BATTERY_CHARGER_STATUS_CHARGING_COMPLETE', + 49: 'BATTERY_CHARGER_STATUS_POWER_DOWN', + 50: 'LTC4123_RECOVERY_ATTEMPT', + 51: 'LTC4123_RECOVERY_GAVE_UP', + 52: 'LTC4123_CHRG_COMPLETE_OVERRIDDEN_BAD_BATT', + // DEV-790 USB enumeration debug events + 53: 'USB_POWER_READY_EVT', + 54: 'USB_USBD_ENABLE_CALLED', + 55: 'USB_USBD_START_CALLED', + 56: 'USB_COM_PORT_DISABLED_ON_DETECT', + 57: 'USB_USBD_STOPPED_EVT', + }; + const LOOKUP_STATUS_NAMES = { + 0: 'Zero', + 1: 'Full', + 2: '2Del', + 3: 'Emty', + 4: 'Bad', + 5: 'NUse', + }; + function u32le_at(bytes, off) { + return (((bytes[off] ?? 0) | + ((bytes[off + 1] ?? 0) << 8) | + ((bytes[off + 2] ?? 0) << 16) | + ((bytes[off + 3] ?? 0) << 24)) >>> + 0); + } + function decodeAsciiTrimFF(bytes) { + let end = bytes.length; + while (end > 0 && bytes[end - 1] === 0xff) + end--; + if (end === 0) + return ''; + return new TextDecoder().decode(bytes.slice(0, end)); + } + /** Convert unix seconds into Verisense 7-byte RTC payload (4-byte minutes + 3-byte ticks). */ + function unixSecondsToAsmRtcBytes(unixSeconds) { + if (!Number.isFinite(unixSeconds) || unixSeconds < 0) { + throw new Error('unixSecondsToAsmRtcBytes: unixSeconds must be a finite positive number'); + } + const minutes = Math.floor(unixSeconds / 60); + const secondsInMinute = unixSeconds - minutes * 60; + const ticks = Math.floor(secondsInMinute * 32768); + return new Uint8Array([ + minutes & 0xff, + (minutes >> 8) & 0xff, + (minutes >> 16) & 0xff, + (minutes >> 24) & 0xff, + ticks & 0xff, + (ticks >> 8) & 0xff, + (ticks >> 16) & 0xff, + ]); + } + /** Convert Verisense 7-byte RTC payload into unix seconds. */ + function asmRtcBytesToUnixSeconds(rtc7) { + if (rtc7.length !== 7) { + throw new Error('asmRtcBytesToUnixSeconds: payload must be exactly 7 bytes'); + } + const minutes = u32le_at(rtc7, 0); + const ticks = u24le(rtc7, 4); + return minutes * 60 + ticks / 32768.0; + } + /** Convert Verisense 8-byte minute counter payload into unix seconds. */ + function asmRtcMinutesBytesToUnixSeconds(minutes8) { + if (minutes8.length !== 8) { + throw new Error('asmRtcMinutesBytesToUnixSeconds: payload must be exactly 8 bytes'); + } + let minutes = 0n; + for (let i = 0; i < 8; i++) { + minutes |= BigInt(minutes8[i]) << BigInt(i * 8); + } + return Number(minutes) * 60; + } + /** + * Build a production configuration payload (56 bytes) from structured options. + * This matches the Python tooling layout used by ASM_BLE.py / ASM_Device.py. + */ + function buildProductionConfigPayload(opts) { + const mo = String(opts.manufacturingOrderNumberHex ?? '').trim(); + const mac = String(opts.macIdHex ?? '').trim(); + if (!/^[0-9a-fA-F]{8}$/.test(mo)) { + throw new Error('buildProductionConfigPayload: manufacturingOrderNumberHex must be 8 hex chars'); + } + if (!/^[0-9a-fA-F]{4}$/.test(mac)) { + throw new Error('buildProductionConfigPayload: macIdHex must be 4 hex chars'); + } + const uniqueBytes = new Uint8Array(6); + uniqueBytes.set(new Uint8Array(mo.match(/../g).map((h) => Number.parseInt(h, 16))), 0); + uniqueBytes.set(new Uint8Array(mac.match(/../g).map((h) => Number.parseInt(h, 16))), 4); + uniqueBytes.reverse(); + const revHwInternal = (opts.revHwInternal ?? 0) & 0xffff; + const revFwInternal = (opts.revFwInternal ?? 0) & 0xffff; + const out = new Uint8Array(56); + out[0] = 0x5a; + out.set(uniqueBytes, 1); + out[7] = opts.revHwMajor & 0xff; + out[8] = opts.revHwMinor & 0xff; + out[9] = opts.revFwMajor & 0xff; + out[10] = opts.revFwMinor & 0xff; + out[11] = revFwInternal & 0xff; + out[12] = (revFwInternal >> 8) & 0xff; + out[13] = revHwInternal & 0xff; + out[14] = (revHwInternal >> 8) & 0xff; + // 0xFF is the "unset" sentinel for the passkey/advertising-name region + // (bytes 15..54). The configFlags byte (55) must NOT be left as 0xFF — its + // bit 0 is PROD_CONFIG_FLAG_DFU_ENABLED, so 0xFF reads as "DFU enabled" and + // disabling DFU would silently have no effect. It is set explicitly below. + out.fill(0xff, 15, 55); + const passkeyId = opts.passkeyId ?? ''; + if (passkeyId.length > 0) { + if (passkeyId.length !== 2) { + throw new Error('buildProductionConfigPayload: passkeyId must be 2 chars when provided'); + } + out.set(new TextEncoder().encode(passkeyId), 15); + } + const passkey = opts.passkey ?? ''; + if (passkey.length > 0) { + if (passkey.length !== 6) { + throw new Error('buildProductionConfigPayload: passkey must be 6 chars when provided'); + } + out.set(new TextEncoder().encode(passkey), 17); + } + const advPrefix = opts.advertisingNamePrefix ?? ''; + if (advPrefix.length > 32) { + throw new Error('buildProductionConfigPayload: advertisingNamePrefix must be <= 32 chars'); + } + if (advPrefix.length > 0) { + out.set(new TextEncoder().encode(advPrefix), 23); + } + // Always set configFlags explicitly (0x01 = DFU enabled on boot, 0x00 = + // disabled). Matches the firmware reference encoding in ASM_Device.py. + out[55] = (opts.dfuEnabled ?? true) ? PROD_CONFIG_FLAG_DFU_ENABLED : 0; + return out; + } + /** Parse production configuration with optional passkey/name/flag fields. */ + function parseProductionConfigPayloadFull(response) { + if (response.length < 11) { + throw new Error('parseProductionConfigPayloadFull: payload must be at least 11 bytes'); + } + const base = parseProductionConfigPayload(response); + const uniqueIdentifier = [...response.slice(1, 7)] + .reverse() + .map((b) => b.toString(16).padStart(2, '0')) + .join('') + .toUpperCase(); + const revHwMajor = response[7] ?? 0; + const revHwMinor = response[8] ?? 0; + const revFwMajor = response[9] ?? 0; + const revFwMinor = response[10] ?? 0; + const revFwInternal = response.length >= 13 ? u16le_at(response, 11) : 0; + const revHwInternal = response.length >= 15 ? u16le_at(response, 13) : 0; + const passkeyId = response.length >= 17 ? decodeAsciiTrimFF(response.slice(15, 17)) : ''; + const passkey = response.length >= 23 ? decodeAsciiTrimFF(response.slice(17, 23)) : ''; + const advertisingNamePrefix = response.length >= 55 ? decodeAsciiTrimFF(response.slice(23, 55)) : ''; + const dfuEnabled = response.length >= 56 ? !!(response[55] & PROD_CONFIG_FLAG_DFU_ENABLED) : true; + return { + ...base, + manufacturingOrderNumber: uniqueIdentifier.slice(0, 8), + macId: uniqueIdentifier.slice(8, 12), + uniqueIdentifier, + revHwMajor, + revHwMinor, + revHwInternal, + revFwMajor, + revFwMinor, + revFwInternal, + passkeyId, + passkey, + advertisingNamePrefix, + dfuEnabled, + }; + } + /** + * Parse STATUS1/STATUS2 payload into a typed object. + * + * This ports the core byte parsing from ASM_Device.parse_status while keeping + * the output concise and UI-friendly. + */ + function parseStatusPayload(response, sourceStatusProperty = 'status1') { + if (response.length < 24) { + throw new Error('parseStatusPayload: payload must be at least 24 bytes'); + } + const uniqueIdentifier = [...response.slice(0, 6)] + .reverse() + .map((b) => b.toString(16).padStart(2, '0')) + .join('') + .toUpperCase(); + const hasTickFields = response.length >= 56; + const hasExtendedCapacity = response.length >= 65; + const statusTimestampSeconds = hasTickFields + ? asmRtcBytesToUnixSeconds(new Uint8Array([...response.slice(6, 10), ...response.slice(34, 37)])) + : u32le_at(response, 6) * 60; + const batteryMilliVolts = u16le_at(response, 10); + const batteryPercent = response[12] ?? 0; + const lastOkTransferSeconds = hasTickFields + ? asmRtcBytesToUnixSeconds(new Uint8Array([...response.slice(13, 17), ...response.slice(37, 40)])) + : u32le_at(response, 13) * 60; + const lastFailTransferSeconds = hasTickFields + ? asmRtcBytesToUnixSeconds(new Uint8Array([...response.slice(17, 21), ...response.slice(40, 43)])) + : u32le_at(response, 17) * 60; + const memoryFreeKb = hasExtendedCapacity + ? (response[21] | (response[22] << 8) | (response[23] << 16) | (response[57] << 24)) >>> 0 + : (response[21] | (response[22] << 8) | (response[23] << 16)) >>> 0; + const memoryCapacityKb = hasExtendedCapacity ? u32le_at(response, 60) : null; + const memoryUsedKb = memoryCapacityKb == null ? null : Math.max(0, memoryCapacityKb - memoryFreeKb); + // Bank breakdown: FULL=syncable data, 2DEL=partially-deleted, BAD=unusable flash. + // Ported from ASM_Device.parse_status. Present in payloads >= 56 bytes. In the + // extended (fw v1.02.102+, payload >= 65 bytes) format the FULL and 2DEL totals + // are split: 3 low bytes at 47-49 / 50-52 plus a high byte appended at offset + // 58 / 59 respectively (mirroring the free-memory split to byte 57). + const hasBankData = response.length >= 56; + let memoryFullBanksKb = null; + let memoryTwoDelBanksKb = null; + let memoryBadBanksKb = null; + if (hasBankData) { + if (hasExtendedCapacity) { + memoryFullBanksKb = + (response[47] | (response[48] << 8) | (response[49] << 16) | (response[58] << 24)) >>> 0; + memoryTwoDelBanksKb = + (response[50] | (response[51] << 8) | (response[52] << 16) | (response[59] << 24)) >>> 0; + memoryBadBanksKb = u32le_at(response, 53); // bytes 53-56 + } + else { + memoryFullBanksKb = (response[47] | (response[48] << 8) | (response[49] << 16)) >>> 0; + memoryTwoDelBanksKb = (response[50] | (response[51] << 8) | (response[52] << 16)) >>> 0; + memoryBadBanksKb = (response[53] | (response[54] << 8) | (response[55] << 16)) >>> 0; + } + } + const batteryFallCounter = response.length >= 26 ? u16le_at(response, 24) : null; + let statusFlags = null; + if (response.length >= 34) { + const f = response[26]; + statusFlags = { + usbPluggedIn: (f & 0x01) !== 0, + recordingPaused: (f & 0x02) !== 0, + flashIsFull: (f & 0x04) !== 0, + powerIsGood: (f & 0x08) !== 0, + adaptiveSchedulerOn: (f & 0x10) !== 0, + dfuServiceOn: (f & 0x20) !== 0, + firstBoot: (f & 0x40) !== 0, + repeatedBatteryMeasurement: (f & 0x80) !== 0, + }; + } + let chargerPresent = null; + let chargerStatusCode = null; + let chargerStatusName = null; + if (hasExtendedCapacity) { + const chargerStatusByte = response[64] ?? 0; + chargerPresent = (chargerStatusByte & 0x01) !== 0; + chargerStatusCode = (chargerStatusByte >> 1) & 0x07; + chargerStatusName = + chargerStatusCode === 0 + ? 'CHARGER_STATUS_BAD_BATTERY' + : chargerStatusCode === 1 + ? 'CHARGER_STATUS_CHARGING' + : chargerStatusCode === 2 + ? 'CHARGER_STATUS_CHARGING_COMPLETE' + : chargerStatusCode === 3 + ? 'CHARGER_STATUS_POWER_DOWN' + : chargerStatusCode === 4 + ? 'CHARGER_STATUS_TRICKLE_CHARGING' + : chargerStatusCode === 7 + ? 'CHARGER_STATUS_NOT_READ' + : 'CHARGER_STATUS_UNKNOWN'; + } + return { + uniqueIdentifier, + sourceStatusProperty, + statusTimestampSeconds, + batteryMilliVolts, + batteryPercent, + lastOkTransferSeconds, + lastFailTransferSeconds, + memoryFreeKb, + memoryCapacityKb, + memoryUsedKb, + memoryFullBanksKb, + memoryTwoDelBanksKb, + memoryBadBanksKb, + statusFlags, + batteryFallCounter, + chargerPresent, + chargerStatusCode, + chargerStatusName, + }; + } + /** Parse scheduler debug response payload from DEBUG_COMMAND_ID.RWC_SCHEDULER_READ. */ + function parseSchedulerDebugPayload(payload) { + if (payload.length < 42) { + throw new Error('parseSchedulerDebugPayload: payload is too short'); + } + let idx = 0; + const currentTimeUnixSeconds = asmRtcBytesToUnixSeconds(payload.slice(idx, idx + 7)); + idx += 7; + const bleControlByte = payload[idx++] ?? 0xff; + const bleControlCounter = bleControlByte === 0x00 + ? 'data-transfer' + : bleControlByte === 0x01 + ? 'status1' + : bleControlByte === 0x02 + ? 'rtc-sync' + : bleControlByte === 0x03 + ? 'status2' + : bleControlByte === 0xff + ? 'never' + : 'unknown'; + const next8 = () => { + const v = asmRtcMinutesBytesToUnixSeconds(payload.slice(idx, idx + 8)); + idx += 8; + return v; + }; + const out = { + currentTimeUnixSeconds, + bleControlCounter, + pendingDataTransferUnixSeconds: next8(), + pendingStatus1UnixSeconds: next8(), + pendingRtcSyncUnixSeconds: next8(), + pendingRetryUnixSeconds: next8(), + retryCount: payload[idx++] ?? 0, + retryOperation: (payload[idx++] ?? 0) === 1 ? 'ble-on' : 'ble-off', + }; + if (payload.length >= idx + 10) { + out.adaptiveScheduler = { + nextUnixSeconds: next8(), + enabled: (payload[idx++] ?? 0) === 1, + syncFailCounter: payload[idx++] ?? 0, + }; + } + if (payload.length >= idx + 11) { + const nextUnixSeconds = next8(); + const op = payload[idx++] ?? 0; + out.ltfRetry = { + nextUnixSeconds, + currentOperation: op === 0 + ? 'flash-write-retry-inactive' + : op === 1 + ? 'short-flash-write-retry' + : op === 2 + ? 'attempt-flash-write' + : op === 3 + ? 'long-flash-write-retry' + : op === 4 + ? 'sensor-paused-until-usb-plug-in' + : 'unknown', + failCounterShort: payload[idx++] ?? 0, + failCounterLong: payload[idx++] ?? 0, + }; + } + if (payload.length >= idx + 8) { + out.pendingStatus2UnixSeconds = next8(); + } + if (payload.length >= idx + 8) { + out.ppgMeasurementUnixSeconds = next8(); + } + if (payload.length >= idx + 8) { + out.stepCounterResetUnixSeconds = next8(); + } + if (payload.length >= idx + 8) { + out.sensorInactivityUnixSeconds = next8(); + } + return out; + } + /** Decode the `optimizationResult` byte from {@link parseBleLinkDebugPayload} + * (see {@link VerisenseBleOptimizationResult} for the bit meanings). */ + function decodeVerisenseBleOptimizationResult(resultByte) { + const mask = Number(resultByte ?? 0) & 0xff; + return { + notConnected: (mask & 0x80) !== 0, + phyRequested: (mask & 0x01) !== 0, + connIntervalRequested: (mask & 0x02) !== 0, + dataLengthRequested: (mask & 0x04) !== 0, + resultMask: mask, + }; + } + /** Parse debug payload from BLE link read/optimize commands. */ + function parseBleLinkDebugPayload(payload) { + if (payload.length < 10) { + throw new Error('parseBleLinkDebugPayload: payload is too short'); + } + const connectionIntervalUnits = u16le_at(payload, 4); + return { + attMtu: u16le_at(payload, 0), + maxDataLength: u16le_at(payload, 2), + connectionIntervalUnits, + connectionIntervalMs: connectionIntervalUnits * 1.25, + txPhy: payload[6] ?? 0, + rxPhy: payload[7] ?? 0, + optimizationResult: payload[8] ?? 0, + isConnected: (payload[9] ?? 0) !== 0, + }; + } + /** Parse debug payload listing bank indexes with bad CRC (2-byte LE entries). */ + function parsePayloadCrcErrorBankIndexes(payload) { + if (payload.length % 2 !== 0) { + throw new Error('parsePayloadCrcErrorBankIndexes: payload length must be even'); + } + const out = []; + for (let i = 0; i < payload.length; i += 2) + out.push(u16le_at(payload, i)); + return out; + } + /** Parse 8-byte debug event-log entries. */ + function parseEventLogPayload(payload) { + if (payload.length % 8 !== 0) { + throw new Error('parseEventLogPayload: payload length must be a multiple of 8'); + } + const out = []; + for (let i = 0; i < payload.length; i += 8) { + const entry = payload.slice(i, i + 8); + const eventId = entry[7]; + if (eventId === 0) + continue; + out.push({ + index: i / 8, + eventId, + eventName: LOG_EVENT_NAMES[eventId] ?? `EVENT_${eventId}`, + timestampUnixSeconds: eventId === 20 ? null : asmRtcBytesToUnixSeconds(entry.slice(0, 7)), + batteryMilliVolts: eventId === 20 ? u24le(entry, 0) : null, + }); + } + return out; + } + /** Parse record-buffer details payload (26-byte current layout, 19-byte legacy layout). */ + function parseRecordBufferDetailsPayload(payload) { + const bytesPerBuffer = payload.length % 26 === 0 ? 26 : payload.length % 19 === 0 ? 19 : 0; + if (!bytesPerBuffer) { + throw new Error('parseRecordBufferDetailsPayload: unsupported payload length'); + } + const out = []; + for (let i = 0; i < payload.length; i += bytesPerBuffer) { + const row = payload.slice(i, i + bytesPerBuffer); + out.push({ + bufferIndex: row[0], + bufferState: row[1], + packagedPayloadIndex: u16le_at(row, 2), + currentByteIndexForSensorData: u16le_at(row, 4), + usedBufferLength: u16le_at(row, 6), + fifoTicks: u16le_at(row, 8), + dataTimestampRwcMinutes: u32le_at(row, 10), + dataTimestampRwcTicks: u24le(row, 14), + temperatureData: u16le_at(row, 17), + dataTimestampUcClockMinutes: bytesPerBuffer >= 23 ? u32le_at(row, 19) : null, + dataTimestampUcClockTicks: bytesPerBuffer >= 26 ? u24le(row, 23) : null, + }); + } + return out; + } + /** + * Infer the lookup-table bank count from a raw debug payload length. The payload + * is 3 bytes per bank, optionally prefixed with a 4-byte head/tail block. + * Returns 0 if the length matches neither layout. + */ + function inferVerisenseLookupBankCount(payloadLen) { + if (!Number.isFinite(payloadLen) || payloadLen <= 0) + return 0; + if (payloadLen >= 4 && (payloadLen - 4) % 3 === 0) + return Math.floor((payloadLen - 4) / 3); + if (payloadLen % 3 === 0) + return Math.floor(payloadLen / 3); + return 0; + } + /** + * Parse lookup-table debug payload entries (3 bytes per bank), with optional + * 4-byte tail/head prefix present in older firmware debug responses. When + * `totalBanks` is omitted it is inferred from the payload length via + * {@link inferVerisenseLookupBankCount}. + */ + function parseLookupTablePayload(payload, totalBanks) { + const bytesPerBank = 3; + const banks = totalBanks ?? inferVerisenseLookupBankCount(payload.length); + const expectedNoHeadTail = banks * bytesPerBank; + const expectedWithHeadTail = expectedNoHeadTail + 4; + let data = payload; + let head = null; + let tail = null; + if (payload.length === expectedWithHeadTail) { + tail = u16le_at(payload, 0); + head = u16le_at(payload, 2); + data = payload.slice(4); + } + else if (payload.length !== expectedNoHeadTail) { + throw new Error(`parseLookupTablePayload: payload length ${payload.length} does not match expected ${expectedNoHeadTail} or ${expectedWithHeadTail}`); + } + const entries = []; + for (let bankIndex = 0; bankIndex < banks; bankIndex++) { + const off = bankIndex * bytesPerBank; + const statusByte = data[off]; + const pendingEepromWrite = (statusByte & 0x80) !== 0; + const statusCode = statusByte & 0x7f; + entries.push({ + bankIndex, + statusCode, + statusName: LOOKUP_STATUS_NAMES[statusCode] ?? 'Unknown', + pendingEepromWrite, + payloadIndex: u16le_at(data, off + 1), + }); + } + return { head, tail, entries }; + } + /** + * Parse the production config response payload into a structured object. + */ + function parseProductionConfigPayload(response) { + const configHeader = response[0]; + const asmid = [...response.slice(1, 7)] + .reverse() + .map((b) => b.toString(16).padStart(2, '0')) + .join(''); + const revHwMajor = response[7]; + const revHwMinor = response[8]; + const revFwMajor = response[9]; + const revFwMinor = response[10]; + const fwInternalArray = response.slice(11, 13); + const revFwInternal = fwInternalArray[0] | (fwInternalArray[1] << 8); + let revHwInternal = 0; + if (response.length >= 15) { + const hwInternalArray = response.slice(13, 15); + if (!isUniformByteArray(hwInternalArray, 0xff)) { + revHwInternal = hwInternalArray[0] | (hwInternalArray[1] << 8); + } + } + return { + hardware: `${revHwMajor}.${revHwMinor}.${revHwInternal}`, + firmware: `${revFwMajor}.${revFwMinor}.${revFwInternal}`, + asmid: asmid.toUpperCase(), + configHeader, + revHwMajor, + revHwMinor, + revHwInternal, + revFwMajor, + revFwMinor, + revFwInternal, + }; + } + /** + * Firmware default passkeys by passkey ID: a production config programmed + * with passkey ID "01" pairs with the fixed PIN "123456". Other IDs have no + * fixed default (ID "00" uses the per-device derived PIN — see + * {@link computeVerisensePairingPin}). + */ + const VERISENSE_DEFAULT_PASSKEY_BY_ID = Object.freeze({ + '01': '123456', + }); + /** The fixed passkey for a passkey ID, or undefined when the ID has none + * (leave the passkey bytes unset in the production config). */ + function defaultVerisensePasskeyForId(passkeyId) { + return VERISENSE_DEFAULT_PASSKEY_BY_ID[String(passkeyId ?? '').trim()]; + } + /** + * Build the name a Verisense sensor advertises over BLE: + * `--` (e.g. "Verisense-01-25112101B10F"). + * Returns null when any part is missing — matches how apps derive the name + * from a parsed production config that may be blank/erased. + */ + function buildVerisenseAdvertisedName(parts) { + const prefix = String(parts.prefix ?? '').trim(); + const passkeyId = String(parts.passkeyId ?? '').trim(); + const uniqueId = String(parts.uniqueId ?? '').trim(); + if (!prefix || !passkeyId || !uniqueId) + return null; + return `${prefix}-${passkeyId}-${uniqueId}`; + } + /** + * Split a Verisense advertised name back into its parts. The unique ID is the + * final `-`-separated token; the passkey ID the token before it; anything + * earlier (which may itself contain `-`) is the prefix. Returns null when the + * name does not have at least three tokens. + */ + function parseVerisenseAdvertisedName(name) { + const tokens = String(name ?? '') + .trim() + .split('-'); + if (tokens.length < 3) + return null; + const uniqueId = tokens[tokens.length - 1]; + const passkeyId = tokens[tokens.length - 2]; + const prefix = tokens.slice(0, -2).join('-'); + if (!prefix || !passkeyId || !uniqueId) + return null; + return { prefix, passkeyId, uniqueId }; + } + /** + * The 4-hex MAC ID from a Verisense advertised name (the advertised name ends + * with the unique ID = manufacturing order + MAC; its last 4 hex chars are + * the MAC ID). Returns null when the tail is not valid hex. + */ + function deriveVerisenseMacIdFromName(name) { + const tail = (String(name ?? '') + .trim() + .split('-') + .pop() ?? '') + .replace(/[^0-9A-Fa-f]/g, '') + .toUpperCase() + .slice(-4); + return /^[0-9A-F]{4}$/.test(tail) ? tail : null; + } + /** + * Short device tag for file names (e.g. "…-B10F-…"): the last 4 hex chars of + * a device unique ID or advertised name. Returns "" when unknown so callers + * can omit it cleanly. + */ + function verisenseDeviceFileTag(idOrName) { + const hex = String(idOrName ?? '').replace(/[^0-9A-Fa-f]/g, ''); + return hex.length >= 4 ? hex.slice(-4).toUpperCase() : ''; + } + + /** + * Verisense sensor-calibration TLV codec. + * + * Mirrors the firmware `asm_calibration.{c,h}` byte format. A calibration "blob" + * is a self-describing block of per-sensor calibration that the device persists, + * exposes over the `CALIBRATION` command, and stamps into every logged payload + * header via a CRC-16 version tag. + * + * Layout (all little-endian): + * + * Global header (12 bytes) + * 0 u16 totalLen (= blob.length - 2) + * 2 u8 calibFormatVersion + * 3 u8 hwVerMajor + * 4 u8 hwVerMinor + * 5 u8 fwVerMajor + * 6 u8 fwVerMinor + * 7 u16 fwVerPatch + * 9 u8 sensorBlockCount + * 10 u16 reserved + * + * Per-sensor block (12-byte header + payload) + * 0 u16 sensorId (calibration-domain id, see {@link CalibSensorId}) + * 2 u8 range/quality (bits[5:0] full-scale index; bits[7:6] calib quality) + * 3 u8 dataLen + * 4 u8[8] ts (0 = default/seeded; RTC time = real per-unit cal) + * 12 payload[dataLen] + * + * IMU payload (60 bytes, float32): bias[3] · sens[3] · align[9] (row-major 3x3) + * + * Calibration math (ASM-DES04 §8): output = K·R·physical + b, so the host + * recovers physical = R⁻¹·K⁻¹·(raw − b). K is the diagonal sensitivity, R the + * rotation into the common ASM axes, b the offset bias. + */ + const SC_CALIB_FORMAT_VERSION = 1; + const SC_GLOBAL_HEADER_BYTES = 12; + const SC_BLOCK_HEADER_BYTES = 12; + const SC_TS_BYTES = 8; + const SC_DATA_LEN_IMU = 60; + /** + * The per-block `range` byte packs the full-scale index in bits [5:0] and a 2-bit + * calibration-quality indicator in bits [7:6]. Lookups/comparisons must use only + * the index (`range & SC_CAL_RANGE_MASK`). Quality has no producer yet (always 0), + * so it is reserved without growing the blob or bumping the format version. + */ + const SC_CAL_RANGE_MASK = 0x3f; + const SC_CAL_QUALITY_SHIFT = 6; + const SC_CAL_QUALITY_MASK = 0x03; + /** Calibration-quality indicator (ST MotionAC / Android sensor-accuracy convention). */ + const CalibQuality = { + UNKNOWN: 0, + POOR: 1, + OK: 2, + GOOD: 3, + }; + /** + * Calibration-domain sensor IDs. Distinct from the data-stream sensor IDs + * (1=ADC, 2=LIS2DW12, 3=LSM6DS3, 4=PPG, 6=LSM6DSV, 7=VD6283, 8=MAX32674, + * 9=MLX90632). These reuse the Shimmer3 `SC_SENSOR_*` values where they exist, + * so accel/gyro/mag can each carry their own calibration even though one + * data-stream id (6) covers all three. + * + * Data-stream → calibration mapping: 6 → {37, 38, 42}, 2 → {39}, 3 → {40, 41}. + */ + const CalibSensorId = { + LSM6DSV_ACCEL: 37, + LSM6DSV_GYRO: 38, + LIS2DW12_ACCEL: 39, + /** 1st-gen LSM6DS3 accel (data-stream id 3). */ + LSM6DS3_ACCEL: 40, + /** 1st-gen LSM6DS3 gyro (data-stream id 3). */ + LSM6DS3_GYRO: 41, + LIS2MDL_MAG: 42, + }; + function parseImuPayload(p) { + return { + bias: [f32le(p, 0), f32le(p, 4), f32le(p, 8)], + sens: [f32le(p, 12), f32le(p, 16), f32le(p, 20)], + align: [ + f32le(p, 24), + f32le(p, 28), + f32le(p, 32), + f32le(p, 36), + f32le(p, 40), + f32le(p, 44), + f32le(p, 48), + f32le(p, 52), + f32le(p, 56), + ], + }; + } + /** Parse a calibration blob into a typed, indexable {@link CalibrationSet}. */ + function parseCalibrationBlob(blob) { + if (blob.length < SC_GLOBAL_HEADER_BYTES) { + throw new Error(`parseCalibrationBlob: blob too short (${blob.length} < ${SC_GLOBAL_HEADER_BYTES})`); + } + const totalLen = u16le_at(blob, 0); + if (totalLen + 2 !== blob.length) { + throw new Error(`parseCalibrationBlob: totalLen ${totalLen} does not match blob.length-2 ${blob.length - 2}`); + } + const formatVersion = blob[2]; + const hwVerMajor = blob[3]; + const hwVerMinor = blob[4]; + const fwVerMajor = blob[5]; + const fwVerMinor = blob[6]; + const fwVerPatch = u16le_at(blob, 7); + const blockCount = blob[9]; + const reserved = u16le_at(blob, 10); + const blocks = []; + let off = SC_GLOBAL_HEADER_BYTES; + for (let i = 0; i < blockCount; i++) { + if (off + SC_BLOCK_HEADER_BYTES > blob.length) { + throw new Error(`parseCalibrationBlob: block ${i} header out of range`); + } + const sensorId = u16le_at(blob, off); + const rangeByte = blob[off + 2]; + const range = rangeByte & SC_CAL_RANGE_MASK; + const quality = (rangeByte >> SC_CAL_QUALITY_SHIFT) & SC_CAL_QUALITY_MASK; + const dataLen = blob[off + 3]; + const ts = blob.slice(off + 4, off + 4 + SC_TS_BYTES); + const payloadStart = off + SC_BLOCK_HEADER_BYTES; + if (payloadStart + dataLen > blob.length) { + throw new Error(`parseCalibrationBlob: block ${i} payload out of range`); + } + const payload = blob.slice(payloadStart, payloadStart + dataLen); + const isDefault = ts.every((b) => b === 0); + const block = { sensorId, range, quality, dataLen, ts, isDefault, payload }; + if (dataLen === SC_DATA_LEN_IMU) { + block.imu = parseImuPayload(payload); + } + blocks.push(block); + off = payloadStart + dataLen; + } + const crc16 = crc16_ccitt_false(blob); + return { + formatVersion, + hwVerMajor, + hwVerMinor, + fwVerMajor, + fwVerMinor, + fwVerPatch, + reserved, + blocks, + crc16, + getImu(sensorId, range) { + const b = blocks.find((x) => x.sensorId === sensorId && x.range === range && x.imu); + return b?.imu ?? null; + }, + }; + } + function serializeImuPayload(imu) { + const out = new Uint8Array(SC_DATA_LEN_IMU); + const dv = new DataView(out.buffer); + for (let i = 0; i < 3; i++) + dv.setFloat32(i * 4, imu.bias[i] ?? 0, true); + for (let i = 0; i < 3; i++) + dv.setFloat32(12 + i * 4, imu.sens[i] ?? 0, true); + for (let i = 0; i < 9; i++) + dv.setFloat32(24 + i * 4, imu.align[i] ?? 0, true); + return out; + } + /** Serialize a calibration set into a blob (inverse of {@link parseCalibrationBlob}). */ + function serializeCalibrationBlob(input) { + const payloads = input.blocks.map((b) => { + if (b.payload) + return b.payload; + if (b.imu) + return serializeImuPayload(b.imu); + throw new Error('serializeCalibrationBlob: each block needs imu or payload'); + }); + let total = SC_GLOBAL_HEADER_BYTES; + for (const p of payloads) + total += SC_BLOCK_HEADER_BYTES + p.length; + const out = new Uint8Array(total); + const dv = new DataView(out.buffer); + dv.setUint16(0, total - 2, true); + out[2] = input.formatVersion ?? SC_CALIB_FORMAT_VERSION; + out[3] = input.hwVerMajor & 0xff; + out[4] = input.hwVerMinor & 0xff; + out[5] = input.fwVerMajor & 0xff; + out[6] = input.fwVerMinor & 0xff; + dv.setUint16(7, input.fwVerPatch & 0xffff, true); + out[9] = input.blocks.length & 0xff; + dv.setUint16(10, (input.reserved ?? 0) & 0xffff, true); + let off = SC_GLOBAL_HEADER_BYTES; + input.blocks.forEach((b, i) => { + const payload = payloads[i]; + dv.setUint16(off, b.sensorId & 0xffff, true); + out[off + 2] = + (b.range & SC_CAL_RANGE_MASK) | + (((b.quality ?? 0) & SC_CAL_QUALITY_MASK) << SC_CAL_QUALITY_SHIFT); + out[off + 3] = payload.length & 0xff; + if (b.ts) + out.set(b.ts.subarray(0, SC_TS_BYTES), off + 4); // else leave zero (default) + out.set(payload, off + SC_BLOCK_HEADER_BYTES); + off += SC_BLOCK_HEADER_BYTES + payload.length; + }); + return out; + } + /** CRC-16/CCITT-FALSE over a serialized blob — the value stamped into payload headers. */ + function calibrationBlobCrc(blob) { + return crc16_ccitt_false(blob); + } + /** + * Apply IMU calibration to a raw tri-axial sample. + * + * physical = align · (K⁻¹ · (raw − bias)) + * + * `bias` (b) is subtracted and `sens` (K, diagonal) divided per axis, then the + * `align` matrix (row-major 3x3) is applied directly to rotate the sensor frame + * into the common ASM frame. With identity `align` and zero `bias` this reduces + * to `raw / sens`. + * + * Convention note: `align` is the directly-applied sensor-frame → ASM-frame + * matrix (= R⁻¹ in ASM-DES04 §8's `output = K·R·physical + b` notation). This + * matches the cloud calibration CSV `rotation_*` columns one-to-one — the CSV + * stores the same applied matrix, row-major — so the sensor-calibration parser + * maps blob → CSV with NO transpose. (Confirmed against a LIS2DW12 sample CSV: + * offset→bias, sensitivity→sens, rotation→align.) + */ + function applyImuCalibration(raw, cal) { + const v0 = (raw[0] - cal.bias[0]) / cal.sens[0]; + const v1 = (raw[1] - cal.bias[1]) / cal.sens[1]; + const v2 = (raw[2] - cal.bias[2]) / cal.sens[2]; + const a = cal.align; + return [ + a[0] * v0 + a[1] * v1 + a[2] * v2, + a[3] * v0 + a[4] * v1 + a[5] * v2, + a[6] * v0 + a[7] * v1 + a[8] * v2, + ]; + } + + /** Build a protocol header byte from command/property nibbles. */ + function buildHeader(command, property) { + return ((command & 0xf0) | (property & 0x0f)) & 0xff; + } + /** Decode a protocol header byte into command/property fields. */ + function parseHeader(header) { + return { + command: (header & 0xf0), + property: (header & 0x0f), + }; + } + /** Build a complete protocol message (header + 16-bit LE payload length + payload bytes). */ + function buildMessage(command, property, payloadBytes = []) { + const payload = payloadBytes instanceof Uint8Array ? payloadBytes : new Uint8Array(payloadBytes); + const out = new Uint8Array(3 + payload.length); + out[0] = buildHeader(command, property); + out[1] = payload.length & 0xff; + out[2] = (payload.length >> 8) & 0xff; + out.set(payload, 3); + return out; + } + // --------------------------------------------------------------------------- + // Streaming-frame framing / resynchronisation + // --------------------------------------------------------------------------- + /** + * Header byte that prefixes every streaming data frame: + * `RESPONSE (0x30) | STREAM_MODE (0x0a) === 0x3A`. + */ + const STREAM_FRAME_HEADER = buildHeader(ASM_COMMAND.RESPONSE, ASM_PROPERTY.STREAM_MODE); + /** Smallest valid streaming payload: sensorId(1) + tick(3) + CRC16(2). */ + const STREAM_FRAME_MIN_PAYLOAD = 6; + /** + * Largest streaming payload we will accept. The firmware packages multi-sample + * sensor records into a single logical frame that is frequently much larger + * than one BLE notification (e.g. ~1.8 kB for an LSM6DSV accel/gyro/mag burst) + * and fragments it across several notifications; the host reassembles them in + * its receive buffer before this scanner runs. The ceiling must therefore cover + * the firmware's largest packaged payload — it mirrors the length-only path's + * `MAX_FRAME_PAYLOAD_LEN` (see VerisenseClient) — not the BLE MTU. It still + * bounds how far a corrupt length field can run before the CRC rejects it + * during resync. + * + * WARNING: do NOT shrink this to an MTU-sized value. A small ceiling silently + * drops every large frame (accel/gyro/mag), because their length exceeds the + * cap and the CRC trailer is never reached — the stream just looks dead. + */ + const STREAM_FRAME_MAX_PAYLOAD = 40000; + const STREAM_SCAN_NEED_MORE = { status: 'need-more' }; + const STREAM_SCAN_INVALID = { status: 'invalid' }; + /** + * Try to read one CRC-validated streaming frame from the front of `buf`. + * + * On the wire a streaming frame is: + * + * ``` + * [0x3A][ len LE (2) ][ sensorId(1) | tick(3) | samples… | CRC16(2) ] + * ``` + * + * where `len` is the payload length **including** the trailing 2-byte CRC, and + * the CRC-16/CCITT-FALSE covers the payload up to (but not including) those last + * 2 bytes — matching the firmware's `crc16_ccitt(buf + 3, len - 2)`. + * + * The framing has no start/sync marker, so the CRC is what makes + * resynchronisation reliable: after a flaky link drops bytes and knocks the + * stream out of alignment, the caller slides one byte at a time and accepts a + * boundary only when its CRC checks out, so misaligned/garbage data can no + * longer masquerade as a valid (but wrong sensor-id) packet. + * + * Returns: + * - `need-more` — too few bytes buffered to decide; wait for the next chunk. + * - `invalid` — the front of the buffer is not a valid frame start; the + * caller should drop one byte and try again. + * - `frame` — a CRC-valid frame; `payload` is the `len`-byte payload (CRC + * trailer included) and `consumed` is `3 + len` bytes to remove. + */ + function scanStreamFrame(buf) { + if (buf.length < 3) + return STREAM_SCAN_NEED_MORE; + if (buf[0] !== STREAM_FRAME_HEADER) + return STREAM_SCAN_INVALID; + const len = (buf[1] | (buf[2] << 8)) >>> 0; + if (len < STREAM_FRAME_MIN_PAYLOAD || len > STREAM_FRAME_MAX_PAYLOAD) { + return STREAM_SCAN_INVALID; + } + if (buf.length < 3 + len) + return STREAM_SCAN_NEED_MORE; + // CRC trailer is the last 2 payload bytes (LE); it covers the payload before it. + const crcAt = 3 + len - 2; + const claimed = (buf[crcAt] | (buf[crcAt + 1] << 8)) >>> 0; + const calc = crc16_ccitt_false(buf.subarray(3, crcAt)); + if (calc !== claimed) + return STREAM_SCAN_INVALID; + return { status: 'frame', payload: buf.slice(3, 3 + len), consumed: 3 + len }; + } + /** Parse a complete protocol message into structured fields. */ + function parseMessage(msg) { + if (msg.length < 3) + throw new Error('Invalid Verisense message: header is incomplete'); + const header = msg[0]; + const payloadLength = u16le$1(msg[1], msg[2]); + if (msg.length !== payloadLength + 3) { + throw new Error(`Invalid Verisense message: length=${payloadLength}, actualPayload=${Math.max(0, msg.length - 3)}`); + } + const { command, property } = parseHeader(header); + return { + header, + command, + property, + payloadLength, + payload: msg.slice(3), + }; + } + function isAckCommand(command) { + return command === ASM_COMMAND.ACK || command === ASM_COMMAND.ACK_NEXT_STAGE; + } + function isNackCommand(command) { + return (command === ASM_COMMAND.NACK_BAD_HEADER_COMMAND || + command === ASM_COMMAND.NACK_BAD_HEADER_PROPERTY || + command === ASM_COMMAND.NACK_GENERIC); + } + /** Convert a pending-events payload (property IDs) into a typed array. */ + function parsePendingEvents(payload) { + const out = []; + for (let i = 0; i < payload.length; i++) + out.push((payload[i] & 0x0f)); + return out; + } + + function pad2(n) { + return Math.trunc(n).toString().padStart(2, '0'); + } + function pad5(n) { + return Math.trunc(n).toString().padStart(5, '0'); + } + function dateToYyMMddHHmmss(date) { + const yy = pad2(date.getUTCFullYear() % 100); + const mm = pad2(date.getUTCMonth() + 1); + const dd = pad2(date.getUTCDate()); + const hh = pad2(date.getUTCHours()); + const min = pad2(date.getUTCMinutes()); + const ss = pad2(date.getUTCSeconds()); + return `${yy}${mm}${dd}_${hh}${min}${ss}`; + } + /** Build a binary upload file name: yyMMdd_HHmmss_00000.bin */ + function buildUploadBinaryFileName(uploadDate, firstPayloadIndex) { + if (!Number.isFinite(firstPayloadIndex) || firstPayloadIndex < 0 || firstPayloadIndex > 0xffff) { + throw new Error('buildUploadBinaryFileName: firstPayloadIndex must be in range 0..65535'); + } + return `${dateToYyMMddHHmmss(uploadDate)}_${pad5(firstPayloadIndex)}.bin`; + } + /** Build parsed CSV file name: yyMMdd_HHmmss_DataSource_00000.csv */ + function buildParsedCsvFileName(startDate, dataSource, firstPayloadIndex) { + if (!dataSource || !String(dataSource).trim()) { + throw new Error('buildParsedCsvFileName: dataSource must be a non-empty string'); + } + if (!Number.isFinite(firstPayloadIndex) || firstPayloadIndex < 0 || firstPayloadIndex > 0xffff) { + throw new Error('buildParsedCsvFileName: firstPayloadIndex must be in range 0..65535'); + } + return `${dateToYyMMddHHmmss(startDate)}_${String(dataSource).trim()}_${pad5(firstPayloadIndex)}.csv`; + } + /** Add duplicate suffix like " (2)" before extension. */ + function applyDuplicateSuffix(fileName, duplicateIndex) { + if (duplicateIndex < 2) { + throw new Error('applyDuplicateSuffix: duplicateIndex must be >= 2'); + } + const idx = fileName.lastIndexOf('.'); + if (idx <= 0) + return `${fileName} (${duplicateIndex})`; + const stem = fileName.slice(0, idx); + const ext = fileName.slice(idx); + return `${stem} (${duplicateIndex})${ext}`; + } + /** Return first non-colliding duplicate name for a target file name. */ + function nextAvailableDuplicateFileName(fileName, existingNames) { + const existing = new Set(existingNames); + if (!existing.has(fileName)) + return fileName; + let i = 2; + while (true) { + const candidate = applyDuplicateSuffix(fileName, i); + if (!existing.has(candidate)) + return candidate; + i++; + } + } + /** Parse first payload index (uint16 LE) from a payload byte array. */ + function getFirstPayloadIndex(payload) { + if (payload.length < 2) { + throw new Error('getFirstPayloadIndex: payload must contain at least 2 bytes'); + } + return u16le_at(payload, 0); + } + /** + * Evaluate whether parsed CSV output should roll to a new file. + * Rules mirror ASM-DES08 split conditions. + */ + function evaluateParsedFileSplit(input) { + const reasons = []; + const prev = input.prevTimestampSec; + const curr = input.currTimestampSec; + // Split when crossing 12:00am or 12:00pm boundaries. + const prevHalfDay = Math.floor(prev / (12 * 60 * 60)); + const currHalfDay = Math.floor(curr / (12 * 60 * 60)); + if (currHalfDay !== prevHalfDay) + reasons.push('midday-midnight-boundary'); + if ((input.prevConfigSignature ?? null) !== (input.currConfigSignature ?? null)) { + reasons.push('config-change'); + } + if (input.expectedDeltaSec != null) { + const tol = Math.max(0, input.timestampToleranceSec ?? 0); + const delta = curr - prev; + if (Math.abs(delta - input.expectedDeltaSec) > tol) { + reasons.push('timestamp-discontinuity'); + } + } + if (input.powerResetDetected) { + reasons.push('power-reset'); + } + return { shouldSplit: reasons.length > 0, reasons }; + } + + const VERISENSE_HW_MAJOR_FRIENDLY_NAMES = { + 61: 'IMU', + 62: 'GSR+', + 64: 'SDK', + 68: 'Pulse+', + }; + function getVerisenseHardwareFriendlyName(revHwMajor) { + return VERISENSE_HW_MAJOR_FRIENDLY_NAMES[revHwMajor] ?? null; + } + /** + * Second-generation Verisense hardware is currently defined as: + * - SR61.5+ + * - SR68.9+ + * - Any future major revision above SR68 + */ + function isVerisenseSecondGenerationHardware(revHwMajor, revHwMinor) { + const major = Number(revHwMajor); + const minor = Number(revHwMinor); + if (!Number.isFinite(major) || !Number.isFinite(minor)) + return false; + if (major > 68) + return true; + if (major === 61 && minor >= 5) + return true; + if (major === 68 && minor >= 9) + return true; + return false; + } + function getVerisenseHardwareCapabilities(revHwMajor, revHwMinor) { + const secondGeneration = isVerisenseSecondGenerationHardware(revHwMajor, revHwMinor); + return { + secondGeneration, + supportsMagnetometer: secondGeneration, + }; + } + /** + * GSR-capable hardware. Mirrors the firmware's authoritative + * `ShimBrd_isGsrSupportedForHwVersion` (shimmer_boards.c): + * - SR62 (any revision) + * - SR61 minor >= 5 + * - SR68 minor >= 5 + * + * Deliberately NOT {@link isVerisenseSecondGenerationHardware}: that predicate + * requires SR68 >= 9, but GSR arrived on the SR68 at minor revision 5. + */ + function isVerisenseGsrSupportedHardware(revHwMajor, revHwMinor) { + const major = Number(revHwMajor); + const minor = Number(revHwMinor); + if (!Number.isFinite(major) || !Number.isFinite(minor)) + return false; + return major === 62 || ((major === 61 || major === 68) && minor >= 5); + } + const VERISENSE_SENSOR_SUPPORT_NONE = { + accel1: false, + gyroAccel2: false, + imuGen2: false, + gsr: false, + ppg: false, + ambientLight: false, + skinTemperature: false, + algorithmHub: false, + ledAutoBrightness: false, + }; + const VERISENSE_SENSOR_SUPPORT_ALL = { + accel1: true, + gyroAccel2: true, + imuGen2: true, + gsr: true, + ppg: true, + ambientLight: true, + skinTemperature: true, + algorithmHub: true, + ledAutoBrightness: true, + }; + /** + * Resolves which sensor blocks a given Verisense hardware revision carries, + * derived from the firmware Model IC matrix + * (verisense-firmware/docs/VERISENSE_MODEL_IC_MATRIX.md). + * + * Unknown / development hardware (e.g. SR64, or any unrecognised major + * revision) reports every block as present so consumers never hide a setting + * they cannot confidently rule out. + */ + function getVerisenseHardwareSensorSupport(revHwMajor, revHwMinor) { + const major = Number(revHwMajor); + const minor = Number(revHwMinor); + if (!Number.isFinite(major) || !Number.isFinite(minor)) { + return { ...VERISENSE_SENSOR_SUPPORT_ALL }; + } + const gen2 = isVerisenseSecondGenerationHardware(major, minor); + switch (major) { + case 61: // Verisense IMU + return gen2 + ? // SR61.5+: LSM6DSV + LIS2MDL, GSR, ambient light, 2xRGB LEDs. + { + ...VERISENSE_SENSOR_SUPPORT_NONE, + imuGen2: true, + gsr: true, + ambientLight: true, + ledAutoBrightness: true, + } + : // SR61.1-4: LIS2DW12 + LSM6DS3 only. + { ...VERISENSE_SENSOR_SUPPORT_NONE, accel1: true, gyroAccel2: true }; + case 62: // Verisense GSR+: LIS2DW12 + LSM6DS3, GSR, analog PPG. + return { + ...VERISENSE_SENSOR_SUPPORT_NONE, + accel1: true, + gyroAccel2: true, + gsr: true, + ppg: true, + }; + case 63: // Verisense PPG: LIS2DW12 + LSM6DS3 + PPG. + return { ...VERISENSE_SENSOR_SUPPORT_NONE, accel1: true, gyroAccel2: true, ppg: true }; + case 68: // Verisense Pulse+ + return gen2 + ? // SR68.9+: full 2nd-gen stack. The LIS2DW12 (accel1) is physically + // present but routed to the algorithm hub and not recorded from, so + // it is treated as unsupported for operational-config purposes. + { + ...VERISENSE_SENSOR_SUPPORT_NONE, + imuGen2: true, + gsr: true, + ppg: true, + ambientLight: true, + skinTemperature: true, + algorithmHub: true, + ledAutoBrightness: true, + } + : // SR68.1-8: LIS2DW12 + PPG; GSR added from SR68.5 (Model IC matrix + + // firmware ShimBrd_isGsrSupportedForHwVersion); skin temperature from + // SR68.7. + { + ...VERISENSE_SENSOR_SUPPORT_NONE, + accel1: true, + ppg: true, + gsr: isVerisenseGsrSupportedHardware(major, minor), + skinTemperature: minor >= 7, + }; + default: + // SR64 (dev board) and any future/unknown major: assume everything. + return { ...VERISENSE_SENSOR_SUPPORT_ALL }; + } + } + function getVerisenseHardwareRevision(source) { + if (!source) + return null; + const major = Number(source.revHwMajor); + const minor = Number(source.revHwMinor); + const internal = Number(source.revHwInternal); + if (!Number.isFinite(major) || !Number.isFinite(minor) || !Number.isFinite(internal)) { + return null; + } + if (major <= 0 || major > 255 || minor < 0 || minor > 255 || internal < 0 || internal > 65535) { + return null; + } + return { + major: Math.trunc(major), + minor: Math.trunc(minor), + internal: Math.trunc(internal), + }; + } + function supportsVerisenseMagnetometer(source) { + const hw = getVerisenseHardwareRevision(source); + if (!hw) + return false; + return getVerisenseHardwareCapabilities(hw.major, hw.minor).supportsMagnetometer; + } + function formatVerisenseHardwareRevision(revHwMajor, revHwMinor, revHwInternal = 0, opts = {}) { + const prefix = opts.prefix ?? 'SR'; + const base = `${prefix}${revHwMajor}.${revHwMinor}.${revHwInternal}`; + if (!opts.includeFriendlyName) + return base; + const friendly = getVerisenseHardwareFriendlyName(revHwMajor); + return friendly ? `${base} (${friendly})` : base; + } + /** + * Battery voltage scaling for streamed ADC battery samples. + * Status responses already contain firmware-scaled battery values and should not use this helper. + */ + function getVerisenseStreamingBatteryVoltageMultiplier(revHwMajor, revHwMinor) { + // SR62 + if (revHwMajor === 62) + return 2.0; + // SR61.5+, SR68.9+, and newer major revisions. + if (isVerisenseSecondGenerationHardware(revHwMajor, revHwMinor)) { + return 2.469; + } + return 1.0; + } + + const VERISENSE_OPERATIONAL_FIELD_SCHEMA = [ + // GEN_CFG_0 + { + key: 'BLUETOOTH_EN', + label: 'Bluetooth', + desc: 'Enable BLE', + kind: 'bit', + index: OP_IDX.GEN_CFG_0, + shift: 4, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'USB_EN', + label: 'USB', + desc: 'Enable USB interface', + kind: 'bit', + index: OP_IDX.GEN_CFG_0, + shift: 3, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + // GEN_CFG_0 bit 2 is unused (was PRIORITISE_LONG_TERM_FLASH, removed in + // DEV-806): never used and never read by the firmware. The bit is left unused + // in the byte layout (free to repurpose); older configs that set it are simply + // ignored. + { + key: 'DEVICE_EN', + label: 'Device', + desc: 'Master device enable', + kind: 'bit', + index: OP_IDX.GEN_CFG_0, + shift: 1, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'RECORDING_EN', + label: 'Recording', + desc: 'Enable recording', + kind: 'bit', + index: OP_IDX.GEN_CFG_0, + shift: 0, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + // GEN_CFG_1 + { + key: 'DATA_COMPRESSION_MODE', + label: 'Data Compression', + desc: '0: Off, 1: ZLIB (future), 2: XZ (future), 3: Reserved', + kind: 'bit', + index: OP_IDX.GEN_CFG_1, + shift: 0, + width: 2, + options: [ + [0, 'Off'], + [1, 'ZLIB (future)'], + [2, 'XZ (future)'], + [3, 'Reserved'], + ], + }, + // GEN_CFG_2/3 + { + key: 'HR_PPG_CHANNEL', + label: 'HR PPG Channel', + desc: 'Default HR channel', + kind: 'bit', + index: OP_IDX.GEN_CFG_2, + shift: 6, + width: 2, + options: [ + [0, 'IR'], + [1, 'RED'], + [2, 'GREEN'], + [3, 'BLUE'], + ], + }, + { + key: 'STEP_COUNT_EN', + label: 'Step Counter', + desc: 'Enable step counter', + kind: 'bit', + index: OP_IDX.GEN_CFG_2, + shift: 5, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'PENDING_EVENTS_SCHEDULER_DISABLED', + label: 'Pending Events Scheduler', + desc: 'Enable/disable pending events scheduler', + kind: 'bit', + index: OP_IDX.GEN_CFG_2, + shift: 4, + width: 1, + options: [ + [0, 'Enabled'], + [1, 'Disabled'], + ], + }, + { + key: 'LOW_BATT_AUTO_STOP_DISABLED', + label: 'Low-Power Auto-Stop', + desc: 'Stop recording and BLE data transfers when the battery drops below the low-power threshold. Disabling keeps the device recording until the battery is exhausted, at the risk of data loss from brown-out.', + kind: 'bit', + index: OP_IDX.GEN_CFG_2, + shift: 3, + width: 1, + options: [ + [0, 'Enabled'], + [1, 'Disabled'], + ], + }, + { + key: 'BATT_TYPE', + label: 'Battery Type', + desc: 'Battery chemistry', + kind: 'bit', + index: OP_IDX.GEN_CFG_2, + shift: 0, + width: 1, + options: [ + [0, 'Zinc-Air'], + [1, 'NiMH'], + ], + }, + { + key: 'MAG_EN', + label: 'Magnetometer', + desc: 'Enable LIS2MDL magnetometer (second-generation hardware)', + kind: 'bit', + index: OP_IDX.GEN_CFG_3, + shift: 2, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'LED_MODE', + label: 'LED Mode', + desc: '0 Off, 1 On, 2 Low-power', + kind: 'bit', + index: OP_IDX.GEN_CFG_3, + shift: 0, + width: 2, + options: [ + [0, 'Off'], + [1, 'On'], + [2, 'Low-power'], + [3, 'Reserved'], + ], + }, + // ACCEL1 + { + key: 'ODR', + label: 'Accel1 ODR', + desc: 'Accel1 sampling rate mode', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_0, + shift: 4, + width: 4, + options: [ + [0, 'Power-down'], + [1, '12.5/1.6 Hz'], + [2, '12.5 Hz'], + [3, '25 Hz'], + [4, '50 Hz'], + [5, '100 Hz'], + [6, '200 Hz'], + [7, '400/200 Hz'], + [8, '800/200 Hz'], + [9, '1600/200 Hz'], + ], + }, + { + key: 'MODE', + label: 'Accel1 Mode', + desc: 'Operating mode', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_0, + shift: 2, + width: 2, + options: [ + [0, 'Low-Power'], + [1, 'High-Performance'], + [2, 'Single conversion'], + [3, 'Reserved'], + ], + }, + { + key: 'LP_MODE', + label: 'Accel1 LP Mode', + desc: 'Low-power sub-mode', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_0, + shift: 0, + width: 2, + options: [ + [0, 'LP1'], + [1, 'LP2'], + [2, 'LP3'], + [3, 'LP4'], + ], + }, + { + key: 'BW_FILT', + label: 'Accel1 BW Filter', + desc: '00 ODR/2, 01 ODR/4, 10 ODR/10, 11 ODR/20', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_1, + shift: 6, + width: 2, + options: [ + [0, 'ODR/2'], + [1, 'ODR/4'], + [2, 'ODR/10'], + [3, 'ODR/20'], + ], + }, + { + key: 'FS', + label: 'Accel1 Range', + desc: 'Full-scale range', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_1, + shift: 4, + width: 2, + options: [ + [0, '+-2g'], + [1, '+-4g'], + [2, '+-8g'], + [3, '+-16g'], + ], + }, + { + key: 'FDS', + label: 'Accel1 FDS', + desc: 'Filtered data selection', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_1, + shift: 3, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'LOW_NOISE', + label: 'Accel1 Low Noise', + desc: 'Low-noise mode', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_1, + shift: 2, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'HP_REF_MODE', + label: 'Accel1 HP Ref Mode', + desc: 'High-pass reference mode', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_2, + shift: 1, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'FMode', + label: 'Accel1 FIFO Mode', + desc: 'LIS2DW12 FIFO mode', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_3, + shift: 5, + width: 3, + options: [ + [0, 'Bypass'], + [1, 'FIFO'], + [2, 'Reserved'], + [3, 'Continuous-to-FIFO'], + [4, 'Bypass-to-Continuous'], + [5, 'Reserved'], + [6, 'Continuous'], + [7, 'Reserved'], + ], + }, + { + key: 'FTH', + label: 'Accel1 FIFO Threshold', + desc: '5-bit threshold (0-31)', + kind: 'bit', + index: OP_IDX.ACCEL1_CFG_3, + shift: 0, + width: 5, + min: 0, + max: 31, + }, + // ACCEL2/GYRO + { + key: 'FTH_LSB', + label: 'LSM FIFO Threshold LSB', + desc: 'Lower 8 bits of LSM FIFO threshold', + kind: 'u8', + index: OP_IDX.GYRO_ACCEL2_CFG_0, + min: 0, + max: 255, + }, + { + key: 'TIMER_PEDO_FIFDO_EN', + label: 'Timer/Pedo FIFO Dataset', + desc: 'Include step/timestamp as 4th dataset', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_1, + shift: 7, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'TIMER_PEDO_FIFO_DRDY', + label: 'Timer/Pedo FIFO DRDY', + desc: '0 write by DRDY, 1 disable write at each step', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_1, + shift: 6, + width: 1, + options: [ + [0, 'DRDY'], + [1, 'Step detect'], + ], + }, + { + key: 'FTH_MSB', + label: 'LSM FIFO Threshold MSB', + desc: 'Upper 4 bits of LSM FIFO threshold', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_1, + shift: 0, + width: 4, + min: 0, + max: 15, + }, + { + key: 'DEC_FIFO_GYRO', + label: 'Gyro FIFO Decimation', + desc: 'Decimation factor for gyro', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_2, + shift: 3, + width: 3, + options: [ + [0, 'Not in FIFO'], + [1, 'No decimation'], + [2, 'x2'], + [3, 'x3'], + [4, 'x4'], + [5, 'x8'], + [6, 'x16'], + [7, 'x32'], + ], + }, + { + key: 'DEC_FIFO_XL', + label: 'Accel2 FIFO Decimation', + desc: 'Decimation factor for accel2', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_2, + shift: 0, + width: 3, + options: [ + [0, 'Not in FIFO'], + [1, 'No decimation'], + [2, 'x2'], + [3, 'x3'], + [4, 'x4'], + [5, 'x8'], + [6, 'x16'], + [7, 'x32'], + ], + }, + { + key: 'ODR_FIFO', + label: 'LSM FIFO ODR', + desc: 'FIFO sampling rate', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_3, + shift: 3, + width: 4, + options: [ + [0, 'Disabled'], + [1, '12.5 Hz'], + [2, '26 Hz'], + [3, '52 Hz'], + [4, '104 Hz'], + [5, '208 Hz'], + [6, '416 Hz'], + [7, '833 Hz'], + [8, '1.66 kHz'], + [9, '3.33 kHz'], + [10, '6.66 kHz'], + ], + }, + { + key: 'FIFO_MODE', + label: 'LSM FIFO Mode', + desc: 'FIFO behavior', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_3, + shift: 0, + width: 3, + options: [ + [0, 'Bypass'], + [1, 'FIFO'], + [2, 'Reserved'], + [3, 'Continuous-to-FIFO'], + [4, 'Bypass-to-Continuous'], + [5, 'Reserved'], + [6, 'Continuous'], + [7, 'Reserved'], + ], + }, + { + key: 'ODR_XL', + label: 'Accel2 ODR', + desc: 'Accel2 sampling rate', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_4, + shift: 4, + width: 4, + options: [ + [0, 'Power-down'], + [1, '12.5 Hz'], + [2, '26 Hz'], + [3, '52 Hz'], + [4, '104 Hz'], + [5, '208 Hz'], + [6, '416 Hz'], + [7, '833 Hz'], + [8, '1.66 kHz'], + [9, '3.33 kHz'], + [10, '6.66 kHz'], + ], + }, + { + key: 'FS_XL', + label: 'Accel2 Range', + desc: '00 +-2g, 01 +-16g, 10 +-4g, 11 +-8g', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_4, + shift: 2, + width: 2, + options: [ + [0, '+-2g'], + [1, '+-16g'], + [2, '+-4g'], + [3, '+-8g'], + ], + }, + { + key: 'BW_XL', + label: 'Accel2 BW', + desc: 'Anti-alias filter bandwidth', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_4, + shift: 0, + width: 2, + options: [ + [0, '400 Hz'], + [1, '200 Hz'], + [2, '100 Hz'], + [3, '50 Hz'], + ], + }, + { + key: 'ODR_G', + label: 'Gyro ODR', + desc: 'Gyro sampling rate', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_5, + shift: 4, + width: 4, + options: [ + [0, 'Power-down'], + [1, '12.5 Hz'], + [2, '26 Hz'], + [3, '52 Hz'], + [4, '104 Hz'], + [5, '208 Hz'], + [6, '416 Hz'], + [7, '833 Hz'], + [8, '1.66 kHz'], + ], + }, + { + key: 'FS_G', + label: 'Gyro Range', + desc: 'Gyro full-scale', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_5, + shift: 2, + width: 2, + options: [ + [0, '250 dps'], + [1, '500 dps'], + [2, '1000 dps'], + [3, '2000 dps'], + ], + }, + { + key: 'FS_125', + label: 'Gyro 125 dps', + desc: 'Enable 125 dps full-scale', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_5, + shift: 1, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'G_HM_MODE', + label: 'Gyro High-Performance Mode', + desc: '0 HP enabled, 1 HP disabled', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_6, + shift: 7, + width: 1, + options: [ + [0, 'Enabled'], + [1, 'Disabled'], + ], + }, + { + key: 'HP_G_EN', + label: 'Gyro HPF', + desc: 'Gyro high-pass filter', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_6, + shift: 6, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'HPCF_G', + label: 'Gyro HPF Cutoff', + desc: 'Gyro HPF cutoff frequency', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_6, + shift: 4, + width: 2, + options: [ + [0, '0.0081 Hz'], + [1, '0.0324 Hz'], + [2, '2.07 Hz'], + [3, '16.32 Hz'], + ], + }, + { + key: 'HP_G_RST', + label: 'Gyro HPF Reset', + desc: 'Reset digital HPF', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_6, + shift: 3, + width: 1, + options: [ + [0, 'Off'], + [1, 'On'], + ], + }, + { + key: 'ROUNDING_STATUS', + label: 'Rounding Status', + desc: 'Source register rounding', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_6, + shift: 2, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'LPF2_XL_EN', + label: 'Accel2 LPF2', + desc: 'LPF2 selection', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_7, + shift: 7, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'HPCF_XL', + label: 'Accel2 HP/Slope Cutoff', + desc: 'HPCF_XL bits', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_7, + shift: 5, + width: 2, + min: 0, + max: 3, + }, + { + key: 'HP_SLOPE_XL_EN', + label: 'Accel2 HP/Slope Enable', + desc: 'HP/slope filter selection', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_7, + shift: 2, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'LOW_PASS_ON_6D', + label: 'Low-pass on 6D', + desc: 'Low-pass filter on 6D function', + kind: 'bit', + index: OP_IDX.GYRO_ACCEL2_CFG_7, + shift: 0, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + // LSM6DSV explicit host fields (bytes 18..20) + { + key: 'LSM6DSV_ODR_XL', + label: 'LSM6DSV Accel ODR', + desc: 'Accel ODR (LSM6DSV ODR_XL datasheet register value)', + kind: 'bit', + index: OP_IDX.LSM6DSV_CFG_0, + shift: 0, + width: 4, + options: [ + [0, 'Off'], + [1, '1.875 Hz'], + [2, '7.5 Hz'], + [3, '15 Hz'], + [4, '30 Hz'], + [5, '60 Hz'], + [6, '120 Hz'], + [7, '240 Hz'], + [8, '480 Hz'], + [9, '960 Hz'], + [10, '1920 Hz'], + [11, '3840 Hz'], + [12, '7680 Hz'], + ], + }, + { + key: 'LSM6DSV_FS_XL', + label: 'LSM6DSV Accel Range', + desc: 'Second-gen accel range code', + kind: 'bit', + index: OP_IDX.LSM6DSV_CFG_0, + shift: 4, + width: 2, + options: [ + [0, '+-2g'], + [1, '+-4g'], + [2, '+-8g'], + [3, '+-16g'], + ], + }, + { + key: 'LSM6DSV_ODR_G', + label: 'LSM6DSV Gyro ODR', + desc: 'Gyro ODR (LSM6DSV ODR_G datasheet register value)', + kind: 'bit', + index: OP_IDX.LSM6DSV_CFG_1, + shift: 0, + width: 4, + options: [ + [0, 'Off'], + [1, '1.875 Hz'], + [2, '7.5 Hz'], + [3, '15 Hz'], + [4, '30 Hz'], + [5, '60 Hz'], + [6, '120 Hz'], + [7, '240 Hz'], + [8, '480 Hz'], + [9, '960 Hz'], + [10, '1920 Hz'], + [11, '3840 Hz'], + [12, '7680 Hz'], + ], + }, + { + key: 'LSM6DSV_FS_G', + label: 'LSM6DSV Gyro Range', + desc: 'Gyro range (LSM6DSV FS_G datasheet register value)', + kind: 'bit', + index: OP_IDX.LSM6DSV_CFG_1, + shift: 4, + width: 4, + options: [ + [0, '125 dps'], + [1, '250 dps'], + [2, '500 dps'], + [3, '1000 dps'], + [4, '2000 dps'], + ], + }, + { + key: 'LIS2MDL_ODR', + label: 'Mag Output Rate', + desc: 'Magnetometer output (sensor-hub) rate. Firmware derives the LIS2MDL ODR to keep a fresh sample available. Bounded by the accel/gyro ODR (the sensor-hub trigger).', + kind: 'bit', + index: OP_IDX.LSM6DSV_CFG_2, + shift: 0, + width: 2, + options: [ + [0, '15 Hz (LIS2MDL 20 Hz)'], + [1, '30 Hz (LIS2MDL 50 Hz)'], + [2, '60 Hz (LIS2MDL 100 Hz)'], + [3, '120 Hz (LIS2MDL 100 Hz)'], + ], + }, + // Timing and BLE scheduler + { + key: 'START_TIME', + label: 'Start Time', + desc: '32-bit start time', + kind: 'u32', + index: OP_IDX.START_TIME, + min: 0, + max: 4294967295, + }, + { + key: 'END_TIME', + label: 'End Time', + desc: '32-bit end time', + kind: 'u32', + index: OP_IDX.END_TIME, + min: 0, + max: 4294967295, + }, + { + key: 'INACTIVE_TIMEOUT_MINUTES', + label: 'Inactive Timeout (minutes)', + desc: 'Minutes of no activity before the device stops recording and sleeps. 0 disables inactivity detection.', + kind: 'inactiveMinutes', + index: OP_IDX.INACTIVE_TIMEOUT, + min: 0, + max: 63, + }, + { + key: 'RESUME_REC_ON_ACTIVITY', + label: 'Resume Rec On Activity', + desc: 'Automatically resume recording when activity is detected after an inactivity sleep. Only has an effect when Logging is enabled and the inactive timeout is above 0.', + kind: 'inactiveResume', + index: OP_IDX.INACTIVE_TIMEOUT, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'BLE_CONNECTION_TRIES_PER_DAY', + label: 'Connection Attempts per Wake', + desc: 'Number of connection attempts the device makes each time a sync window opens (applies to all schedules).', + kind: 'u8', + index: OP_IDX.BLE_RETRY_COUNT, + min: 0, + max: 255, + }, + { + key: 'BLE_TX_POWER', + label: 'BLE TX Power', + desc: 'Radio TX power', + kind: 'u8', + index: OP_IDX.BLE_TX_POWER, + options: [ + [0x08, '+8 dBm'], + [0x07, '+7 dBm'], + [0x06, '+6 dBm'], + [0x05, '+5 dBm'], + [0x04, '+4 dBm'], + [0x03, '+3 dBm'], + [0x02, '+2 dBm'], + [0x00, '+0 dBm'], + [0xfc, '-4 dBm'], + [0xf8, '-8 dBm'], + [0xf4, '-12 dBm'], + [0xf0, '-16 dBm'], + [0xec, '-20 dBm'], + [0xd8, '-40 dBm'], + ], + }, + { + key: 'BLE_DATA_TRANS_WKUP_INT_HOURS', + label: 'Data Transfer Wake Interval (hrs)', + desc: 'How often the data-transfer sync runs: 0 = off, 24 = once daily at the sync time, 1–23 = every N hours.', + kind: 'u8', + index: OP_IDX.BLE_DATA_TRANS_WKUP_INT_HRS, + min: 0, + max: 24, + }, + { + key: 'BLE_DATA_TRANS_WKUP_TIME', + label: 'Data Transfer Sync Time', + desc: 'Time of day for the data-transfer sync (minutes since midnight, 0–1439).', + kind: 'u16', + index: OP_IDX.BLE_DATA_TRANS_WKUP_TIME, + min: 0, + max: 1439, + }, + { + key: 'BLE_DATA_TRANS_WKUP_DUR', + label: 'Data Transfer Active Duration (minutes)', + desc: 'Minutes Bluetooth stays active during the data-transfer sync window.', + kind: 'u8', + index: OP_IDX.BLE_DATA_TRANS_WKUP_DUR, + min: 0, + max: 255, + }, + { + key: 'BLE_DATA_TRANS_RETRY_INT', + label: 'Data Transfer Retry Interval (minutes)', + desc: 'Minutes between connection attempts within the data-transfer sync window.', + kind: 'u16', + index: OP_IDX.BLE_DATA_TRANS_RETRY_INT, + min: 0, + max: 1439, + }, + { + key: 'BLE_STATUS_WKUP_INT_HOURS', + label: 'Status Wake Interval (hrs)', + desc: 'How often the status sync runs: 0 = off, 24 = once daily at the sync time, 1–23 = every N hours.', + kind: 'u8', + index: OP_IDX.BLE_STATUS_WKUP_INT_HRS, + min: 0, + max: 24, + }, + { + key: 'BLE_STATUS_WKUP_TIME', + label: 'Status Sync Time', + desc: 'Time of day for the status sync (minutes since midnight, 0–1439).', + kind: 'u16', + index: OP_IDX.BLE_STATUS_WKUP_TIME, + min: 0, + max: 1439, + }, + { + key: 'BLE_STATUS_WKUP_DUR', + label: 'Status Active Duration (minutes)', + desc: 'Minutes Bluetooth stays active during the status sync window.', + kind: 'u8', + index: OP_IDX.BLE_STATUS_WKUP_DUR, + min: 0, + max: 255, + }, + { + key: 'BLE_STATUS_RETRY_INT', + label: 'Status Retry Interval (minutes)', + desc: 'Minutes between connection attempts within the status sync window.', + kind: 'u16', + index: OP_IDX.BLE_STATUS_RETRY_INT, + min: 0, + max: 1439, + }, + { + key: 'BLE_RTC_SYNC_WKUP_INT_HOURS', + label: 'Time Sync Wake Interval (hrs)', + desc: 'How often the time (RTC) sync runs: 0 = off, 24 = once daily at the sync time, 1–23 = every N hours.', + kind: 'u8', + index: OP_IDX.BLE_RTC_SYNC_WKUP_INT_HRS, + min: 0, + max: 24, + }, + { + key: 'BLE_RTC_SYNC_WKUP_TIME', + label: 'Time Sync Time', + desc: 'Time of day for the time (RTC) sync (minutes since midnight, 0–1439).', + kind: 'u16', + index: OP_IDX.BLE_RTC_SYNC_WKUP_TIME, + min: 0, + max: 1439, + }, + { + key: 'BLE_RTC_SYNC_WKUP_DUR', + label: 'Time Sync Active Duration (minutes)', + desc: 'Minutes Bluetooth stays active during the time (RTC) sync window.', + kind: 'u8', + index: OP_IDX.BLE_RTC_SYNC_WKUP_DUR, + min: 0, + max: 255, + }, + { + key: 'BLE_RTC_SYNC_RETRY_INT', + label: 'Time Sync Retry Interval (minutes)', + desc: 'Minutes between connection attempts within the time (RTC) sync window.', + kind: 'u16', + index: OP_IDX.BLE_RTC_SYNC_RETRY_INT, + min: 0, + max: 1439, + }, + // ADC/PPG + { + key: 'ADC_SAMPLE_RATE', + label: 'ADC Sample Rate', + desc: 'ADC sample rate code', + kind: 'bit', + index: OP_IDX.ADC_CHANNEL_SETTINGS_0, + shift: 0, + width: 6, + options: [ + [0, 'Off'], + [1, '32768.0 Hz'], + [2, '16384.0 Hz'], + [3, '8192.0 Hz'], + [4, '6553.6 Hz'], + [5, '4096.0 Hz'], + [6, '3276.8 Hz'], + [7, '2048.0 Hz'], + [8, '1638.4 Hz'], + [9, '1310.72 Hz'], + [10, '1024.0 Hz'], + [11, '819.2 Hz'], + [12, '655.36 Hz'], + [13, '512.0 Hz'], + [14, '409.6 Hz'], + [15, '327.68 Hz'], + [16, '256.0 Hz'], + [17, '204.8 Hz'], + [18, '163.84 Hz'], + [19, '128.0 Hz'], + [20, '102.4 Hz'], + [21, '81.92 Hz'], + [22, '64.0 Hz'], + [23, '51.2 Hz'], + [24, '40.96 Hz'], + [25, '32.0 Hz'], + [26, '25.6 Hz'], + [27, '20.48 Hz'], + [28, '16.0 Hz'], + [29, '12.8 Hz'], + [30, '10.24 Hz'], + [31, '8.0 Hz'], + [32, '6.4 Hz'], + [33, '5.12 Hz'], + [34, '4.0 Hz'], + [35, '3.2 Hz'], + [36, '2.56 Hz'], + [37, '2.0 Hz'], + [38, '1.6 Hz'], + [39, '1.28 Hz'], + [40, '1.0 Hz'], + [41, '0.8 Hz'], + [42, '0.64 Hz'], + ], + }, + { + key: 'ADC_OVERSAMPLE_RATE', + label: 'ADC Oversample', + desc: 'ADC oversampling', + kind: 'bit', + index: OP_IDX.ADC_CHANNEL_SETTINGS_1, + shift: 4, + width: 4, + options: [ + [0, 'Disabled'], + [1, '2x'], + [2, '4x'], + [3, '8x'], + [4, '16x'], + [5, '32x'], + [6, '64x'], + [7, '128x'], + [8, '256x'], + ], + }, + { + key: 'GSR_RANGE_SETTING', + label: 'GSR Range', + desc: 'Selectable GSR range setting', + kind: 'bit', + index: OP_IDX.ADC_CHANNEL_SETTINGS_1, + shift: 0, + width: 3, + options: [ + [0, 'Range 0 (8k-63k or 125uS-15.87uS)'], + [1, 'Range 1 (63k-220k or 15.87uS-4.5uS)'], + [2, 'Range 2 (220k-680k or 4.5uS-1.47uS)'], + [3, 'Range 3 (680k-4.7M or 1.47uS-0.21uS)'], + [4, 'Auto-Range'], + ], + }, + { + key: 'ADAPTIVE_SCHEDULER_FAILCOUNT_MAX', + label: 'Fallback Trigger (missed syncs)', + desc: 'Consecutive missed sync windows before the adaptive fallback turns on and starts retrying more often. Typical 2–3. 0 disables the fallback.', + kind: 'u8', + // Max is the full u8 range: the firmware disabled sentinel is 0xFF, and the + // encoder clamps to max — a tighter cap would corrupt a disabled config. + index: OP_IDX.ADAPTIVE_SCHEDULER_FAILCOUNT_MAX, + min: 0, + max: 255, + }, + { + key: 'ADAPTIVE_SCHEDULER_INTERVAL', + label: 'Fallback Retry Interval (minutes)', + desc: 'Once the fallback is on, minutes between extra BLE retry wakes. Typical ≈426 (about 7 hours). 0 (or 65535) disables the fallback.', + kind: 'u16', + // Max is the full u16 range: the firmware disabled sentinel is 0xFFFF, and + // the encoder clamps to max — a tighter cap would corrupt a disabled config. + index: OP_IDX.ADAPTIVE_SCHEDULER_INT, + min: 0, + max: 65535, + }, + { + key: 'PPG_REC_DUR_SECS', + label: 'PPG Record Duration (s)', + desc: '0 = always on', + kind: 'u16', + index: OP_IDX.PPG_REC_DUR_SECS_LSB, + min: 0, + max: 65535, + }, + { + key: 'PPG_REC_INT_MINS', + label: 'PPG Record Interval (minutes)', + desc: '0 = always on', + kind: 'u16', + index: OP_IDX.PPG_REC_INT_MINS_LSB, + min: 0, + max: 65535, + }, + { + key: 'SMP_AVE', + label: 'PPG Sample Averaging', + desc: 'FIFO sample averaging', + kind: 'bit', + index: OP_IDX.PPG_FIFO_CONFIG, + shift: 5, + width: 3, + options: [ + [0, '1'], + [1, '2'], + [2, '4'], + [3, '8'], + [4, '16'], + [5, '32'], + [6, '32'], + [7, '32'], + ], + }, + { + key: 'PPG_ADC_RGE', + label: 'PPG ADC Range', + desc: 'ADC range / full-scale', + kind: 'bit', + index: OP_IDX.PPG_MODE_CONFIG2, + shift: 5, + width: 2, + options: [ + [0, '7.8125 / 4096'], + [1, '15.625 / 8192'], + [2, '31.25 / 16384'], + [3, '62.5 / 32768'], + ], + }, + { + key: 'PPG_SR', + label: 'PPG Sample Rate', + desc: 'PPG sample rate', + kind: 'bit', + index: OP_IDX.PPG_MODE_CONFIG2, + shift: 2, + width: 3, + options: [ + [0, '50 Hz'], + [1, '100 Hz'], + [2, '200 Hz'], + [3, '400 Hz'], + [4, '800 Hz'], + [5, '1000 Hz'], + [6, '1600 Hz'], + [7, '3200 Hz'], + ], + }, + { + key: 'PPG_LED_PW', + label: 'PPG LED Pulse Width', + desc: '50/100/200/400 us', + kind: 'bit', + index: OP_IDX.PPG_MODE_CONFIG2, + shift: 0, + width: 2, + options: [ + [0, '50 us'], + [1, '100 us'], + [2, '200 us'], + [3, '400 us'], + ], + }, + { + key: 'PPG_MA_DEFAULT', + label: 'PPG MA Default', + desc: 'Default LED current (mA)', + kind: 'u8', + index: OP_IDX.PPG_MA_DEFAULT, + min: 0, + max: 255, + }, + { + key: 'PPG_MA_MAX_RED_IR', + label: 'PPG MA Max Red/IR', + desc: 'Max current for Red/IR (mA)', + kind: 'u8', + index: OP_IDX.PPG_MA_MAX_RED_IR, + min: 0, + max: 255, + }, + { + key: 'PPG_MA_MAX_GREEN_BLUE', + label: 'PPG MA Max Green/Blue', + desc: 'Max current for Green/Blue (mA)', + kind: 'u8', + index: OP_IDX.PPG_MA_MAX_GREEN_BLUE, + min: 0, + max: 255, + }, + { + key: 'PPG_AGC_TARGET_PERCENT_OF_RANGE', + label: 'PPG AGC Target %', + desc: 'AGC target percent of range', + kind: 'u8', + index: OP_IDX.PPG_AGC_TARGET_PERCENT_OF_RANGE, + min: 0, + max: 100, + }, + { + key: 'PPG_UNUSED_BYTE', + label: 'PPG Unused Byte', + desc: 'Reserved', + kind: 'u8', + index: 65, + min: 0, + max: 255, + }, + { + key: 'PPG_MA_LED_PILOT', + label: 'PPG MA LED Pilot', + desc: 'Pilot/proximity LED current', + kind: 'u8', + index: OP_IDX.PPG_MA_LED_PILOT, + min: 0, + max: 255, + }, + { + key: 'XTALK_DAC1', + label: 'PPG DAC1 Crosstalk', + desc: '5-bit value', + kind: 'u8', + index: OP_IDX.PPG_DAC1_CROSSTALK, + min: 0, + max: 31, + }, + { + key: 'XTALK_DAC2', + label: 'PPG DAC2 Crosstalk', + desc: '5-bit value', + kind: 'u8', + index: OP_IDX.PPG_DAC2_CROSSTALK, + min: 0, + max: 31, + }, + { + key: 'XTALK_DAC3', + label: 'PPG DAC3 Crosstalk', + desc: '5-bit value', + kind: 'u8', + index: OP_IDX.PPG_DAC3_CROSSTALK, + min: 0, + max: 31, + }, + { + key: 'XTALK_DAC4', + label: 'PPG DAC4 Crosstalk', + desc: '5-bit value', + kind: 'u8', + index: OP_IDX.PPG_DAC4_CROSSTALK, + min: 0, + max: 31, + }, + { + key: 'PROX_AGC_MODE', + label: 'Proximity/AGC Mode', + desc: '0 Disabled, 1 Driver approach, 2 Hybrid', + kind: 'u8', + index: OP_IDX.PROX_AGC_MODE, + options: [ + [0, 'AGC Off / Prox Off'], + [1, 'AGC On / Driver Prox'], + [2, 'AGC On / Hybrid Prox'], + ], + }, + // ------------------------------------------------------------------------- + // v9 second-generation sensor settings (light / skin-temp / algo-hub / LED) + // ------------------------------------------------------------------------- + // OP_CONFIG_VERSION (byte 9) is an internal layout marker, not a user setting. + // It is auto-stamped on serialize (see VERISENSE_OP_CONFIG_VERSION_V9 / + // createBlankVerisenseOperationalConfig), so it is intentionally NOT an + // editable field here. + // AMBIENT_LIGHT_EN / SKIN_TEMP_EN / ALGO_HUB_EN are sensor enables and are + // rendered as checkboxes (see VERISENSE_SENSOR_ENABLE_FIELDS), not here. + // GEN_CFG_3 bit 6 is reserved (was PPG_VIA_HUB): the MAX86176 is hardwired to + // the hub, so raw PPG always arrives under the PPG sensor id (4) when a PPG + // channel is enabled, and the algorithm output under id 8 when ALGO_HUB_EN is + // set - no routing bit is needed. + { + key: 'LIGHT_GAIN_INDEX', + label: 'Light Gain', + // Default index 0 = 1.0x, matching the VD6283 reference example + // (SetGain(..., 256), i.e. the 8.8 value 0x0100). + desc: 'VD6283 channel gain (default 1.0x)', + kind: 'u8', + index: OP_IDX.LIGHT_GAIN_INDEX, + min: 0, + max: 7, + options: [ + [0, '1.0x'], + [1, '1.67x'], + [2, '2.5x'], + [3, '5.0x'], + [4, '10.0x'], + [5, '25.0x'], + [6, '50.0x'], + [7, '66.67x'], + ], + }, + { + key: 'LIGHT_EXPOSURE_INDEX', + label: 'Light Exposure', + // Default index 0 = 100 ms (100000 us), matching the VD6283 reference + // example (SetExposureTime(..., 100000)). + desc: 'VD6283 exposure / integration time (default 100 ms). The chip cannot sample faster than it integrates, so the exposure caps the achievable sample rate at ~1/exposure (shown per option). Picking a higher sample rate therefore requires a shorter exposure.', + kind: 'u8', + index: OP_IDX.LIGHT_EXPOSURE_INDEX, + min: 0, + max: 7, + // Label suffix = max sample rate this exposure allows (≈ 1/exposure, capped + // at the 20 Hz poll ceiling). + options: [ + [0, '100 ms (max 10 Hz)'], + [1, '1.6 ms (max 20 Hz)'], + [2, '6.4 ms (max 20 Hz)'], + [3, '12.8 ms (max 20 Hz)'], + [4, '25.6 ms (max 20 Hz)'], + [5, '51.2 ms (max ~19 Hz)'], + [6, '102.4 ms (max ~9.8 Hz)'], + [7, '204.8 ms (max ~4.9 Hz)'], + ], + }, + // LIGHT_CONFIG bit 0 (continuous mode) is intentionally NOT exposed: the + // VD6283 must run in continuous mode for the timer-driven poll to read it, so + // the firmware hardcodes it. The op-config bit is left unused (free to + // repurpose). + { + key: 'LIGHT_DARK_ENABLE', + label: 'Light Dark Channel', + desc: 'Replace the visible/clear channel reading with the dark (covered-photodiode) baseline', + kind: 'bit', + index: OP_IDX.LIGHT_CONFIG, + shift: 1, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'LIGHT_FLICKER_EN', + label: 'Light Flicker Detect', + desc: 'RESERVED: VD6283 flicker detection (host PDM path pending nRF SDK v17 — not yet active)', + kind: 'bit', + index: OP_IDX.LIGHT_CONFIG, + shift: 2, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled (reserved)'], + ], + }, + { + key: 'LIGHT_SAMPLE_RATE_INDEX', + label: 'Light Sample Rate', + desc: 'Ambient-light sample rate. The firmware sets the VD6283 inter-measurement (continuous-mode) cadence to this period, so the sensor measures only as often as it is read and idles in between for lower power. The rate is limited by the exposure time (the chip cannot measure faster than it integrates): 20 Hz needs exposure ≤ 50 ms, 10 Hz needs ≤ 100 ms, etc. — see the Light Exposure options.', + kind: 'u8', + index: OP_IDX.LIGHT_SAMPLE_RATE_INDEX, + min: 0, + max: 6, + options: [ + [0, 'Off'], + [1, '0.5 Hz'], + [2, '1 Hz'], + [3, '2 Hz'], + [4, '5 Hz'], + [5, '10 Hz'], + [6, '20 Hz'], + ], + }, + { + key: 'SKIN_TEMP_MEAS_TYPE', + label: 'Skin Temp Mode', + desc: 'MLX90632 measurement type (default Medical for skin/body temperature)', + kind: 'bit', + index: OP_IDX.SKIN_TEMP_CONFIG, + shift: 0, + width: 1, + options: [ + [0, 'Medical (25–42.5 °C, ±0.2 °C)'], + [1, 'Extended (wider range, lower accuracy)'], + ], + }, + { + // Single skin-temp rate setting. Stored as the MLX90632 refresh-rate code + // (byte 76 bits 3:1); the firmware sets the chip refresh AND derives the read + // poll from it. Shown as the *medical* output rate (= refresh ÷ 2; extended + // mode is ÷ 3). The legacy poll field (byte 77) and power-mode bits (byte 76 + // bits 5:4) are now unused (free to repurpose) — continuous mode is required + // and set automatically. + key: 'SKIN_TEMP_SAMPLE_RATE', + label: 'Skin Temp Sample Rate', + desc: 'MLX90632 sample rate (medical output = chip refresh ÷2; extended ÷3). Drives both the chip refresh and the read poll.', + kind: 'bit', + index: OP_IDX.SKIN_TEMP_CONFIG, + shift: 1, + width: 3, + options: [ + [0, '0.25 Hz'], + [1, '0.5 Hz'], + [2, '1 Hz'], + [3, '2 Hz'], + [4, '4 Hz'], + [5, '8 Hz'], + [6, '16 Hz'], + [7, '32 Hz'], + ], + }, + { + key: 'ALGO_OP_MODE', + label: 'Algo Operation Mode', + desc: 'MAX32674 sensor-hub operation mode', + kind: 'u8', + index: OP_IDX.ALGO_OP_MODE, + min: 0, + max: 5, + options: [ + [0, 'Raw'], + [1, 'WHRM (HR)'], + [3, 'IRN'], + [4, 'HRV'], + [5, 'RR'], + ], + }, + { + key: 'ALGO_REPORT_MODE', + label: 'Algo Report Mode', + desc: 'Sensor-hub report mode', + kind: 'bit', + index: OP_IDX.ALGO_REPORT_MODE_RATE, + shift: 0, + width: 2, + options: [ + [1, 'Basic'], + [2, 'Extended'], + ], + }, + { + key: 'ALGO_REPORT_PERIOD', + label: 'Algo Report Period', + desc: 'Sensor-hub report period code', + kind: 'bit', + index: OP_IDX.ALGO_REPORT_MODE_RATE, + shift: 2, + width: 6, + }, + { + key: 'ALGO_AEC_ENABLE', + label: 'Algo Auto Exposure Control (AEC)', + desc: 'Enable the WHRM/SpO2 automatic exposure control (AEC) loop for the optical PPG AFE. Not related to ECG.', + kind: 'bit', + index: OP_IDX.ALGO_CONTROL, + shift: 0, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'ALGO_SCD_ENABLE', + label: 'Algo Skin Contact Detect', + desc: 'Enable skin-contact detection', + kind: 'bit', + index: OP_IDX.ALGO_CONTROL, + shift: 1, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'ALGO_AUTO_PD_ENABLE', + label: 'Algo Auto PD Current', + desc: 'Enable automatic photodiode current control', + kind: 'bit', + index: OP_IDX.ALGO_CONTROL, + shift: 2, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'ALGO_INITIAL_HR', + label: 'Algo Initial HR', + desc: 'Optional WHRM initial heart-rate seed (bpm, 0 = none)', + kind: 'u8', + index: OP_IDX.ALGO_INITIAL_HR, + min: 0, + max: 255, + }, + { + key: 'LED_AUTO_BRIGHTNESS_ENABLE', + label: 'LED Auto-Brightness', + desc: 'Drive RGB LED brightness from ambient light', + kind: 'bit', + index: OP_IDX.LED_AUTO_BRIGHTNESS_CFG, + shift: 0, + width: 1, + options: [ + [0, 'Disabled'], + [1, 'Enabled'], + ], + }, + { + key: 'LED_MAX_BRIGHTNESS', + label: 'LED Max Brightness', + desc: 'Ceiling for auto-brightness mode (0-255)', + kind: 'u8', + index: OP_IDX.LED_MAX_BRIGHTNESS, + min: 0, + max: 255, + }, + { + key: 'LED_LUX_THRESHOLD', + label: 'LED Lux Threshold', + desc: 'Below this ambient level the LED stays at max brightness', + kind: 'u16', + index: OP_IDX.LED_LUX_THRESHOLD, + min: 0, + max: 65535, + }, + { + key: 'PERSON_HEIGHT_CM', + label: 'Height', + desc: 'Subject height for the MAX32674 algorithm suite (cm)', + kind: 'u16', + index: OP_IDX.PERSON_HEIGHT_CM, + min: 50, + max: 250, + }, + { + key: 'PERSON_WEIGHT_KG', + label: 'Weight', + desc: 'Subject weight for the MAX32674 algorithm suite (kg)', + kind: 'u16', + index: OP_IDX.PERSON_WEIGHT_KG, + min: 10, + max: 300, + }, + { + key: 'PERSON_AGE', + label: 'Age', + desc: 'Subject age for the MAX32674 algorithm suite (years)', + kind: 'u8', + index: OP_IDX.PERSON_AGE, + min: 0, + max: 120, + }, + { + key: 'PERSON_GENDER', + label: 'Gender', + desc: 'Subject gender for the MAX32674 algorithm suite', + kind: 'u8', + index: OP_IDX.PERSON_GENDER, + min: 0, + max: 1, + options: [ + [0, 'Male'], + [1, 'Female'], + ], + }, + ]; + const VERISENSE_OP_CONFIG_BYTE_SIZE = 92; + function createBlankVerisenseOperationalConfig(byteSize = VERISENSE_OP_CONFIG_BYTE_SIZE) { + const blank = new Uint8Array(byteSize); + blank[0] = 0x5a; + // Stamp the layout version so v9-sized configs are recognised as second-gen. + if (byteSize >= VERISENSE_OP_CONFIG_BYTE_SIZE) { + blank[OP_IDX.OP_CONFIG_VERSION] = OP_CONFIG_VERSION_V9; + // Seed the MAX32674 subject parameters with the Maxim algorithm defaults + // (height 175 cm, weight 78 kg, age 30 yr, gender Male) so the UI shows + // sane values rather than blanks. u16 fields are little-endian. + blank[OP_IDX.PERSON_HEIGHT_CM] = 175 & 0xff; + blank[OP_IDX.PERSON_HEIGHT_CM + 1] = (175 >> 8) & 0xff; + blank[OP_IDX.PERSON_WEIGHT_KG] = 78 & 0xff; + blank[OP_IDX.PERSON_WEIGHT_KG + 1] = (78 >> 8) & 0xff; + blank[OP_IDX.PERSON_AGE] = 30; + blank[OP_IDX.PERSON_GENDER] = 0; + } + return blank; + } + function clampInt(v, min, max) { + const n = Math.trunc(Number(v)); + if (!Number.isFinite(n)) + return min; + return Math.max(min, Math.min(max, n)); + } + function readVerisenseOperationalFieldValue(op, field) { + if (field.kind === 'bit') { + const width = field.width ?? 1; + const shift = field.shift ?? 0; + const mask = (1 << width) - 1; + return (op[field.index] >> shift) & mask; + } + if (field.kind === 'u8') + return op[field.index] & 0xff; + if (field.kind === 'u16') { + return (op[field.index] & 0xff) | ((op[field.index + 1] & 0xff) << 8); + } + if (field.kind === 'u32') { + return (((op[field.index] & 0xff) | + ((op[field.index + 1] & 0xff) << 8) | + ((op[field.index + 2] & 0xff) << 16) | + ((op[field.index + 3] & 0xff) << 24)) >>> + 0); + } + if (field.kind === 'inactiveResume') { + return op[field.index] & (0x01 << 6) ? 1 : 0; + } + if (field.kind === 'inactiveMinutes') { + return op[field.index] & 0x3f; + } + return 0; + } + function writeVerisenseOperationalFieldValue(op, field, rawValue) { + if (field.kind === 'bit') { + const width = field.width ?? 1; + const shift = field.shift ?? 0; + const mask = (1 << width) - 1; + const value = clampInt(rawValue, 0, mask); + op[field.index] = (op[field.index] & ~(mask << shift)) | ((value & mask) << shift); + return; + } + if (field.kind === 'u8') { + op[field.index] = clampInt(rawValue, field.min ?? 0, field.max ?? 255) & 0xff; + return; + } + if (field.kind === 'u16') { + const value = clampInt(rawValue, field.min ?? 0, field.max ?? 65535); + op[field.index] = value & 0xff; + op[field.index + 1] = (value >> 8) & 0xff; + return; + } + if (field.kind === 'u32') { + const value = clampInt(rawValue, field.min ?? 0, field.max ?? 4294967295) >>> 0; + op[field.index] = value & 0xff; + op[field.index + 1] = (value >> 8) & 0xff; + op[field.index + 2] = (value >> 16) & 0xff; + op[field.index + 3] = (value >> 24) & 0xff; + return; + } + if (field.kind === 'inactiveResume') { + const enabled = clampInt(rawValue, 0, 1) === 1; + op[field.index] = enabled ? op[field.index] | (0x01 << 6) : op[field.index] & -65; + return; + } + if (field.kind === 'inactiveMinutes') { + const minutes = clampInt(rawValue, field.min ?? 0, field.max ?? 63) & 0x3f; + op[field.index] = (op[field.index] & 0xc0) | minutes; + } + } + function setVerisenseOperationalBitRange(op, index, shift, width, rawValue) { + const mask = (1 << width) - 1; + const value = clampInt(rawValue, 0, mask); + op[index] = (op[index] & ~(mask << shift)) | ((value & mask) << shift); + } + /** GEN_CFG_0 bit masks for the two host comms channels (see byte map / firmware + * ASM_definitions.h). */ + const GEN_CFG_0_BLUETOOTH_EN_MASK = 1 << 4; + const GEN_CFG_0_USB_EN_MASK = 1 << 3; + /** + * Enforce the USB/Bluetooth comms-channel interlock on an operational-config + * buffer. + * + * A Verisense must never be configured with BOTH Bluetooth and USB disabled, or + * it becomes unreachable for reconfiguration (the radio is the only wireless way + * back in, and disabling USB removes the wired fallback). If a config has both + * `BLUETOOTH_EN` and `USB_EN` cleared, this forces BOTH back on. + * + * This mirrors the firmware safeguard (`enforceCommsChannelInterlock` in + * `ASM_Production/main.c`, applied on config write and parse). Enforcing it here + * in the SDK means any consuming application is protected — a device can't be + * stranded by a third-party tool writing 0/0. + * + * Mutates `op` in place. Returns `true` if a correction was applied. + */ + function enforceVerisenseCommsChannelInterlock(op) { + if (!op || op.length <= OP_IDX.GEN_CFG_0) + return false; + const genCfg0 = op[OP_IDX.GEN_CFG_0]; + const bothDisabled = (genCfg0 & GEN_CFG_0_BLUETOOTH_EN_MASK) === 0 && (genCfg0 & GEN_CFG_0_USB_EN_MASK) === 0; + if (!bothDisabled) + return false; + op[OP_IDX.GEN_CFG_0] = genCfg0 | GEN_CFG_0_BLUETOOTH_EN_MASK | GEN_CFG_0_USB_EN_MASK; + return true; + } + const VERISENSE_SENSOR_ENABLE_FIELDS = [ + { key: 'ACCEL_1_EN', index: OP_IDX.GEN_CFG_0, shift: 7 }, + { key: 'ACCEL_2_EN', index: OP_IDX.GEN_CFG_0, shift: 6 }, + { key: 'GYRO_EN', index: OP_IDX.GEN_CFG_0, shift: 5 }, + { key: 'MAG_EN', index: OP_IDX.GEN_CFG_3, shift: 2 }, + { key: 'GSR_EN', index: OP_IDX.GEN_CFG_1, shift: 7 }, + { key: 'PPG_GREEN_EN', index: OP_IDX.GEN_CFG_1, shift: 6 }, + { key: 'PPG_RED_EN', index: OP_IDX.GEN_CFG_1, shift: 5 }, + { key: 'PPG_IR_EN', index: OP_IDX.GEN_CFG_1, shift: 4 }, + { key: 'ECG_EN', index: OP_IDX.GEN_CFG_1, shift: 3 }, + { key: 'PPG_BLUE_EN', index: OP_IDX.GEN_CFG_1, shift: 2 }, + { key: 'VPROG_EN', index: OP_IDX.GEN_CFG_2, shift: 2 }, + { key: 'VBATT_EN', index: OP_IDX.GEN_CFG_2, shift: 1 }, + // v9 second-generation sensors. On 2nd-gen the raw PPG (id 4) is gated by the + // existing PPG channel enables above; ALGO_HUB_EN gates the algorithm (id 8). + { key: 'AMBIENT_LIGHT_EN', index: OP_IDX.GEN_CFG_3, shift: 3 }, + { key: 'SKIN_TEMP_EN', index: OP_IDX.GEN_CFG_3, shift: 4 }, + { key: 'ALGO_HUB_EN', index: OP_IDX.GEN_CFG_3, shift: 5 }, + ]; + const VERISENSE_OPERATIONAL_FIELD_GROUPS = [ + { + id: 'gen', + title: 'General / Sensors', + openByDefault: false, + keys: [ + 'BLUETOOTH_EN', + 'USB_EN', + 'DEVICE_EN', + 'RECORDING_EN', + 'DATA_COMPRESSION_MODE', + 'HR_PPG_CHANNEL', + 'STEP_COUNT_EN', + 'LOW_BATT_AUTO_STOP_DISABLED', + 'BATT_TYPE', + 'MAG_EN', + 'LED_MODE', + 'BLE_TX_POWER', + ], + }, + { + id: 'accel1', + title: 'Accel1', + openByDefault: false, + keys: [ + 'ODR', + 'MODE', + 'LP_MODE', + 'BW_FILT', + 'FS', + 'FDS', + 'LOW_NOISE', + 'HP_REF_MODE', + 'FMode', + 'FTH', + ], + }, + { + id: 'gyro_accel2', + title: 'Gyro / Accel2', + openByDefault: false, + keys: [ + 'FTH_LSB', + 'TIMER_PEDO_FIFDO_EN', + 'TIMER_PEDO_FIFO_DRDY', + 'FTH_MSB', + 'DEC_FIFO_GYRO', + 'DEC_FIFO_XL', + 'ODR_FIFO', + 'FIFO_MODE', + 'ODR_XL', + 'FS_XL', + 'BW_XL', + 'ODR_G', + 'FS_G', + 'FS_125', + 'G_HM_MODE', + 'HP_G_EN', + 'HPCF_G', + 'HP_G_RST', + 'ROUNDING_STATUS', + 'LPF2_XL_EN', + 'HPCF_XL', + 'HP_SLOPE_XL_EN', + 'LOW_PASS_ON_6D', + ], + }, + { + id: 'lsm6dsv', + title: 'Accel / Gyro / Mag', + openByDefault: false, + keys: ['LSM6DSV_ODR_XL', 'LSM6DSV_FS_XL', 'LSM6DSV_ODR_G', 'LSM6DSV_FS_G', 'LIS2MDL_ODR'], + }, + { + id: 'recording_window', + title: 'Recording Window', + openByDefault: false, + keys: ['START_TIME', 'END_TIME'], + }, + { + id: 'inactivity', + title: 'Inactivity', + openByDefault: false, + keys: ['INACTIVE_TIMEOUT_MINUTES', 'RESUME_REC_ON_ACTIVITY'], + }, + { + id: 'ble_wake', + title: 'BLE Wake Schedule', + openByDefault: false, + keys: [ + 'PENDING_EVENTS_SCHEDULER_DISABLED', + 'BLE_CONNECTION_TRIES_PER_DAY', + 'ADAPTIVE_SCHEDULER_INTERVAL', + 'ADAPTIVE_SCHEDULER_FAILCOUNT_MAX', + 'BLE_DATA_TRANS_WKUP_INT_HOURS', + 'BLE_DATA_TRANS_WKUP_TIME', + 'BLE_DATA_TRANS_WKUP_DUR', + 'BLE_DATA_TRANS_RETRY_INT', + 'BLE_STATUS_WKUP_INT_HOURS', + 'BLE_STATUS_WKUP_TIME', + 'BLE_STATUS_WKUP_DUR', + 'BLE_STATUS_RETRY_INT', + 'BLE_RTC_SYNC_WKUP_INT_HOURS', + 'BLE_RTC_SYNC_WKUP_TIME', + 'BLE_RTC_SYNC_WKUP_DUR', + 'BLE_RTC_SYNC_RETRY_INT', + ], + // PENDING_EVENTS and BLE retry count stay ungrouped (rendered above the + // subpanels); the remaining fields cluster by purpose: data transfer, + // status, RTC sync, and the adaptive scheduler. + subgroups: [ + { + id: 'ble_data', + title: 'Data Transfer Schedule', + keys: [ + 'BLE_DATA_TRANS_WKUP_INT_HOURS', + 'BLE_DATA_TRANS_WKUP_TIME', + 'BLE_DATA_TRANS_WKUP_DUR', + 'BLE_DATA_TRANS_RETRY_INT', + ], + }, + { + id: 'ble_status', + title: 'Status Sync Schedule', + keys: [ + 'BLE_STATUS_WKUP_INT_HOURS', + 'BLE_STATUS_WKUP_TIME', + 'BLE_STATUS_WKUP_DUR', + 'BLE_STATUS_RETRY_INT', + ], + }, + { + id: 'ble_rtc_sync', + title: 'Time Sync Schedule', + keys: [ + 'BLE_RTC_SYNC_WKUP_INT_HOURS', + 'BLE_RTC_SYNC_WKUP_TIME', + 'BLE_RTC_SYNC_WKUP_DUR', + 'BLE_RTC_SYNC_RETRY_INT', + ], + }, + { + id: 'adaptive_scheduler', + title: 'Adaptive Scheduler (fallback)', + keys: ['ADAPTIVE_SCHEDULER_FAILCOUNT_MAX', 'ADAPTIVE_SCHEDULER_INTERVAL'], + }, + ], + }, + { + id: 'adc_gsr', + title: 'ADC / GSR', + openByDefault: false, + keys: ['ADC_SAMPLE_RATE', 'ADC_OVERSAMPLE_RATE', 'GSR_RANGE_SETTING'], + }, + { + id: 'ppg', + title: 'PPG', + openByDefault: false, + keys: [ + 'PPG_REC_DUR_SECS', + 'PPG_REC_INT_MINS', + 'SMP_AVE', + 'PPG_ADC_RGE', + 'PPG_SR', + 'PPG_LED_PW', + 'PPG_MA_DEFAULT', + 'PPG_MA_MAX_RED_IR', + 'PPG_MA_MAX_GREEN_BLUE', + 'PPG_AGC_TARGET_PERCENT_OF_RANGE', + 'PPG_UNUSED_BYTE', + 'PPG_MA_LED_PILOT', + 'XTALK_DAC1', + 'XTALK_DAC2', + 'XTALK_DAC3', + 'XTALK_DAC4', + 'PROX_AGC_MODE', + ], + }, + { + id: 'light', + title: 'Ambient Light', + openByDefault: false, + keys: [ + 'LIGHT_GAIN_INDEX', + 'LIGHT_EXPOSURE_INDEX', + 'LIGHT_DARK_ENABLE', + 'LIGHT_FLICKER_EN', + 'LIGHT_SAMPLE_RATE_INDEX', + ], + }, + { + id: 'skin_temp', + title: 'Skin Temperature', + openByDefault: false, + keys: ['SKIN_TEMP_MEAS_TYPE', 'SKIN_TEMP_SAMPLE_RATE'], + }, + { + id: 'algo', + title: 'Algorithm Hub', + openByDefault: false, + keys: [ + 'ALGO_OP_MODE', + 'ALGO_REPORT_MODE', + 'ALGO_REPORT_PERIOD', + 'ALGO_AEC_ENABLE', + 'ALGO_SCD_ENABLE', + 'ALGO_AUTO_PD_ENABLE', + 'ALGO_INITIAL_HR', + ], + }, + { + id: 'person', + title: 'Subject / Person Parameters', + openByDefault: false, + keys: ['PERSON_AGE', 'PERSON_HEIGHT_CM', 'PERSON_WEIGHT_KG', 'PERSON_GENDER'], + }, + { + id: 'led', + title: 'LED Auto-Brightness', + openByDefault: false, + keys: ['LED_AUTO_BRIGHTNESS_ENABLE', 'LED_MAX_BRIGHTNESS', 'LED_LUX_THRESHOLD'], + }, + ]; + const VERISENSE_OPERATIONAL_FIELD_FALLBACK_GROUP_ID = 'gen'; + /** + * Maps each hardware-gated operational-config group id to the sensor block that + * gates it (see {@link VerisenseHardwareSensorSupport}). Group ids absent from + * this map (e.g. `gen`, `ble_wake`) configure behaviour that applies to + * every board and are always considered supported. + */ + const VERISENSE_OPERATIONAL_FIELD_GROUP_SENSOR = { + accel1: 'accel1', + gyro_accel2: 'gyroAccel2', + lsm6dsv: 'imuGen2', + adc_gsr: 'gsr', + ppg: 'ppg', + light: 'ambientLight', + skin_temp: 'skinTemperature', + algo: 'algorithmHub', + person: 'algorithmHub', + led: 'ledAutoBrightness', + }; + /** + * Returns the set of operational-config group ids (from + * {@link VERISENSE_OPERATIONAL_FIELD_GROUPS}) whose underlying sensor is present + * on the given hardware revision. A group is supported when it is not gated by a + * sensor block, or when its gating sensor is present. + * + * Returns `null` when the hardware revision is unknown so callers can fall back + * to showing every group. + */ + function getVerisenseSupportedOperationalFieldGroupIds(source) { + const hw = getVerisenseHardwareRevision(source); + if (!hw) + return null; + const support = getVerisenseHardwareSensorSupport(hw.major, hw.minor); + const supported = new Set(); + for (const group of VERISENSE_OPERATIONAL_FIELD_GROUPS) { + const sensorKey = VERISENSE_OPERATIONAL_FIELD_GROUP_SENSOR[group.id]; + if (!sensorKey || support[sensorKey]) + supported.add(group.id); + } + return supported; + } + /** LIGHT_CONFIG bit 1 is the VD6283 dark-channel select: when set, the shared + * visible/clear slot carries the dark (covered-photodiode) baseline instead of + * the visible reading. Returns false for empty/nullish config. */ + function isVerisenseLightDarkChannelEnabled(op) { + if (!op?.length) + return false; + return ((op[OP_IDX.LIGHT_CONFIG] ?? 0) & (1 << 1)) !== 0; + } + /** + * Pad an operational config authored at a legacy/shorter length onto a blank + * full-size (v9, {@link VERISENSE_OP_CONFIG_BYTE_SIZE}-byte) image so the + * working config is always canonical size — otherwise trailing v9 fields + * (e.g. the person-parameter bytes) would be absent. Configs already at or + * beyond full size are returned as-is. + */ + function padVerisenseOperationalConfig(bytes) { + const src = bytes instanceof Uint8Array ? bytes : new Uint8Array(Array.from(bytes)); + if (src.length >= VERISENSE_OP_CONFIG_BYTE_SIZE) + return src; + const full = createBlankVerisenseOperationalConfig(VERISENSE_OP_CONFIG_BYTE_SIZE); + full.set(src); + return full; + } + /** + * Firmware default rate/mode codes per sensor group, for config editors that + * auto-seed a rate when a sensor is first enabled and power it down when all + * of its enables are cleared. Editors should only seed the `on` default when + * the field currently holds the `off` (power-down) code, so a user-chosen + * rate is never clobbered. Sensors whose rate field has no power-down value + * (magnetometer LIS2MDL_ODR, PPG_SR) are omitted — their enable bit / channel + * toggles are the on/off control. Default ODR codes mirror the standard + * customer template (Accel1 = 50 Hz, ADC = 128 Hz). + */ + const VERISENSE_SENSOR_RATE_DEFAULT_GROUPS = [ + { enableKeys: ['ACCEL_1_EN'], fields: [{ key: 'ODR', on: 4, off: 0 }] }, + { + enableKeys: ['ACCEL_2_EN'], + fields: [{ keyByGen: { dsv: 'LSM6DSV_ODR_XL', ds3: 'ODR_XL' }, on: 3, off: 0 }], + }, + { + enableKeys: ['GYRO_EN'], + fields: [{ keyByGen: { dsv: 'LSM6DSV_ODR_G', ds3: 'ODR_G' }, on: 3, off: 0 }], + }, + { + enableKeys: ['GSR_EN', 'VBATT_EN', 'VPROG_EN'], + fields: [{ key: 'ADC_SAMPLE_RATE', on: 19, off: 0 }], + }, + { + enableKeys: ['AMBIENT_LIGHT_EN'], + fields: [{ key: 'LIGHT_SAMPLE_RATE_INDEX', on: 2, off: 0 }], + }, + { + enableKeys: ['SKIN_TEMP_EN'], + fields: [{ key: 'SKIN_TEMP_SAMPLE_RATE', on: 5, off: 0 }], + }, + { enableKeys: ['ALGO_HUB_EN'], fields: [{ key: 'ALGO_OP_MODE', on: 1, off: 0 }] }, + ]; + /** Resolve a rate-default field to its concrete schema key for the given IMU + * generation, or null when the field has no key for that generation. */ + function resolveVerisenseSensorRateFieldKey(field, generation) { + return field.key ?? field.keyByGen?.[generation] ?? null; + } + /** + * The three firmware sync schedules (data transfer, status, RTC sync), each + * with wake-interval-hours / wake-time / active-duration / retry-interval + * fields. Interval semantics (from firmware `hal_rtc.c`): 0 = off, 24 = once + * daily at the wake time, 1-23 = every N hours. Wake time is + * minutes-since-midnight (device local time), duration is minutes 0-255, + * retry interval is minutes 0-1439. The number of connection attempts per + * window is the separate global `BLE_CONNECTION_TRIES_PER_DAY` field. + */ + const VERISENSE_BLE_SYNC_SCHEDULES = [ + { + id: 'data', + subgroupId: 'ble_data', + intervalKey: 'BLE_DATA_TRANS_WKUP_INT_HOURS', + timeKey: 'BLE_DATA_TRANS_WKUP_TIME', + durKey: 'BLE_DATA_TRANS_WKUP_DUR', + retryKey: 'BLE_DATA_TRANS_RETRY_INT', + }, + { + id: 'status', + subgroupId: 'ble_status', + intervalKey: 'BLE_STATUS_WKUP_INT_HOURS', + timeKey: 'BLE_STATUS_WKUP_TIME', + durKey: 'BLE_STATUS_WKUP_DUR', + retryKey: 'BLE_STATUS_RETRY_INT', + }, + { + id: 'rtcSync', + subgroupId: 'ble_rtc_sync', + intervalKey: 'BLE_RTC_SYNC_WKUP_INT_HOURS', + timeKey: 'BLE_RTC_SYNC_WKUP_TIME', + durKey: 'BLE_RTC_SYNC_WKUP_DUR', + retryKey: 'BLE_RTC_SYNC_RETRY_INT', + }, + ]; + /** Value ranges for the BLE sync-schedule fields (clamp editor input to + * these before writing). */ + const VERISENSE_BLE_SCHEDULE_RANGES = Object.freeze({ + intervalHours: Object.freeze({ min: 0, max: 24 }), + timeMins: Object.freeze({ min: 0, max: 1439 }), + durMin: Object.freeze({ min: 0, max: 255 }), + retryIntMin: Object.freeze({ min: 0, max: 1439 }), + }); + /** + * Canonical schedule defaults: 01:00 daily, 10-minute window, 15-minute + * retry, 5 connection attempts per wake. Also the "reset" values applied + * when the pending-events scheduler is disabled, so a disabled config lands + * in a clean known state. + */ + const VERISENSE_BLE_SCHEDULE_DEFAULTS = Object.freeze({ + intervalHours: 24, + timeMins: 60, + durMin: 10, + retryIntMin: 15, + connectionTries: 5, + }); + /** Format minutes-since-midnight as `"HH:MM"`, or null when out of range. + * Fractional input is rounded to the nearest whole minute first, so the + * minutes component always stays in 0–59. */ + function minutesSinceMidnightToHHMM(mins) { + if (mins == null) + return null; + const v = Math.round(Number(mins)); + if (!Number.isFinite(v) || v < 0 || v > 1439) + return null; + const h = Math.floor(v / 60); + const m = v % 60; + return `${String(h).padStart(2, '0')}:${String(m).padStart(2, '0')}`; + } + /** Parse `"HH:MM"` (or `"H:MM"`) into minutes-since-midnight, or null when + * malformed / out of range. */ + function hhmmToMinutesSinceMidnight(text) { + const m = /^(\d{1,2}):(\d{2})$/.exec(String(text ?? '').trim()); + if (!m) + return null; + const h = Number(m[1]); + const mm = Number(m[2]); + if (h < 0 || h > 23 || mm < 0 || mm > 59) + return null; + return h * 60 + mm; + } + /** + * The stream-packet sensor IDs a device will emit for a given set of sensor + * enables (see `VERISENSE_STREAM_SENSOR_LABELS` for the ID meanings). The + * IMU block splits by hardware generation: first-gen streams accel2+gyro as + * ID 3 (LSM6DS3); second-gen streams accel2+gyro+mag as ID 6 (LSM6DSV + + * LIS2MDL). Any enabled PPG channel produces the single PPG stream (ID 4). + */ + function expectedVerisenseStreamSensorIds(enables, opts) { + const ids = new Set(); + if (enables.gsr || enables.vbatt || enables.vprog) + ids.add(1); + if (enables.accel1) + ids.add(2); + if (enables.accel2 || enables.gyro || enables.mag) + ids.add(opts.secondGeneration ? 6 : 3); + if (enables.ppg) + ids.add(4); + if (enables.ambientLight) + ids.add(7); + if (enables.algoHub) + ids.add(8); + if (enables.skinTemp) + ids.add(9); + return ids; + } + const STREAM_ENABLE_BY_FIELD_KEY = { + ACCEL_1_EN: 'accel1', + ACCEL_2_EN: 'accel2', + GYRO_EN: 'gyro', + MAG_EN: 'mag', + GSR_EN: 'gsr', + PPG_GREEN_EN: 'ppg', + PPG_RED_EN: 'ppg', + PPG_IR_EN: 'ppg', + PPG_BLUE_EN: 'ppg', + VPROG_EN: 'vprog', + VBATT_EN: 'vbatt', + AMBIENT_LIGHT_EN: 'ambientLight', + SKIN_TEMP_EN: 'skinTemp', + ALGO_HUB_EN: 'algoHub', + }; + /** {@link expectedVerisenseStreamSensorIds} computed straight from op-config + * bytes via the sensor-enable bit schema. */ + function expectedVerisenseStreamSensorIdsFromConfig(op, opts) { + const enables = {}; + if (op?.length) { + for (const f of VERISENSE_SENSOR_ENABLE_FIELDS) { + const enableKey = STREAM_ENABLE_BY_FIELD_KEY[f.key]; + if (!enableKey) + continue; + if ((((op[f.index] ?? 0) >> f.shift) & 0x01) === 1) + enables[enableKey] = true; + } + } + return expectedVerisenseStreamSensorIds(enables, opts); + } + + /** + * Abstract base class for all Verisense sensor decoders. + * + * Provides: + * - Timestamp unwrapping (handles the 1-minute rollover at 32768 ticks/s). + * - System-time offset tracking for plotting calibrated wall-clock timestamps. + * - Per-sample time extrapolation based on sampling rate and last-sample tick. + */ + class SensorBase { + constructor() { + this.lastTicksUnwrapped = 0; + this.cycle = 0; + /** (system time) − (shimmer time) at first sample, in milliseconds. */ + this.systemOffsetFirstTime = null; + /** Sampling rate in Hz (used for per-sample time extrapolation). */ + this.samplingRateHz = null; + /** Whether this sensor is enabled in the operational config. */ + this.enabled = true; + /** + * Per-device calibration read from the sensor, or null when none is available + * (decoders then fall back to nominal full-scale/datasheet scaling). Set via + * {@link applyCalibration}; subclasses read it in their calibrate routines. + */ + this.calibration = null; + } + /** Supply (or clear) the device calibration set used by this decoder. */ + applyCalibration(set) { + this.calibration = set; + } + /** Reset all timestamp state (call on (re)connect or when streaming restarts). */ + resetTimestamps() { + this.lastTicksUnwrapped = 0; + this.cycle = 0; + this.systemOffsetFirstTime = null; + } + /** + * Unwrap a rolling 24-bit tick counter to a monotonically increasing value. + */ + unwrapTicks(ticks) { + let unwrapped = ticks + SensorBase.TICKS_MAX_VALUE * this.cycle; + if (this.lastTicksUnwrapped > unwrapped) { + this.cycle += 1; + unwrapped = ticks + SensorBase.TICKS_MAX_VALUE * this.cycle; + } + this.lastTicksUnwrapped = unwrapped; + return unwrapped; + } + /** Convert unwrapped ticks to milliseconds. */ + ticksToMillis(unwrappedTicks) { + return (unwrappedTicks / SensorBase.CLOCK_FREQ) * 1000.0; + } + /** + * Compute the calibrated shimmer timestamp for the *last* sample in a burst, + * and store the first-seen system-offset for later plotting. + * + * @param lastSampleTicksU24 24-bit tick counter from the packet header. + * @param systemMillis `Date.now()` at the time of packet receipt. + */ + getTimestampUnwrappedMillis(lastSampleTicksU24, systemMillis) { + const unwrappedTicks = this.unwrapTicks(lastSampleTicksU24); + const shimmerMillis = this.ticksToMillis(unwrappedTicks); + if (this.systemOffsetFirstTime == null) { + this.systemOffsetFirstTime = systemMillis - shimmerMillis; + } + return { shimmerMillis, systemOffsetFirstTime: this.systemOffsetFirstTime }; + } + /** + * Extrapolate the timestamp for sample `i` of `numSamples` in a burst, + * given the timestamp of the *last* sample and the sampling rate. + * + * @returns Object with `tsMillis`, `systemTsMillis`, and `systemTsPlotMillis`. + */ + extrapolateSampleTimes(opts) { + const sr = opts.samplingRateHz ?? this.samplingRateHz; + const { tsLastSampleMillis, systemTsLastSampleMillis, systemOffsetFirstTime } = opts; + if (!sr || sr <= 0) { + return { + tsMillis: tsLastSampleMillis, + systemTsMillis: systemTsLastSampleMillis, + systemTsPlotMillis: systemOffsetFirstTime != null + ? tsLastSampleMillis + systemOffsetFirstTime + : systemTsLastSampleMillis, + }; + } + const sampleOffsetSec = (opts.numSamples - opts.i - 1) / sr; + const tsMillis = tsLastSampleMillis - sampleOffsetSec * 1000; + const systemTsMillis = systemTsLastSampleMillis - sampleOffsetSec * 1000; + const systemTsPlotMillis = systemOffsetFirstTime != null ? tsMillis + systemOffsetFirstTime : systemTsMillis; + return { tsMillis, systemTsMillis, systemTsPlotMillis }; + } + /** + * Compute per-sample timestamps for a whole decoded burst. + * + * The base implementation treats every decoded sample as one evenly-spaced + * time step at `samplingRateHz` (correct when each decoded sample is a single + * combined time step). Sensors whose decoded array *interleaves* multiple + * streams at different cadences (e.g. the LSM6DSV tagged FIFO, which mixes + * accel / gyro / mag entries) override this to timestamp each stream on its + * own rate — otherwise the shared rate spreads each stream's samples too far + * back and consecutive blocks overlap on the time axis. + */ + computeSampleTimestamps(decodedSamples, block) { + const num = decodedSamples.length; + const out = new Array(num); + for (let i = 0; i < num; i++) { + out[i] = this.extrapolateSampleTimes({ + numSamples: num, + i, + samplingRateHz: this.samplingRateHz, + tsLastSampleMillis: block.tsLastSampleMillis, + systemTsLastSampleMillis: block.systemTsLastSampleMillis, + systemOffsetFirstTime: block.systemOffsetFirstTime, + }); + } + return out; + } + /** + * Turn a decoded + timestamped burst into one or more stream contributions + * for live throughput / packet-loss tracking. The default treats the sensor + * as a single stream; sensors whose decoded array interleaves several + * sub-streams at different cadences (e.g. the LSM6DSV tagged FIFO) override + * this to report one contribution per sub-stream so loss is tracked + * independently. + */ + getStreamContributions(samplesWithTime, sensorId) { + let first = null; + let last = null; + for (const s of samplesWithTime) { + const t = s?.timestamps?.tsMillis; + if (typeof t !== 'number') + continue; + if (first == null || t < first) + first = t; + if (last == null || t > last) + last = t; + } + return [ + { + key: String(sensorId), + label: `Sensor ${sensorId}`, + samplingRateHz: this.samplingRateHz, + sampleCount: samplesWithTime.length, + firstSampleMillis: first, + lastSampleMillis: last, + }, + ]; + } + } + /** Verisense clock frequency in ticks per second. */ + SensorBase.CLOCK_FREQ = 32768; + /** 1-minute rollover at 32768 ticks/s (matches C# Sensor.cs). */ + SensorBase.TICKS_MAX_VALUE = 60 * 32768; + + /** + * Decoder for grouped ADC channels (Verisense sensor id = 1). + * + * Includes GSR plus battery/ADC channels carried in the same packet source. + * Implements C# `SensorGSR.cs` including: + * - Per-hardware reference resistor selection (SR68 vs Shimmer3 resistors). + * - Auto-range decoding from the raw ADC value's upper bits. + * - Range-3 clamping threshold that differs by hardware. + * - Conductance (uS) output with connectivity detection. + */ + class SensorADC extends SensorBase { + constructor() { + super(); + this.LIMIT_MIN_VALID_USIEMENS = 0.03; + this.GSR_UNCAL_LIMIT_RANGE3_SR68 = 1134; + this.GSR_UNCAL_LIMIT_RANGE3_SR62 = 683; + this.SHIMMER3_REF_KOHMS = [40.2, 287.0, 1000.0, 3300.0]; + this.SR68_REF_KOHMS = [21.0, 150.0, 562.0, 1740.0]; + this.gsrEnabled = true; + this.battEnabled = false; + /** GSR range 0-3 (fixed) or 4 (auto-range). */ + this.gsrRangeSetting = 4; + this.hardwareIdentifier = 'VERISENSE_PULSE_PLUS'; + this.hwRevisionMajor = null; + this.hwRevisionMinor = null; + this.hwRevisionInternal = null; + // Decoded from opConfig for debug/display + this.gsrRateSettingRaw = 0; + this.gsrRangeSettingRaw = 0; + this.gsrOversamplingRateSettingRaw = 0; + this.samplingRateHz = 50; + } + setHardwareIdentifier(idStr) { + this.hardwareIdentifier = idStr; + } + setHardwareRevision(revHwMajor, revHwMinor, revHwInternal = 0) { + this.hwRevisionMajor = Number.isFinite(revHwMajor) ? Math.trunc(revHwMajor) : null; + this.hwRevisionMinor = Number.isFinite(revHwMinor) ? Math.trunc(revHwMinor) : null; + this.hwRevisionInternal = Number.isFinite(revHwInternal) ? Math.trunc(revHwInternal) : null; + } + setGsrRangeSetting(v) { + this.gsrRangeSetting = v; + } + getBatteryVoltageMultiplier() { + if (this.hwRevisionMajor != null && this.hwRevisionMinor != null) { + return getVerisenseStreamingBatteryVoltageMultiplier(this.hwRevisionMajor, this.hwRevisionMinor); + } + // Backward-compatible fallback when production config revision is unavailable. + if (this.hardwareIdentifier === 'VERISENSE_GSR_PLUS') + return 2.0; + return 1.0; + } + /** + * Whether this board uses the SR62 (Verisense GSR+) Shimmer3-style analog + * front end: 3.0 V SAADC reference, 40.2/287/1000/3300 kΩ GSR feedback + * resistors, 0.5 V GSR reference and range-3 uncal limit 683. Every other + * GSR-capable board (SR61 >= 5, SR68 >= 5 — firmware + * `ShimBrd_isGsrSupportedForHwVersion`) carries the second-generation DC + * front end: 1.8 V reference, 21/150/562/1740 kΩ, 0.4986 V, limit 1134. + * + * Mirrors the firmware's `selectFeedbackResistorsFromHwVersion` (hal_gsr.c), + * which keys the choice on the major revision alone (SR62 vs everything + * else). Prefers the production-config hardware revision; falls back to the + * caller-supplied hardware identifier when no revision has been read yet. + * Previously this was keyed only on the `VERISENSE_PULSE_PLUS` identifier + * string, so an SR61-5/6 presenting its true identity decoded ~1.91× high + * (DEV-874). + */ + usesSr62GsrFrontEnd() { + if (this.hwRevisionMajor != null) { + return this.hwRevisionMajor === 62; + } + return this.hardwareIdentifier === 'VERISENSE_GSR_PLUS'; + } + setEnabled(arg1, opConfigBytes) { + if (opConfigBytes != null) { + const desired = typeof arg1 === 'boolean' ? { gsr: arg1 } : arg1 && typeof arg1 === 'object' ? arg1 : {}; + return this._patchEnabled(desired, opConfigBytes); + } + const obj = typeof arg1 === 'boolean' ? { gsr: arg1 } : arg1 && typeof arg1 === 'object' ? arg1 : {}; + if (typeof obj.gsr === 'boolean') + this.gsrEnabled = obj.gsr; + if (typeof obj.batt === 'boolean') + this.battEnabled = obj.batt; + return { gsr: this.gsrEnabled, batt: this.battEnabled }; + } + _patchEnabled({ gsr, batt }, opConfigBytes) { + const op = normalizeOperationalConfig(opConfigBytes); + const out = new Uint8Array(op); + if (typeof gsr === 'boolean') { + const idx = OP_IDX.GEN_CFG_1; + out[idx] = gsr ? (out[idx] | 0x80) & 0xff : out[idx] & 0x7f & 0xff; + } + if (typeof batt === 'boolean') { + const idx = OP_IDX.GEN_CFG_2; + out[idx] = batt ? (out[idx] | 0x02) & 0xff : out[idx] & 0xfd & 0xff; + } + return out; + } + patchGsrRange(rangeCfg, op) { + const out = new Uint8Array(op); + const i = OP_IDX.ADC_CHANNEL_SETTINGS_1; + out[i] = (out[i] & 0b11111000) | (rangeCfg & 0x07); + return out; + } + patchGsrSamplingRate(rateCfg, op) { + const out = new Uint8Array(op); + const i = OP_IDX.ADC_CHANNEL_SETTINGS_0; + out[i] = (out[i] & 0b11000000) | (rateCfg & 0x3f); + return out; + } + patchGsrOversampling(overCfg, op) { + const out = new Uint8Array(op); + const i = OP_IDX.ADC_CHANNEL_SETTINGS_1; + out[i] = (out[i] & 0b00001111) | ((overCfg & 0x0f) << 4); + return out; + } + calibrateAdcToVolts(uncal12bit) { + const adcRange = 2 ** 12 - 1; + let refVoltage = 1.8 / 4.0; + if (this.usesSr62GsrFrontEnd()) { + refVoltage = 3.0 / 4.0; + } + const adcScaling = 1.0 / 4.0; + return (uncal12bit * refVoltage) / adcRange / adcScaling; + } + calibrateGsrToKOhmsUsingAmplifierEq(volts, range) { + let rFeedback = this.SR68_REF_KOHMS[range]; + let gsrRefVoltage = 0.4986; + if (this.usesSr62GsrFrontEnd()) { + rFeedback = this.SHIMMER3_REF_KOHMS[range]; + gsrRefVoltage = 0.5; + } + return rFeedback / (volts / gsrRefVoltage - 1.0); + } + nudgeGsrResistance(kOhms) { + const limitsByRange = { + 0: [8.0, 63.0], + 1: [63.0, 220.0], + 2: [220.0, 680.0], + 3: [680.0, 4700.0], + 4: [8.0, 4700.0], + }; + const lim = limitsByRange[this.gsrRangeSetting] ?? [8.0, 4700.0]; + return Math.min(Math.max(kOhms, lim[0]), lim[1]); + } + kOhmToUSiemens(kOhms) { + return 1000.0 / kOhms; + } + /** + * Convert the 6-bit ADC sample-rate code to the streamed output rate in Hz, + * or null for "Off"/unknown codes. Used for per-sample timestamp spacing. + */ + decodeAdcSampleRateHz(rateCode) { + const divisor = SensorADC.ADC_RATE_DIVISORS[rateCode]; + if (!divisor) + return null; + return SensorBase.CLOCK_FREQ / divisor; + } + parsePayload(sensorPayloadBytes) { + const bytesPerSample = this.gsrEnabled && this.battEnabled ? 4 : 2; + const n = Math.floor(sensorPayloadBytes.length / bytesPerSample); + const out = []; + for (let i = 0; i < n; i++) { + const base = i * bytesPerSample; + let batt = null; + let gsr = null; + const gsrStart = this.battEnabled && this.gsrEnabled ? 2 : 0; + if (this.gsrEnabled) { + const gsrraw = i16le(sensorPayloadBytes, base + gsrStart); + let adc12 = gsrraw & 0x0fff; + let currentRange = this.gsrRangeSetting; + if (currentRange === 4) + currentRange = (gsrraw >> 14) & 0x03; + if (currentRange === 3) { + const limit = this.usesSr62GsrFrontEnd() + ? this.GSR_UNCAL_LIMIT_RANGE3_SR62 + : this.GSR_UNCAL_LIMIT_RANGE3_SR68; + if (adc12 < limit) + adc12 = limit; + } + const volts = this.calibrateAdcToVolts(adc12); + let kOhms = this.calibrateGsrToKOhmsUsingAmplifierEq(volts, currentRange); + kOhms = this.nudgeGsrResistance(kOhms); + const uS = this.kOhmToUSiemens(kOhms); + const connectivity = uS > this.LIMIT_MIN_VALID_USIEMENS ? 'Connected' : 'Disconnected'; + gsr = { raw: gsrraw, adc12, range: currentRange, volts, kOhms, uS, connectivity }; + } + if (this.battEnabled) { + const raw16 = i16le(sensorPayloadBytes, base) & 0xffff; + const adc12 = raw16 & 0x0fff; + const usbPluggedIn = ((raw16 >> 15) & 0x01) === 1; + const chargerStatusBits = (raw16 >> 13) & 0x03; + let mv = this.calibrateAdcToVolts(adc12) * 1000.0; + mv *= this.getBatteryVoltageMultiplier(); + const chargerStatusMap = { + 0: 'Power-Down/Suspended', + 1: 'Charging', + 2: 'Charging Complete', + 3: 'Bad Battery/LDO', + }; + batt = { + raw16, + adc12, + mV: mv, + usbPluggedIn, + chargerStatusBits, + chargerStatus: chargerStatusMap[chargerStatusBits] ?? 'Unknown', + }; + } + out.push({ gsr, batt }); + } + return out; + } + applyOperationalConfig(op) { + const gen1 = op[OP_IDX.GEN_CFG_1] ?? 0; + const gen2 = op[OP_IDX.GEN_CFG_2] ?? 0; + this.gsrEnabled = ((gen1 >> 7) & 0x01) === 1; + this.battEnabled = (gen2 & 0b00000010) !== 0; + const rateCfg = (op[OP_IDX.ADC_CHANNEL_SETTINGS_0] ?? 0) & 0x3f; + const cfg1 = (op[OP_IDX.ADC_CHANNEL_SETTINGS_1] ?? 0) & 0xff; + const rangeCfg = cfg1 & 0x07; + const oversamplingCfg = (cfg1 >> 4) & 0x0f; + this.gsrRateSettingRaw = rateCfg; + this.gsrRangeSettingRaw = rangeCfg; + this.gsrOversamplingRateSettingRaw = oversamplingCfg; + // Drive per-sample timestamp spacing from the configured ADC rate. Without + // this, samplingRateHz stays at the constructor default (50 Hz); when the + // real rate differs, computeSampleTimestamps mis-spaces samples and + // consecutive blocks overlap on the time axis (the GSR "zigzag"). + const rateHz = this.decodeAdcSampleRateHz(rateCfg); + if (rateHz) + this.samplingRateHz = rateHz; + if (rangeCfg >= 0 && rangeCfg <= 4) { + this.gsrRangeSetting = rangeCfg; + } + } + } + /** + * ADC sample-rate code → divisor of the 32768 Hz clock. Mirrors the firmware + * `samplingRateInTicksArray` (hal_adc.c): the sampling timer fires every + * `divisor` ticks, producing one sample set per fire, so the streamed output + * rate = 32768 / divisor. Oversampling uses SAADC burst mode and therefore + * does NOT divide the output rate. Index 0 = "Off". + */ + SensorADC.ADC_RATE_DIVISORS = [ + 0, 1, 2, 4, 5, 8, 10, 16, 20, 25, 32, 40, 50, 64, 80, 100, 128, 160, 200, 256, 320, 400, 512, + 640, 800, 1024, 1280, 1600, 2048, 2560, 3200, 4096, 5120, 6400, 8192, 10240, 12800, 16384, + 20480, 25600, 32768, 40960, 51200, + ]; + + /** + * Decoder for the LIS2DW12 low-power accelerometer (Verisense sensor id = 2). + * + * Sensitivity values are given in raw-LSB / (m/s²) per axis — matching + * the C# `SensorLIS2DW12.cs` implementation. + */ + class SensorLIS2DW12 extends SensorBase { + constructor() { + super(); + this.offset = [0, 0, 0]; + this.align = [ + [0, 0, 1], + [1, 0, 0], + [0, 1, 0], + ]; + this.sensitivityByRange = { + '2G': [1671.665922915, 1671.665922915, 1671.665922915], + '4G': [835.832961457, 835.832961457, 835.832961457], + '8G': [417.916480729, 417.916480729, 417.916480729], + '16G': [208.958240364, 208.958240364, 208.958240364], + }; + this.range = '2G'; + /** Numeric full-scale index (0=2G..3=16G) used to select the device calibration block. */ + this.rangeIndex = 0; + this.samplingRateHz = 50; + } + setRange(rangeStr) { + if (this.sensitivityByRange[rangeStr]) + this.range = rangeStr; + } + // --- Functional OpConfig helpers (returns new Uint8Array, does not mutate) --- + setEnabled(enabled, opConfigBytes) { + if (opConfigBytes == null) { + this.enabled = enabled; + return this.enabled; + } + const op = normalizeOperationalConfig(opConfigBytes); + const out = new Uint8Array(op); + const idx = OP_IDX.GEN_CFG_0; + out[idx] = enabled ? (out[idx] | 0x80) & 0xff : out[idx] & 0x7f & 0xff; + return out; + } + setAccelEnabled(enabled, opConfigBytes) { + return this.setEnabled(enabled, opConfigBytes); + } + patchAccelRange(rangeCfg, op) { + const out = new Uint8Array(op); + const i = OP_IDX.ACCEL1_CFG_1; + out[i] = (out[i] & 0b11001111) | ((rangeCfg & 0x03) << 4); + return out; + } + patchAccelSamplingRate(rateCfg, op) { + const out = new Uint8Array(op); + const i = OP_IDX.ACCEL1_CFG_0; + out[i] = (out[i] & 0b00001111) | ((rateCfg & 0x0f) << 4); + return out; + } + _calibrate(raw) { + // Prefer per-device calibration from the sensor when available for this range. + const dev = this.calibration?.getImu(CalibSensorId.LIS2DW12_ACCEL, this.rangeIndex); + if (dev) + return applyImuCalibration(raw, dev); + // Fallback: nominal offset / alignment / datasheet sensitivity. + const v = [ + raw[0] - this.offset[0], + raw[1] - this.offset[1], + raw[2] - this.offset[2], + ]; + const a = this.align; + const aligned = [ + a[0][0] * v[0] + a[0][1] * v[1] + a[0][2] * v[2], + a[1][0] * v[0] + a[1][1] * v[1] + a[1][2] * v[2], + a[2][0] * v[0] + a[2][1] * v[1] + a[2][2] * v[2], + ]; + const s = this.sensitivityByRange[this.range]; + return [aligned[0] / s[0], aligned[1] / s[1], aligned[2] / s[2]]; + } + parsePayload(sensorPayloadBytes) { + const BYTES_PER_SAMPLE = 6; + const n = Math.floor(sensorPayloadBytes.length / BYTES_PER_SAMPLE); + const out = []; + for (let i = 0; i < n; i++) { + const off = i * BYTES_PER_SAMPLE; + const raw = [ + i16le(sensorPayloadBytes, off + 0), + i16le(sensorPayloadBytes, off + 2), + i16le(sensorPayloadBytes, off + 4), + ]; + const cal = this._calibrate(raw); + out.push({ raw, cal, units: { cal: 'm/s^2' } }); + } + return out; + } + applyOperationalConfig(op) { + const gen0 = op[OP_IDX.GEN_CFG_0]; + const cfg0 = op[OP_IDX.ACCEL1_CFG_0]; + const cfg1 = op[OP_IDX.ACCEL1_CFG_1]; + if (gen0 == null || cfg0 == null || cfg1 == null) { + console.warn('[LIS2DW12] Missing required bytes; cannot apply config.'); + return; + } + this.enabled = ((gen0 >> 7) & 0x01) === 1; + const rangeSetting = (cfg1 >> 4) & 0x03; + const modeSetting = (cfg0 >> 2) & 0x03; + const rateSetting = (cfg0 >> 4) & 0x0f; + const rangeMap = { 0: '2G', 1: '4G', 2: '8G', 3: '16G' }; + this.setRange(rangeMap[rangeSetting] ?? '2G'); + this.rangeIndex = rangeSetting & 0x03; + const lowPowerHzByCfg = { + 1: 1.6, + 2: 12.5, + 3: 25, + 4: 50, + 5: 100, + 6: 200, + }; + const highPerfHzByCfg = { + 1: 12.5, + 3: 25, + 4: 50, + 5: 100, + 6: 200, + 7: 400, + 8: 800, + 9: 1600, + }; + const isLowPower = modeSetting === 0; + const hz = isLowPower ? lowPowerHzByCfg[rateSetting] : highPerfHzByCfg[rateSetting]; + if (hz) + this.samplingRateHz = hz; + } + } + + /** + * Decoder for the LSM6DS3 combined accelerometer + gyroscope (Verisense sensor id = 3). + * + * Sensitivity values mirror the C# `SensorLSM6DS3.cs` implementation. + */ + class SensorLSM6DS3 extends SensorBase { + constructor() { + super(); + this.offset = [0, 0, 0]; + // Applied directly as `physical = align · (raw − offset)` (no inversion), so this + // must be the *inverse* alignment R⁻¹ = Rᵀ — matching the Shimmer Java reference + // `UtilCalibration` (C = R⁻¹·K⁻¹·(U−B)) and the gen-1 calibration doc's R, which + // is the forward §8 rotation. (Previously stored the un-transposed R, which + // applied R instead of R⁻¹.) + this.align = [ + [0, -1, 0], + [0, 0, -1], + [1, 0, 0], + ]; + this.accSensByRange = { + '2G': [1671.665922915, 1671.665922915, 1671.665922915], + '4G': [835.832961457, 835.832961457, 835.832961457], + '8G': [417.916480729, 417.916480729, 417.916480729], + '16G': [208.958240364, 208.958240364, 208.958240364], + }; + this.gyroSensByRange = { + '250DPS': [114.285714286, 114.285714286, 114.285714286], + '500DPS': [57.142857143, 57.142857143, 57.142857143], + '1000DPS': [28.571428571, 28.571428571, 28.571428571], + '2000DPS': [14.285714286, 14.285714286, 14.285714286], + }; + this.accRange = '2G'; + this.gyroRange = '250DPS'; + this.accEnabled = true; + this.gyroEnabled = true; + this.samplingRateHz = 50; + } + setAccelEnabled(v) { + this.accEnabled = !!v; + } + setGyroEnabled(v) { + this.gyroEnabled = !!v; + } + setAccelRange(r) { + if (this.accSensByRange[r]) + this.accRange = r; + } + setGyroRange(r) { + if (this.gyroSensByRange[r]) + this.gyroRange = r; + } + _applyAlignAndOffset(raw3) { + const v = [ + raw3[0] - this.offset[0], + raw3[1] - this.offset[1], + raw3[2] - this.offset[2], + ]; + const a = this.align; + return [ + a[0][0] * v[0] + a[0][1] * v[1] + a[0][2] * v[2], + a[1][0] * v[0] + a[1][1] * v[1] + a[1][2] * v[2], + a[2][0] * v[0] + a[2][1] * v[1] + a[2][2] * v[2], + ]; + } + _calibrateAccel(raw) { + const dev = this.calibration?.getImu(CalibSensorId.LSM6DS3_ACCEL, SensorLSM6DS3.ACC_RANGE_CODE[this.accRange]); + if (dev) + return applyImuCalibration(raw, dev); + const aligned = this._applyAlignAndOffset(raw); + const s = this.accSensByRange[this.accRange]; + return [aligned[0] / s[0], aligned[1] / s[1], aligned[2] / s[2]]; + } + _calibrateGyro(raw) { + const dev = this.calibration?.getImu(CalibSensorId.LSM6DS3_GYRO, SensorLSM6DS3.GYRO_RANGE_CODE[this.gyroRange]); + if (dev) + return applyImuCalibration(raw, dev); + const aligned = this._applyAlignAndOffset(raw); + const s = this.gyroSensByRange[this.gyroRange]; + return [aligned[0] / s[0], aligned[1] / s[1], aligned[2] / s[2]]; + } + parsePayload(sensorPayloadBytes) { + let bytesPerSample = 6; + if (this.gyroEnabled && this.accEnabled) + bytesPerSample = 12; + const n = Math.floor(sensorPayloadBytes.length / bytesPerSample); + const out = []; + for (let i = 0; i < n; i++) { + const base = i * bytesPerSample; + let gyroRaw = null; + let accRaw = null; + if (this.gyroEnabled && this.accEnabled) { + gyroRaw = [ + i16le(sensorPayloadBytes, base + 0), + i16le(sensorPayloadBytes, base + 2), + i16le(sensorPayloadBytes, base + 4), + ]; + accRaw = [ + i16le(sensorPayloadBytes, base + 6), + i16le(sensorPayloadBytes, base + 8), + i16le(sensorPayloadBytes, base + 10), + ]; + } + else if (this.gyroEnabled) { + gyroRaw = [ + i16le(sensorPayloadBytes, base + 0), + i16le(sensorPayloadBytes, base + 2), + i16le(sensorPayloadBytes, base + 4), + ]; + } + else if (this.accEnabled) { + accRaw = [ + i16le(sensorPayloadBytes, base + 0), + i16le(sensorPayloadBytes, base + 2), + i16le(sensorPayloadBytes, base + 4), + ]; + } + let accCal = null; + let gyroCal = null; + if (accRaw) { + accCal = this._calibrateAccel(accRaw); + } + if (gyroRaw) { + gyroCal = this._calibrateGyro(gyroRaw); + } + out.push({ + accel: accRaw && accCal ? { raw: accRaw, cal: accCal, units: 'm/s^2' } : null, + gyro: gyroRaw && gyroCal ? { raw: gyroRaw, cal: gyroCal, units: 'deg/s' } : null, + }); + } + return out; + } + applyOperationalConfig(op) { + this.accEnabled = (op[OP_IDX.GEN_CFG_0] & 0b01000000) !== 0; + this.gyroEnabled = (op[OP_IDX.GEN_CFG_0] & 0b00100000) !== 0; + const cfg4 = op[OP_IDX.GYRO_ACCEL2_CFG_4]; + const accelRateCfg = (cfg4 >> 4) & 0x0f; + const cfg5 = op[OP_IDX.GYRO_ACCEL2_CFG_5]; + const accelRangeCfg = (cfg5 >> 2) & 0x03; + const gyroRangeCfg = (cfg5 >> 4) & 0x03; + const accelRangeMap = { 0: '2G', 1: '4G', 2: '8G', 3: '16G' }; + const gyroRangeMap = { + 0: '250DPS', + 1: '500DPS', + 2: '1000DPS', + 3: '2000DPS', + }; + this.setAccelRange(accelRangeMap[accelRangeCfg] ?? this.accRange); + this.setGyroRange(gyroRangeMap[gyroRangeCfg] ?? this.gyroRange); + const hzByCfg = { + 0: null, + 1: 12.5, + 2: 26, + 3: 52, + 4: 104, + 5: 208, + 6: 416, + 7: 833, + 8: 1660, + }; + const hz = hzByCfg[accelRateCfg]; + if (hz) + this.samplingRateHz = hz; + } + } + // Calibration-block range codes (must match getVerisenseCalibrationSensors gen-1). + SensorLSM6DS3.ACC_RANGE_CODE = { + '2G': 0, + '4G': 1, + '8G': 2, + '16G': 3, + }; + SensorLSM6DS3.GYRO_RANGE_CODE = { + '250DPS': 0, + '500DPS': 1, + '1000DPS': 2, + '2000DPS': 3, + }; + + class SensorLSM6DSV extends SensorBase { + constructor() { + super(); + this.accEnabled = true; + this.gyroEnabled = true; + this.magEnabled = true; + this.accelFsG = 2; + this.gyroFsDps = 2000; + // Numeric full-scale codes (register values) used to select the device + // calibration block: accel 0..3 (2/4/8/16 g), gyro 0..4 (125..2000 dps). + this.fsXlCode = 0; + this.fsGCode = 4; + // Configured per-stream rates (the FIFO interleaves accel/gyro/mag, so each + // stream is timestamped on its own rate — see computeSampleTimestamps). Public + // so the per-sub-stream loss tracking (getStreamContributions) can read each. + // accelHz/gyroHz are the configured LSM6DSV ODRs; magHz is the configured + // magnetometer output (sensor-hub) rate. The firmware FIFO-batches accel/gyro + // at their ODR, so they deliver at the configured rate; the mag is still + // bounded by the accel/gyro hub trigger, so a mag rate above the accel/gyro + // ODR delivers slower — which shows up as packet loss. + this.accelHz = 15; + this.gyroHz = 15; + this.magHz = 15; + this.samplingRateHz = 15; + } + decodeAccelFsG(code) { + switch (code) { + case 0: + return 2; + case 1: + return 4; + case 2: + return 8; + case 3: + return 16; + default: + return 2; + } + } + decodeGyroFsDps(code) { + // LSM6DSV FS_G datasheet register values. + switch (code) { + case 0: + return 125; + case 1: + return 250; + case 2: + return 500; + case 3: + return 1000; + case 4: + return 2000; + default: + return 2000; + } + } + decodeOdrHz(code) { + // LSM6DSV ODR_XL / ODR_G datasheet register values (normal mode). + switch (code) { + case 0: + return 0; // Off + case 1: + return 1.875; + case 2: + return 7.5; + case 3: + return 15; + case 4: + return 30; + case 5: + return 60; + case 6: + return 120; + case 7: + return 240; + case 8: + return 480; + case 9: + return 960; + case 10: + return 1920; + case 11: + return 3840; + case 12: + return 7680; + default: + return 15; + } + } + decodeMagOutputRateHz(code) { + // Magnetometer output (sensor-hub) rate code from op-config byte 20 bits 1:0. + // This is the rate mag samples reach the host; the firmware derives the + // underlying LIS2MDL ODR (20/50/100/100 Hz) to keep a fresh sample available. + switch (code) { + case 0: + return 15; + case 1: + return 30; + case 2: + return 60; + case 3: + return 120; + default: + return 15; + } + } + calibrateAccel(raw) { + const dev = this.calibration?.getImu(CalibSensorId.LSM6DSV_ACCEL, this.fsXlCode); + if (dev) + return applyImuCalibration(raw, dev); + const scale = (this.accelFsG / 32768) * 9.80665; + return [raw[0] * scale, raw[1] * scale, raw[2] * scale]; + } + calibrateGyro(raw) { + const dev = this.calibration?.getImu(CalibSensorId.LSM6DSV_GYRO, this.fsGCode); + if (dev) + return applyImuCalibration(raw, dev); + // ST angular-rate sensitivity: 4.375 mdps/LSB at ±125 dps, doubling per + // range (LSM6DSV datasheet §4.3; same spec as the gen-1 LSM6DS3 and the + // device calibration seed / calibrationDefaults GYRO_RANGES). Unlike the + // accel, the gyro does NOT span the full 16-bit range at nominal full + // scale, so a FS/32768 derivation reads ~12.8% low (DEV-874). + const scale = 0.004375 * (this.gyroFsDps / 125); + return [raw[0] * scale, raw[1] * scale, raw[2] * scale]; + } + calibrateMag(raw) { + const dev = this.calibration?.getImu(CalibSensorId.LIS2MDL_MAG, 0); + if (dev) + return applyImuCalibration(raw, dev); + // LIS2MDL nominal sensitivity is 1.5 mGauss/LSB (0.15 uT/LSB). + const scale = 0.15; + return [raw[0] * scale, raw[1] * scale, raw[2] * scale]; + } + parsePayload(sensorPayloadBytes) { + if (!sensorPayloadBytes?.length) + return []; + // Entry count is a 16-bit little-endian value (a full FIFO drain can return + // more than 255 samples), followed by `count` x 7-byte tagged entries. + const entryCount = ((sensorPayloadBytes[0] ?? 0) | ((sensorPayloadBytes[1] ?? 0) << 8)) >>> 0; + const maxEntriesByLength = Math.floor((sensorPayloadBytes.length - 2) / 7); + const n = Math.min(entryCount, maxEntriesByLength); + const out = []; + let offset = 2; + for (let i = 0; i < n; i++) { + const tagCnt = sensorPayloadBytes[offset]; + const tag = (tagCnt >> 3) & 0x1f; + const cnt = (tagCnt >> 1) & 0x03; + const x = i16le(sensorPayloadBytes, offset + 1); + const y = i16le(sensorPayloadBytes, offset + 3); + const z = i16le(sensorPayloadBytes, offset + 5); + const raw = [x, y, z]; + let accel = null; + let gyro = null; + let mag = null; + if (tag === SensorLSM6DSV.TAG_ACCEL && this.accEnabled) { + accel = { raw, cal: this.calibrateAccel(raw), units: 'm/s^2' }; + } + else if (tag === SensorLSM6DSV.TAG_GYRO && this.gyroEnabled) { + gyro = { raw, cal: this.calibrateGyro(raw), units: 'deg/s' }; + } + else if (tag === SensorLSM6DSV.TAG_SENSORHUB_SLAVE0 && this.magEnabled) { + mag = { raw, cal: this.calibrateMag(raw), units: 'uT' }; + } + if (accel || gyro || mag) { + out.push({ tag, cnt, accel, gyro, mag }); + } + offset += 7; + } + return out; + } + applyOperationalConfig(op) { + this.accEnabled = (op[OP_IDX.GEN_CFG_0] & 0b01000000) !== 0; + this.gyroEnabled = (op[OP_IDX.GEN_CFG_0] & 0b00100000) !== 0; + this.magEnabled = (op[OP_IDX.GEN_CFG_3] & 0b00000100) !== 0; + const cfg0 = op[OP_IDX.LSM6DSV_CFG_0] ?? 0; + const cfg1 = op[OP_IDX.LSM6DSV_CFG_1] ?? 0; + const cfg2 = op[OP_IDX.LSM6DSV_CFG_2] ?? 0; + const odrXl = cfg0 & 0x0f; + const fsXl = (cfg0 >> 4) & 0x03; + const odrG = cfg1 & 0x0f; + const fsG = (cfg1 >> 4) & 0x0f; + const odrMag = cfg2 & 0x03; + this.accelFsG = this.decodeAccelFsG(fsXl); + this.gyroFsDps = this.decodeGyroFsDps(fsG); + this.fsXlCode = fsXl; + this.fsGCode = fsG; + this.accelHz = this.accEnabled ? this.decodeOdrHz(odrXl) : 0; + this.gyroHz = this.gyroEnabled ? this.decodeOdrHz(odrG) : 0; + // Configured mag output rate (NOT capped at the accel/gyro trigger). Loss is + // measured against this, so when the accel/gyro that trigger the sensor hub + // are too slow to deliver it, the shortfall surfaces as mag loss. + this.magHz = this.magEnabled ? this.decodeMagOutputRateHz(odrMag) : 0; + this.samplingRateHz = Math.max(this.accelHz, this.gyroHz, this.magHz, 1); + } + /** + * Timestamp each stream (accel / gyro / mag) so all three cover the same block + * time window. The tagged FIFO interleaves the streams, so the generic + * global-index spacing spreads each stream by (#interleaved-streams)x too far + * back and makes consecutive blocks overlap on the time axis. + * + * Each stream's effective rate is derived from *this block*: the block's + * covered duration is taken from a directly-sampled reference stream (accel, + * else gyro) at its known ODR, and every stream is then spread evenly over + * that same duration by its own sample count. This is important for the mag + * (LIS2MDL), which is read via the LSM6DSV sensor hub — its entries land in + * the FIFO at the hub batch rate, NOT the LIS2MDL ODR, so a fixed mag ODR + * would mis-spread it (the zig-zag). Deriving the rate from the block keeps it + * aligned regardless of the hub rate. + */ + computeSampleTimestamps(decodedSamples, block) { + const samples = decodedSamples; + let accelTotal = 0; + let gyroTotal = 0; + let magTotal = 0; + for (const s of samples) { + if (s.accel) + accelTotal++; + else if (s.gyro) + gyroTotal++; + else if (s.mag) + magTotal++; + } + // Block duration (s) from a directly-sampled reference stream at a known ODR. + let blockPeriodSec = 0; + if (accelTotal > 0 && this.accelHz > 0) + blockPeriodSec = accelTotal / this.accelHz; + else if (gyroTotal > 0 && this.gyroHz > 0) + blockPeriodSec = gyroTotal / this.gyroHz; + else if (magTotal > 0 && this.magHz > 0) + blockPeriodSec = magTotal / this.magHz; + // Effective per-stream rate so each stream spans exactly blockPeriodSec. + const rateFor = (total) => blockPeriodSec > 0 && total > 0 ? total / blockPeriodSec : (this.samplingRateHz ?? 1); + const accelRate = rateFor(accelTotal); + const gyroRate = rateFor(gyroTotal); + const magRate = rateFor(magTotal); + let ai = 0; + let gi = 0; + let mi = 0; + return samples.map((s) => { + let numSamples = samples.length; + let i = 0; + let rate = this.samplingRateHz; + if (s.accel) { + numSamples = accelTotal; + i = ai++; + rate = accelRate; + } + else if (s.gyro) { + numSamples = gyroTotal; + i = gi++; + rate = gyroRate; + } + else if (s.mag) { + numSamples = magTotal; + i = mi++; + rate = magRate; + } + return this.extrapolateSampleTimes({ + numSamples, + i, + samplingRateHz: rate, + tsLastSampleMillis: block.tsLastSampleMillis, + systemTsLastSampleMillis: block.systemTsLastSampleMillis, + systemOffsetFirstTime: block.systemOffsetFirstTime, + }); + }); + } + /** + * Report up to three independent sub-streams (accel / gyro / mag) so loss is + * tracked per stream. Each sub-stream's expected rate is its configured rate + * (ODR for accel/gyro, output rate for mag); loss is measured against that, so + * the mag's hub-trigger bound — or any rate the firmware/link can't keep up + * with — surfaces as loss when a configured rate exceeds what's delivered. + */ + getStreamContributions(samplesWithTime, sensorId) { + const samples = samplesWithTime; + const subs = [ + { + key: `${sensorId}:accel`, + label: 'Accel', + rate: this.accelHz, + has: (s) => !!s.accel, + }, + { + key: `${sensorId}:gyro`, + label: 'Gyro', + rate: this.gyroHz, + has: (s) => !!s.gyro, + }, + // Mag enters the FIFO at its configured sensor-hub output rate (`magHz`). + { key: `${sensorId}:mag`, label: 'Mag', rate: this.magHz, has: (s) => !!s.mag }, + ]; + const out = []; + for (const sub of subs) { + let count = 0; + let first = null; + let last = null; + for (const s of samples) { + if (!sub.has(s)) + continue; + count++; + const t = s?.timestamps?.tsMillis; + if (typeof t !== 'number') + continue; + if (first == null || t < first) + first = t; + if (last == null || t > last) + last = t; + } + if (count === 0) + continue; // disabled or no samples in this burst + out.push({ + key: sub.key, + label: sub.label, + samplingRateHz: sub.rate > 0 ? sub.rate : null, + sampleCount: count, + firstSampleMillis: first, + lastSampleMillis: last, + }); + } + return out; + } + } + SensorLSM6DSV.TAG_GYRO = 0x01; + SensorLSM6DSV.TAG_ACCEL = 0x02; + SensorLSM6DSV.TAG_SENSORHUB_SLAVE0 = 0x0e; + + /** + * Decoder for the PPG sensor (Verisense sensor id = 4). + * + * Calibration constants mirror C# `SensorPPG.cs`. + */ + class SensorPPG extends SensorBase { + constructor() { + super(); + this.red = false; + this.ir = false; + this.green = false; + this.blue = false; + /** + * 2nd-gen hub mode: PPG arrives via the MAX32674 hub as a fixed block of 6 raw + * MAX86176 LED channels (6 x u24), independent of the RED/IR/GREEN/BLUE enable + * bits. Set from the connected device's hardware generation (see + * VerisenseClient). When false, the 1st-gen named-channel layout is used. + */ + this.hubMode = false; + this.adcLsb = [7.8125, 15.625, 31.25, 62.5]; + this.adcBitShift = [2 ** 7, 2 ** 6, 2 ** 5, 2 ** 4]; + this.adcResolutionIndex = 0; // 0..3 + /** PPG_SR code → base sampling rate in Hz (op byte PPG_MODE_CONFIG2 bits 4:2). */ + this.PPG_SR_HZ = [50, 100, 200, 400, 800, 1000, 1600, 3200]; + /** SMP_AVE code → FIFO sample-averaging factor (op byte PPG_FIFO_CONFIG bits 7:5). */ + this.SMP_AVE_FACTOR = [1, 2, 4, 8, 16, 32, 32, 32]; + this.samplingRateHz = 50; + } + setChannels(channels) { + if (typeof channels.RED === 'boolean') + this.red = channels.RED; + if (typeof channels.IR === 'boolean') + this.ir = channels.IR; + if (typeof channels.GREEN === 'boolean') + this.green = channels.GREEN; + if (typeof channels.BLUE === 'boolean') + this.blue = channels.BLUE; + } + setHubMode(enabled) { + this.hubMode = enabled; + } + setAdcResolutionIndex(i) { + if (i >= 0 && i <= 3) + this.adcResolutionIndex = i; + } + calibrateValue(uncalValue) { + const idx = this.adcResolutionIndex; + return ((uncalValue / this.adcBitShift[idx]) * this.adcLsb[idx]) / 1000.0; + } + /** + * 2nd-gen hub PPG block: N samples x (3 x u24 LED channels = green, IR, red), + * no count prefix (sample count derived from the block length, matching the + * firmware packer). + */ + parseHubPayload(sensorPayloadBytes) { + const bytesPerSample = 9; // 3 channels x 3 bytes + const n = Math.floor(sensorPayloadBytes.length / bytesPerSample); + const out = []; + for (let i = 0; i < n; i++) { + const base = i * bytesPerSample; + out.push({ + leds: [ + u24le(sensorPayloadBytes, base + 0), // green (LED1) + u24le(sensorPayloadBytes, base + 3), // IR (LED2) + u24le(sensorPayloadBytes, base + 6), // red (LED3) + ], + }); + } + return out; + } + parsePayload(sensorPayloadBytes) { + if (this.hubMode) { + return this.parseHubPayload(sensorPayloadBytes); + } + const enabled = []; + if (this.red) + enabled.push('RED'); + if (this.ir) + enabled.push('IR'); + if (this.green) + enabled.push('GREEN'); + if (this.blue) + enabled.push('BLUE'); + const bytesPerSample = enabled.length * 3; + if (bytesPerSample === 0) + return []; + const n = Math.floor(sensorPayloadBytes.length / bytesPerSample); + const out = []; + for (let i = 0; i < n; i++) { + const base = i * bytesPerSample; + let off = 0; + const sample = {}; + for (const ch of enabled) { + const b0 = sensorPayloadBytes[base + off + 0]; + const b1 = sensorPayloadBytes[base + off + 1]; + const b2 = sensorPayloadBytes[base + off + 2]; + off += 3; + let uncal = (b0 | (b1 << 8) | (b2 << 16)) >>> 0; + uncal &= 0x7ffff; + sample[ch] = { + raw: uncal, + cal: this.calibrateValue(uncal), + units: { raw: 'counts', cal: 'scaled' }, + }; + } + out.push(sample); + } + return out; + } + applyOperationalConfig(op) { + // PPG *channel* flags have a hardware-specific bit mapping (1st-gen named + // channels vs MAX86176 hub), so those are still left to setChannels(). The + // sample rate is a well-defined field, though, and it drives per-sample + // timestamp spacing: without it samplingRateHz stays at the 50 Hz default + // and any other configured rate makes consecutive blocks overlap on the + // time axis (the same "zigzag" fixed for GSR/IMU). + const norm = normalizeOperationalConfig(op); + if (!norm) + return; + const srCode = ((norm[OP_IDX.PPG_MODE_CONFIG2] ?? 0) >> 2) & 0x07; + const smpAveCode = ((norm[OP_IDX.PPG_FIFO_CONFIG] ?? 0) >> 5) & 0x07; + const baseHz = this.PPG_SR_HZ[srCode]; + const aveFactor = this.SMP_AVE_FACTOR[smpAveCode] ?? 1; + // The MAX86xxx averages SMP_AVE samples into one FIFO entry, so the streamed + // output rate is the base PPG_SR divided by the averaging factor. + if (baseHz) + this.samplingRateHz = baseHz / aveFactor; + } + } + + /** Slow-sensor sample-rate index -> Hz (matches firmware slowSensorRateMs). This + * is the configured (target) rate the firmware polls at; the sensor's exposure + * may prevent reaching it, which surfaces as packet loss against this rate. */ + const SLOW_SENSOR_RATE_HZ = [0, 0.5, 1, 2, 5, 10, 20]; + /** Op-config index -> exposure µs (matches firmware vd6283_exposureIndexToUs). */ + const EXPOSURE_US_TABLE = [100000, 1600, 6400, 12800, 25600, 51200, 102400, 204800]; + /** Op-config index -> 8.8 fixed-point gain (matches firmware vd6283_gainIndexToValue). */ + const GAIN_8P8_TABLE = [0x0100, 0x01ab, 0x0280, 0x0500, 0x0a00, 0x1900, 0x3200, 0x42ab]; + /** Reference exposure (firmware VD6283TX_DEFAULT_EXPO). */ + const DEFAULT_EXPO_US = 100800; + /** ALS-counts -> XYZ matrix (firmware App_vd6283tx.c). Rows are X, Y, Z. */ + const XYZ_MATRIX = [ + [0.20557, 0.4167, -0.143816], + [-0.028752, 0.506372, -0.120614], + [-0.552625, 0.335866, 0.494781], + ]; + /** + * Decoder for the VD6283TX45 ambient light sensor (Verisense sensor id = 7). + * + * Data block payload = N samples x 18 bytes (6 channels x 24-bit LE counts). + * In addition to the raw channel counts, each sample carries the derived lux + * and CCT, computed from the RED/GREEN/BLUE channels with the configured gain + * and exposure (ported from firmware App_vd6283tx.c). + */ + class SensorVD6283 extends SensorBase { + constructor() { + super(); + this.exposureUs = EXPOSURE_US_TABLE[0]; + this.gain8p8 = GAIN_8P8_TABLE[0]; + /** Op-config dark-channel bit (LIGHT_CONFIG bit 1): when set the shared second + * slot carries the dark baseline (`DARK`) instead of the visible reading. */ + this.darkEnabled = false; + this.samplingRateHz = 1; + } + /** Normalise a raw channel count for the XYZ transform (gain + exposure). */ + normalizeForXyz(meas) { + const expoScale = DEFAULT_EXPO_US / this.exposureUs; + // Firmware divides by 256 (16.8 / 8.8 fixed-point); float division here is + // a touch more precise than the firmware's integer division. + return (expoScale * (meas / 256)) / (this.gain8p8 / 256 || 1); + } + /** Compute illuminance (lux) and CCT (K) from RED/GREEN/BLUE counts. */ + computeLuxCct(red, green, blue) { + const r = this.normalizeForXyz(red); + const g = this.normalizeForXyz(green); + const b = this.normalizeForXyz(blue); + const X = XYZ_MATRIX[0][0] * r + XYZ_MATRIX[0][1] * g + XYZ_MATRIX[0][2] * b; + const Y = XYZ_MATRIX[1][0] * r + XYZ_MATRIX[1][1] * g + XYZ_MATRIX[1][2] * b; + const Z = XYZ_MATRIX[2][0] * r + XYZ_MATRIX[2][1] * g + XYZ_MATRIX[2][2] * b; + const lux = Y < 0 ? 0 : Y; + const norm = X + Y + Z; + let cct = 0; + if (norm !== 0) { + const x = X / norm; + const y = Y / norm; + const n = (x - 0.332) / (0.1858 - y); + cct = 449 * n ** 3 + 3525 * n ** 2 + 6823.3 * n + 5520.33; + } + return { lux, cct }; + } + parsePayload(sensorPayloadBytes) { + if (!sensorPayloadBytes?.length) + return []; + const n = Math.floor(sensorPayloadBytes.length / SensorVD6283.BYTES_PER_SAMPLE); + const out = []; + for (let i = 0; i < n; i++) { + const base = i * SensorVD6283.BYTES_PER_SAMPLE; + const RED = u24le(sensorPayloadBytes, base + 0); + // Slot 1 is visible-or-dark depending on the configured dark-channel bit. + const slot1 = u24le(sensorPayloadBytes, base + 3); + const VISIBLE = this.darkEnabled ? null : slot1; + const DARK = this.darkEnabled ? slot1 : null; + const BLUE = u24le(sensorPayloadBytes, base + 6); + const GREEN = u24le(sensorPayloadBytes, base + 9); + const IR = u24le(sensorPayloadBytes, base + 12); + const CLEAR = u24le(sensorPayloadBytes, base + 15); + // lux/CCT derive from RED/GREEN/BLUE, so the dark-channel selection (which + // only affects slot 1) leaves them valid in either mode. + const { lux, cct } = this.computeLuxCct(RED, GREEN, BLUE); + out.push({ RED, VISIBLE, BLUE, GREEN, IR, CLEAR, DARK, lux, cct }); + } + return out; + } + applyOperationalConfig(op) { + this.enabled = (op[OP_IDX.GEN_CFG_3] & (1 << 3)) !== 0; + const rateIdx = op[OP_IDX.LIGHT_SAMPLE_RATE_INDEX] ?? 0; + // Report the configured rate; loss is measured against it so a long exposure + // (or any firmware/hardware shortfall) that prevents reaching it shows up. + this.samplingRateHz = SLOW_SENSOR_RATE_HZ[rateIdx] || 1; + const expoIdx = op[OP_IDX.LIGHT_EXPOSURE_INDEX] ?? 0; + const gainIdx = op[OP_IDX.LIGHT_GAIN_INDEX] ?? 0; + this.exposureUs = EXPOSURE_US_TABLE[expoIdx] ?? EXPOSURE_US_TABLE[0]; + this.gain8p8 = GAIN_8P8_TABLE[gainIdx] ?? GAIN_8P8_TABLE[0]; + // LIGHT_CONFIG bit 1 selects the dark channel on slot 1 (see VD6283Sample). + this.darkEnabled = isVerisenseLightDarkChannelEnabled(op); + } + } + SensorVD6283.NUM_CHANNELS = 6; + SensorVD6283.BYTES_PER_SAMPLE = 18; + + function u16le(bytes, off) { + return (bytes[off] & 0xff) | ((bytes[off + 1] & 0xff) << 8); + } + /** + * Decoder for the MAX32674 algorithm hub (Verisense sensor id = 8). + * + * Data block payload = [sampleCount:1] then sampleCount x 14 bytes: + * accel x,y,z : 3 x i16 (6) | hr u16 (2) | hr_conf u8 (1) | + * spo2 u16 (2) | spo2_conf u8 (1) | activity u8 (1) | scd_contact u8 (1) + * + * Raw PPG is reported separately under the PPG sensor id (4). + */ + class SensorMAX32674 extends SensorBase { + constructor() { + super(); + // Approximate; the hub reports at the configured algorithm report rate. + this.samplingRateHz = 25; + } + parsePayload(sensorPayloadBytes) { + if (!sensorPayloadBytes?.length) + return []; + const count = sensorPayloadBytes[0] ?? 0; + const maxByLength = Math.floor((sensorPayloadBytes.length - 1) / SensorMAX32674.BYTES_PER_SAMPLE); + const n = Math.min(count, maxByLength); + const out = []; + for (let i = 0; i < n; i++) { + const base = 1 + i * SensorMAX32674.BYTES_PER_SAMPLE; + out.push({ + accel: { + raw: [ + i16le(sensorPayloadBytes, base + 0), + i16le(sensorPayloadBytes, base + 2), + i16le(sensorPayloadBytes, base + 4), + ], + }, + hr: u16le(sensorPayloadBytes, base + 6), + hrConfidence: sensorPayloadBytes[base + 8] ?? 0, + spo2: u16le(sensorPayloadBytes, base + 9), + spo2Confidence: sensorPayloadBytes[base + 11] ?? 0, + activityClass: sensorPayloadBytes[base + 12] ?? 0, + scdContactState: sensorPayloadBytes[base + 13] ?? 0, + }); + } + return out; + } + applyOperationalConfig(op) { + this.enabled = (op[OP_IDX.GEN_CFG_3] & (1 << 5)) !== 0; + // samplingRateHz is left at its default; the hub report period mapping is + // hardware-specific and not derived from a single op-config byte. + } + } + SensorMAX32674.BYTES_PER_SAMPLE = 14; + + /** MLX90632 refresh-rate code (op-config byte 76 bits 3:1) -> refresh Hz. The + * single skin-temp rate setting is stored as this code; the output (sample) rate + * is refresh / sub-measurements (medical = 2, extended = 3). */ + const MLX_REFRESH_HZ = [0.5, 1, 2, 4, 8, 16, 32, 64]; + /** + * Decoder for the MLX90632 skin temperature sensor (Verisense sensor id = 9). + * + * Data block payload = N samples x 4 bytes: object int16 then ambient int16, + * each in centi-degrees Celsius (value / 100 = degrees C). + */ + class SensorMLX90632 extends SensorBase { + constructor() { + super(); + this.samplingRateHz = 1; + } + parsePayload(sensorPayloadBytes) { + if (!sensorPayloadBytes?.length) + return []; + const n = Math.floor(sensorPayloadBytes.length / SensorMLX90632.BYTES_PER_SAMPLE); + const out = []; + for (let i = 0; i < n; i++) { + const base = i * SensorMLX90632.BYTES_PER_SAMPLE; + const objRaw = i16le(sensorPayloadBytes, base + 0); + const ambRaw = i16le(sensorPayloadBytes, base + 2); + out.push({ + object: { raw: objRaw, cal: objRaw / 100, units: 'degC' }, + ambient: { raw: ambRaw, cal: ambRaw / 100, units: 'degC' }, + }); + } + return out; + } + applyOperationalConfig(op) { + this.enabled = (op[OP_IDX.GEN_CFG_3] & (1 << 4)) !== 0; + // Single skin-temp rate: stored as the MLX90632 refresh-rate code (byte 76 + // bits 3:1). The output (sample) rate the firmware delivers is the refresh + // rate divided by the sub-measurement count (medical = 2, extended = 3). + const cfg = op[OP_IDX.SKIN_TEMP_CONFIG] ?? 0; + const isExtended = (cfg & 0x01) !== 0; + const refreshCode = (cfg >> 1) & 0x07; + const refreshHz = MLX_REFRESH_HZ[refreshCode] ?? 16; + this.samplingRateHz = refreshHz / (isExtended ? 3 : 2); + } + } + SensorMLX90632.BYTES_PER_SAMPLE = 4; + + function defaultAcceptedCommands(command) { + if (command === ASM_COMMAND.READ) + return new Set([ASM_COMMAND.RESPONSE]); + if (command === ASM_COMMAND.WRITE) { + return new Set([ASM_COMMAND.ACK, ASM_COMMAND.ACK_NEXT_STAGE, ASM_COMMAND.RESPONSE]); + } + return new Set([ASM_COMMAND.ACK, ASM_COMMAND.ACK_NEXT_STAGE, ASM_COMMAND.RESPONSE]); + } + function toCommandResponse(msg) { + return { + header: msg.header, + command: msg.command, + property: msg.property, + payload: msg.payload, + }; + } + function validatePendingResponse(pending, msg) { + if (isNackCommand(msg.command)) { + return new Error(`Device returned NACK command=0x${msg.command.toString(16)} property=0x${msg.property.toString(16)}`); + } + if (pending.acceptedProperties?.size) { + if (!pending.acceptedProperties.has(msg.property)) { + return new Error(`Unexpected response property 0x${msg.property.toString(16)} (expected one of ${Array.from(pending.acceptedProperties) + .map((p) => `0x${p.toString(16)}`) + .join(', ')})`); + } + } + else if (msg.property !== pending.expectedProperty) { + return new Error(`Unexpected response property 0x${msg.property.toString(16)} (expected 0x${pending.expectedProperty.toString(16)})`); + } + if (!pending.acceptedCommands.has(msg.command)) { + return new Error(`Unexpected response command 0x${msg.command.toString(16)} for property 0x${msg.property.toString(16)}`); + } + return null; + } + + // Thrown by connectWithRetry() when disconnect() is called while a connect + // attempt is in flight. Must NOT match any of the retryable-error patterns + // (request timeout / gatt server is disconnected / unexpected response + // property) so it always aborts the retry loop. + const CONNECT_CANCELLED_MESSAGE = 'Connect cancelled: disconnect requested during connect attempt.'; + // --------------------------------------------------------------------------- + // VerisenseBleDevice + // --------------------------------------------------------------------------- + /** + * Web Bluetooth client for the Verisense sensor platform. + * + * Extends {@link BaseShimmerClient} and adds an event-emitter API + * (on/off/emit) for the richer event model the Verisense protocol needs. + * + * Supports: + * - BLE streaming (accel, ADC/GSR, gyro, PPG) + * - Web Serial (USB COM port) as an alternative transport + * - Logged-data download (`transferLoggedData`) + * - Operational config read/write + * + * Events: + * - `"connected"` — `{ name?: string; id?: string; kind?: string }` + * - `"disconnected"` — `{ kind: TransportKind }` + * - `"streaming"` — `{ on: boolean }` + * - `"streamPacket"` / `"data"` — `StreamPacket` + * - `"streamStats"` — `StreamStatsSnapshot` (throttled ~3 Hz live throughput/loss) + * - `"opConfig"` — `{ op: Uint8Array }` + * - `"productionConfig"` — `ProductionConfig` + * - `"commandPayload"` — `{ payload: Uint8Array }` + */ + class VerisenseBleDevice extends BaseShimmerClient { + on(ev, fn) { + if (!this._evMap.has(ev)) + this._evMap.set(ev, new Set()); + this._evMap.get(ev).add(fn); + return () => this.off(ev, fn); + } + off(ev, fn) { + this._evMap.get(ev)?.delete(fn); + } + emit(ev, data) { + const s = this._evMap.get(ev); + if (s) + for (const fn of s) + fn(data); + } + constructor(opts = {}) { + super({ debug: opts.debug ?? true }); + // Event emitter state + this._evMap = new Map(); + // Transport handles + this._transportKind = null; + this.device = null; + this.server = null; + this.service = null; + this.tx = null; + this.rx = null; + this.port = null; + this._serialAbort = null; + this._serialReader = null; + this._serialReadLoopTask = null; + this._onGattDisconnected = null; + this._suppressDisconnectedEvent = false; + // Protocol state + this._mode = 'idle'; + this._rxStreamBuf = new Uint8Array(0); + this._pending = null; + this._loggedChain = Promise.resolve(); + this._sync = null; + this._testReportMode = false; // Flag to capture raw streaming bytes for test reports + this._throughputTestMode = false; // Flag to count raw bytes during a BLE throughput test + this._bootstrapRequestTimeoutOverrideMs = null; + // Set by disconnect() so an in-flight connectWithRetry() loop stops instead + // of treating the resulting GATT teardown as a transient link drop. + this._connectCancelRequested = false; + this._isSecondGenerationHw = false; + // Live stream statistics (throughput / packet-loss). Reset on stream start. + this._streamStats = new StreamStatsTracker(); + this._lastStreamStatsEmitMillis = 0; + // Cached configs + this.operationalConfig = null; + this.productionConfig = null; + // Debug flags + this.debugSync = false; + this._syncRxCount = 0; + this._syncPayloadCount = 0; + /** Per-device calibration last read from the device, or null. */ + this._calibration = null; + this.hardwareIdentifier = opts.hardwareIdentifier ?? 'VERISENSE_PULSE_PLUS'; + this.stripStreamCrc = opts.stripStreamCrc ?? true; + this.sensors = { + 1: new SensorADC(), + 2: new SensorLIS2DW12(), + 3: new SensorLSM6DS3(), + 4: new SensorPPG(), + 6: new SensorLSM6DSV(), + 7: new SensorVD6283(), + 8: new SensorMAX32674(), + 9: new SensorMLX90632(), + }; + this.sensors[1].setHardwareIdentifier(this.hardwareIdentifier); + } + _log(...args) { + if (this.debug) + console.log('[Verisense]', ...args); + } + // Quick accessors + get adc() { + return this.sensors[1]; + } + get accel1() { + return this.sensors[2]; + } + get gyroAccel2() { + return this._isSecondGenerationHw ? this.sensors[6] : this.sensors[3]; + } + get gyroAccel2Lsm6ds3() { + return this.sensors[3]; + } + get gyroAccel2Lsm6dsv() { + return this.sensors[6]; + } + get ppg() { + return this.sensors[4]; + } + _setOperationalConfigErasedFallback(lengthHint) { + const fallbackLen = lengthHint ?? this.operationalConfig?.length ?? VERISENSE_OP_CONFIG_BYTE_SIZE; + const op = new Uint8Array(fallbackLen); + op.fill(0xff); + this.operationalConfig = op; + this.emit('opConfigErased', { raw: new Uint8Array(op) }); + this.emit('opConfig', { op: new Uint8Array(op), erased: true }); + return op; + } + async _bootstrapConfigsAfterConnect() { + await this.readProductionConfigFromDevice(); + try { + await this.readOpConfigFromDevice(); + } + catch (e) { + const msg = e instanceof Error ? e.message : String(e); + const invalidOp = /Invalid operational config returned from device/i.test(msg); + const productionErased = this._isUninitializedBlob(this.productionConfig); + if (invalidOp && productionErased) { + console.warn('[opcfg] invalid operational config during bootstrap; treating as erased because production config is uninitialized', { payloadLengthHint: this.operationalConfig?.length ?? VERISENSE_OP_CONFIG_BYTE_SIZE }); + this._setOperationalConfigErasedFallback(); + return; + } + throw e; + } + } + // --------------------------------------------------------------------------- + // BLE connect / disconnect + // --------------------------------------------------------------------------- + async connect(opts = {}) { + if (this._transportKind === 'serial' || this.port) { + try { + await this.disconnect(); + } + catch { + /* ignore */ + } + } + this._transportKind = 'ble'; + // A previous session's disconnect (including the internal teardown above) + // must not cancel this fresh connect attempt. + this._connectCancelRequested = false; + const requestOpts = { + filters: opts.filters ?? [{ services: [NUS_SERVICE] }], + // NORDIC_DFU_SERVICE must be granted at requestDevice() time so the + // buttonless DFU control point is reachable from rebootToDfuBootloader(). + optionalServices: opts.optionalServices ?? [NUS_SERVICE, NORDIC_DFU_SERVICE], + }; + this.device = opts.device ?? (await navigator.bluetooth.requestDevice(requestOpts)); + try { + if (this._onGattDisconnected && this.device) { + this.device.removeEventListener('gattserverdisconnected', this._onGattDisconnected); + } + } + catch { + /* ignore */ + } + this._onGattDisconnected = () => { + this._mode = 'idle'; + this._transportKind = null; + if (this._suppressDisconnectedEvent) + return; + this.emit('disconnected', { kind: 'ble' }); + }; + this.device.addEventListener('gattserverdisconnected', this._onGattDisconnected); + this.server = await this.device.gatt.connect(); + this.service = await this.server.getPrimaryService(NUS_SERVICE); + this.tx = await this.service.getCharacteristic(NUS_TX); + this.rx = await this.service.getCharacteristic(NUS_RX); + await this.rx.startNotifications(); + this.rx.addEventListener('characteristicvaluechanged', (ev) => { + const dv = ev.target?.value; + if (!dv) + return; + const bytes = new Uint8Array(dv.buffer.slice(dv.byteOffset, dv.byteOffset + dv.byteLength)); + this._feedStreamBytes(bytes); + }); + this._emitStatus(`Connected: ${this.device.name ?? 'Verisense'}`); + this.emit('connected', { name: this.device.name, id: this.device.id }); + await this._bootstrapConfigsAfterConnect(); + return true; + } + async _cleanupFailedBleConnectAttempt(retrySettleMs) { + this._suppressDisconnectedEvent = true; + try { + if (this._onGattDisconnected && this.device) { + this.device.removeEventListener('gattserverdisconnected', this._onGattDisconnected); + } + } + catch { + /* ignore */ + } + try { + if (this.device?.gatt?.connected) { + this.device.gatt.disconnect(); + } + } + catch { + /* ignore */ + } + this.tx = null; + this.rx = null; + this.service = null; + this.server = null; + this._pending = null; + this._mode = 'idle'; + this._transportKind = null; + await new Promise((resolve) => setTimeout(resolve, Math.max(0, retrySettleMs))); + this._suppressDisconnectedEvent = false; + } + async _retryBootstrapInPlaceWithBudget(totalBudgetMs, perAttemptTimeoutMs) { + const budgetMs = Math.max(1000, Math.trunc(totalBudgetMs)); + const attemptTimeoutBaseMs = Math.max(1000, Math.trunc(perAttemptTimeoutMs)); + const deadline = Date.now() + budgetMs; + while (Date.now() < deadline) { + if (this._connectCancelRequested) { + throw new Error(CONNECT_CANCELLED_MESSAGE); + } + const remainingMs = Math.max(1000, deadline - Date.now()); + this._bootstrapRequestTimeoutOverrideMs = Math.min(attemptTimeoutBaseMs, remainingMs); + try { + this._pending = null; + this._resetAssembler(); + await this._bootstrapConfigsAfterConnect(); + return true; + } + catch (e) { + const msg = e instanceof Error ? e.message : String(e); + const retryable = /Unexpected response property/i.test(msg) || + /A request is already pending/i.test(msg) || + /request timeout/i.test(msg); + if (!retryable || Date.now() + 100 >= deadline) { + throw e; + } + await new Promise((resolve) => setTimeout(resolve, 100)); + } + } + return false; + } + async connectWithRetry(opts = {}) { + const { bootstrapTimeoutMs = 3000, pairingBootstrapTimeoutMs = 45000, maxRetries = 2, retrySettleMs = 250, retryOnUnexpectedProperty = true, onRetry = null, ...connectOpts } = opts; + const clampedDefaultTimeoutMs = Math.max(1000, Math.trunc(bootstrapTimeoutMs)); + const clampedPairingTimeoutMs = Math.max(clampedDefaultTimeoutMs, Math.trunc(pairingBootstrapTimeoutMs)); + const clampedMaxRetries = Math.max(0, Math.trunc(maxRetries)); + let lastError = null; + this._connectCancelRequested = false; + for (let attempt = 0; attempt <= clampedMaxRetries; attempt += 1) { + if (this._connectCancelRequested) { + throw new Error(CONNECT_CANCELLED_MESSAGE); + } + const attemptTimeoutMs = clampedDefaultTimeoutMs; + this._bootstrapRequestTimeoutOverrideMs = attemptTimeoutMs; + try { + return await this.connect(connectOpts); + } + catch (e) { + lastError = e; + // An explicit disconnect() during the attempt is a user cancel, not a + // transient link drop — tear down and stop retrying. + if (this._connectCancelRequested) { + await this._cleanupFailedBleConnectAttempt(retrySettleMs); + throw new Error(CONNECT_CANCELLED_MESSAGE, { cause: e }); + } + const msg = e instanceof Error ? e.message : String(e); + const isRequestTimeout = /request timeout/i.test(msg); + const isGattDisconnected = /gatt server is disconnected/i.test(msg); + const isUnexpectedResponseProperty = retryOnUnexpectedProperty && /Unexpected response property/i.test(msg); + const shouldRetry = (isRequestTimeout || isGattDisconnected || isUnexpectedResponseProperty) && + attempt < clampedMaxRetries; + if (!shouldRetry) { + await this._cleanupFailedBleConnectAttempt(retrySettleMs); + throw e; + } + // If pairing/passkey entry is still in progress, a request timeout can occur + // while the BLE link itself remains up. In that case, retry bootstrap in-place + // first to avoid forcing a disconnect that interrupts Windows bonding UX. + if (isRequestTimeout && this.device?.gatt?.connected && this.tx && this.rx) { + onRetry?.({ + attempt, + maxRetries: clampedMaxRetries, + bootstrapTimeoutMs: attemptTimeoutMs, + nextBootstrapTimeoutMs: clampedPairingTimeoutMs, + reason: 'request-timeout', + error: msg, + }); + try { + await this._retryBootstrapInPlaceWithBudget(clampedPairingTimeoutMs, clampedDefaultTimeoutMs); + return true; + } + catch (bootstrapRetryError) { + if (this._connectCancelRequested) { + await this._cleanupFailedBleConnectAttempt(retrySettleMs); + throw new Error(CONNECT_CANCELLED_MESSAGE, { cause: bootstrapRetryError }); + } + lastError = bootstrapRetryError; + } + } + let reason; + if (isRequestTimeout) { + reason = 'request-timeout'; + } + else if (isGattDisconnected) { + reason = 'gatt-disconnected'; + } + else { + reason = 'unexpected-response-property'; + } + onRetry?.({ + attempt, + maxRetries: clampedMaxRetries, + bootstrapTimeoutMs: attemptTimeoutMs, + nextBootstrapTimeoutMs: clampedPairingTimeoutMs, + reason, + error: msg, + }); + await this._cleanupFailedBleConnectAttempt(retrySettleMs); + } + finally { + this._bootstrapRequestTimeoutOverrideMs = null; + } + } + throw lastError instanceof Error ? lastError : new Error('BLE connect failed'); + } + // --- Web Serial (USB COM port) connect --- + async connectSerial(opts = {}) { + if (!('serial' in navigator)) { + throw new Error('Web Serial not supported. Use Chrome/Edge on HTTPS or http://localhost.'); + } + if (this._transportKind === 'ble' && this.device?.gatt?.connected) { + await this.disconnect(); + } + else if (this._transportKind === 'serial' && this.port) { + await this.disconnect(); + } + this._transportKind = 'serial'; + this._mode = 'idle'; + this._resetAssembler(); + const serial = navigator.serial; + if (!opts.port) { + opts.port = await serial.requestPort(opts.filters ? { filters: opts.filters } : undefined); + } + this.port = opts.port; + await this.port.open({ + baudRate: opts.baudRate ?? 115200, + dataBits: opts.dataBits ?? 8, + stopBits: opts.stopBits ?? 1, + parity: opts.parity ?? 'none', + flowControl: opts.flowControl ?? 'none', + }); + this._serialAbort = new AbortController(); + this._startSerialReadLoop(this._serialAbort.signal); + this._emitStatus('Connected via USB Serial'); + this.emit('connected', { kind: 'serial' }); + await this._bootstrapConfigsAfterConnect(); + return true; + } + async _serialWrite(u8) { + const writable = this.port.writable; + if (!writable) + throw new Error('Not connected'); + const writer = writable.getWriter(); + try { + await writer.write(u8); + } + finally { + writer.releaseLock(); + } + } + _startSerialReadLoop(signal) { + const port = this.port; + this._serialReadLoopTask = (async () => { + let reader = null; + try { + const readable = port.readable; + if (!readable) + return; + reader = readable.getReader(); + this._serialReader = reader; + while (!signal.aborted) { + const { value, done } = await reader.read(); + if (done) + break; + if (value?.length) + this._feedStreamBytes(new Uint8Array(value)); + } + } + catch (e) { + if (!signal.aborted) + console.warn('[serial] read loop error:', e); + } + finally { + try { + reader?.releaseLock?.(); + } + catch { + /* ignore */ + } + if (this._serialReader === reader) + this._serialReader = null; + this._serialReadLoopTask = null; + if (!signal.aborted) { + this._mode = 'idle'; + this.emit('disconnected', { kind: 'serial' }); + } + } + })(); + } + async _serialDisconnect(reason = 'user') { + try { + this._serialAbort?.abort(); + } + catch { + /* ignore */ + } + const cancelActiveReader = async () => { + const r = this._serialReader; + if (!r) + return false; + try { + await r.cancel(); + } + catch { + /* ignore */ + } + try { + r.releaseLock(); + } + catch { + /* ignore */ + } + if (this._serialReader === r) + this._serialReader = null; + return true; + }; + await cancelActiveReader(); + const portReadableLocked = this.port + ?.readable?.locked; + if (portReadableLocked && !this._serialReader) { + for (let i = 0; i < 10; i++) { + await new Promise((r) => setTimeout(r, 20)); + if (await cancelActiveReader()) + break; + } + } + try { + const task = this._serialReadLoopTask; + if (task) + await Promise.race([task, new Promise((r) => setTimeout(r, 750))]); + } + catch { + /* ignore */ + } + try { + const writable = this.port?.writable; + if (writable?.locked) { + const w = writable.getWriter(); + try { + await w.abort?.(); + } + catch { + /* ignore */ + } + try { + w.releaseLock(); + } + catch { + /* ignore */ + } + } + } + catch { + /* ignore */ + } + try { + await this.port?.close?.(); + } + catch { + /* ignore */ + } + this.port = null; + this._serialAbort = null; + this._serialReader = null; + this._serialReadLoopTask = null; + console.warn(`[serial] disconnect done reason=${reason}`); + } + async disconnect(opts = {}) { + // If a connectWithRetry() loop is mid-attempt, this explicit disconnect + // must stop it from retrying with the same device. connect() clears the + // flag when the next fresh connect starts. + this._connectCancelRequested = true; + const kind = this._transportKind === 'serial' ? 'serial' : 'ble'; + if (this._mode === 'streaming') { + try { + await this.stopStreaming(); + } + catch { + /* ignore */ + } + } + if (this._sync) { + try { + this._abortSync(new Error(opts.reason ?? 'Disconnected')); + } + catch { + /* ignore */ + } + } + if (this._transportKind === 'serial') { + try { + await this._serialDisconnect(opts.reason ?? 'user'); + } + catch { + /* ignore */ + } + } + else { + // Best-effort courtesy notification; swallow the rejection when the BLE + // transport is not up (e.g. disconnect clicked mid-connect, tx not set). + void this.writeBytes(buildMessage(ASM_COMMAND.WRITE, ASM_PROPERTY.DEVICE_DISCONNECT), { + withResponse: false, + }).catch(() => { }); + try { + if (this.rx) + await this.rx.stopNotifications?.(); + } + catch { + /* ignore */ + } + try { + if (this._onGattDisconnected && this.device) { + this.device.removeEventListener('gattserverdisconnected', this._onGattDisconnected); + } + } + catch { + /* ignore */ + } + try { + if (this.device?.gatt?.connected) + this.device.gatt.disconnect(); + } + catch { + /* ignore */ + } + } + this._mode = 'idle'; + this._transportKind = null; + this.port = null; + this._serialAbort = null; + this.tx = this.rx = null; + this.service = this.server = this.device = null; + this.emit('disconnected', { kind }); + return true; + } + // --------------------------------------------------------------------------- + // Streaming + // --------------------------------------------------------------------------- + async startStreaming() { + // Clear live throughput / packet-loss stats for the new streaming session. + this._streamStats.reset(); + this._lastStreamStatsEmitMillis = 0; + await this.setStreamingMode(true); + this._mode = 'streaming'; + this.emit('streaming', { on: true }); + } + async stopStreaming() { + // Stop is best-effort. The application-level ACK for STREAM_MODE-disable rides + // on BLE notifications, which are unacknowledged and can be dropped under + // high-throughput streaming; the in-flight stream tail is also parsed by the + // command path (not the CRC-gated stream scanner) once we leave streaming + // mode, so the small ACK frame is easily lost or mis-framed. We confirm + // delivery of the disable command via a write-with-response, then reconcile + // local state regardless — a missing ACK must never leave the client wedged + // in 'streaming' (which locks the UI). This mirrors the best-effort stop used + // by Shimmer3RClient and the DEVICE_DISCONNECT path in disconnect(). + try { + await this.writeBytes(buildMessage(ASM_COMMAND.WRITE, ASM_PROPERTY.STREAM_MODE, [STREAM_MODE.DISABLE]), { withResponse: true }); + } + catch (e) { + this._log('stopStreaming: disable write failed; reconciling state anyway:', e); + } + finally { + this._mode = 'idle'; + this._resetAssembler(); + this.emit('streaming', { on: false }); + } + } + // --------------------------------------------------------------------------- + // Logged data transfer + // --------------------------------------------------------------------------- + async transferLoggedData(opts = {}) { + const { fileHandle = null, timeoutMs = 1000, maxNack = 5, maxCrcNack = 5, onProgress = null, } = opts; + const bleOk = !!(this.rx && this.tx); + const serOk = !!this.port; + if (!bleOk && !serOk) + throw new Error('Not connected'); + if (this._mode === 'streaming') + throw new Error('Stop streaming before TransferLoggedData'); + if (this._mode === 'logged') + throw new Error('Already syncing logged data'); + let writable = null; + const chunks = []; + if (fileHandle) + writable = await fileHandle.createWritable(); + this._mode = 'logged'; + this._resetAssembler(); + this._loggedChain = Promise.resolve(); + this._syncRxCount = 0; + this._syncPayloadCount = 0; + const sync = { + receiving: true, + lastReply: 'NONE', + emptyAckCount: 0, + nackCount: 0, + nackCrcCount: 0, + maxNack, + maxCrcNack, + lastRxAt: Date.now(), + timeoutMs, + bytesWritten: 0, + lastPayloadIndex: 0, + resolve: null, + reject: null, + timer: null, + writable, + chunks, + onProgress: onProgress ?? null, + }; + this._sync = sync; + const donePromise = new Promise((resolve, reject) => { + sync.resolve = resolve; + sync.reject = reject; + }); + let watchdogRunning = false; + sync.timer = setInterval(async () => { + if (watchdogRunning) + return; + watchdogRunning = true; + try { + if (!this._sync?.receiving) + return; + const age = Date.now() - this._sync.lastRxAt; + if (age < this._sync.timeoutMs) + return; + try { + if (this._sync.lastReply === 'NONE') { + await this.writeBytes(buildMessage(ASM_COMMAND.READ, ASM_PROPERTY.DATA), { + withResponse: true, + }); + } + else { + this._clearSyncRxBuffers('timeout-nack'); + await this.writeBytes(buildMessage(ASM_COMMAND.NACK_GENERIC, ASM_PROPERTY.DATA)); + this._sync.nackCount++; + this._sync.lastReply = 'NACK'; + if (this._sync.nackCount >= this._sync.maxNack) + throw new Error('Too many NACK timeouts'); + } + this._sync.lastRxAt = Date.now(); + } + catch (e) { + this._abortSync(e instanceof Error ? e : new Error(String(e))); + } + } + finally { + watchdogRunning = false; + } + }, Math.max(250, Math.floor(timeoutMs / 2))); + try { + await this.writeBytes(buildMessage(ASM_COMMAND.READ, ASM_PROPERTY.DATA), { + withResponse: true, + }); + const result = await donePromise; + await (this._loggedChain ?? Promise.resolve()); + if (!fileHandle) { + const blob = new Blob(chunks.map(toArrayBuffer), { type: 'application/octet-stream' }); + return { ...result, blob }; + } + return result; + } + finally { + if (sync.timer) { + clearInterval(sync.timer); + sync.timer = null; + } + if (writable) + await writable.close(); + } + } + // --------------------------------------------------------------------------- + // Request / response helpers + // --------------------------------------------------------------------------- + async writeBytes(bytes, opts = {}) { + const u8 = bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes); + if (this._transportKind === 'serial') { + await this._serialWrite(u8); + return; + } + if (!this.tx) + throw new Error('Not connected'); + if (opts.withResponse) { + await this.tx.writeValue(toArrayBuffer(u8)); + return; + } + const txExt = this.tx; + if (txExt.writeValueWithoutResponse) { + await txExt.writeValueWithoutResponse(toArrayBuffer(u8)); + } + else { + await this.tx.writeValue(toArrayBuffer(u8)); + } + } + async _requestByCommand(command, property, payloadBytes = [], timeoutMs = 3000, acceptedCommands, acceptedProperties) { + if (this._pending) + throw new Error('A request is already pending'); + this._mode = 'command'; + this._resetAssembler(); + const req = buildMessage(command, property, payloadBytes); + const accepted = acceptedCommands ?? defaultAcceptedCommands(command); + const pendingPromise = new Promise((resolve, reject) => { + const t = setTimeout(() => { + this._pending = null; + reject(new Error('Request timeout')); + }, timeoutMs); + this._pending = { + expectedProperty: property, + acceptedCommands: accepted, + acceptedProperties, + resolve: (resp) => { + clearTimeout(t); + this._pending = null; + resolve(resp); + }, + reject: (e) => { + clearTimeout(t); + this._pending = null; + reject(e); + }, + }; + }); + await this.writeBytes(req); + return pendingPromise; + } + async readProperty(property, timeoutMs = 3000) { + return this._requestByCommand(ASM_COMMAND.READ, property, [], timeoutMs); + } + async writeProperty(property, payloadBytes = [], timeoutMs = 3000) { + return this._requestByCommand(ASM_COMMAND.WRITE, property, payloadBytes, timeoutMs); + } + async request(opcode, payloadBytes = [], timeoutMs = 3000) { + const { command, property } = parseHeader(opcode & 0xff); + const effectiveTimeoutMs = this._bootstrapRequestTimeoutOverrideMs != null && timeoutMs === 3000 + ? this._bootstrapRequestTimeoutOverrideMs + : timeoutMs; + const rsp = await this._requestByCommand(command, property, payloadBytes, effectiveTimeoutMs); + return { payload: rsp.payload }; + } + // Convenience command methods (all protocol properties) + readStatus() { + return this.request(ASM_COMMAND.READ | ASM_PROPERTY.STATUS1); + } + async readStatusParsed() { + const { payload } = await this.readStatus(); + return parseStatusPayload(payload, 'status1'); + } + readStatus2() { + return this.request(ASM_COMMAND.READ | ASM_PROPERTY.STATUS2); + } + async readStatus2Parsed() { + const { payload } = await this.readStatus2(); + return parseStatusPayload(payload, 'status2'); + } + readData() { + return this.request(ASM_COMMAND.READ | ASM_PROPERTY.DATA); + } + readProductionConfig() { + return this.request(ASM_COMMAND.READ | ASM_PROPERTY.PRODUCTION_CONFIGURATION); + } + readOperationalConfig() { + return this.request(ASM_COMMAND.READ | ASM_PROPERTY.OPERATIONAL_CONFIGURATION); + } + readTime() { + return this.request(ASM_COMMAND.READ | ASM_PROPERTY.TIME); + } + async readTimeUnixSeconds() { + const { payload } = await this.readTime(); + return asmRtcBytesToUnixSeconds(payload); + } + readPendingEvents() { + return this.request(ASM_COMMAND.READ | ASM_PROPERTY.PENDING_EVENTS); + } + async readPendingEventsParsed() { + const { payload } = await this.readPendingEvents(); + return parsePendingEvents(payload); + } + async writeProductionConfig(bytes) { + const payload = normalizeBytePayload(bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes)); + if (!payload || payload.length < 11 || payload.length > 56) { + throw new Error('writeProductionConfig: payload length must be between 11 and 56 bytes'); + } + await this.writeProperty(ASM_PROPERTY.PRODUCTION_CONFIGURATION, payload); + } + async writeOperationalConfig(bytes) { + const payload = normalizeBytePayload(bytes instanceof Uint8Array ? bytes : new Uint8Array(bytes)); + if (!payload || payload.length < 50) { + throw new Error('writeOperationalConfig: payload length must be at least 50 bytes'); + } + // Safety interlock (mirrors firmware): never write a config with both + // Bluetooth and USB disabled, or the device becomes unreachable for + // reconfiguration. Apply to a copy so the caller's buffer is left untouched + // (normalizeBytePayload returns the input reference for a Uint8Array). + const corrected = new Uint8Array(payload); + enforceVerisenseCommsChannelInterlock(corrected); + await this.writeProperty(ASM_PROPERTY.OPERATIONAL_CONFIGURATION, corrected); + } + async writeTime(rtc7) { + const payload = normalizeBytePayload(rtc7 instanceof Uint8Array ? rtc7 : new Uint8Array(rtc7)); + if (!payload || payload.length !== 7) { + throw new Error('writeTime: payload must be exactly 7 bytes'); + } + await this.writeProperty(ASM_PROPERTY.TIME, payload); + } + async writeTimeUnixSeconds(unixSeconds) { + await this.writeTime(unixSecondsToAsmRtcBytes(unixSeconds)); + } + /** + * Request the Verisense firmware to expose the Nordic Secure DFU service. + * + * Writes the ASM `DFU_MODE` property. The firmware treats this as a request + * to enable the buttonless DFU service but does NOT reboot or expose the + * service immediately — it enables it on the next BLE disconnect. The host + * must therefore disconnect and reconnect before the Nordic DFU service (and + * {@link rebootToDfuBootloader}) become available on the connection. + */ + async enableDfuServiceOnNextDisconnect() { + await this.writeProperty(ASM_PROPERTY.DFU_MODE, []); + } + /** + * Reboot the device straight into the Nordic Secure DFU bootloader using the + * buttonless DFU service. + * + * Requires the Nordic DFU service to already be active on the current BLE + * connection — call {@link enableDfuServiceOnNextDisconnect}, then disconnect + * and reconnect first. Writes the "Enter Bootloader" op-code (0x01) to the + * buttonless DFU control-point characteristic; the device acknowledges via an + * indication, then disconnects and resets into the bootloader. + * + * @param options.waitForDisconnect Resolve only once the device drops the + * link (i.e. has begun rebooting). Default `true`. + * @param options.disconnectAfterCommand Force a local GATT disconnect if the + * device has not dropped the link itself. Default `true`. + * @param options.timeoutMs Max time to wait for the device to + * disconnect after the command. Default `10000`. + */ + async rebootToDfuBootloader(options = {}) { + const { waitForDisconnect = true, disconnectAfterCommand = true, timeoutMs = 10000 } = options; + if (this._transportKind !== 'ble' || !this.server || !this.device?.gatt?.connected) { + throw new Error('rebootToDfuBootloader: requires an active BLE connection'); + } + let dfuService; + try { + dfuService = await this.server.getPrimaryService(NORDIC_DFU_SERVICE); + } + catch { + throw new Error('rebootToDfuBootloader: Nordic DFU service is not present on this connection. ' + + 'Call enableDfuServiceOnNextDisconnect(), then disconnect and reconnect first.'); + } + // The buttonless control point lives under one of two UUIDs depending on + // whether the firmware shares its bonds with the bootloader. + let controlPoint = null; + for (const uuid of [NORDIC_DFU_BUTTONLESS_WITHOUT_BONDS, NORDIC_DFU_BUTTONLESS_WITH_BONDS]) { + try { + controlPoint = await dfuService.getCharacteristic(uuid); + break; + } + catch { + /* try the next variant */ + } + } + if (!controlPoint) { + throw new Error('rebootToDfuBootloader: buttonless DFU control-point characteristic not found'); + } + // Start watching for the disconnect before issuing the command so we never + // miss the event if the device reboots immediately. + const disconnected = waitForDisconnect ? this._waitForGattDisconnect(timeoutMs) : null; + // The buttonless control point delivers its response via indications; + // subscribe so the firmware sends it before resetting. Some stacks reject a + // duplicate subscription — the command write below still succeeds. + try { + await controlPoint.startNotifications(); + } + catch { + /* ignore — indication subscription is best-effort */ + } + const cp = controlPoint; + const payload = Uint8Array.from([NORDIC_DFU_OP_ENTER_BOOTLOADER]); + if (cp.writeValueWithResponse) { + await cp.writeValueWithResponse(toArrayBuffer(payload)); + } + else { + await cp.writeValue(toArrayBuffer(payload)); + } + if (disconnected) { + const didDisconnect = await disconnected; + if (!didDisconnect && disconnectAfterCommand && this.device?.gatt?.connected) { + try { + this.device.gatt.disconnect(); + } + catch { + /* ignore */ + } + } + } + else if (disconnectAfterCommand && this.device?.gatt?.connected) { + try { + this.device.gatt.disconnect(); + } + catch { + /* ignore */ + } + } + } + /** + * Resolve when the BLE link drops (`gattserverdisconnected`), or after + * `timeoutMs`. Resolves `true` if the device disconnected, `false` on timeout. + */ + _waitForGattDisconnect(timeoutMs) { + const device = this.device; + if (!device || !device.gatt?.connected) + return Promise.resolve(true); + return new Promise((resolve) => { + let settled = false; + const onDisconnect = () => finish(true); + const finish = (didDisconnect) => { + if (settled) + return; + settled = true; + clearTimeout(timer); + try { + device.removeEventListener('gattserverdisconnected', onDisconnect); + } + catch { + /* ignore */ + } + resolve(didDisconnect); + }; + const timer = setTimeout(() => finish(false), Math.max(0, timeoutMs)); + device.addEventListener('gattserverdisconnected', onDisconnect); + }); + } + async runTestMode(testPayload) { + const payload = normalizeBytePayload(testPayload instanceof Uint8Array ? testPayload : new Uint8Array(testPayload)); + if (!payload || payload.length < 2) { + throw new Error('runTestMode: payload must contain at least [testId, hwMajor]'); + } + await this.writeProperty(ASM_PROPERTY.TEST_MODE, payload); + } + async runHardwareTest(testId, hwMajor, hwMinor = 0, hwInternal = 0) { + const payload = new Uint8Array([ + testId & 0xff, + hwMajor & 0xff, + hwMinor & 0xff, + hwInternal & 0xff, + (hwInternal >> 8) & 0xff, + ]); + await this.runTestMode(payload); + } + /** + * Ask the device to stop/exit any running test, including an in-progress + * hardware test report (TEST_MODE "exit", id 0x00). The firmware acts on this + * from interrupt context, so it aborts the blocking report promptly instead of + * running it to completion against a connection no one is reading. Best-effort + * and safe to call when no test is running. + */ + async stopTestMode(hwMajor = 0, hwMinor = 0, hwInternal = 0) { + await this.runTestMode([ + 0x00, + hwMajor & 0xff, + hwMinor & 0xff, + hwInternal & 0xff, + (hwInternal >> 8) & 0xff, + ]); + } + async runHardwareTestReport(hwMajor, hwMinor = 0, hwInternal = 0, opts = {}) { + const timeoutMs = Math.max(1000, Math.trunc(opts.timeoutMs ?? 120000)); + const completionIdleMs = Math.max(100, Math.trunc(opts.completionIdleMs ?? 1200)); + const marker = String(opts.marker ?? '').trim(); + const endMarker = String(opts.endMarker ?? + (marker.includes('TEST START') ? marker.replace('TEST START', 'TEST END') : '')).trim(); + const factoryTestType = Math.max(0, Math.min(0xff, Math.trunc(opts.factoryTestType ?? 0))); + const abortSignal = opts.signal ?? null; + const onChunk = typeof opts.onChunk === 'function' ? opts.onChunk : null; + const TEST_REPORT_MODE_ID = 0xfe; + const payload = new Uint8Array([ + TEST_REPORT_MODE_ID, + hwMajor & 0xff, + hwMinor & 0xff, + hwInternal & 0xff, + (hwInternal >> 8) & 0xff, + factoryTestType & 0xff, + ]); + return new Promise((resolve, reject) => { + let done = false; + let aggregate = ''; + let decoder; + try { + decoder = new TextDecoder('latin1'); + } + catch { + decoder = new TextDecoder(); + } + let sawMarker = marker.length === 0; + const effectiveIdleMs = Math.max(completionIdleMs, 10000); + let idleTimer = null; + let timeoutTimer = null; + let off = null; + let onAbort = null; + const sanitizeChunk = (text) => { + // Drop control bytes that occasionally appear in factory stream noise + // while preserving CR/LF/TAB for report formatting. + // eslint-disable-next-line no-control-regex -- intentionally strips binary control bytes + return text.replace(/[\u0000-\u0008\u000B\u000C\u000E-\u001F\u007F]/g, ''); + }; + const cleanup = () => { + this._testReportMode = false; + if (off) { + try { + off(); + } + catch { + /* ignore */ + } + off = null; + } + if (idleTimer) { + clearTimeout(idleTimer); + idleTimer = null; + } + if (timeoutTimer) { + clearTimeout(timeoutTimer); + timeoutTimer = null; + } + if (abortSignal && onAbort) { + try { + abortSignal.removeEventListener('abort', onAbort); + } + catch { + /* ignore */ + } + onAbort = null; + } + }; + const finish = (err) => { + if (done) + return; + done = true; + cleanup(); + if (err) { + // Best-effort: tell the device to stop the in-progress test/report so it + // doesn't keep running a blocking suite against a connection no one is + // reading (dialog closed / aborted / timed out). The firmware acts on + // this from interrupt context, so the report aborts promptly. + void this.stopTestMode(hwMajor, hwMinor, hwInternal).catch(() => { }); + reject(err); + return; + } + const tail = decoder.decode(); + if (tail) { + aggregate += tail; + } + resolve(aggregate); + }; + const scheduleIdleFinish = () => { + if (idleTimer) + clearTimeout(idleTimer); + idleTimer = setTimeout(() => { + if (!sawMarker) + return; + finish(); + }, effectiveIdleMs); + }; + off = this.on('testReportChunk', (rawChunk) => { + if (done || !rawChunk?.length) + return; + const chunk = sanitizeChunk(decoder.decode(rawChunk, { stream: true })); + if (!chunk.length) + return; + aggregate += chunk; + if (!sawMarker && marker.length > 0 && aggregate.includes(marker)) { + sawMarker = true; + } + const sawEndMarker = (endMarker.length > 0 && aggregate.includes(endMarker)) || /TEST END/.test(aggregate); + if (sawEndMarker) { + finish(); + return; + } + if (onChunk) { + try { + onChunk(chunk, aggregate); + } + catch { + /* ignore callback errors */ + } + } + if (sawMarker) { + scheduleIdleFinish(); + } + }); + timeoutTimer = setTimeout(() => { + finish(new Error(`runHardwareTestReport timeout after ${timeoutMs} ms while waiting for report data`)); + }, timeoutMs); + if (abortSignal) { + if (abortSignal.aborted) { + finish(new Error('runHardwareTestReport aborted')); + return; + } + onAbort = () => finish(new Error('runHardwareTestReport aborted')); + abortSignal.addEventListener('abort', onAbort, { once: true }); + } + // Enable test report mode before sending command + this._testReportMode = true; + void this.runTestMode(payload).catch((e) => { + const msg = e instanceof Error ? e.message : String(e); + finish(new Error(`runHardwareTestReport failed to start test mode: ${msg}`)); + }); + }); + } + _buildDebugPayload(debugId, args = []) { + const argBytes = args instanceof Uint8Array ? args : new Uint8Array(args); + const payload = new Uint8Array(1 + argBytes.length); + payload[0] = debugId & 0xff; + payload.set(argBytes, 1); + return payload; + } + _debugIndexArgs(index) { + const i = Math.max(0, Math.min(0xff, Math.trunc(index))); + return i > 0 ? [i] : []; + } + _waitForDebugResponse(timeoutMs = 3000) { + return new Promise((resolve, reject) => { + let done = false; + let off = null; + let timer = null; + const cleanup = () => { + if (off) { + try { + off(); + } + catch { + /* ignore */ + } + off = null; + } + if (timer) { + clearTimeout(timer); + timer = null; + } + }; + off = this.on('commandPayload', (evt) => { + if (done || !evt) + return; + if (evt.command !== ASM_COMMAND.RESPONSE || evt.property !== ASM_PROPERTY.DEBUG_COMMAND) + return; + done = true; + cleanup(); + resolve({ payload: evt.payload ?? new Uint8Array(0) }); + }); + timer = setTimeout(() => { + if (done) + return; + done = true; + cleanup(); + reject(new Error('Debug response timeout')); + }, timeoutMs); + }); + } + async readDebugCommand(debugId, args = [], timeoutMs = 3000) { + const payload = this._buildDebugPayload(debugId, args); + const debugAcceptedProps = new Set([ASM_PROPERTY.DEBUG_COMMAND, 0]); + // Python flow: WRITE DEBUG command, optional empty/transient frame, then RESPONSE DEBUG payload. + const responsePromise = this._waitForDebugResponse(timeoutMs); + try { + await this._requestByCommand(ASM_COMMAND.WRITE, ASM_PROPERTY.DEBUG_COMMAND, payload, timeoutMs, undefined, debugAcceptedProps); + return await responsePromise; + } + catch (e) { + void responsePromise.catch(() => { }); + const msg = e instanceof Error ? e.message : String(e); + const isDebugNack = /NACK command=0x(?:50|60|70) property=0x9/i.test(msg); + const isDebugAckPropertyZero = /Unexpected response property 0x0 \(expected 0x9\)/i.test(msg); + if (isDebugNack || isDebugAckPropertyZero) { + return this._waitForDebugResponse(timeoutMs); + } + throw e; + } + } + async sendDebugCommand(debugId, args = [], timeoutMs = 3000) { + const rsp = await this._requestByCommand(ASM_COMMAND.WRITE, ASM_PROPERTY.DEBUG_COMMAND, this._buildDebugPayload(debugId, args), timeoutMs); + return { payload: rsp.payload }; + } + /** + * Stream a MAX32674C algorithm-hub firmware image (.msbl) to the device and + * flash it into the hub via the Maxim bootloader. This is a one-time factory + * operation: it blocks the device for ~1-2 minutes while the hub flash is + * erased and each page is written. Only SR68 Pulse+ hardware (the only board + * carrying the hub) accepts it — other hardware NACKs the BEGIN stage. + * + * @param msbl raw .msbl file bytes + * @param onProgress optional progress callback (pagesDone, totalPages) + * @returns the hub application firmware version string read back after flashing + */ + async uploadHubFirmware(msbl, onProgress) { + const img = msbl instanceof Uint8Array ? msbl : new Uint8Array(msbl); + if (img.length < MSBL.HEADER_SIZE) { + throw new Error('uploadHubFirmware: file is too small to be a valid .msbl'); + } + const numPages = img[MSBL.OFF_NUMPAGES] | (img[MSBL.OFF_NUMPAGES + 1] << 8); + const expectedLen = MSBL.HEADER_SIZE + numPages * MSBL.PAGE_FILE_BYTES; + if (numPages === 0 || img.length < expectedLen) { + throw new Error(`uploadHubFirmware: invalid .msbl (pages=${numPages}, length=${img.length}, expected>=${expectedLen})`); + } + // BEGIN: device enters bootloader, programs IV/auth/page-count, erases flash. + try { + await this._requestByCommand(ASM_COMMAND.WRITE, ASM_PROPERTY.DEBUG_COMMAND, this._buildHubUploadPayload(HUB_FW_UPLOAD_STAGE.BEGIN, img.subarray(0, MSBL.HEADER_SIZE)), 15000); + } + catch (e) { + throw new Error(`Hub FW upload BEGIN failed: ${e instanceof Error ? e.message : String(e)}`, { + cause: e, + }); + } + // Pages: stream each page in order, awaiting ACK_NEXT_STAGE (page flashed). + const MAX_PAGE_RETRIES = 5; + for (let page = 0; page < numPages; page++) { + const base = MSBL.HEADER_SIZE + page * MSBL.PAGE_FILE_BYTES; + const pageBytes = img.subarray(base, base + MSBL.PAGE_FILE_BYTES); + let attempt = 0; + for (;;) { + try { + await this._sendHubPage(page, pageBytes); + break; + } + catch (e) { + if (++attempt >= MAX_PAGE_RETRIES) { + await this._abortHubUpload(); + throw new Error(`Hub FW upload failed at page ${page + 1}/${numPages} after ${attempt} attempts: ${e instanceof Error ? e.message : String(e)}`, { cause: e }); + } + } + } + onProgress?.(page + 1, numPages); + } + // END: device resets the hub to application mode and returns its FW version. + const endRsp = await this._requestByCommand(ASM_COMMAND.WRITE, ASM_PROPERTY.DEBUG_COMMAND, this._buildHubUploadPayload(HUB_FW_UPLOAD_STAGE.END), 8000); + return new TextDecoder().decode(endRsp.payload).replace(/\0+$/, '').trim(); + } + /** Build a debug payload `[HUB_FW_UPLOAD, stage, ...stageArgs]`. */ + _buildHubUploadPayload(stage, stageArgs = []) { + const a = stageArgs instanceof Uint8Array ? stageArgs : new Uint8Array(stageArgs); + const staged = new Uint8Array(1 + a.length); + staged[0] = stage & 0xff; + staged.set(a, 1); + return this._buildDebugPayload(DEBUG_COMMAND_ID.HUB_FW_UPLOAD, staged); + } + /** Send one 8208-byte page as in-order <=64-byte chunks; await ACK_NEXT_STAGE. */ + async _sendHubPage(page, pageBytes) { + const CHUNK = 64; // keep each packet within the device's ~96-byte RX buffer + const total = pageBytes.length; + for (let off = 0; off < total; off += CHUNK) { + const end = Math.min(off + CHUNK, total); + const isFinal = end >= total; + const args = new Uint8Array(4 + (end - off)); + args[0] = page & 0xff; + args[1] = (page >> 8) & 0xff; + args[2] = off & 0xff; + args[3] = (off >> 8) & 0xff; + args.set(pageBytes.subarray(off, end), 4); + const payload = this._buildHubUploadPayload(HUB_FW_UPLOAD_STAGE.PAGE_CHUNK, args); + if (isFinal) { + // Final chunk completes the page; the device flashes it (~0.7 s) and + // replies ACK_NEXT_STAGE (or NACK on failure -> throws -> page retry). + await this._requestByCommand(ASM_COMMAND.WRITE, ASM_PROPERTY.DEBUG_COMMAND, payload, 6000); + } + else { + // Mid-page chunk: reliable, in-order delivery via write-with-response, + // with no application-level reply from the device. + await this.writeBytes(buildMessage(ASM_COMMAND.WRITE, ASM_PROPERTY.DEBUG_COMMAND, payload), { + withResponse: true, + }); + } + } + } + /** Best-effort abort: tell the device to reset the hub back to application mode. */ + async _abortHubUpload() { + try { + await this._requestByCommand(ASM_COMMAND.WRITE, ASM_PROPERTY.DEBUG_COMMAND, this._buildHubUploadPayload(HUB_FW_UPLOAD_STAGE.ABORT), 5000); + } + catch { + /* best effort */ + } + } + /** Read the flash lookup table. The read walks the whole flash on-device + * and can time out on busy sensors, so `retries` re-issues the command + * (total attempts = retries + 1) before giving up. Non-finite or negative + * `retries` is treated as 0; rejections are always `Error` instances. */ + async readFlashLookupTable(index = 0, timeoutMs = 12000, retries = 0) { + const extraAttempts = Number.isFinite(retries) ? Math.max(0, Math.trunc(retries)) : 0; + let lastError = null; + for (let attempt = 0; attempt <= extraAttempts; attempt++) { + try { + return await this.readDebugCommand(DEBUG_COMMAND_ID.FLASH_LOOKUP_TABLE_READ, this._debugIndexArgs(index), timeoutMs); + } + catch (e) { + lastError = e; + } + } + if (lastError instanceof Error) + throw lastError; + throw new Error(lastError == null ? 'readFlashLookupTable: read failed' : String(lastError)); + } + async readRealWorldClockScheduler(index = 0) { + return this.readDebugCommand(DEBUG_COMMAND_ID.RWC_SCHEDULER_READ, this._debugIndexArgs(index)); + } + async readRealWorldClockSchedulerParsed(index = 0) { + const { payload } = await this.readRealWorldClockScheduler(index); + return parseSchedulerDebugPayload(payload); + } + async loadTestLookupTable(index = 0) { + return this.readDebugCommand(DEBUG_COMMAND_ID.LOAD_TEST_LOOKUP_TABLE, this._debugIndexArgs(index)); + } + async checkPayloadCrcErrors(index = 0) { + return this.readDebugCommand(DEBUG_COMMAND_ID.CHECK_PAYLOAD_CRC_ERRORS, this._debugIndexArgs(index)); + } + async checkPayloadCrcErrorsParsed(index = 0) { + const { payload } = await this.checkPayloadCrcErrors(index); + return parsePayloadCrcErrorBankIndexes(payload); + } + async readEventLog(index = 0) { + return this.readDebugCommand(DEBUG_COMMAND_ID.READ_EVENT_LOG, this._debugIndexArgs(index)); + } + async readEventLogParsed(index = 0) { + const { payload } = await this.readEventLog(index); + return parseEventLogPayload(payload); + } + async readRecordBufferDetails(index = 0) { + return this.readDebugCommand(DEBUG_COMMAND_ID.READ_RECORD_BUFFER_DETAILS, this._debugIndexArgs(index)); + } + async readRecordBufferDetailsParsed(index = 0) { + const { payload } = await this.readRecordBufferDetails(index); + return parseRecordBufferDetailsPayload(payload); + } + async eraseOperationalConfig() { + await this.sendDebugCommand(DEBUG_COMMAND_ID.ERASE_OPERATIONAL_CONFIG); + } + async eraseProductionConfig() { + await this.sendDebugCommand(DEBUG_COMMAND_ID.ERASE_PRODUCTION_CONFIG); + } + async clearPendingEvents() { + await this.sendDebugCommand(DEBUG_COMMAND_ID.CLEAR_PENDING_EVENTS); + } + async eraseAllLoggedData(timeoutMs = 12000) { + await this.sendDebugCommand(DEBUG_COMMAND_ID.ERASE_FLASH_AND_LOOKUP_TABLE, [], timeoutMs); + } + /** + * Low-level: ask the device to saturate the BLE link with dummy data for + * `durationMs` milliseconds (debug command 0x0B). The device ACKs immediately + * and then blasts a fixed 244-byte buffer as fast as the link will accept it. + * + * This only starts the blast; it does not measure anything. Prefer + * {@link runBleThroughputTest}, which sends this command and measures the + * throughput actually received at the host. + * + * @param durationMs Blast duration in milliseconds (clamped to the protocol's 0..65535 range). + */ + async testDataTransferLoop(durationMs) { + const clamped = Math.max(0, Math.min(0xffff, Math.trunc(durationMs))); + await this.sendDebugCommand(DEBUG_COMMAND_ID.TEST_DATA_TRANSFER_LOOP, [ + clamped & 0xff, + (clamped >> 8) & 0xff, + ]); + } + /** + * Measure the maximum BLE link throughput, independent of sensor + * configuration. Asks the device to blast dummy data for `durationMs` + * (see {@link testDataTransferLoop}) and measures the goodput actually + * received at the host. + * + * The reported rate reflects device→host (notification) throughput and is + * governed by the negotiated PHY, connection interval, MTU and packets per + * connection interval — i.e. the real link, not any sensor's sample rate. + * + * The measurement finishes when the device falls silent for `idleMs` after + * the blast (or when the overall safety timeout elapses). + * + * @returns received byte/packet counts and the computed throughput. + */ + async runBleThroughputTest(opts = {}) { + const durationMs = Math.max(100, Math.min(60000, Math.trunc(opts.durationMs ?? 5000))); + const idleMs = Math.max(100, Math.min(5000, Math.trunc(opts.idleMs ?? 600))); + const overallTimeoutMs = Math.max(durationMs + 1000, Math.trunc(opts.timeoutMs ?? durationMs + 5000)); + const abortSignal = opts.signal ?? null; + const onProgress = typeof opts.onProgress === 'function' ? opts.onProgress : null; + return new Promise((resolve, reject) => { + let done = false; + let bytes = 0; + let packets = 0; + let firstByteMs = 0; + let lastByteMs = 0; + let idleTimer = null; + let timeoutTimer = null; + let off = null; + let onAbort = null; + const buildResult = () => { + const elapsedMs = packets > 1 && lastByteMs > firstByteMs ? lastByteMs - firstByteMs : durationMs; + const bps = elapsedMs > 0 ? (bytes * 1000) / elapsedMs : 0; + return { + bytesReceived: bytes, + packetsReceived: packets, + durationRequestedMs: durationMs, + elapsedMs, + throughputBytesPerSec: bps, + throughputKBps: bps / 1000, + throughputKbps: (bps * 8) / 1000, + }; + }; + const cleanup = () => { + this._throughputTestMode = false; + if (off) { + try { + off(); + } + catch { + /* ignore */ + } + off = null; + } + if (idleTimer) { + clearTimeout(idleTimer); + idleTimer = null; + } + if (timeoutTimer) { + clearTimeout(timeoutTimer); + timeoutTimer = null; + } + if (abortSignal && onAbort) { + try { + abortSignal.removeEventListener('abort', onAbort); + } + catch { + /* ignore */ + } + onAbort = null; + } + }; + const finish = (err) => { + if (done) + return; + done = true; + cleanup(); + if (err) + reject(err); + else + resolve(buildResult()); + }; + const scheduleIdleFinish = () => { + if (idleTimer) + clearTimeout(idleTimer); + idleTimer = setTimeout(() => { + // Only finish on idle once data has actually started arriving. + if (packets > 0) + finish(); + }, idleMs); + }; + off = this.on('throughputChunk', (len) => { + if (done || !len) + return; + const now = nowMillis(); + if (packets === 0) + firstByteMs = now; + lastByteMs = now; + bytes += len; + packets++; + if (onProgress) { + try { + onProgress(buildResult()); + } + catch { + /* ignore callback errors */ + } + } + scheduleIdleFinish(); + }); + // Safety net: the device stops after durationMs, so the idle gap should + // normally finish first. If it never does, finalize with what we have. + timeoutTimer = setTimeout(() => finish(), overallTimeoutMs); + if (abortSignal) { + if (abortSignal.aborted) { + finish(new Error('runBleThroughputTest aborted')); + return; + } + onAbort = () => finish(new Error('runBleThroughputTest aborted')); + abortSignal.addEventListener('abort', onAbort, { once: true }); + } + // Enable raw-count mode before sending so no blast bytes are missed. The + // ACK is consumed by the normal command path (while _pending is set); the + // dummy blast that follows is counted by the _feedStreamBytes branch. + this._throughputTestMode = true; + void this.testDataTransferLoop(durationMs).catch((e) => { + const msg = e instanceof Error ? e.message : String(e); + finish(new Error(`runBleThroughputTest failed to start: ${msg}`)); + }); + }); + } + async ledTest(ledIndex) { + await this.sendDebugCommand(DEBUG_COMMAND_ID.LED_TEST, [ledIndex & 0xff]); + } + async max86xxxLedTest(start) { + await this.sendDebugCommand(DEBUG_COMMAND_ID.MAX86XXX_LED_TEST, [start ? 0x01 : 0x00]); + } + async startPowerProfilerTest() { + await this.sendDebugCommand(DEBUG_COMMAND_ID.POWER_PROFILER_TEST); + } + async requestSystemReset() { + await this.sendDebugCommand(DEBUG_COMMAND_ID.SYSTEM_RESET); + } + async startIcPowerConsumptionTest(loopCount, stageIntervalMs) { + const clampedLoopCount = Math.max(0, Math.min(0xffff, Math.trunc(loopCount))); + const clampedStageInterval = Math.max(0, Math.min(0xffff, Math.trunc(stageIntervalMs))); + await this.sendDebugCommand(DEBUG_COMMAND_ID.IC_POWER_CONSUMPTION_TEST, [ + clampedLoopCount & 0xff, + (clampedLoopCount >> 8) & 0xff, + clampedStageInterval & 0xff, + (clampedStageInterval >> 8) & 0xff, + ]); + } + async deleteAllBonds() { + await this.sendDebugCommand(DEBUG_COMMAND_ID.DELETE_ALL_BONDS); + } + async _assertBleLinkDebugSupported() { + let parsed; + if (this.productionConfig?.length) { + if (this._isErasedBlob(this.productionConfig)) { + throw new Error('BLE link debug commands require firmware >= 1.4.23, but production config is erased.'); + } + parsed = parseProductionConfigPayload(this.productionConfig); + } + else { + parsed = await this.readProductionConfigFromDevice(); + if (this._isErasedBlob(this.productionConfig)) { + throw new Error('BLE link debug commands require firmware >= 1.4.23, but production config is erased.'); + } + } + const current = { + major: Number(parsed.revFwMajor), + minor: Number(parsed.revFwMinor), + internal: Number(parsed.revFwInternal), + }; + if (!Number.isFinite(current.major) || + !Number.isFinite(current.minor) || + !Number.isFinite(current.internal)) { + throw new Error('BLE link debug commands require firmware >= 1.4.23, but firmware version is unavailable.'); + } + const min = BLE_LINK_MIN_FW; + if (compareVerisenseFirmwareVersion(current, min) < 0) { + throw new Error(`BLE link debug commands require firmware >= ${formatVerisenseFirmwareVersion(min)} (current ${formatVerisenseFirmwareVersion(current)}).`); + } + } + async readBleLinkParams() { + await this._assertBleLinkDebugSupported(); + return this.readDebugCommand(DEBUG_COMMAND_ID.BLE_LINK_PARAMS_READ); + } + async readBleLinkParamsParsed() { + const { payload } = await this.readBleLinkParams(); + return parseBleLinkDebugPayload(payload); + } + async optimizeBleLink() { + await this._assertBleLinkDebugSupported(); + return this.readDebugCommand(DEBUG_COMMAND_ID.BLE_LINK_OPTIMIZE); + } + async optimizeBleLinkParsed() { + const { payload } = await this.optimizeBleLink(); + return parseBleLinkDebugPayload(payload); + } + _bleLinkSignature(parsed) { + return [ + parsed.attMtu, + parsed.maxDataLength, + parsed.connectionIntervalUnits, + parsed.txPhy, + parsed.rxPhy, + parsed.isConnected ? 1 : 0, + ].join('|'); + } + _bleLinkOptimizedEnough(parsed, { targetConnectionIntervalUnits, targetPhy, minDataLength, }) { + const intervalOk = parsed.connectionIntervalUnits <= targetConnectionIntervalUnits; + const phyOk = parsed.txPhy === targetPhy && parsed.rxPhy === targetPhy; + const mtuBoundDataLength = Math.max(20, (parsed.attMtu || 23) - 3); + const requiredDataLength = Math.min(minDataLength, mtuBoundDataLength); + const dataLenOk = parsed.maxDataLength >= requiredDataLength; + return intervalOk && phyOk && dataLenOk; + } + _isAbortError(error) { + if (error?.name === 'AbortError') + return true; + const msg = error instanceof Error ? error.message : String(error); + return /abort/i.test(msg); + } + _waitWithAbort(ms, signal) { + if (!Number.isFinite(ms) || ms <= 0) + return Promise.resolve(); + if (signal?.aborted) { + const err = new Error('Operation aborted'); + err.name = 'AbortError'; + return Promise.reject(err); + } + return new Promise((resolve, reject) => { + const timer = setTimeout(() => { + if (signal) + signal.removeEventListener('abort', onAbort); + resolve(); + }, ms); + const onAbort = () => { + clearTimeout(timer); + if (signal) + signal.removeEventListener('abort', onAbort); + const err = new Error('Operation aborted'); + err.name = 'AbortError'; + reject(err); + }; + if (signal) { + signal.addEventListener('abort', onAbort, { once: true }); + } + }); + } + async autoOptimizeBleLink(opts = {}) { + const startedAt = nowMillis(); + const pollIntervalMs = Math.max(100, Math.trunc(opts.pollIntervalMs ?? 700)); + const stableReadCount = Math.max(1, Math.trunc(opts.stableReadCount ?? 3)); + const maxDurationMs = Math.max(pollIntervalMs, Math.trunc(opts.maxDurationMs ?? 20000)); + const settleMode = opts.settleMode === 'stability' ? 'stability' : 'target-and-stability'; + const minSettleTimeMs = Math.max(0, Math.trunc(opts.minSettleTimeMs ?? (settleMode === 'stability' ? pollIntervalMs * 2 : 0))); + const forceOptimizeAttempts = Math.max(0, Math.trunc(opts.forceOptimizeAttempts ?? (settleMode === 'stability' ? 2 : 0))); + const targetConnectionIntervalUnits = Math.max(6, Math.trunc(opts.targetConnectionIntervalUnits ?? 6)); + const targetPhy = Math.max(1, Math.min(4, Math.trunc(opts.targetPhy ?? 2))); + const minDataLength = Math.max(20, Math.min(251, Math.trunc(opts.minDataLength ?? 251))); + const signal = opts.signal ?? null; + let iterations = 0; + let optimizeAttempts = 0; + let stableCount = 0; + let lastSignature = ''; + let lastParsed = null; + const finish = (reason) => ({ + reason, + iterations, + optimizeAttempts, + stableCount, + lastParsed, + durationMs: Math.max(0, nowMillis() - startedAt), + }); + if (this._transportKind !== 'ble') + return finish('not-ble'); + if (signal?.aborted) + return finish('aborted'); + while (nowMillis() - startedAt < maxDurationMs) { + if (signal?.aborted) + return finish('aborted'); + if (this._transportKind !== 'ble') + return finish('not-ble'); + let parsed; + try { + parsed = await this.readBleLinkParamsParsed(); + } + catch (error) { + if (this._isAbortError(error)) + return finish('aborted'); + const msg = error instanceof Error ? error.message : String(error); + if (/require firmware >=|unavailable on this firmware|firmware version is unavailable/i.test(msg)) { + return finish('unsupported'); + } + throw error; + } + iterations += 1; + lastParsed = parsed; + let signature = this._bleLinkSignature(parsed); + stableCount = signature === lastSignature ? stableCount + 1 : 1; + lastSignature = signature; + let optimizedEnough = this._bleLinkOptimizedEnough(parsed, { + targetConnectionIntervalUnits, + targetPhy, + minDataLength, + }); + if (typeof opts.onSample === 'function') { + opts.onSample({ + source: 'read', + iteration: iterations, + stableCount, + parsed, + signature, + optimizedEnough, + }); + } + const shouldOptimize = settleMode === 'stability' ? optimizeAttempts < forceOptimizeAttempts : !optimizedEnough; + if (shouldOptimize) { + try { + parsed = await this.optimizeBleLinkParsed(); + } + catch (error) { + if (this._isAbortError(error)) + return finish('aborted'); + throw error; + } + optimizeAttempts += 1; + lastParsed = parsed; + signature = this._bleLinkSignature(parsed); + stableCount = signature === lastSignature ? stableCount + 1 : 1; + lastSignature = signature; + optimizedEnough = this._bleLinkOptimizedEnough(parsed, { + targetConnectionIntervalUnits, + targetPhy, + minDataLength, + }); + if (typeof opts.onSample === 'function') { + opts.onSample({ + source: 'optimize', + iteration: iterations, + stableCount, + parsed, + signature, + optimizedEnough, + }); + } + } + const elapsedMs = Math.max(0, nowMillis() - startedAt); + const stableReady = stableCount >= stableReadCount && elapsedMs >= minSettleTimeMs; + const settleReady = settleMode === 'stability' ? stableReady : stableReady && optimizedEnough; + if (settleReady) { + return finish('stabilized'); + } + try { + await this._waitWithAbort(pollIntervalMs, signal); + } + catch (error) { + if (this._isAbortError(error)) + return finish('aborted'); + throw error; + } + } + return finish('timeout'); + } + async setStreamingMode(enabled) { + await this.writeProperty(ASM_PROPERTY.STREAM_MODE, [enabled ? STREAM_MODE.ENABLE : STREAM_MODE.DISABLE], 3000); + } + async disconnectRequest() { + try { + return await this.request(ASM_COMMAND.WRITE | ASM_PROPERTY.DEVICE_DISCONNECT, [], 1500); + } + catch (e) { + const msg = e instanceof Error ? e.message : String(e); + if (/timeout/i.test(msg)) + return { payload: new Uint8Array(0) }; + throw e; + } + } + // --------------------------------------------------------------------------- + // Operational config helpers + // --------------------------------------------------------------------------- + async getOpConfig() { + if (this.operationalConfig?.length) + return new Uint8Array(this.operationalConfig); + throw new Error('Operational config not cached. Call readOpConfigFromDevice() first.'); + } + _isErasedBlob(payload) { + return isUniformByteArray(payload, 0xff); + } + _isZeroBlob(payload) { + return isUniformByteArray(payload, 0x00); + } + _isUninitializedBlob(payload) { + return this._isErasedBlob(payload) || this._isZeroBlob(payload); + } + async readProductionConfigFromDevice() { + const rsp = await this.readProductionConfig(); + const prod = normalizeOperationalConfig(rsp?.payload); + if (!prod?.length) + throw new Error('Invalid production config returned from device'); + const erased = this._isErasedBlob(prod); + this.productionConfig = prod; + const parsed = parseProductionConfigPayload(prod); + if (!erased && typeof parsed.revHwMajor === 'number' && typeof parsed.revHwMinor === 'number') { + const hwIdentifier = parsed.revHwMajor === 62 ? 'VERISENSE_GSR_PLUS' : 'VERISENSE_PULSE_PLUS'; + this.adc.setHardwareIdentifier(hwIdentifier); + this.adc.setHardwareRevision(parsed.revHwMajor, parsed.revHwMinor, typeof parsed.revHwInternal === 'number' ? parsed.revHwInternal : 0); + this._isSecondGenerationHw = isVerisenseSecondGenerationHardware(parsed.revHwMajor, parsed.revHwMinor); + // On 2nd-gen hardware the raw PPG (id 4) is the 6-channel MAX86176 block + // drained from the hub, not the 1st-gen named-channel layout. + this.ppg.setHubMode(this._isSecondGenerationHw); + } + if (erased) { + this.emit('productionConfigErased', { raw: new Uint8Array(prod) }); + } + this.emit('productionConfig', parsed); + return parsed; + } + async readOpConfigFromDevice() { + const rsp = await this.readOperationalConfig(); + const op = normalizeOperationalConfig(rsp?.payload); + // Some firmware erase flows can return an empty payload for operational config. + // Treat this as erased (all 0xFF) instead of invalid. + if (!op?.length) { + return this._setOperationalConfigErasedFallback(); + } + if (this._isZeroBlob(op)) { + console.warn('[opcfg] operational config payload is all 0x00; treating as erased'); + return this._setOperationalConfigErasedFallback(op.length); + } + const erased = this._isErasedBlob(op); + if (!erased && op[0] !== 0x5a) { + throw new Error('Invalid operational config returned from device'); + } + this.operationalConfig = op; + if (!erased) { + try { + this.applyOperationalConfig(op); + } + catch (e) { + console.warn('[opcfg] apply after read failed:', e); + } + } + else { + this.emit('opConfigErased', { raw: new Uint8Array(op) }); + } + this.emit('opConfig', { op, erased }); + return new Uint8Array(op); + } + /** + * Push an operational config into every sensor decoder (rates, ranges, + * channel enables) and cache it as the client's working config. Used + * automatically after {@link readOpConfigFromDevice}; call it directly when + * loading a config from a template/file without a device round-trip. + */ + applyOperationalConfig(opConfigBytes) { + const op = opConfigBytes instanceof Uint8Array ? opConfigBytes : new Uint8Array(opConfigBytes); + this.operationalConfig = op; + this.accel1.applyOperationalConfig(op); + this.sensors[3].applyOperationalConfig(op); + this.sensors[6].applyOperationalConfig(op); + this.adc.applyOperationalConfig(op); + this.ppg.applyOperationalConfig(op); + this.sensors[7].applyOperationalConfig(op); + this.sensors[8].applyOperationalConfig(op); + this.sensors[9].applyOperationalConfig(op); + } + async writeOpConfig(opConfigBytes) { + const op = normalizeOperationalConfig(opConfigBytes instanceof Uint8Array ? opConfigBytes : new Uint8Array(opConfigBytes)); + if (!op || op.length < 4) + throw new Error('writeOpConfig: invalid opconfig'); + if (op[0] !== 0x5a) + throw new Error('writeOpConfig: opconfig must start with 0x5A'); + await this.writeOperationalConfig(op); + await this.readOpConfigFromDevice(); + } + /** The parsed calibration set last read via {@link readCalibrationParsed}, or null. */ + getCalibration() { + return this._calibration; + } + /** + * Read the raw calibration blob from the device (CMD_AR_CFG_CALIB). The whole + * blob (~1 KB) arrives in one response, reassembled across BLE/USB fragments. + * Requires FW v2.0.4+; older firmware NACKs or times out. + */ + async readCalibration(timeoutMs = 8000) { + const rsp = await this.readProperty(ASM_PROPERTY.CALIBRATION, timeoutMs); + const blob = rsp.payload; + if (!blob || blob.length < SC_GLOBAL_HEADER_BYTES) { + throw new Error('readCalibration: device returned no/short calibration blob'); + } + return new Uint8Array(blob); + } + /** + * Read + parse the calibration set, cache it, and push it into the IMU + * decoders so subsequent samples calibrate from per-device values. Call before + * a logged-data transfer and/or after connect (no-op on FW that lacks it — + * the call rejects and the decoders keep their full-scale fallback). + */ + async readCalibrationParsed() { + const blob = await this.readCalibration(); + const set = parseCalibrationBlob(blob); + this._calibration = set; + try { + this.accel1.applyCalibration(set); + this.sensors[6].applyCalibration(set); + } + catch (e) { + console.warn('[calib] apply after read failed:', e); + } + return set; + } + /** + * Write a calibration blob to the device (CMD_AR_CFG_CALIB), chunked in + * <=128-byte pieces as [offset_lo, offset_hi, ...chunk]. The device reassembles + * and commits on the final chunk. Requires FW v2.0.4+. + */ + async writeCalibration(blob, chunkSize = 128) { + if (!blob || blob.length < SC_GLOBAL_HEADER_BYTES) { + throw new Error('writeCalibration: invalid calibration blob'); + } + const step = Math.max(1, Math.min(chunkSize, 128)); // firmware ramWrite caps chunks at 128 + for (let offset = 0; offset < blob.length; offset += step) { + const chunk = blob.subarray(offset, Math.min(offset + step, blob.length)); + const payload = new Uint8Array(2 + chunk.length); + payload[0] = offset & 0xff; + payload[1] = (offset >> 8) & 0xff; + payload.set(chunk, 2); + await this.writeProperty(ASM_PROPERTY.CALIBRATION, payload); + } + } + getSensor(name) { + const k = String(name ?? '').toLowerCase(); + if (!k) + return null; + if (k.includes('lis2dw12') || k.includes('accel1') || k === '2') + return this.accel1; + if (k.includes('lsm6dsv') || k === '6') + return this.sensors[6]; + if (k.includes('lsm6') || k.includes('gyro') || k.includes('accel2') || k === '3') + return this.gyroAccel2; + if (k.includes('vbatt') || k.includes('batt') || k.includes('battery') || k.includes('adc')) + return this.adc; + if (k.includes('gsr') || k === '1') + return this.adc; + if (k.includes('ppg') || k === '4') + return this.ppg; + return null; + } + // --------------------------------------------------------------------------- + // RX assembly and dispatch + // --------------------------------------------------------------------------- + _abortSync(err) { + const s = this._sync; + if (!s) + return; + s.receiving = false; + if (s.timer) + clearInterval(s.timer); + this._sync = null; + this._mode = 'idle'; + s.reject(err); + } + _finishSync() { + const s = this._sync; + if (!s) + return; + s.receiving = false; + if (s.timer) + clearInterval(s.timer); + const bytesWritten = s.bytesWritten; + const payloadIndex = s.lastPayloadIndex; + this._sync = null; + this._mode = 'idle'; + s.resolve({ ok: true, bytesWritten, payloadIndex }); + } + async _handleLoggedPayload(payloadU8) { + this._syncPayloadCount++; + const s = this._sync; + if (!s) + return; + const computed = computeCrcLikeCSharp(payloadU8); + const original = getOriginalCrcLE(payloadU8); + const crcOk = computed === original; + const payloadIndex = u16le_at(payloadU8, 0); + if (!crcOk) { + s.lastReply = 'NACK'; + s.nackCrcCount++; + this._clearSyncRxBuffers('crc-nack'); + await this.writeBytes(buildMessage(ASM_COMMAND.NACK_GENERIC, ASM_PROPERTY.DATA)); + if (s.nackCrcCount >= s.maxCrcNack) + this._abortSync(new Error('Too many CRC failures')); + s.onProgress?.({ payloadIndex, bytesWritten: s.bytesWritten, crcOk: false }); + return; + } + s.lastPayloadIndex = payloadIndex; + if (s.writable) { + await s.writable.write(toArrayBuffer(payloadU8)); + } + else { + s.chunks.push(new Uint8Array(payloadU8)); + } + s.bytesWritten += payloadU8.length; + s.emptyAckCount = 0; + s.lastReply = 'ACK'; + s.nackCount = 0; + s.nackCrcCount = 0; + await this.writeBytes(buildMessage(ASM_COMMAND.ACK_NEXT_STAGE, ASM_PROPERTY.DATA), { + withResponse: true, + }); + s.onProgress?.({ payloadIndex, bytesWritten: s.bytesWritten, crcOk: true }); + } + _resetAssembler() { + this._rxStreamBuf = new Uint8Array(0); + } + _appendStreamBuf(chunk) { + const merged = new Uint8Array(this._rxStreamBuf.length + chunk.length); + merged.set(this._rxStreamBuf, 0); + merged.set(chunk, this._rxStreamBuf.length); + this._rxStreamBuf = merged; + } + _clearSyncRxBuffers(reason = '') { + this._rxStreamBuf = new Uint8Array(0); + this._resetAssembler(); + if (this.debugSync) + console.warn('[sync] cleared RX buffers', { reason }); + } + _isPlausibleHeaderByte(hdr) { + const command = hdr & 0xf0; + const property = hdr & 0x0f; + const validCommand = command === ASM_COMMAND.READ || + command === ASM_COMMAND.WRITE || + command === ASM_COMMAND.RESPONSE || + command === ASM_COMMAND.ACK || + command === ASM_COMMAND.NACK_BAD_HEADER_COMMAND || + command === ASM_COMMAND.NACK_BAD_HEADER_PROPERTY || + command === ASM_COMMAND.NACK_GENERIC || + command === ASM_COMMAND.ACK_NEXT_STAGE; + if (!validCommand) + return false; + // Known properties are 0x01..0x0D; keep 0x00 permissive for transient frames. + return (property === 0 || (property >= ASM_PROPERTY.STATUS1 && property <= ASM_PROPERTY.CALIBRATION)); + } + _isPlausibleFrameStart(hdr, len) { + // Logged sync frames can be large and should be length-gated like the working single-file implementation. + if (this._mode === 'logged') { + return len <= VerisenseBleDevice.MAX_FRAME_PAYLOAD_LEN; + } + if (!this._isPlausibleHeaderByte(hdr)) + return false; + // Debug responses may carry large blobs (for example flash lookup tables), + // while normal properties and streaming/logged payloads should stay bounded. + // DEBUG and CALIBRATION responses can be large (lookup tables / the ~1 KB + // calibration blob) and arrive across multiple fragments. + const expectsLargeResponse = this._mode === 'command' && + (this._pending?.expectedProperty === ASM_PROPERTY.DEBUG_COMMAND || + this._pending?.expectedProperty === ASM_PROPERTY.CALIBRATION); + const maxLen = expectsLargeResponse + ? VerisenseBleDevice.MAX_DEBUG_FRAME_PAYLOAD_LEN + : VerisenseBleDevice.MAX_FRAME_PAYLOAD_LEN; + return len <= maxLen; + } + _resolvePendingCommand(msg) { + const pending = this._pending; + if (pending) { + // Some firmware/transport paths emit a transient empty 0x00/0x00 frame + // immediately before the real command response; ignore and keep waiting. + if (msg.command === 0 && + msg.property === 0 && + msg.payload.length === 0) { + return; + } + const err = validatePendingResponse(pending, msg); + if (err) { + this._pending = null; + if (this._mode === 'command') + this._mode = 'idle'; + pending.reject(err); + } + else { + this._pending = null; + if (this._mode === 'command') + this._mode = 'idle'; + pending.resolve(toCommandResponse(msg)); + } + } + else { + this._pending = null; + if (this._mode === 'command') + this._mode = 'idle'; + } + this.emit('commandPayload', { + header: msg.header, + command: msg.command, + property: msg.property, + payload: msg.payload, + }); + } + _feedStreamBytes(chunk) { + if (this._mode === 'logged' && this._sync) + this._sync.lastRxAt = Date.now(); + // Test report data is streamed as raw text bytes after the initial ACK. + // Once the command pending state is cleared, bypass frame parsing entirely. + if (this._testReportMode && !this._pending) { + if (chunk?.length) + this.emit('testReportChunk', chunk); + return; + } + // Throughput-test data is raw dummy bytes streamed after the initial ACK. + // The ACK itself is consumed by the normal frame path while _pending is set; + // everything after is counted (not parsed) until the test finishes. + if (this._throughputTestMode && !this._pending) { + if (chunk?.length) + this.emit('throughputChunk', chunk.length); + return; + } + this._appendStreamBuf(chunk); + for (;;) { + // Streaming frames carry a CRC-16 trailer; use it to lock onto frame + // boundaries. A candidate is accepted only when its CRC validates, so + // after a weak link drops bytes we slide past the garbage and re-lock on + // the next genuine frame instead of emitting misaligned (wrong sensor-id) + // packets. Legacy firmware that streams without a CRC trailer + // (stripStreamCrc=false) falls through to the length-only path below. + if (this._mode === 'streaming' && this.stripStreamCrc) { + const scan = scanStreamFrame(this._rxStreamBuf); + if (scan.status === 'need-more') + return; + if (scan.status === 'invalid') { + if (this.debugSync) { + console.warn('[rx] stream resync: dropping byte', { + dropped: this._rxStreamBuf[0], + bufLen: this._rxStreamBuf.length, + }); + } + this._rxStreamBuf = this._rxStreamBuf.slice(1); + this._streamStats.recordResyncDrop(1); + continue; + } + this._rxStreamBuf = this._rxStreamBuf.slice(scan.consumed); + this._handleStreamingPayload(scan.payload); + continue; + } + if (this._rxStreamBuf.length < 3) + return; + const hdr = this._rxStreamBuf[0]; + const len = (this._rxStreamBuf[1] | (this._rxStreamBuf[2] << 8)) >>> 0; + if (!this._isPlausibleFrameStart(hdr, len)) { + if (this.debugSync) { + console.warn('[rx] resync: dropping byte', { + dropped: hdr, + nextLen: len, + bufLen: this._rxStreamBuf.length, + }); + } + this._rxStreamBuf = this._rxStreamBuf.slice(1); + continue; + } + if (len === 0) { + const header = hdr & 0xff; + const decodedHeader = parseHeader(header); + const msg = { + header, + command: decodedHeader.command, + property: decodedHeader.property, + payloadLength: 0, + payload: new Uint8Array(0), + }; + this._rxStreamBuf = this._rxStreamBuf.slice(3); + if (this._mode === 'logged' && hdr === buildHeader(ASM_COMMAND.ACK, ASM_PROPERTY.DATA)) { + const s = this._sync; + if (s && s.bytesWritten === 0 && s.emptyAckCount < 6) { + s.emptyAckCount++; + if (this.debugSync) + console.log('[sync] empty ACK before payload; requesting next DATA chunk.'); + void this.writeBytes(buildMessage(ASM_COMMAND.READ, ASM_PROPERTY.DATA), { + withResponse: true, + }).catch((e) => this._abortSync(e)); + continue; + } + if (this.debugSync) + console.log('[sync] EOS received. Finishing.'); + this._finishSync(); + continue; + } + if (this._mode === 'command') { + this._resolvePendingCommand(msg); + } + continue; + } + if (this._rxStreamBuf.length < 3 + len) + return; + const payload = this._rxStreamBuf.slice(3, 3 + len); + this._rxStreamBuf = this._rxStreamBuf.slice(3 + len); + const header = hdr & 0xff; + const decodedHeader = parseHeader(header); + const msg = { + header, + command: decodedHeader.command, + property: decodedHeader.property, + payloadLength: payload.length, + payload, + }; + if (this._mode === 'logged') { + this._loggedChain = (this._loggedChain ?? Promise.resolve()) + .then(() => this._handleLoggedPayload(msg.payload)) + .catch((e) => this._abortSync(e)); + continue; + } + if (this._mode === 'streaming') { + this._handleStreamingPayload(msg.payload); + continue; + } + this._resolvePendingCommand(msg); + } + } + _handleStreamingPayload(payload) { + if (payload.length < 4) + return; + let body = payload; + let crcOk = null; + if (this.stripStreamCrc && payload.length >= 6) { + // Reached only for frames the CRC-gated scanner already validated (see + // _feedStreamBytes), so the CRC is known good; just strip the 2-byte + // trailer before decoding. + body = payload.slice(0, payload.length - 2); + crcOk = true; + } + const sensorId = body[0]; + const tick = u24le(body, 1); + const sensorPayload = body.slice(4); + const sensor = this.sensors[sensorId]; + const systemTsLastSampleMillis = nowMillis(); + let tsInfo = null; + if (sensor) + tsInfo = sensor.getTimestampUnwrappedMillis(tick, systemTsLastSampleMillis); + let decodedSamples = null; + if (sensor) + decodedSamples = sensor.parsePayload(sensorPayload); + let samplesWithTime = decodedSamples; + if (sensor && Array.isArray(decodedSamples) && decodedSamples.length > 0 && tsInfo) { + // Per-stream-aware (sensors with interleaved FIFO streams override this). + const tsArray = sensor.computeSampleTimestamps(decodedSamples, { + tsLastSampleMillis: tsInfo.shimmerMillis, + systemTsLastSampleMillis, + systemOffsetFirstTime: tsInfo.systemOffsetFirstTime, + }); + samplesWithTime = decodedSamples.map((s, i) => ({ + ...s, + timestamps: tsArray[i], + })); + } + const packet = { + sensorId, + tick_u24: tick, + decoded: samplesWithTime, + rawPayload: sensorPayload, + crcOk, + }; + // Live throughput / packet-loss accounting. Loss is derived from gaps in the + // monotonic device clock (tsMillis) via getStreamContributions; throughput + // uses the full BLE frame size and host receive time. + const contributions = sensor && Array.isArray(samplesWithTime) && samplesWithTime.length + ? sensor.getStreamContributions(samplesWithTime, sensorId) + : []; + this._streamStats.recordPacket({ + sensorId, + byteLength: payload.length, + crcOk, + recvMillis: systemTsLastSampleMillis, + contributions, + }); + this.emit('streamPacket', packet); + this.emit('data', packet); + // Throttled stats push (~3 Hz) so the UI can subscribe instead of polling. + if (systemTsLastSampleMillis - this._lastStreamStatsEmitMillis >= 333) { + this._lastStreamStatsEmitMillis = systemTsLastSampleMillis; + this.emit('streamStats', this._streamStats.snapshot(systemTsLastSampleMillis)); + } + } + /** Snapshot of live stream statistics (throughput / packet-loss). */ + getStreamStats() { + return this._streamStats.snapshot(nowMillis()); + } + } + // Single source of truth for the max frame size, shared with the CRC-gated + // streaming scanner so both framing paths accept the same large (fragmented) + // payloads. See STREAM_FRAME_MAX_PAYLOAD. + VerisenseBleDevice.MAX_FRAME_PAYLOAD_LEN = STREAM_FRAME_MAX_PAYLOAD; + VerisenseBleDevice.MAX_DEBUG_FRAME_PAYLOAD_LEN = 0xffff; + // Static NUS UUIDs + VerisenseBleDevice.NUS_SERVICE = NUS_SERVICE; + VerisenseBleDevice.NUS_TX = NUS_TX; + VerisenseBleDevice.NUS_RX = NUS_RX; + + /** + * Verisense Nordic Secure-DFU flow helpers (DEV-845). + * + * The byte transport is Nordic's `web-bluetooth-dfu` library (`SecureDfu` + + * `SecureDfuPackage`, vendored by consuming apps); this module owns everything + * learned about running that library reliably against Verisense sensors over + * desktop Chrome/Edge Web Bluetooth: + * + * - classification of transient BLE-stack errors vs DFU protocol errors + * - a fix for the library's swallowed-rejection hang in `sendOperation` + * - bounded + retried `setDfuMode` (with a full GATT reset between attempts) + * - the two-phase combined-package update (SoftDevice/bootloader then + * application), including resume of an interrupted combined update + * - the bootloader device-picker filter and packet-pacing defaults + * + * The library objects are injected (structurally typed), so this module has no + * build-time dependency on the vendored scripts. All user-visible progress is + * reported through an `onStatus` callback; no DOM access happens here. + */ + /** + * Transient connection/BLE-stack errors worth retrying. "unknown reason" + * (NotSupportedError) is Chrome-on-Windows' generic wrapper for any GATT + * operation the OS stack fails without an ATT error code (DEV-845) — + * typically a startNotifications/write right after a (re)connect, or a + * link being torn down mid-encryption. Recoverable on retry; DFU protocol + * errors (wrong image, version too low, ...) never match. + */ + const VERISENSE_DFU_TRANSIENT_ERROR_REGEX = /unreachable|networkerror|gatt server|disconnected|no longer in range|connection|unknown reason|notsupportederror/i; + /** Total attempts (first try + retries) for the DFU connection-retry helpers. */ + const VERISENSE_DFU_CONNECT_ATTEMPTS = 3; + /** Delay between DFU connection retries, letting the device finish rebooting. */ + const VERISENSE_DFU_RETRY_DELAY_MS = 2000; + /** Time allowed for the base image's post-install reboot back into the bootloader. */ + const VERISENSE_DFU_REBOOT_DELAY_MS = 3000; + /** Bound on `setDfuMode` (connect + notifications + one write): the happy path + * completes in seconds, so a hit means a genuine stall — including the vendored + * library's swallowed-rejection case that {@link patchSecureDfuSendOperation} + * and {@link promiseWithTimeout} exist to catch. */ + const VERISENSE_DFU_SET_MODE_TIMEOUT_MS = 30000; + /** + * Per-packet pacing for the firmware transfer, in ms. The packet + * characteristic is written without response; over Web Bluetooth, Chrome + * drops packets if it outruns the device, so at 0 ms the first pass can fail + * object CRC validation and the library silently retries the WHOLE transfer + * at ~10 ms (the pass that succeeds). Pacing at 10 ms makes the first pass + * succeed outright. Pass 0 ("fast") for full speed on a known-clean link. + * (nRF Connect sidesteps this via a wired connectivity dongle rather than + * the OS BLE stack.) + */ + const VERISENSE_DFU_RELIABLE_PACKET_DELAY_MS = 10; + const VERISENSE_DFU_FAST_PACKET_DELAY_MS = 0; + /** + * The Verisense bootloader advertises as "Verisense-BL..."; app-mode sensors + * ("Verisense-..." without the -BL) are deliberately excluded from DFU device + * pickers to keep them unambiguous. The DFU service UUID is not advertised in + * app mode, so it cannot be used to widen the filter; it still needs to be + * granted via `optionalServices` for the GATT connection. + */ + const VERISENSE_DFU_BOOTLOADER_NAME_PREFIX = 'Verisense-BL'; + /** + * The library's routine object-retransmission notices (e.g. "object failed to + * validate"). Over Web Bluetooth, firmware packets are written without + * response and Chrome can drop one if it outruns the device; that makes a + * 4 KB object's CRC mismatch, so the library transparently re-creates and + * re-sends that object. The transfer still completes correctly (every object + * is CRC-checked before Execute, and the bootloader CRC/signature-checks the + * whole image), so these are non-issues that only alarm users. Real failures + * still surface via the promise rejection paths. + */ + const VERISENSE_DFU_ROUTINE_LOG_REGEX = /validat|crc|mismatch|retr|re-?send|re-?creat/i; + /** True for library log messages that are routine retransmission noise and + * should not be surfaced to end users (see {@link VERISENSE_DFU_ROUTINE_LOG_REGEX}). */ + function isRoutineVerisenseDfuLogMessage(message) { + return VERISENSE_DFU_ROUTINE_LOG_REGEX.test(String(message ?? '')); + } + /** "attempt N of M" wording for retry status lines. The retry helpers count + * attempts DOWN (remaining, including the one that just failed), so the + * attempt about to start is total - remaining + 2. */ + function verisenseDfuAttemptLabel(attemptsRemaining, totalAttempts = VERISENSE_DFU_CONNECT_ATTEMPTS) { + return `attempt ${totalAttempts - attemptsRemaining + 2} of ${totalAttempts}`; + } + /** + * Fix the swallowed-rejection hang in `web-bluetooth-dfu` v1.2.1 (DEV-845): + * upstream `SecureDfu.sendOperation` retries a failed control-point write once + * after 500 ms, but if the retry ALSO fails the rejection is dropped and the + * returned promise never settles — the transfer hangs forever. This replaces + * the method with the same logic as upstream, plus: a second write failure + * rejects the pending operation. + * + * Call once per page load with the vendored `SecureDfu` constructor before + * creating instances. Safe to call repeatedly (idempotent). + */ + function patchSecureDfuSendOperation(SecureDfuCtor) { + const patched = function (characteristic, operation, buffer) { + return new Promise((resolve, reject) => { + let size = operation.length; + if (buffer) + size += buffer.byteLength; + const value = new Uint8Array(size); + value.set(operation); + if (buffer) + value.set(new Uint8Array(buffer), operation.length); + this.notifyFns[operation[0]] = { resolve, reject }; + characteristic + .writeValue(value) + .catch((error) => { + this.log(error); + return this.delayPromise(500).then(() => characteristic.writeValue(value)); + }) + .catch((error) => { + delete this.notifyFns[operation[0]]; + reject(error); + }); + }); + }; + SecureDfuCtor.prototype.sendOperation = patched; + } + /** + * Classify known Bluetooth-stack failures seen during Verisense DFU (DEV-845). + * Two signatures of the same Windows pairing/GATT-cache failure loop: + * "unknown reason" (NotSupportedError) is the stack failing an operation on a + * live link, and "GATT Server is disconnected" (NetworkError) is the sensor + * tearing the link down mid-operation — on units without the firmware fix, + * typically its ~400 ms security request colliding with a stale pairing key. + * Unrecognised errors return `category: null` so their raw text passes + * through unchanged. + */ + function classifyVerisenseDfuError(error) { + const rawMessage = String(error); + const name = error && typeof error === 'object' && 'name' in error && typeof error.name === 'string' + ? error.name + : 'GATT error'; + let category = null; + let friendlyMessage = null; + if (/gatt server is disconnected/i.test(rawMessage)) { + category = 'device-disconnected'; + friendlyMessage = 'The sensor disconnected before the operation could complete'; + } + else if (/unknown reason|notsupportederror/i.test(rawMessage)) { + category = 'stack-operation-failed'; + friendlyMessage = 'The Bluetooth stack failed the operation unexpectedly'; + } + return { + category, + friendlyMessage, + transient: VERISENSE_DFU_TRANSIENT_ERROR_REGEX.test(rawMessage), + name, + rawMessage, + }; + } + /** + * Reject a promise that hasn't settled within `ms`. Used to guard + * `SecureDfu.setDfuMode()`: the library builds its buttonless branch as + * `new Promise((resolve, reject) => { startNotifications().then( + * ...sendOperation...).then(resolve) })` with NO `.catch(reject)`, so if + * startNotifications() or the button-command write fails the promise never + * settles. (The {@link patchSecureDfuSendOperation} override makes that write + * reject rather than hang, which this same missing catch would swallow.) + * The timeout message deliberately includes "connection" so it matches + * {@link VERISENSE_DFU_TRANSIENT_ERROR_REGEX} and drives the retry helpers. + * Kept as a timeout rather than re-implementing setDfuMode so the buttonless + * reboot logic isn't duplicated, and so it defends against any stall cause. + */ + function promiseWithTimeout(promise, ms, label) { + let timer; + const timeout = new Promise((_resolve, reject) => { + timer = setTimeout(() => { + reject(new Error(`${label} timed out after ${ms}ms (connection may have stalled)`)); + }, ms); + }); + return Promise.race([promise, timeout]).finally(() => clearTimeout(timer)); + } + /** A bundled firmware name must be a plain `.zip` filename — no path + * separators or traversal — so a malformed/hostile manifest can't make an app + * fetch outside its firmware folder. */ + function isSafeFirmwareArchiveName(name) { + return typeof name === 'string' && /^[^/\\]+\.zip$/i.test(name) && !name.includes('..'); + } + /** + * `navigator.bluetooth.requestDevice()` options for picking a Verisense + * bootloader (replaces the DFU library's `acceptAllDevices`; see + * {@link VERISENSE_DFU_BOOTLOADER_NAME_PREFIX} for why name-prefix only). + * Pass the vendored library's `SecureDfu.SERVICE_UUID`. + */ + function buildVerisenseDfuRequestDeviceOptions(dfuServiceUuid) { + return { + filters: [{ namePrefix: VERISENSE_DFU_BOOTLOADER_NAME_PREFIX }], + optionalServices: [dfuServiceUuid], + }; + } + function delay(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); + } + /** Normalize an `attempts` option to a finite integer >= 1 so the retry + * loops keep their documented "total attempts" semantics for 0/negative/NaN + * inputs. */ + function normalizeAttempts(attempts) { + const v = Number(attempts ?? VERISENSE_DFU_CONNECT_ATTEMPTS); + return Number.isFinite(v) ? Math.max(1, Math.trunc(v)) : VERISENSE_DFU_CONNECT_ATTEMPTS; + } + /** + * `SecureDfu.update()` with retries on connection-level errors. Combined + * (SoftDevice+bootloader+application) packages transfer in two parts with a + * device reset in between; the reconnect for part 2 can fail while the device + * is still rebooting, so transient errors retry after a settle delay. DFU + * protocol errors are not retried. + */ + async function updateVerisenseDfuImageWithRetry(dfu, device, image, options = {}) { + const totalAttempts = normalizeAttempts(options.attempts); + const retryDelayMs = options.retryDelayMs ?? VERISENSE_DFU_RETRY_DELAY_MS; + for (let attemptsRemaining = totalAttempts;; attemptsRemaining--) { + try { + await dfu.update(device, image.initData, image.imageData); + return; + } + catch (error) { + const transient = VERISENSE_DFU_TRANSIENT_ERROR_REGEX.test(String(error)); + if (attemptsRemaining <= 1 || !transient) + throw error; + const attemptLabel = verisenseDfuAttemptLabel(attemptsRemaining, totalAttempts); + options.onRetry?.({ stage: 'update', attemptsRemaining, attemptLabel, error }); + options.onStatus?.(`Reconnecting to bootloader (${attemptLabel})...`); + await delay(retryDelayMs); + } + } + } + /** + * `SecureDfu.setDfuMode()` bounded by a timeout and retried on transient + * errors (DEV-845). setDfuMode (connect + find the buttonless characteristic + * + startNotifications + write) is where Windows' BLE stack intermittently + * fails with "GATT operation failed for unknown reason", typically on the + * first GATT operation after a connect that follows a disconnect. Before each + * retry the GATT connection is fully torn down so the next attempt starts + * from a clean link. Protocol errors (e.g. "Unsupported device") are not + * retried. Resolves like setDfuMode: the device when it is already in + * bootloader mode, or null after the buttonless reboot command has been sent. + */ + async function setVerisenseDfuModeWithRetry(dfu, device, options = {}) { + const totalAttempts = normalizeAttempts(options.attempts); + const retryDelayMs = options.retryDelayMs ?? VERISENSE_DFU_RETRY_DELAY_MS; + const timeoutMs = options.setDfuModeTimeoutMs ?? VERISENSE_DFU_SET_MODE_TIMEOUT_MS; + for (let attemptsRemaining = totalAttempts;; attemptsRemaining--) { + try { + const result = await promiseWithTimeout(dfu.setDfuMode(device), timeoutMs, 'Enter DFU mode'); + return result ?? null; + } + catch (error) { + const transient = VERISENSE_DFU_TRANSIENT_ERROR_REGEX.test(String(error)); + if (attemptsRemaining <= 1 || !transient) + throw error; + const attemptLabel = verisenseDfuAttemptLabel(attemptsRemaining, totalAttempts); + options.onRetry?.({ stage: 'set-dfu-mode', attemptsRemaining, attemptLabel, error }); + options.onStatus?.(`Connection hiccup - retrying (${attemptLabel})...`); + // Full connection-state reset so the retry starts from a clean link. + if (device.gatt?.connected) { + device.gatt.disconnect(); + } + await delay(retryDelayMs); + } + } + } + /** + * Run a full Verisense DFU transfer from a loaded Nordic DFU package: base + * image (SoftDevice/bootloader) first when present, then the application + * image. Resumes interrupted combined updates: a bootloader only installs + * once per version number, so if a previous (interrupted) attempt already + * installed this base image the target rejects it with a firmware-version + * error — that is swallowed and the flow continues to the application image. + * + * Progress text is reported via `options.onStatus`; transfer byte progress + * comes from the `SecureDfu` instance's own "progress" events, which the app + * subscribes to directly. Rejects with the raw library error on failure (run + * it through {@link classifyVerisenseDfuError} for display). + */ + async function runVerisenseDfuUpdate(dfu, device, dfuPackage, options = {}) { + const rebootDelayMs = options.rebootDelayMs ?? VERISENSE_DFU_REBOOT_DELAY_MS; + const baseImage = await dfuPackage.getBaseImage(); + if (baseImage) { + options.onStatus?.(`Updating ${baseImage.type}: ${baseImage.imageFile}...`); + try { + await dfu.update(device, baseImage.initData, baseImage.imageData); + // The base image resets the target on completion; give it time to + // reboot back into the bootloader before part 2. + options.onStatus?.('SoftDevice/bootloader installed - device rebooting...'); + await delay(rebootDelayMs); + } + catch (error) { + if (!/firmware version is too low/i.test(String(error))) + throw error; + options.onStatus?.('SoftDevice/bootloader already up to date - continuing with application...'); + } + } + const appImage = await dfuPackage.getAppImage(); + if (appImage) { + options.onStatus?.(`Updating ${appImage.type}: ${appImage.imageFile}...`); + await updateVerisenseDfuImageWithRetry(dfu, device, appImage, options); + } + } + + /** + * Verisense calibration defaults, hardware/firmware gating, and timestamp helpers. + * + * The byte-level codec lives in `calibration.ts`; this module is the host-side + * single source of truth for the *default* calibration (the mirror of the + * firmware `AsmCalib_seedDefaults`) plus the small amount of domain logic the UI + * used to carry: which calibration blocks a board has, the minimum firmware that + * supports `CMD_AR_CFG_CALIB`, and the 8-byte timestamp encode/decode. + */ + /** Minimum firmware that implements the `CMD_AR_CFG_CALIB` (0x0D) command. */ + const VERISENSE_CALIBRATION_MIN_FW = { + major: 2, + minor: 0, + internal: 4, + }; + /** Whether the given firmware version supports the calibration command. */ + function supportsVerisenseCalibration(fw) { + if (!fw) + return false; + return compareVerisenseFirmwareVersion(fw, VERISENSE_CALIBRATION_MIN_FW) >= 0; + } + // --------------------------------------------------------------------------- + // 8-byte little-endian Unix-epoch-seconds timestamp (block header `ts` field). + // --------------------------------------------------------------------------- + /** Encode Unix-epoch seconds into the 8-byte little-endian calibration `ts`. */ + function unixSecondsToCalibTsBytes(unixSeconds) { + const out = new Uint8Array(SC_TS_BYTES); + let v = Math.max(0, Math.floor(Number(unixSeconds) || 0)); + for (let i = 0; i < SC_TS_BYTES; i++) { + out[i] = v & 0xff; + v = Math.floor(v / 256); + } + return out; + } + /** Decode the 8-byte little-endian calibration `ts` back to Unix-epoch seconds + * (0 = default/seeded). */ + function calibTsBytesToUnixSeconds(ts) { + if (!ts || ts.length < SC_TS_BYTES) + return 0; + let secs = 0; + for (let i = SC_TS_BYTES - 1; i >= 0; i--) + secs = secs * 256 + (ts[i] & 0xff); + return secs; + } + const ACCEL_RANGES = [ + { code: 0, label: '±2g', sens: 1671.665922915 }, + { code: 1, label: '±4g', sens: 835.832961457 }, + { code: 2, label: '±8g', sens: 417.916480729 }, + { code: 3, label: '±16g', sens: 208.958240364 }, + ]; + // LSM6DSV gyro full-scale codes 0..4 (125/250/500/1000/2000 dps). + const GYRO_RANGES = [ + { code: 0, label: '±125dps', sens: 228.571428571 }, + { code: 1, label: '±250dps', sens: 114.285714286 }, + { code: 2, label: '±500dps', sens: 57.142857143 }, + { code: 3, label: '±1000dps', sens: 28.571428571 }, + { code: 4, label: '±2000dps', sens: 14.285714286 }, + ]; + // LSM6DS3 gyro full-scale codes 0..3 (250/500/1000/2000 dps) — the gen-1 op-config + // gyro field is 2 bits, so 125 dps is not selectable via the standard range (see + // SensorLSM6DS3). Codes here match that field and the decoder lookup. + const LSM6DS3_GYRO_RANGES = [ + { code: 0, label: '±250dps', sens: 114.285714286 }, + { code: 1, label: '±500dps', sens: 57.142857143 }, + { code: 2, label: '±1000dps', sens: 28.571428571 }, + { code: 3, label: '±2000dps', sens: 14.285714286 }, + ]; + /** + * 2nd-generation catalog (LSM6DSV accel+gyro, LIS2DW12, LIS2MDL). Alignment + * matrices derived from the ST datasheet axis figures + the SR68-10 pin-1 + * placement; common frame +X=strap, +Y=out of face, +Z=toward hand. LSM6DSV / + * LIS2DW12 are proper rotations (det +1); the LIS2MDL frame is left-handed + * (det −1, a reflection). Kept byte-for-byte in sync with the firmware seed + * (asm_calibration.c) and VERISENSE_CALIBRATION.md §4. + */ + const CALIBRATION_SENSORS_GEN2 = [ + { + id: CalibSensorId.LSM6DSV_ACCEL, + label: 'Accelerometer (LSM6DSV)', + unit: 'LSB/(m/s²)', + align: [0, -1, 0, 0, 0, 1, -1, 0, 0], + ranges: ACCEL_RANGES, + }, + { + id: CalibSensorId.LSM6DSV_GYRO, + label: 'Gyroscope (LSM6DSV)', + unit: 'LSB/dps', + align: [0, -1, 0, 0, 0, 1, -1, 0, 0], + ranges: GYRO_RANGES, + }, + { + id: CalibSensorId.LIS2DW12_ACCEL, + label: 'Accelerometer 2 (LIS2DW12)', + unit: 'LSB/(m/s²)', + align: [1, 0, 0, 0, 0, 1, 0, -1, 0], + ranges: ACCEL_RANGES, + }, + { + id: CalibSensorId.LIS2MDL_MAG, + label: 'Magnetometer (LIS2MDL)', + unit: 'LSB/Gauss', + align: [0, 1, 0, 0, 0, 1, -1, 0, 0], + ranges: [{ code: 0, label: '±49.152Ga', sens: 667 }], + }, + ]; + /** + * 1st-generation catalog (LIS2DW12 + LSM6DS3 accel/gyro). Sensitivities and + * alignment from the gen-1 calibration document (ASM-DES §8). The doc states the + * forward rotation `R` (output = K·R·physical); the stored `align` is the applied + * sensor→common map = Rᵀ. Note the LIS2DW12 mounting differs from gen-2, so its + * alignment (id 39) is generation-specific. All proper rotations (det +1). + */ + const CALIBRATION_SENSORS_GEN1 = [ + { + id: CalibSensorId.LIS2DW12_ACCEL, + label: 'Accelerometer 1 (LIS2DW12)', + unit: 'LSB/(m/s²)', + align: [0, 1, 0, 0, 0, 1, 1, 0, 0], + ranges: ACCEL_RANGES, + }, + { + id: CalibSensorId.LSM6DS3_ACCEL, + label: 'Accelerometer 2 (LSM6DS3)', + unit: 'LSB/(m/s²)', + align: [0, -1, 0, 0, 0, -1, 1, 0, 0], + ranges: ACCEL_RANGES, + }, + { + id: CalibSensorId.LSM6DS3_GYRO, + label: 'Gyroscope (LSM6DS3)', + unit: 'LSB/dps', + align: [0, -1, 0, 0, 0, -1, 1, 0, 0], + ranges: LSM6DS3_GYRO_RANGES, + }, + ]; + /** + * The calibration sensor catalog for a board: the 1st-generation set + * (LIS2DW12 + LSM6DS3) for 1st-gen hardware, otherwise the 2nd-generation set + * (LSM6DSV + LIS2DW12 + LIS2MDL). Unknown/offline (no revision) defaults to + * 2nd-gen. Note id 39 (LIS2DW12) appears in both with a generation-specific + * alignment, so the catalog must be resolved per hardware revision. + */ + function getVerisenseCalibrationSensors(revHwMajor, revHwMinor) { + if (revHwMajor != null && + revHwMinor != null && + !isVerisenseSecondGenerationHardware(revHwMajor, revHwMinor)) { + return CALIBRATION_SENSORS_GEN1; + } + return CALIBRATION_SENSORS_GEN2; + } + /** + * Build the default calibration set for a board (bias=0, default sensitivity, + * default alignment, ts=0). Host-side mirror of `AsmCalib_seedDefaults`; useful + * for "reset to defaults" and round-trip tests. + */ + function buildDefaultVerisenseCalibrationSet(opts) { + const sensors = getVerisenseCalibrationSensors(opts.hwVerMajor, opts.hwVerMinor); + const blocks = sensors.flatMap((s) => s.ranges.map((r) => ({ + sensorId: s.id, + range: r.code, + imu: { + bias: [0, 0, 0], + sens: [r.sens, r.sens, r.sens], + align: s.align.slice(), + }, + }))); + return { + hwVerMajor: opts.hwVerMajor, + hwVerMinor: opts.hwVerMinor, + fwVerMajor: opts.fwVerMajor, + fwVerMinor: opts.fwVerMinor, + fwVerPatch: opts.fwVerPatch, + blocks, + }; + } + /** + * Map each calibration-domain sensor id to whether it is present and usable on + * the connected hardware: + * - `enabled` — present and recorded from; show + allow edit. + * - `disabled` — physically present but not recorded from (LIS2DW12 routed to + * the algorithm hub on 2nd-gen SR68); show greyed. + * - `hidden` — not fitted on this hardware. + * + * `support` is the result of `getVerisenseHardwareSensorSupport`. A null/absent + * support object (offline / unknown hardware) reports every sensor `enabled`. + */ + function getVerisenseCalibrationSensorAvailability(support) { + const all = (v) => ({ + [CalibSensorId.LSM6DSV_ACCEL]: v, + [CalibSensorId.LSM6DSV_GYRO]: v, + [CalibSensorId.LIS2DW12_ACCEL]: v, + [CalibSensorId.LSM6DS3_ACCEL]: v, + [CalibSensorId.LSM6DS3_GYRO]: v, + [CalibSensorId.LIS2MDL_MAG]: v, + }); + if (!support) + return all('enabled'); + const imuGen2 = support.imuGen2 ? 'enabled' : 'hidden'; + const gen1Imu = support.gyroAccel2 ? 'enabled' : 'hidden'; + // LIS2DW12: recorded directly on 1st-gen (accel1); present-but-algo-hub-routed + // on 2nd-gen (imuGen2) so shown disabled; otherwise not fitted. + const lis2dw12 = support.accel1 + ? 'enabled' + : support.imuGen2 + ? 'disabled' + : 'hidden'; + return { + [CalibSensorId.LSM6DSV_ACCEL]: imuGen2, + [CalibSensorId.LSM6DSV_GYRO]: imuGen2, + [CalibSensorId.LIS2MDL_MAG]: imuGen2, + [CalibSensorId.LIS2DW12_ACCEL]: lis2dw12, + [CalibSensorId.LSM6DS3_ACCEL]: gen1Imu, + [CalibSensorId.LSM6DS3_GYRO]: gen1Imu, + }; + } + + exports.ASM_COMMAND = ASM_COMMAND; + exports.ASM_PROPERTY = ASM_PROPERTY; + exports.BLE_LINK_MIN_FW = BLE_LINK_MIN_FW; + exports.BaseShimmerClient = BaseShimmerClient; + exports.CHANNEL_FORMATS = CHANNEL_FORMATS; + exports.CalibQuality = CalibQuality; + exports.CalibSensorId = CalibSensorId; + exports.DEBUG_COMMAND_ID = DEBUG_COMMAND_ID; + exports.GSR_NAME = GSR_NAME; + exports.NORDIC_DFU_BUTTONLESS_WITHOUT_BONDS = NORDIC_DFU_BUTTONLESS_WITHOUT_BONDS; + exports.NORDIC_DFU_BUTTONLESS_WITH_BONDS = NORDIC_DFU_BUTTONLESS_WITH_BONDS; + exports.NORDIC_DFU_OP_ENTER_BOOTLOADER = NORDIC_DFU_OP_ENTER_BOOTLOADER; + exports.NORDIC_DFU_SERVICE = NORDIC_DFU_SERVICE; + exports.NUS_RX = NUS_RX; + exports.NUS_SERVICE = NUS_SERVICE; + exports.NUS_TX = NUS_TX; + exports.OPCODES = OPCODES; + exports.OP_IDX = OP_IDX; + exports.ObjectCluster = ObjectCluster; + exports.RtcDriftMonitor = RtcDriftMonitor; + exports.SC_CALIB_FORMAT_VERSION = SC_CALIB_FORMAT_VERSION; + exports.SC_CAL_QUALITY_MASK = SC_CAL_QUALITY_MASK; + exports.SC_CAL_QUALITY_SHIFT = SC_CAL_QUALITY_SHIFT; + exports.SC_CAL_RANGE_MASK = SC_CAL_RANGE_MASK; + exports.SC_DATA_LEN_IMU = SC_DATA_LEN_IMU; + exports.SC_GLOBAL_HEADER_BYTES = SC_GLOBAL_HEADER_BYTES; + exports.SHIMMER3R_DEFAULTS = SHIMMER3R_DEFAULTS; + exports.STREAM_MODE = STREAM_MODE; + exports.SensorADC = SensorADC; + exports.SensorBase = SensorBase; + exports.SensorBitmapShimmer3 = SensorBitmapShimmer3; + exports.SensorLIS2DW12 = SensorLIS2DW12; + exports.SensorLSM6DS3 = SensorLSM6DS3; + exports.SensorLSM6DSV = SensorLSM6DSV; + exports.SensorMAX32674 = SensorMAX32674; + exports.SensorMLX90632 = SensorMLX90632; + exports.SensorPPG = SensorPPG; + exports.SensorVD6283 = SensorVD6283; + exports.Shimmer3RClient = Shimmer3RClient; + exports.StreamStatsTracker = StreamStatsTracker; + exports.TEST_MODE_ID = TEST_MODE_ID; + exports.TIMESTAMP_FIELD = TIMESTAMP_FIELD; + exports.VERISENSE_BLE_SCHEDULE_DEFAULTS = VERISENSE_BLE_SCHEDULE_DEFAULTS; + exports.VERISENSE_BLE_SCHEDULE_RANGES = VERISENSE_BLE_SCHEDULE_RANGES; + exports.VERISENSE_BLE_SYNC_SCHEDULES = VERISENSE_BLE_SYNC_SCHEDULES; + exports.VERISENSE_CALIBRATION_MIN_FW = VERISENSE_CALIBRATION_MIN_FW; + exports.VERISENSE_DEFAULT_PASSKEY_BY_ID = VERISENSE_DEFAULT_PASSKEY_BY_ID; + exports.VERISENSE_DFU_BOOTLOADER_NAME_PREFIX = VERISENSE_DFU_BOOTLOADER_NAME_PREFIX; + exports.VERISENSE_DFU_CONNECT_ATTEMPTS = VERISENSE_DFU_CONNECT_ATTEMPTS; + exports.VERISENSE_DFU_FAST_PACKET_DELAY_MS = VERISENSE_DFU_FAST_PACKET_DELAY_MS; + exports.VERISENSE_DFU_REBOOT_DELAY_MS = VERISENSE_DFU_REBOOT_DELAY_MS; + exports.VERISENSE_DFU_RELIABLE_PACKET_DELAY_MS = VERISENSE_DFU_RELIABLE_PACKET_DELAY_MS; + exports.VERISENSE_DFU_RETRY_DELAY_MS = VERISENSE_DFU_RETRY_DELAY_MS; + exports.VERISENSE_DFU_ROUTINE_LOG_REGEX = VERISENSE_DFU_ROUTINE_LOG_REGEX; + exports.VERISENSE_DFU_SET_MODE_TIMEOUT_MS = VERISENSE_DFU_SET_MODE_TIMEOUT_MS; + exports.VERISENSE_DFU_TRANSIENT_ERROR_REGEX = VERISENSE_DFU_TRANSIENT_ERROR_REGEX; + exports.VERISENSE_HW_MAJOR_FRIENDLY_NAMES = VERISENSE_HW_MAJOR_FRIENDLY_NAMES; + exports.VERISENSE_MAX_PLAUSIBLE_UNIX_SECONDS = VERISENSE_MAX_PLAUSIBLE_UNIX_SECONDS; + exports.VERISENSE_OPERATIONAL_FIELD_FALLBACK_GROUP_ID = VERISENSE_OPERATIONAL_FIELD_FALLBACK_GROUP_ID; + exports.VERISENSE_OPERATIONAL_FIELD_GROUPS = VERISENSE_OPERATIONAL_FIELD_GROUPS; + exports.VERISENSE_OPERATIONAL_FIELD_GROUP_SENSOR = VERISENSE_OPERATIONAL_FIELD_GROUP_SENSOR; + exports.VERISENSE_OPERATIONAL_FIELD_SCHEMA = VERISENSE_OPERATIONAL_FIELD_SCHEMA; + exports.VERISENSE_OP_CONFIG_BYTE_SIZE = VERISENSE_OP_CONFIG_BYTE_SIZE; + exports.VERISENSE_SENSOR_ENABLE_FIELDS = VERISENSE_SENSOR_ENABLE_FIELDS; + exports.VERISENSE_SENSOR_RATE_DEFAULT_GROUPS = VERISENSE_SENSOR_RATE_DEFAULT_GROUPS; + exports.VERISENSE_STREAM_SENSOR_LABELS = VERISENSE_STREAM_SENSOR_LABELS; + exports.VerisenseBleDevice = VerisenseBleDevice; + exports.applyDuplicateSuffix = applyDuplicateSuffix; + exports.applyImuCalibration = applyImuCalibration; + exports.asmRtcBytesToUnixSeconds = asmRtcBytesToUnixSeconds; + exports.asmRtcMinutesBytesToUnixSeconds = asmRtcMinutesBytesToUnixSeconds; + exports.buildDefaultVerisenseCalibrationSet = buildDefaultVerisenseCalibrationSet; + exports.buildHeader = buildHeader; + exports.buildMessage = buildMessage; + exports.buildParsedCsvFileName = buildParsedCsvFileName; + exports.buildProductionConfigPayload = buildProductionConfigPayload; + exports.buildUploadBinaryFileName = buildUploadBinaryFileName; + exports.buildVerisenseAdvertisedName = buildVerisenseAdvertisedName; + exports.buildVerisenseDfuRequestDeviceOptions = buildVerisenseDfuRequestDeviceOptions; + exports.calibTsBytesToUnixSeconds = calibTsBytesToUnixSeconds; + exports.calibrateGsrDataToResistanceFromAmplifierEq = calibrateGsrDataToResistanceFromAmplifierEq; + exports.calibrateShimmer3RAdcChannel = calibrateShimmer3RAdcChannel; + exports.calibrateU12AdcValue = calibrateU12AdcValue; + exports.calibrationBlobCrc = calibrationBlobCrc; + exports.classifyVerisenseDfuError = classifyVerisenseDfuError; + exports.compareVerisenseFirmwareVersion = compareVerisenseFirmwareVersion; + exports.computeVerisensePairingPin = computeVerisensePairingPin; + exports.crc16_ccitt_false = crc16_ccitt_false; + exports.createBlankVerisenseOperationalConfig = createBlankVerisenseOperationalConfig; + exports.csvCell = csvCell; + exports.decodeVerisenseBleOptimizationResult = decodeVerisenseBleOptimizationResult; + exports.defaultVerisensePasskeyForId = defaultVerisensePasskeyForId; + exports.deriveVerisenseMacIdFromName = deriveVerisenseMacIdFromName; + exports.describeVerisenseChargerStatus = describeVerisenseChargerStatus; + exports.enforceVerisenseCommsChannelInterlock = enforceVerisenseCommsChannelInterlock; + exports.evaluateParsedFileSplit = evaluateParsedFileSplit; + exports.expectedVerisenseStreamSensorIds = expectedVerisenseStreamSensorIds; + exports.expectedVerisenseStreamSensorIdsFromConfig = expectedVerisenseStreamSensorIdsFromConfig; + exports.formatByteArrayAsHex = formatByteArrayAsHex; + exports.formatByteAsHex = formatByteAsHex; + exports.formatPendingEventProperties = formatPendingEventProperties; + exports.formatSchedulerPayloadForLog = formatSchedulerPayloadForLog; + exports.formatStatusPayloadForLog = formatStatusPayloadForLog; + exports.formatVerisenseChargerStatus = formatVerisenseChargerStatus; + exports.formatVerisenseFirmwareVersion = formatVerisenseFirmwareVersion; + exports.formatVerisenseHardwareRevision = formatVerisenseHardwareRevision; + exports.formatVerisenseUnixAndHuman = formatVerisenseUnixAndHuman; + exports.getFirstPayloadIndex = getFirstPayloadIndex; + exports.getOversamplingRatioADS1292R = getOversamplingRatioADS1292R; + exports.getVerisenseCalibrationSensorAvailability = getVerisenseCalibrationSensorAvailability; + exports.getVerisenseCalibrationSensors = getVerisenseCalibrationSensors; + exports.getVerisenseHardwareCapabilities = getVerisenseHardwareCapabilities; + exports.getVerisenseHardwareFriendlyName = getVerisenseHardwareFriendlyName; + exports.getVerisenseHardwareRevision = getVerisenseHardwareRevision; + exports.getVerisenseHardwareSensorSupport = getVerisenseHardwareSensorSupport; + exports.getVerisenseStreamSensorLabel = getVerisenseStreamSensorLabel; + exports.getVerisenseStreamingBatteryVoltageMultiplier = getVerisenseStreamingBatteryVoltageMultiplier; + exports.getVerisenseSupportedOperationalFieldGroupIds = getVerisenseSupportedOperationalFieldGroupIds; + exports.hhmmToMinutesSinceMidnight = hhmmToMinutesSinceMidnight; + exports.inferVerisenseChargerChipFamily = inferVerisenseChargerChipFamily; + exports.inferVerisenseLookupBankCount = inferVerisenseLookupBankCount; + exports.isAckCommand = isAckCommand; + exports.isNackCommand = isNackCommand; + exports.isRoutineVerisenseDfuLogMessage = isRoutineVerisenseDfuLogMessage; + exports.isSafeFirmwareArchiveName = isSafeFirmwareArchiveName; + exports.isUniformByteArray = isUniformByteArray; + exports.isVerisenseGsrSupportedHardware = isVerisenseGsrSupportedHardware; + exports.isVerisenseLightDarkChannelEnabled = isVerisenseLightDarkChannelEnabled; + exports.isVerisenseSecondGenerationHardware = isVerisenseSecondGenerationHardware; + exports.minutesSinceMidnightToHHMM = minutesSinceMidnightToHHMM; + exports.nextAvailableDuplicateFileName = nextAvailableDuplicateFileName; + exports.normalizeBytePayload = normalizeBytePayload; + exports.normalizeOperationalConfig = normalizeOperationalConfig; + exports.nudgeGsrResistance = nudgeGsrResistance; + exports.padVerisenseOperationalConfig = padVerisenseOperationalConfig; + exports.parseBleLinkDebugPayload = parseBleLinkDebugPayload; + exports.parseCalibrationBlob = parseCalibrationBlob; + exports.parseEventLogPayload = parseEventLogPayload; + exports.parseHeader = parseHeader; + exports.parseHexByteString = parseHexByteString; + exports.parseLookupTablePayload = parseLookupTablePayload; + exports.parseMessage = parseMessage; + exports.parsePayloadCrcErrorBankIndexes = parsePayloadCrcErrorBankIndexes; + exports.parsePendingEvents = parsePendingEvents; + exports.parseProductionConfigPayload = parseProductionConfigPayload; + exports.parseProductionConfigPayloadFull = parseProductionConfigPayloadFull; + exports.parseRecordBufferDetailsPayload = parseRecordBufferDetailsPayload; + exports.parseSchedulerDebugPayload = parseSchedulerDebugPayload; + exports.parseStatusPayload = parseStatusPayload; + exports.parseVerisenseAdvertisedName = parseVerisenseAdvertisedName; + exports.patchSecureDfuSendOperation = patchSecureDfuSendOperation; + exports.promiseWithTimeout = promiseWithTimeout; + exports.readVerisenseOperationalFieldValue = readVerisenseOperationalFieldValue; + exports.resolveVerisenseSensorRateFieldKey = resolveVerisenseSensorRateFieldKey; + exports.runVerisenseDfuUpdate = runVerisenseDfuUpdate; + exports.serializeCalibrationBlob = serializeCalibrationBlob; + exports.setVerisenseDfuModeWithRetry = setVerisenseDfuModeWithRetry; + exports.setVerisenseOperationalBitRange = setVerisenseOperationalBitRange; + exports.supportsVerisenseCalibration = supportsVerisenseCalibration; + exports.supportsVerisenseMagnetometer = supportsVerisenseMagnetometer; + exports.unixSecondsToAsmRtcBytes = unixSecondsToAsmRtcBytes; + exports.unixSecondsToCalibTsBytes = unixSecondsToCalibTsBytes; + exports.updateVerisenseDfuImageWithRetry = updateVerisenseDfuImageWithRetry; + exports.verisenseDeviceFileTag = verisenseDeviceFileTag; + exports.verisenseDfuAttemptLabel = verisenseDfuAttemptLabel; + exports.writeVerisenseOperationalFieldValue = writeVerisenseOperationalFieldValue; + +})); +//# sourceMappingURL=shimmer-web-sdk.umd.js.map diff --git a/Verisense/vendor/shimmer-web-sdk.umd.js.map b/Verisense/vendor/shimmer-web-sdk.umd.js.map new file mode 100644 index 0000000..f0f0b01 --- /dev/null +++ b/Verisense/vendor/shimmer-web-sdk.umd.js.map @@ -0,0 +1 @@ +{"version":3,"file":"shimmer-web-sdk.umd.js","sources":["../src/core/ObjectCluster.ts","../src/core/BaseShimmerClient.ts","../src/core/arrayBuffer.ts","../src/core/csv.ts","../src/core/RtcDriftMonitor.ts","../src/core/StreamStats.ts","../src/devices/shimmer3r/constants.ts","../src/devices/shimmer3r/SensorBitmap.ts","../src/devices/shimmer3r/channelFormats.ts","../src/devices/shimmer3r/calibration.ts","../src/devices/shimmer3r/protocol.ts","../src/devices/shimmer3r/Shimmer3RClient.ts","../src/devices/verisense/constants.ts","../src/devices/verisense/protocolUtils.ts","../src/devices/verisense/calibration.ts","../src/devices/verisense/protocolMessage.ts","../src/devices/verisense/protocolDataFlow.ts","../src/devices/verisense/hardwareModels.ts","../src/devices/verisense/operationalConfig.ts","../src/devices/verisense/sensors/SensorBase.ts","../src/devices/verisense/sensors/SensorADC.ts","../src/devices/verisense/sensors/SensorLIS2DW12.ts","../src/devices/verisense/sensors/SensorLSM6DS3.ts","../src/devices/verisense/sensors/SensorLSM6DSV.ts","../src/devices/verisense/sensors/SensorPPG.ts","../src/devices/verisense/sensors/SensorVD6283.ts","../src/devices/verisense/sensors/SensorMAX32674.ts","../src/devices/verisense/sensors/SensorMLX90632.ts","../src/devices/verisense/requestValidation.ts","../src/devices/verisense/VerisenseClient.ts","../src/devices/verisense/dfu.ts","../src/devices/verisense/calibrationDefaults.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null],"names":["u16le","u24le"],"mappings":"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"} \ No newline at end of file diff --git a/Verisense/verisense.js b/Verisense/verisense.js deleted file mode 100644 index 0b5b1fb..0000000 --- a/Verisense/verisense.js +++ /dev/null @@ -1,1854 +0,0 @@ -/** - * Verisense (Web Bluetooth) – single-file JS class - * - Connects to Verisense over Nordic UART Service (NUS) - * - Supports command requests + streaming reassembly - * - Decodes sensors: GSR (id=1), LIS2DW12 accel (id=2), LSM6DS3 accel/gyro (id=3), PPG (id=4) - * - * Notes: - * - Web Bluetooth requires HTTPS + a user gesture (e.g., button click). - * - This mirrors the C# streaming shape: [hdr][lenLE16] + payload chunks, - * where payload starts with: [sensorId][tick u24][sensorPayload...][optional CRC16]. - */ - -class TinyEmitter { - constructor() { this._m = new Map(); } - on(ev, fn) { if (!this._m.has(ev)) this._m.set(ev, new Set()); this._m.get(ev).add(fn); return () => this.off(ev, fn); } - off(ev, fn) { const s = this._m.get(ev); if (s) s.delete(fn); } - emit(ev, data) { const s = this._m.get(ev); if (s) for (const fn of s) fn(data); } -} - -function parseProductionConfigPayload(response) { - const isAllFFs = (arr) => arr.every(b => b === 255); - - const configHeader = response[0]; - - const asmid = [...response.slice(1, 7)].reverse() - .map(b => b.toString(16).padStart(2, '0')).join(''); - - const revHwMajor = response[7]; - const revHwMinor = response[8]; - - const revFwMajor = response[9]; - const revFwMinor = response[10]; - - const fwInternalArray = response.slice(11, 13); - const revFwInternal = fwInternalArray[0] | (fwInternalArray[1] << 8); - - let revHwInternal = 0; - - if (response.length >= 15) { - const hwInternalArray = response.slice(13, 15); - if (!isAllFFs(hwInternalArray)) { - revHwInternal = hwInternalArray[0] | (hwInternalArray[1] << 8); - } - } - - return { - hardware: `${revHwMajor}.${revHwMinor}.${revHwInternal}`, - firmware: `${revFwMajor}.${revFwMinor}.${revFwInternal}`, - asmid: asmid.toUpperCase(), - configHeader: configHeader - }; -} - -function normalizeOperationalConfig(payload) { - if (!payload) return null; - if (payload instanceof Uint8Array) return payload; - if (payload instanceof ArrayBuffer) return new Uint8Array(payload); - if (Array.isArray(payload)) return new Uint8Array(payload); - // DataView / TypedArray - if (payload.buffer) return new Uint8Array(payload.buffer, payload.byteOffset ?? 0, payload.byteLength ?? payload.buffer.byteLength); - throw new Error("normalizeOperationalConfig: unsupported payload type"); -} - -const OP_IDX = Object.freeze({ - GEN_CFG_0: 1, - GEN_CFG_1: 2, - GEN_CFG_2: 3, - GEN_CFG_3: 4, - - ACCEL1_CFG_0: 5, - ACCEL1_CFG_1: 6, - ACCEL1_CFG_2: 7, - ACCEL1_CFG_3: 8, - - GYRO_ACCEL2_CFG_0: 10, - GYRO_ACCEL2_CFG_1: 11, - GYRO_ACCEL2_CFG_2: 12, - GYRO_ACCEL2_CFG_3: 13, - GYRO_ACCEL2_CFG_4: 14, - GYRO_ACCEL2_CFG_5: 15, - GYRO_ACCEL2_CFG_6: 16, - GYRO_ACCEL2_CFG_7: 17, - - START_TIME: 21, - END_TIME: 25, - INACTIVE_TIMEOUT: 29, - BLE_RETRY_COUNT: 30, - BLE_TX_POWER: 31, - BLE_DATA_TRANS_WKUP_INT_HRS: 32, - BLE_DATA_TRANS_WKUP_TIME: 33, - BLE_DATA_TRANS_WKUP_DUR: 35, - BLE_DATA_TRANS_RETRY_INT: 36, - BLE_STATUS_WKUP_INT_HRS: 38, - BLE_STATUS_WKUP_TIME: 39, - BLE_STATUS_WKUP_DUR: 41, - BLE_STATUS_RETRY_INT: 42, - BLE_RTC_SYNC_WKUP_INT_HRS: 44, - BLE_RTC_SYNC_WKUP_TIME: 45, - BLE_RTC_SYNC_WKUP_DUR: 47, - BLE_RTC_SYNC_RETRY_INT: 48, - - ADC_CHANNEL_SETTINGS_0: 50, - ADC_CHANNEL_SETTINGS_1: 51, - ADAPTIVE_SCHEDULER_INT: 52, - ADAPTIVE_SCHEDULER_FAILCOUNT_MAX: 54, - PPG_REC_DUR_SECS_LSB: 55, - PPG_REC_DUR_SECS_MSB: 56, - PPG_REC_INT_MINS_LSB: 57, - PPG_REC_INT_MINS_MSB: 58, - PPG_FIFO_CONFIG: 59, - PPG_MODE_CONFIG2: 60, - PPG_MA_DEFAULT: 61, - PPG_MA_MAX_RED_IR: 62, - PPG_MA_MAX_GREEN_BLUE: 63, - PPG_AGC_TARGET_PERCENT_OF_RANGE: 64, - PPG_MA_LED_PILOT: 66, - PPG_DAC1_CROSSTALK: 67, - PPG_DAC2_CROSSTALK: 68, - PPG_DAC3_CROSSTALK: 69, - PPG_DAC4_CROSSTALK: 70, - PROX_AGC_MODE: 71 -}); - -const READ_DATA_REQ = new Uint8Array([0x12, 0x00, 0x00]); -const DISCONNECT_REQ = new Uint8Array([0x2B, 0x00, 0x00]); -const DATA_ACK = new Uint8Array([0x82, 0x00, 0x00]); -const DATA_NACK = new Uint8Array([0x72, 0x00, 0x00]); -const DATA_EOS_HDR = 0x42; - -function u16le_at(bytes, off) { - return (bytes[off] | (bytes[off + 1] << 8)) >>> 0; -} - -function getOriginalCrcLE(payload) { - const n = payload.length; - return (payload[n - 2] | (payload[n - 1] << 8)) >>> 0; -} - -function computeCrcLikeCSharp(payload) { - // C# ComputeCRC iterates to length-2 (excludes CRC bytes) - const n = payload.length; - const data = payload.subarray(0, n - 2); - return crc16_ccitt_false(data); -} - -// safe byte getter -function b(op, idx) { - if (!op || idx == null) return null; - if (idx < 0 || idx >= op.length) return null; - return op[idx] & 0xFF; -} - -function u16le(b0, b1) { return (b1 << 8) | b0; } -function i16le(bytes, off) { - const v = (bytes[off] | (bytes[off + 1] << 8)); - return (v & 0x8000) ? v - 0x10000 : v; -} -function u24le(bytes, off) { return (bytes[off] | (bytes[off + 1] << 8) | (bytes[off + 2] << 16)) >>> 0; } -function nowMillis() { return Date.now(); } - -function crc16_ccitt_false(bytes) { - // CRC-16/CCITT-FALSE: poly 0x1021, init 0xFFFF, xorOut 0x0000 - let crc = 0xFFFF; - for (let i = 0; i < bytes.length; i++) { - crc ^= (bytes[i] << 8); - for (let b = 0; b < 8; b++) { - crc = (crc & 0x8000) ? ((crc << 1) ^ 0x1021) : (crc << 1); - crc &= 0xFFFF; - } - } - return crc & 0xFFFF; -} - -// ---------- base sensor (timestamp unwrap + extrapolation) ---------- -class SensorBase { - // matches Sensor.cs - static CLOCK_FREQ = 32768; // ticks/sec - static TICKS_MAX_VALUE = 60 * 32768; // 1 minute rollover - - constructor() { - this.lastTicksUnwrapped = 0; - this.cycle = 0; - this.systemOffsetFirstTime = null; // systemMillis - shimmerMillis - this.samplingRateHz = null; // optional, for extrapolation - } - - resetTimestamps() { - this.lastTicksUnwrapped = 0; - this.cycle = 0; - this.systemOffsetFirstTime = null; - } - - unwrapTicks(ticks) { - let unwrapped = ticks + (SensorBase.TICKS_MAX_VALUE * this.cycle); - if (this.lastTicksUnwrapped > unwrapped) { - this.cycle += 1; - unwrapped = ticks + (SensorBase.TICKS_MAX_VALUE * this.cycle); - } - this.lastTicksUnwrapped = unwrapped; - return unwrapped; - } - - ticksToMillis(unwrappedTicks) { - // ticks/sec = 32768 => ticks per ms = 32.768 - return (unwrappedTicks / SensorBase.CLOCK_FREQ) * 1000.0; - } - - getTimestampUnwrappedMillis(lastSampleTicksU24, systemMillis) { - const unwrappedTicks = this.unwrapTicks(lastSampleTicksU24); - const shimmerMillis = this.ticksToMillis(unwrappedTicks); - - // store first-time system offset - if (this.systemOffsetFirstTime == null) { - this.systemOffsetFirstTime = systemMillis - shimmerMillis; - } - return { shimmerMillis, systemOffsetFirstTime: this.systemOffsetFirstTime }; - } - - extrapolateSampleTimes({ - numSamples, - i, // 0..numSamples-1 - samplingRateHz, - tsLastSampleMillis, - systemTsLastSampleMillis, - systemOffsetFirstTime - }) { - const sr = samplingRateHz ?? this.samplingRateHz; - if (!sr || sr <= 0) { - return { - tsMillis: tsLastSampleMillis, - systemTsMillis: systemTsLastSampleMillis, - systemTsPlotMillis: (systemOffsetFirstTime != null) - ? tsLastSampleMillis + systemOffsetFirstTime - : systemTsLastSampleMillis - }; - } - const sampleOffsetSec = (numSamples - i - 1) / sr; - const tsMillis = tsLastSampleMillis - (sampleOffsetSec * 1000); - const systemTsMillis = systemTsLastSampleMillis - (sampleOffsetSec * 1000); - const systemTsPlotMillis = (systemOffsetFirstTime != null) - ? tsMillis + systemOffsetFirstTime - : systemTsMillis; - return { tsMillis, systemTsMillis, systemTsPlotMillis }; - } -} - -// ---------- sensor: LIS2DW12 accel (id=2) ---------- -class SensorLIS2DW12 extends SensorBase { - constructor() { - super(); - // from SensorLIS2DW12.cs - this.offset = [0, 0, 0]; - this.align = [ - [0, 0, 1], - [1, 0, 0], - [0, 1, 0] - ]; - this.sensitivityByRange = { - "2G": [1671.665922915, 1671.665922915, 1671.665922915], - "4G": [835.832961457, 835.832961457, 835.832961457], - "8G": [417.916480729, 417.916480729, 417.916480729], - "16G": [208.958240364, 208.958240364, 208.958240364] - }; - this.range = "2G"; // default - this.samplingRateHz = 50; // set this to your actual config - } - - setRange(rangeStr /* "2G"|"4G"|"8G"|"16G" */) { - if (this.sensitivityByRange[rangeStr]) this.range = rangeStr; - } - - // --- OpConfig patch helpers (functional style) --- - // Usage: newOp = sensor.setEnabled(true, currentOp) - // (returns a *new* Uint8Array; does not mutate input) - setEnabled(enabled, opConfigBytes) { - // If called without op bytes, just set local decoder state - if (opConfigBytes == null) { - this.enabled = !!enabled; - return this.enabled; - } - if (typeof OP_IDX === "undefined" || OP_IDX.GEN_CFG_0 == null) { - throw new Error("OP_IDX.GEN_CFG_0 not defined; cannot patch accel1 enable"); - } - const op = normalizeOperationalConfig(opConfigBytes); - const out = new Uint8Array(op); // clone - const idx = OP_IDX.GEN_CFG_0; - - if (!!enabled) out[idx] = (out[idx] | 0x80) & 0xFF; // bit7 = enable - else out[idx] = (out[idx] & 0x7F) & 0xFF; - - return out; - } - - // alias for readability - setAccelEnabled(enabled, opConfigBytes) { - return this.setEnabled(enabled, opConfigBytes); - } - - - _calibrate(raw) { - // CalibrateInertialSensorData( raw, ALIGN, SENS, OFFSET ) - const v = [ - raw[0] - this.offset[0], - raw[1] - this.offset[1], - raw[2] - this.offset[2] - ]; - // alignment matrix multiply: out = A * v - const a = this.align; - const aligned = [ - a[0][0]*v[0] + a[0][1]*v[1] + a[0][2]*v[2], - a[1][0]*v[0] + a[1][1]*v[1] + a[1][2]*v[2], - a[2][0]*v[0] + a[2][1]*v[1] + a[2][2]*v[2], - ]; - const s = this.sensitivityByRange[this.range]; - return [ aligned[0] / s[0], aligned[1] / s[1], aligned[2] / s[2] ]; // m/s^2 - } - - parsePayload(sensorPayloadBytes) { - // sample = 6 bytes: x,y,z int16 LE per sample - const BYTES_PER_SAMPLE = 6; - const n = Math.floor(sensorPayloadBytes.length / BYTES_PER_SAMPLE); - const out = []; - for (let i = 0; i < n; i++) { - const off = i * BYTES_PER_SAMPLE; - const raw = [ - i16le(sensorPayloadBytes, off + 0), - i16le(sensorPayloadBytes, off + 2), - i16le(sensorPayloadBytes, off + 4), - ]; - const cal = this._calibrate(raw); - out.push({ raw, cal, units: { cal: "m/s^2" } }); - } - return out; - } - - // inside SensorLIS2DW12 class - - patchAccelRange(rangeCfg /*0..3*/, op) { - const out = new Uint8Array(op); - const i = OP_IDX.ACCEL1_CFG_1; - out[i] = (out[i] & 0b11001111) | ((rangeCfg & 0x03) << 4); // :contentReference[oaicite:9]{index=9} - return out; - } - - patchAccelSamplingRate(rateCfg /*0..15*/, op) { - const out = new Uint8Array(op); - const i = OP_IDX.ACCEL1_CFG_0; - out[i] = (out[i] & 0b00001111) | ((rateCfg & 0x0F) << 4); // :contentReference[oaicite:10]{index=10} - return out; - } - - applyOperationalConfig(op) { - console.log("[LIS2DW12] applyOperationalConfig()"); - console.log("[LIS2DW12] op len =", op?.length, "op[0]=", op ? `0x${op[0].toString(16)}` : "(null)"); - console.log("GEN_CFG_0", OP_IDX.GEN_CFG_0); - console.log("ACCEL1_CFG_0", OP_IDX.ACCEL1_CFG_0); - console.log("ACCEL1_CFG_1", OP_IDX.ACCEL1_CFG_1); - console.log("ACCEL1_CFG_2", OP_IDX.ACCEL1_CFG_2); - - const gen0 = b(op, OP_IDX.GEN_CFG_0); - const cfg0 = b(op, OP_IDX.ACCEL1_CFG_0); - const cfg1 = b(op, OP_IDX.ACCEL1_CFG_1); - - if (gen0 == null || cfg0 == null || cfg1 == null) { - console.warn("[LIS2DW12] Missing required bytes; cannot apply config."); - return; - } - - this.enabled = ((gen0 >> 7) & 0x01) === 1; - - const rangeSetting = (cfg1 >> 4) & 0x03; - const modeSetting = (cfg0 >> 2) & 0x03; - const rateSetting = (cfg0 >> 4) & 0x0F; - - console.log("[LIS2DW12] decoded bits:", { - enabled: this.enabled, - rangeSetting, - modeSetting, - rateSetting - }); - - const rangeMap = { 0: "2G", 1: "4G", 2: "8G", 3: "16G" }; - const nextRange = rangeMap[rangeSetting] ?? "2G"; - const prevRange = this.range; - - this.setRange(nextRange); - - const lowPowerHzByCfg = { 1: 1.6, 2: 12.5, 3: 25, 4: 50, 5: 100, 6: 200 }; - const highPerfHzByCfg = { 1: 12.5, 3: 25, 4: 50, 5: 100, 6: 200, 7: 400, 8: 800, 9: 1600 }; - - const isLowPower = (modeSetting === 0); - const hz = isLowPower ? lowPowerHzByCfg[rateSetting] : highPerfHzByCfg[rateSetting]; - const prevHz = this.samplingRateHz; - - if (hz) this.samplingRateHz = hz; - - console.log("[LIS2DW12] applied:", { - prevRange, nextRange: this.range, - prevHz, nextHz: this.samplingRateHz, - isLowPower - }); -} -} - -// ---------- sensor: LSM6DS3 accel/gyro (id=3) ---------- -class SensorLSM6DS3 extends SensorBase { - constructor() { - super(); - // from SensorLSM6DS3.cs - this.offset = [0, 0, 0]; - this.align = [ - [0, 0, 1], - [-1, 0, 0], - [0, -1, 0] - ]; - - // LSB per unit (diagonal), so unit = raw / diag - this.accSensByRange = { - "2G": [1671.665922915, 1671.665922915, 1671.665922915], - "4G": [835.832961457, 835.832961457, 835.832961457], - "8G": [417.916480729, 417.916480729, 417.916480729], - "16G": [208.958240364, 208.958240364, 208.958240364] - }; - this.gyroSensByRange = { - "250DPS": [114.285714286, 114.285714286, 114.285714286], - "500DPS": [57.142857143, 57.142857143, 57.142857143], - "1000DPS": [28.571428571, 28.571428571, 28.571428571], - "2000DPS": [14.285714286, 14.285714286, 14.285714286] - }; - - this.accRange = "2G"; - this.gyroRange = "250DPS"; - this.accEnabled = true; - this.gyroEnabled = true; - this.samplingRateHz = 50; // set to your actual config - - - - - } - - setAccelEnabled(v) { this.accEnabled = !!v; } - setGyroEnabled(v) { this.gyroEnabled = !!v; } - setAccelRange(r) { if (this.accSensByRange[r]) this.accRange = r; } - setGyroRange(r) { if (this.gyroSensByRange[r]) this.gyroRange = r; } - - _applyAlignAndOffset(raw3) { - const v = [ - raw3[0] - this.offset[0], - raw3[1] - this.offset[1], - raw3[2] - this.offset[2] - ]; - const a = this.align; - return [ - a[0][0]*v[0] + a[0][1]*v[1] + a[0][2]*v[2], - a[1][0]*v[0] + a[1][1]*v[1] + a[1][2]*v[2], - a[2][0]*v[0] + a[2][1]*v[1] + a[2][2]*v[2], - ]; - } - - parsePayload(sensorPayloadBytes) { - // C# layout: - // - If gyro && accel enabled: accel is at +6, gyro at +0 (so bytes/sample=12) - // - Else: accel alone => 6, gyro alone => 6 - let bytesPerSample = 6; - if (this.gyroEnabled && this.accEnabled) bytesPerSample = 12; - - const n = Math.floor(sensorPayloadBytes.length / bytesPerSample); - const out = []; - - for (let i = 0; i < n; i++) { - const base = i * bytesPerSample; - - let gyroRaw = null, gyroCal = null; - let accRaw = null, accCal = null; - - if (this.gyroEnabled && this.accEnabled) { - gyroRaw = [ i16le(sensorPayloadBytes, base + 0), i16le(sensorPayloadBytes, base + 2), i16le(sensorPayloadBytes, base + 4) ]; - accRaw = [ i16le(sensorPayloadBytes, base + 6), i16le(sensorPayloadBytes, base + 8), i16le(sensorPayloadBytes, base + 10) ]; - } else if (this.gyroEnabled) { - gyroRaw = [ i16le(sensorPayloadBytes, base + 0), i16le(sensorPayloadBytes, base + 2), i16le(sensorPayloadBytes, base + 4) ]; - } else if (this.accEnabled) { - accRaw = [ i16le(sensorPayloadBytes, base + 0), i16le(sensorPayloadBytes, base + 2), i16le(sensorPayloadBytes, base + 4) ]; - } - - if (accRaw) { - const aligned = this._applyAlignAndOffset(accRaw); - const s = this.accSensByRange[this.accRange]; - accCal = [ aligned[0]/s[0], aligned[1]/s[1], aligned[2]/s[2] ]; - } - if (gyroRaw) { - const aligned = this._applyAlignAndOffset(gyroRaw); - const s = this.gyroSensByRange[this.gyroRange]; - gyroCal = [ aligned[0]/s[0], aligned[1]/s[1], aligned[2]/s[2] ]; - } - - out.push({ - accel: accRaw ? { raw: accRaw, cal: accCal, units: "m/s^2" } : null, - gyro: gyroRaw ? { raw: gyroRaw, cal: gyroCal, units: "deg/s" } : null - }); - } - return out; - } - - applyOperationalConfig(op) { - // Enabled flags (GEN_CFG_0 bit6 accel2, bit5 gyro) :contentReference[oaicite:10]{index=10} - this.accEnabled = (op[OP_IDX.GEN_CFG_0] & 0b01000000) !== 0; - this.gyroEnabled = (op[OP_IDX.GEN_CFG_0] & 0b00100000) !== 0; - - // Sampling rate nibble(s) live in GYRO_ACCEL2_CFG_4 (accel hi nibble, gyro low nibble) - const cfg4 = op[OP_IDX.GYRO_ACCEL2_CFG_4]; - const accelRateCfg = (cfg4 >> 4) & 0x0F; - const gyroRateCfg = (cfg4 >> 0) & 0x0F; - - // Config-value -> Hz mapping (match your SamplingRate.Settings) - const hzByCfg = { - 0: null, - 1: 12.5, - 2: 26, - 3: 52, - 4: 104, - 5: 208, - 6: 416, - 7: 833, - 8: 1660 - }; - - // Range bits live in GYRO_ACCEL2_CFG_5 - const cfg5 = op[OP_IDX.GYRO_ACCEL2_CFG_5]; - const accelRangeCfg = (cfg5 >> 2) & 0x03; // :contentReference[oaicite:11]{index=11} - const gyroRangeCfg = (cfg5 >> 4) & 0x03; // :contentReference[oaicite:12]{index=12} - - const accelRangeMap = { 0: "2G", 1: "4G", 2: "8G", 3: "16G" }; - const gyroRangeMap = { 0: "250DPS", 1: "500DPS", 2: "1000DPS", 3: "2000DPS" }; - - this.setAccelRange(accelRangeMap[accelRangeCfg] ?? this.accRange); - this.setGyroRange(gyroRangeMap[gyroRangeCfg] ?? this.gyroRange); - - // In your C# there’s effectively “one ODR”, but accel/gyro fields exist; pick accel as main - const hz = hzByCfg[accelRateCfg] ?? hzByCfg[gyroRateCfg]; - if (hz) this.samplingRateHz = hz; - } -} - -// ---------- sensor: PPG (id=4) ---------- -class SensorPPG extends SensorBase { - constructor() { - super(); - // enabled channels - this.red = false; - this.ir = false; - this.green = false; - this.blue = false; - - // from SensorPPG.cs - this.adcLsb = [7.8125, 15.625, 31.25, 62.5]; - this.adcBitShift = [2 ** 7, 2 ** 6, 2 ** 5, 2 ** 4]; - this.adcResolutionIndex = 0; // 0..3 - - this.samplingRateHz = 50; // set to your actual config - } - - setChannels({ red, ir, green, blue }) { - if (typeof red === "boolean") this.red = red; - if (typeof ir === "boolean") this.ir = ir; - if (typeof green === "boolean") this.green = green; - if (typeof blue === "boolean") this.blue = blue; - } - - setAdcResolutionIndex(i /*0..3*/) { - if (i >= 0 && i <= 3) this.adcResolutionIndex = i; - } - - calibrateValue(uncalValue) { - // C#: - // cal = (uncal / bitShift[idx]) * lsb[idx] / 1000 - const idx = this.adcResolutionIndex; - return (uncalValue / this.adcBitShift[idx]) * this.adcLsb[idx] / 1000.0; - } - - parsePayload(sensorPayloadBytes) { - // Element order in C#: - // 1 PPG_RED, 2 PPG_IR, 3 PPG_GREEN, 4 PPG_BLUE - const enabled = []; - if (this.red) enabled.push("RED"); - if (this.ir) enabled.push("IR"); - if (this.green) enabled.push("GREEN"); - if (this.blue) enabled.push("BLUE"); - - const bytesPerSample = enabled.length * 3; - if (bytesPerSample === 0) return []; - - const n = Math.floor(sensorPayloadBytes.length / bytesPerSample); - const out = []; - - for (let i = 0; i < n; i++) { - const base = i * bytesPerSample; - let off = 0; - const sample = {}; - for (const ch of enabled) { - const b0 = sensorPayloadBytes[base + off + 0]; - const b1 = sensorPayloadBytes[base + off + 1]; - const b2 = sensorPayloadBytes[base + off + 2]; - off += 3; - - // 3-byte int, then mask 0x7FFFF like C# - let uncal = (b0 | (b1 << 8) | (b2 << 16)) >>> 0; - uncal &= 0x7FFFF; - - sample[ch] = { - raw: uncal, - cal: this.calibrateValue(uncal), - // C# stores "NanoAmpere" for CAL. Keep the numeric value + let you label it in UI. - units: { raw: "counts", cal: "scaled" } - }; - } - out.push(sample); - } - return out; - } - - -} - -// ---------- sensor: GSR (id=1) ---------- -class SensorGSR extends SensorBase { - constructor() { - super(); - // from SensorGSR.cs - this.LIMIT_MIN_VALID_USIEMENS = 0.03; - this.GSR_UNCAL_LIMIT_RANGE3_SR68 = 1134; - this.GSR_UNCAL_LIMIT_RANGE3_SR62 = 683; - - this.SHIMMER3_REF_KOHMS = [40.2, 287.0, 1000.0, 3300.0]; - this.SR68_REF_KOHMS = [21.0, 150.0, 562.0, 1740.0]; - - // user-config - this.gsrEnabled = true; - this.battEnabled = false; - this.gsrRangeSetting = 4; // 0..3 fixed, 4 auto (matches C#) - this.hardwareIdentifier = "VERISENSE_PULSE_PLUS"; // or "VERISENSE_GSR_PLUS" or other - - this.samplingRateHz = 50; // set to your actual config - } - - setHardwareIdentifier(idStr) { this.hardwareIdentifier = idStr; } - setEnabled(arg1, opConfigBytes) { - // Supports BOTH styles: - // 1) Legacy local flags: setEnabled({ gsr:true, batt:false }) - // 2) Functional opcfg patch: newOp = setEnabled(true, currentOp) - // or: newOp = setEnabled({ gsr:true, batt:false }, currentOp) - - // --- (2) functional style: returns a *new* Uint8Array --- - if (opConfigBytes != null) { - const desired = - (typeof arg1 === "boolean") ? { gsr: arg1 } : - (arg1 && typeof arg1 === "object") ? arg1 : - {}; - return this._patchEnabled(desired, opConfigBytes); - } - - // --- (1) legacy style: just updates local decoder flags --- - const obj = - (typeof arg1 === "boolean") ? { gsr: arg1 } : - (arg1 && typeof arg1 === "object") ? arg1 : - {}; - const { gsr, batt } = obj; - - if (typeof gsr === "boolean") this.gsrEnabled = gsr; - if (typeof batt === "boolean") this.battEnabled = batt; - - return { gsr: this.gsrEnabled, batt: this.battEnabled }; - } - - _patchEnabled({ gsr, batt } = {}, opConfigBytes) { - if (typeof OP_IDX === "undefined") { - throw new Error("OP_IDX not defined; cannot patch GSR enable bits"); - } - const op = normalizeOperationalConfig(opConfigBytes); - const out = new Uint8Array(op); // clone - - // GEN_CFG_1 bit7 = GSR enable (per your C#) - if (typeof gsr === "boolean") { - if (OP_IDX.GEN_CFG_1 == null) throw new Error("OP_IDX.GEN_CFG_1 missing"); - const idx = OP_IDX.GEN_CFG_1; - if (gsr) out[idx] = (out[idx] | 0x80) & 0xFF; - else out[idx] = (out[idx] & 0x7F) & 0xFF; - } - - // GEN_CFG_2 bit1 = Batt enable (per your C#) - if (typeof batt === "boolean") { - if (OP_IDX.GEN_CFG_2 == null) throw new Error("OP_IDX.GEN_CFG_2 missing"); - const idx = OP_IDX.GEN_CFG_2; - if (batt) out[idx] = (out[idx] | 0x02) & 0xFF; - else out[idx] = (out[idx] & 0xFD) & 0xFF; - } - - return out; - } - - patchGsrRange(rangeCfg /*0..4*/, op) { - const out = new Uint8Array(op); - const i = OP_IDX.ADC_CHANNEL_SETTINGS_1; - out[i] = (out[i] & 0b11111000) | (rangeCfg & 0x07); // :contentReference[oaicite:11]{index=11} - return out; - } - - patchGsrSamplingRate(rateCfg /*0..63*/, op) { - const out = new Uint8Array(op); - const i = OP_IDX.ADC_CHANNEL_SETTINGS_0; - out[i] = (out[i] & 0b11000000) | (rateCfg & 0x3F); // :contentReference[oaicite:12]{index=12} - return out; - } - - patchGsrOversampling(overCfg /*0..15*/, op) { - const out = new Uint8Array(op); - const i = OP_IDX.ADC_CHANNEL_SETTINGS_1; - out[i] = (out[i] & 0b00001111) | ((overCfg & 0x0F) << 4); // :contentReference[oaicite:13]{index=13} - return out; - - } - // Convenience aliases - setGSREnabled(enabled, opConfigBytes) { - return this.setEnabled(enabled, opConfigBytes); - } - setBattEnabled(enabled, opConfigBytes) { - return this.setEnabled({ batt: enabled }, opConfigBytes); - } - - - setGsrRangeSetting(v /*0..4*/) { this.gsrRangeSetting = v; } - - calibrateAdcToVolts(uncal12bit) { - // from VerisenseDevice.CalibrateADCValueToVolts - const adcRange = (2 ** 12) - 1; - let refVoltage = (1.8 / 4.0); - if (this.hardwareIdentifier === "VERISENSE_GSR_PLUS") { - refVoltage = (3.0 / 4.0); - } - const adcScaling = (1.0 / 4.0); - const adcOffset = 0; - return ((((uncal12bit - adcOffset) * refVoltage) / adcRange) / adcScaling); - } - - calibrateGsrToKOhmsUsingAmplifierEq(volts, range /*0..3*/) { - // from SensorGSR.CalibrateGsrDataToKOhmsUsingAmplifierEq - let rFeedback = this.SHIMMER3_REF_KOHMS[range]; - if (this.hardwareIdentifier === "VERISENSE_PULSE_PLUS") { - rFeedback = this.SR68_REF_KOHMS[range]; - } - let gsr_ref_voltage = 0.5; - if (this.hardwareIdentifier === "VERISENSE_PULSE_PLUS") { - gsr_ref_voltage = 0.4986; - } - const rSource = rFeedback / ((volts / gsr_ref_voltage) - 1.0); - return rSource; - } - - nudgeGsrResistance(kOhms) { - // approximate to the configured range limits (like UtilCalibration.NudgeDouble) - const limitsByRange = { - 0: [8.0, 63.0], - 1: [63.0, 220.0], - 2: [220.0, 680.0], - 3: [680.0, 4700.0], - 4: [8.0, 4700.0] - }; - const lim = limitsByRange[this.gsrRangeSetting] ?? [8.0, 4700.0]; - return Math.min(Math.max(kOhms, lim[0]), lim[1]); - } - - kOhmToUSiemens(kOhms) { return 1000.0 / kOhms; } - -// Operational Config → sensor settings (ported from C# SensorGSR.InitializeUsingOperationConfig) - applyOperationalConfig(op) { - console.log("gsr" + op); - if (!op) return; - - const gen1 = op[OP_IDX.GEN_CFG_1] ?? 0; - const gen2 = op[OP_IDX.GEN_CFG_2] ?? 0; - - // C#: if ((GEN_CFG_1 >> 7) == 1) GSREnabled = true; - this.gsrEnabled = ((gen1 >> 7) & 0x01) === 1; - - // C#: if ((GEN_CFG_2 & 0b00000010) > 1) BattEnabled = true; - this.battEnabled = (gen2 & 0b00000010) !== 0; - - // Rate/range/oversampling are stored for debugging (mapping tables can be added later) - const rateCfg = (op[OP_IDX.ADC_CHANNEL_SETTINGS_0] ?? 0) & 0x3F; - const cfg1 = (op[OP_IDX.ADC_CHANNEL_SETTINGS_1] ?? 0) & 0xFF; - const rangeCfg = cfg1 & 0x07; - const oversamplingCfg = (cfg1 >> 4) & 0x0F; - - this.gsrRateSettingRaw = rateCfg; - this.gsrRangeSettingRaw = rangeCfg; - this.gsrOversamplingRateSettingRaw = oversamplingCfg; - - // In C#, rangeCfg is mapped through GSRRange.Settings. In practice this is usually 0..4. - // We keep it conservative: accept 0..4, otherwise leave current setting unchanged. - if (rangeCfg >= 0 && rangeCfg <= 4) { - this.gsrRangeSetting = rangeCfg; - } - - // NOTE: samplingRateHz mapping is firmware/settings-table specific. - // We leave this.samplingRateHz as-is, but you can log rateCfg to build a table. - } - - parsePayload(sensorPayloadBytes) { - // sample is 2 bytes (GSR only) or 4 bytes (Batt + GSR), both int16 but only 12-bit ADC used - const bytesPerSample = (this.gsrEnabled && this.battEnabled) ? 4 : 2; - const n = Math.floor(sensorPayloadBytes.length / bytesPerSample); - const out = []; - - for (let i = 0; i < n; i++) { - const base = i * bytesPerSample; - - let batt = null; - let gsr = null; - - let gsrStart = 0; - let battStart = 0; - if (this.battEnabled && this.gsrEnabled) gsrStart = 2; - - if (this.gsrEnabled) { - const gsrraw = i16le(sensorPayloadBytes, base + gsrStart); - console.log("gsrraw: " + gsrraw); - let adc12 = (gsrraw & 0x0FFF); - - let currentRange = this.gsrRangeSetting; - if (currentRange === 4) { - currentRange = (gsrraw >> 14) & 0x03; // auto-range bits - } - - // range-3 clamp differs by hardware - if (currentRange === 3) { - if (this.hardwareIdentifier === "VERISENSE_PULSE_PLUS") { - if (adc12 < this.GSR_UNCAL_LIMIT_RANGE3_SR68) adc12 = this.GSR_UNCAL_LIMIT_RANGE3_SR68; - } else if (this.hardwareIdentifier === "VERISENSE_GSR_PLUS") { - if (adc12 < this.GSR_UNCAL_LIMIT_RANGE3_SR62) adc12 = this.GSR_UNCAL_LIMIT_RANGE3_SR62; - } - } - - const volts = this.calibrateAdcToVolts(adc12); - let kOhms = this.calibrateGsrToKOhmsUsingAmplifierEq(volts, currentRange); - kOhms = this.nudgeGsrResistance(kOhms); - const uS = this.kOhmToUSiemens(kOhms); - const connectivity = (uS > this.LIMIT_MIN_VALID_USIEMENS) ? "Connected" : "Disconnected"; - - gsr = { raw: gsrraw, adc12, range: currentRange, volts, kOhms, uS, connectivity }; - console.log(gsr); - } - - if (this.battEnabled) { - const braw = i16le(sensorPayloadBytes, base + battStart) & 0x0FFF; - // C# reports mV using CalibrateADCValueToMilliVolts - const mv = this.calibrateAdcToVolts(braw) * 1000.0; - batt = { raw: braw, mV: mv }; - } - - out.push({ gsr, batt }); - } - - return out; - } -} - -// ---------- Verisense device (Web Bluetooth) ---------- -export class VerisenseBleDevice extends TinyEmitter { - // NUS UUIDs (from your C#) - static NUS_SERVICE = "6e400001-b5a3-f393-e0a9-e50e24dcca9e"; - static NUS_TX = "6e400002-b5a3-f393-e0a9-e50e24dcca9e"; // write - static NUS_RX = "6e400003-b5a3-f393-e0a9-e50e24dcca9e"; // notify - - constructor({ - hardwareIdentifier = "VERISENSE_PULSE_PLUS", - stripStreamCrc = true, - verifyStreamCrc = false - } = {}) { - super(); - this.hardwareIdentifier = hardwareIdentifier; - this._sync = null; - this._rxStreamBuf = new Uint8Array(0); - - // ---- transport ---- - // Default: BLE (Web Bluetooth). Optional: USB serial (Web Serial). - this._transportKind = null; // 'ble' | 'serial' - this.port = null; // Web Serial port (if using serial) - this._serialAbort = null; // AbortController for read loop - this._onGattDisconnected = null; // stored BLE disconnect handler - - this.device = null; - this.server = null; - this.service = null; - this.tx = null; - this.rx = null; - this.debugSync = true; - this._syncRxCount = 0; - this._syncPayloadCount = 0; - - this._loggedChain = Promise.resolve(); - this._mode = "idle"; // "idle" | "streaming" | "command" - this._newPayload = true; - this._expectedLen = 0; - this._buf = new Uint8Array(0); - - this.stripStreamCrc = !!stripStreamCrc; - this.verifyStreamCrc = !!verifyStreamCrc; - - // sensor map (matches VerisenseDevice.CreateSensorMap) - this.sensors = { - 1: new SensorGSR(), - 2: new SensorLIS2DW12(), - 3: new SensorLSM6DS3(), - 4: new SensorPPG() - }; - this.sensors[1].setHardwareIdentifier(this.hardwareIdentifier); - - // pending command response - this._pending = null; // { resolve, reject } - } - - // quick access - get gsr() { return this.sensors[1]; } - get accel1() { return this.sensors[2]; } - get gyroAccel2() { return this.sensors[3]; } - get ppg() { return this.sensors[4]; } - - async connect({ device = null, filters, optionalServices } = {}) { - console.log("CONNECT"); - - - // If we're currently connected over serial, tear that down first so UI can use one device instance. - if (this._transportKind === "serial" || this.port) { - try { await this.disconnect({ reason: "Switching transport" }); } catch {} - } - - this._transportKind = "ble"; - const opts = { - filters: filters ?? [{ services: [VerisenseBleDevice.NUS_SERVICE] }], - optionalServices: optionalServices ?? [VerisenseBleDevice.NUS_SERVICE] - }; - - this.device = device ?? await navigator.bluetooth.requestDevice(opts); - - // Keep a removable handler so manual disconnect doesn't double-emit. - try { - if (this._onGattDisconnected && this.device) { - this.device.removeEventListener("gattserverdisconnected", this._onGattDisconnected); - } - } catch {} - - this._onGattDisconnected = () => { - this._mode = "idle"; - this._transportKind = null; - this.emit("disconnected", { kind: "ble" }); - }; - - this.device.addEventListener("gattserverdisconnected", this._onGattDisconnected); - - this.server = await this.device.gatt.connect(); - this.service = await this.server.getPrimaryService(VerisenseBleDevice.NUS_SERVICE); - this.tx = await this.service.getCharacteristic(VerisenseBleDevice.NUS_TX); - this.rx = await this.service.getCharacteristic(VerisenseBleDevice.NUS_RX); - - await this.rx.startNotifications(); - this.rx.addEventListener("characteristicvaluechanged", (ev) => { - const v = ev.target.value; - const bytes = new Uint8Array(v.buffer.slice(v.byteOffset, v.byteOffset + v.byteLength)); - this._feedStreamBytes(bytes) - }); - console.log(`CONNECT`); - this.emit("connected", { name: this.device.name, id: this.device.id }); - - await this.readProductionConfigFromDevice(); - - await this.readOpConfigFromDevice(); - - return true; - } - - // --- Web Serial (USB COM port) connect --- - // Usage: - // const v = new VerisenseBleDevice(...); // same protocol/core class - // await v.connectSerial({ baudRate: 115200 }); - // - // Note: Web Serial is Chromium-based browsers only (Chrome/Edge). - async connectSerial({ - port = null, - baudRate = 115200, - dataBits = 8, - stopBits = 1, - parity = "none", - flowControl = "none", - filters = null // e.g. [{ usbVendorId: 0x1234, usbProductId: 0x5678 }] - } = {}) { - if (!("serial" in navigator)) { - throw new Error("Web Serial not supported in this browser. Use Chrome/Edge on HTTPS or http://localhost."); - } - - // If already connected (BLE or Serial), disconnect first. - if (this._transportKind === "ble" && this.device?.gatt?.connected) { - await this.disconnect({ reason: "Reconnecting (serial)" }); - } else if (this._transportKind === "serial" && this.port) { - await this.disconnect({ reason: "Reconnecting (serial)" }); - } - - this._transportKind = "serial"; - this._mode = "idle"; - this._resetAssembler(); - - // Port selection (must be called from a user gesture) - if (!port) { - const opts = filters ? { filters } : undefined; - port = await navigator.serial.requestPort(opts); - } - this.port = port; - - await this.port.open({ baudRate, dataBits, stopBits, parity, flowControl }); - - // Kick off async read loop -> feeds _onRx() - this._serialAbort = new AbortController(); - this._startSerialReadLoop(this._serialAbort.signal); - - this.emit("connected", { kind: "serial" }); - await this.readOpConfigFromDevice(); - return true; - } - - async _serialWrite(u8) { - if (!this.port?.writable) throw new Error("Not connected"); - const writer = this.port.writable.getWriter(); - try { - await writer.write(u8); - } finally { - writer.releaseLock(); - } - } - - _startSerialReadLoop(signal) { - const port = this.port; - - // Keep a reference so disconnect() can await/cancel cleanly. - this._serialReadLoopTask = (async () => { - let reader = null; - try { - if (!port?.readable) return; - - // Create ONE reader and keep it until we're done. - // This avoids races where disconnect aborts, but the loop grabs a new reader lock anyway. - reader = port.readable.getReader(); - this._serialReader = reader; - - while (!signal.aborted) { - const { value, done } = await reader.read(); - if (done) break; - if (value && value.length) this._feedStreamBytes(new Uint8Array(value)); - } - } catch (e) { - if (!signal.aborted) console.warn("[serial] read loop error:", e); - } finally { - try { reader?.releaseLock?.(); } catch {} - if (this._serialReader === reader) this._serialReader = null; - this._serialReadLoopTask = null; - - // If we didn't abort (i.e. port dropped), emit disconnected here. - if (!signal.aborted) { - this._mode = "idle"; - this.emit("disconnected", { kind: "serial" }); - } - } - })(); - } - - async _serialDisconnect(reason = "user") { - const port = this.port; - - const had = { - hasPort: !!port, - readableLocked: !!port?.readable?.locked, - writableLocked: !!port?.writable?.locked, - hasAbort: !!this._serialAbort, - hasReader: !!this._serialReader, - hasTask: !!this._serialReadLoopTask, - }; - console.warn(`[serial] disconnect begin reason=${reason}`, had); - - // 1) Stop the read loop (but abort alone doesn't unblock reader.read()). - try { this._serialAbort?.abort(); } catch (e) { - console.warn("[serial] abort error:", e); - } - - // Helper: cancel the active reader (the ONLY reliable way to unblock reader.read()). - const cancelActiveReader = async () => { - const r = this._serialReader; - if (!r) return false; - try { await r.cancel(); } catch (e) { console.warn("[serial] reader.cancel error:", e); } - try { r.releaseLock(); } catch {} - if (this._serialReader === r) this._serialReader = null; - return true; - }; - - // 2) Cancel reader if we have it. - await cancelActiveReader(); - - // 2b) If readable is still locked but we don't have the reader ref yet, wait briefly. - if (port?.readable?.locked && !this._serialReader) { - for (let i = 0; i < 10; i++) { - await new Promise(r => setTimeout(r, 20)); - if (await cancelActiveReader()) break; - } - } - - // 3) Wait a moment for the read loop to unwind and release any remaining locks. - try { - const task = this._serialReadLoopTask; - if (task) { - await Promise.race([task, new Promise(r => setTimeout(r, 750))]); - } - } catch {} - - // 4) Best-effort: abort any pending writes if a writer lock is held. - try { - if (port?.writable?.locked) { - const w = port.writable.getWriter(); - try { await w.abort?.(); } catch {} - try { w.releaseLock(); } catch {} - } - } catch {} - - // 5) Now close the port. If readable/writable is still locked, Chromium throws: - // "Cannot cancel a locked stream" - try { - await port?.close?.(); - } catch (e) { - console.warn("[serial] port.close failed (readable/writable still locked)", e); - } - - this.port = null; - this._serialAbort = null; - this._serialReader = null; - this._serialReadLoopTask = null; - - console.warn(`[serial] disconnect done reason=${reason}`); - } - -// Unified disconnect for BLE + Web Serial. -// UI should always call: await v.disconnect() -async disconnect({ reason = null } = {}) { - const kind = this._transportKind === "serial" ? "serial" : "ble"; - - // Best-effort: stop streaming so device returns to idle - if (this._mode === "streaming") { - try { await this.stopStreaming(); } catch {} - } - - // Abort any in-flight logged transfer - if (this._sync) { - try { this._abortSync(new Error(reason || "Disconnected")); } catch {} - } - - // Tear down transport - if (this._transportKind === "serial") { - try { await this._serialDisconnect(reason || "user"); - } catch {} - } else { - this.writeBytes(DISCONNECT_REQ, { withResponse: false }); - try { if (this.rx) await this.rx.stopNotifications?.(); } catch {} - try { if (this._onGattDisconnected && this.device) this.device.removeEventListener("gattserverdisconnected", this._onGattDisconnected); } catch {} - try { if (this.device?.gatt?.connected) this.device.gatt.disconnect(); } catch {} - } - - // Clear handles (safe for both) - this._mode = "idle"; - this._transportKind = null; - - this.port = null; - this._serialAbort = null; - - this.tx = null; - this.rx = null; - this.service = null; - this.server = null; - this.device = null; - - this.emit("disconnected", { kind }); - return true; -} - -async transferLoggedData({ - fileHandle = null, // FileSystemFileHandle (Chromium) if you want true streaming-to-disk - timeoutMs = 1000, - maxNack = 5, - maxCrcNack = 5, - onProgress = null, // ({ payloadIndex, bytesWritten, crcOk }) => void -} = {}) { - const bleOk = !!(this.rx && this.tx); - const serOk = !!(this.port?.readable && this.port?.writable); - if (!bleOk && !serOk) throw new Error("Not connected"); - if (this._mode === "streaming") throw new Error("Stop streaming before TransferLoggedData"); - if (this._mode === "logged") throw new Error("Already syncing logged data"); - - // ---- writer setup ---- - let writable = null; - const chunks = []; // fallback if no fileHandle - let bytesWritten = 0; - - if (fileHandle) { - // Chromium/Edge: real incremental write to disk - writable = await fileHandle.createWritable(); - } - - // ---- init sync session ---- - this._mode = "logged"; - this._resetAssembler(); - this._loggedChain = Promise.resolve(); - - if (this.debugSync) { - console.log("[sync] START transferLoggedData", { - hasFileHandle: !!fileHandle, - timeoutMs, maxNack, maxCrcNack, - mode: this._mode - }); - } - this._syncRxCount = 0; - this._syncPayloadCount = 0; - - - const sync = { - receiving: true, - newPayload: true, - lastReply: "NONE", - nackCount: 0, - nackCrcCount: 0, - lastRxAt: Date.now(), - timeoutMs, - bytesWritten: 0, - resolve: null, - reject: null, - timer: null, - writable, - chunks, - onProgress, - }; - this._sync = sync; - - const donePromise = new Promise((resolve, reject) => { sync.resolve = resolve; sync.reject = reject; }); - - // ---- timeout loop (C# ProcessDataTimeout equivalent) ---- - sync.timer = setInterval(async () => { - if (!this._sync?.receiving) return; - const age = Date.now() - this._sync.lastRxAt; - if (age < this._sync.timeoutMs) return; - - try { - if (this._sync.lastReply === "NONE") { - // resend read request - await this.writeBytes(READ_DATA_REQ, { withResponse: true }); - } else { - // force resend of last by NACK - this._clearSyncRxBuffers("timeout-nack"); - await this.writeBytes(DATA_NACK); - this._sync.nackCount++; - this._sync.lastReply = "NACK"; - if (this._sync.nackCount >= maxNack) throw new Error("Too many NACK timeouts"); - } - this._sync.lastRxAt = Date.now(); - } catch (e) { - this._abortSync(e); - } - }, Math.max(250, Math.floor(timeoutMs / 2))); - - // ---- kick it off ---- - await this.writeBytes(READ_DATA_REQ, { withResponse: true }); - - // ---- wait ---- - const result = await donePromise; - - // Make sure any queued payload writes have finished before closing/flushing - await (this._loggedChain ?? Promise.resolve()); - - // close writer if used - if (writable) { - await writable.close(); - } - - // if fallback: create blob - if (!fileHandle) { - const blob = new Blob(chunks, { type: "application/octet-stream" }); - return { ...result, blob }; - } - - return result; -} - - - // ---------- requests ---------- - async writeBytes(bytes, { withResponse = false } = {}) { - const u8 = (bytes instanceof Uint8Array) ? bytes : new Uint8Array(bytes); - - // Serial transport - if (this._transportKind === "serial") { - await this._serialWrite(u8); - return; - } - - // BLE transport (default) - if (!this.tx) throw new Error("Not connected"); - - // For sync/control frames (ACK/NACK/REQ), use write-with-response to get radio-level flow control. - if (withResponse) { - await this.tx.writeValue(u8); - return; - } - - // Bulk/normal writes can use withoutResponse if available (lower latency). - if (this.tx.writeValueWithoutResponse) { - await this.tx.writeValueWithoutResponse(u8); - } else { - await this.tx.writeValue(u8); - } - } - - _makeReq(opcode, payloadBytes = []) { - const p = (payloadBytes instanceof Uint8Array) ? payloadBytes : new Uint8Array(payloadBytes); - const len = p.length; - const out = new Uint8Array(3 + len); - out[0] = opcode & 0xFF; - out[1] = len & 0xFF; - out[2] = (len >> 8) & 0xFF; - out.set(p, 3); - return out; - } - - // Generic: send request and wait for next complete command payload - async request(opcode, payloadBytes = [], timeoutMs = 3000) { - if (this._pending) throw new Error("A request is already pending"); - this._mode = "command"; - this._resetAssembler(); - - const req = this._makeReq(opcode, payloadBytes); - - const p = new Promise((resolve, reject) => { - const t = setTimeout(() => { - this._pending = null; - reject(new Error("Request timeout")); - }, timeoutMs); - - this._pending = { - resolve: (x) => { clearTimeout(t); this._pending = null; resolve(x); }, - reject: (e) => { clearTimeout(t); this._pending = null; reject(e); } - }; - }); - - await this.writeBytes(req); - return p; - } - - // Convenience (from VerisenseBLEDevice.cs) - readStatus() { return this.request(0x11); } - readStatus2() { return this.request(0x1C); } - readProductionConfig() { return this.request(0x13); } - readOperationalConfig(){ return this.request(0x14); } - readTime() { return this.request(0x15); } - readPendingEvents() { return this.request(0x17); } - disconnectRequest() { return this.request(0x2B); } - - async startStreaming() { - // StreamDataRequest = [0x2A, 0x01, 0x00, 0x01] - this._mode = "streaming"; - this._resetAssembler(); - await this.writeBytes(this._makeReq(0x2A, [0x01])); - this.emit("streaming", { on: true }); - } - - async stopStreaming() { - // StopStreamRequest = [0x2A, 0x01, 0x00, 0x02] - await this.writeBytes(this._makeReq(0x2A, [0x02])); - this._mode = "idle"; - this.emit("streaming", { on: false }); - } - - // ---------- RX parsing / reassembly ---------- - _abortSync(err) { - const s = this._sync; - if (!s) return; - s.receiving = false; - if (s.timer) clearInterval(s.timer); - this._sync = null; - this._mode = "idle"; - s.reject(err instanceof Error ? err : new Error(String(err))); -} - -_finishSync() { - const s = this._sync; - if (!s) return; - s.receiving = false; - if (s.timer) clearInterval(s.timer); - const bytesWritten = s.bytesWritten; - this._sync = null; - this._mode = "idle"; - s.resolve({ ok: true, bytesWritten }); -} - -async _handleLoggedPayload(payloadU8) { - this._syncPayloadCount++; - - if (this.debugSync) { - const head = Array.from(payloadU8.slice(0, 10)).map(b => b.toString(16).padStart(2,"0")).join(" "); - console.log(`[sync][payload#${this._syncPayloadCount}] len=${payloadU8.length} head=${head}`); - } - - const s = this._sync; - if (!s) return; - - // payloadU8 includes CRC at end - const computed = computeCrcLikeCSharp(payloadU8); - const original = getOriginalCrcLE(payloadU8); - const crcOk = (computed === original); - - // payloadIndex is first 2 bytes (little endian) in your C# bin stream - const payloadIndex = u16le_at(payloadU8, 0); - - if (!crcOk) { - s.lastReply = "NACK"; - s.nackCrcCount++; - this._clearSyncRxBuffers("crc-nack"); - await this.writeBytes(DATA_NACK); - - if (s.nackCrcCount >= 5) { - this._abortSync(new Error("Too many CRC failures (NACKCRCcounter>=5)")); - } - - if (s.onProgress) s.onProgress({ payloadIndex, bytesWritten: s.bytesWritten, crcOk: false }); - return; - } - if (this.debugSync) { - console.log("[sync] writing...", { hasWritable: !!s.writable, payloadLen: payloadU8.length, bytesWrittenBefore: s.bytesWritten }); - } - - // write to bin (either disk stream or memory) - if (s.writable) { - await s.writable.write(payloadU8); - } else { - s.chunks.push(payloadU8.slice()); // copy - } - s.bytesWritten += payloadU8.length; - - // ACK and reset counters (like C# FinishPayload) - s.lastReply = "ACK"; - s.nackCount = 0; - s.nackCrcCount = 0; - await this.writeBytes(DATA_ACK, { withResponse: true }); - - if (s.onProgress) s.onProgress({ payloadIndex, bytesWritten: s.bytesWritten, crcOk: true }); -} - - - - _resetAssembler() { - this._newPayload = true; - this._expectedLen = 0; - this._buf = new Uint8Array(0); - } - - _appendBuf(chunk) { - const merged = new Uint8Array(this._buf.length + chunk.length); - merged.set(this._buf, 0); - merged.set(chunk, this._buf.length); - this._buf = merged; - } - - _onRx(bytes) { - try { - console.log('RX BYTES: ' + bytes); - if (this._mode === "logged" && this.debugSync) { - this._syncRxCount++; - if (this._syncRxCount <= 25 || (this._syncRxCount % 100) === 0) { - const head = Array.from(bytes.slice(0, 8)).map(b => b.toString(16).padStart(2,"0")).join(" "); - console.log(`[sync][rx#${this._syncRxCount}] len=${bytes.length} head=${head}`, { - newPayload: this._newPayload, - expectedLen: this._expectedLen, - bufLen: this._buf?.length ?? 0, - mode: this._mode - }); - } -} - - - // If you're in logged-sync mode, refresh timeout watchdog on *any* RX - if (this._mode === "logged" && this._sync) this._sync.lastRxAt = Date.now(); - - // Logged sync EOS marker: 0x42 00 00 - if (this._mode === "logged" && bytes.length === 3 && bytes[0] === DATA_EOS_HDR) { - if (this.debugSync) console.log("[sync] EOS received (0x42 00 00). Finishing. bytesWritten=", this._sync?.bytesWritten); - this._resetAssembler(); - this._finishSync(); - return; - } - - // Streaming special case: 0x4A 00 00 (len=0) seen sometimes - if (this._mode === "streaming" && bytes.length === 3 && bytes[0] === 0x4A) return; - - // Assemble: first chunk has [hdr][lenLE16] then payload bytes; later chunks are raw continuation. - if (this._newPayload) { - if (bytes.length < 3) return; - const len = u16le(bytes[1], bytes[2]); - - // Sanity guard: if we ever get desynced (dropped/extra byte), we'll start - // interpreting random bytes as [hdr][lenLE16]. Bail out and resync. - const MAX_FRAME = 40000; // expected logged frames are ~32k; keep a little headroom - if (len < 0 || len > MAX_FRAME) { - console.warn("[rx] Implausible frame length; resyncing", { hdr: bytes[0], len }); - this._resetAssembler(); - if (bytes.length > 1) { - const rest = bytes.slice(1); - const feed = () => this._onRx(rest); - (typeof queueMicrotask === "function") ? queueMicrotask(feed) : Promise.resolve().then(feed); - } - return; - } - - this._expectedLen = len; - this._buf = new Uint8Array(0); - - if (bytes.length > 3) this._appendBuf(bytes.slice(3)); - this._newPayload = false; - } else { - this._appendBuf(bytes); - } - - if (this._buf.length < this._expectedLen) return; - - const payload = this._buf.slice(0, this._expectedLen); - const remainder = (this._buf.length > this._expectedLen) - ? this._buf.slice(this._expectedLen) - : null; - - this._resetAssembler(); - - // If BLE/serial delivered bytes for *next* frame in the same chunk, - // do NOT drop them—feed them back in. - if (remainder && remainder.length) { - const feed = () => this._onRx(remainder); - (typeof queueMicrotask === "function") ? queueMicrotask(feed) : Promise.resolve().then(feed); - } - - // --- LOGGED SYNC PAYLOADS --- - if (this._mode === "logged") { - // IMPORTANT: _handleLoggedPayload is async; serialize it. - this._loggedChain = (this._loggedChain ?? Promise.resolve()) - .then(() => this._handleLoggedPayload(payload)) - .catch((e) => this._abortSync(e)); - return; - } - - // --- STREAMING PAYLOADS --- - if (this._mode === "streaming") { - this._handleStreamingPayload(payload); - return; - } - - // --- COMMAND / IDLE PAYLOADS (THIS FIXES opcfg TIMEOUT) --- - const pending = this._pending; - this._pending = null; - - if (this._mode === "command") this._mode = "idle"; - - if (pending) pending.resolve({ payload }); - this.emit("commandPayload", { payload }); - - } catch (e) { - console.warn("[_onRx] error:", e); - // If logged sync is active, abort cleanly instead of leaving it wedged - if (this._mode === "logged") this._abortSync(e); - } -} - - - _handleStreamingPayload(payload) { - // payload starts with: [sensorId][tick u24][sensorPayload...][optional crc16] - if (payload.length < 4) return; - - let body = payload; - let crcOk = null; - - if (this.stripStreamCrc && payload.length >= 6) { - // assume last 2 bytes are CRC16 (little-endian) - const claimed = (payload[payload.length - 2] | (payload[payload.length - 1] << 8)) >>> 0; - const dataNoCrc = payload.slice(0, payload.length - 2); - - if (this.verifyStreamCrc) { - const calc = crc16_ccitt_false(dataNoCrc); - crcOk = (calc === claimed); - } - - body = dataNoCrc; - - if (this.verifyStreamCrc && crcOk === false) { - this.emit("streamCrcFail", { claimed, body: dataNoCrc }); - // still continue emitting raw+decoded so you can decide what to do - } - } - - const sensorId = body[0]; - const tick = u24le(body, 1); - const sensorPayload = body.slice(4); - - const sensor = this.sensors[sensorId]; - const systemTsLastSampleMillis = nowMillis(); - let tsInfo = null; - if (sensor) tsInfo = sensor.getTimestampUnwrappedMillis(tick, systemTsLastSampleMillis); - - let decodedSamples = null; - if (sensor) decodedSamples = sensor.parsePayload(sensorPayload); - - // optional timestamp extrapolation per sample - let samplesWithTime = decodedSamples; - if (sensor && Array.isArray(decodedSamples) && decodedSamples.length > 0 && tsInfo) { - const num = decodedSamples.length; - samplesWithTime = decodedSamples.map((s, i) => { - const t = sensor.extrapolateSampleTimes({ - numSamples: num, - i, - samplingRateHz: sensor.samplingRateHz, - tsLastSampleMillis: tsInfo.shimmerMillis, - systemTsLastSampleMillis, - systemOffsetFirstTime: tsInfo.systemOffsetFirstTime - }); - return { ...s, timestamps: t }; - }); - } - - const packet = { - sensorId, - tick_u24: tick, - decoded: samplesWithTime, - rawPayload: sensorPayload, - crcOk - }; - - this.emit("streamPacket", packet); - this.emit("data", packet); // alias - } - - _appendStreamBuf(chunk) { - const merged = new Uint8Array(this._rxStreamBuf.length + chunk.length); - merged.set(this._rxStreamBuf, 0); - merged.set(chunk, this._rxStreamBuf.length); - this._rxStreamBuf = merged; -} - -_feedStreamBytes(chunk) { - if (this._mode === "logged" && this._sync) this._sync.lastRxAt = Date.now(); - - this._appendStreamBuf(chunk); - - while (true) { - if (this._rxStreamBuf.length < 3) return; - - const hdr = this._rxStreamBuf[0]; - const len = (this._rxStreamBuf[1] | (this._rxStreamBuf[2] << 8)) >>> 0; - - // consume header - if (len === 0) { - this._rxStreamBuf = this._rxStreamBuf.slice(3); - - // EOS marker for sync - if (this._mode === "logged" && hdr === DATA_EOS_HDR) { - if (this.debugSync) console.log("[sync] EOS received (stream parser). Finishing."); - this._finishSync(); - } - // streaming keepalive 0x4A 00 00: ignore - continue; - } - - if (this._rxStreamBuf.length < 3 + len) return; - - const payload = this._rxStreamBuf.slice(3, 3 + len); - this._rxStreamBuf = this._rxStreamBuf.slice(3 + len); - - // Now dispatch exactly like your “payload complete” section: - if (this._mode === "logged") { - this._loggedChain = (this._loggedChain ?? Promise.resolve()) - .then(() => this._handleLoggedPayload(payload)) - .catch((e) => this._abortSync(e)); - continue; - } - - if (this._mode === "streaming") { - this._handleStreamingPayload(payload); - continue; - } - - const pending = this._pending; - this._pending = null; - if (this._mode === "command") this._mode = "idle"; - if (pending) pending.resolve({ payload }); - this.emit("commandPayload", { payload }); - } -} -_clearSyncRxBuffers(reason = "") { - // When we decide to NACK / retry, discard any partial RX state. - // Otherwise the resent packet can be concatenated onto stale bytes and misalign parsing. - const had = { - rxStreamBufLen: this._rxStreamBuf?.length ?? 0, - asmBufLen: this._buf?.length ?? 0, - expectedLen: this._expectedLen ?? 0, - newPayload: this._newPayload ?? true - }; - - this._rxStreamBuf = new Uint8Array(0); - this._resetAssembler(); - - if (this.debugSync) { - console.warn("[sync] cleared RX buffers", { reason, had }); - } -} - - - - // ----------------------------------------------------------------- - // Operational Config helpers (device-level) - // ----------------------------------------------------------------- - - /** - * Get the currently cached operational config (Uint8Array). - * If not present, reads it from the device. - */ - async getOpConfig() { - // NOTE: This is a *cache-only* getter. It never talks to the device. - // Use readOpConfigFromDevice() when you explicitly want to refresh. - if (this.operationalConfig && this.operationalConfig.length) { - return new Uint8Array(this.operationalConfig); - } - throw new Error("Operational config not cached. Call readOpConfigFromDevice() first."); -} - - -async readProductionConfigFromDevice() { - if (typeof this.readProductionConfig !== "function") { - throw new Error("readProductionConfig() not implemented in this build"); - } - - const rsp = await this.readProductionConfig(); // { payload } - const payload = rsp?.payload; - const prod = normalizeOperationalConfig(payload); - - if (!prod || !prod.length) { - throw new Error("Invalid operational config returned from device"); - } - - this.productionConfig = prod; - console.log("Production Config:", prod); - console.log("Production Config:", parseProductionConfigPayload(prod)); - this.emit("Production Config", parseProductionConfigPayload(prod)); -} - -/** - * Read operational config from the device (opcode 0x14), normalize it, - * cache it on this.operationalConfig, and apply it to sensor decoders. - */ -async readOpConfigFromDevice() { - if (typeof this.readOperationalConfig !== "function") { - throw new Error("readOperationalConfig() not implemented in this build"); - } - - const rsp = await this.readOperationalConfig(); // { payload } - const payload = rsp?.payload; - const op = normalizeOperationalConfig(payload); - - if (!op || !op.length || op[0] !== 0x5A) { - throw new Error("Invalid operational config returned from device"); - } - - this.operationalConfig = op; - - // Apply to sensors (best-effort) - try { - if (this.accel1?.applyOperationalConfig) this.accel1.applyOperationalConfig(op); - if (this.gyroAccel2?.applyOperationalConfig) this.gyroAccel2.applyOperationalConfig(op); - if (this.gsr?.applyOperationalConfig) this.gsr.applyOperationalConfig(op); - if (this.ppg?.applyOperationalConfig) this.ppg.applyOperationalConfig(op); - } catch (e) { - console.warn("[opcfg] apply after read failed:", e); - } - - console.log("[opcfg] Accel1 :", { - accEnabled: this.accel1.accEnabled, - accRange: this.accel1.accRange, - hz: this.accel1.samplingRateHz - }); - console.log("[opcfg] gyroAccel2 :", { - accEnabled: this.gyroAccel2.accEnabled, - gyroEnabled: this.gyroAccel2.gyroEnabled, - accRange: this.gyroAccel2.accRange, - gyroRange: this.gyroAccel2.gyroRange, - hz: this.gyroAccel2.samplingRateHz - }); - console.log("[opcfg] gsr :", { - gsrEnabled: this.gsr.gsrEnabled, - gsrRange: this.gsr.gsrRangeSetting, - hz: this.gsr.samplingRateHz - }); - this.emit("opConfig", { op }); - return new Uint8Array(op); -} - - - // aliases (to match your pseudo-code style) - async getopconfig(opts) { return this.getOpConfig(opts); } - - /** - * Write operational config bytes to the device, then optionally verify by reading back. - * - */ - async writeOpConfig(opConfigBytes, _opts = {}) { - const op = normalizeOperationalConfig(opConfigBytes); - if (!op || op.length < 4) throw new Error("writeOpConfig: invalid opconfig"); - if (op[0] !== 0x5A) throw new Error("writeOpConfig: opconfig must start with 0x5A"); - - const WRITE_OPCFG = 0x24; - - // 1) send write (don’t wait for an RX reply that may never come) - const req = this._makeReq(WRITE_OPCFG, op); - - // (optional but recommended for BLE robustness) - await this.writeBytes(req, { withResponse: true }); - - // 2) ALWAYS read back + reparse (this is your “real confirmation”) - await this.readOpConfigFromDevice(); // should update this.operationalConfig internally - -} - - - async writeopconfig(opConfigBytes, opts) { return this.writeOpConfig(opConfigBytes, opts); } - - /** - * Convenience: get a sensor by name. - * Accepts: "LIS2DW12"|"accel1", "LSM6DS3"|"gyroAccel2", "GSR", "PPG" - */ - getSensor(name) { - const k = String(name ?? "").toLowerCase(); - if (!k) return null; - if (k.includes("lis2dw12") || k.includes("accel1") || k === "2") return this.accel1 ?? null; - if (k.includes("lsm6") || k.includes("gyro") || k.includes("accel2") || k === "3") return this.gyroAccel2 ?? null; - if (k.includes("gsr") || k === "1") return this.gsr ?? null; - if (k.includes("ppg") || k === "4") return this.ppg ?? null; - return null; - } - GetSensor(name) { return this.getSensor(name); } - -} - - diff --git a/break-emg/index.html b/break-emg/index.html index 07945c7..dc8cbe6 100644 --- a/break-emg/index.html +++ b/break-emg/index.html @@ -1,383 +1,908 @@ - + - - - - - - - Breakout Game (EMG) — Shimmer3R API - - - -
-
-

🎮 EMG Wrist-Controlled Paddle Game

-

Requirements:

-
    -
  • Device: Shimmer3R (EMG)
  • -
  • Firmware: Version ≥ v1.0.22
  • -
-
-

⚡ EMG Electrode Placement

-

This game uses wrist extension and wrist flexion to control the paddle. To get good signals, place electrodes on the belly of each muscle. For the right hand, use EMG1 (Ch1N red and Ch1P brown). Polarity doesn't matter because the signal is rectified. - Place the reference electrode (green) at an electrically neutral bony prominence (e.g., wrist).

- Example - 🎥 Demo Video - -

✅ FLEXION — Locate Flexor Muscles

-
  • 📍 Target: Flexor carpi radialis / ulnaris
  • 🔘 Location: Inner forearm, 2–3 fingers below elbow
-
  1. Sit with palm up
  2. Bend wrist toward body
  3. Place electrode on firm bulge
- -

✅ EXTENSION — Locate Extensor Muscles

-
  • 📍 Target: Extensor carpi radialis longus
  • 🔘 Location: Outer top of forearm, near elbow
-
  1. Rest forearm palm-down
  2. Lift hand upward
  3. Place electrode on tightening band
- -

Tip: adjust the activation threshold slider to tune sensitivity.

-
- - + + + + + + + Breakout Game (EMG) — Shimmer3R API + + + + +
+
+

🎮 EMG Wrist-Controlled Paddle Game

+

Requirements:

+
    +
  • Device: Shimmer3R (EMG)
  • +
  • Firmware: Version ≥ v1.0.22
  • +
+
+

⚡ EMG Electrode Placement

+

+ This game uses wrist extension and + wrist flexion to control the paddle. To get good + signals, place electrodes on the belly of each muscle. For the right + hand, use EMG1 (Ch1N red and Ch1P brown). Polarity doesn't matter + because the signal is rectified. Place the reference electrode (green) + at an electrically neutral bony prominence (e.g., wrist). +

+ Example + 🎥 Demo Video + +

✅ FLEXION — Locate Flexor Muscles

+
    +
  • 📍 Target: Flexor carpi radialis / ulnaris
  • +
  • + 🔘 Location: Inner forearm, 2–3 fingers below elbow +
  • +
+
    +
  1. Sit with palm up
  2. +
  3. Bend wrist toward body
  4. +
  5. Place electrode on firm bulge
  6. +
+ +

✅ EXTENSION — Locate Extensor Muscles

+
    +
  • 📍 Target: Extensor carpi radialis longus
  • +
  • + 🔘 Location: Outer top of forearm, near elbow +
  • +
+
    +
  1. Rest forearm palm-down
  2. +
  3. Lift hand upward
  4. +
  5. Place electrode on tightening band
  6. +
+ +

+ Tip: adjust the activation threshold slider to tune sensitivity. +

+
+ + +
+ +
+
+ +
+ + + + +

No device selected

+
+
+ +
+
+
+ +
+
+ +
+

+    
+ +
+ +
+
+ +
- -
-
- -
- - - - -

No device selected

-
-
- -
-
-
- -
-
- -
- -
-
- -
📈 EMG Signal 1 (brown - red)
- -
📈 EMG Signal 2 (black - white)
- - - - - - - - - + e.preventDefault(); + }); + canvas.addEventListener("touchend", () => { + leftPressed = false; + rightPressed = false; + }); + + function collisionDetection() { + for (let c = 0; c < brickColumnCount; c++) { + for (let r = 0; r < brickRowCount; r++) { + const b = bricks[c][r]; + if (b.status === 1) { + if ( + x > b.x && + x < b.x + brickWidth && + y > b.y && + y < b.y + brickHeight + ) { + speedY = -speedY; + b.status = 0; + } + } + } + } + } + function checkWin() { + for (let c = 0; c < brickColumnCount; c++) { + for (let r = 0; r < brickRowCount; r++) { + if (bricks[c][r].status === 1) return false; + } + } + return true; + } + function drawBall() { + ctx.beginPath(); + ctx.arc(x, y, ballRadius, 0, Math.PI * 2); + ctx.fillStyle = "#f00"; + ctx.fill(); + ctx.closePath(); + } + function drawPaddle() { + ctx.beginPath(); + ctx.rect( + paddleX, + canvas.height - paddleHeight, + paddleWidth, + paddleHeight, + ); + ctx.fillStyle = "#00f"; + ctx.fill(); + ctx.closePath(); + } + function drawBricks() { + for (let c = 0; c < brickColumnCount; c++) { + for (let r = 0; r < brickRowCount; r++) { + if (bricks[c][r].status === 1) { + const brickX = c * (brickWidth + brickPadding) + brickOffsetLeft; + const brickY = r * (brickHeight + brickPadding) + brickOffsetTop; + bricks[c][r].x = brickX; + bricks[c][r].y = brickY; + ctx.beginPath(); + ctx.rect(brickX, brickY, brickWidth, brickHeight); + ctx.fillStyle = "#0f0"; + ctx.fill(); + ctx.closePath(); + } + } + } + } + + function startGame() { + x = canvas.width / 2; + y = canvas.height - 30; + paddleX = (canvas.width - paddleWidth) / 2; + lastTime = null; + speedX = ballSpeed; + speedY = -ballSpeed; + cancelAnimationFrame(animationId); + animationId = requestAnimationFrame(draw); + gameOver = false; + gameWon = false; + for (let c = 0; c < brickColumnCount; c++) { + for (let r = 0; r < brickRowCount; r++) { + bricks[c][r].status = 1; + } + } + } + function draw(ts) { + if (!lastTime) lastTime = ts; + const dt = (ts - lastTime) / 1000; + lastTime = ts; + ctx.clearRect(0, 0, canvas.width, canvas.height); + drawBricks(); + drawBall(); + drawPaddle(); + collisionDetection(); + if (!gameWon && checkWin()) { + gameWon = true; + alert( + "🎉 You Win! You can still move the paddle. Press Start Game to restart.", + ); + } + if ( + x + speedX * dt > canvas.width - ballRadius || + x + speedX * dt < ballRadius + ) + speedX = -speedX; + if (y + speedY * dt < ballRadius) speedY = -speedY; + else if (y + speedY * dt > canvas.height - ballRadius) { + if (x > paddleX && x < paddleX + paddleWidth) { + speedY = -speedY; + } else if (!gameOver) { + gameOver = true; + if (document.getElementById("autoRestart").checked) { + showCustomAlert( + "Game Over! Game will restart in 5 seconds", + 4500, + ); + setTimeout(() => { + if (!gameOver && !gameWon) return; + startGame(); + }, 5000); + } else { + showCustomAlert( + "Game Over! You can still move the paddle. Press Start Game to restart.", + 5000, + ); + } + } + } + const moveSpeed = 350; + if (rightPressed && paddleX < canvas.width - paddleWidth) + paddleX += moveSpeed * dt; + else if (leftPressed && paddleX > 0) paddleX -= moveSpeed * dt; + if (!gameOver && !gameWon) { + x += speedX * dt; + y += speedY * dt; + } + animationId = requestAnimationFrame(draw); + } + + document.getElementById("startBtn").addEventListener("click", startGame); + ballSpeedSlider.addEventListener("input", () => { + ballSpeed = parseInt(ballSpeedSlider.value, 10); + ballSpeedLabel.textContent = ballSpeed; + const angle = Math.atan2(speedY, speedX); + speedX = ballSpeed * Math.cos(angle); + speedY = ballSpeed * Math.sin(angle); + }); + + // Tip overlay controls + window.addEventListener("DOMContentLoaded", () => { + if (localStorage.getItem("hideIntroOverlay") === "true") { + document.getElementById("introOverlay").style.display = "none"; + } + }); + document.getElementById("closeIntroBtn").addEventListener("click", () => { + const dontShow = document.getElementById("dontShowAgain").checked; + if (dontShow) localStorage.setItem("hideIntroOverlay", "true"); + document.getElementById("introOverlay").style.display = "none"; + }); + document.getElementById("showTipBtn").addEventListener("click", () => { + document.getElementById("introOverlay").style.display = "flex"; + localStorage.removeItem("hideIntroOverlay"); + }); + + // Custom alert (unchanged) + function showCustomAlert(message, duration = 3000) { + const el = document.getElementById("customAlert"); + el.textContent = message; + el.style.display = "block"; + setTimeout(() => { + el.style.display = "none"; + }, duration); + } + + // Keyboard/gamepad flags + + +
+ Game Over! You can still move the paddle. Press Start Game to restart. +
+ diff --git a/break-gyro/index.html b/break-gyro/index.html index b17a3b7..4cc8185 100644 --- a/break-gyro/index.html +++ b/break-gyro/index.html @@ -1,482 +1,588 @@ - + - - - - - - - - Breakout Game - - - -
-
-

🎮 Welcome to Breakout!

-

Here's what you need to know to get started:

-
    -
  • Connect your Bluetooth device: Click 🔍 Scan, then ⚙️ Configure.
  • -
  • Start data stream: Tap 📡 Start Streaming to enable motion-based control.
  • -
  • Tilt to move: Rotate the device around the Z-axis to move the paddle.
  • -
  • No Bluetooth? Use arrow keys or touch to control the paddle.
  • -
  • Objective: Break all the bricks. Don’t let the ball fall!
  • -
  • Start game: Click ▶️ Start Game.
  • -
-

Requirements:

-
    -
  • Device: Shimmer3R
  • -
  • Firmware: Version ≥ v1.0.22
  • -
- Shimmer3 Axis Diagram -

- ↺ Rotate the device clockwise (right) or counter-clockwise (left) around the Z-axis to control the paddle. -

-
- - -
- -
-
- -
- - - - - - -

No device selected

-
-
- - -
- -
-

-  
- - - - - + + + + + Breakout Game + + + + +
+
+

🎮 Welcome to Breakout!

+

Here's what you need to know to get started:

+
    +
  • + Connect your Bluetooth device: Click + 🔍 Scan, then + ⚙️ Configure. +
  • +
  • + Start data stream: Tap + 📡 Start Streaming to enable + motion-based control. +
  • +
  • + Tilt to move: Rotate the device + around the Z-axis to move the paddle. +
  • +
  • + No Bluetooth? Use arrow keys or touch to control + the paddle. +
  • +
  • + Objective: Break all the bricks. Don’t let the ball + fall! +
  • +
  • + Start game: Click + ▶️ Start Game. +
  • +
+

Requirements:

+
    +
  • Device: Shimmer3R
  • +
  • Firmware: Version ≥ v1.0.22
  • +
+ Shimmer3 Axis Diagram +

+ ↺ Rotate the device clockwise (right) or counter-clockwise (left) + around the Z-axis to control the paddle. +

+
+ + +
+ +
+
+ +
+ + + + + + +

No device selected

+
+
+ + +
+ +
+

+    
+ + + + + - - - - -
- Game Over! You can still move the paddle. Press Start Game to restart. -
- + + + + + +
+ Game Over! You can still move the paddle. Press Start Game to restart. +
+ diff --git a/brick/index.html b/brick/index.html index 3e05560..d43b38c 100644 --- a/brick/index.html +++ b/brick/index.html @@ -1,577 +1,1129 @@ - + - - - - - - - Gyro Blocks — Dual BLE - - - - - - - -
-

🎮 Gyro Blocks — Dual BLE (Move + Rotate)

-

Use two Shimmer devices: one controls left/right movement; the other controls rotation. Keyboard fallback works too.

- -
-
- -
- - - -
- -
- - Score: 0 - Lines: 0 - Level: 1 + + + + + + + Gyro Blocks — Dual BLE + + + + + +