10#ifndef M5_UNIT_IMU_UNIT_UNIT_BMM150_DATA_HPP
11#define M5_UNIT_IMU_UNIT_UNIT_BMM150_DATA_HPP
51 return (p == Preset::LowPower) ? 0x01
52 : (p == Preset::Regular) ? 0x04
53 : (p == Preset::EnhancedRegular) ? 0x07
60 return (p == Preset::LowPower) ? 0x02
61 : (p == Preset::Regular) ? 0x0E
62 : (p == Preset::EnhancedRegular) ? 0x1A
69 return static_cast<uint16_t
>(1 + 2 * rep_xy);
75 return static_cast<uint16_t
>(1 + rep_z);
93 return (rate == DataRate::Rate10Hz) ? 100000U
94 : (rate == DataRate::Rate2Hz) ? 500000U
95 : (rate == DataRate::Rate6Hz) ? 166667U
96 : (rate == DataRate::Rate8Hz) ? 125000U
97 : (rate == DataRate::Rate15Hz) ? 66667U
98 : (rate == DataRate::Rate20Hz) ? 50000U
99 : (rate == DataRate::Rate25Hz) ? 40000U
114constexpr int16_t XY_OVERFLOW_RAW{-4096};
115constexpr int16_t Z_OVERFLOW_RAW{-16384};
116constexpr int32_t Z_POSITIVE_SATURATION{32767};
117constexpr int32_t Z_NEGATIVE_SATURATION{-32767};
144 std::array<uint8_t, 8>
raw{};
152 const int16_t v =
static_cast<int16_t
>((
raw[1] << 8) |
raw[0]);
153 return static_cast<int16_t
>(v >> 3);
158 const int16_t v =
static_cast<int16_t
>((
raw[3] << 8) |
raw[2]);
159 return static_cast<int16_t
>(v >> 3);
164 const int16_t v =
static_cast<int16_t
>((
raw[5] << 8) |
raw[4]);
165 return static_cast<int16_t
>(v >> 1);
170 const uint16_t v =
static_cast<uint16_t
>((
raw[7] << 8) |
raw[6]);
171 return static_cast<uint16_t
>(v >> 2);
176 return (
raw[6] & 0x01) != 0;
185 const int16_t data_x =
x_raw();
186 if (data_x == internal::XY_OVERFLOW_RAW) {
189 uint16_t base =
rhall();
197 const int32_t xyz1_scaled =
static_cast<int32_t
>(
trim.
dig_xyz1) * 16384;
198 const uint16_t normalized =
static_cast<uint16_t
>(xyz1_scaled / base) -
static_cast<uint16_t
>(0x4000);
199 const int16_t centered =
static_cast<int16_t
>(normalized);
200 const int32_t squared =
static_cast<int32_t
>(centered) *
static_cast<int32_t
>(centered);
201 const int32_t cross_term =
static_cast<int32_t
>(
trim.
dig_xy2) * (squared / 128);
202 const int32_t xy1_scaled =
static_cast<int32_t
>(
static_cast<int16_t
>(
trim.
dig_xy1) * 128);
203 const int32_t linear_term =
static_cast<int32_t
>(centered) * xy1_scaled;
204 const int32_t combined = ((cross_term + linear_term) / 512) +
static_cast<int32_t
>(0x100000);
205 const int32_t gain =
static_cast<int32_t
>(
static_cast<int16_t
>(
trim.
dig_x2) +
static_cast<int16_t
>(0xA0));
206 const int32_t scale = (combined * gain) / 4096;
207 const int32_t applied =
static_cast<int32_t
>(data_x) * scale;
209 int16_t result =
static_cast<int16_t
>(applied / 8192);
210 result =
static_cast<int16_t
>((result +
static_cast<int16_t
>(
trim.
dig_x1) * 8) / 16);
216 const int16_t data_y =
y_raw();
217 if (data_y == internal::XY_OVERFLOW_RAW) {
220 uint16_t base =
rhall();
228 const int32_t normalized_full = (
static_cast<int32_t
>(
trim.
dig_xyz1) * 16384) / base;
229 const uint16_t normalized =
static_cast<uint16_t
>(normalized_full) -
static_cast<uint16_t
>(0x4000);
230 const int16_t centered =
static_cast<int16_t
>(normalized);
231 const int32_t squared =
static_cast<int32_t
>(centered) *
static_cast<int32_t
>(centered);
232 const int32_t cross_term =
static_cast<int32_t
>(
trim.
dig_xy2) * (squared / 128);
233 const int32_t xy1_scaled =
static_cast<int32_t
>(
static_cast<int16_t
>(
trim.
dig_xy1) * 128);
234 const int32_t combined_num = cross_term +
static_cast<int32_t
>(centered) * xy1_scaled;
235 const int32_t combined = combined_num / 512;
236 const int32_t gain =
static_cast<int32_t
>(
static_cast<int16_t
>(
trim.
dig_y2) +
static_cast<int16_t
>(0xA0));
237 const int32_t scale = ((combined +
static_cast<int32_t
>(0x100000)) * gain) / 4096;
238 const int32_t applied =
static_cast<int32_t
>(data_y) * scale;
240 int16_t result =
static_cast<int16_t
>(applied / 8192);
241 result =
static_cast<int16_t
>((result +
static_cast<int16_t
>(
trim.
dig_y1) * 8) / 16);
247 const int16_t data_z =
z_raw();
248 if (data_z == internal::Z_OVERFLOW_RAW) {
251 const uint16_t rh =
rhall();
256 const int16_t hall_offset =
257 static_cast<int16_t
>(
static_cast<int16_t
>(rh) -
static_cast<int16_t
>(
trim.
dig_xyz1));
258 const int32_t z3_term = (
static_cast<int32_t
>(
trim.
dig_z3) *
static_cast<int32_t
>(hall_offset)) / 4;
259 const int32_t z_delta =
static_cast<int32_t
>(data_z -
trim.
dig_z4) * 32768;
260 const int32_t z1_raw =
static_cast<int32_t
>(
trim.
dig_z1) * (
static_cast<int16_t
>(rh) * 2);
261 const int16_t z1_rounded =
static_cast<int16_t
>((z1_raw + 32768) / 65536);
263 int32_t result = (z_delta - z3_term) / (
trim.
dig_z2 + z1_rounded);
265 if (result > internal::Z_POSITIVE_SATURATION) {
266 result = internal::Z_POSITIVE_SATURATION;
267 }
else if (result < internal::Z_NEGATIVE_SATURATION) {
268 result = internal::Z_NEGATIVE_SATURATION;
272 return static_cast<int16_t
>(result);
281 return scale_16(
comp_x());
286 return scale_16(
comp_y());
291 return scale_16(
comp_z());
297 static inline int32_t scale_16(
const int16_t compensated)
299 return (compensated == OVERFLOW_OUTPUT) ? compensated :
static_cast<int32_t
>(compensated) * 16;
Top level namespace of M5Stack.
Definition ahrs_controller.cpp:26
One measurement (8 bytes burst from REG_DATA_X_LSB, register 0x42)
Definition unit_bmm150_data.hpp:143
std::array< uint8_t, 8 > raw
[0..1] X, [2..3] Y, [4..5] Z, [6..7] RHALL (bit0 of [6] = DRDY)
Definition unit_bmm150_data.hpp:144
int32_t adj_z() const
comp_z() rescaled to 16 LSB/uT (OVERFLOW_OUTPUT preserved as the -32768 sentinel)
Definition unit_bmm150_data.hpp:289
uint16_t rhall() const
Raw hall resistance (14bit unsigned, register bits[15:2])
Definition unit_bmm150_data.hpp:168
int16_t comp_y() const
Compensated magnetometer Y (OVERFLOW_OUTPUT on overflow)
Definition unit_bmm150_data.hpp:214
int32_t adj_x() const
comp_x() rescaled to 16 LSB/uT (OVERFLOW_OUTPUT preserved as the -32768 sentinel)
Definition unit_bmm150_data.hpp:279
int16_t y_raw() const
Raw magnetometer Y (13bit signed, register bits[15:3])
Definition unit_bmm150_data.hpp:156
trim_t trim
Trim values used by the compensation formulas.
Definition unit_bmm150_data.hpp:145
int16_t comp_x() const
Compensated magnetometer X (OVERFLOW_OUTPUT on overflow)
Definition unit_bmm150_data.hpp:183
bool drdy() const
Data ready flag (bit0 of register 0x48)
Definition unit_bmm150_data.hpp:174
int16_t x_raw() const
Raw magnetometer X (13bit signed, register bits[15:3])
Definition unit_bmm150_data.hpp:150
int16_t comp_z() const
Compensated magnetometer Z (OVERFLOW_OUTPUT on overflow), saturated to +-32767 before scaling.
Definition unit_bmm150_data.hpp:245
int16_t z_raw() const
Raw magnetometer Z (15bit signed, register bits[15:1])
Definition unit_bmm150_data.hpp:162
int32_t adj_y() const
comp_y() rescaled to 16 LSB/uT (OVERFLOW_OUTPUT preserved as the -32768 sentinel)
Definition unit_bmm150_data.hpp:284
Factory trim (calibration) values read from registers 0x5D-0x71, consumed by the compensation formula...
Definition unit_bmm150_data.hpp:125
int16_t dig_z2
0x68/0x69
Definition unit_bmm150_data.hpp:131
int8_t dig_x1
0x5D
Definition unit_bmm150_data.hpp:126
int16_t dig_z4
0x62/0x63
Definition unit_bmm150_data.hpp:133
uint16_t dig_z1
0x6A/0x6B
Definition unit_bmm150_data.hpp:130
uint16_t dig_xyz1
0x6C/0x6D (14bit)
Definition unit_bmm150_data.hpp:136
int8_t dig_y2
0x65
Definition unit_bmm150_data.hpp:129
uint8_t dig_xy1
0x71
Definition unit_bmm150_data.hpp:134
int8_t dig_xy2
0x70
Definition unit_bmm150_data.hpp:135
int8_t dig_y1
0x5E
Definition unit_bmm150_data.hpp:127
int8_t dig_x2
0x64
Definition unit_bmm150_data.hpp:128
int16_t dig_z3
0x6E/0x6F
Definition unit_bmm150_data.hpp:132
DataRate
Output data rate (REG_OP_MODE register bits 5:3, value order is NOT monotonic in Hz)
Definition unit_bmm150_data.hpp:25
@ Rate10Hz
10Hz (power-on default)
constexpr uint32_t rate_interval_us(const DataRate rate)
Output period (us) of the given data rate.
Definition unit_bmm150_data.hpp:91
constexpr uint8_t preset_rep_xy(const Preset p)
REG_REP_XY register value (0x51) for the given preset.
Definition unit_bmm150_data.hpp:49
Preset
Preset accuracy/power modes, controlling the REG_REP_XY/REG_REP_Z repetition counts (see preset_rep_x...
Definition unit_bmm150_data.hpp:41
@ LowPower
Lowest power, lowest accuracy.
@ HighAccuracy
Highest accuracy, highest power.
@ EnhancedRegular
Enhanced accuracy over Regular.
@ Regular
Balanced accuracy/power (recommended default)
constexpr uint8_t preset_rep_z(const Preset p)
REG_REP_Z register value (0x52) for the given preset.
Definition unit_bmm150_data.hpp:58
constexpr int16_t OVERFLOW_OUTPUT
Sentinel returned by comp_x()/comp_y()/comp_z() on overflow or invalid input.
Definition unit_bmm150_data.hpp:111
constexpr uint16_t repetition_z(const uint8_t rep_z)
Repetitions actually performed on Z for a REG_REP_Z register value (nZ = 1 + REPZ)
Definition unit_bmm150_data.hpp:73
constexpr bool repetition_fits(const DataRate rate, const uint8_t rep_xy, const uint8_t rep_z)
Can a measurement with these repetitions complete within one period of this rate?
Definition unit_bmm150_data.hpp:105
constexpr uint32_t measurement_time_us(const uint8_t rep_xy, const uint8_t rep_z)
Active measurement time (us) for the given repetition register values.
Definition unit_bmm150_data.hpp:85
constexpr uint16_t repetition_xy(const uint8_t rep_xy)
Repetitions actually performed on X/Y for a REG_REP_XY register value (nXY = 1 + 2*REPXY)
Definition unit_bmm150_data.hpp:67