Skip to content

Fix int8_t overflow in AAF frequency selection for ICM-42688P/42686P#11682

Merged
sensei-hacker merged 1 commit into
iNavFlight:release/9.1from
sensei-hacker:fix/icm42688-aaf-freq-overflow
Jul 2, 2026
Merged

Fix int8_t overflow in AAF frequency selection for ICM-42688P/42686P#11682
sensei-hacker merged 1 commit into
iNavFlight:release/9.1from
sensei-hacker:fix/icm42688-aaf-freq-overflow

Conversation

@sensei-hacker

Copy link
Copy Markdown
Member

Summary

getGyroAafConfig() in src/main/drivers/accgyro/accgyro_icm42605.c tracks the running "best candidate" Anti-Alias Filter (AAF) frequency in a local variable selectedFreq declared as int8_t (max value 127). The aafLUT42688[] table (used for ICM-42688P/42686P) contains freq values up to 1962, all stored as uint16_t in aafConfig_t. Any LUT value above 127 silently truncates on assignment to selectedFreq, corrupting the closest-frequency comparison and causing the wrong AAF register configuration to be selected.

This affects every board using the ICM-42688P/42686P gyro at INAV's default hardware LPF setting (GYRO_LPF_256HZ, set unconditionally in gyro.c): the function selects 303Hz instead of the correct 258Hz AAF cutoff.

Changes

  • Changed selectedFreq from int8_t to uint16_t in getGyroAafConfig(), matching the type of aafConfig_t.freq (the field it tracks) and desiredFreq (the value it's compared against).

Testing

  • Wrote a standalone test harness reproducing the exact struct/LUT/algorithm from the source file, confirming the bug: for GYRO_LPF_256HZ (default) on the 42688P table, the buggy code selects 303Hz instead of the correct 258Hz; also reproduced for GYRO_LPF_188HZ on both the 42688P and 42605 tables.
  • Re-ran the same harness with the fix applied — all cases now select the correct closest-frequency LUT entry.
  • Built the AETH743Basic target (uses ICM-42688P, confirmed via WHOAMI-detected ICM42605_VARIANT_42688P at runtime, exercising aafLUT42688[] directly) — build succeeds with zero warnings on the changed file.
  • Verified via manual trace of C integer promotion rules that the ABS() macro (src/main/common/maths.h) has no signed/unsigned hazard now that desiredFreq, selectedFreq, and aafConfigs[i].freq are all uint16_t — both operands promote to signed int before subtraction on all INAV-supported 32-bit targets.

Code Review

Reviewed with inav-code-review agent — approved, no issues found.

Related

This is a long-standing pre-existing bug present on master, maintenance-9.x, maintenance-10.x, and release/9.1. Flagged by Qodo bot review on PR #11681 (a release/9.1 → maintenance-10.x branch-sync merge) and independently verified against the actual file content. Targeting release/9.1 per current branch-basing guidance; this will flow up to maintenance-10.x via the normal release/9.1 → maintenance-10.x merge process.

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.
@qodo-code-review

Copy link
Copy Markdown
Contributor

PR Summary by Qodo

Fix AAF frequency selection overflow for ICM-42688P/42686P

🐞 Bug fix 🕐 Less than 10 minutes

Grey Divider

AI Description

• Fix AAF closest-frequency selection by preventing int8 truncation of LUT frequencies.
• Ensure ICM-42688P/42686P selects the correct AAF cutoff for default LPF settings.
Diagram

graph TD
  A["Gyro LPF setting"] --> B["getGyroAafConfig()"] --> C["AAF LUT (42688/42605)"] --> D["selectedFreq (uint16_t)"] --> E["Closest match"] --> F["AAF registers"]
  subgraph Legend
    direction LR
    _cfg["Config/input"] ~~~ _fn["Function"] ~~~ _tbl["Lookup table"]
  end
Loading
High-Level Assessment

The PR’s approach is the correct minimal fix: use a wide enough type (uint16_t) for selectedFreq to match the LUT frequency domain and prevent truncation. Alternatives like casting during comparisons or using a separate delta-only variable add complexity without improving correctness.

Files changed (1) +1 / -1

Bug fix (1) +1 / -1
accgyro_icm42605.cPrevent AAF LUT frequency truncation during closest-match selection +1/-1

Prevent AAF LUT frequency truncation during closest-match selection

• Changes getGyroAafConfig() to track the running selected frequency as uint16_t instead of int8_t. This prevents overflow/truncation when LUT entries exceed 127Hz (notably on the ICM-42688P/42686P table), restoring correct closest-frequency selection.

src/main/drivers/accgyro/accgyro_icm42605.c

@qodo-code-review

Copy link
Copy Markdown
Contributor

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0)

Grey Divider

Great, no issues found!

Qodo reviewed your code and found no material issues that require review

Grey Divider

Qodo Logo

@sensei-hacker sensei-hacker merged commit 449a645 into iNavFlight:release/9.1 Jul 2, 2026
22 checks passed
@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

Test firmware build ready — commit 1ffa80b

Download firmware for PR #11682

240 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.

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.

1 participant