Skip to content

Commit f262154

Browse files
Temporary fix for mpu9250 compass (#560)
1 parent e87a213 commit f262154

File tree

3 files changed

+26
-15
lines changed

3 files changed

+26
-15
lines changed

src/main/drivers/compass_ak8963.c

+24-14
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717

1818
#include <stdbool.h>
1919
#include <stdint.h>
20+
#include <string.h>
2021

2122
#include <math.h>
2223

@@ -261,12 +262,13 @@ bool ak8963Read(int16_t *magData)
261262
bool ack = false;
262263
uint8_t buf[7];
263264

264-
// set magData to zero for case of failed read
265-
magData[X] = 0;
266-
magData[Y] = 0;
267-
magData[Z] = 0;
265+
static bool lastReadResult = false;
268266

269267
#if defined(USE_SPI) && defined(MPU9250_SPI_INSTANCE)
268+
static int16_t cachedMagData[3];
269+
270+
// set magData to latest cached value
271+
memcpy(magData, cachedMagData, sizeof(cachedMagData));
270272

271273
// we currently need a different approach for the MPU9250 connected via SPI.
272274
// we cannot use the ak8963SensorRead() method for SPI, it is to slow and blocks for far too long.
@@ -280,12 +282,12 @@ bool ak8963Read(int16_t *magData)
280282
case CHECK_STATUS:
281283
ak8963SensorStartRead(AK8963_MAG_I2C_ADDRESS, AK8963_MAG_REG_STATUS1, 1);
282284
state++;
283-
return false;
285+
return lastReadResult;
284286

285287
case WAITING_FOR_STATUS: {
286288
uint32_t timeRemaining = ak8963SensorQueuedReadTimeRemaining();
287289
if (timeRemaining) {
288-
return false;
290+
return lastReadResult;
289291
}
290292

291293
ack = ak8963SensorCompleteRead(&buf[0]);
@@ -299,22 +301,23 @@ bool ak8963Read(int16_t *magData)
299301
retry = false;
300302
goto restart;
301303
}
302-
return false;
303-
}
304304

305+
lastReadResult = false;
306+
return lastReadResult;
307+
}
305308

306309
// read the 6 bytes of data and the status2 register
307310
ak8963SensorStartRead(AK8963_MAG_I2C_ADDRESS, AK8963_MAG_REG_HXL, 7);
308311

309312
state++;
310313

311-
return false;
314+
return lastReadResult;
312315
}
313316

314317
case WAITING_FOR_DATA: {
315318
uint32_t timeRemaining = ak8963SensorQueuedReadTimeRemaining();
316319
if (timeRemaining) {
317-
return false;
320+
return lastReadResult;
318321
}
319322

320323
ack = ak8963SensorCompleteRead(&buf[0]);
@@ -326,25 +329,32 @@ bool ak8963Read(int16_t *magData)
326329
uint8_t status = buf[0];
327330

328331
if (!ack || (status & STATUS1_DATA_READY) == 0) {
329-
return false;
332+
lastReadResult = false;
333+
return lastReadResult;
330334
}
331335

332336
ack = ak8963SensorRead(AK8963_MAG_I2C_ADDRESS, AK8963_MAG_REG_HXL, 7, &buf[0]);
333337
#endif
338+
334339
uint8_t status2 = buf[6];
335340
if (!ack || (status2 & STATUS2_DATA_ERROR) || (status2 & STATUS2_MAG_SENSOR_OVERFLOW)) {
336-
return false;
341+
lastReadResult = false;
342+
return lastReadResult;
337343
}
338344

339345
magData[X] = -(int16_t)(buf[1] << 8 | buf[0]) * magGain[X];
340346
magData[Y] = -(int16_t)(buf[3] << 8 | buf[2]) * magGain[Y];
341347
magData[Z] = -(int16_t)(buf[5] << 8 | buf[4]) * magGain[Z];
342348

343349
#if defined(USE_SPI) && defined(MPU9250_SPI_INSTANCE)
350+
// cache mag data for reuse
351+
memcpy(cachedMagData, magData, sizeof(cachedMagData));
344352
state = CHECK_STATUS;
345-
return true;
353+
lastReadResult = true;
346354
#else
347-
return ak8963SensorWrite(AK8963_MAG_I2C_ADDRESS, AK8963_MAG_REG_CNTL, CNTL_MODE_ONCE); // start reading again
355+
lastReadResult = ak8963SensorWrite(AK8963_MAG_I2C_ADDRESS, AK8963_MAG_REG_CNTL, CNTL_MODE_ONCE); // start reading again
348356
#endif
357+
358+
return lastReadResult;
349359
}
350360
#endif

src/main/main.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ int main(void)
615615
#endif
616616
#ifdef MAG
617617
setTaskEnabled(TASK_COMPASS, sensors(SENSOR_MAG));
618-
#if defined(MPU6500_SPI_INSTANCE) && defined(USE_MAG_AK8963)
618+
#if (defined(MPU6500_SPI_INSTANCE) || defined(MPU9250_SPI_INSTANCE)) && defined(USE_MAG_AK8963)
619619
// fixme temporary solution for AK6983 via slave I2C on MPU9250
620620
rescheduleTask(TASK_COMPASS, 1000000 / 40);
621621
#endif

src/main/sensors/compass.c

+1
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ void updateCompass(flightDynamicsTrims_t *magZero)
8787
magADC[Z] = 0;
8888
return;
8989
}
90+
9091
for (int axis = 0; axis < XYZ_AXIS_COUNT; axis++) {
9192
magADC[axis] = magADCRaw[axis]; // int32_t copy to work with
9293
}

0 commit comments

Comments
 (0)