Skip to content

AP_Compass: remove IIS2MDC driver and migrate boards to LIS2MDL#33121

Open
dakejahl wants to merge 3 commits into
ArduPilot:masterfrom
dakejahl:delete-iis2mdc-driver
Open

AP_Compass: remove IIS2MDC driver and migrate boards to LIS2MDL#33121
dakejahl wants to merge 3 commits into
ArduPilot:masterfrom
dakejahl:delete-iis2mdc-driver

Conversation

@dakejahl
Copy link
Copy Markdown
Contributor

@dakejahl dakejahl commented May 19, 2026

Summary

Delete the redundant AP_Compass_IIS2MDC driver and switch every board that referenced it to the LIS2MDL driver, which handles the identical silicon. Also gate the LIS2MDL internal-bus auto-probe with if (all_external) so it stops shadowing explicit COMPASS lines on internal buses.

Problem

LIS2MDL and IIS2MDC are the same die — same WHO_AM_I (0x40 at reg 0x4F), same register layout, same axis convention, same sensitivity. ST sells them under separate part numbers (consumer vs industrial grade) but they're electrically and software-identical.

LIS2MDL is default-enabled on boards with >1 MB flash and its internal-bus auto-probe in AP_Compass.cpp lacks the if (all_external) gate that HMC5843/QMC5883L/QMC5883P/IIS2MDC use. So on every board with AP_COMPASS_PROBING_ENABLED and an internal IIS2MDC at I2C 0x1E, the LIS2MDL auto-probe registered the chip first with hard-coded ROTATION_NONE, and the explicit COMPASS IIS2MDC ... ROTATION_XYZ line was blocked by _i2c_sensor_is_registered(). The rotation in the hwdef was silently dropped.

On boards that already used ROTATION_NONE (ARK_FPV, Morakot, navigator) this was invisible. On boards that needed a real rotation (ARK_PI6X YAW_180, CUAV-7-Nano ROLL_90_YAW_270, PrincipIoTH7Pi YAW_270) mag calibration could not converge because the IMU and the compass were misaligned in yaw. Discovered during ARK FMU V6S board bring-up.

Solution

Remove all IIS2MDC driver code, config, enum values, and tooling entries. Gate the LIS2MDL internal-bus auto-probe with if (all_external). Switch the six affected boards from COMPASS IIS2MDC ... to COMPASS LIS2MDL ..., preserving each board's existing rotation: ARK_FPV, ARK_PI6X, CUAV-7-Nano, Morakot, PrincipIoTH7Pi, navigator (Linux).

On boards that enabled AP_COMPASS_PROBING_ENABLED, the LIS2MDL auto-probe was already shadowing the IIS2MDC, so stored COMPASS*_DEV_ID values already carry DEVTYPE_LIS2MDL (0x19). On boards that disabled probing (e.g. PrincipIoTH7Pi), only the explicit COMPASS IIS2MDC ... line ran and 0x18 was actually stored. A PARAMETER_CONVERSION block in Compass::init() rewrites any stored 0x18 to 0x19, preserving bus type/number/address so existing mag calibrations survive the upgrade without forcing users to re-calibrate.

dakejahl added 3 commits May 19, 2026 16:11
LIS2MDL and IIS2MDC are the same die and share WHO_AM_I (0x40 at reg
0x4F), the same register layout, the same axis convention, and the same
sensitivity. ST sells them as separate part numbers (consumer vs
industrial grade) but they are electrically and software-identical, so
having two ArduPilot drivers for them is redundant.

The LIS2MDL driver is default-enabled on boards with >1 MB flash, and
its internal-bus auto-probe lacked the `if (all_external)` gate used by
HMC5843, QMC5883L, QMC5883P, and IIS2MDC. The LIS2MDL auto-probe
therefore claimed every IIS2MDC chip first with ROTATION_NONE
hard-coded, and any explicit `COMPASS IIS2MDC ...` line was then blocked
by `_i2c_sensor_is_registered()`. The rotation declared in the board
hwdef was silently dropped.

Delete the AP_Compass_IIS2MDC driver, the AP_COMPASS_IIS2MDC_ENABLED
config, DRIVER_IIS2MDC, DEVTYPE_IIS2MDC, the IIS2MDC probe block in
`_probe_external_i2c_compasses()`, and the corresponding entries in
Tools/scripts/build_options.py and Tools/scripts/decode_devid.py. Gate
the LIS2MDL internal-bus auto-probe with `if (all_external)` so it stops
shadowing explicit COMPASS lines on internal buses.

Stored COMPASS_DEV_ID values with DEVTYPE_IIS2MDC (0x18) will be
replaced by DEVTYPE_LIS2MDL (0x19) on next boot. In practice no real
unit should have 0x18 stored - the LIS2MDL auto-probe was already
shadowing every IIS2MDC chip - so anyone with a working calibration on
these boards already has 0x19.
The IIS2MDC driver has been removed; LIS2MDL handles the identical
silicon. Switch the COMPASS line on each affected board to LIS2MDL,
preserving the existing rotation:

  ARK_FPV         ROTATION_NONE
  ARK_PI6X        ROTATION_YAW_180
  CUAV-7-Nano     ROTATION_ROLL_90_YAW_270
  Morakot         ROTATION_NONE
  PrincipIoTH7Pi  ROTATION_YAW_270
  navigator       ROTATION_ROLL_180_YAW_270

Also drop the no-longer-valid `define AP_COMPASS_IIS2MDC_ENABLED 1`
lines from each hwdef.
Some boards that referenced the IIS2MDC driver did not enable
`AP_COMPASS_PROBING_ENABLED` (e.g. PrincipIoTH7Pi), so only the explicit
COMPASS line ran on those units and `COMPASS*_DEV_ID` was stored with
the old DEVTYPE_IIS2MDC (0x18) byte. Without this migration, removing
the driver would force every such unit to re-calibrate the
magnetometer, which is painful for users managing fleets.

At Compass::init(), rewrite the devtype byte of every stored
`_state[i].dev_id` and `_priority_did_stored_list[i]` whose devtype is
0x18 (the now-removed DEVTYPE_IIS2MDC) to 0x19 (DEVTYPE_LIS2MDL),
preserving the bus type, bus number, and I2C address. Existing
calibration data, which is keyed off the saved dev IDs, is then
automatically associated with the LIS2MDL driver after upgrade and the
user is not forced to re-calibrate.

The literal 0x18 is used rather than a named constant because the
DEVTYPE_IIS2MDC enum value was removed in the prior commit.
@dakejahl
Copy link
Copy Markdown
Contributor Author

@andyp1per this one is for you

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