mirror of
https://github.com/meshtastic/firmware.git
synced 2026-09-29 17:55:25 -04:00
Stop accelerometer thread when double-tap/wake-on-motion disabled at runtime (#11025)
* Stop accelerometer thread when double-tap/wake-on-motion disabled at runtime double_tap_as_button_press and wake_on_tap_or_motion are applied live: the OFF->ON edge calls accelerometerThread->start(), but there was no ON->OFF branch, so turning either flag off left the sensor thread running (polling I2C, drawing power) until reboot. Worse, because enabled stayed true, a later OFF->ON edge was a no-op (the enabled==false guard blocked re-start), leaving the feature un-restartable without a reboot. Add the symmetric ON->OFF branch in both handlers. When a flag goes true->off and the other consumer of the shared thread is also off, call accelerometerThread->disable() (stops runOnce polling and clears enabled so a later re-enable can start() again). Each branch checks the other flag first so disabling one feature never stops the sensor while the other still needs it. * Keep accelerometer thread running when its sensor drives the compass * Guard accelerometer thread config toggles against a null thread pointer * AdminModule: factor shared accelerometer start/stop into a helper The device and display config handlers had mirror-image blocks reconciling the shared accelerometer thread. Extract reconcileAccelerometerThread(wasOn, nowOn, otherFeatureOn) so the null guard, edge logic, compass (providesHeading) guard, and rationale live in one place; each call site is now a single call. Behavior is unchanged. Also drops the redundant per-field assignment that the whole-struct `config.device = ...` / `config.display = ...` overwrites anyway. --------- Co-authored-by: Thomas Göttgens <tgoettgens@gmail.com>
This commit is contained in:
1 parent
40d0d80f35
commit
b20d89974a
6 files changed
+38
-12
No files matched your search
+25
-12
@@ -786,6 +786,27 @@ void AdminModule::handleSetOwner(const meshtastic_User &o)
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && \
|
||||
!MESHTASTIC_EXCLUDE_ACCELEROMETER
|
||||
// Shared by double-tap-as-button (device) and wake-on-motion (display). Start on either flag's
|
||||
// off->on edge; stop on the on->off edge once neither needs it (disable() clears `enabled` so a
|
||||
// later re-enable restarts). Skip the stop if the sensor also drives the compass, else the heading
|
||||
// freezes until reboot. wasOn/nowOn = old/new of the changed flag; otherFeatureOn = the other flag.
|
||||
static void reconcileAccelerometerThread(bool wasOn, bool nowOn, bool otherFeatureOn)
|
||||
{
|
||||
if (!accelerometerThread) // null unless a sensor was detected at boot
|
||||
return;
|
||||
|
||||
if (!wasOn && nowOn && accelerometerThread->enabled == false) {
|
||||
accelerometerThread->enabled = true;
|
||||
accelerometerThread->start();
|
||||
} else if (wasOn && !nowOn && !otherFeatureOn && accelerometerThread->enabled == true &&
|
||||
!accelerometerThread->providesHeading()) {
|
||||
accelerometerThread->disable();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void AdminModule::handleSetConfig(const meshtastic_Config &c, bool fromOthers)
|
||||
{
|
||||
auto changes = SEGMENT_CONFIG;
|
||||
@@ -801,12 +822,8 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c, bool fromOthers)
|
||||
config.has_device = true;
|
||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && \
|
||||
!MESHTASTIC_EXCLUDE_ACCELEROMETER
|
||||
if (config.device.double_tap_as_button_press == false && c.payload_variant.device.double_tap_as_button_press == true &&
|
||||
accelerometerThread->enabled == false) {
|
||||
config.device.double_tap_as_button_press = c.payload_variant.device.double_tap_as_button_press;
|
||||
accelerometerThread->enabled = true;
|
||||
accelerometerThread->start();
|
||||
}
|
||||
reconcileAccelerometerThread(config.device.double_tap_as_button_press,
|
||||
c.payload_variant.device.double_tap_as_button_press, config.display.wake_on_tap_or_motion);
|
||||
#endif
|
||||
if (config.device.button_gpio == c.payload_variant.device.button_gpio &&
|
||||
config.device.buzzer_gpio == c.payload_variant.device.buzzer_gpio &&
|
||||
@@ -905,12 +922,8 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c, bool fromOthers)
|
||||
}
|
||||
#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR && \
|
||||
!MESHTASTIC_EXCLUDE_ACCELEROMETER
|
||||
if (config.display.wake_on_tap_or_motion == false && c.payload_variant.display.wake_on_tap_or_motion == true &&
|
||||
accelerometerThread->enabled == false) {
|
||||
config.display.wake_on_tap_or_motion = c.payload_variant.display.wake_on_tap_or_motion;
|
||||
accelerometerThread->enabled = true;
|
||||
accelerometerThread->start();
|
||||
}
|
||||
reconcileAccelerometerThread(config.display.wake_on_tap_or_motion, c.payload_variant.display.wake_on_tap_or_motion,
|
||||
config.device.double_tap_as_button_press);
|
||||
#endif
|
||||
config.display = c.payload_variant.display;
|
||||
break;
|
||||
|
||||
Reference in new issue
Block a user