33#include "../../../SensorBuildOpt.h"
34#if !SENSORLIB_EXCLUDE_BMA423
37#include "../../../bosch/bma4xx/bma423.h"
53 float g_value =
static_cast<float>(threshold_5_11) / 2048.0f;
54 return g_value * 1000.0f;
64 if (threshold_mg < 0 || threshold_mg > 1000.0f) {
65 SENSORLIB_LOG_E(
"Threshold out of range (0-1000mg): %.1f mg, will be clamped", threshold_mg);
66 threshold_mg = (threshold_mg < 0) ? 0 : 1000.0f;
68 float g_value = threshold_mg / 1000.0f;
69 return static_cast<uint16_t
>(g_value * 2048.0f + 0.5f);
79 return static_cast<float>(samples) * 20.0f;
89 return static_cast<uint16_t
>(ms / 20.0f + 0.5f);
97 uint8_t motion_feature_enabled = 0;
98 uint16_t any_motion_threshold = 0x00AA;
99 uint16_t any_motion_duration = 0x0005;
100 uint16_t no_motion_threshold = 0x00AA;
101 uint16_t no_motion_duration = 0x0032;
107 enum class BMA423_TapType {
148 _mon_cfg.any_motion_threshold = 0x00AA;
149 _mon_cfg.any_motion_duration = 0x0005;
150 _mon_cfg.no_motion_threshold = 0x00AA;
151 _mon_cfg.no_motion_duration = 0x0032;
152 _tapType = BMA423_TapType::DOUBLE_TAP;
295 const uint16_t motion_mask = BMA423_ANY_MOTION | BMA423_NO_MOTION;
297 if ((feature & (BMA423_ANY_MOTION | BMA423_NO_MOTION)) == (BMA423_ANY_MOTION | BMA423_NO_MOTION)) {
298 SENSORLIB_LOG_E(
"Both any-motion and no-motion are specified, only any-motion will be enabled.");
299 feature &= (~BMA423_NO_MOTION);
302 if (enable && (feature & motion_mask)) {
303 uint16_t motion_to_enable = feature & motion_mask;
304 if (
_mon_cfg.motion_feature_enabled != 0 &&
305 _mon_cfg.motion_feature_enabled != motion_to_enable) {
306 if (bma423_feature_enable(
_mon_cfg.motion_feature_enabled, 0,
dev.get()) != 0) {
316 if (feature & BMA423_STEP_CNTR) {
317 if (bma423_step_detector_enable(enable ? BMA4_ENABLE : BMA4_DISABLE,
dev.get()) != 0) {
318 SENSORLIB_LOG_E(
"Failed to %s step detector", enable ?
"enable" :
"disable");
323 if (bma423_feature_enable(feature, enable,
dev.get()) != 0) {
325 enable ?
"enable" :
"disable", feature);
329 if (feature & motion_mask) {
331 _mon_cfg.motion_feature_enabled = feature & motion_mask;
333 if ((feature & motion_mask) ==
_mon_cfg.motion_feature_enabled) {
334 _mon_cfg.motion_feature_enabled = 0;
365 bool enableStepCounter(
bool enable, uint16_t step_counter_wm = 1,
bool reset_counter =
false)
override
368 if (bma423_step_counter_set_watermark(step_counter_wm,
dev.get()) != 0) {
374 if (bma423_reset_step_counter(
dev.get()) != 0) {
390 return bma423_step_counter_get_watermark(&step_counter_wm,
dev.get()) == 0;
405 if (!
enableInterrupt(pin_map, BMA423_STEP_CNTR_INT, interrupt_enable)) {
439 return bma423_select_platform(
static_cast<uint8_t
>(platform),
dev.get()) == 0;
471 _tapType = BMA423_TapType::DOUBLE_TAP;
474 _tapType = BMA423_TapType::SINGLE_TAP;
479 return bma423_tap_selection(
static_cast<uint8_t
>(
_tapType),
dev.get()) == 0;
493 if (!
enableInterrupt(pin_map, BMA423_ACTIVITY_INT, interrupt_enable)) {
510 bool interrupt_enable =
false,
520 if (cfg.
x_axis) axis |= BMA423_X_AXIS_EN;
521 if (cfg.
y_axis) axis |= BMA423_Y_AXIS_EN;
522 if (cfg.
z_axis) axis |= BMA423_Z_AXIS_EN;
524 if (bma423_anymotion_enable_axis(axis,
dev.get()) != 0) {
529 if (!
enableInterrupt(pin_map, BMA423_ANY_NO_MOTION_INT, interrupt_enable)) {
551 bool interrupt_enable =
false,
561 if (cfg.
x_axis) axis |= BMA423_X_AXIS_EN;
562 if (cfg.
y_axis) axis |= BMA423_Y_AXIS_EN;
563 if (cfg.
z_axis) axis |= BMA423_Z_AXIS_EN;
565 if (bma423_anymotion_enable_axis(axis,
dev.get()) != 0) {
570 if (!
enableInterrupt(pin_map, BMA423_ANY_NO_MOTION_INT, interrupt_enable)) {
597 _mon_cfg.no_motion_duration = duration;
598 _mon_cfg.no_motion_threshold = threshold;
618 _mon_cfg.any_motion_duration = duration;
619 _mon_cfg.any_motion_threshold = threshold;
637 bool configMotion(
bool any_motion, uint16_t threshold, uint16_t duration)
override
639 struct bma423_anymotion_config any_motion_cfg;
640 any_motion_cfg.threshold = threshold;
641 any_motion_cfg.duration = duration;
642 any_motion_cfg.nomotion_sel = any_motion ? 0 : 1;
645 _mon_cfg.any_motion_threshold = threshold;
646 _mon_cfg.any_motion_duration = duration;
648 _mon_cfg.no_motion_threshold = threshold;
649 _mon_cfg.no_motion_duration = duration;
652 SENSORLIB_LOG_D(
"BMA423 motion config (raw): threshold=0x%04X, duration=%u, type: %s",
654 any_motion ?
"Any-motion" :
"No-motion");
656 return bma423_set_any_motion_config(&any_motion_cfg,
dev.get()) == 0;
673 struct bma423_anymotion_config any_motion;
674 if (bma423_get_any_motion_config(&any_motion,
dev.get()) != 0) {
678 threshold = any_motion.threshold;
679 duration = any_motion.duration;
680 no_motion = any_motion.nomotion_sel;
693 uint32_t step_count = 0;
694 if (bma423_step_counter_output(&step_count,
dev.get()) != 0) {
708 return bma423_reset_step_counter(
dev.get()) == 0;
719 uint8_t activity_type = 0;
720 if (bma423_activity_output(&activity_type,
dev.get()) != 0) {
733 return _mon_cfg.motion_feature_enabled;
741 return _mon_cfg.motion_feature_enabled == BMA423_ANY_MOTION;
749 return _mon_cfg.motion_feature_enabled == BMA423_NO_MOTION;
761 if (bma4_read_int_status(&
_status,
dev.get()) != 0) {
785 if ((
_status & BMA423_ANY_NO_MOTION_INT)) {
813 bool boschInitImpl()
override
815 int8_t rslt = bma423_init(
dev.get());
821 dev->config_size = BMA423_CONFIG_FILE_SIZE;
823 rslt = bma423_write_config_file(
dev.get());
InterruptPinMap
Enumeration of interrupt pin mapping options.
#define SENSORLIB_LOG_E(...)
#define SENSORLIB_LOG_D(...)
Utility class for BMA423-specific conversions.
static float samples50HzToMs(uint16_t samples)
Convert duration from 50Hz samples to milliseconds.
static uint16_t msToSamples50Hz(float ms)
Convert duration from milliseconds to 50Hz samples.
static float threshold5_11ToMg(uint16_t threshold_5_11)
Converts threshold values in 5.11g format to milligrams (mg)
static uint16_t mgToThreshold5_11(float threshold_mg)
Convert threshold from milli-g to 5.11g format.
void setOnStepDetectedCallback(std::function< void()> cb)
Set the callback for step detection events.
void setOnDataReadyCallback(std::function< void(AccelerometerData)> cb)
Set the callback for data ready events.
bool configNoMotion(uint16_t threshold, uint16_t duration) override
Configure no-motion detection using raw register values.
SensorBMA423()
Constructor for the SensorBMA423 class.
void setOnTapCallback(std::function< void(TapType)> cb)
Set the callback for tap events.
~SensorBMA423()=default
Destructor for the SensorBMA423 class.
bool getStepCounterWatermark(uint16_t &step_counter_wm) const
Get the current step counter watermark.
bool isNoMotionEnabled() const
Check if no-motion detection is enabled.
bool configAnyMotion(uint16_t threshold, uint16_t duration) override
Configure any-motion detection using raw register values.
void setOnActivityCallback(std::function< void(ActivityType)> cb)
Set the callback for activity events.
bool enableDataReady(bool enable=true, InterruptPinMap pin_map=InterruptPinMap::PIN1) override
Enable data ready interrupt.
bool resetStepCounter()
Reset the step counter.
bool enableNoMotionDetection(const MotionAxesConfig &cfg, bool enable, bool interrupt_enable=false, InterruptPinMap pin_map=InterruptPinMap::PIN1) override
Enable or disable no-motion detection.
bool selectTapType(TapType tap)
Select tap detection tap type.
bool enableStepCounter(bool enable, uint16_t step_counter_wm=1, bool reset_counter=false) override
Enable or disable step counter.
void setCallbacks(const EventCallbacks &cbs)
Set all callbacks at once.
void setOnNoMotionCallback(std::function< void(void)> cb)
Set the callback for no-motion events.
const EventCallbacks & getCallbacks() const
Get the current callbacks (const version)
uint8_t getEnabledMotionFeature() const
Get which motion detection feature is currently enabled.
bool selectPlatform(Platform platform)
Select the platform for the sensor.
bool enableTapDetector(bool enable, bool interrupt_enable=false, InterruptPinMap pin_map=InterruptPinMap::PIN1) override
Enable or disable tap detection.
bool getMotionConfig(uint16_t &threshold, uint16_t &duration, bool &no_motion)
Get current no-motion/any-motion detection configuration for BMA423.
bool isAnyMotionEnabled() const
Check if any-motion detection is enabled.
EventCallbacks & getCallbacks()
Get the current callbacks.
Platform
Select the platform for the sensor.
bool enableActivityRecognition(bool enable, bool interrupt_enable=false, InterruptPinMap pin_map=InterruptPinMap::PIN1) override
Enable or disable activity recognition.
bool configMotion(bool any_motion, uint16_t threshold, uint16_t duration) override
Configure motion detection parameters using raw register values.
bool enableStepDetector(bool enable, bool interrupt_enable=false, InterruptPinMap pin_map=InterruptPinMap::PIN1) override
Enable or disable step detector.
bool enableAnyMotionDetection(const MotionAxesConfig &cfg, bool enable, bool interrupt_enable=false, InterruptPinMap pin_map=InterruptPinMap::PIN1) override
Enable or disable any-motion detection.
void setOnStepCountCallback(std::function< void(uint32_t)> cb)
Set the callback for step count events.
BMA4XXCapability::Capability getCapabilities() const override
Get supported capabilities.
void update() override
Update sensor state and process interrupts.
void setOnTiltDetectedCallback(std::function< void(void)> cb)
Set the callback for tilt detection events.
ActivityType getActivityType()
Get the current activity type.
bool enableFeature(uint16_t feature, bool enable)
Enable or disable a specific feature.
bool enableTiltDetector(bool enable, bool interrupt_enable=false, InterruptPinMap pin_map=InterruptPinMap::PIN1) override
Enable or disable tilt detection.
void setOnAnyMotionCallback(std::function< void(void)> cb)
Set the any-motion callback for motion events.
uint32_t getStepCount()
Get the current step count.
uint8_t _remap_reg_offset
bool enableInterrupt(InterruptPinMap pin_map, uint16_t interrupt_sources, bool enable)
Enable or disable specific interrupt sources on a pin.
bool readData(AccelerometerData &data) override
Get the accelerometer data.
std::unique_ptr< struct bma4_dev > dev
ActivityType
Activity detection type.
TapType
Tap detection type.
Structure representing accelerometer data.
Event callbacks for the sensor.
std::function< void()> onTiltDetected
Callback for tilt detection.
std::function< void()> onStepDetected
Callback for step detection events.
std::function< void(TapType)> onTap
Callback for tap detection events.
std::function< void()> onAnyMotion
Callback for any-motion detection.
std::function< void(AccelerometerData &)> onDataReady
Callback for new accelerometer data.
std::function< void()> onNoMotion
Callback for no-motion detection.
std::function< void(ActivityType)> onActivity
Callback for activity recognition events.
std::function< void(uint32_t)> onStepCount
Callback for step count updates.
Motion axes configuration.
uint8_t z_axis
Enable motion detection on Z-axis (1=enabled, 0=disabled)
uint8_t y_axis
Enable motion detection on Y-axis (1=enabled, 0=disabled)
uint8_t x_axis
Enable motion detection on X-axis (1=enabled, 0=disabled)