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:
David Sidrane
2017-07-08 15:37:46 +02:00
committed by Lorenz Meier
parent 270dd5282a
commit aec109ac2c
3 changed files with 59 additions and 32 deletions
+52 -29
View File
@@ -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;
} }
+3 -3
View File
@@ -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:
+4
View File
@@ -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);