@@ -125,28 +125,36 @@ void ICM20948::update()
125125 float gy = (float )rawGyro[1 ] * gRes - calibration.gyroBias [1 ];
126126 float gz = (float )rawGyro[2 ] * gRes - calibration.gyroBias [2 ];
127127
128- // rawData[14] = ST1: bit 0 is DRDY from AK09916
129- if (magInitialized && (rawData[14 ] & 0x01 )) {
130- mag.timestamp = now;
128+ // Detect new AK09916 data by comparing raw bytes rather than ST1.DRDY.
129+ // The ICM20948 I2C master runs independently at ~1.1 kHz and clears ST1.DRDY
130+ // via ST2 on its first read; subsequent reads within the same accel cycle see
131+ // DRDY=0, so the latched EXT_SLV_SENS_DATA rarely shows DRDY=1 even when the
132+ // mag is producing data normally. The measurement bytes are stable between
133+ // AK09916 conversions, so a value change reliably marks a new sample.
134+ if (magInitialized) {
131135 int16_t mc[3 ];
132136 mc[0 ] = (int16_t )((rawData[16 ] << 8 ) | rawData[15 ]);
133137 mc[1 ] = (int16_t )((rawData[18 ] << 8 ) | rawData[17 ]);
134138 mc[2 ] = (int16_t )((rawData[20 ] << 8 ) | rawData[19 ]);
135-
136- // Remap AK09916 axis to align with ICM20948
137- float mx = ((float )mc[1 ] * mRes - calibration.magBias [1 ]) * calibration.magScale [1 ];
138- float my = ((float )mc[0 ] * mRes - calibration.magBias [0 ]) * calibration.magScale [0 ];
139- float mz = -((float )mc[2 ] * mRes - calibration.magBias [2 ]) * calibration.magScale [2 ];
140-
141- switch (geometryIndex) {
142- case 0 : mag.magX = mx; mag.magY = my; mag.magZ = mz; break ;
143- case 1 : mag.magX = -my; mag.magY = mx; mag.magZ = mz; break ;
144- case 2 : mag.magX = -mx; mag.magY = -my; mag.magZ = mz; break ;
145- case 3 : mag.magX = my; mag.magY = -mx; mag.magZ = mz; break ;
146- case 4 : mag.magX = -mz; mag.magY = -my; mag.magZ = -mx; break ;
147- case 5 : mag.magX = -mz; mag.magY = mx; mag.magZ = -my; break ;
148- case 6 : mag.magX = -mz; mag.magY = my; mag.magZ = mx; break ;
149- case 7 : mag.magX = -mz; mag.magY = -mx; mag.magZ = my; break ;
139+ if (mc[0 ] != prevRawMag[0 ] || mc[1 ] != prevRawMag[1 ] || mc[2 ] != prevRawMag[2 ]) {
140+ prevRawMag[0 ] = mc[0 ]; prevRawMag[1 ] = mc[1 ]; prevRawMag[2 ] = mc[2 ];
141+ mag.timestamp = now;
142+
143+ // Remap AK09916 axis to align with ICM20948
144+ float mx = ((float )mc[1 ] * mRes - calibration.magBias [1 ]) * calibration.magScale [1 ];
145+ float my = ((float )mc[0 ] * mRes - calibration.magBias [0 ]) * calibration.magScale [0 ];
146+ float mz = -((float )mc[2 ] * mRes - calibration.magBias [2 ]) * calibration.magScale [2 ];
147+
148+ switch (geometryIndex) {
149+ case 0 : mag.magX = mx; mag.magY = my; mag.magZ = mz; break ;
150+ case 1 : mag.magX = -my; mag.magY = mx; mag.magZ = mz; break ;
151+ case 2 : mag.magX = -mx; mag.magY = -my; mag.magZ = mz; break ;
152+ case 3 : mag.magX = my; mag.magY = -mx; mag.magZ = mz; break ;
153+ case 4 : mag.magX = -mz; mag.magY = -my; mag.magZ = -mx; break ;
154+ case 5 : mag.magX = -mz; mag.magY = mx; mag.magZ = -my; break ;
155+ case 6 : mag.magX = -mz; mag.magY = my; mag.magZ = mx; break ;
156+ case 7 : mag.magX = -mz; mag.magY = -mx; mag.magZ = my; break ;
157+ }
150158 }
151159 }
152160
0 commit comments