From 712cdc78254c4eca736cc34618719790c8d1f7ff Mon Sep 17 00:00:00 2001 From: Peter Barker Date: Tue, 25 Aug 2026 14:34:10 +1000 Subject: [PATCH] AP_Compass: AK8963: check bus results when calibrating _calibrate() put the device into fuse-ROM access mode and read the three sensitivity adjustment values, but ignored the result of both transfers. It then computed _magnetometer_ASA from the buffer and returned true regardless, so a failed read left the driver calibrating from stack garbage, and a failed mode change left it calibrating from whatever the registers hold outside fuse-ROM mode. Either way its one caller was told the calibration had succeeded. Return false when either transfer fails, which the caller already handles. The driver's other two register_write() calls already propagate their result. Co-Authored-By: Claude Opus 5 --- libraries/AP_Compass/AP_Compass_AK8963.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/libraries/AP_Compass/AP_Compass_AK8963.cpp b/libraries/AP_Compass/AP_Compass_AK8963.cpp index e450913a91d..ed3fafcea4e 100644 --- a/libraries/AP_Compass/AP_Compass_AK8963.cpp +++ b/libraries/AP_Compass/AP_Compass_AK8963.cpp @@ -257,11 +257,19 @@ bool AP_Compass_AK8963::_reset() bool AP_Compass_AK8963::_calibrate() { /* Enable FUSE-mode in order to be able to read calibration data */ - _bus->register_write(AK8963_CNTL1, AK8963_FUSE_MODE | AK8963_16BIT_ADC); + if (!_bus->register_write(AK8963_CNTL1, AK8963_FUSE_MODE | AK8963_16BIT_ADC)) { + // without fuse-ROM access mode the sensitivity adjustment + // registers do not hold the calibration data + return false; + } uint8_t response[3]; - _bus->block_read(AK8963_ASAX, response, 3); + if (!_bus->block_read(AK8963_ASAX, response, 3)) { + // the sensitivity adjustment values were not read; response is + // undefined, so do not calibrate from it + return false; + } for (int i = 0; i < 3; i++) { float data = response[i];