mirror of
https://gitee.com/mirrors_PX4/PX4-Autopilot.git
synced 2026-11-02 10:21:35 +08:00
mpu9250:mag restructure to have proper retires for setup
We want to setup the mag interface with retries and report failurs. Move retry logic to contol point, instead of hiding re-reading the ID in ak8963_check_id. Allow it to fail once to overcome a read of 0 on firt read. after 2 failure report error to console and reset the mpu9250's I2C master (SPI to I2C bridge) The same retry logic is used on the ak8963_read_adjustments with a reset of the I2C master module after 5 fails. If it fails fter 10 retires. Disabel the mad and report the failure on the console, stating it is disabled.
This commit is contained in:
committed by
Lorenz Meier
parent
270dd5282a
commit
aec109ac2c
+52
-29
@@ -41,6 +41,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <px4_config.h>
|
#include <px4_config.h>
|
||||||
|
#include <px4_log.h>
|
||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
@@ -470,18 +471,11 @@ MPU9250_mag::read_reg(unsigned int reg)
|
|||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
MPU9250_mag::ak8963_check_id(void)
|
MPU9250_mag::ak8963_check_id(uint8_t &deviceid)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 5; i++) {
|
deviceid = read_reg(AK8963REG_WIA);
|
||||||
|
|
||||||
uint8_t deviceid = read_reg(AK8963REG_WIA);
|
return (AK8963_DEVICE_ID == deviceid);
|
||||||
|
|
||||||
if (AK8963_DEVICE_ID == deviceid) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -552,42 +546,71 @@ MPU9250_mag::ak8963_read_adjustments(void)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
int
|
||||||
MPU9250_mag::ak8963_setup(void)
|
MPU9250_mag::ak8963_setup(void)
|
||||||
{
|
{
|
||||||
int retries = 10;
|
int retries = 10;
|
||||||
|
|
||||||
/* Configures the parent to act in master mode */
|
do {
|
||||||
if (_interface == nullptr) {
|
|
||||||
uint8_t user_ctrl = _parent->read_reg(MPUREG_USER_CTRL);
|
|
||||||
_parent->write_checked_reg(MPUREG_USER_CTRL, user_ctrl | BIT_I2C_MST_EN);
|
|
||||||
_parent->write_reg(MPUREG_I2C_MST_CTRL, BIT_I2C_MST_P_NSR | BIT_I2C_MST_WAIT_FOR_ES | BITS_I2C_MST_CLOCK_400HZ);
|
|
||||||
|
|
||||||
} else {
|
/* When _interface is null we are using SPI and must
|
||||||
// uint8_t user_ctrl = _parent->read_reg(MPUREG_USER_CTRL);
|
* use the parent interface to configure the device to act
|
||||||
|
* in master mode (SPI to I2C bridge)
|
||||||
|
*/
|
||||||
|
if (_interface == nullptr) {
|
||||||
|
_parent->modify_checked_reg(MPUREG_USER_CTRL, 0, BIT_I2C_MST_EN);
|
||||||
|
_parent->write_reg(MPUREG_I2C_MST_CTRL, BIT_I2C_MST_P_NSR | BIT_I2C_MST_WAIT_FOR_ES | BITS_I2C_MST_CLOCK_400HZ);
|
||||||
|
|
||||||
// // Passthrough mode
|
} else {
|
||||||
// _parent->write_checked_reg(MPUREG_USER_CTRL, user_ctrl & (~BIT_I2C_MST_EN));
|
_parent->modify_checked_reg(MPUREG_USER_CTRL, BIT_I2C_MST_EN, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ak8963_check_id()) {
|
uint8_t id = 0;
|
||||||
::printf("AK8963: bad id\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!ak8963_read_adjustments()) {
|
if (ak8963_check_id(id)) {
|
||||||
if (!retries--) {
|
|
||||||
::printf("AK8963: failed to read adjustment data\n");
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
retries--;
|
||||||
|
|
||||||
|
if (retries < 8) {
|
||||||
|
PX4_ERR("AK8963: bad id %d retries %d", id, retries);
|
||||||
|
_parent->modify_checked_reg(MPUREG_USER_CTRL, 0, BIT_I2C_MST_RST);
|
||||||
|
up_udelay(100);
|
||||||
|
}
|
||||||
|
} while (retries > 0);
|
||||||
|
|
||||||
|
if (retries > 0) {
|
||||||
|
retries = 10;
|
||||||
|
|
||||||
|
while (!ak8963_read_adjustments() && retries) {
|
||||||
|
retries--;
|
||||||
|
PX4_ERR("AK8963: failed to read adjustment data. Retries %d", retries);
|
||||||
|
|
||||||
|
if (retries == 5) {
|
||||||
|
_parent->modify_checked_reg(MPUREG_USER_CTRL, 0, BIT_I2C_MST_RST);
|
||||||
|
up_udelay(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (retries == 0) {
|
||||||
|
PX4_ERR("AK8963: failed to initialize, disabled!");
|
||||||
|
_parent->modify_checked_reg(MPUREG_USER_CTRL, 0, BIT_I2C_MST_RST);
|
||||||
|
_parent->write_reg(MPUREG_I2C_MST_CTRL, 0);
|
||||||
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
write_reg(AK8963REG_CNTL1, AK8963_CONTINUOUS_MODE2 | AK8963_16BIT_ADC);
|
write_reg(AK8963REG_CNTL1, AK8963_CONTINUOUS_MODE2 | AK8963_16BIT_ADC);
|
||||||
|
|
||||||
|
|
||||||
if (_interface == NULL) {
|
if (_interface == NULL) {
|
||||||
/* Configure mpu to internally read ak8963 data */
|
|
||||||
|
/* Configure mpu' I2c Master interface to read ak8963 data
|
||||||
|
* Into to fifo
|
||||||
|
*/
|
||||||
set_passthrough(AK8963REG_ST1, sizeof(struct ak8963_regs));
|
set_passthrough(AK8963REG_ST1, sizeof(struct ak8963_regs));
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return OK;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -104,9 +104,9 @@ public:
|
|||||||
void passthrough_write(uint8_t reg, uint8_t val);
|
void passthrough_write(uint8_t reg, uint8_t val);
|
||||||
void read_block(uint8_t reg, uint8_t *val, uint8_t count);
|
void read_block(uint8_t reg, uint8_t *val, uint8_t count);
|
||||||
|
|
||||||
void ak8963_reset(void);
|
int ak8963_reset(void);
|
||||||
bool ak8963_setup(void);
|
int ak8963_setup(void);
|
||||||
bool ak8963_check_id(void);
|
bool ak8963_check_id(uint8_t &id);
|
||||||
bool ak8963_read_adjustments(void);
|
bool ak8963_read_adjustments(void);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -388,6 +388,10 @@ int MPU9250::reset()
|
|||||||
|
|
||||||
usleep(1000);
|
usleep(1000);
|
||||||
|
|
||||||
|
// Enable I2C bus or Disable I2C bus (recommended on data sheet)
|
||||||
|
|
||||||
|
write_checked_reg(MPUREG_USER_CTRL, is_i2c() ? 0 : BIT_I2C_IF_DIS);
|
||||||
|
|
||||||
// SAMPLE RATE
|
// SAMPLE RATE
|
||||||
_set_sample_rate(_sample_rate);
|
_set_sample_rate(_sample_rate);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user