G6 v1 panel-protocol compliance: CRC integrity + parity fix#27
Merged
Conversation
bitget returns the input class (uint8), and `total_ones = total_ones + bitget(...)` accumulated in uint8 saturates at 255. For GS16 panels the popcount can reach ~800, so the saturation flipped the parity bit for any panel with >255 ones — caught when MATLAB-encoded GS16 patterns failed byte-equivalence vs the JS encoder. Accumulate in double; cast each bitget result to double before adding. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Bring the MATLAB G6 encoder/reader into v1 panel-protocol spec compliance.
Algorithms (LUT-driven, persistent caching, universal-check at first use):
- g6/crc8_autosar.m: poly 0x2F, init 0xFF, xorout 0xFF; universal check 0xDF
over "123456789". Casts to double to avoid uint8 saturation in the LUT-
index arithmetic (255+1 saturates to 255 otherwise — bit me in testing).
- g6/crc16_ccitt_false.m: poly 0x1021, init 0xFFFF; universal check 0x29B1.
Encoder integration (g6/g6_save_pattern.m):
- Header byte 18 now CRC-8/AUTOSAR over header bytes 1-17 (was: XOR over
all frame data).
- Each frame ends with a 2-byte CRC-16/CCITT-FALSE trailer (little-endian)
over {FR_magic, frame_index, panel_blocks} of that frame.
- all_frames preallocated to total_frames_size to avoid O(N^2) growth via
`[all_frames, ...]` concatenation. Cast to double() to avoid uint8
saturation on `row_count * length(installed_cols) * block_size`.
Reader integration (maDisplayTools.m::load_pat_g6):
- New 'strict' name-value argument; default false. Three-tier policy:
UI tolerant warnings (default), CI strict error, firmware fatal (per
spec; not implemented here).
- V2 header CRC verified (byte 18 over bytes 1-17). V1 unchanged.
- V2 frames: per-frame CRC-16 trailer parsed and verified after panels.
Gated on header version >= 2; V1 path skips the trailer.
- maDisplayTools.load_pat plumbs varargin through to load_pat_g6.
Old G6 v2 .pat files (no CRC trailer) fail file-size validation under
the new reader — they must be regenerated. Pre-release context: no G6
patterns have ever displayed on hardware, so no backward-compat needed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
3 rows × 16 columns = 48 panels — max-density G6 arena (fills the 48-bit panel_mask). Geometry definition already exists at configs/arenas/G6_3x16_full.yaml; this commit gives it a stable arena_id so it can appear in pattern file headers. Mirrored in webDisplayTools/js/arena-configs.js (separate PR). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
g6/test_g6_crc.m — 11 checks: universal vectors (0xDF, 0x29B1 over
"123456789"), CRC-8 protocol-specific vectors from the panel-protocol
spec (2L Oneshot all-zero → 0xC6, 16L Oneshot all-zero → 0x6D), the
canonical CRC-16 frame-header vector, JSON cross-check, plus
round-trip + header/frame corruption tests asserting strict mode
errors and tolerant mode warns.
g6/generate_g6_encoding_reference.m — adds a crc_test_vectors section
(CRC-8 + CRC-16 algorithm params and pinned vectors) and a
canonical_patterns section (G6_2x10 GS2 1-frame checker with SHA-256
of the encoded bytes — the byte-equivalence anchor for MATLAB ↔ JS
encoder regression). The naive `strrep` pretty-printer was replaced
with `jsonencode(... 'PrettyPrint', true)` because the former
corrupted strings containing literal '{' or '}'.
g6/g6_encoding_reference.json — regenerated; SHA-256 matches the
webDisplayTools/data/ mirror.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
All G6 patterns under patterns/web_generated/ regenerated using webDisplayTools/tests/generate-roundtrip-patterns.js (the canonical producer for "web_generated" files). New CRC-8 header byte + per-frame CRC-16 trailer; correct parity bits on every panel block. Modified (existing files, new format adds +40 bytes per file for the 20-frame patterns: per-frame CRC-16 trailer × 20 frames): - web_G6_2x10_gs16_square_grating_G6.pat - web_G6_2x10_gs2_square_grating_G6.pat - web_G6_2x8of10_gs16_sine_grating_G6.pat - web_G6_3x12of18_gs16_horiz_grating_G6.pat Added (matrix expansion — GS2 coverage for partial arenas, full G6_3x16, 1-frame all-zero edge case): - web_G6_2x10_gs2_blank_G6.pat - web_G6_2x8of10_gs2_square_grating_G6.pat - web_G6_3x12of18_gs2_horiz_grating_G6.pat - web_G6_3x16_full_gs2_square_grating_G6.pat - web_G6_3x16_full_gs16_sine_grating_G6.pat - manifest.json (per-file metadata + sha256 from the JS generator) All 9 G6 files pass strict-mode CRC validation (`node tests/verify-pat-crc.js patterns/web_generated/`). G4 files not touched (G4 format predates the CRC scheme). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Codex skill artifact dir (plan reviews, prompts, output JSONL). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
mbreiser
added a commit
that referenced
this pull request
May 24, 2026
Header CRC-8/AUTOSAR + per-frame CRC-16/CCITT-FALSE trailer (per PR #27). Pre-2026-05-24 G6 v2 files are obsolete and need regeneration. G4 unaffected. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Brings the MATLAB G6 encoder/reader into v1 panel-protocol spec compliance, mirroring the changes already merged in
reiserlab/webDisplayTools(PR commita348ae1).{FR_magic, frame_index, panel_blocks}of each frameload_pat/load_pat_g6: new'strict'name-value option — CRC failures throw under strict mode, warn otherwise (UI-tolerant by default)compute_headerpopcount overflow fix:total_oneswas accumulating in uint8, saturating at 255 — broke parity for GS16 panels (~800 ones). Now accumulates in double.G6_3x16_full(already defined inconfigs/arenas/)g6_encoding_reference.jsonregenerated; cross-repo byte-identical with webDisplayTools/data/.patfiles in patterns/web_generated/ regenerated (matrix expanded from 4 → 9 to cover all 4 registered G6 arenas × both GS modes, plus 1-frame edge case)Verification
addpath(genpath('.')); test_g6_crc()→ 11/11 checks passnode tests/verify-pat-crc.js patterns/web_generated/(from webDisplayTools) → 9/9 G6 files pass strict CRC, 4 G4 skippedPatternPreviewerApp.loadFile(...)on all 9 patterns → zero warningsMigration
Pre-release context: no G6 patterns have ever been displayed on hardware, so this is a one-way migration — old G6 v2
.patfiles written before this change are no longer parseable (file-size formula mismatch).Test plan
cd maDisplayTools && matlab -batch "addpath(genpath('.')); test_g6_crc"shows 11/11 PASSnode tests/verify-pat-crc.js maDisplayTools/patterns/web_generated/(from webDisplayTools) shows 9 pass / 0 failPatternPreviewerAppGUI — loads with no warnings🤖 Generated with Claude Code