mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-10-27 16:33:34 +08:00
ak09916: PX4_ERR if reset/configure is failing after 5s
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019-2020 PX4 Development Team. All rights reserved.
|
* Copyright (c) 2019-2022 PX4 Development Team. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@@ -50,7 +50,6 @@ AK09916::AK09916(const I2CSPIDriverConfig &config) :
|
|||||||
AK09916::~AK09916()
|
AK09916::~AK09916()
|
||||||
{
|
{
|
||||||
perf_free(_reset_perf);
|
perf_free(_reset_perf);
|
||||||
perf_free(_transfer_perf);
|
|
||||||
perf_free(_bad_register_perf);
|
perf_free(_bad_register_perf);
|
||||||
perf_free(_bad_transfer_perf);
|
perf_free(_bad_transfer_perf);
|
||||||
perf_free(_magnetic_sensor_overflow_perf);
|
perf_free(_magnetic_sensor_overflow_perf);
|
||||||
@@ -65,8 +64,6 @@ int AK09916::init()
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
_retries = 2;
|
|
||||||
|
|
||||||
return Reset() ? 0 : -1;
|
return Reset() ? 0 : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,7 +80,6 @@ void AK09916::print_status()
|
|||||||
I2CSPIDriverBase::print_status();
|
I2CSPIDriverBase::print_status();
|
||||||
|
|
||||||
perf_print_counter(_reset_perf);
|
perf_print_counter(_reset_perf);
|
||||||
perf_print_counter(_transfer_perf);
|
|
||||||
perf_print_counter(_bad_register_perf);
|
perf_print_counter(_bad_register_perf);
|
||||||
perf_print_counter(_bad_transfer_perf);
|
perf_print_counter(_bad_transfer_perf);
|
||||||
perf_print_counter(_magnetic_sensor_overflow_perf);
|
perf_print_counter(_magnetic_sensor_overflow_perf);
|
||||||
@@ -91,32 +87,39 @@ void AK09916::print_status()
|
|||||||
|
|
||||||
int AK09916::probe()
|
int AK09916::probe()
|
||||||
{
|
{
|
||||||
const uint8_t WIA1 = RegisterRead(Register::WIA1);
|
// 3 retries
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
|
||||||
if (WIA1 != Company_ID) {
|
const uint8_t WIA1 = RegisterRead(Register::WIA1);
|
||||||
DEVICE_DEBUG("unexpected WIA1 0x%02x", WIA1);
|
const uint8_t WIA2 = RegisterRead(Register::WIA2);
|
||||||
return PX4_ERROR;
|
|
||||||
|
if ((WIA1 == Company_ID) && (WIA2 == Device_ID)) {
|
||||||
|
return PX4_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WIA1 != Company_ID) {
|
||||||
|
DEVICE_DEBUG("unexpected WIA1 0x%02x", WIA1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WIA2 != Device_ID) {
|
||||||
|
DEVICE_DEBUG("unexpected WIA2 0x%02x", WIA2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8_t WIA2 = RegisterRead(Register::WIA2);
|
return PX4_ERROR;
|
||||||
|
|
||||||
if (WIA2 != Device_ID) {
|
|
||||||
DEVICE_DEBUG("unexpected WIA2 0x%02x", WIA2);
|
|
||||||
return PX4_ERROR;
|
|
||||||
}
|
|
||||||
|
|
||||||
return PX4_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AK09916::RunImpl()
|
void AK09916::RunImpl()
|
||||||
{
|
{
|
||||||
|
const hrt_abstime now = hrt_absolute_time();
|
||||||
|
|
||||||
switch (_state) {
|
switch (_state) {
|
||||||
case STATE::RESET:
|
case STATE::RESET:
|
||||||
perf_count(_reset_perf);
|
perf_count(_reset_perf);
|
||||||
// CNTL3 SRST: Soft reset
|
// CNTL3 SRST: Soft reset
|
||||||
RegisterWrite(Register::CNTL3, CNTL3_BIT::SRST);
|
RegisterWrite(Register::CNTL3, CNTL3_BIT::SRST);
|
||||||
_reset_timestamp = hrt_absolute_time();
|
_reset_timestamp = now;
|
||||||
_consecutive_failures = 0;
|
_failure_count = 0;
|
||||||
_state = STATE::WAIT_FOR_RESET;
|
_state = STATE::WAIT_FOR_RESET;
|
||||||
ScheduleDelayed(100_ms);
|
ScheduleDelayed(100_ms);
|
||||||
break;
|
break;
|
||||||
@@ -124,16 +127,14 @@ void AK09916::RunImpl()
|
|||||||
case STATE::WAIT_FOR_RESET:
|
case STATE::WAIT_FOR_RESET:
|
||||||
if ((RegisterRead(Register::WIA1) == Company_ID) && (RegisterRead(Register::WIA2) == Device_ID)) {
|
if ((RegisterRead(Register::WIA1) == Company_ID) && (RegisterRead(Register::WIA2) == Device_ID)) {
|
||||||
// if reset succeeded then configure
|
// if reset succeeded then configure
|
||||||
RegisterWrite(Register::CNTL2, CNTL2_BIT::MODE3);
|
|
||||||
_state = STATE::CONFIGURE;
|
_state = STATE::CONFIGURE;
|
||||||
ScheduleDelayed(100_ms);
|
ScheduleDelayed(100_ms);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// RESET not complete
|
// RESET not complete
|
||||||
if (hrt_elapsed_time(&_reset_timestamp) > 1000_ms) {
|
if (hrt_elapsed_time(&_reset_timestamp) > 30_s) {
|
||||||
PX4_DEBUG("Reset failed, retrying");
|
PX4_ERR("Reset failed, retrying");
|
||||||
_state = STATE::RESET;
|
Reset();
|
||||||
ScheduleDelayed(100_ms);
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
PX4_DEBUG("Reset not complete, check again in 100 ms");
|
PX4_DEBUG("Reset not complete, check again in 100 ms");
|
||||||
@@ -151,26 +152,34 @@ void AK09916::RunImpl()
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
// CONFIGURE not complete
|
// CONFIGURE not complete
|
||||||
if (hrt_elapsed_time(&_reset_timestamp) > 1000_ms) {
|
if (hrt_elapsed_time(&_reset_timestamp) > 30_s) {
|
||||||
PX4_DEBUG("Configure failed, resetting");
|
PX4_ERR("Configure failed, resetting");
|
||||||
_state = STATE::RESET;
|
Reset();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
PX4_DEBUG("Configure failed, retrying");
|
PX4_DEBUG("Configure failed, retrying");
|
||||||
|
ScheduleDelayed(100_ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
ScheduleDelayed(100_ms);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE::READ: {
|
case STATE::READ: {
|
||||||
perf_begin(_transfer_perf);
|
|
||||||
TransferBuffer buffer{};
|
struct TransferBuffer {
|
||||||
const hrt_abstime timestamp_sample = hrt_absolute_time();
|
uint8_t ST1;
|
||||||
|
uint8_t HXL;
|
||||||
|
uint8_t HXH;
|
||||||
|
uint8_t HYL;
|
||||||
|
uint8_t HYH;
|
||||||
|
uint8_t HZL;
|
||||||
|
uint8_t HZH;
|
||||||
|
uint8_t TMPS;
|
||||||
|
uint8_t ST2;
|
||||||
|
} buffer{};
|
||||||
|
|
||||||
uint8_t cmd = static_cast<uint8_t>(Register::ST1);
|
uint8_t cmd = static_cast<uint8_t>(Register::ST1);
|
||||||
int ret = transfer(&cmd, 1, (uint8_t *)&buffer, sizeof(TransferBuffer));
|
int ret = transfer(&cmd, 1, (uint8_t *)&buffer, sizeof(TransferBuffer));
|
||||||
perf_end(_transfer_perf);
|
|
||||||
|
|
||||||
bool success = false;
|
bool success = false;
|
||||||
|
|
||||||
@@ -186,31 +195,39 @@ void AK09916::RunImpl()
|
|||||||
// sensor's frame is +X forward (X), +Y right (Y), +Z down (Z)
|
// sensor's frame is +X forward (X), +Y right (Y), +Z down (Z)
|
||||||
_px4_mag.set_error_count(perf_event_count(_bad_register_perf) + perf_event_count(_bad_transfer_perf)
|
_px4_mag.set_error_count(perf_event_count(_bad_register_perf) + perf_event_count(_bad_transfer_perf)
|
||||||
+ perf_event_count(_magnetic_sensor_overflow_perf));
|
+ perf_event_count(_magnetic_sensor_overflow_perf));
|
||||||
_px4_mag.update(timestamp_sample, x, y, z);
|
|
||||||
|
_px4_mag.update(now, x, y, z);
|
||||||
|
|
||||||
success = true;
|
success = true;
|
||||||
|
|
||||||
_consecutive_failures = 0;
|
if (_failure_count > 0) {
|
||||||
|
_failure_count--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
_failure_count++;
|
||||||
|
|
||||||
|
// full reset if things are failing consistently
|
||||||
|
if (_failure_count > 10) {
|
||||||
|
Reset();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!success || hrt_elapsed_time(&_last_config_check_timestamp) > 100_ms) {
|
if (!success || hrt_elapsed_time(&_last_config_check_timestamp) > 100_ms) {
|
||||||
// check configuration registers periodically or immediately following any failure
|
// check configuration registers periodically or immediately following any failure
|
||||||
if (RegisterCheck(_register_cfg[_checked_register])) {
|
if (RegisterCheck(_register_cfg[_checked_register])) {
|
||||||
_last_config_check_timestamp = timestamp_sample;
|
_last_config_check_timestamp = now;
|
||||||
_checked_register = (_checked_register + 1) % size_register_cfg;
|
_checked_register = (_checked_register + 1) % size_register_cfg;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// register check failed, force reset
|
// register check failed, force reset
|
||||||
perf_count(_bad_register_perf);
|
perf_count(_bad_register_perf);
|
||||||
Reset();
|
Reset();
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_consecutive_failures > 10) {
|
|
||||||
Reset();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -219,9 +236,11 @@ void AK09916::RunImpl()
|
|||||||
|
|
||||||
bool AK09916::Configure()
|
bool AK09916::Configure()
|
||||||
{
|
{
|
||||||
|
_retries = 2;
|
||||||
|
|
||||||
// first set and clear all configured register bits
|
// first set and clear all configured register bits
|
||||||
for (const auto ®_cfg : _register_cfg) {
|
for (const auto ®_cfg : _register_cfg) {
|
||||||
RegisterWrite(reg_cfg.reg, reg_cfg.set_bits);
|
RegisterSetAndClearBits(reg_cfg.reg, reg_cfg.set_bits, reg_cfg.clear_bits);
|
||||||
}
|
}
|
||||||
|
|
||||||
// now check that all are configured
|
// now check that all are configured
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019-2020 PX4 Development Team. All rights reserved.
|
* Copyright (c) 2019-2022 PX4 Development Team. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@@ -64,19 +64,6 @@ public:
|
|||||||
void print_status() override;
|
void print_status() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
struct TransferBuffer {
|
|
||||||
uint8_t ST1;
|
|
||||||
uint8_t HXL;
|
|
||||||
uint8_t HXH;
|
|
||||||
uint8_t HYL;
|
|
||||||
uint8_t HYH;
|
|
||||||
uint8_t HZL;
|
|
||||||
uint8_t HZH;
|
|
||||||
uint8_t TMPS;
|
|
||||||
uint8_t ST2;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct register_config_t {
|
struct register_config_t {
|
||||||
Register reg;
|
Register reg;
|
||||||
uint8_t set_bits{0};
|
uint8_t set_bits{0};
|
||||||
@@ -98,14 +85,13 @@ private:
|
|||||||
PX4Magnetometer _px4_mag;
|
PX4Magnetometer _px4_mag;
|
||||||
|
|
||||||
perf_counter_t _reset_perf{perf_alloc(PC_COUNT, MODULE_NAME": reset")};
|
perf_counter_t _reset_perf{perf_alloc(PC_COUNT, MODULE_NAME": reset")};
|
||||||
perf_counter_t _transfer_perf{perf_alloc(PC_ELAPSED, MODULE_NAME": transfer")};
|
|
||||||
perf_counter_t _bad_register_perf{perf_alloc(PC_COUNT, MODULE_NAME": bad register")};
|
perf_counter_t _bad_register_perf{perf_alloc(PC_COUNT, MODULE_NAME": bad register")};
|
||||||
perf_counter_t _bad_transfer_perf{perf_alloc(PC_COUNT, MODULE_NAME": bad transfer")};
|
perf_counter_t _bad_transfer_perf{perf_alloc(PC_COUNT, MODULE_NAME": bad transfer")};
|
||||||
perf_counter_t _magnetic_sensor_overflow_perf{perf_alloc(PC_COUNT, MODULE_NAME": magnetic sensor overflow")};
|
perf_counter_t _magnetic_sensor_overflow_perf{perf_alloc(PC_COUNT, MODULE_NAME": magnetic sensor overflow")};
|
||||||
|
|
||||||
hrt_abstime _reset_timestamp{0};
|
hrt_abstime _reset_timestamp{0};
|
||||||
hrt_abstime _last_config_check_timestamp{0};
|
hrt_abstime _last_config_check_timestamp{0};
|
||||||
unsigned _consecutive_failures{0};
|
int _failure_count{0};
|
||||||
|
|
||||||
enum class STATE : uint8_t {
|
enum class STATE : uint8_t {
|
||||||
RESET,
|
RESET,
|
||||||
@@ -118,6 +104,6 @@ private:
|
|||||||
static constexpr uint8_t size_register_cfg{1};
|
static constexpr uint8_t size_register_cfg{1};
|
||||||
register_config_t _register_cfg[size_register_cfg] {
|
register_config_t _register_cfg[size_register_cfg] {
|
||||||
// Register | Set bits, Clear bits
|
// Register | Set bits, Clear bits
|
||||||
{ Register::CNTL2, CNTL2_BIT::MODE3, 0 },
|
{ Register::CNTL2, CNTL2_BIT::MODE3_SET, CNTL2_BIT::MODE3_CLEAR },
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (c) 2019-2020 PX4 Development Team. All rights reserved.
|
* Copyright (c) 2019-2022 PX4 Development Team. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@@ -93,10 +93,8 @@ enum ST2_BIT : uint8_t {
|
|||||||
// CNTL2
|
// CNTL2
|
||||||
enum CNTL2_BIT : uint8_t {
|
enum CNTL2_BIT : uint8_t {
|
||||||
// MODE[4:0] bits
|
// MODE[4:0] bits
|
||||||
MODE1 = Bit1, // “00010”: Continuous measurement mode 1 (10Hz)
|
MODE3_SET = Bit2 | Bit1, // “00110”: Continuous measurement mode 3 (50Hz)
|
||||||
MODE2 = Bit2, // “00100”: Continuous measurement mode 2 (20Hz)
|
MODE3_CLEAR = Bit4 | Bit3 | Bit0,
|
||||||
MODE3 = Bit2 | Bit1, // “00110”: Continuous measurement mode 3 (50Hz)
|
|
||||||
MODE4 = Bit3, // “01000”: Continuous measurement mode 4 (100Hz)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// CNTL3
|
// CNTL3
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
############################################################################
|
############################################################################
|
||||||
#
|
#
|
||||||
# Copyright (c) 2019-2020 PX4 Development Team. All rights reserved.
|
# Copyright (c) 2019-2022 PX4 Development Team. All rights reserved.
|
||||||
#
|
#
|
||||||
# Redistribution and use in source and binary forms, with or without
|
# Redistribution and use in source and binary forms, with or without
|
||||||
# modification, are permitted provided that the following conditions
|
# modification, are permitted provided that the following conditions
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
*
|
*
|
||||||
* Copyright (c) 2020, 2021 PX4 Development Team. All rights reserved.
|
* Copyright (c) 2019-2022 PX4 Development Team. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
|
|||||||
Reference in New Issue
Block a user