Repository navigation
Conversation
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.
Both drivers already route data-ready to INT1; they now describe their read to accgyro_data_ready.c. The BMI270 read starts at ACC_DATA_X_LSB (a dummy byte, accelerometer, gyro), for the secondary too, as the driver's own read does; its pin signals new data of either sensor. The ICM-45686 read starts at ACCEL_DATA_X1_UI (accelerometer, gyro, temperature); its secondary reads the gyro only. Neither has been tested on a board yet, so gyro_data_ready AUTO leaves them polled: ON turns them on.
common_hardware.c passes BMI270_EXTI_PIN and ICM45686_EXTI_PIN to their registrations when the target defines them. BMI270 pins added where INAV and Betaflight's config for the same board agree on the CS pin and SPI bus; in a folder with several targets, only those Betaflight confirms.
|
ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing |
PR Summary by QodoAdd opt-in data-ready gyro reads for BMI270 and IM-45686
AI Description
Diagram
High-Level Assessment
Files changed (139)
|
Code Review by Qodo
1.
|
…et does not enable
|
Test firmware build ready — commit Download firmware for PR #12066 251 targets built. Find your board's
|
|
RAM / Flash usage vs. base commit
See RAM/flash optimization guide for techniques to reduce usage. |
0b96a15 to
3625db6
Compare
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.
AUTO now reads them on their data-ready interrupt as it does the ICM426xx; where no interrupt arrives the gyro is read from its registers as before.
The three share the register layout of accgyro_mpu.c: one read from ACCEL_XOUT_H brings accelerometer, temperature and gyro. INT gives a 50 us pulse at each new sample.
From Betaflight's config for the same board, where it agrees with INAV on the IMU's bus and chip select, the pin is free and the target is F4, F7 or H7.
3625db6 to
e82cc31
Compare
The MPU9250 has the MPU6500's registers and takes the same read. The LSM6DXX drivers already route gyro data-ready, pulsed, to INT1; the read takes the gyro and the accelerometer from OUTX_L_G. The LSM6DSO and LSM6DSL run at 6664 Hz whatever is asked, so with data-ready the gyro task and its first filter run at that rate instead of the MPU table's.
From Betaflight's config for the same board, where both agree on the CS pin and SPI bus. DAKEFPVF722X8 already declared LSM6DXX_EXTI_PIN PC4, which matches; the registration now passes it.
The comparison script read a #define without a value as swallowing the next line, so some CS and interrupt pins were never compared. With that fixed, the same rule adds these: Betaflight's config for the same board agrees on CS and bus, the pin is free, and its port is enabled. None of the pins added before changes.
…Betaflight comparison missed
…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)
|
PG note (corrected): this PR appends a field to the end of |
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.
|
@sensei-hacker first run on hardware today: a Holybro Kakute H7 Mini with a BMI270 on SPI4 (interrupt PE1), image merged on the current maintenance-10.x. The interrupt is taken, GYRO task 26 -> 1 us, IMU at rest clean with gyro 0, moved by hand the gyro and accelerometer agree to 7 degrees, 173 s blackbox on its NAND flash with GYRO_RAW and ACC; details in the description. The ICM-45686, LSM6DXX and MPU IMUs remain untested. Is there anything else you would like tested? |
# Conflicts: # src/main/drivers/bus_spi_hal_ll.c
|
Thanks for the PR, and for the pin work across so many boards! I looked at this with an AI-based tool (Claude Code) that read the diff, built it on 16 targets and ran tests on a few boards. It may be wrong on any of these points, so please treat them as questions and correct me where I have misread something. Which IMUs have actually run?
Here is what I know has run on hardware, yours and ours together:
If I have read that right, F4, F7 and H7 are each covered, and so are the ICM426xx, BMI270 and LSM6DXX, so those three flags look reasonable to me. I would not ask for every IMU on every MCU. The two without any run are ICM-45686 and the MPU descriptor. Do you know of any other runs I have missed? If not, would you be open to LSM6DXX rateWhen data-ready is wanted, the driver reports 150 us (6664 Hz) and the gyro task runs at that rate. Do you know what happens if data-ready then fails to start (for example no free DMA streams on an F4)? The description says the task polls at 150 us in that case, which I could not exercise. Have you been able to try that fallback? Testing wantedIf anyone has these boards, a short bench run would help: an ICM-45686 (the TBS Lucid H7 has one), and an MPU6000 or MPU6500 board; MPU9250 and ICM-20689 too if the descriptor stays shared. The thing to look at in each case is the Because this makes data-ready the default on untested IMUs, I have set it to 10.1 with Testing Required. |
Neither has run on data-ready yet, so their drivers are not marked tested: AUTO keeps polling them and ON still turns it on. The MPU drivers write INT_PIN_CFG and INT_ENABLE only when data-ready will read the pin, so with AUTO an MPU is configured as before this PR.
|
Thanks for running it, and for the table. Which IMUs have run. Your table is complete as far as I know: I have run the ICM-42688-P and the BMI270 only, and I have no board with an ICM-45686 or an MPU. And yes, I agree, and I've set LSM6DXX rate. I have no LSM6DXX board, so the fallback is untried on hardware. In the code it is as the description says: the gyro task period is set in |
Depends on #12065, which depends on #12064. Their commits show here until they are merged, with copies of their later changes; the rest are this PR: the BMI270 and ICM-45686 read on their data-ready interrupt and their pins, then the MPU6000, MPU6500 and ICM-20689 read and their pins, then the MPU9250 and LSM6DXX read and their pins.
CI needs #12075. The red
build (7)here is KAKUTEH7WING failing incommon/log.c: the settings generator dropsUSE_LOGfor that target because of how it reads the compiler's output, not because of this code. #12075 fixes the generator. The same tree builds locally.On by default for the BMI270 and the LSM6DXX, the two IMUs this PR adds that have run on hardware (BMI270 on a Holybro Kakute H7 Mini, see below; LSM6DXX on a DAKEFPVF405, in the review), as it already is for the ICM426xx with #12064 and #12065. With
gyro_data_ready = AUTO(the default) they read on data-ready where the target declares the pin. The ICM-45686 and the MPU IMUs have not run yet: they read on data-ready withgyro_data_ready = ON, and with AUTO their drivers set the IMU up as before. Where no interrupt comes the gyro is read from its registers as before.set gyro_data_ready = OFFgoes back to polling.What changes
The data-ready PR put the reading in
accgyro_data_ready.c, common to gyro drivers. A driver only describes its read: which registers, how to decode them, its own register read for when samples stop coming, and whether it has run on hardware, one flag per driver that decides whatgyro_data_ready = AUTOreads on data-ready. This PR adds the BMI270, the ICM-45686, the LSM6DXX and the MPU family to it: MPU6000, MPU6500 (with the ICM-20602 and ICM-20608 its driver runs), MPU9250 and ICM-20689, which share their register layout inaccgyro_mpu.c.The BMI270, ICM-45686 and LSM6DXX drivers already route their data-ready signal to INT1, active high and push-pull (a pulse on the LSM6DXX). The MPU drivers did not: they now set
INT_PIN_CFGandINT_ENABLEfor a 50 µs pulse at each new sample, at the initialisation speed, since the MPU6000 takes register writes at 1 MHz at most.ACC_DATA_X_LSB: a dummy byte, accelerometer, gyro (13 bytes)ACCEL_DATA_X1_UI: accelerometer, gyro, temperature (14 bytes)GYRO_DATA_X1_UI(6)ACCEL_XOUT_H: accelerometer, temperature, gyro (14 bytes)GYRO_XOUT_H(6)OUTX_L_G: gyro, accelerometer (12 bytes)OUTX_L_G(6)The BMI270 read is the one its driver already does: the driver reads accelerometer and gyro in one transfer for every gyro, primary or secondary, and the accelerometer takes its values from there. So the secondary reads the same 13 bytes, as Betaflight's data-ready read does; its INT1 signals new data of either sensor, and no data-ready flag is left set. The BMI270 sends one dummy byte before its data on SPI; the decoding skips it, as the driver does. Its temperature stays a register read, as today.
The LSM6DXX driver reads no temperature, so neither does its data-ready read. The LSM6DSO and LSM6DSL run at 6664 Hz whatever INAV asks, while the driver reports the rate of the MPU table (4 kHz), and the gyro task and its first filter run at that rate. Polled, that is consistent: each read takes the latest sample. On data-ready every sample reaches the filter, so where data-ready will start (a pin, and
gyro_data_readynot OFF) the driver reports the chip's 150 µs and both run at 6664 Hz. If data-ready then cannot start, the task polls at the same 150 µs, which reads each sample once. The LSM6DSV16X and LSM6DSK320X already report their 8 kHz.Everything else is shared with the ICM426xx, which ran on the bench: the queue, the pause of a gyro nobody reads, the fallback to register reads when samples stop for 2 ms, the SPI and DMA side.
Targets
common_hardware.cpassesBMI270_EXTI_PIN,ICM45686_EXTI_PIN,MPU6000_EXTI_PIN,MPU6500_EXTI_PINandMPU9250_EXTI_PIN(on SPI),ICM20689_EXTI_PINandLSM6DXX_EXTI_PINto their registrations when the target defines them.BMI270 pins added, from Betaflight's config for the same board where both configs agree on the CS pin and SPI bus. In a folder with several targets, only those Betaflight confirms:
GYRO_INT_EXTI; FLYWOOF745 (and NANO) and SPEEDYBEEF745AIO PE1; GEPRCF722_BT_HD, GEPRC_F722_AIO (and _UART3) and IFLIGHT_BLITZ_F7_PRO PA8; IFLIGHT_BLITZ_F7_AIO and IFLIGHT_H743_AIO_V2 PD0; KAKUTEH7 (and MINI, V2) PE1; MATEKF405TE (and _SD) PC15Already passing a BMI270 pin, which matches Betaflight: AOCODARCH7DUAL, DAKEFPVF722X8, DAKEFPVH743, DAKEFPVH743PRO, DAKEFPVH743_SLIM, and HAKRCF722V2 (from #12065).
MPU6000 pins added:
MPU6500 (also ICM-20602 and ICM-20608) pins added:
ICM-20689 pins added:
MPU9250 pins added:
Already passing an MPU pin that matches Betaflight: 21 MPU6000 and 6 MPU6500 target variants.
LSM6DXX pins added: PC4 on DAKEFPVF405 and DAKEFPVF722, the pin their MPU and BMI270 already use. DAKEFPVF722X8 already declared PC4, which matches Betaflight, and now gets it passed.
Pins my first comparison missed, added with the same rule: the script read a
#definewithout a value as swallowing the next line, so some CS and interrupt pins were never compared. With that fixed, none of the pins above changes, and these are added:Every data-ready pin in the tree (182) is on a port its target enables.
ICM-45686: only the TBS Lucid H7 family has it. The data-ready PR already gives TBS_LUCID_H7 and TBS_LUCID_H7_WING their pins, and TBS_LUCID_H7_OEM and V3 had them. TBS_LUCID_H7_WING_MINI passes none, and Betaflight has no config to take them from.
Left out: AT32 boards, where the data-ready read does not exist yet; DAKEFPVH743's second IMU, where INAV and Betaflight disagree on the bus; OMNIBUSF7, whose variants have different MPU6500 pins; FF_PIKOF4, FIREWORKSV2, FOXEERF722DUAL and MAMBAH743, where only some variants are confirmed and the registrations are shared; two MPU6500 pins that the target uses for something else; the targets with no Betaflight config to compare against (51 BMI270, 86 MPU6000, 49 MPU6500, 12 MPU9250, 3 ICM-20689 and 6 LSM6DXX variants), among them ORBITH743v2, which declares an LSM6DXX pin its own registration does not pass; the BMI088, BMI160 and ICM-40609-D, for which Betaflight declares no pin on any INAV board.
Size
Against #12065:
The MPU part, against #12065 with data-ready on by default:
KAKUTEF7, KAKUTEF7HDV, MATEKF722, MATEKF405, OMNIBUSF4, SPEEDYBEEF7 and MATEKH743 build without warnings.
The MPU9250 and LSM6DXX part, against the MPU part:
KAKUTEF7 and KAKUTEF7HDV keep fitting their ITCM (99.07 % and 98.88 %). All of these build without warnings.
Built without warnings on these, and on BETAFPVF411 (95.4% of its flash), GEPRCF745_BT_HD (ITCM at 97.9%), SPEEDYBEEF405V3, SPEEDYBEEF7MINIV2 and TBS_LUCID_H7_WING_MINI.
Not tested, testing wanted
Only the BMI270 has run this, on one H7 board. Please try it on a board with one of the other IMUs from the lists above, props off first.
get gyro_data_readyshowsAUTO, the default.resourcelists the gyro's interrupt pin asMPU1 EXTI. If it does not, data-ready was not set up.set gyro_data_ready = OFFand please report it.tasks: the GYRO task average drops by several µs.GYRO_RAWandACC, board still and moving.A report of which board, which gyro, which MCU, and what was checked is very welcome, even if everything simply works.
After review
Built on F4, F7, H7, AT32 and SITL; KAKUTEF7 and KAKUTEF7HDV fit their ITCM. Run on hardware with a BMI270 only (see below).
Tested on more boards (2026-10-06)
Testing: the branch has maintenance-10.x merged in since 066dbe0, 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 a Holybro Kakute H7 Mini, BMI270 on SPI4 with its interrupt on PE1, image merged on
maintenance-10.x f6579d2:
resourceE01: MPU1 EXTI, GYRO task 26 -> 1 us average, IMU at rest (46, -4, 510) noise0.4 and gyro 0 (no byte out of place), moved by hand 20 s with gyro and accelerometer agreeing to 7 deg (78 deg with
the signs flipped), 173 s blackbox on the board's NAND flash with GYRO_RAW and ACC clean. The ICM-45686, LSM6DXX and
MPU IMUs remain untested.
After review (2026-10-19)
ONstill reads them on data-ready, and with AUTO the MPU drivers no longer writeINT_PIN_CFGandINT_ENABLE, so an MPU is set up as before this PR. Thegyro_data_readydescription and docs/Settings.md say which IMUs AUTO covers. Flash +32 B on MATEKF722SE, -48 B on MATEKF405, ITCM unchanged; unit tests 620/620.