M5Unit-IMU 0.0.2 git rev:e5b00aa
Loading...
Searching...
No Matches
unit_bmi270_aux_bmm150.hpp
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2026 M5Stack Technology CO LTD
3 *
4 * SPDX-License-Identifier: MIT
5 */
10#ifndef M5_UNIT_IMU_UNIT_UNIT_BMI270_AUX_BMM150_HPP
11#define M5_UNIT_IMU_UNIT_UNIT_BMI270_AUX_BMM150_HPP
12
13#include "unit_bmi270.hpp"
14
15namespace m5 {
16namespace unit {
17
50 M5_UNIT_COMPONENT_HPP_BUILDER(UnitBMI270AuxBMM150, 0x69);
51
52public:
65 bmm150::Preset aux_mag_preset{bmm150::Preset::Regular};
66 };
67
70 explicit UnitBMI270AuxBMM150(const uint8_t addr = DEFAULT_ADDRESS);
73 {
74 }
75
77 virtual bool begin() override;
78
84 {
85 // Only aux_mag_preset is kept here; the inherited fields are re-read from the base, which
86 // updates its own copy from writeAccelRange()/writeGyroRange()/start_periodic_measurement()
87 config_t cfg = _cfg_aux_bmm150;
88 static_cast<UnitBMI270::config_t&>(cfg) = UnitBMI270::config();
89 return cfg;
90 }
95 void config(const config_t& cfg)
96 {
97 _cfg_aux_bmm150 = cfg;
99 }
101
107 virtual m5::imu::Capability imuSpec() const override
108 {
110 const auto base = Capability::Accel | Capability::Gyro | Capability::Temp;
111 return _aux_mag ? (base | Capability::Mag) : base;
112 }
115 virtual void imuConvertParam(m5::imu::imu_convert_param_t& out) const override;
117
124 bool sleep() override;
125
128
134 bool writeAuxMagPreset(const bmm150::Preset preset);
147 bool writeAuxMagRepetition(const uint8_t rep_xy, const uint8_t rep_z);
156 bool readAuxMagRepetition(uint8_t& rep_xy, uint8_t& rep_z) const;
158
159protected:
160 // Base configuration, then probe and configure the AUX BMM150.
161 // A probe failure is not an error: it just means this board has no magnetometer on the
162 // interface, so it is switched back off and measurement continues with 6 axes. An
163 // AUX mag repetition the fixed poll rate cannot keep up with *is* an error, and is rejected
164 // before any register is touched.
165 virtual bool start_periodic_measurement(const bmi270::AccelRange accel_range, const bmi270::GyroRange gyro_range,
166 const bmi270::AccelODR accel_odr, const bmi270::GyroODR gyro_odr,
167 const bmi270::FilterPerf accel_filter_perf,
168 const bmi270::AccelBwp accel_bwp, const bmi270::FilterPerf gyro_filter_perf,
169 const bmi270::GyroBwp gyro_bwp) override;
171 virtual bool read_sensor_burst(bmi270::Data& d) override;
172
176 enum class AuxDetect : uint8_t {
177 Unknown,
178 Absent,
179 Present,
180 };
181
182 // AUX support, in the three stages start_periodic_measurement() drives them:
183 //
184 // setup mode -> detect (only while Unknown) -> data mode
185 //
186 // On success the interface is left in data mode, where the BMI270 auto-polls the BMM150 at 25Hz
187 // into REG_DATA_0..REG_DATA_7.
188
189 // Drives the three stages, skipping the detection once it has an answer. False means this unit
190 // runs as a plain 6-axis BMI270, which on most boards is the expected outcome, not a failure
191 bool setup_aux_bmm150();
192 // Switches the interface on and into manual (single-register) access, so the BMM150's own
193 // registers can be reached with aux_read_register8()/aux_write_register8()
194 bool aux_enter_setup_mode();
195 // Resets the BMM150, checks its chip ID and reads its factory trim into _mag_trim. Requires
196 // setup mode. Returning false is the normal outcome on a board that wires nothing here
197 bool aux_detect_bmm150();
198 // Applies the repetition, starts the BMM150's normal mode and hands the interface over to the
199 // BMI270's auto-poll. Requires setup mode and a preceding successful detection
200 bool aux_enter_data_mode();
201 // Polls REG_STATUS.aux_busy (bit2) until clear; gates every AUX manual transaction below
202 bool aux_wait_ready();
203 bool aux_write_register8(const uint8_t reg, const uint8_t val);
204 bool aux_read_register8(const uint8_t reg, uint8_t& out);
205 // Manual burst read of 8 bytes starting at a BMM150 register, via the AUX bridge
206 bool aux_read_burst8(const uint8_t bmm150_reg, std::array<uint8_t, 8>& out);
207 // Reads the BMM150 factory trim (registers 0x5D-0x71) through 3 overlapping 8 byte AUX
208 // bursts (0x5D/0x65/0x6A) and maps them the same way as UnitBMM150::read_trim()
209 bool aux_read_trim(bmm150::trim_t& trim);
210
211private:
212 // Only the aux_mag_preset field is authoritative here -- config() refreshes the inherited ones
213 // from the base rather than reading them back out of this copy
214 config_t _cfg_aux_bmm150{};
215 // Live state, seeded from _cfg_aux_bmm150 by begin() and thereafter owned by
216 // writeAuxMagRepetition(); what aux_enter_data_mode() writes to the magnetometer
217 uint8_t _aux_rep_xy{};
218 uint8_t _aux_rep_z{};
219 // Does this board carry a BMM150? Answered once, kept across stop/start; invalidated by
220 // begin() (soft reset wipes the AUX setup) and sleep() (suspend resets the magnetometer)
221 AuxDetect _aux_detect{AuxDetect::Unknown};
222 bool _aux_mag{false}; // True while the bridge is in data mode and delivering mag samples
223 bmm150::trim_t _mag_trim{}; // Factory trim read via the AUX bridge, valid once _aux_detect is Present
224};
225
226} // namespace unit
227} // namespace m5
228#endif
BMI270 that switches on its auxiliary (AUX) interface and drives a BMM150 through it.
Definition unit_bmi270_aux_bmm150.hpp:49
AuxDetect
Definition unit_bmi270_aux_bmm150.hpp:176
@ Unknown
Not probed yet, or invalidated by begin()/sleep()
@ Present
A BMM150 answered and _mag_trim holds its factory trim.
@ Absent
Nothing answered on the interface; it is left switched off.
virtual void imuConvertParam(m5::imu::imu_convert_param_t &out) const override
Gets the conversion parameters for raw IMU data.
Definition unit_bmi270_aux_bmm150.cpp:206
virtual ~UnitBMI270AuxBMM150()
Destructor.
Definition unit_bmi270_aux_bmm150.hpp:72
virtual bool read_sensor_burst(bmi270::Data &d) override
One 20 byte burst covering mag + accel + gyro, instead of the base's 12 byte accel/gyro read.
Definition unit_bmi270_aux_bmm150.cpp:187
bool readAuxMagRepetition(uint8_t &rep_xy, uint8_t &rep_z) const
Read the repetition (oversampling) the AUX BMM150 is configured with.
Definition unit_bmi270_aux_bmm150.cpp:123
config_t config() const
Gets the configuration.
Definition unit_bmi270_aux_bmm150.hpp:83
void config(const config_t &cfg)
Set the configuration.
Definition unit_bmi270_aux_bmm150.hpp:95
virtual m5::imu::Capability imuSpec() const override
Capability of this unit.
Definition unit_bmi270_aux_bmm150.hpp:107
bool writeAuxMagPreset(const bmm150::Preset preset)
Write the accuracy/power preset of the AUX BMM150.
Definition unit_bmi270_aux_bmm150.cpp:102
UnitBMI270AuxBMM150(const uint8_t addr=DEFAULT_ADDRESS)
Construct with the BMI270's I2C address (the AUX BMM150 sits behind the bridge)
Definition unit_bmi270_aux_bmm150.cpp:84
bool sleep() override
Suspend the chip, parking the AUX BMM150 first.
Definition unit_bmi270_aux_bmm150.cpp:214
bool writeAuxMagRepetition(const uint8_t rep_xy, const uint8_t rep_z)
Write the repetition (oversampling) of the AUX BMM150.
Definition unit_bmi270_aux_bmm150.cpp:107
virtual bool begin() override
Seed the magnetometer's live state from config_t, then run the base begin()
Definition unit_bmi270_aux_bmm150.cpp:88
6-axis (accel + gyro) IMU unit. CoreS3/AtomS3R built-in
Definition unit_bmi270.hpp:34
config_t config() const
Gets the configuration.
Definition unit_bmi270.hpp:92
Capability
Capability of the IMU data source (bitwise combinable)
Definition imu_types.hpp:22
Top level namespace of M5Stack.
Definition ahrs_controller.cpp:26
Unit-related namespace.
Raw to physical unit conversion coefficients.
Definition imu_types.hpp:69
Settings for begin()
Definition unit_bmi270.hpp:47
Settings for begin(), extending the base with the magnetometer's own.
Definition unit_bmi270_aux_bmm150.hpp:57
bmm150::Preset aux_mag_preset
Definition unit_bmi270_aux_bmm150.hpp:65
One measurement. Accel/gyro are always 12 bytes, little-endian (register 0x0C when the AUX/BMM150 bri...
Definition unit_bmi270_data.hpp:179
Factory trim (calibration) values read from registers 0x5D-0x71, consumed by the compensation formula...
Definition unit_bmm150_data.hpp:125
UnitBMI270 (6-axis IMU) unit component.
GyroBwp
Gyroscope bandwidth parameter (REG_GYR_CONF register 0x42, bits[5:4])
Definition unit_bmi270_data.hpp:110
AccelBwp
Accelerometer bandwidth parameter (REG_ACC_CONF register 0x40, bits[6:4])
Definition unit_bmi270_data.hpp:93
FilterPerf
Filter performance mode (REG_ACC_CONF bit7 / REG_GYR_CONF bit7)
Definition unit_bmi270_data.hpp:81
GyroODR
Gyroscope output data rate (REG_GYR_CONF register 0x42, bits[3:0])
Definition unit_bmi270_data.hpp:65
GyroRange
Gyroscope full scale range (REG_GYR_RANGE register 0x43)
Definition unit_bmi270_data.hpp:38
AccelRange
Accelerometer full scale range (REG_ACC_RANGE register 0x41)
Definition unit_bmi270_data.hpp:25
AccelODR
Accelerometer output data rate (REG_ACC_CONF register 0x40, bits[3:0])
Definition unit_bmi270_data.hpp:50
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