32#include "../../../SensorBuildOpt.h"
33#if !SENSORLIB_EXCLUDE_QMC6309
38static constexpr uint8_t QMC6309_SLAVE_ADDRESS = (0x7C);
39static constexpr uint8_t QMC6309H_SLAVE_ADDRESS = (0x0C);
83 uint8_t buffer[6] = {0};
85 int status =
readReg(REG_0x09_STAT);
105 if (
readRegBuff(REG_0x01_LSB_DX, buffer,
sizeof(buffer)) < 0) {
109 data.
raw.
x = (int16_t)(buffer[1] << 8) | (buffer[0]);
110 data.
raw.
y = (int16_t)(buffer[3] << 8) | (buffer[2]);
111 data.
raw.
z = (int16_t)(buffer[5] << 8) | (buffer[4]);
183 if (
writeReg(REG_0x0B_CMD2, 0x80) < 0) {
187 if (
writeReg(REG_0x0B_CMD2, 0x00) < 0) {
195 while (retry++ < 5) {
196 int status =
readReg(REG_0x09_STAT);
215 int16_t x_result = 0, y_result = 0, z_result = 0;
216 return selfTest(x_result, y_result, z_result);
226 bool selfTest(int16_t &x_result, int16_t &y_result, int16_t &z_result)
240 if (
writeReg(REG_0x0E_SELFTEST_CTRL, MASK_SOFT_RST) < 0) {
246 while (!
getRegBit(REG_0x09_STAT, 2) && retry++ < 50) {
254 int x_test =
readReg(REG_0x13_SELFTEST_X);
255 int y_test =
readReg(REG_0x14_SELFTEST_Y);
256 int z_test =
readReg(REG_0x15_SELFTEST_Z);
257 if (x_test < 0 || y_test < 0 || z_test < 0) {
262 x_result = (int8_t)x_test;
263 y_result = (int8_t)y_test;
264 z_result = (int8_t)z_test;
268 int16_t x_abs = x_result < 0 ? -x_result : x_result;
269 int16_t y_abs = y_result < 0 ? -y_result : y_result;
270 int16_t z_abs = z_result < 0 ? -z_result : z_result;
272 bool x_ok = (x_abs >= 1 && x_abs <= 50);
273 bool y_ok = (y_abs >= 1 && y_abs <= 50);
274 bool z_ok = (z_abs >= 1 && z_abs <= 50);
276 if (!x_ok || !y_ok || !z_ok) {
277 SENSORLIB_LOG_W(
"Self-test data out of range: X=%d, Y=%d, Z=%d (expected abs in 1..50)",
278 x_result, y_result, z_result);
281 return x_ok && y_ok && z_ok;
294 float full_scale = 0.0f;
295 float sensitivity = 0.0f;
296 uint8_t range_value = 0;
299 sensitivity = 0.001f;
300 range_value = 0x00 << 2;
304 sensitivity = 0.0005f;
305 range_value = 0x01 << 2;
309 sensitivity = 0.00025f;
310 range_value = 0x02 << 2;
318 if (
updateBits(REG_0x0B_CMD2, 0x0C, range_value) < 0) {
335 int rangeInt =
static_cast<int>(data_rate_hz * 100 + 0.5);
336 uint8_t regValue = 0;
339 regValue = 0x00 << 4;
342 regValue = 0x01 << 4;
345 regValue = 0x02 << 4;
348 regValue = 0x03 << 4;
351 regValue = 0x04 << 4;
357 if (
updateBits(REG_0x0A_CMD1, 0x70, regValue) < 0) {
374 uint8_t mode_val = 0x00;
392 if (
updateBits(REG_0x0A_CMD1, 0x03, mode_val) < 0) {
409 uint8_t osr_val = 0x00;
431 return updateBits(REG_0x0A_CMD1, 0x18, osr_val) == 0;
453 uint8_t lpf_val = 0x00;
474 return updateBits(REG_0x0A_CMD1, 0xE0, lpf_val) == 0;
527 uint8_t sr_val = 0x00;
542 return updateBits(REG_0x0B_CMD2, 0x03, sr_val) == 0;
553 _qmc6309h_vdd_mode = mode;
558 static constexpr uint8_t QMC6309_CHIP_ID = 0x90;
559 static constexpr uint8_t QMC6309H_CHIP_ID = 0xA5;
560 static constexpr uint8_t REG_0x00_CHIP_ID = 0x00;
561 static constexpr uint8_t REG_0x01_LSB_DX = 0x01;
562 static constexpr uint8_t REG_0x02_MSB_DX = 0x02;
563 static constexpr uint8_t REG_0x03_LSB_DY = 0x03;
564 static constexpr uint8_t REG_0x04_MSB_DY = 0x04;
565 static constexpr uint8_t REG_0x05_LSB_DZ = 0x05;
566 static constexpr uint8_t REG_0x06_MSB_DZ = 0x06;
567 static constexpr uint8_t REG_0x09_STAT = 0x09;
568 static constexpr uint8_t REG_0x0A_CMD1 = 0x0A;
569 static constexpr uint8_t REG_0x0B_CMD2 = 0x0B;
570 static constexpr uint8_t REG_0x40_IO_CONFIG = 0x40;
571 static constexpr uint8_t REG_0x28_OTP_CTRL = 0x28;
572 static constexpr uint8_t REG_0x29_SIGN = 0x29;
574 static constexpr uint8_t REG_0x0E_SELFTEST_CTRL = 0x0E;
575 static constexpr uint8_t REG_0x13_SELFTEST_X = 0x13;
576 static constexpr uint8_t REG_0x14_SELFTEST_Y = 0x14;
577 static constexpr uint8_t REG_0x15_SELFTEST_Z = 0x15;
579 static constexpr uint8_t MASK_DRDY = 0x01;
580 static constexpr uint8_t MASK_OVFL = 0x02;
581 static constexpr uint8_t MASK_ST_RDY = 0x04;
582 static constexpr uint8_t MASK_NVM_RDY = 0x08;
583 static constexpr uint8_t MASK_NVM_LOAD_DONE = 0x10;
584 static constexpr uint8_t MASK_SOFT_RST = 0x80;
585 static constexpr uint8_t MASK_ODR = 0x70;
586 static constexpr uint8_t MASK_RNG = 0x0C;
587 static constexpr uint8_t MASK_SET_RESET_MODE = 0x03;
589 bool _is_qmc6309h =
false;
592 bool applyQMC6309HVoltageMode()
598 int reg =
readReg(REG_0x40_IO_CONFIG);
604 uint8_t value = (uint8_t)reg;
605 switch (_qmc6309h_vdd_mode) {
607 value = (value & 0x3F) | 0x80;
610 value = (value & 0x3F) | 0x40;
616 if (
writeReg(REG_0x40_IO_CONFIG, value) < 0) {
626 for (uint8_t retry = 0; retry < 20; ++retry) {
627 if (
writeReg(REG_0x28_OTP_CTRL, 0x02) < 0) {
634 for (uint8_t count = 0; count < 100; ++count) {
635 int status =
readReg(REG_0x09_STAT);
647 bool initImpl(uint8_t param)
override
666 _is_qmc6309h =
false;
668 }
else if (
_info.
uid == QMC6309H_CHIP_ID) {
676 if (!applyQMC6309HVoltageMode()) {
@ MAGNETOMETER
Magnetometer sensor.
OperationMode
Enumeration of sensor operation modes.
@ LPF_2
2 Hz low-pass filter
@ LPF_4
4 Hz low-pass filter
@ LPF_16
16 Hz low-pass filter
@ LPF_8
8 Hz low-pass filter
@ LPF_1
1 Hz low-pass filter
MagFullScaleRange
Enumeration defining full-scale range settings for the sensor.
MagDownSampleRatio
Enumeration defining down-sample ratios for the sensor.
@ DSR_1
1x down-sample ratio
MagOverSampleRatio
Enumeration defining over-sample ratios for the sensor.
@ OSR_8
8x over-sample ratio
@ OSR_4
4x over-sample ratio
@ OSR_2
2x over-sample ratio
@ OSR_1
1x over-sample ratio
#define SENSORLIB_LOG_W(...)
#define SENSORLIB_LOG_E(...)
std::unique_ptr< SensorHal > hal
uint16_t _oversampling_rate
SensorConfig _config
Current configuration.
SensorInfo _info
Sensor information.
bool getRegBit(uint8_t reg, uint8_t bit)
int readReg(uint8_t reg) const
int writeReg(uint8_t reg, uint8_t val)
int readRegBuff(uint8_t reg, uint8_t *buf, size_t len) const
int updateBits(uint8_t reg, uint8_t mask, uint8_t value_shifted)
bool reset() override
Resets the sensor to its default state.
bool configMagnetometer(OperationMode mode, MagFullScaleRange range, float data_rate_hz, MagOverSampleRatio osr, MagDownSampleRatio dsr=MagDownSampleRatio::DSR_1) override
Configures the magnetometer with multiple parameters.
bool isNVMReady()
Checks if the NVM is ready for access.
bool setOperationMode(OperationMode mode) override
Sets the operation mode of the magnetometer.
~SensorQMC6309()=default
Destructor.
bool isDataReady() override
Checks if new data is available from the sensor.
bool setOutputDataRate(float data_rate_hz) override
Sets the output data rate for the magnetometer.
void setVoltageMode(VoltageMode mode)
Set the voltage mode for QMC6309H variant.
SensorQMC6309()=default
Default constructor.
bool readData(MagnetometerData &data) override
Reads the magnetic field data from the sensor.
uint8_t getChipID() const
Gets the chip ID of the magnetometer.
bool setOversamplingRate(MagOverSampleRatio osr) override
Sets the oversampling rate of the magnetometer.
bool setLowPassFilter(MagLowPassFilter lpf)
Sets the low-pass filter of the magnetometer.
bool isDataOverflow()
Checks if data overflow has occurred.
bool setSetResetMode(MagSetResetMode mode)
Sets the set/reset mode of the magnetometer.
bool setFullScaleRange(MagFullScaleRange range) override
Sets the full-scale range of the magnetometer.
bool isNVMLoadDone()
Checks if the NVM load is complete.
bool setDownsamplingRate(MagDownSampleRatio dsr) override
Sets the downsampling rate of the magnetometer.
bool selfTest() override
Checks if the sensor is functioning correctly.
bool selfTest(int16_t &x_result, int16_t &y_result, int16_t &z_result)
Performs a self-test on the sensor.
float calculateHeading(const MagnetometerData &data, float declination=0.0f)
Calculate heading (yaw) angle from magnetometer data in radians.
constexpr bool _isBitSet(T value, uint8_t bit)
Structure representing magnetometer data.
float heading_degrees
heading angle (degrees)
float heading
heading angle (radians)
SensorVector magnetic_field
magnetic field strength (Gauss)
bool overflow
data overflow flag
int16_t x
X-axis raw value.
int16_t y
Y-axis raw value.
int16_t z
Z-axis raw value.
uint32_t latency
Reporting latency in milliseconds.
float sample_rate
Sample rate in Hz.
float range
Measurement range.
SensorType type
Type of the sensor.
OperationMode mode
Operation mode.
uint8_t version
Hardware/firmware version.
uint8_t i2c_address
Default I2C address.
uint32_t uid
Unique identifier.
SensorType type
Sensor type.
const char * manufacturer
Manufacturer name.
const char * model
Model name/identifier.