diff --git a/_javascript/firmware_picker.js b/_javascript/firmware_picker.js index 7f47fe69..e2e613b1 100644 --- a/_javascript/firmware_picker.js +++ b/_javascript/firmware_picker.js @@ -381,10 +381,31 @@ /(?:^|[_-])(?:ps|femoff)(?=$|[_-])/.test(lowerTarget)); } - function omitNrf52TransportsReplacedByFull(profiles) { + function isDualCdcFullCompanion(profile) { + if (!profile || profile.role !== "companion" || profile.mode !== "full") { + return false; + } + if (profile.installKinds.includes("zip")) return true; + const target = String(profile.target || "").toLowerCase(); + if (/^heltec_v4(?:_2_v4_3|_3)?(?:_r8)?(?:_tft)?_companion_radio_full(?:_|$)/ + .test(target)) { + return true; + } + return [ + "lilygo_tbeam_1w_companion_radio_full", + "station_g2_companion_radio_full", + "station_g3_esp32_companion_radio_full", + "xiao_s3_wio_companion_radio_full", + "heltec_tracker_v2_companion_radio_full_femon", + "meshnology_w12_companion_radio_full", + "nibble_screen_connect_companion_radio_full_", + "nibble_zero_connect_companion_radio_full_", + ].includes(target); + } + + function omitTransportsReplacedByDualCdcFull(profiles) { const fullKeys = new Set((profiles || []).filter(function (profile) { - return profile.role === "companion" && profile.mode === "full" && - profile.installKinds.includes("zip"); + return isDualCdcFullCompanion(profile); }).map(function (profile) { return profile.hardware + "\n" + profile.variant; })); @@ -392,20 +413,19 @@ return (profiles || []).filter(function (profile) { const key = profile.hardware + "\n" + profile.variant; const replacedAttachedTransport = profile.role === "companion" && - (profile.mode === "usb" || profile.mode === "ble"); + (profile.mode === "usb" || profile.mode === "ble" || + profile.mode === "wifi"); return !(replacedAttachedTransport && fullKeys.has(key)); }); } - function applyNrf52FullCompanionCapabilities(profiles) { + function applyDualCdcFullCompanionCapabilities(profiles) { return (profiles || []).map(function (profile) { - const nativeNrf52Full = profile.role === "companion" && - profile.mode === "full" && profile.installKinds.includes("zip"); - if (!nativeNrf52Full) return profile; + if (!isDualCdcFullCompanion(profile)) return profile; - // Current nRF52 Full Companion images expose two CDC ACM interfaces: - // framed Companion traffic on interface 00 and plaintext logging on 02. - // The saved USB logging gate covers only the second interface. + // Supported Full Companion images always expose framed Companion traffic + // on interface 00. Logging defaults off; enabling it and rebooting adds + // the independent plaintext CDC interface 02. profile.logging = "usb-runtime"; profile.loggingModes = ["none", "usb"]; profile.dedicatedUsbLogging = true; @@ -512,8 +532,8 @@ }).filter(function (profile) { return !isHiddenLegacyProfile(profile); }); - const profiles = omitNrf52TransportsReplacedByFull( - applyNrf52FullCompanionCapabilities(visibleProfiles) + const profiles = omitTransportsReplacedByDualCdcFull( + applyDualCdcFullCompanionCapabilities(visibleProfiles) ).sort(function (a, b) { return a.target.localeCompare(b.target, undefined, { numeric: true, @@ -712,11 +732,11 @@ ); } else if (profile.logging === "usb-runtime") { extra.push( - "Use get usb.logging and set usb.logging off|on to choose and save normal output-off or USB packet logging." + "Full Companion starts with USB logging off and only interface 00. Use get usb.logging, or set usb.logging on reboot to save logging on and reboot when needed; set usb.logging off reboot removes interface 02 again." ); if (profile.dedicatedUsbLogging) { extra.push( - "This nRF52 Full Companion exposes two serial ports on one USB cable: interface 00 carries Companion/terminal/mOTA traffic and interface 02 carries plaintext logging. Match services by USB interface number instead of assuming tty or COM numbering." + "Interface 00 always carries Companion/terminal/mOTA traffic. After logging is enabled and the node reboots, interface 02 carries plaintext logs. Match services by USB interface number instead of assuming tty or COM numbering." ); } } @@ -757,7 +777,7 @@ if (profile.dedicatedUsbLogging) { factRows.splice(3, 0, [ "USB port split", - "Interface 00 Companion; interface 02 logging", + "Interface 00 always; interface 02 after logging on + reboot", ]); } replaceFacts(facts, factRows); @@ -1086,10 +1106,15 @@ flattenReleaseAssets: flattenReleaseAssets, parseFirmwareAsset: parseFirmwareAsset, parseTargetProfile: parseTargetProfile, + applyDualCdcFullCompanionCapabilities: + applyDualCdcFullCompanionCapabilities, applyNrf52FullCompanionCapabilities: - applyNrf52FullCompanionCapabilities, + applyDualCdcFullCompanionCapabilities, canonicalHardware: canonicalHardware, - omitNrf52TransportsReplacedByFull: omitNrf52TransportsReplacedByFull, + omitTransportsReplacedByDualCdcFull: + omitTransportsReplacedByDualCdcFull, + omitNrf52TransportsReplacedByFull: + omitTransportsReplacedByDualCdcFull, hardwareFamilyFor: hardwareFamilyFor, humanizeHardwareVariant: humanizeHardwareVariant, buildCatalog: buildCatalog, diff --git a/cli_build_matrix/index.html b/cli_build_matrix/index.html index 4a357868..e7041f41 100644 --- a/cli_build_matrix/index.html +++ b/cli_build_matrix/index.html @@ -1460,8 +1460,8 @@ retain 50 because their MQTT discovery tables are constrained by internal DRAM.< Uses the matching non-MQTT target only when no WiFi MQTT sibling exists, with debug and packet logging enabled and the complete command surface supported by that role and hardware. Its persistent USB gate also covers output-off operation, avoiding a second FULL ESP-NOW image. -nRF52 Full Companion -Uses one physical USB connection with interface 00 for framed Companion/terminal/mOTA traffic and interface 02 for plaintext logging. It also provides BLE and source-only LoRa OTA. get/set usb.logging persistently gates only the logging interface. +Dual-CDC Full Companion +nRF52 and qualified native-USB ESP32-S3 Full images use one physical USB connection. Fresh installs expose only interface 00 for framed Companion/terminal/mOTA traffic. Enabling logging and rebooting adds interface 02 for plaintext logs. They also provide BLE and source-only LoRa OTA; ESP32 additionally provides WiFi. get/set usb.logging persistently controls whether the logging interface is present. no_external_sensors @@ -1484,19 +1484,25 @@ available from a canonical image:

replaced by their ordinary Station target. G2 boosted receive gain is the persisted radio.rxgain on|off setting; the G3 alias changed only the advertised default name. -
  • When an nRF52 board has a generated Full Companion, that one artifact - replaces its separate USB, BLE, and USB packet-logging Companion artifacts. - It provides BLE plus two USB CDC interfaces: interface 00 carries framed - Companion/terminal/mOTA traffic and interface 02 carries plaintext logs. +
  • When a board has a dual-CDC Full Companion, that one artifact replaces its + separate USB, BLE, ordinary WiFi, and USB packet-logging Companion artifacts. + Current support includes nRF52 Full Companion plus qualified native-USB + ESP32-S3 Full targets: Heltec V4, T-Beam 1W, Station G2/G3, XIAO S3 WIO, + Heltec Tracker V2, Meshnology W12, and Nibble Screen/Zero Connect. RAK3112 + and Heltec RC32 keep separate transport and logging artifacts pending live + hardware validation. + It provides BLE plus an always-present interface 00 for framed + Companion/terminal/mOTA traffic. Enabling logging and rebooting adds + interface 02 for plaintext logs. Its LoRa OTA support is source-only: it can serve a host file to another node but has no staging store and cannot update itself over LoRa.
  • The old aliases still work with build-firmware and build-matching-firmwares. Dedicated repeater LoRa OTA receiver images are not collapsed; they retain their exact storage, bootloader, role, and target -identity contracts. ESP32 USB, BLE, WiFi, and Full Companion images also remain -separate because Full changes partitions, RAM use, active transports, and power -behavior.

    +identity contracts. ESP32 boards without the tested dual-CDC Full profile keep +USB, BLE, WiFi, and Full Companion images separate because Full changes +partitions, RAM use, active transports, and power behavior.

    Complete CLI policy

    The compact ESP32 CLI has been removed. MQTT observers and ESP-NOW bridges are automatically promoted to FULL builds with expanded partitions rather than diff --git a/cli_command_availability/index.html b/cli_command_availability/index.html index f86ed628..db252a9a 100644 --- a/cli_command_availability/index.html +++ b/cli_command_availability/index.html @@ -1860,7 +1860,7 @@ fix, no WiFi connection, an inactive bridge, or an nRF52 bootloader without Logging get/set usb.logging; unified FULL get/set logging.output -Logging artifacts; CommonCLI USB gate is persistent; unified ESP32 FULL selects off/USB/WiFi/both; nRF52 Full Companion gates its second USB port +Logging artifacts; CommonCLI USB gate is persistent; unified ESP32 FULL selects off/USB/WiFi/both; dual-CDC Full Companion adds/removes its second USB port after reboot No Yes No @@ -3189,7 +3189,7 @@ fix, no WiFi connection, an inactive bridge, or an nRF52 bootloader without Logging get/set usb.logging; unified FULL get/set logging.output -Logging artifacts; CommonCLI USB gate is persistent; unified ESP32 FULL selects off/USB/WiFi/both; nRF52 Full Companion gates its second USB port +Logging artifacts; CommonCLI USB gate is persistent; unified ESP32 FULL selects off/USB/WiFi/both; dual-CDC Full Companion adds/removes its second USB port after reboot No Yes No diff --git a/cli_commands/index.html b/cli_commands/index.html index 084a54c8..f2514c7b 100644 --- a/cli_commands/index.html +++ b/cli_commands/index.html @@ -5527,13 +5527,27 @@ emitted only when that hardware/role has no matching WiFi MQTT environment.

    get usb.logging
     set usb.logging on
     set usb.logging off
    +set usb.logging on reboot
    +set usb.logging off reboot
     

    These commands are compiled into logging artifacts and control their live USB debug and packet output. CommonCLI roles save the setting in /com_prefs, so -it survives reboot; first boot defaults to on. nRF52 Full Companion applies the -gate only to USB interface 02, its dedicated plaintext logging port. USB -interface 00 continues carrying Companion, terminal, and serial mOTA traffic. -Turning USB logging off does not disable CLI replies or Companion protocol +it survives reboot; their first boot defaults to on.

    +

    On Full Companion these lines belong to its text terminal, not meshcli's +Binary get/set parameter namespace. Open interface 00, send ++++MESHCORE-TERM-START, and then issue the command. Running +meshcli ... get usb.logging directly can instead return +Unknown var usb.logging because that is a different protocol operation.

    +

    Dual-CDC Full Companion instead defaults logging to off and enumerates only +USB interface 00, which carries Companion, terminal, and serial mOTA traffic. +Enabling logging adds interface 02, its dedicated plaintext logging port, on +the next boot. Disabling it removes interface 02 on the next boot. A command +without the optional reboot argument saves the choice and reports that a +reboot is required when the USB interface count must change. The exact +set usb.logging on reboot and set usb.logging off reboot forms save the +choice, send their reply, and reboot one second later only when needed. This +behavior includes nRF52 and qualified native-USB ESP32-S3 Full images.

    +

    Turning USB logging off does not disable CLI replies or Companion protocol frames. It also does not change the node-storage capture controlled by log start and log stop.

    Unified ESP32 FULL builds add one saved selector for both output paths:

    diff --git a/companion_radio_full/index.html b/companion_radio_full/index.html index 4003badc..3460f83f 100644 --- a/companion_radio_full/index.html +++ b/companion_radio_full/index.html @@ -515,10 +515,10 @@