@@ -110,9 +110,9 @@ ADIS16448::ADIS16448(I2CSPIBusOption bus_option, int bus, uint32_t device, enum
110
110
ADIS16448::~ADIS16448 ()
111
111
{
112
112
perf_free (_reset_perf);
113
- perf_free (_perf_crc_bad);
114
113
perf_free (_bad_register_perf);
115
114
perf_free (_bad_transfer_perf);
115
+ perf_free (_perf_crc_bad);
116
116
}
117
117
118
118
int ADIS16448::init ()
@@ -147,9 +147,9 @@ void ADIS16448::print_status()
147
147
I2CSPIDriverBase::print_status ();
148
148
149
149
perf_print_counter (_reset_perf);
150
- perf_print_counter (_perf_crc_bad);
151
150
perf_print_counter (_bad_register_perf);
152
151
perf_print_counter (_bad_transfer_perf);
152
+ perf_print_counter (_perf_crc_bad);
153
153
}
154
154
155
155
int ADIS16448::probe ()
@@ -159,25 +159,24 @@ int ADIS16448::probe()
159
159
PX4_WARN (" Power-On Start-Up Time is 205 ms" );
160
160
}
161
161
162
- const uint16_t PROD_ID = RegisterRead (Register::PROD_ID);
162
+ for (int attempt = 0 ; attempt < 3 ; attempt++) {
163
+ const uint16_t PROD_ID = RegisterRead (Register::PROD_ID);
163
164
164
- if (PROD_ID ! = Product_identification) {
165
- DEVICE_DEBUG ( " unexpected PROD_ID 0x%02x " , PROD_ID );
166
- return PX4_ERROR ;
167
- }
165
+ if (PROD_ID = = Product_identification) {
166
+ const uint16_t SERIAL_NUM = RegisterRead (Register::SERIAL_NUM );
167
+ const uint16_t LOT_ID1 = RegisterRead (Register::LOT_ID1) ;
168
+ const uint16_t LOT_ID2 = RegisterRead (Register::LOT_ID2);
168
169
169
- const uint16_t SERIAL_NUM = RegisterRead (Register::SERIAL_NUM);
170
- const uint16_t LOT_ID1 = RegisterRead (Register::LOT_ID1);
171
- const uint16_t LOT_ID2 = RegisterRead (Register::LOT_ID2);
170
+ PX4_INFO (" Serial Number: 0x%02x, Lot ID1: 0x%02x ID2: 0x%02x" , SERIAL_NUM, LOT_ID1, LOT_ID2);
172
171
173
- PX4_INFO ( " Serial Number: 0x%02x, Lot ID1: 0x%02x ID2: 0x%02x " , SERIAL_NUM, LOT_ID1, LOT_ID2) ;
172
+ return PX4_OK ;
174
173
175
- // Only enable CRC-16 for verified lots (HACK to support older ADIS16448AMLZ with no explicit detection)
176
- if (LOT_ID1 == 0x1824 ) {
177
- _check_crc = true ;
174
+ } else {
175
+ DEVICE_DEBUG ( " unexpected PROD_ID 0x%02x " , PROD_ID);
176
+ }
178
177
}
179
178
180
- return PX4_OK ;
179
+ return PX4_ERROR ;
181
180
}
182
181
183
182
void ADIS16448::RunImpl ()
@@ -208,23 +207,43 @@ void ADIS16448::RunImpl()
208
207
if (hrt_elapsed_time (&_reset_timestamp) > 1000_ms) {
209
208
PX4_DEBUG (" Reset failed, retrying" );
210
209
_state = STATE::RESET;
211
- ScheduleDelayed (100_ms );
210
+ ScheduleDelayed (1000_ms );
212
211
213
212
} else {
214
- PX4_DEBUG (" Reset not complete, check again in 10 ms" );
215
- ScheduleDelayed (10_ms );
213
+ PX4_DEBUG (" Reset not complete, check again in 100 ms" );
214
+ ScheduleDelayed (100_ms );
216
215
}
217
216
}
218
217
219
218
} else {
220
219
RegisterWrite (Register::MSC_CTRL, MSC_CTRL_BIT::Internal_self_test);
221
220
_state = STATE::SELF_TEST_CHECK;
222
- ScheduleDelayed (45_ms ); // Automatic Self-Test Time 45 ms
221
+ ScheduleDelayed (90_ms ); // Automatic Self-Test Time > 45 ms
223
222
}
224
223
225
224
break ;
226
225
227
226
case STATE::SELF_TEST_CHECK: {
227
+ const uint16_t MSC_CTRL = RegisterRead (Register::MSC_CTRL);
228
+
229
+ if (MSC_CTRL & MSC_CTRL_BIT::Internal_self_test) {
230
+ // self test not finished, check again
231
+ if (hrt_elapsed_time (&_reset_timestamp) < 1000_ms) {
232
+ ScheduleDelayed (45_ms);
233
+ PX4_DEBUG (" self test not complete, check again in 45 ms" );
234
+ return ;
235
+
236
+ } else {
237
+ // still not cleared, fail self test
238
+ _self_test_passed = false ;
239
+ _state = STATE::RESET;
240
+ ScheduleDelayed (1000_ms);
241
+ return ;
242
+ }
243
+ }
244
+
245
+ bool test_passed = true ;
246
+
228
247
const uint16_t DIAG_STAT = RegisterRead (Register::DIAG_STAT);
229
248
230
249
if (DIAG_STAT & DIAG_STAT_BIT::Self_test_diagnostic_error_flag) {
@@ -248,6 +267,7 @@ void ADIS16448::RunImpl()
248
267
249
268
if (gyro_x_fail || gyro_y_fail || gyro_z_fail) {
250
269
PX4_ERR (" gyroscope self-test failure" );
270
+ test_passed = false ;
251
271
}
252
272
253
273
// Accelerometer
@@ -257,18 +277,20 @@ void ADIS16448::RunImpl()
257
277
258
278
if (accel_x_fail || accel_y_fail || accel_z_fail) {
259
279
PX4_ERR (" accelerometer self-test failure" );
280
+ test_passed = false ;
260
281
}
282
+ }
261
283
262
- _self_test_passed = false ;
263
- _state = STATE::RESET;
264
- ScheduleDelayed (1000_ms);
265
-
266
- } else {
284
+ if (test_passed) {
267
285
PX4_DEBUG (" self test passed" );
268
286
_self_test_passed = true ;
269
- _state = STATE::RESET;
270
- ScheduleNow ();
287
+
288
+ } else {
289
+ _self_test_passed = false ;
271
290
}
291
+
292
+ _state = STATE::RESET;
293
+ ScheduleDelayed (10_ms);
272
294
}
273
295
274
296
break ;
@@ -364,18 +386,38 @@ void ADIS16448::RunImpl()
364
386
_px4_accel.set_temperature (temperature);
365
387
_px4_gyro.set_temperature (temperature);
366
388
389
+ bool imu_updated = false ;
390
+
367
391
// sensor's frame is +x forward, +y left, +z up
368
392
// flip y & z to publish right handed with z down (x forward, y right, z down)
369
393
const int16_t accel_x = buffer.XACCL_OUT ;
370
394
const int16_t accel_y = (buffer.YACCL_OUT == INT16_MIN) ? INT16_MAX : -buffer.YACCL_OUT ;
371
395
const int16_t accel_z = (buffer.ZACCL_OUT == INT16_MIN) ? INT16_MAX : -buffer.ZACCL_OUT ;
372
396
397
+ if (accel_x != _accel_prev[0 ] || accel_y != _accel_prev[1 ] || accel_z != _accel_prev[2 ]) {
398
+ imu_updated = true ;
399
+
400
+ _accel_prev[0 ] = accel_x;
401
+ _accel_prev[1 ] = accel_y;
402
+ _accel_prev[2 ] = accel_z;
403
+ }
404
+
373
405
const int16_t gyro_x = buffer.XGYRO_OUT ;
374
406
const int16_t gyro_y = (buffer.YGYRO_OUT == INT16_MIN) ? INT16_MAX : -buffer.YGYRO_OUT ;
375
407
const int16_t gyro_z = (buffer.ZGYRO_OUT == INT16_MIN) ? INT16_MAX : -buffer.ZGYRO_OUT ;
376
408
377
- _px4_accel.update (now, accel_x, accel_y, accel_z);
378
- _px4_gyro.update (now, gyro_x, gyro_y, gyro_z);
409
+ if (gyro_x != _gyro_prev[0 ] || gyro_y != _gyro_prev[1 ] || gyro_z != _gyro_prev[2 ]) {
410
+ imu_updated = true ;
411
+
412
+ _gyro_prev[0 ] = gyro_x;
413
+ _gyro_prev[1 ] = gyro_y;
414
+ _gyro_prev[2 ] = gyro_z;
415
+ }
416
+
417
+ if (imu_updated) {
418
+ _px4_accel.update (now, accel_x, accel_y, accel_z);
419
+ _px4_gyro.update (now, gyro_x, gyro_y, gyro_z);
420
+ }
379
421
380
422
// DIAG_STAT bit 7: New data, xMAGN_OUT/BARO_OUT
381
423
if (buffer.DIAG_STAT & DIAG_STAT_BIT::New_data_xMAGN_OUT_BARO_OUT) {
@@ -435,6 +477,27 @@ void ADIS16448::RunImpl()
435
477
436
478
bool ADIS16448::Configure ()
437
479
{
480
+ const uint16_t LOT_ID1 = RegisterRead (Register::LOT_ID1);
481
+
482
+ // Only enable CRC-16 for verified lots (HACK to support older ADIS16448AMLZ with no explicit detection)
483
+ if (LOT_ID1 == 0x1824 ) {
484
+ _check_crc = true ;
485
+
486
+ if (_perf_crc_bad == nullptr ) {
487
+ _perf_crc_bad = perf_alloc (PC_COUNT, MODULE_NAME" : CRC16 bad" );
488
+ }
489
+
490
+ } else {
491
+ _check_crc = false ;
492
+
493
+ for (auto ®_cfg : _register_cfg) {
494
+ if (reg_cfg.reg == Register::MSC_CTRL) {
495
+ reg_cfg.set_bits = reg_cfg.set_bits & ~MSC_CTRL_BIT::CRC16_for_burst;
496
+ break ;
497
+ }
498
+ }
499
+ }
500
+
438
501
// first set and clear all configured register bits
439
502
for (const auto ®_cfg : _register_cfg) {
440
503
RegisterSetAndClearBits (reg_cfg.reg , reg_cfg.set_bits , reg_cfg.clear_bits );
0 commit comments