diff --git a/libraries/AP_Compass/AP_Compass_HMC5843.cpp b/libraries/AP_Compass/AP_Compass_HMC5843.cpp index 4418efeebc..5c1bd6b0bf 100644 --- a/libraries/AP_Compass/AP_Compass_HMC5843.cpp +++ b/libraries/AP_Compass/AP_Compass_HMC5843.cpp @@ -197,6 +197,27 @@ bool AP_Compass_HMC5843::re_initialise() } +bool AP_Compass_HMC5843::_detect_version() +{ + _base_config = 0x0; + + if (!write_register(ConfigRegA, SampleAveraging_8<<5 | DataOutputRate_75HZ<<2 | NormalOperation) || + !read_register(ConfigRegA, &_base_config)) { + return false; + } + if (_base_config == (SampleAveraging_8<<5 | DataOutputRate_75HZ<<2 | NormalOperation)) { + /* a 5883L supports the sample averaging config */ + _product_id = AP_COMPASS_TYPE_HMC5883L; + return true; + } else if (_base_config == (NormalOperation | DataOutputRate_75HZ<<2)) { + _product_id = AP_COMPASS_TYPE_HMC5843; + return true; + } else { + /* not behaving like either supported compass type */ + return false; + } +} + // Public Methods ////////////////////////////////////////////////////////////// bool AP_Compass_HMC5843::init() @@ -216,17 +237,11 @@ AP_Compass_HMC5843::init() hal.scheduler->panic(PSTR("Failed to get HMC5843 semaphore")); } - // determine if we are using 5843 or 5883L - _base_config = 0; - if (!write_register(ConfigRegA, SampleAveraging_8<<5 | DataOutputRate_75HZ<<2 | NormalOperation) || - !read_register(ConfigRegA, &_base_config)) { - _i2c_sem->give(); - hal.scheduler->resume_timer_procs(); - return false; + if (!_detect_version()) { + goto errout; } - if ( _base_config == (SampleAveraging_8<<5 | DataOutputRate_75HZ<<2 | NormalOperation)) { - // a 5883L supports the sample averaging config - _product_id = AP_COMPASS_TYPE_HMC5883L; + + if (_product_id == AP_COMPASS_TYPE_HMC5883L) { calibration_gain = 0x60; /* note that the HMC5883 datasheet gives the x and y expected @@ -236,13 +251,6 @@ AP_Compass_HMC5843::init() expected_x = 766; expected_yz = 713; gain_multiple = 660.0f / 1090; // adjustment for runtime vs calibration gain - } else if (_base_config == (NormalOperation | DataOutputRate_75HZ<<2)) { - _product_id = AP_COMPASS_TYPE_HMC5843; - } else { - // not behaving like either supported compass type - _i2c_sem->give(); - hal.scheduler->resume_timer_procs(); - return false; } calibration[0] = 0; @@ -351,6 +359,12 @@ AP_Compass_HMC5843::init() } return success; + +errout: + + _i2c_sem->give(); + hal.scheduler->resume_timer_procs(); + return false; } // Read Sensor data diff --git a/libraries/AP_Compass/AP_Compass_HMC5843.h b/libraries/AP_Compass/AP_Compass_HMC5843.h index 314c473906..c710d069b7 100644 --- a/libraries/AP_Compass/AP_Compass_HMC5843.h +++ b/libraries/AP_Compass/AP_Compass_HMC5843.h @@ -19,6 +19,9 @@ private: bool re_initialise(void); bool read_register(uint8_t address, uint8_t *value); bool write_register(uint8_t address, uint8_t value); + + bool _detect_version(); + uint32_t _retry_time; // when unhealthy the millis() value to retry at AP_HAL::Semaphore* _i2c_sem;