Skip to content

gyro: read the ICM426xx through its FIFO on data-ready (off by default) - #12067

Open
MrScothh wants to merge 23 commits into
iNavFlight:next-10.1from
MrScothh:feature/gyro-fifo
Open

MrScothh wants to merge 23 commits into
iNavFlight:next-10.1from
MrScothh:feature/gyro-fifo

Conversation

@MrScothh

@MrScothh MrScothh commented Sep 28, 2026 •

Copy link
Copy Markdown
Contributor

Builds on #12065 (data-ready reads on F4 and F7), which builds on #12064 (data-ready on H7) and #12061 (SPI back to back), both merged. Their commits show here until they are merged, with copies of their later changes; the rest are this PR. It does not need #12066.

Off by default. gyro_fifo_samples = 0 keeps the data-ready read of those PRs exactly as it is.

What this adds

With data-ready, the ICM426xx interrupts once per sample and each interrupt starts one SPI read. gyro_fifo_samples (1 to 4) lets the IMU queue that many samples in its FIFO and interrupt once for all of them:

  • The FIFO holds the gyro, and the accelerometer and temperature when the flight controller takes them from this IMU (16-byte packets; 8 bytes with the gyro only). The count is in packets.
  • INT1 fires on the FIFO threshold, and again at every sample while the threshold is still met, so a read that fell behind catches up. Stream mode keeps the newest samples if the FIFO ever fills.
  • One read from FIFO_COUNTH brings the count and the packets: one more packet than the threshold where the read fits, so a single late sample does not leave the reads one behind. Every packet read has left the FIFO, so all of them are decoded, up to the first empty one.
  • A FIFO that is more than two reads behind, a packet out of step, or four reads in a row with packets counted and none held, is flushed from the gyro task. After a pause (the queue full because nobody read it) the FIFO is flushed rather than read again.
  • The temperature in the FIFO is 8 bits at 2.07 per degree; it is scaled to the register's units.
  • The gyro sample queue grows from 8 to 16 samples, two reads' worth at 4 plus margin.
  • If the FIFO needs three flushes for a fault within a second, it gives up for the rest of the session: its interrupt is turned off and the gyro is read from its registers, as with data-ready off.
  • debug_mode = GYRO_FIFO, first gyro: debug[0] flushes, debug[1] samples they dropped, debug[2] samples per read, debug[3] 1 once the FIFO has given up.

Only where it can run. USE_GYRO_FIFO is defined where the ICM426xx driver is built and the target names its interrupt pin (ICM42605_EXTI_PIN, GYRO1_EXTI_PIN or GYRO2_EXTI_PIN): about 100 of the 300 F4, F7 and H7 builds. It carries the FIFO code, the longer read buffers (72 B on F4, 96 B on F7 and H7), the 16-sample queue and gyro_fifo_samples; the other builds keep #12065's.

The trade-off, in the setting's description: fewer interrupts and nothing lost to a late read, but the oldest sample of a group reaches the gyro task up to gyro_fifo_samples sample periods later (1 ms at 4 with a 4 kHz gyro).

Measured

TBS Lucid H7 Wing, ICM-42688-P on SPI1 at 4 kHz, 20 s per setting, counters in a bench build that are not part of this PR:

gyro_fifo_samples reads/s samples/s samples per read time in the interrupts
1 3993 3993 1 every time 0.59 %
2 1996 3992 2 every time 0.37 %
4 998 3992 4 every time 0.23 %

No flush, no packet out of step, no invalid sample in any run. Each setting was also saved five times with the host closing the USB port during the write, plus another 20 saves at 1, all fine (that interaction is handled in #12064).

Size

Against #12065 (7c07383):

Target MCU FIFO Flash RAM
MATEKH743 H743 yes +1296 B +256 B, D2 +512 B
TBS_LUCID_H7_WING H743 yes +1168 B +64 B, D2 +512 B
MATEKF405SE F405 yes +1420 B +320 B
MAMBAF722_2022B F722 yes +1100 B (99.45%) +624 B
MATEKF722SE F722 no +32 B 0
BLUEBERRYF435WING AT32F435 no +24 B 0

Without the FIFO only the debug mode's name is added. Also built on FLASHHOBBYF722 (99.60%, the fullest F722 with the FIFO), KAKUTEF7 and KAKUTEF7HDV (ITCM unchanged) and SITL.

Not tested, testing wanted

  • The ICM-42688-P ran this on two H7 boards and on two F7 boards (Flywoo F722 Pro V2, see below, and Diatone Mamba F722 2022B, comment of 2026-10-07). The ICM-42605 and the ICM-42686-P have the same FIFO registers but are untested, and so is F4.
  • Not flown. With data-ready already on a board, please try set gyro_fifo_samples = 2 on the bench, then check tasks (GYRO task), the Sensors tab (gyro and accelerometer follow the board) and a blackbox log with GYRO_RAW and ACC.

A report of which board and what was checked is very welcome.

After review

Built on F4, F7, H7, AT32 and SITL; KAKUTEF7 and KAKUTEF7HDV fit their ITCM. On the TBS Lucid H7 Wing after review: FIFO at 2 samples, 1996 reads/s and 3992 samples/s, no flush and no packet out of step; 40 saves with the USB port closing, no stop.

After sensei's review of 2026-10-18: the FIFO only where it can run, the limit on flushes, the GYRO_FIFO debug mode, the bus held across a flush and the clear of its flag, 96 B rows on F7 and H7 (whole cache lines). Built on F4, F7, H7, AT32 and SITL, unit tests pass.

On the TBS Lucid H7 Wing (2026-10-20), at rest, 60 s per case, each ICM-42688-P in turn (gyro_to_use 0 on SPI1, 1 on SPI4): with gyro_fifo_samples 2 and 4 every read held 2 and 4 samples (GYRO_FIFO debug), there was no flush and the FIFO never gave up; the GYRO task ran at 3952 to 3984 Hz, 1 to 2 us on average, 7 to 10 us at most. The one flush is at boot, before the gyro task runs: the queue fills, the FIFO pauses and restarts flushed (15 samples), which doesn't count as a fault.

Tested on more boards (2026-10-06)

Testing: the branch has maintenance-10.x merged in since 1ee20ac, with #12032 (H7 SPI2-4 divisors) and #11943 (flash flush), so an image from this head builds as tested below.

Tested 2026-10-06 on an F7, Flywoo F722 Pro V2, gyro_fifo_samples = 2: GYRO task 5 us average (3 with data-ready
alone, 12 polling), IMU at rest acc noise 0.7, gyro 0 +-0.2, moved by hand 25 s consistent (8 deg). Image from this
head on its old base (the F7 has nothing on SPI2-4 at risk); other ICM426xx variants still untested.

The SPI of F7 has a 4-byte FIFO and that of F4 none, so there every
data-ready read goes through two DMA streams. The SPI stays enabled, as
for the main loop's transfers, and setting its DMA requests starts the
read. The streams are taken like on H7, among the options the
reference manual gives each request, at the end of initialisation.

Nobody has tested this on an F4 or F7 board yet, so gyro_data_ready
AUTO leaves it off there: ON turns it on.
Pins added where INAV and Betaflight's config for the same board agree
on the gyro's CS pin and SPI bus. In a folder with several targets the
pin goes only to those Betaflight confirms. Two targets had a pin that
disagreed with Betaflight and is fixed: KAKUTEF4WING (PB12, now PB2)
and AOCODARCF405AIO (PC5, now PC4, as on the rest of the Aocoda F405
family, where PC5 is a PINIO). INAV never read those pins, so the
wrong values never showed.
gyro_fifo_samples (0 to 4, default 0: register reads as before) lets the
ICM426xx queue that many samples in its FIFO and raise its interrupt once
for all of them. One read from FIFO_COUNTH brings the count and the packets,
and the gyro task still gets every sample. A FIFO that falls behind or out
of step is flushed from the gyro task.
@qodo-code-review

Copy link
Copy Markdown
Contributor

ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing

@qodo-free-for-open-source-projects

Copy link
Copy Markdown

PR Summary by Qodo

Add optional ICM426xx FIFO reads on gyro data-ready

✨ Enhancement 🐞 Bug fix ⚙️ Configuration changes 📝 Documentation 🕐 40+ Minutes

Grey Divider

AI Description

• Add opt-in FIFO batching to reduce gyro interrupts while retaining late samples.
• Add interrupt-driven SPI reads, sample queuing, and recovery paths across H7, F4, and F7.
• Declare IMU interrupt pins and document settings; FIFO batching remains off by default.
Diagram

graph TD
  CFG["Gyro settings"] --> IMU["ICM426xx FIFO"] --> IRQ["Data-ready interrupt"] --> BUS["SPI arbitration"] --> DMA["SPI read"] --> DECODE["Packet decoder"] --> QUEUE["Sample queue"] --> TASK["Gyro task"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Keep one register read per data-ready interrupt
  • ➕ Preserves minimum sample latency and avoids FIFO packet recovery.
  • ➖ Retains one interrupt and SPI read per sample; cannot recover samples delayed before a read.
2. Poll and drain the FIFO from the gyro task
  • ➕ Avoids interrupt-driven SPI arbitration and its DMA requirements.
  • ➖ Task scheduling determines read latency and may allow more FIFO backlog.

Recommendation: Keep the opt-in, watermark-triggered FIFO approach: it reduces reads and preserves delayed samples without changing the default register-read behavior. Review its interrupt/DMA failure paths and validate untested IMUs and MCU families before broader enablement.

Files changed (120) +1955 / -134

Enhancement (18) +1722 / -69
config_eeprom.cSuspend interrupt reads before settings writes +5/-0

Suspend interrupt reads before settings writes

• Stops new data-ready SPI reads before flash operations that can stall interrupt handling.

src/main/config/config_eeprom.c

accgyro.cQueue interrupt-acquired gyro samples +33/-0

Queue interrupt-acquired gyro samples

• Adds bounded push and pop operations, retaining queued samples when the ring fills.

src/main/drivers/accgyro/accgyro.c

accgyro.hDescribe gyro data-ready state and sample queue +56/-0

Describe gyro data-ready state and sample queue

• Adds driver capability state, a 16-entry sample ring, and helpers for pending samples and active interrupt reads.

src/main/drivers/accgyro/accgyro.h

accgyro_data_ready.cCoordinate IMU interrupts, FIFO reads, and recovery +324/-0

Coordinate IMU interrupts, FIFO reads, and recovery

• Starts data-ready reads, decodes and queues samples, shares recent accelerometer and temperature data, and falls back to register reads. Flushes stale or misaligned FIFO data and suspends reads for flash writes.

src/main/drivers/accgyro/accgyro_data_ready.c

accgyro_data_ready.hDefine data-ready driver and FIFO contracts +75/-0

Define data-ready driver and FIFO contracts

• Introduces read descriptors, packet outcomes, FIFO callbacks, and gyro data-ready entry points.

src/main/drivers/accgyro/accgyro_data_ready.h

accgyro_icm42605.cImplement ICM426xx FIFO sampling +145/-0

Implement ICM426xx FIFO sampling

• Configures stream-mode FIFO watermark interrupts and parses gyro-only or combined packets, including temperature conversion. Supplies register-read fallback and reuses recent interrupt-acquired accelerometer and temperature values.

src/main/drivers/accgyro/accgyro_icm42605.c

adc.hExpose ADC DMA stream relocation +6/-0

Expose ADC DMA stream relocation

• Declares the F4/F7 operation that can move ADC1 off a stream needed by SPI data-ready DMA.

src/main/drivers/adc.h

adc_stm32f4xx.cClaim and relocate F4 ADC DMA streams +33/-0

Claim and relocate F4 ADC DMA streams

• Registers ADC stream ownership and safely moves ADC1 between eligible streams when another user needs its current stream.

src/main/drivers/adc_stm32f4xx.c

adc_stm32f7xx.cClaim and relocate F7 ADC DMA streams +27/-0

Claim and relocate F7 ADC DMA streams

• Registers ADC stream ownership and adds ADC1 stop, relocation, and restart logic for stream conflicts.

src/main/drivers/adc_stm32f7xx.c

bus_busdev_spi.cArbitrate SPI device transfers and combine register transactions +24/-8

Arbitrate SPI device transfers and combine register transactions

• Acquires the bus around device selection and speed changes. Sends register addresses and payloads as one back-to-back transfer on H7/F7.

src/main/drivers/bus_busdev_spi.c

bus_spi.cAdd F4 DMA-backed data-ready SPI reads +82/-0

Add F4 DMA-backed data-ready SPI reads

• Sets up per-bus transfer buffers and DMA completion handling, including cleanup of stopped reads.

src/main/drivers/bus_spi.c

bus_spi.hExpose interrupt-read and SPI arbitration APIs +21/-0

Expose interrupt-read and SPI arbitration APIs

• Declares data-ready request, initialization, callback, bus acquire/release, and H7/F7 combined-register transfer APIs.

src/main/drivers/bus_spi.h

bus_spi_data_ready.cArbitrate interrupt and main-loop SPI access +179/-0

Arbitrate interrupt and main-loop SPI access

• Defers reads while the main loop owns a bus, bounds waits for unfinished transfers, and disables interrupt reads after repeated failures.

src/main/drivers/bus_spi_data_ready.c

bus_spi_data_ready_dma.cAllocate and drive data-ready DMA streams +251/-0

Allocate and drive data-ready DMA streams

• Selects unowned RX/TX streams across F4, F7, and H7, respects reserved UART streams, and supports ADC relocation where possible.

src/main/drivers/bus_spi_data_ready_dma.c

bus_spi_data_ready_impl.hDefine MCU-specific data-ready SPI interface +65/-0

Define MCU-specific data-ready SPI interface

• Declares hardware read hooks and the DMA stream operations used by the shared arbiter.

src/main/drivers/bus_spi_data_ready_impl.h

bus_spi_hal_ll.cPipeline H7/F7 SPI transfers and add interrupt reads +314/-46

Pipeline H7/F7 SPI transfers and add interrupt reads

• Sends bytes back-to-back, combines address and data, and bounds transfer failure recovery. Adds H7 SPI-FIFO or DMA reads and F7 DMA reads for data-ready requests.

src/main/drivers/bus_spi_hal_ll.c

fc_init.cStart data-ready reads after system initialization +3/-0

Start data-ready reads after system initialization

• Defers gyro interrupt setup until other DMA users have claimed their streams.

src/main/fc/fc_init.c

gyro.cDrain queued samples through gyro processing +79/-15

Drain queued samples through gyro processing

• Passes settings to drivers and starts reads after initialization. Processes each queued sample through calibration and first-stage filtering while retaining register-read behavior.

src/main/sensors/gyro.c

Bug fix (4) +13 / -4
adc_stm32h7xx.cRegister H7 ADC DMA ownership +6/-0

Register H7 ADC DMA ownership

• Claims the ADC DMA stream so opportunistic SPI allocation does not take an active stream.

src/main/drivers/adc_stm32h7xx.c

sdcard_spi.cArbitrate SD-card initialization clocks +3/-0

Arbitrate SD-card initialization clocks

• Acquires the SPI bus around dummy clocks sent without selecting an SD-card device.

src/main/drivers/sdcard/sdcard_spi.c

target.hCorrect shared IMU interrupt pin to PC4 +3/-3

Correct shared IMU interrupt pin to PC4

• Changes the declared MPU6000, MPU6500, and BMI270 interrupt pin from PC5 to PC4.

src/main/target/AOCODARCF405AIO/target.h

target.hCorrect ICM42605 interrupt pin +1/-1

Correct ICM42605 interrupt pin

• Changes the declared IMU interrupt from PB12 to PB2.

src/main/target/KAKUTEF4WING/target.h

Documentation (1) +22 / -0
Settings.mdDocument gyro data-ready and FIFO settings +22/-0

Document gyro data-ready and FIFO settings

• Explains activation, supported IMUs, the FIFO range, and the latency-versus-interrupt trade-off.

docs/Settings.md

Other (97) +198 / -61
CMakeLists.txtBuild the new data-ready modules +4/-0

Build the new data-ready modules

• Adds gyro coordination and SPI data-ready source files to common firmware sources.

src/main/CMakeLists.txt

nvic.hReserve gyro data-ready interrupt priority +2/-0

Reserve gyro data-ready interrupt priority

• Assigns the same priority to data-ready and read-completion interrupts to prevent mutual preemption.

src/main/drivers/nvic.h

settings.yamlExpose data-ready and FIFO settings +16/-0

Expose data-ready and FIFO settings

• Adds AUTO/ON/OFF data-ready selection and an off-by-default FIFO threshold of zero to four samples.

src/main/fc/settings.yaml

gyro.hStore data-ready configuration in gyro settings +14/-0

Store data-ready configuration in gyro settings

• Appends the data-ready mode and FIFO threshold, defines the mode enum, and declares delayed startup.

src/main/sensors/gyro.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Makes the board's IMU interrupt pin available to data-ready reads.

src/main/target/AIKONF4V2/target.h

target.cRegister ICM42605 interrupt pin +1/-1

Register ICM42605 interrupt pin

• Passes the board's declared IMU interrupt pin to its SPI device registration.

src/main/target/AOCODARCF722AIO/target.c

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the IMU interrupt pin needed for optional data-ready reads.

src/main/target/AXISFLYINGF7PRO/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/BETAFPVF722/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Makes the IMU interrupt pin available to data-ready setup.

src/main/target/BLADE_F4/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/BOTWINGF405/target.h

target.hDeclare ICM42605 interrupt on PC13 +1/-0

Declare ICM42605 interrupt on PC13

• Adds the board-specific IMU interrupt pin.

src/main/target/BOTWINGF722/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/BROTHERHOBBYF405V3/target.h

target.cRegister both ICM42605 interrupt pins +2/-2

Register both ICM42605 interrupt pins

• Passes each IMU's interrupt pin into its SPI device registration.

src/main/target/BROTHERHOBBYH743/target.c

target.hDeclare two ICM42605 interrupt pins +2/-0

Declare two ICM42605 interrupt pins

• Maps the primary interrupt to PB2 and the secondary interrupt to PE15.

src/main/target/BROTHERHOBBYH743/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/CADDXF4_AIO_ELRS/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/DAKEFPVF405/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/DAKEFPVF722/target.h

target.cRegister primary IMU interrupt pin +5/-5

Register primary IMU interrupt pin

• Passes the primary slot's interrupt pin to its alternative IMU registrations; the secondary slot remains unchanged.

src/main/target/DAKEFPVH743/target.c

target.hDeclare primary IMU interrupt on PC4 +1/-0

Declare primary IMU interrupt on PC4

• Defines the interrupt pin shared by primary-slot IMU options.

src/main/target/DAKEFPVH743/target.h

target.cRegister both IMU-slot interrupt pins +10/-10

Register both IMU-slot interrupt pins

• Passes each slot's interrupt pin to all of its alternative sensor registrations.

src/main/target/DAKEFPVH743PRO/target.c

target.hDeclare primary and secondary IMU interrupts +2/-0

Declare primary and secondary IMU interrupts

• Maps the two IMU slots to PC4 and PB2.

src/main/target/DAKEFPVH743PRO/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/FLASHHOBBYF405/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/FLASHHOBBYF722/target.h

target.hReuse existing gyro interrupt mapping +1/-0

Reuse existing gyro interrupt mapping

• Assigns the ICM42605 interrupt to GYRO_INT_EXTI.

src/main/target/FLYWOOF405PRO/target.h

target.cRegister ICM42605 interrupt pin +1/-1

Register ICM42605 interrupt pin

• Passes the declared interrupt pin to the ICM42605 SPI device registration.

src/main/target/FLYWOOF722PRO/target.c

target.hDeclare ICM42605 interrupt on PC3 +1/-0

Declare ICM42605 interrupt on PC3

• Adds the board-specific IMU interrupt pin.

src/main/target/FLYWOOF722PRO/target.h

target.hDeclare ICM42605 interrupt on PE1 +1/-0

Declare ICM42605 interrupt on PE1

• Adds the board-specific IMU interrupt pin.

src/main/target/FLYWOOF745/target.h

target.cRegister both ICM426xx interrupt pins +2/-2

Register both ICM426xx interrupt pins

• Passes the primary and secondary interrupt pins to their SPI device registrations.

src/main/target/FLYWOOH743PRO/target.c

target.hDeclare two ICM426xx interrupt pins +2/-0

Declare two ICM426xx interrupt pins

• Maps primary and secondary IMU interrupts to PB2 and PE15.

src/main/target/FLYWOOH743PRO/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/FOXEERF405V2/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/FOXEERF722V4/target.h

target.hDeclare variant-specific ICM42605 interrupt +1/-0

Declare variant-specific ICM42605 interrupt

• Assigns PD0 as the IMU interrupt pin in the applicable variant branch.

src/main/target/FOXEERF745AIO/target.h

target.hDeclare interrupt outside the MAMBAF405 variant +3/-0

Declare interrupt outside the MAMBAF405 variant

• Assigns PC4 to the ICM42605 only where the shared target definition permits it.

src/main/target/FURYF4OSD/target.h

target.hDeclare ICM42605 interrupt on PC3 +1/-0

Declare ICM42605 interrupt on PC3

• Adds the board-specific IMU interrupt pin.

src/main/target/GEPRCF405/target.h

target.hDeclare ICM42605 interrupt on PC3 +1/-0

Declare ICM42605 interrupt on PC3

• Adds the board-specific IMU interrupt pin.

src/main/target/GEPRCF405_BT_HD/target.h

target.hDeclare ICM42605 interrupt on PC3 +1/-0

Declare ICM42605 interrupt on PC3

• Adds the board-specific IMU interrupt pin.

src/main/target/GEPRCF722/target.h

target.hDeclare ICM42605 interrupt on PA8 +1/-0

Declare ICM42605 interrupt on PA8

• Adds the board-specific IMU interrupt pin.

src/main/target/GEPRCF722_BT_HD/target.h

target.cRegister both IMU interrupt pins +4/-4

Register both IMU interrupt pins

• Passes each slot's interrupt pin to its MPU6000 and ICM426xx alternatives.

src/main/target/GEPRCF745_BT_HD/target.c

target.hDeclare two IMU interrupt pins +2/-0

Declare two IMU interrupt pins

• Maps the first IMU to PD0 and the second to PD8.

src/main/target/GEPRCF745_BT_HD/target.h

target.hDeclare ICM42605 interrupt on PA8 +1/-0

Declare ICM42605 interrupt on PA8

• Adds the board-specific IMU interrupt pin.

src/main/target/GEPRC_F722_AIO/target.h

target.cRegister both IMU interrupt pins +4/-4

Register both IMU interrupt pins

• Passes each slot's interrupt pin to its MPU6000 and ICM426xx alternatives.

src/main/target/GEPRC_TAKER_H743/target.c

target.hDeclare two IMU interrupt pins +2/-0

Declare two IMU interrupt pins

• Maps the first IMU to PD0 and the second to PD8.

src/main/target/GEPRC_TAKER_H743/target.h

target.cRegister ICM426xx interrupt pin +1/-1

Register ICM426xx interrupt pin

• Passes the declared interrupt pin into the ICM426xx SPI device registration.

src/main/target/HAKRCF405D/target.c

target.hDeclare ICM42605 interrupt on PC3 +1/-0

Declare ICM42605 interrupt on PC3

• Adds the board-specific IMU interrupt pin.

src/main/target/HAKRCF405D/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/HAKRCF405V2/target.h

target.hDeclare ICM42605 interrupt on PA1 +1/-0

Declare ICM42605 interrupt on PA1

• Adds the board's IMU pin declaration; data-ready SPI support remains limited by MCU build flags.

src/main/target/HAKRCF411D/target.h

target.cRegister both gyro-slot interrupt pins +6/-6

Register both gyro-slot interrupt pins

• Passes the two slot pins to MPU6000, ICM426xx, and BMI270 alternatives on their shared SPI bus.

src/main/target/HAKRCF722V2/target.c

target.hDeclare two gyro interrupt pins +2/-0

Declare two gyro interrupt pins

• Maps the first gyro to PC4 and the second to PB10.

src/main/target/HAKRCF722V2/target.h

target.cRegister both ICM426xx interrupt pins +2/-2

Register both ICM426xx interrupt pins

• Passes each IMU's declared interrupt pin to its SPI device registration.

src/main/target/HAKRCH743/target.c

target.hDeclare two ICM426xx interrupt pins +2/-0

Declare two ICM426xx interrupt pins

• Maps the primary IMU to PB2 and the secondary to PC14.

src/main/target/HAKRCH743/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/HGLRCF405V2/target.h

target.cRegister ICM426xx interrupt pin +1/-1

Register ICM426xx interrupt pin

• Passes the declared interrupt pin into the IMU SPI device registration.

src/main/target/HUMMINGBIRD_FC305/target.c

target.hDeclare ICM42605 interrupt on PB6 +1/-0

Declare ICM42605 interrupt on PB6

• Adds the board-specific IMU interrupt pin.

src/main/target/HUMMINGBIRD_FC305/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/IFLIGHT_BLITZ_F722/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/IFLIGHT_BLITZ_F722_X1/target.h

target.hDeclare ICM42605 interrupt on PD0 +1/-0

Declare ICM42605 interrupt on PD0

• Adds the board-specific IMU interrupt pin.

src/main/target/IFLIGHT_BLITZ_F7_AIO/target.h

target.hDeclare interrupt for the H7 Pro variant +3/-0

Declare interrupt for the H7 Pro variant

• Maps ICM42605 data-ready to PB2 only for the selected board variant.

src/main/target/IFLIGHT_BLITZ_H7_PRO/target.h

target.hReuse existing gyro interrupt mapping +1/-0

Reuse existing gyro interrupt mapping

• Assigns the ICM42605 interrupt to GYRO_INT_EXTI.

src/main/target/JHEF405PRO/target.h

target.hDeclare interrupt for supported Kakute variants +3/-0

Declare interrupt for supported Kakute variants

• Maps ICM42605 data-ready to PC5 only for KAKUTEF4 and KAKUTEF4V2.

src/main/target/KAKUTEF4/target.h

target.hDeclare ICM42605 interrupt on PE1 +1/-0

Declare ICM42605 interrupt on PE1

• Adds the board-specific IMU interrupt pin.

src/main/target/KAKUTEH7/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the IMU interrupt mapping within the applicable board variant.

src/main/target/MAMBAF405_2022A/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the IMU interrupt mapping within the applicable board variant.

src/main/target/MAMBAF722_2022A/target.h

target.cRegister ICM42605 interrupt pin +1/-1

Register ICM42605 interrupt pin

• Passes the variant's declared interrupt pin to its ICM42605 SPI device registration.

src/main/target/MAMBAH743/target.c

target.hDeclare variant-specific ICM42605 interrupts +2/-0

Declare variant-specific ICM42605 interrupts

• Maps the IMU interrupt to PC4 or PE15 according to the selected board variant.

src/main/target/MAMBAH743/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/MATEKF405SE/target.h

target.hDeclare ICM42605 interrupt on PC15 +1/-0

Declare ICM42605 interrupt on PC15

• Adds the board-specific IMU interrupt pin.

src/main/target/MATEKF405TE/target.h

target.cRegister supported IMU interrupt pins +3/-3

Register supported IMU interrupt pins

• Passes the SPI1 interrupt pin to its sensor alternatives and the SPI4 pin to the ICM42605 registration.

src/main/target/MATEKH743/target.c

target.hDeclare SPI1 and SPI4 IMU interrupts +2/-0

Declare SPI1 and SPI4 IMU interrupts

• Maps the relevant IMU interrupt pins to PB2 and PE15.

src/main/target/MATEKH743/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/PRINCIPIOTF7/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/RADIOLINKF405/target.h

target.cRegister ICM426xx interrupt pin +1/-1

Register ICM426xx interrupt pin

• Passes the declared pin to the ICM426xx SPI device registration.

src/main/target/RADIOLINKF722/target.c

target.hDeclare ICM426xx interrupt on PC4 +1/-0

Declare ICM426xx interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/RADIOLINKF722/target.h

target.hDeclare ICM426xx interrupt on PD0 +1/-0

Declare ICM426xx interrupt on PD0

• Adds the interrupt pin in the ICM426xx-equipped variant branch.

src/main/target/SEQUREH7/target.h

target.cRegister ICM42605 interrupt pin +1/-1

Register ICM42605 interrupt pin

• Passes the declared interrupt pin into the IMU SPI device registration.

src/main/target/SIMPLIFLYH7/target.c

target.hDeclare ICM42605 interrupt on PC3 +1/-0

Declare ICM42605 interrupt on PC3

• Adds the board-specific IMU interrupt pin.

src/main/target/SIMPLIFLYH7/target.h

target.hDeclare interrupt for the AIO variant +3/-0

Declare interrupt for the AIO variant

• Maps the ICM42605 interrupt to PC4 only when building SKYSTARSF405AIO.

src/main/target/SKYSTARSF405HD/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/SKYSTARSF405V2/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/SOLOGOODF722/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/SPEDIXF405/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/SPEDIXF722/target.h

target.cRegister both ICM426xx interrupt pins +2/-2

Register both ICM426xx interrupt pins

• Passes the primary and secondary interrupt pins to their SPI device registrations.

src/main/target/SPEDIXH743/target.c

target.hDeclare two ICM426xx interrupt pins +2/-0

Declare two ICM426xx interrupt pins

• Maps the SPI1 IMU to PD7 and the SPI4 IMU to PE4.

src/main/target/SPEDIXH743/target.h

target.hDeclare ICM42605 interrupt on PE9 +1/-0

Declare ICM42605 interrupt on PE9

• Adds the board-specific IMU interrupt pin.

src/main/target/SPEEDYBEEF405AIO/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/SPEEDYBEEF405MINI/target.h

target.cRegister ICM426xx interrupt pin +1/-1

Register ICM426xx interrupt pin

• Passes the declared pin to the ICM426xx SPI device registration.

src/main/target/SPEEDYBEEF405V4/target.c

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/SPEEDYBEEF405V4/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/TAKERF722SE/target.h

target.cRegister both gyro-slot interrupt pins +6/-6

Register both gyro-slot interrupt pins

• Passes each slot's interrupt pin to its alternative IMU registrations.

src/main/target/TBS_LUCID_H7/target.c

target.hDeclare two gyro-slot interrupts +2/-0

Declare two gyro-slot interrupts

• Maps the first gyro to PB2 and the second to PE15.

src/main/target/TBS_LUCID_H7/target.h

target.cRegister both gyro-slot interrupt pins +6/-6

Register both gyro-slot interrupt pins

• Passes each slot's interrupt pin to its alternative IMU registrations.

src/main/target/TBS_LUCID_H7_WING/target.c

target.hDeclare two gyro-slot interrupts +2/-0

Declare two gyro-slot interrupts

• Maps the first gyro to PB2 and the second to PE15.

src/main/target/TBS_LUCID_H7_WING/target.h

target.hDeclare interrupt for TMOTORF7 variant +3/-0

Declare interrupt for TMOTORF7 variant

• Maps the ICM42605 interrupt to PC4 only for TMOTORF7.

src/main/target/TMOTORF7/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/TMOTORF7V2/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/TMOTORVELOXF7V2/target.h

target.hDeclare ICM42605 interrupt on PC4 +1/-0

Declare ICM42605 interrupt on PC4

• Adds the board's IMU interrupt mapping.

src/main/target/WARPF7/target.h

common.hEnable data-ready SPI builds on supported MCU families +5/-0

Enable data-ready SPI builds on supported MCU families

• Defines the feature for STM32F4, F7, and H7 targets.

src/main/target/common.h

common_hardware.cPass optional ICM42605 interrupt pin to SPI registration +4/-1

Pass optional ICM42605 interrupt pin to SPI registration

• Uses a target-defined interrupt pin where present and retains NONE as the fallback.

src/main/target/common_hardware.c

@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Action required

1. H7 gyro reads can send a stale command ✓ Resolved
Description
spiDataReadyDmaSetup() writes the transmit buffer without cleaning its data-cache lines before
spiDataReadyHwStart() gives that buffer to DMA. On H7 DMA-backed reads, including FIFO reads, DMA
can fetch the previous contents from cacheable RAM instead of the register address and dummy bytes.
Code

src/main/drivers/bus_spi_hal_ll.c[R539-540]

+    memset(spiDataReadyTx[device], 0xFF, SPI_DATA_READY_MAX);
+    spiDataReadyTx[device][0] = h->reg;
Evidence
The H7 MPU marks DMA RAM cacheable, setup writes the transmit buffer, and the DMA start passes that
buffer directly to the controller. The existing SDIO transmit path cleans its cache before DMA.

src/main/drivers/memprot_stm32h7xx.c[42-55]
src/main/drivers/bus_spi_hal_ll.c[532-540]
src/main/drivers/bus_spi_hal_ll.c[574-581]
src/main/drivers/sdcard/sdmmc_sdio_hal.c[610-617]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The H7 data-ready transmit buffer is cacheable, but CPU writes are not cleaned before DMA reads it.
## Fix Focus Areas
- src/main/drivers/bus_spi_hal_ll.c[532-543]
- src/main/drivers/bus_spi_hal_ll.c[572-592]
## Recommended Fix
Clean the cache lines covering each transmit buffer after writing its command and dummy bytes and before starting DMA. Ensure the cleaned range meets cache-line alignment requirements.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. A gyro read can start during a save ✓ Resolved
Description
gyroDataReadySuspend() disables the gyro interrupt and marks the stream paused, but its SPI
acquire/release pair leaves an existing pending data-ready request intact. If an interrupt arrived
during an earlier transfer, spiBusRelease() starts that read when suspension releases the bus,
leaving an asynchronous transfer active as the configuration flash write begins.
Code

src/main/drivers/accgyro/accgyro_data_ready.c[R258-261]

+        const SPIDevice bus = d->gyro->busDev->busdev.spi.spiBus;
+        spiBusAcquire(bus);
+        spiBusRelease(bus);
+    }
Evidence
A data-ready request received while a read is active or the bus is held sets pending. Acquiring
the bus does not clear that request, and releasing the final hold starts it; suspension performs
that release immediately before the EEPROM write path proceeds.

src/main/drivers/bus_spi_data_ready.c[119-132]
src/main/drivers/bus_spi_data_ready.c[135-177]
src/main/drivers/accgyro/accgyro_data_ready.c[247-262]
src/main/config/config_eeprom.c[323-331]
src/main/drivers/accgyro/accgyro_data_ready.c[247-261]
src/main/drivers/bus_spi_data_ready.c[119-133]
src/main/drivers/bus_spi_data_ready.c[164-178]
src/main/config/config_eeprom.c[323-342]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Suspension can restart a pending data-ready SPI read immediately before a configuration flash write.
## Fix Focus Areas
- src/main/drivers/accgyro/accgyro_data_ready.c[247-262]
- src/main/drivers/bus_spi_data_ready.c[164-178]
## Recommended Fix
Add an SPI data-ready suspension operation that disables new requests, synchronizes with any active transfer, and clears `pending` without starting another read when the bus is released. Call it from `gyroDataReadySuspend()` instead of the acquire/release pair, and retain the paused state until the gyro task deliberately resumes it.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. FIFO recovery still delivers old samples ✓ Resolved
Description
gyroDataReadyFifoSamples() can mark an overfull FIFO for flushing and then push its packets into
the software queue. When gyroDataReadyRead() performs that flush without a queue-full pause, it
leaves those queued packets in place, so the gyro task processes the backlog that recovery was meant
to discard.
Code

src/main/drivers/accgyro/accgyro_data_ready.c[R204-207]

+    if (d->fifoSamples && (d->paused || d->fifoFlush)) {
+        // What the FIFO holds is old, or out of step with the reads
+        d->driver->fifo->flush(gyro);
+        d->fifoFlush = false;
Evidence
A count above the backlog limit sets fifoFlush, but the same callback continues to enqueue valid
packets. The subsequent recovery resets the software queue only in the separate paused branch.

src/main/drivers/accgyro/accgyro_data_ready.c[152-180]
src/main/drivers/accgyro/accgyro_data_ready.c[200-233]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Flushing an overfull or out-of-step hardware FIFO leaves already-enqueued stale packets available to the gyro task.
## Fix Focus Areas
- src/main/drivers/accgyro/accgyro_data_ready.c[152-180]
- src/main/drivers/accgyro/accgyro_data_ready.c[200-218]
## Recommended Fix
When handling a FIFO recovery flag, discard the corresponding queued samples as well as flushing the hardware FIFO. Synchronize the queue reset with the data-ready callback and retain the existing pause/resume behavior.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can import rules and skills only from the repositories your team follows

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread src/main/drivers/bus_spi_hal_ll.c
Comment thread src/main/drivers/accgyro/accgyro_data_ready.c
Comment thread src/main/drivers/accgyro/accgyro_data_ready.c
@github-actions

github-actions Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

RAM / Flash usage vs. base commit 01a7aa3 — commit 9f5b757

Using the nearest available size baseline: this build contains base commit d02085d, which has no stored baseline yet, so the deltas also include what was merged to the base since 01a7aa3.

Target Flash Δ RAM Δ
MATEKF405 ⚠️ +4352 B (+0.60%) CCM: -4 B (-0.01%)
RAM: +444 B (+0.43%)
MATEKF722 +2600 B (+0.54%) ITCM_RAM: -872 B (-6.96%)
RAM: +580 B (+0.67%)
TCM: +4 B (+0.02%)
MATEKF765 +3996 B (+0.53%) DTCM_RAM: ±0 B (±0.00%)
SRAM1: +648 B (+0.52%)
MATEKH743 ⚠️ +4556 B (+0.57%) D2_RAM: +768 B (+23.53%)
DTCM_RAM: ±0 B (±0.00%)
ITCM_RAM: -896 B (-5.46%)
RAM: +476 B (+0.33%)

See RAM/flash optimization guide for techniques to reduce usage.

@github-actions

github-actions Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Test firmware build ready — commit 9f5b757

Download firmware for PR #12067

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

@MrScothh
MrScothh force-pushed the feature/gyro-fifo branch 2 times, most recently from 1e18810 to 3b813d9 Compare September 28, 2026 19:08
AUTO now reads the ICM-42605 and ICM-42688-P on their data-ready interrupt on every
family. Where no interrupt arrives the gyro is read from its registers as before.
…eads it

Written once at setup, so cleaned once there: nothing at run time. A no-op
today: DMA_RAM is Shareable in the H7 MPU setup and the Cortex-M7 does not
cache it, and on F7, which runs the same setup, INAV leaves the D-cache off.
It matches the invalidate on the reply and stays right should either change.

(cherry picked from commit 4287429)
@sensei-hacker sensei-hacker added this to the 11.0 milestone Oct 4, 2026
@sensei-hacker

sensei-hacker commented Oct 4, 2026 •

Copy link
Copy Markdown
Member

PG note (corrected): this PR appends gyro_fifo_samples to the end of PG_GYRO_CONFIG with a zero default, so it does not need its own version bump or settings reset. It only matters if a released v13 record (with the gyro_data_ready byte from #12064–#12066) existed separately; within one unreleased cycle no bump is needed. Please drop the version bump unless a reviewer finds a reason it is required. Milestone is 10.1.

The new fields are appended with a zero default, so stored settings load as they are: pgLoad copies
the stored bytes over the defaults. On H7 without USE_DUAL_GYRO gyro_data_ready takes the old
record's tail padding, which the reset template leaves at zero.
@MrScothh

MrScothh commented Oct 5, 2026

Copy link
Copy Markdown
Contributor Author

Done in 3285977: the version stays at 12, and gyro_fifo_samples is appended with a zero default too. Details on #12064.

@MrScothh

MrScothh commented Oct 6, 2026

Copy link
Copy Markdown
Contributor Author

@sensei-hacker tested on an F7 today, a Flywoo F722 Pro V2 with gyro_fifo_samples = 2: GYRO task 5 us (3 with data-ready alone, 12 polling), IMU at rest and moved by hand consistent; details in the description. Other ICM426xx variants remain untested. Is there anything else you would like tested?

@MrScothh

MrScothh commented Oct 7, 2026

Copy link
Copy Markdown
Contributor Author

The ICM-42605 has run this now, on two boards at rest (not moved by hand, no log yet):

Board maintenance-10.x (polled) data-ready FIFO, gyro_fifo_samples = 2
E-flite T-28's TBS Lucid H7 Wing (H743) GYRO 3968 Hz, 9 us avg / 13 max 3984 Hz, 2 / 10 us 3984 Hz, 1 / 6 us
Diatone Mamba F722 2022B (F722) 3968 Hz, 12 / 22 us 3891 Hz, 4 / 15 us 3952 Hz, 4 / 29 us

resource shows the interrupt pin as MPU1 EXTI on both (PB2 and PC4). The gyro reads within 1 deg/s of zero and the accelerometer 1.006 g and 1.020 g in every mode. The ICM-42686-P and F4 remain untested.

@MrScothh

MrScothh commented Oct 7, 2026

Copy link
Copy Markdown
Contributor Author

Axes checked with the board moved by hand: the Diatone Mamba F722 2022B (ICM-42605) held in three poses and turned, on maintenance-10.x (polled), on data-ready, and with gyro_fifo_samples = 2. The accelerometer in the held pose and the gyro integrated over the move:

maintenance-10.x data-ready FIFO, 2 samples
nose up, held: acc x +0.40 g +0.29 g +0.49 g
back to level: rotation about y +23 deg +26 deg +27 deg
right side down, held: acc y +0.48 g +0.47 g +0.53 g
right side down: rotation about x +30 deg +27 deg +21 deg
turned 90 deg clockwise: rotation about z -84 deg -91 deg -96 deg

Same axes and signs in all three.

@MrScothh

MrScothh commented Oct 8, 2026

Copy link
Copy Markdown
Contributor Author

A correction to my comments of 2026-10-07 here and on #12064: the E-flite T-28's TBS Lucid H7 Wing and the Diatone Mamba F722 2022B both carry an ICM-42688-P, not an ICM-42605. INAV prints "ICM42605" for the 42605, the 42686-P and the 42688-P alike, and I took the name from status; their WHO_AM_I register reads 0x47. So the ICM-42605 itself is still untested with these PRs; the numbers in those comments stand, for the 42688-P.

# Conflicts:
#	src/main/drivers/bus_spi_hal_ll.c
@sensei-hacker

Copy link
Copy Markdown
Member

Thanks for the PR! I looked at this with an AI-based tool that read the diff and ran it on one F7 board. It may well be wrong on any of these points, so please treat them as questions.

On DAKEFPVF722X8 (F7, ICM-42605), gyro_fifo_samples 0/1/2/4 gave the same tasks load, armed DShot blackbox runs were fine at 1 and 4, and hand motion looked right in the configurator.

Questions

  1. Loss visibility. A flush drops the whole queue silently, and there are no counters or debug output. Would you add a flush / packets-lost counter, perhaps behind a debug mode, so a user who sees odd gyro behaviour can tell?
  2. Flush race. The flush flag looks like it is cleared outside the atomic block. Could the interrupt set it between the read and the clear, losing a flush request?
  3. Flash cost. The FIFO path does not seem to be gated by IMU, so every data-ready target pays about 0.6-1.2 KB, and DAKEFPVF722X8 goes to 98.9% full. Would it work to compile it only for targets that use an ICM426xx?
  4. Merge order. The description says this does not need gyro: BMI270, ICM-45686, LSM6DXX and the MPU IMUs on data-ready #12066, but the branch is not built on it, and it also carries 32f2928, which makes data-ready AUTO by default for the ICM426xx on F4 and F7. Is that commit meant to be here, and which merge order do you expect?
  5. H7 buffer. The 72-byte buffer is not cache-line aligned. That seems harmless while DMA_RAM is uncached, but would aligning it be cheap insurance?
  6. Testing. Has it run on F4 or H7, on ICM42688P, or on a dual-gyro board? I could not check sample order or latency inside a FIFO group (my check ran at 20 Hz).

@sensei-hacker
sensei-hacker changed the base branch from maintenance-10.x to next-10.1 October 18, 2026 06:50
sensei-hacker and others added 3 commits October 18, 2026 03:16
…ebug

USE_GYRO_FIFO is defined only when the ICM426xx driver is built and the
target names its interrupt pin. It carries the FIFO code, the larger
data-ready rows and sample queue, and gyro_fifo_samples; the other data-ready
builds keep the smaller ones (about -0.6 KB flash, -0.4 KB RAM).

Three flushes for a fault within a second make the FIFO give up for the
session: the interrupt is disabled and the gyro is read from its registers.

The flush and the clear of its flag run under one hold of the bus, so no
read starts between them.

The GYRO_FIFO debug mode shows the flushes, the samples they dropped, the
samples per read and whether the FIFO gave up.

On F7 and H7 the rows are 96 B, whole cache lines.
@MrScothh

Copy link
Copy Markdown
Contributor Author

Thanks for testing it.

1. Loss visibility. Agreed, and I've added a limit too. What already guarded it: a FIFO more than two groups behind, a packet out of step or four reads in a row with nothing usable trigger a flush, a full queue pauses the interrupt, and 2 ms without a sample switches to the registers, so a lost interrupt can't freeze the gyro. What it lacked was a limit on the flushes: a fault that keeps raising them would leave the gyro running in fits. Now, if the FIFO needs three flushes for a fault within a second, it gives up for the rest of the session and the gyro is read from its registers, as with data-ready off, the same one-way fallback the data-ready reads have after three stalls. The GYRO_FIFO debug mode shows the flushes, the samples they dropped, the samples per read and whether it gave up.

2. Flush race. Yes, and clearing the flag first isn't enough either: the read still running when the flush begins can raise it again with data from before the flush. The flush and the clear now run under one hold of the bus, so no read starts between them, and a request raised meanwhile can only come from that last read, which is about what the flush empties.

3. Flash cost. Done: USE_GYRO_FIFO is defined only where the ICM426xx driver is built and the target names its interrupt pin (ICM42605_EXTI_PIN, or GYRO1_/GYRO2_EXTI_PIN on the dual-IMU boards), and it takes the FIFO code, the larger buffers and queue, and gyro_fifo_samples with it. That is about 100 of the 300 F4, F7 and H7 builds. Elsewhere it saves about 0.6 KB of flash and 0.4 KB of RAM (MATEKF722SE -560 B / -424 B, KAKUTEF7 -664 B / -384 B). It doesn't spare the tight F722s, which mostly have an ICM426xx with its pin, so they can use it.

4. Merge order. 32f2928 is #12065's "data-ready on by default for the ICM426xx on F4 and F7 too" (93bfebe there), copied here because this PR builds on #12065, not on #12066. The order is #12064, #12065, then this one; #12066 is independent of it.

5. H7 buffer. On H7, DMA_RAM is shareable, which the Cortex-M7 does not cache unless CACR.SIWT is set, and INAV doesn't set it, so the alignment was harmless. The rows are now 96 B anyway, whole cache lines, on F7 and H7, which share this code (192 B more RAM).

6. Testing. So far only with the ICM-42688-P, on H7 and F7 boards: not on F4, not with the other ICM426xx chips and not with both gyros of a dual-gyro board. Inside a group the samples come oldest first, and the oldest is up to gyro_fifo_samples sample periods late, as the setting's description says.

@MrScothh

Copy link
Copy Markdown
Contributor Author

Against an older baseline: the ITCM drop is #12169, merged into next-10.1 since. Most of the rest is #12065, which this PR builds on. This PR's own share against #12065: +1296 B of flash, +512 B of D2_RAM (the FIFO's longer read buffers) and +256 B of RAM on MATEKH743; MATEKF405, MATEKF722 and MATEKF765 have no ICM426xx with its interrupt pin, so no FIFO, and only the debug mode's name (+28 to +36 B).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants