Skip to content

Release/9.1 to master#11697

Merged
sensei-hacker merged 62 commits into
masterfrom
release/9.1
Jul 8, 2026
Merged

Release/9.1 to master#11697
sensei-hacker merged 62 commits into
masterfrom
release/9.1

Conversation

@sensei-hacker

Copy link
Copy Markdown
Member

No description provided.

engineer-dakefpv and others added 30 commits December 16, 2025 17:30
Split OMNIBUSF4 mega-target into 4 directories to improve maintainability:
- DYSF4: DYSF4PRO, DYSF4PROV2
- OMNIBUSF4: Base OMNIBUSF4 variant only
- OMNIBUSF4PRO: OMNIBUSF4PRO, OMNIBUSF4V3, OMNIBUSF4V3_ICM
- OMNIBUSF4V3_SS: Softserial variants (S6_SS, S5S6_SS, S5_S6_2SS)

Each directory now contains only the code relevant to its variants,
with irrelevant preprocessor conditionals removed.

Changes:
- Reduced DYSF4/target.h from 271 to 169 lines (37% reduction)
- Reduced preprocessor conditionals from 18 to 4 in DYSF4 files
- All 11 targets build successfully and produce identical binaries
Remove preprocessor conditionals that can never be true in split directories:
- OMNIBUSF4PRO: Remove checks for _S6_SS variants (in different directory)
- OMNIBUSF4V3_SS: Remove checks for OMNIBUSF4PRO/V3 (in different directory)
- Remove OMNIBUSF4PRO_LEDSTRIPM5 references (target no longer exists)

Update comments to accurately describe what targets each directory contains.

All affected targets build successfully.
The OMNIBUSF4 directory now only contains the base OMNIBUSF4 target.
All other variants (OMNIBUSF4PRO, OMNIBUSF4V3, DYSF4, etc.) are in
separate directories.

Used unifdef to remove all conditionals for non-OMNIBUSF4 targets:
- Removed checks for OMNIBUSF4PRO, OMNIBUSF4V3, DYSF4PRO, DYSF4PROV2
- Removed checks for softserial variants (_S6_SS, etc.)
- Removed LEDSTRIPM5 references

Results:
- target.h: 280 → 147 lines (47% reduction, 133 lines removed)
- target.c: cleaned (7 conditionals removed)
- All conditionals removed: 0 remaining in both files
- OMNIBUSF4 target builds successfully

The OMNIBUSF4 directory now contains only the code specific to the
base OMNIBUSF4 variant with no dead branches.
1. Added alias for OMNIBUSF4V3_ICM → OMNIBUSF4V3 in OMNIBUSF4PRO/target.h
   This fixes a critical bug where OMNIBUSF4V3_ICM would get wrong configuration:
   - Wrong IMU alignment (CW180 instead of CW270)
   - Missing MPU6500/BMI270 support
   - Wrong barometer (I2C-only instead of SPI BMP280)
   - Missing UART inverter support
   - Wrong SPI3_NSS_PIN (PB3 instead of PA15)
   - Wrong blackbox (SPI flash instead of SD card)
   - Wrong timer configuration

2. Removed dead #else clauses after OMNIBUS split:
   - DYSF4/target.h: Removed unreachable fallback cases
   - OMNIBUSF4PRO/target.h: All #else branches now dead after alias fix
   - OMNIBUSF4V3_SS/target.h: Removed unreachable softserial fallback

All affected targets verified to build successfully.
- DYSF4/target.h: Removed ICM20608 comment (no ICM support in this directory)
- OMNIBUSF4/target.h: Removed ICM20608 comment (no ICM support in this directory)
- OMNIBUSF4/target.h: Removed obsolete relationship comments from consolidated file

ICM20608 support only exists in OMNIBUSF4PRO and OMNIBUSF4V3_SS directories.
The #else branch at lines 44-46 was unreachable after adding
OMNIBUSF4V3_ICM aliasing. All three targets (OMNIBUSF4PRO,
OMNIBUSF4V3, OMNIBUSF4V3_ICM) always use TIM4/PB9, never TIM12/PB15.
1. Removed outdated 'pad labelled CH5/CH6 on OMNIBUSF4PRO' comments from:
   - OMNIBUSF4/target.h and target.c (wrong target)
   - DYSF4/target.h and target.c (wrong target)
   - OMNIBUSF4V3_SS/target.c (wrong target)

   These comments are only accurate in the OMNIBUSF4PRO directory where
   PC8/PC9 really are labelled CH5/CH6 on the physical board.

2. Removed redundant conditional from OMNIBUSF4PRO/target.c:
   #if (defined(OMNIBUSF4PRO) || defined(OMNIBUSF4V3))
   This is always true since all 3 targets in this directory
   (OMNIBUSF4PRO, OMNIBUSF4V3, OMNIBUSF4V3_ICM) have one of these defined.
Remove orphaned indentation from preprocessor defines that were
previously inside conditional blocks but are now at top level after
the target split.

Files changed:
- OMNIBUSF4/target.h: Fixed 2-space and 4-space orphaned indents
- DYSF4/target.h: Fixed 2-space orphaned indents
- OMNIBUSF4V3_SS/target.h: Fixed extensive 2-space orphaned indents
- OMNIBUSF4PRO/target.h: Fixed 4-space orphaned indent on ADC_CHANNEL_3_PIN

Valid indentation inside active #if blocks was preserved.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The upstream added OMNIBUSF4V3_ICM support to the monolithic
OMNIBUSF4/target.h. This PR moves OMNIBUSF4V3_ICM to the new
OMNIBUSF4PRO/ directory alongside V3.

Resolution:
- OMNIBUSF4/target.h: keep PR version (base target only, no PRO/V3/ICM)
- OMNIBUSF4/CMakeLists.txt: keep PR version (only OMNIBUSF4 here)
- OMNIBUSF4PRO/target.h: add ICM42605 support for OMNIBUSF4V3_ICM,
  which was present in upstream but missing from the split target
…thout reboot

Driver-based providers (MSP, FAKE) leave gpsState.gpsPort NULL because
gpsInit() skips serial port opening for them. If gps_provider is then
changed via CLI to a serial-based provider without rebooting, the next
gpsUpdate() tick dispatches into the serial protocol handler with a NULL
port, causing a hard fault.

Add a guard in gpsUpdate() that returns false early when a serial-based
provider is configured but no port is open. Also guard gpsEnablePassthrough()
which had the same latent NULL dereference.
New board revision ships with BMI270 instead of ICM42688. Adding BMI270
defines on the same SPI1/PA4 allows a single firmware image to serve both
board revisions via INAV's auto-probe at boot.
The nano field in UBX-NAV-TIMEUTC and UBX-NAV-PVT messages is int32_t
and legitimately goes negative near second boundaries. Dividing without
clamping produced a large positive uint16_t (e.g. -50ms → 65486 ms),
setting the RTC ~64 seconds fast on first GPS lock. Once set, rtcHasTime()
prevents correction until reboot.

Clamp to zero before the division on both message handlers.
Remove blocking `delay(1)` calls from SDIO SD-card driver retry logic in
both read and write paths. These delays stalled the flight-control loop
on transient DMA/bus rejections, causing loop overruns and dropped gyro
samples during active blackbox logging.

The retries are naturally paced by the asyncfatfs/blackbox polling loop
(one iteration per PID loop), which eliminates the need for an explicit
delay. By returning SDCARD_OPERATION_BUSY / false immediately on rejection,
the cooperative scheduler continues running other tasks instead of spinning
the CPU for 1 ms per retry.

Impact:
- Eliminates up to ~3 ms of blocking CPU stall per transient rejection
  (3 retries × 1 ms delay at 2 kHz loop rate)
- Retries still occur up to SDCARD_MAX_OPERATION_RETRIES (3) times before
  card reset, preserving the retry-before-reset intent
- Retry spacing now depends on loop rate:
  - 1 kHz loop: 1 ms spacing (same as before)
  - 2-4 kHz loop: 250-500 µs spacing (tighter, safer for fast loops)

Backend audit: sdcard_spi.c, sdmmc_sdio_f4xx.c, and sdmmc_sdio_hal.c
all have no per-block hot-path blocking delays (only init/reset delays).
Move state assignment after confirming DMA operation starts successfully.
Previously, sdcard.state was set to SDCARD_STATE_SENDING_WRITE before the
SD_WriteBlocks_DMA() call. On DMA rejection and retry, the state remained
SENDING_WRITE, causing the next poll cycle to call SD_CheckWrite() on a
transfer that never actually started, leading to stale status
misinterpretation.

This fix mirrors the read-path behavior (sdcardSdio_readBlock) where state
is only set after confirming the DMA operation succeeded. This ensures:
- Retry mechanism works correctly (state stays READY for next attempt)
- Poll cycle sees accurate state
- No risk of invoking completion callbacks for failed operations

This bug becomes critical after removing blocking delays from retry paths,
as retries now happen immediately on the next loop iteration instead of
after 1ms, exposing the state inconsistency more frequently.

Related: commit 146ff56 (introduced the retry logic with this bug)
Roll/pitch/yaw rates are described as a fixed ceiling autotune
respects; in reality, with the default fw_autotune_rate_adjustment
setting, autotune actively rewrites roll_rate/pitch_rate/yaw_rate
while flying. The doc also claimed autotune sets P and I gains,
which hasn't been true since gain the P/I/D-from-FF formula was
removed in 2021. Neither yaw nor the MANUAL-mode no-op were
mentioned.

Rewrites the pre-flight parameter table and flying instructions to
describe what the code actually does: FeedForward is tuned on all
three axes, P/I are never touched, rate tuning depends on flight
mode and fw_autotune_rate_adjustment, and AUTOTUNE has no effect at
all in MANUAL mode.
_logBufferHex() sized a stack buffer using two `const size_t` locals
(charsPerByte, maxBytes). In C, const-qualified objects are not integer
constant expressions, so the array size expression was technically a
variable-length array; recent AppleClang treats reliance on its
extension that folds such expressions back to a constant as an error
under -Werror -Wgnu-folding-constant, breaking build-SITL-Mac.

Replace the const locals with a local enum, whose members are genuine
integer constant expressions in C. The buffer size and behavior are
unchanged (13 + 5*8 + 1 = 54 bytes either way).
STATIC_ASSERT expands to a typedef of a char array sized by the
condition, a common compile-time-assertion trick. This call site's
condition compared GPS_DEGREES_DIVIDER (already 10000000L) against the
floating-point literal 1e7. Per C11 6.6p6, integer constant expressions
may not contain floating constants, so despite being trivially
foldable, AppleClang's -Wgnu-folding-constant -Werror rejects it.

Replace 1e7 with 10000000L to match GPS_DEGREES_DIVIDER's own literal
form, making the condition a pure integer constant expression. No
change to the assertion's truth value or any runtime behavior.
Fix build-SITL-Mac VLA-folding-constant error in log.c (9.1 backport)
LIMIT caps rates at the starting value but isn't strictly
monotonic downward - it can raise a previously-lowered rate
back up toward that ceiling.
docs(autotune): fix fixed-wing autotune docs to match actual behavior
selectedFreq in getGyroAafConfig() was declared int8_t (max 127), but
aafLUT42688[] contains freq values up to 1962. Values above 127 silently
truncated on assignment, corrupting the closest-frequency comparison and
causing the wrong AAF register configuration to be selected. This affected
every board using this gyro at the default 256Hz LPF setting (selected
303Hz instead of the correct 258Hz cutoff). Changed to uint16_t to match
aafConfig_t.freq's own type.
…erflow

Fix int8_t overflow in AAF frequency selection for ICM-42688P/42686P
target/JHEMCUF435: fix UART7 ESC telemetry defaults
fix(gps): guard against NULL serial port when GPS provider changed without reboot
…delay

Fix SDIO blocking delays and state management issues
valeriyc and others added 20 commits July 5, 2026 21:03
Sets the target's two PINIO pins as user-assignable boxes (BOX_PERMANENT_ID_USER1/2)
via targetConfiguration(), per review request on upstream PR #11394.
…-targets

Refactor: Split OMNIBUSF4 family into 4 target directories
Add SOLOGOODF722 target (with config.c for PINIO user boxes)
Update AET-H743-Basic - add bmi088 and bmi270 imu
Add PINIO2 (PB4), CAMERA_CONTROL_PIN (PA8), and ICM42688P IMU support
on the existing SPI1/PA4 gyro bus, matching the current upstream
Betaflight unified-target config for this board.
Flags this pin for the planned 10.0 flexible PWM-capable PINIO feature,
since CAMERA_CONTROL_PIN has no consuming driver in INAV today.
…ntly inert

10.0's planned PWM-capable PINIO feature will give this pin real function;
reword the comment so it doesn't read as a permanent dead end.
USE_IMU_ICM42688P has no registration path anywhere in the tree --
ICM42605, ICM42686P, and ICM42688P share one driver gated only by
USE_IMU_ICM42605, whose WHO_AM_I switch already covers all three.
The block added no behavior; replace it with a comment so a future
reader doesn't mistake it for what enables ICM42688P support here.
- Actually write pinioBoxConfigMutable()->permanentId[n] lines in
  generated config.c; they previously existed only as commented-out
  Python source and never reached the file, so every generated target
  had an empty targetConfiguration() regardless of how many PINIO pins
  it defined.
- Cap the PINIO loop at PINIO_COUNT (4) in both target.h and config.c
  generation -- the target.h loop previously went up to PINIO8 with no
  way to ever wire those beyond what firmware supports.
- Generate CAMERA_CONTROL_PIN when present in the source config, with a
  comment noting it has no consuming driver prior to INAV 10.0's planned
  PWM-capable PINIO feature.
- Warn on stderr when a Betaflight source lists a known-unsupported gyro
  chip (LSM6DSV16X, LSM6DSK320X) instead of silently omitting it.
STM32H743 board with dual ICM42688P gyros (each registered via the shared
USE_IMU_ICM42605 driver, tagged 0/1 on separate SPI buses with CLKIN sync
pins wired as plain timer outputs -- no driver actually consumes CLKIN),
DPS310 baro, MAX7456 OSD, PY25Q128HA flash, 8 motors, 4 servos, and 2
PINIO pins.

TIM4 CH4 (servo 4) requires USE_DSHOT_DMAR, a known H7 DMAMUX quirk where
that channel has no DMA request line otherwise. Motor/servo DMA options
deliberately skip option 8 (DMA2 Stream0) since it's hardwired to ADC1,
which this board also uses for VBAT/current sensing. UART5 is RX-only
(ESC telemetry); its TX pin is wired to PC12, an otherwise-unused pin,
since the H7 UART5 driver requires a real AF-valid TX pin to be defined
even when unused.
These chips reorganize CTRL1_XL/CTRL2_G to hold ODR + operating mode
only (full scale moved to CTRL6_C/CTRL8_XL) with a different ODR bit
encoding than the existing LSM6DSO/DSL/DS3 chips, so they get their
own config sequence (lsm6dxxConfigGenV) via an early-return branch,
leaving the legacy path untouched. Register values cross-checked
against the ST datasheets and atbetaflight's hardware-validated
accgyro_spi_lsm6dsv16x.c.

Also wires DAKEFPVF405/target.h to the driver (shares CS/bus/alignment
with the board's existing gyro options, per its manufacturer config),
since it's the hardware testbed for this change.

Hardware-validated on two physical DAKEFPVF405 units (one per chip):
detection, at-rest/dynamic accel+gyro sanity, and CW90_DEG orientation
sign all confirmed correct.
Fix bf2inav.py PINIO/CAMERA_CONTROL_PIN gaps
…river

Add LSM6DSV16X/LSM6DSK320X support to LSM6DXX accgyro driver
…ingv2

Add BMI270 support to COREWINGF405WINGV2
TIM3 CH3 (LED strip) was assigned DMA option 8 (DMA2 Stream0), the
same stream ADC1 uses for VBAT/current sensing, causing DMA
contention between the two peripherals. Move the LED strip to DMA
option 9 (DMA2 Stream1), which is unclaimed on this target, matching
the fix already applied to the sibling DAKEFPVH743_SLIM target.

Verified on physical hardware: LED strip, VBAT, and current sensing
all work correctly with DSHOT and the LED strip active simultaneously.
…dc-dma

Fix LED strip / ADC1 DMA conflict on DAKEFPVH743PRO
@qodo-code-review

Copy link
Copy Markdown
Contributor

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

Branch Targeting Suggestion

You've targeted the master branch with this PR. Please consider if a version branch might be more appropriate:

  • maintenance-9.x - If your change is backward-compatible and won't create compatibility issues between INAV firmware and Configurator 9.x versions. This will allow your PR to be included in the next 9.x release.

  • maintenance-10.x - If your change introduces compatibility requirements between firmware and configurator that would break 9.x compatibility. This is for PRs which will be included in INAV 10.x

If master is the correct target for this change, no action is needed.


This is an automated suggestion to help route contributions to the appropriate branch.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown

Test firmware build ready — commit e519b69

Download firmware for PR #11697

243 targets built. Find your board's .hex file by name on that page (e.g. MATEKF405SE.hex). Files are individually downloadable — no GitHub login required.

Development build for testing only. Use Full Chip Erase when flashing.

@sensei-hacker sensei-hacker merged commit 1531750 into master Jul 8, 2026
24 checks passed
@sensei-hacker sensei-hacker added this to the 9.1 milestone Jul 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants