diff --git a/docs/firmware_picker.md b/docs/firmware_picker.md index 411025050..926d965f3 100644 --- a/docs/firmware_picker.md +++ b/docs/firmware_picker.md @@ -356,6 +356,9 @@ verified canonical image can therefore replace the matching SuperIO or non-shell recommendation. These accessory choices do not change the radio hardware selection. See [optional screens](optional_screens.md). +The [variant consolidation validation](test-results/firmware_variant_consolidation.md) +records the qualified package hashes, controls checks and pending hardware tests. + Ordinary non-OTA roles also use one artifact for normal operation and USB logging. On ESP32 1.17.1.5, run `set powersaving off` before `set usb.logging on`. Select the saved mode with `set usb.logging off|on`; no `-logging-` diff --git a/docs/optional_screens.md b/docs/optional_screens.md index 8a3ec048b..609c85ff4 100644 --- a/docs/optional_screens.md +++ b/docs/optional_screens.md @@ -41,6 +41,10 @@ and `270`, including portrait/landscape dashboard changes without reflashing. The stock R8 expansion board has no accelerometer for automatic orientation. See the [rotation commands](cli_commands.md#set-display-rotation). +The [variant consolidation validation](test-results/firmware_variant_consolidation.md) +records the ten qualified packages, software checks and remaining physical tests +for R8 rotation, Muzi SuperIO and T-Echo Lite detection. + Full Wireless Tracker repeaters retain the board's 50-neighbor capacity, as the V1.1 and V2 Full profiles already do. This preserves RAM for the screen, GPS, MQTT and update services; the RAM admission limits remain unchanged. diff --git a/docs/test-results/firmware_variant_consolidation.json b/docs/test-results/firmware_variant_consolidation.json new file mode 100644 index 000000000..650ea5ff2 --- /dev/null +++ b/docs/test-results/firmware_variant_consolidation.json @@ -0,0 +1,260 @@ +{ + "complete": true, + "profiles": [ + { + "application_bytes": 902956, + "application_sha256": "246b07c54f5c76c9b6d1f8fc30ad4de34d74ae182a3e06822a14bd3b1293371e", + "available_internal_bytes": 75948, + "embedded_version": "v1.18.0.1-variants-b31d942b", + "files": { + "PicoW_companion_radio-v1.18.0.1-variants-b31d942b.bin": "246b07c54f5c76c9b6d1f8fc30ad4de34d74ae182a3e06822a14bd3b1293371e", + "PicoW_companion_radio-v1.18.0.1-variants-b31d942b.uf2": "71bb65c155bbaeeef069e9d6c5d89bfd0bfd19a918a46b8750b20ceea11f08d2" + }, + "logical_target": "PicoW_companion_radio", + "markers": { + "companion.picow.combined": "meshcore.capability.companion.picow.combined.v1" + }, + "ram_margin_bytes": 58540, + "required_heap_bytes": 17408, + "target": "PicoW_companion_radio", + "uf2_end": "0x100dc800", + "uf2_start": "0x10000000" + }, + { + "application_bytes": 2287528, + "application_sha256": "19170cc8866b7bab7a66162513cb27e263275d71296e39cd7cdf6205c62dd148", + "available_internal_bytes": 231424, + "embedded_version": "v1.18.0.1-variants-b31d942b", + "files": { + "heltec_v4_r8_tft_companion_radio_full-v1.18.0.1-variants-b31d942b-merged.bin": "e41321b5bfe352cd06c383aa5d078dbdfa486466e1d2e581d7a56ebb98fd7cbb", + "heltec_v4_r8_tft_companion_radio_full-v1.18.0.1-variants-b31d942b.bin": "19170cc8866b7bab7a66162513cb27e263275d71296e39cd7cdf6205c62dd148" + }, + "hardware": "heltec_v4_r8_tft", + "logical_target": "heltec_v4_r8_tft_companion_radio_full", + "markers": { + "display.autodetect": "meshcore.capability.display.autodetect.heltec_r8.v1", + "display.rotation.runtime": "meshcore.capability.display.rotation.heltec_r8.v1" + }, + "ota_target": "0x0", + "ram_margin_bytes": 66528, + "required_heap_bytes": 164896, + "target": "heltec_v4_r8_tft_companion_radio_full" + }, + { + "application_bytes": 2297368, + "application_sha256": "0837183ff0835e8c4c9d7893ae7cada540a6ed40f1e0c692c7dfc47e1ed611f1", + "available_internal_bytes": 202120, + "embedded_version": "v1.18.0.1-variants-observer-b31d942b", + "files": { + "heltec_v4_r8_tft_repeater_observer_mqtt-full-usb-wifi-ota-v1.18.0.1-variants-b31d942b-merged.bin": "c36b2b75fb6bfb1899c76986ce290d27357e1a2efe0c096341d0feecc7afc268", + "heltec_v4_r8_tft_repeater_observer_mqtt-full-usb-wifi-ota-v1.18.0.1-variants-b31d942b.bin": "0837183ff0835e8c4c9d7893ae7cada540a6ed40f1e0c692c7dfc47e1ed611f1" + }, + "hardware": "heltec_v4_r8_tft", + "logical_target": "heltec_v4_r8_tft_repeater_observer_mqtt", + "markers": { + "display.autodetect": "meshcore.capability.display.autodetect.heltec_r8.v1", + "display.rotation.runtime": "meshcore.capability.display.rotation.heltec_r8.v1" + }, + "ota_target": "0xdd39457b", + "ram_margin_bytes": 5736, + "required_heap_bytes": 196384, + "target": "heltec_v4_r8_tft_repeater" + }, + { + "application_bytes": 2302648, + "application_sha256": "28ffdb3bd325ae4d9d4f513007de833bb9aeaf2543399aca2dd57e5ff8bff26f", + "available_internal_bytes": 197656, + "embedded_version": "v1.18.0.1-variants-observer-b31d942b", + "files": { + "heltec_v4_r8_tft_room_server_observer_mqtt-full-usb-wifi-ota-v1.18.0.1-variants-b31d942b-merged.bin": "9d0a42c13fa53153301e5c96c4825ba7bca08851787a112c96bfedc5b6fbfd08", + "heltec_v4_r8_tft_room_server_observer_mqtt-full-usb-wifi-ota-v1.18.0.1-variants-b31d942b.bin": "28ffdb3bd325ae4d9d4f513007de833bb9aeaf2543399aca2dd57e5ff8bff26f" + }, + "hardware": "heltec_v4_r8_tft", + "logical_target": "heltec_v4_r8_tft_room_server_observer_mqtt", + "markers": { + "display.autodetect": "meshcore.capability.display.autodetect.heltec_r8.v1", + "display.rotation.runtime": "meshcore.capability.display.rotation.heltec_r8.v1" + }, + "ota_target": "0x1d1c0d92", + "ram_margin_bytes": 7784, + "required_heap_bytes": 189872, + "target": "heltec_v4_r8_tft_room_server" + }, + { + "application_bytes": 1590952, + "application_sha256": "064c4c98d2b6c20d366c2c5fc2a63dce2b6590dd6c70e9b112a1f17984bd3844", + "available_internal_bytes": 273872, + "embedded_version": "v1.18.0.1-variants-b31d942b", + "files": { + "heltec_v4_r8_tft_sensor-full-ota-v1.18.0.1-variants-b31d942b-merged.bin": "c8e154a76fe7a2960c18a6ddd3b34ea877c74f7e0936b48b6b2fa99a1a431bc0", + "heltec_v4_r8_tft_sensor-full-ota-v1.18.0.1-variants-b31d942b.bin": "064c4c98d2b6c20d366c2c5fc2a63dce2b6590dd6c70e9b112a1f17984bd3844" + }, + "hardware": "heltec_v4_r8_tft", + "logical_target": "heltec_v4_r8_tft_sensor", + "markers": { + "display.autodetect": "meshcore.capability.display.autodetect.heltec_r8.v1", + "display.rotation.runtime": "meshcore.capability.display.rotation.heltec_r8.v1" + }, + "ota_target": "0x5fc52bcb", + "ram_margin_bytes": 131472, + "required_heap_bytes": 142400, + "target": "heltec_v4_r8_tft_sensor" + }, + { + "application_bytes": 2283496, + "application_sha256": "73ec156914e8f1302f42fddba02478951c3d0fd7a03cdb0d2ecff310bad02543", + "available_internal_bytes": 204336, + "embedded_version": "v1.18.0.1-variants-observer-b31d942b", + "files": { + "heltec_v4_repeater_observer_mqtt-full-usb-wifi-ota-v1.18.0.1-variants-b31d942b-merged.bin": "f4cce7eec6b06f0346cb904ec03f5728e023248eca226b946f536a93a86800e6", + "heltec_v4_repeater_observer_mqtt-full-usb-wifi-ota-v1.18.0.1-variants-b31d942b.bin": "73ec156914e8f1302f42fddba02478951c3d0fd7a03cdb0d2ecff310bad02543" + }, + "hardware": "heltec_v4", + "logical_target": "heltec_v4_repeater_observer_mqtt", + "markers": { + "hardware.heltec_v4.oled_kit": "meshcore.capability.hardware.heltec_v4.oled_kit.v1" + }, + "ota_target": "0xab74db9e", + "ram_margin_bytes": 5904, + "required_heap_bytes": 198432, + "target": "heltec_v4_repeater" + }, + { + "application_bytes": 2281768, + "application_sha256": "85c2dcaa00e8b1fad223454328f855fc25b42498f335752bdd7850b19f27cb6e", + "available_internal_bytes": 233072, + "embedded_version": "v1.18.0.1-variants-b31d942b", + "files": { + "heltec_v4_tft_companion_radio_full_femon-v1.18.0.1-variants-b31d942b-merged.bin": "94ad5d1481a36714dbe7e39da15c8128b5c423ff3abcc8da4b25eb441329a088", + "heltec_v4_tft_companion_radio_full_femon-v1.18.0.1-variants-b31d942b.bin": "85c2dcaa00e8b1fad223454328f855fc25b42498f335752bdd7850b19f27cb6e" + }, + "hardware": "heltec_v4_tft", + "logical_target": "heltec_v4_tft_companion_radio_full_femon", + "markers": { + "hardware.heltec_v4.tft_kit": "meshcore.capability.hardware.heltec_v4.tft_kit.v1" + }, + "ota_target": "0x0", + "ram_margin_bytes": 68176, + "required_heap_bytes": 164896, + "target": "heltec_v4_tft_companion_radio_full_femon" + }, + { + "application_bytes": 580640, + "application_sha256": "0d9fbe41f3eda4c1639ef0af36eff35d4f83779c7749c6aaf1bb89eab2daec16", + "available_internal_bytes": 89856, + "embedded_version": "v1.18.0.1-variants-b31d942b", + "files": { + "muzi_base_uno_companion_radio_full-v1.18.0.1-variants-b31d942b.uf2": "0860679f11b6c5d765a3075e6d45f685a35d88de299a16faa43659f7ff9c50f9", + "muzi_base_uno_companion_radio_full-v1.18.0.1-variants-b31d942b.zip": "5c649ab442a34b4e08f3cdbe57577132f279dc85c790517f7759915003729bb3" + }, + "hardware": "muzi_base_uno", + "logical_target": "muzi_base_uno_companion_radio_full", + "markers": { + "display.autodetect": "meshcore.capability.display.autodetect.muzi_superio.v1" + }, + "ota_target": "0x0", + "ram_margin_bytes": 32704, + "required_heap_bytes": 57152, + "target": "muzi_base_uno_companion_radio_full", + "uf2_end": "0xb3d00", + "uf2_start": "0x26000" + }, + { + "application_bytes": 571792, + "application_sha256": "d5970c20227fe1b0de5ebe32abb31612609cec404e0fd818f49967a1906cd6fe", + "available_internal_bytes": 89936, + "embedded_version": "v1.18.0.1-variants-b31d942b", + "files": { + "muzi_base_duo_companion_radio_full-v1.18.0.1-variants-b31d942b.uf2": "ae9c52c008691e00e3790b39cbde8b58b8040dfc09b4e69fe1a71394276be126", + "muzi_base_duo_companion_radio_full-v1.18.0.1-variants-b31d942b.zip": "f4fa59ef3f403f609cef8dda521442d3363bd43ebbef3d11cea9cc3a8e79a7c5" + }, + "hardware": "muzi_base_duo", + "logical_target": "muzi_base_duo_companion_radio_full", + "markers": { + "display.autodetect": "meshcore.capability.display.autodetect.muzi_superio.v1" + }, + "ota_target": "0x0", + "ram_margin_bytes": 32784, + "required_heap_bytes": 57152, + "target": "muzi_base_duo_companion_radio_full", + "uf2_end": "0xb1a00", + "uf2_start": "0x26000" + }, + { + "application_bytes": 595896, + "application_sha256": "91495097a5249ae422381642f9add59d881e8d5a25bb38886d461053cd78a7c8", + "available_internal_bytes": 81984, + "embedded_version": "v1.18.0.1-variants-b31d942b", + "files": { + "LilyGo_T-Echo-Lite_companion_radio_full-v1.18.0.1-variants-b31d942b.uf2": "ab7782e28dcb5db35b0eff64cd45a217c9c5546ba078874b4a3f0fc1f1a31eed", + "LilyGo_T-Echo-Lite_companion_radio_full-v1.18.0.1-variants-b31d942b.zip": "8338d5a1efa4c00118922e5039a66a2e5684f6bf9d25ded5986dfa5cf507e20a" + }, + "hardware": "LilyGo_T-Echo-Lite", + "logical_target": "LilyGo_T-Echo-Lite_companion_radio_full", + "markers": { + "display.autodetect": "meshcore.capability.display.autodetect.techo_lite.v1" + }, + "ota_target": "0x0", + "ram_margin_bytes": 28928, + "required_heap_bytes": 53056, + "target": "LilyGo_T-Echo-Lite_companion_radio_full", + "uf2_end": "0xb7800", + "uf2_start": "0x26000" + } + ], + "schema_version": 1, + "scope": "Local packaged-firmware qualification and actual-package picker replay; physical hardware tests pending.", + "source": "b31d942b231360386fdfb92d0561f36095fdf011", + "validation": { + "native_suites": { + "test_heltec_r8_display_rotation.py": { + "methods": 4, + "passed": true, + "seconds": 4.502 + }, + "test_muzi_accessory_detection.py": { + "methods": 3, + "passed": true, + "seconds": 1.324 + }, + "test_techo_lite_display_detection.py": { + "methods": 4, + "passed": true, + "seconds": 3.115 + } + }, + "packages_verified": 10, + "physical_tests_performed": false, + "picker_browser": { + "checks": [ + "default-and-advanced:default-full", + "default-and-advanced:advanced-default", + "default-and-advanced:advanced-reduced", + "default-and-advanced:select-reduced", + "default-and-advanced:reduced-download", + "default-and-advanced:uncheck-returns-full", + "default-and-advanced:reset-full", + "explicit-reduced-url:url-auto-advanced", + "explicit-reduced-url:url-reduced-selected", + "explicit-reduced-url:url-reduced-download", + "explicit-reduced-url:url-no-unavailable", + "old-metadata:old-two-configurations", + "old-metadata:old-both-choices", + "old-metadata:old-not-hidden" + ], + "passed": true + }, + "picker_qualified_profiles": 10, + "webconfig_browser": { + "methods": 25, + "passed": true, + "seconds": 10.37 + }, + "webconfig_source": { + "methods": 13, + "passed": true, + "seconds": 0.009 + } + }, + "version": "v1.18.0.1-variants" +} diff --git a/docs/test-results/firmware_variant_consolidation.md b/docs/test-results/firmware_variant_consolidation.md new file mode 100644 index 000000000..f4a370160 --- /dev/null +++ b/docs/test-results/firmware_variant_consolidation.md @@ -0,0 +1,69 @@ + + + + +# Firmware variant consolidation validation + +All ten packaged profiles passed. Firmware source: +[`b31d942b231360386fdfb92d0561f36095fdf011`](https://github.com/mikecarper/MeshCore/commit/b31d942b231360386fdfb92d0561f36095fdf011). +Version: `v1.18.0.1-variants-b31d942b`. PlatformIO builds ran one at a time. +The packages were built locally; physical testing of these combinations remains pending. + +## Qualified behavior + +- The Pico W combined Companion supplies USB, Bluetooth LE and WiFi in one image. It does not acquire a wireless self-updater from that transport combination. +- The base Heltec V4 OLED Repeater supports the matching OLED expansion kit. The original V4 TFT Full Companion supports the matching TFT kit and retains its 3,400 mV shutdown guard. TFT and OLED wiring remain distinct. +- V4 R8 TFT Companion, Repeater, Room Server and Sensor applications contain the optional-panel detection and runtime-rotation implementations. Saved `display.rotation` values select clockwise offsets of 0, 90, 180 or 270 degrees from the compiled board default without another portrait image. Zero restores that board orientation; `display.flip` adds 180 degrees. The stock expansion kit has no orientation sensor. +- Muzi Base Uno and Duo Full Companions detect their SuperIO SH1107 panel and handle optional GPS independently. Their SX1262 and LR1121 radio choices remain distinct. +- T-Echo Lite Full Companion checks the SSD1681 panel before initializing e-paper and supports the corresponding core-only assembly. + +Future release selection retires an alternate choice only after its exact successor is qualified. Existing published binaries, filenames and update identities retain their original meaning. Switching between different target identities requires the documented local installation or an exact compatible update route. + +## Packaged applications + +| Profile | Application bytes | RAM admission margin (bytes) | Application SHA-256 prefix | +| --- | ---: | ---: | --- | +| Pico W combined Companion | 902,956 | 58,540 | `246b07c54f5c` | +| V4 R8 TFT Full Companion | 2,287,528 | 66,528 | `19170cc8866b` | +| V4 R8 TFT Full Repeater | 2,297,368 | 5,736 | `0837183ff083` | +| V4 R8 TFT Full Room Server | 2,302,648 | 7,784 | `28ffdb3bd325` | +| V4 R8 TFT Full Sensor | 1,590,952 | 131,472 | `064c4c98d2b6` | +| V4 OLED Full Repeater | 2,283,496 | 5,904 | `73ec156914e8` | +| V4 TFT Full Companion | 2,281,768 | 68,176 | `85c2dcaa00e8` | +| Muzi Base Uno Full Companion | 580,640 | 32,704 | `0d9fbe41f3ed` | +| Muzi Base Duo Full Companion | 571,792 | 32,784 | `d5970c20227f` | +| T-Echo Lite Full Companion | 595,896 | 28,928 | `91495097a524` | + +The [machine-readable evidence](firmware_variant_consolidation.json) contains the full application SHA-256 values, hashes for every offered BIN/merged BIN/UF2/DFU ZIP, exact requested and packaged targets, source version, hardware/update identity where present, detection markers and RAM values. The application hash covers the ESP32 BIN, nRF52 DFU application's BIN, or decoded RP2040 flash application; container hashes are recorded separately. + +RAM margins are linked capacity after the complete modeled heap requirement and transient reserve. They are admission results; runtime load and physical current were not measured. + +The verifier checked every memory manifest's file bindings and RAM admission. It read the promised marker and exact firmware/source version from each uploadable application, compared ESP32 application bytes with their merged install, compared nRF52 DFU application bytes with decoded UF2, and required Pico W's decoded UF2 to match its BIN. UF2 headers, unused sector bytes and alignment padding cannot provide application capability evidence. Observer-named ESP32 packages retain their actual target and embedded observer version in the JSON. + +## Software and browser checks + +| Check | Result | +| --- | --- | +| Native R8 rotation, Muzi accessories and T-Echo Lite detection | PASS, 11 methods across three suites; production paths, sanitizers and negative controls | +| RP2040 application admission and existing capability checker | PASS, 11 RP2040 methods and 18 existing methods; malformed UF2, wrong family/address/layout, BIN mismatch and metadata-only proof rejected | +| Consolidation policy, release controls and legacy compatibility | PASS, focused Python suites; packaged marker/config/source gating, paired sensor policies and unchanged historical downloads | +| Picker JavaScript | PASS, five suites covering consolidation, Full defaults, explicit Reduced links, historical metadata and runtime directions | +| WebConfig source checks | PASS, 13 methods | +| WebConfig browser behavior | PASS, 25 methods in the real Chromium headless browser, including saved rotation load/change | +| Firmware picker browser behavior | PASS, 14 DOM checks across Full default/Advanced interaction, explicit Reduced links and stale metadata | +| Complete build-profile selection suite | PASS | +| Actual package controls and picker replay | PASS, 10 qualified profiles; R8 rotation commands offered for all four roles | +| Physical boards/accessories, sleep current and radio/transport load | Not performed | + +The production controls generator and picker used release metadata assembled from these exact local files. Public firmware gains the new behavior when a matching qualified image is published. Full sensor support is the ordinary picker default; Advanced retains Reduced images and explicitly linked Reduced selections. Release policy keeps both Full and Reduced downloads and their exact update endpoints. + +## Physical acceptance still pending + +- **V4 R8 TFT:** cold USB/battery boots with the panel present and absent; all four angles, saved reboot persistence and `display.flip` interaction; dashboard geometry, touch wake/toggle behavior and sleep/wake at every angle; radio transmit/receive and GPS operation. +- **Muzi Base Uno/Duo:** cold boots with SuperIO present and absent; screen supply shutdown/wake, joystick and buzzer; GPS discovery and mode-switch changes; the power-button shutdown/wake sequence; radio operation throughout. +- **T-Echo Lite:** cold boots with the panel present and absent; real controller readback, BUSY settling and timeout behavior; e-paper refresh and sleep/wake; headless buttons, radio and GPS operation. +- **Pico W:** USB, Bluetooth LE and WiFi connections individually and concurrently, including frame delivery under normal radio receive/transmit load. + +These checks are required before describing the hardware combinations as physically qualified. + +The earlier [optional-screen record](../optional_screens.md#validation) covers separate RC32 and Tracker smoke packages; those are not part of this ten-profile matrix.