From b4a7e78d182f72e4b9c1309ea55afd24d1f5edc9 Mon Sep 17 00:00:00 2001 From: Ben Meadors Date: Thu, 16 May 2024 17:27:36 -0500 Subject: [PATCH] Don't reboot for certain config prefs and make accelerometer thread re-entrant (#3889) * Don't reboot for certain config prefs and make accelerometer thread re-entrant * WHOOPS * Don't reboot for LED heartbeat and button press * Remove TZ --- src/AccelerometerThread.h | 89 ++++++++++++++++++++----------------- src/main.cpp | 6 +-- src/main.h | 5 +++ src/modules/AdminModule.cpp | 47 +++++++++++++++++++- 4 files changed, 99 insertions(+), 48 deletions(-) diff --git a/src/AccelerometerThread.h b/src/AccelerometerThread.h index 66e5624f1..ad40cd9bd 100644 --- a/src/AccelerometerThread.h +++ b/src/AccelerometerThread.h @@ -1,3 +1,4 @@ +#pragma once #include "configuration.h" #if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR @@ -14,13 +15,10 @@ #include #include -SensorBMA423 bmaSensor; -bool BMA_IRQ = false; - #define ACCELEROMETER_CHECK_INTERVAL_MS 100 #define ACCELEROMETER_CLICK_THRESHOLD 40 -int readRegister(uint8_t address, uint8_t reg, uint8_t *data, uint8_t len) +static inline int readRegister(uint8_t address, uint8_t reg, uint8_t *data, uint8_t len) { Wire.beginTransmission(address); Wire.write(reg); @@ -33,7 +31,7 @@ int readRegister(uint8_t address, uint8_t reg, uint8_t *data, uint8_t len) return 0; // Pass } -int writeRegister(uint8_t address, uint8_t reg, uint8_t *data, uint8_t len) +static inline int writeRegister(uint8_t address, uint8_t reg, uint8_t *data, uint8_t len) { Wire.beginTransmission(address); Wire.write(reg); @@ -41,8 +39,6 @@ int writeRegister(uint8_t address, uint8_t reg, uint8_t *data, uint8_t len) return (0 != Wire.endTransmission()); } -namespace concurrency -{ class AccelerometerThread : public concurrency::OSThread { public: @@ -53,14 +49,55 @@ class AccelerometerThread : public concurrency::OSThread disable(); return; } + acceleremoter_type = type; if (!config.display.wake_on_tap_or_motion && !config.device.double_tap_as_button_press) { LOG_DEBUG("AccelerometerThread disabling due to no interested configurations\n"); disable(); return; } + init(); + } - acceleremoter_type = type; + void start() + { + init(); + setIntervalFromNow(0); + }; + + protected: + int32_t runOnce() override + { + canSleep = true; // Assume we should not keep the board awake + + if (acceleremoter_type == ScanI2C::DeviceType::MPU6050 && mpu.getMotionInterruptStatus()) { + wakeScreen(); + } else if (acceleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.getClick() > 0) { + uint8_t click = lis.getClick(); + if (!config.device.double_tap_as_button_press) { + wakeScreen(); + } + + if (config.device.double_tap_as_button_press && (click & 0x20)) { + buttonPress(); + return 500; + } + } else if (acceleremoter_type == ScanI2C::DeviceType::BMA423 && bmaSensor.readIrqStatus() != DEV_WIRE_NONE) { + if (bmaSensor.isTilt() || bmaSensor.isDoubleTap()) { + wakeScreen(); + return 500; + } + } else if (acceleremoter_type == ScanI2C::DeviceType::LSM6DS3 && lsm.shake()) { + wakeScreen(); + return 500; + } + + return ACCELEROMETER_CHECK_INTERVAL_MS; + } + + private: + void init() + { LOG_DEBUG("AccelerometerThread initializing\n"); if (acceleremoter_type == ScanI2C::DeviceType::MPU6050 && mpu.begin(accelerometer_found.address)) { @@ -123,38 +160,6 @@ class AccelerometerThread : public concurrency::OSThread // Duration is number of occurances needed to trigger, higher threshold is less sensitive } } - - protected: - int32_t runOnce() override - { - canSleep = true; // Assume we should not keep the board awake - - if (acceleremoter_type == ScanI2C::DeviceType::MPU6050 && mpu.getMotionInterruptStatus()) { - wakeScreen(); - } else if (acceleremoter_type == ScanI2C::DeviceType::LIS3DH && lis.getClick() > 0) { - uint8_t click = lis.getClick(); - if (!config.device.double_tap_as_button_press) { - wakeScreen(); - } - - if (config.device.double_tap_as_button_press && (click & 0x20)) { - buttonPress(); - return 500; - } - } else if (acceleremoter_type == ScanI2C::DeviceType::BMA423 && bmaSensor.readIrqStatus() != DEV_WIRE_NONE) { - if (bmaSensor.isTilt() || bmaSensor.isDoubleTap()) { - wakeScreen(); - return 500; - } - } else if (acceleremoter_type == ScanI2C::DeviceType::LSM6DS3 && lsm.shake()) { - wakeScreen(); - return 500; - } - - return ACCELEROMETER_CHECK_INTERVAL_MS; - } - - private: void wakeScreen() { if (powerFSM.getState() == &stateDARK) { @@ -173,8 +178,8 @@ class AccelerometerThread : public concurrency::OSThread Adafruit_MPU6050 mpu; Adafruit_LIS3DH lis; Adafruit_LSM6DS3TRC lsm; + SensorBMA423 bmaSensor; + bool BMA_IRQ = false; }; -} // namespace concurrency - #endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index f14d08188..64ff92dd7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -94,9 +94,10 @@ NRF52Bluetooth *nrf52Bluetooth; #include "PowerFSMThread.h" -#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR #include "AccelerometerThread.h" #include "AmbientLightingThread.h" +AccelerometerThread *accelerometerThread; #endif #ifdef HAS_I2S @@ -197,9 +198,6 @@ uint32_t timeLastPowered = 0; static Periodic *ledPeriodic; static OSThread *powerFSMthread; -#if !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR -static OSThread *accelerometerThread; -#endif static OSThread *ambientLightingThread; SPISettings spiSettings(4000000, MSBFIRST, SPI_MODE0); diff --git a/src/main.h b/src/main.h index bb812b7b6..db05a4734 100644 --- a/src/main.h +++ b/src/main.h @@ -53,6 +53,11 @@ extern Adafruit_DRV2605 drv; extern AudioThread *audioThread; #endif +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR +#include "AccelerometerThread.h" +extern AccelerometerThread *accelerometerThread; +#endif + extern bool isVibrating; extern int TCPPort; // set by Portduino diff --git a/src/modules/AdminModule.cpp b/src/modules/AdminModule.cpp index adf5620ba..c9416a9b5 100644 --- a/src/modules/AdminModule.cpp +++ b/src/modules/AdminModule.cpp @@ -26,6 +26,9 @@ #if !MESHTASTIC_EXCLUDE_GPS #include "GPS.h" #endif +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR +#include "AccelerometerThread.h" +#endif AdminModule *adminModule; bool hasOpenEditTransaction; @@ -221,12 +224,12 @@ bool AdminModule::handleReceivedProtobuf(const meshtastic_MeshPacket &mp, meshta nodeDB->setLocalPosition(r->set_fixed_position); config.position.fixed_position = true; saveChanges(SEGMENT_DEVICESTATE | SEGMENT_CONFIG, false); - // Send our new fixed position to the mesh for good measure - positionModule->sendOurPosition(); #if !MESHTASTIC_EXCLUDE_GPS if (gps != nullptr) gps->enable(); #endif + // Send our new fixed position to the mesh for good measure + positionModule->sendOurPosition(); } break; } @@ -352,6 +355,26 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c) case meshtastic_Config_device_tag: LOG_INFO("Setting config: Device\n"); config.has_device = true; +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + if (config.device.double_tap_as_button_press == false && c.payload_variant.device.double_tap_as_button_press == true) { + accelerometerThread->start(); + } +#endif +#ifdef LED_PIN + // Turn LED off if heartbeat by config + if (c.payload_variant.device.led_heartbeat_disabled) { + digitalWrite(LED_PIN, LOW ^ LED_INVERTED); + } +#endif + if (config.device.button_gpio == c.payload_variant.device.button_gpio && + config.device.buzzer_gpio == c.payload_variant.device.buzzer_gpio && + config.device.debug_log_enabled == c.payload_variant.device.debug_log_enabled && + config.device.serial_enabled == c.payload_variant.device.serial_enabled && + config.device.role == c.payload_variant.device.role && + config.device.disable_triple_click == c.payload_variant.device.disable_triple_click && + config.device.rebroadcast_mode == c.payload_variant.device.rebroadcast_mode) { + requiresReboot = false; + } config.device = c.payload_variant.device; // If we're setting router role for the first time, install its intervals if (existingRole != c.payload_variant.device.role) @@ -371,6 +394,16 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c) case meshtastic_Config_power_tag: LOG_INFO("Setting config: Power\n"); config.has_power = true; + // Really just the adc override is the only thing that can change without a reboot + if (config.power.device_battery_ina_address == c.payload_variant.power.device_battery_ina_address && + config.power.is_power_saving == c.payload_variant.power.is_power_saving && + config.power.ls_secs == c.payload_variant.power.ls_secs && + config.power.min_wake_secs == c.payload_variant.power.min_wake_secs && + config.power.on_battery_shutdown_after_secs == c.payload_variant.power.on_battery_shutdown_after_secs && + config.power.sds_secs == c.payload_variant.power.sds_secs && + config.power.wait_bluetooth_secs == c.payload_variant.power.wait_bluetooth_secs) { + requiresReboot = false; + } config.power = c.payload_variant.power; break; case meshtastic_Config_network_tag: @@ -381,6 +414,16 @@ void AdminModule::handleSetConfig(const meshtastic_Config &c) case meshtastic_Config_display_tag: LOG_INFO("Setting config: Display\n"); config.has_display = true; + if (config.display.screen_on_secs == c.payload_variant.display.screen_on_secs && + config.display.flip_screen == c.payload_variant.display.flip_screen && + config.display.oled == c.payload_variant.display.oled) { + requiresReboot = false; + } +#if !defined(ARCH_PORTDUINO) && !defined(ARCH_STM32WL) && !MESHTASTIC_EXCLUDE_ENVIRONMENTAL_SENSOR + if (config.display.wake_on_tap_or_motion == false && c.payload_variant.display.wake_on_tap_or_motion == true) { + accelerometerThread->start(); + } +#endif config.display = c.payload_variant.display; break; case meshtastic_Config_lora_tag: