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..74d5bdac3d4 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,22 @@ 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 [ -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
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/gen_docs.sh b/docs/development/msp/gen_docs.sh
index 84aa852841f..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,4 +26,6 @@ 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"
+if [ -t 0 ]; then
+ read -n 1 -s -r -p "Press any key to continue"
+fi
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 |
|---|---:|---|
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