123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- #include "AP_Compass_RM3100.h"
- #include <AP_HAL/AP_HAL.h>
- #include <utility>
- #include <AP_Math/AP_Math.h>
- #include <stdio.h>
- #define RM3100_POLL_REG 0x00
- #define RM3100_CMM_REG 0x01
- #define RM3100_CCX1_REG 0x04
- #define RM3100_CCX0_REG 0x05
- #define RM3100_CCY1_REG 0x06
- #define RM3100_CCY0_REG 0x07
- #define RM3100_CCZ1_REG 0x08
- #define RM3100_CCZ0_REG 0x09
- #define RM3100_TMRC_REG 0x0B
- #define RM3100_MX2_REG 0x24
- #define RM3100_MX1_REG 0x25
- #define RM3100_MX0_REG 0x26
- #define RM3100_MY2_REG 0x27
- #define RM3100_MY1_REG 0x28
- #define RM3100_MY0_REG 0x29
- #define RM3100_MZ2_REG 0x2A
- #define RM3100_MZ1_REG 0x2B
- #define RM3100_MZ0_REG 0x2C
- #define RM3100_BIST_REG 0x33
- #define RM3100_STATUS_REG 0x34
- #define RM3100_HSHAKE_REG 0x34
- #define RM3100_REVID_REG 0x36
- #define CCP0 0xC8
- #define CCP1 0x00
- #define CCP0_DEFAULT 0xC8
- #define CCP1_DEFAULT 0x00
- #define GAIN_CC50 20.0f
- #define GAIN_CC100 38.0f
- #define GAIN_CC200 75.0f
- #define UTESLA_TO_MGAUSS 10.0f
- #define TMRC 0x94
- #define CMM 0x71
- extern const AP_HAL::HAL &hal;
- AP_Compass_Backend *AP_Compass_RM3100::probe(AP_HAL::OwnPtr<AP_HAL::Device> dev,
- bool force_external,
- enum Rotation rotation)
- {
- if (!dev) {
- return nullptr;
- }
- AP_Compass_RM3100 *sensor = new AP_Compass_RM3100(std::move(dev), force_external, rotation);
- if (!sensor || !sensor->init()) {
- delete sensor;
- return nullptr;
- }
- return sensor;
- }
- AP_Compass_RM3100::AP_Compass_RM3100(AP_HAL::OwnPtr<AP_HAL::Device> _dev,
- bool _force_external,
- enum Rotation _rotation)
- : dev(std::move(_dev))
- , force_external(_force_external)
- , rotation(_rotation)
- {
- }
- bool AP_Compass_RM3100::init()
- {
- if (!dev->get_semaphore()->take(HAL_SEMAPHORE_BLOCK_FOREVER)) {
- return false;
- }
- if (dev->bus_type() == AP_HAL::Device::BUS_TYPE_SPI) {
-
- dev->set_read_flag(0x80);
- }
-
- dev->set_retries(10);
-
- uint8_t ccx0;
- uint8_t ccx1;
- uint8_t ccy0;
- uint8_t ccy1;
- uint8_t ccz0;
- uint8_t ccz1;
- if (!dev->read_registers(RM3100_CCX1_REG, &ccx1, 1) ||
- !dev->read_registers(RM3100_CCX0_REG, &ccx0, 1) ||
- !dev->read_registers(RM3100_CCY1_REG, &ccy1, 1) ||
- !dev->read_registers(RM3100_CCY0_REG, &ccy0, 1) ||
- !dev->read_registers(RM3100_CCZ1_REG, &ccz1, 1) ||
- !dev->read_registers(RM3100_CCZ0_REG, &ccz0, 1) ||
- ccx1 != CCP1_DEFAULT || ccx0 != CCP0_DEFAULT ||
- ccy1 != CCP1_DEFAULT || ccy0 != CCP0_DEFAULT ||
- ccz1 != CCP1_DEFAULT || ccz0 != CCP0_DEFAULT) {
-
- goto fail;
- }
- dev->setup_checked_registers(8);
- dev->write_register(RM3100_TMRC_REG, TMRC, true);
- dev->write_register(RM3100_CMM_REG, CMM, false);
- dev->write_register(RM3100_CCX1_REG, CCP1, true);
- dev->write_register(RM3100_CCX0_REG, CCP0, true);
- dev->write_register(RM3100_CCY1_REG, CCP1, true);
- dev->write_register(RM3100_CCY0_REG, CCP0, true);
- dev->write_register(RM3100_CCZ1_REG, CCP1, true);
- dev->write_register(RM3100_CCZ0_REG, CCP0, true);
- _scaler = (1 / GAIN_CC200) * UTESLA_TO_MGAUSS;
-
- dev->set_retries(3);
-
- dev->get_semaphore()->give();
-
- compass_instance = register_compass();
- printf("Found a RM3100 at address 0x%x as compass %u\n", dev->get_bus_address(), compass_instance);
-
- set_rotation(compass_instance, rotation);
- if (force_external) {
- set_external(compass_instance, true);
- }
-
- dev->set_device_type(DEVTYPE_RM3100);
- set_dev_id(compass_instance, dev->get_bus_id());
-
- dev->register_periodic_callback(1000000U/80U,
- FUNCTOR_BIND_MEMBER(&AP_Compass_RM3100::timer, void));
- return true;
- fail:
- dev->get_semaphore()->give();
- return false;
- }
- void AP_Compass_RM3100::timer()
- {
- struct PACKED {
- uint8_t magx_2;
- uint8_t magx_1;
- uint8_t magx_0;
- uint8_t magy_2;
- uint8_t magy_1;
- uint8_t magy_0;
- uint8_t magz_2;
- uint8_t magz_1;
- uint8_t magz_0;
- } data;
- Vector3f field;
- int32_t magx = 0;
- int32_t magy = 0;
- int32_t magz = 0;
-
- uint8_t status;
- if (!dev->read_registers(RM3100_STATUS_REG, (uint8_t *)&status, 1)) {
- goto check_registers;
- }
- if (!(status & 0x80)) {
-
- goto check_registers;
- }
- if (!dev->read_registers(RM3100_MX2_REG, (uint8_t *)&data, sizeof(data))) {
- goto check_registers;
- }
-
-
- magx = ((uint32_t)data.magx_2 << 24) | ((uint32_t)data.magx_1 << 16) | ((uint32_t)data.magx_0 << 8);
- magy = ((uint32_t)data.magy_2 << 24) | ((uint32_t)data.magy_1 << 16) | ((uint32_t)data.magy_0 << 8);
- magz = ((uint32_t)data.magz_2 << 24) | ((uint32_t)data.magz_1 << 16) | ((uint32_t)data.magz_0 << 8);
-
- magx >>= 8;
- magy >>= 8;
- magz >>= 8;
-
- field(magx * _scaler, magy * _scaler, magz * _scaler);
- accumulate_sample(field, compass_instance);
- check_registers:
- dev->check_next_register();
- }
- void AP_Compass_RM3100::read()
- {
- drain_accumulated_samples(compass_instance);
- }
|