extend BLE outage cushion from hardware evidence

This commit is contained in:
Jay
2026-08-18 11:51:46 -04:00
parent 8f75045796
commit 483ace3578
4 changed files with 18 additions and 7 deletions
+2 -2
View File
@@ -68,7 +68,7 @@ consumer can distinguish a fresh sample from a repeated poll and identify gyro
overruns. Hardware data-ready interrupts and FIFO acquisition are deferred to the overruns. Hardware data-ready interrupts and FIFO acquisition are deferred to the
later sensor-side acquisition refinement. later sensor-side acquisition refinement.
Completed samples enter a 512-record RAM queue, providing 5.12 seconds of Completed samples enter a 1024-record RAM queue, providing 10.24 seconds of
transport-outage tolerance at 100 Hz when the transport reports backpressure or transport-outage tolerance at 100 Hz when the transport reports backpressure or
failure accurately. A failed write retains and retries its packet while this failure accurately. A failed write retains and retries its packet while this
queue accumulates the backlog. A lower-priority output task batches up to eight queue accumulates the backlog. A lower-priority output task batches up to eight
@@ -86,7 +86,7 @@ The preserved USB telemetry option uses ESP-IDF's interrupt-driven USB
Serial/JTAG driver behind Serial/JTAG driver behind
a transport-neutral state machine. A complete frame is submitted atomically to a transport-neutral state machine. A complete frame is submitted atomically to
the driver ring and remains pending across bounded drain timeouts; firmware does the driver ring and remains pending across bounded drain timeouts; firmware does
not resubmit it ambiguously or dequeue another frame. The 512-sample queue not resubmit it ambiguously or dequeue another frame. The 1024-sample queue
therefore also protects a connected endpoint that temporarily stops draining. therefore also protects a connected endpoint that temporarily stops draining.
USB drain confirms that bytes left the device endpoint, not that the capture USB drain confirms that bytes left the device endpoint, not that the capture
+2 -2
View File
@@ -105,8 +105,8 @@ counters remain zero.
## Buffering ## Buffering
Acquisition runs in a dedicated higher-priority task and writes complete samples Acquisition runs in a dedicated higher-priority task and writes complete samples
to a 512-entry RAM queue. The lower-priority output task batches up to eight to a 1024-entry RAM queue. The lower-priority output task batches up to eight
records per frame. At 100 Hz this queue represents about 5.12 seconds of records per frame. At 100 Hz this queue represents about 10.24 seconds of
decoupling when the transport reports backpressure or failure accurately. A decoupling when the transport reports backpressure or failure accurately. A
failed write retains and retries the same encoded packet rather than dequeuing failed write retains and retries the same encoded packet rather than dequeuing
more samples, so the queue accumulates the outage backlog. After reconnection, more samples, so the queue accumulates the outage backlog. After reconnection,
+1 -1
View File
@@ -28,7 +28,7 @@
#define TRIKKE_I2C_FREQ_HZ 400000 #define TRIKKE_I2C_FREQ_HZ 400000
#define TRIKKE_SAMPLE_RATE_HZ 100 #define TRIKKE_SAMPLE_RATE_HZ 100
#define TRIKKE_SAMPLE_TICKS pdMS_TO_TICKS(1000 / TRIKKE_SAMPLE_RATE_HZ) #define TRIKKE_SAMPLE_TICKS pdMS_TO_TICKS(1000 / TRIKKE_SAMPLE_RATE_HZ)
#define TRIKKE_SAMPLE_QUEUE_DEPTH 512 #define TRIKKE_SAMPLE_QUEUE_DEPTH 1024
#define TRIKKE_METADATA_INTERVAL_PACKETS 64 #define TRIKKE_METADATA_INTERVAL_PACKETS 64
#define TRIKKE_STATUS_INTERVAL_PACKETS 64 #define TRIKKE_STATUS_INTERVAL_PACKETS 64
#define TRIKKE_TRANSPORT_RETRY_DELAY_MS 10 #define TRIKKE_TRANSPORT_RETRY_DELAY_MS 10
+13 -2
View File
@@ -24,6 +24,7 @@ from trikke_protocol import (
) )
DEVICE_NAME = "TrikkeSensor" DEVICE_NAME = "TrikkeSensor"
SERVICE_UUID = "7d2ea000-f75b-4a9b-8fbe-3d4c2a1e9c10"
DATA_UUID = "7d2ea000-f75b-4a9b-8fbe-3d4c2a1e9c11" DATA_UUID = "7d2ea000-f75b-4a9b-8fbe-3d4c2a1e9c11"
ACK_UUID = "7d2ea000-f75b-4a9b-8fbe-3d4c2a1e9c12" ACK_UUID = "7d2ea000-f75b-4a9b-8fbe-3d4c2a1e9c12"
@@ -97,7 +98,9 @@ async def capture(args: argparse.Namespace) -> int:
if device is None: if device is None:
print(f"Scanning for {args.name}...") print(f"Scanning for {args.name}...")
device = await BleakScanner.find_device_by_name( device = await BleakScanner.find_device_by_name(
args.name, timeout=5.0 args.name,
timeout=5.0,
service_uuids=[SERVICE_UUID],
) )
if device is None: if device is None:
await asyncio.sleep(0.5) await asyncio.sleep(0.5)
@@ -185,8 +188,16 @@ async def capture(args: argparse.Namespace) -> int:
f"fragment_rejects={reassembler.rejected_fragment_count}, " f"fragment_rejects={reassembler.rejected_fragment_count}, "
f"callback_drops={callback_drop_count}, " f"callback_drops={callback_drop_count}, "
f"packet_gaps={integrity.packet_gap_count}, " f"packet_gaps={integrity.packet_gap_count}, "
f"packet_resets={integrity.packet_reset_count}, "
f"sample_gaps={integrity.sample_gap_count}, " f"sample_gaps={integrity.sample_gap_count}, "
f"crc_errors={parser.crc_errors}, " f"sample_resets={integrity.sample_reset_count}, "
f"timing_anomalies={integrity.timing_anomaly_count}, "
"timestamp_saturation_frames="
f"{integrity.timestamp_saturation_frame_count}, "
f"startup_crc_rejects={parser.startup_crc_errors}, "
f"stream_crc_errors={parser.crc_errors}, "
f"header_errors={parser.header_errors}, "
f"skipped_nonframe_bytes={parser.skipped_bytes}, "
f"trailing_partial_bytes={parser.buffered_bytes}" f"trailing_partial_bytes={parser.buffered_bytes}"
) )
print( print(