From fd6e64dead131bbfac5c49e6f19afa49e732dc89 Mon Sep 17 00:00:00 2001 From: Benedikt Kleiner Date: Tue, 8 Sep 2026 15:51:12 +0800 Subject: [PATCH 1/6] docs: check MSP references are up to date in CI --- .github/workflows/README.md | 4 ++-- .github/workflows/docs.yml | 29 +++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/.github/workflows/README.md b/.github/workflows/README.md index 7e28f7cad01..6a08f134f58 100644 --- a/.github/workflows/README.md +++ b/.github/workflows/README.md @@ -29,8 +29,8 @@ fire. ### Documentation #### `docs.yml` - Documentation Build -**Triggers:** Pull requests affecting documentation -**Purpose:** Validates documentation builds correctly +**Triggers:** Pull requests and pushes affecting settings inputs, source `.c`/`.h` files, the firmware version in `CMakeLists.txt`, MSP docs inputs/outputs, or the workflow itself +**Purpose:** Regenerates `docs/Settings.md` and the MSP Markdown/JSON references, failing if the checked-in files are stale ### Code Quality diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index edaaecdf3bb..5a79e67075a 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -4,10 +4,22 @@ on: paths: - src/main/fc/settings.yaml - docs/Settings.md + - src/utils/update_cli_docs.py + - 'src/main/**/*.c' + - 'src/main/**/*.h' + - CMakeLists.txt + - 'docs/development/msp/**' + - .github/workflows/docs.yml push: paths: - src/main/fc/settings.yaml - docs/Settings.md + - src/utils/update_cli_docs.py + - 'src/main/**/*.c' + - 'src/main/**/*.h' + - CMakeLists.txt + - 'docs/development/msp/**' + - .github/workflows/docs.yml jobs: settings_md: @@ -25,3 +37,20 @@ jobs: echo "::error ::\"docs/Settings.md\" is not up to date, please run \"src/utils/update_cli_docs.py\"" exit 1 fi + + msp_docs: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version: '3.x' + - name: Check that MSP docs are up to date + working-directory: docs/development/msp + run: | + bash gen_docs.sh + if ! git diff --exit-code -- README.md inav_enums.json inav_enums_ref.md; then + echo "::error ::MSP docs are not up to date, please run 'cd docs/development/msp && bash gen_docs.sh'" + exit 1 + fi From 4ac24f5daddb2d54c0802278fd7f8da112e03af8 Mon Sep 17 00:00:00 2001 From: Benedikt Kleiner Date: Tue, 8 Sep 2026 15:58:28 +0800 Subject: [PATCH 2/6] docs: make MSP enum generation deterministic --- docs/development/msp/get_all_inav_enums_h.py | 2 +- docs/development/msp/inav_enums.json | 4 ++-- docs/development/msp/inav_enums_ref.md | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/development/msp/get_all_inav_enums_h.py b/docs/development/msp/get_all_inav_enums_h.py index 971d077d5f4..2f21924cc03 100644 --- a/docs/development/msp/get_all_inav_enums_h.py +++ b/docs/development/msp/get_all_inav_enums_h.py @@ -106,7 +106,7 @@ def parse_args(): root = base_dir / sd if not root.is_dir(): continue - for fn in root.rglob('*'): + for fn in sorted(root.rglob('*')): print(fn) if fn.suffix in ('.c', '.h'): txt = fn.read_text(errors='ignore') diff --git a/docs/development/msp/inav_enums.json b/docs/development/msp/inav_enums.json index 6c5ce2b96fe..f4fbb70ef09 100644 --- a/docs/development/msp/inav_enums.json +++ b/docs/development/msp/inav_enums.json @@ -3495,7 +3495,7 @@ "SDCARD_OPERATION_FAILURE": "3" }, "sdcardReceiveBlockStatus_e": { - "_source": "inav/src/main/drivers/sdcard/sdcard_sdio.c", + "_source": "inav/src/main/drivers/sdcard/sdcard_spi.c", "SDCARD_RECEIVE_SUCCESS": "0", "SDCARD_RECEIVE_BLOCK_IN_PROGRESS": "1", "SDCARD_RECEIVE_ERROR": "2" @@ -3869,7 +3869,7 @@ "THR_HI": "(2 << (2 * THROTTLE))" }, "systemState_e": { - "_source": "inav/src/main/fc/fc_init.c", + "_source": "inav/src/main/fc/fc_init.h", "SYSTEM_STATE_INITIALISING": "0", "SYSTEM_STATE_CONFIG_LOADED": "(1 << 0)", "SYSTEM_STATE_SENSORS_READY": "(1 << 1)", diff --git a/docs/development/msp/inav_enums_ref.md b/docs/development/msp/inav_enums_ref.md index 8ed0540edc9..e1eb58a6f8b 100644 --- a/docs/development/msp/inav_enums_ref.md +++ b/docs/development/msp/inav_enums_ref.md @@ -5111,7 +5111,7 @@ --- ## `sdcardReceiveBlockStatus_e` -> Source: ../../../src/main/drivers/sdcard/sdcard_spi.c +> Source: ../../../src/main/drivers/sdcard/sdcard_sdio.c | Enumerator | Value | Condition | |---|---:|---| @@ -5122,7 +5122,7 @@ --- ## `sdcardReceiveBlockStatus_e` -> Source: ../../../src/main/drivers/sdcard/sdcard_sdio.c +> Source: ../../../src/main/drivers/sdcard/sdcard_spi.c | Enumerator | Value | Condition | |---|---:|---| @@ -5673,7 +5673,7 @@ --- ## `systemState_e` -> Source: ../../../src/main/fc/fc_init.h +> Source: ../../../src/main/fc/fc_init.c | Enumerator | Value | Condition | |---|---:|---| @@ -5687,7 +5687,7 @@ --- ## `systemState_e` -> Source: ../../../src/main/fc/fc_init.c +> Source: ../../../src/main/fc/fc_init.h | Enumerator | Value | Condition | |---|---:|---| From 16a3d10fbd5d2a894ff8a9f6b5f4ad8118bc3cc5 Mon Sep 17 00:00:00 2001 From: Benedikt Kleiner Date: Tue, 8 Sep 2026 15:59:18 +0800 Subject: [PATCH 3/6] docs: detect missing generated MSP references in CI --- .github/workflows/docs.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index 5a79e67075a..74d5bdac3d4 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -50,7 +50,9 @@ jobs: working-directory: docs/development/msp run: | bash gen_docs.sh - if ! git diff --exit-code -- README.md inav_enums.json inav_enums_ref.md; then + if [ -n "$(git status --porcelain -- README.md inav_enums.json inav_enums_ref.md)" ]; then + git status --short -- README.md inav_enums.json inav_enums_ref.md + git diff -- README.md inav_enums.json inav_enums_ref.md echo "::error ::MSP docs are not up to date, please run 'cd docs/development/msp && bash gen_docs.sh'" exit 1 fi From 5f4b3b32a637f99c89da12ef478c1669cc7d596b Mon Sep 17 00:00:00 2001 From: Ray Morris Date: Mon, 14 Sep 2026 01:06:35 -0500 Subject: [PATCH 4/6] docs: regenerate stale MSP reference docs on release/9.1 README.md hadn't been regenerated since MSP2_INAV_SET_AUX_RC and MSP2_INAV_WIND were added to msp_messages.json, and since hwVersion's field description was updated for uint8_t encoding - both source changes landed without a matching `gen_docs.sh` run. The new CI check being backported alongside this (PR #11875) diffs a fresh regen against the checked-in copy, so it would fail immediately on release/9.1 without this. --- docs/development/msp/README.md | 34 ++++++++++++++++++++-- docs/development/msp/msp_messages.checksum | 2 +- docs/development/msp/rev | 2 +- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/docs/development/msp/README.md b/docs/development/msp/README.md index 833a9f6873c..e256610ca73 100644 --- a/docs/development/msp/README.md +++ b/docs/development/msp/README.md @@ -9,8 +9,7 @@ For list of enums, see [Enum documentation page](https://github.com/iNavFlight/i -**JSON file rev: 5 -** +**JSON file rev: 6** **Warning: Verification needed, exercise caution until completely verified for accuracy and cleared, especially for integer signs. Source-based generation/validation is forthcoming. Refer to source for absolute certainty** @@ -417,6 +416,8 @@ For list of enums, see [Enum documentation page](https://github.com/iNavFlight/i [8736 - MSP2_INAV_FULL_LOCAL_POSE](#msp2_inav_full_local_pose) [8737 - MSP2_INAV_SET_WP_INDEX](#msp2_inav_set_wp_index) [8739 - MSP2_INAV_SET_CRUISE_HEADING](#msp2_inav_set_cruise_heading) +[8752 - MSP2_INAV_SET_AUX_RC](#msp2_inav_set_aux_rc) +[8753 - MSP2_INAV_WIND](#msp2_inav_wind) [12288 - MSP2_BETAFLIGHT_BIND](#msp2_betaflight_bind) [12289 - MSP2_RX_BIND](#msp2_rx_bind) @@ -2278,7 +2279,7 @@ For list of enums, see [Enum documentation page](https://github.com/iNavFlight/i | `hdop` | `uint16_t` | 2 | HDOP * 100 | Horizontal Dilution of Precision (`gpsSol.hdop`) | | `eph` | `uint16_t` | 2 | cm | Estimated Horizontal Position Accuracy (`gpsSol.eph`) | | `epv` | `uint16_t` | 2 | cm | Estimated Vertical Position Accuracy (`gpsSol.epv`) | -| `hwVersion` | `uint32_t` | 4 | Version code | GPS hardware version (`gpsState.hwVersion`). Values: 500=UBLOX5, 600=UBLOX6, 700=UBLOX7, 800=UBLOX8, 900=UBLOX9, 1000=UBLOX10, 0=UNKNOWN | +| `hwVersion` | `uint8_t` | 1 | - | GPS hardware version bit-field: bits[7:6]=series (0b01=u-blox Neo/M), bits[5:0]=generation. E.g. 0x48=M8, 0x49=M9, 0x4A=M10, 0=unknown. | **Notes:** Requires `USE_GPS`. @@ -4570,6 +4571,33 @@ For list of enums, see [Enum documentation page](https://github.com/iNavFlight/i **Notes:** Returns error if the aircraft is not armed or `NAV_COURSE_HOLD_MODE` is not active. On success, sets both `posControl.cruise.course` and `posControl.cruise.previousCourse` to the normalised value, preventing spurious heading adjustments from `getCruiseHeadingAdjustment()` on the next control cycle. +## `MSP2_INAV_SET_AUX_RC (8752 / 0x2230)` +**Description:** Bandwidth-efficient auxiliary RC channel update. Sets CH13-CH32 with configurable resolution (2/4/8/16-bit) without affecting primary flight controls. Designed for extending channel count beyond native RC link capacity via MSP passthrough. + +**Request Payload:** +|Field|C Type|Size (Bytes)|Units|Description| +|---|---|---|---|---| +| `definitionByte` | `uint8_t` | 1 | - | Packed start channel and resolution. Bits 7-3: start channel index (valid range 12-31 for CH13-CH32; 0-11 rejected as error). Bits 2-0: resolution mode (0=2-bit, 1=4-bit, 2=8-bit, 3=16-bit; 4-7 reserved/error). | +| `channelData` | `uint8_t[]` | array | PWM (encoded) | Packed channel values, sequential from start channel. Number of channels is derived from data size and resolution. Value 0 means skip (no update). Sub-byte modes (2-bit, 4-bit) are packed MSB-first. 2-bit values 1-3 map to 1000/1500/2000us. 4-bit values 1-15 map to 1000 + (val-1)*1000/14 us. 8-bit values 1-255 map to 1000 + (val-1)*1000/254 us. 16-bit values are direct PWM, clamped to 750-2250us. | + +**Reply Payload:** **None** + +**Notes:** CH1-CH12 (index 0-11) are protected and will return `MSP_RESULT_ERROR`. Payload size must be 2-49 bytes. Constraint: `startChannel + channelCount <= 32`. Values persist until overwritten; no timeout. Applied as a post-RX overlay in `calculateRxChannelsAndUpdateFailsafe()` after MSP RC Override but before failsafe. Does not require `USE_RX_MSP` or MSP-RC-OVERRIDE flight mode. Does not affect failsafe detection. When MSP is the primary RX provider, channels covered by `MSP_SET_RAW_RC` are automatically skipped. Channels in the `mspOverrideChannels` bitmask are skipped when MSP RC Override mode is active. Recommended to send with `MSP_FLAG_DONT_REPLY` (flags=0x01) to save bandwidth on telemetry passthrough links. 16-bit mode requires even number of data bytes and values are clamped to 750-2250us. + +## `MSP2_INAV_WIND (8753 / 0x2231)` +**Description:** Retrieves the estimated horizontal wind speed and direction from the internal wind estimator. + +**Request Payload:** **None** + +**Reply Payload:** +|Field|C Type|Size (Bytes)|Units|Description| +|---|---|---|---|---| +| `windSpeed` | `uint16_t` | 2 | cm/s | Estimated horizontal wind speed (`getEstimatedHorizontalWindSpeed()`). 0 if unavailable. | +| `windAngle` | `uint16_t` | 2 | degrees | Estimated wind direction in degrees (0–359, 0 = North). Derived from centidegree value divided by 100. 0 if unavailable. | +| `flags` | `uint8_t` | 1 | - | Validity flags. Bit 0: wind estimate valid (`isEstimatedWindSpeedValid()`). Remaining bits reserved. | + +**Notes:** Requires `USE_WIND_ESTIMATOR`; returns zeroes when wind estimation is not compiled in or not yet valid. Check bit 0 of `flags` before using speed/angle values. + ## `MSP2_BETAFLIGHT_BIND (12288 / 0x3000)` **Description:** Initiates the receiver binding procedure for supported serial protocols (CRSF, SRXL2). diff --git a/docs/development/msp/msp_messages.checksum b/docs/development/msp/msp_messages.checksum index 031f3b14179..d140d3ba761 100644 --- a/docs/development/msp/msp_messages.checksum +++ b/docs/development/msp/msp_messages.checksum @@ -1 +1 @@ -c9458e9a712b7a4f3bc9333aa7bc3dcb +b7b61504b53cea5a9cf2a66240b6f99b diff --git a/docs/development/msp/rev b/docs/development/msp/rev index 7ed6ff82de6..62f9457511f 100644 --- a/docs/development/msp/rev +++ b/docs/development/msp/rev @@ -1 +1 @@ -5 +6 \ No newline at end of file From 9a650f35a20a247cd9c75fc0f1128b896b178af3 Mon Sep 17 00:00:00 2001 From: Ray Morris Date: Mon, 14 Sep 2026 01:22:48 -0500 Subject: [PATCH 5/6] Fix msp_docs CI job always failing due to gen_docs.sh's interactive prompt release/9.1's gen_docs.sh still ends with an interactive `read -n 1 -s -r -p "Press any key to continue"`. Under GitHub Actions' default non-interactive shell (bash -eo pipefail), reading from a closed stdin fails and becomes the script's own exit status, so `bash gen_docs.sh` returns nonzero even when the docs are perfectly up to date - aborting the step (via -e) before the actual staleness check ever runs. Gate the prompt behind a TTY check so it still pauses for a human running it locally but is a no-op in CI. maintenance-10.x's gen_docs.sh has already been rewritten without this prompt, so this only affects the release/9.1 backport. --- docs/development/msp/gen_docs.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/development/msp/gen_docs.sh b/docs/development/msp/gen_docs.sh index 84aa852841f..4ec87fd112c 100755 --- a/docs/development/msp/gen_docs.sh +++ b/docs/development/msp/gen_docs.sh @@ -24,4 +24,5 @@ echo "###########" echo gen_enum_md.py python gen_enum_md.py rm all_enums.h -read -n 1 -s -r -p "Press any key to continue" +[ -t 0 ] && read -n 1 -s -r -p "Press any key to continue" +true From 991ac266de984e0f7c0737ba3b744622e12575a9 Mon Sep 17 00:00:00 2001 From: Ray Morris Date: Mon, 14 Sep 2026 06:51:38 -0500 Subject: [PATCH 6/6] Fix gen_docs.sh masking a generator crash as CI success The TTY-gated prompt fix (previous commit) unconditionally ended the script with `true`, so if any preceding Python generator step failed partway through, the failure was discarded and the script still exited 0 - the CI job's git-status check would then see whatever partial/unchanged state was left and report success despite the docs never having actually been (re)validated. Add `set -euo pipefail` so any real failure aborts immediately, and replace the bare `true` with a proper `if [ -t 0 ]; then read ...; fi` that doesn't need a trailing catch-all to stay -e-safe. Caught by Qodo's review on the PR carrying the previous fix. --- docs/development/msp/gen_docs.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/docs/development/msp/gen_docs.sh b/docs/development/msp/gen_docs.sh index 4ec87fd112c..5d3c0835512 100755 --- a/docs/development/msp/gen_docs.sh +++ b/docs/development/msp/gen_docs.sh @@ -1,3 +1,5 @@ +set -euo pipefail + INAV_MAIN_PATH="../../../src/main" echo "###########" @@ -24,5 +26,6 @@ echo "###########" echo gen_enum_md.py python gen_enum_md.py rm all_enums.h -[ -t 0 ] && read -n 1 -s -r -p "Press any key to continue" -true +if [ -t 0 ]; then + read -n 1 -s -r -p "Press any key to continue" +fi