17
17
18
18
#include <stdbool.h>
19
19
#include <stdint.h>
20
+ #include <string.h>
20
21
21
22
#include <math.h>
22
23
@@ -261,12 +262,13 @@ bool ak8963Read(int16_t *magData)
261
262
bool ack = false;
262
263
uint8_t buf [7 ];
263
264
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;
268
266
269
267
#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 ));
270
272
271
273
// we currently need a different approach for the MPU9250 connected via SPI.
272
274
// 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)
280
282
case CHECK_STATUS :
281
283
ak8963SensorStartRead (AK8963_MAG_I2C_ADDRESS , AK8963_MAG_REG_STATUS1 , 1 );
282
284
state ++ ;
283
- return false ;
285
+ return lastReadResult ;
284
286
285
287
case WAITING_FOR_STATUS : {
286
288
uint32_t timeRemaining = ak8963SensorQueuedReadTimeRemaining ();
287
289
if (timeRemaining ) {
288
- return false ;
290
+ return lastReadResult ;
289
291
}
290
292
291
293
ack = ak8963SensorCompleteRead (& buf [0 ]);
@@ -299,22 +301,23 @@ bool ak8963Read(int16_t *magData)
299
301
retry = false;
300
302
goto restart ;
301
303
}
302
- return false;
303
- }
304
304
305
+ lastReadResult = false;
306
+ return lastReadResult ;
307
+ }
305
308
306
309
// read the 6 bytes of data and the status2 register
307
310
ak8963SensorStartRead (AK8963_MAG_I2C_ADDRESS , AK8963_MAG_REG_HXL , 7 );
308
311
309
312
state ++ ;
310
313
311
- return false ;
314
+ return lastReadResult ;
312
315
}
313
316
314
317
case WAITING_FOR_DATA : {
315
318
uint32_t timeRemaining = ak8963SensorQueuedReadTimeRemaining ();
316
319
if (timeRemaining ) {
317
- return false ;
320
+ return lastReadResult ;
318
321
}
319
322
320
323
ack = ak8963SensorCompleteRead (& buf [0 ]);
@@ -326,25 +329,32 @@ bool ak8963Read(int16_t *magData)
326
329
uint8_t status = buf [0 ];
327
330
328
331
if (!ack || (status & STATUS1_DATA_READY ) == 0 ) {
329
- return false;
332
+ lastReadResult = false;
333
+ return lastReadResult ;
330
334
}
331
335
332
336
ack = ak8963SensorRead (AK8963_MAG_I2C_ADDRESS , AK8963_MAG_REG_HXL , 7 , & buf [0 ]);
333
337
#endif
338
+
334
339
uint8_t status2 = buf [6 ];
335
340
if (!ack || (status2 & STATUS2_DATA_ERROR ) || (status2 & STATUS2_MAG_SENSOR_OVERFLOW )) {
336
- return false;
341
+ lastReadResult = false;
342
+ return lastReadResult ;
337
343
}
338
344
339
345
magData [X ] = - (int16_t )(buf [1 ] << 8 | buf [0 ]) * magGain [X ];
340
346
magData [Y ] = - (int16_t )(buf [3 ] << 8 | buf [2 ]) * magGain [Y ];
341
347
magData [Z ] = - (int16_t )(buf [5 ] << 8 | buf [4 ]) * magGain [Z ];
342
348
343
349
#if defined(USE_SPI ) && defined(MPU9250_SPI_INSTANCE )
350
+ // cache mag data for reuse
351
+ memcpy (cachedMagData , magData , sizeof (cachedMagData ));
344
352
state = CHECK_STATUS ;
345
- return true;
353
+ lastReadResult = true;
346
354
#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
348
356
#endif
357
+
358
+ return lastReadResult ;
349
359
}
350
360
#endif
0 commit comments