ardupilot/libraries/AP_Compass/AP_Compass_AK8963.h

126 lines
3.6 KiB
C++

/// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
#ifndef AP_Compass_AK8963_H
#define AP_Compass_AK8963_H
#include <AP_HAL.h>
#include "../AP_Common/AP_Common.h"
#include "../AP_Math/AP_Math.h"
#include "Compass.h"
#include "AP_Compass_Backend.h"
class AK8963_Backend
{
public:
virtual ~AK8963_Backend() {}
virtual void read(uint8_t address, uint8_t *buf, uint32_t count) = 0;
virtual void write(uint8_t address, const uint8_t *buf, uint32_t count) = 0;
virtual bool sem_take_nonblocking() = 0;
virtual bool sem_take_blocking() = 0;
virtual bool sem_give() = 0;
virtual bool init() = 0;
virtual uint8_t read(uint8_t address)
{
uint8_t value;
read(address, &value, 1);
return value;
}
virtual void write(uint8_t address, uint8_t value)
{
write(address, &value, 1);
}
};
class AP_Compass_AK8963 : public AP_Compass_Backend
{
public:
AP_Compass_AK8963(Compass &compass);
bool init(void);
void read(void);
void accumulate(void);
protected:
AK8963_Backend *_backend; // Not to be confused with Compass (frontend) "_backends" attribute.
float magnetometer_ASA[3];
float _mag_x;
float _mag_y;
float _mag_z;
uint8_t _compass_instance;
virtual bool read_raw() = 0;
private:
typedef enum
{
STATE_CONVERSION,
STATE_SAMPLE,
STATE_ERROR
} state_t;
virtual bool _backend_init() = 0;
virtual void _register_read(uint8_t address, uint8_t count, uint8_t *value) = 0;
virtual void _register_write(uint8_t address, uint8_t value) = 0;
virtual void _backend_reset() = 0;
virtual uint8_t _read_id() = 0;
virtual void _dump_registers() {}
bool _register_read(uint8_t address, uint8_t *value);
bool _calibrate();
bool _self_test();
void _update();
void _start_conversion();
void _collect_samples();
float _mag_x_accum;
float _mag_y_accum;
float _mag_z_accum;
uint32_t _accum_count;
bool _initialised;
state_t _state;
uint8_t _magnetometer_adc_resolution;
uint32_t _last_update_timestamp;
uint32_t _last_accum_time;
};
class AK8963_MPU9250_SPI_Backend: public AK8963_Backend
{
public:
AK8963_MPU9250_SPI_Backend();
void read(uint8_t address, uint8_t *buf, uint32_t count);
void write(uint8_t address, const uint8_t *buf, uint32_t count);
bool sem_take_nonblocking();
bool sem_take_blocking();
bool sem_give();
bool init() ;
~AK8963_MPU9250_SPI_Backend() {}
private:
AP_HAL::SPIDeviceDriver *_spi;
AP_HAL::Semaphore *_spi_sem;
};
class AP_Compass_AK8963_MPU9250: public AP_Compass_AK8963
{
public:
AP_Compass_AK8963_MPU9250(Compass &compass);
~AP_Compass_AK8963_MPU9250() {}
bool init();
// detect the sensor
static AP_Compass_Backend *detect(Compass &compass);
private:
bool _backend_init();
void _backend_reset();
void _register_read(uint8_t address, uint8_t count, uint8_t *value);
void _register_write(uint8_t address, uint8_t value);
void _dump_registers();
bool read_raw();
uint8_t _read_id();
};
#endif