From 0200d452415e40554c1c0b6fe027447009aedbeb Mon Sep 17 00:00:00 2001 From: oscgonfer Date: Mon, 25 May 2026 13:51:29 +0200 Subject: [PATCH] Make reclock function aware of screen-set I2C speeds --- src/detect/reClockI2C.cpp | 43 ++-- src/detect/reClockI2C.h | 5 +- .../Telemetry/Sensor/PMSA003ISensor.cpp | 39 ++-- src/modules/Telemetry/Sensor/PMSA003ISensor.h | 1 + src/modules/Telemetry/Sensor/SCD30Sensor.cpp | 116 +++++------ src/modules/Telemetry/Sensor/SCD30Sensor.h | 1 + src/modules/Telemetry/Sensor/SCD4XSensor.cpp | 186 +++++++++--------- src/modules/Telemetry/Sensor/SCD4XSensor.h | 1 + src/modules/Telemetry/Sensor/SEN5XSensor.cpp | 40 ++-- src/modules/Telemetry/Sensor/SEN5XSensor.h | 1 + src/modules/Telemetry/Sensor/SFA30Sensor.cpp | 110 ++++++----- src/modules/Telemetry/Sensor/SFA30Sensor.h | 2 + 12 files changed, 280 insertions(+), 265 deletions(-) diff --git a/src/detect/reClockI2C.cpp b/src/detect/reClockI2C.cpp index 60cd3c808..df81a7e23 100644 --- a/src/detect/reClockI2C.cpp +++ b/src/detect/reClockI2C.cpp @@ -1,29 +1,42 @@ #include "reClockI2C.h" #include "ScanI2CTwoWire.h" -uint32_t reClockI2C(uint32_t desiredClock, TwoWire *i2cBus, bool force) +/* See https://github.com/arduino/Arduino/issues/11457 + Currently, only ESP32 can getClock() + While all cores can setClock() + https://github.com/sandeepmistry/arduino-nRF5/blob/master/libraries/Wire/Wire.h#L50 + https://github.com/earlephilhower/arduino-pico/blob/master/libraries/Wire/src/Wire.h#L60 + https://github.com/stm32duino/Arduino_Core_STM32/blob/main/libraries/Wire/src/Wire.h#L103 + For cases when I2C speed is different to the ones defined by sensors (see defines in sensor classes) + we need to reclock I2C and set it back to the previous stablished speed. + Only for cases where we can know it (ESP32 or known screen) we can do this. +*/ + +uint32_t reClockI2C(uint32_t desiredClock, TwoWire *i2cBus, ScanI2C::I2CPort port) { uint32_t currentClock = 0; + uint32_t screenClock = 0; + ScanI2C::I2CPort screenPort = ScanI2C::I2CPort::NO_I2C; - /* See https://github.com/arduino/Arduino/issues/11457 - Currently, only ESP32 can getClock() - While all cores can setClock() - https://github.com/sandeepmistry/arduino-nRF5/blob/master/libraries/Wire/Wire.h#L50 - https://github.com/earlephilhower/arduino-pico/blob/master/libraries/Wire/src/Wire.h#L60 - https://github.com/stm32duino/Arduino_Core_STM32/blob/main/libraries/Wire/src/Wire.h#L103 - For cases when I2C speed is different to the ones defined by sensors (see defines in sensor classes) - we need to reclock I2C and set it back to the previous desired speed. - Only for cases where we can know OR predefine the speed, we can do this. - */ - -// TODO add getClock function or return a predefined clock speed per variant? + // Assume that if we can't getClock, or there is no screen, we can set the clock speed at will #ifdef CAN_RECLOCK_I2C currentClock = i2cBus->getClock(); + LOG_DEBUG("Current I2C frequency: %uHz", currentClock); +#elif HAS_SCREEN + if (screen) { + // If we get a non-zero response here, the screen has set a speed + screenClock = screen->getI2cFrequency(); + screenPort = screen->getI2CPort(); + // Check if i2c port is the same, and that we got a screenClock back (0 means the screen didn't set it) + if (screenClock && (screenPort == port)) + currentClock = screenClock; + LOG_DEBUG("Screen defined I2C frequency: %uHz", screenClock); + } #endif - if ((currentClock != desiredClock) || force) { - LOG_DEBUG("Changing I2C clock to %u", desiredClock); + if (currentClock != desiredClock) { + LOG_DEBUG("Changing I2C clock to %uHz", desiredClock); i2cBus->setClock(desiredClock); } diff --git a/src/detect/reClockI2C.h b/src/detect/reClockI2C.h index 9c53efc4f..b28525414 100644 --- a/src/detect/reClockI2C.h +++ b/src/detect/reClockI2C.h @@ -2,10 +2,13 @@ #ifndef RECLOCK_I2C_ #define RECLOCK_I2C_ +#include "../graphics/Screen.h" #include "ScanI2CTwoWire.h" #include #include -uint32_t reClockI2C(uint32_t desiredClock, TwoWire *i2cBus, bool force); +uint32_t reClockI2C(uint32_t desiredClock, TwoWire *i2cBus, ScanI2C::I2CPort port); + +extern graphics::Screen *screen; #endif diff --git a/src/modules/Telemetry/Sensor/PMSA003ISensor.cpp b/src/modules/Telemetry/Sensor/PMSA003ISensor.cpp index e34b70a1f..c6711fc5a 100644 --- a/src/modules/Telemetry/Sensor/PMSA003ISensor.cpp +++ b/src/modules/Telemetry/Sensor/PMSA003ISensor.cpp @@ -20,16 +20,11 @@ bool PMSA003ISensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) _bus = bus; _address = dev->address.address; + _port = dev->address.port; #ifdef PMSA003I_I2C_CLOCK_SPEED -#ifdef CAN_RECLOCK_I2C - uint32_t currentClock = reClockI2C(PMSA003I_I2C_CLOCK_SPEED, _bus, false); -#elif !HAS_SCREEN - reClockI2C(PMSA003I_I2C_CLOCK_SPEED, _bus, true); -#else - LOG_WARN("%s can't be used at this clock speed, with a screen", sensorName); - return false; -#endif /* CAN_RECLOCK_I2C */ + LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, PMSA003I_I2C_CLOCK_SPEED); + uint32_t currentClock = reClockI2C(PMSA003I_I2C_CLOCK_SPEED, _bus, _port); #endif /* PMSA003I_I2C_CLOCK_SPEED */ _bus->beginTransmission(_address); @@ -38,9 +33,12 @@ bool PMSA003ISensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) return false; } -#if defined(PMSA003I_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef PMSA003I_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* PMSA003I_I2C_CLOCK_SPEED */ status = 1; LOG_INFO("%s Enabled", sensorName); @@ -57,14 +55,8 @@ bool PMSA003ISensor::getMetrics(meshtastic_Telemetry *measurement) } #ifdef PMSA003I_I2C_CLOCK_SPEED -#ifdef CAN_RECLOCK_I2C - uint32_t currentClock = reClockI2C(PMSA003I_I2C_CLOCK_SPEED, _bus, false); -#elif !HAS_SCREEN - reClockI2C(PMSA003I_I2C_CLOCK_SPEED, _bus, true); -#else - LOG_WARN("%s can't be used at this clock speed, with a screen", sensorName); - return false; -#endif /* CAN_RECLOCK_I2C */ + LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, PMSA003I_I2C_CLOCK_SPEED); + uint32_t currentClock = reClockI2C(PMSA003I_I2C_CLOCK_SPEED, _bus, _port); #endif /* PMSA003I_I2C_CLOCK_SPEED */ _bus->requestFrom(_address, (uint8_t)PMSA003I_FRAME_LENGTH); @@ -77,9 +69,12 @@ bool PMSA003ISensor::getMetrics(meshtastic_Telemetry *measurement) buffer[i] = _bus->read(); } -#if defined(PMSA003I_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef PMSA003I_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* PMSA003I_I2C_CLOCK_SPEED */ if (buffer[0] != 0x42 || buffer[1] != 0x4D) { LOG_WARN("%s frame header invalid: 0x%02X 0x%02X", sensorName, buffer[0], buffer[1]); diff --git a/src/modules/Telemetry/Sensor/PMSA003ISensor.h b/src/modules/Telemetry/Sensor/PMSA003ISensor.h index 3fe96888d..ed01a188d 100644 --- a/src/modules/Telemetry/Sensor/PMSA003ISensor.h +++ b/src/modules/Telemetry/Sensor/PMSA003ISensor.h @@ -35,6 +35,7 @@ class PMSA003ISensor : public TelemetrySensor uint8_t buffer[PMSA003I_FRAME_LENGTH]{}; TwoWire *_bus{}; uint8_t _address{}; + ScanI2C::I2CPort _port = ScanI2C::I2CPort::NO_I2C; }; #endif \ No newline at end of file diff --git a/src/modules/Telemetry/Sensor/SCD30Sensor.cpp b/src/modules/Telemetry/Sensor/SCD30Sensor.cpp index 0478b6651..b9c7617ad 100644 --- a/src/modules/Telemetry/Sensor/SCD30Sensor.cpp +++ b/src/modules/Telemetry/Sensor/SCD30Sensor.cpp @@ -16,25 +16,23 @@ bool SCD30Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) _bus = bus; _address = dev->address.address; + _port = dev->address.port; #ifdef SCD30_I2C_CLOCK_SPEED -#ifdef CAN_RECLOCK_I2C - uint32_t currentClock = reClockI2C(SCD30_I2C_CLOCK_SPEED, _bus, false); -#elif !HAS_SCREEN - reClockI2C(SCD30_I2C_CLOCK_SPEED, _bus, true); -#else - LOG_WARN("%s can't be used at this clock speed, with a screen", sensorName); - return false; -#endif /* CAN_RECLOCK_I2C */ + LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD30_I2C_CLOCK_SPEED); + uint32_t currentClock = reClockI2C(SCD30_I2C_CLOCK_SPEED, _bus, _port); #endif /* SCD30_I2C_CLOCK_SPEED */ scd30.begin(*_bus, _address); if (!startMeasurement()) { LOG_ERROR("%s: Failed to start periodic measurement", sensorName); -#if defined(SCD30_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SCD30_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SCD30_I2C_CLOCK_SPEED */ return false; } @@ -42,9 +40,12 @@ bool SCD30Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) LOG_WARN("%s: Could not determine ASC state", sensorName); } -#if defined(SCD30_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SCD30_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SCD30_I2C_CLOCK_SPEED */ if (state == SCD30_MEASUREMENT) { status = 1; @@ -62,27 +63,28 @@ bool SCD30Sensor::getMetrics(meshtastic_Telemetry *measurement) float co2, temperature, humidity; #ifdef SCD30_I2C_CLOCK_SPEED -#ifdef CAN_RECLOCK_I2C - uint32_t currentClock = reClockI2C(SCD30_I2C_CLOCK_SPEED, _bus, false); -#elif !HAS_SCREEN - reClockI2C(SCD30_I2C_CLOCK_SPEED, _bus, true); -#else - LOG_WARN("%s can't be used at this clock speed, with a screen", sensorName); - return false; -#endif /* CAN_RECLOCK_I2C */ + LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD30_I2C_CLOCK_SPEED); + uint32_t currentClock = reClockI2C(SCD30_I2C_CLOCK_SPEED, _bus, _port); #endif /* SCD30_I2C_CLOCK_SPEED */ if (scd30.readMeasurementData(co2, temperature, humidity) != SCD30_NO_ERROR) { LOG_ERROR("SCD30: Failed to read measurement data."); -#if defined(SCD30_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SCD30_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SCD30_I2C_CLOCK_SPEED */ + return false; } -#if defined(SCD30_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SCD30_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SCD30_I2C_CLOCK_SPEED */ if (co2 == 0) { LOG_ERROR("SCD30: Invalid CO₂ reading."); @@ -372,23 +374,19 @@ bool SCD30Sensor::isActive() */ uint32_t SCD30Sensor::wakeUp() { - #ifdef SCD30_I2C_CLOCK_SPEED -#ifdef CAN_RECLOCK_I2C - uint32_t currentClock = reClockI2C(SCD30_I2C_CLOCK_SPEED, _bus, false); -#elif !HAS_SCREEN - reClockI2C(SCD30_I2C_CLOCK_SPEED, _bus, true); -#else - LOG_WARN("%s can't be used at this clock speed, with a screen", sensorName); - return 0; -#endif /* CAN_RECLOCK_I2C */ + LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD30_I2C_CLOCK_SPEED); + uint32_t currentClock = reClockI2C(SCD30_I2C_CLOCK_SPEED, _bus, _port); #endif /* SCD30_I2C_CLOCK_SPEED */ startMeasurement(); -#if defined(SCD30_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SCD30_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SCD30_I2C_CLOCK_SPEED */ return 0; } @@ -400,21 +398,18 @@ uint32_t SCD30Sensor::wakeUp() void SCD30Sensor::sleep() { #ifdef SCD30_I2C_CLOCK_SPEED -#ifdef CAN_RECLOCK_I2C - uint32_t currentClock = reClockI2C(SCD30_I2C_CLOCK_SPEED, _bus, false); -#elif !HAS_SCREEN - reClockI2C(SCD30_I2C_CLOCK_SPEED, _bus, true); -#else - LOG_WARN("%s can't be used at this clock speed, with a screen", sensorName); - return; -#endif /* CAN_RECLOCK_I2C */ + LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD30_I2C_CLOCK_SPEED); + uint32_t currentClock = reClockI2C(SCD30_I2C_CLOCK_SPEED, _bus, _port); #endif /* SCD30_I2C_CLOCK_SPEED */ stopMeasurement(); -#if defined(SCD30_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SCD30_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SCD30_I2C_CLOCK_SPEED */ } bool SCD30Sensor::canSleep() @@ -438,14 +433,8 @@ AdminMessageHandleResult SCD30Sensor::handleAdminMessage(const meshtastic_MeshPa AdminMessageHandleResult result; #ifdef SCD30_I2C_CLOCK_SPEED -#ifdef CAN_RECLOCK_I2C - uint32_t currentClock = reClockI2C(SCD30_I2C_CLOCK_SPEED, _bus, false); -#elif !HAS_SCREEN - reClockI2C(SCD30_I2C_CLOCK_SPEED, _bus, true); -#else - LOG_WARN("%s can't be used at this clock speed, with a screen", sensorName); - return AdminMessageHandleResult::NOT_HANDLED; -#endif /* CAN_RECLOCK_I2C */ + LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD30_I2C_CLOCK_SPEED); + uint32_t currentClock = reClockI2C(SCD30_I2C_CLOCK_SPEED, _bus, _port); #endif /* SCD30_I2C_CLOCK_SPEED */ switch (request->which_payload_variant) { @@ -501,9 +490,12 @@ AdminMessageHandleResult SCD30Sensor::handleAdminMessage(const meshtastic_MeshPa result = AdminMessageHandleResult::NOT_HANDLED; } -#if defined(SCD30_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SCD30_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SCD30_I2C_CLOCK_SPEED */ return result; } diff --git a/src/modules/Telemetry/Sensor/SCD30Sensor.h b/src/modules/Telemetry/Sensor/SCD30Sensor.h index 6e03e2dda..067b9b73b 100644 --- a/src/modules/Telemetry/Sensor/SCD30Sensor.h +++ b/src/modules/Telemetry/Sensor/SCD30Sensor.h @@ -14,6 +14,7 @@ class SCD30Sensor : public TelemetrySensor SensirionI2cScd30 scd30; TwoWire *_bus{}; uint8_t _address{}; + ScanI2C::I2CPort _port = ScanI2C::I2CPort::NO_I2C; bool performFRC(uint16_t targetCO2); bool setASC(bool ascEnabled); diff --git a/src/modules/Telemetry/Sensor/SCD4XSensor.cpp b/src/modules/Telemetry/Sensor/SCD4XSensor.cpp index c6ab7bb04..d5f88312b 100644 --- a/src/modules/Telemetry/Sensor/SCD4XSensor.cpp +++ b/src/modules/Telemetry/Sensor/SCD4XSensor.cpp @@ -18,14 +18,8 @@ bool SCD4XSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) _address = dev->address.address; #ifdef SCD4X_I2C_CLOCK_SPEED -#ifdef CAN_RECLOCK_I2C - uint32_t currentClock = reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, false); -#elif !HAS_SCREEN - reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, true); -#else - LOG_WARN("%s can't be used at this clock speed, with a screen", sensorName); - return false; -#endif /* CAN_RECLOCK_I2C */ + LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD4X_I2C_CLOCK_SPEED); + uint32_t currentClock = reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, _port); #endif /* SCD4X_I2C_CLOCK_SPEED */ scd4x.begin(*_bus, _address); @@ -35,9 +29,12 @@ bool SCD4XSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) // Stop periodic measurement if (!stopMeasurement()) { -#if defined(SCD4X_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SCD4X_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SCD4X_I2C_CLOCK_SPEED */ return false; } @@ -48,33 +45,45 @@ bool SCD4XSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) LOG_INFO("%s: Found SCD41", sensorName); if (!powerUp()) { LOG_ERROR("%s: Error trying to execute powerUp()", sensorName); -#if defined(SCD4X_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SCD4X_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SCD4X_I2C_CLOCK_SPEED */ return false; } } if (!getASC(ascActive)) { LOG_ERROR("%s: Unable to check if ASC is enabled", sensorName); -#if defined(SCD4X_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SCD4X_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SCD4X_I2C_CLOCK_SPEED */ return false; } // Start measurement in selected power mode (low power by default) if (!startMeasurement()) { LOG_ERROR("%s: Couldn't start measurement", sensorName); -#if defined(SCD4X_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SCD4X_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SCD4X_I2C_CLOCK_SPEED */ return false; } -#if defined(SCD4X_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SCD4X_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SCD4X_I2C_CLOCK_SPEED */ if (state == SCD4X_MEASUREMENT) { status = 1; @@ -99,31 +108,31 @@ bool SCD4XSensor::getMetrics(meshtastic_Telemetry *measurement) float temperature, humidity; #ifdef SCD4X_I2C_CLOCK_SPEED -#ifdef CAN_RECLOCK_I2C - uint32_t currentClock = reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, false); -#elif !HAS_SCREEN - reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, true); -#else - LOG_WARN("%s can't be used at this clock speed, with a screen", sensorName); - return false; -#endif /* CAN_RECLOCK_I2C */ + LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD4X_I2C_CLOCK_SPEED); + uint32_t currentClock = reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, _port); #endif /* SCD4X_I2C_CLOCK_SPEED */ bool dataReady; error = scd4x.getDataReadyStatus(dataReady); if (error != SCD4X_NO_ERROR || !dataReady) { -#if defined(SCD4X_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SCD4X_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SCD4X_I2C_CLOCK_SPEED */ LOG_ERROR("SCD4X: Data is not ready"); return false; } error = scd4x.readMeasurement(co2, temperature, humidity); -#if defined(SCD4X_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SCD4X_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SCD4X_I2C_CLOCK_SPEED */ LOG_DEBUG("Got %s readings: co2=%u, co2_temp=%.2f, co2_hum%.2f", sensorName, co2, temperature, humidity); if (error != SCD4X_NO_ERROR) { @@ -637,34 +646,37 @@ bool SCD4XSensor::powerDown() } #ifdef SCD4X_I2C_CLOCK_SPEED -#ifdef CAN_RECLOCK_I2C - uint32_t currentClock = reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, false); -#elif !HAS_SCREEN - reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, true); -#else - LOG_WARN("%s can't be used at this clock speed, with a screen", sensorName); - return false; -#endif /* CAN_RECLOCK_I2C */ + LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD4X_I2C_CLOCK_SPEED); + uint32_t currentClock = reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, _port); #endif /* SCD4X_I2C_CLOCK_SPEED */ if (!stopMeasurement()) { -#if defined(SCD4X_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SCD4X_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SCD4X_I2C_CLOCK_SPEED */ return false; } if (scd4x.powerDown() != SCD4X_NO_ERROR) { LOG_ERROR("%s: Error trying to execute sleep()", sensorName); -#if defined(SCD4X_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SCD4X_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SCD4X_I2C_CLOCK_SPEED */ return false; } -#if defined(SCD4X_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SCD4X_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SCD4X_I2C_CLOCK_SPEED */ state = SCD4X_OFF; return true; @@ -711,27 +723,27 @@ uint32_t SCD4XSensor::wakeUp() { #ifdef SCD4X_I2C_CLOCK_SPEED -#ifdef CAN_RECLOCK_I2C - uint32_t currentClock = reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, false); -#elif !HAS_SCREEN - reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, true); -#else - LOG_WARN("%s can't be used at this clock speed, with a screen", sensorName); - return 0; -#endif /* CAN_RECLOCK_I2C */ + LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD4X_I2C_CLOCK_SPEED); + uint32_t currentClock = reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, _port); #endif /* SCD4X_I2C_CLOCK_SPEED */ if (startMeasurement()) { co2MeasureStarted = getTime(); -#if defined(SCD4X_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SCD4X_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SCD4X_I2C_CLOCK_SPEED */ return SCD4X_WARMUP_MS; } -#if defined(SCD4X_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SCD4X_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SCD4X_I2C_CLOCK_SPEED */ return 0; } @@ -743,21 +755,18 @@ uint32_t SCD4XSensor::wakeUp() void SCD4XSensor::sleep() { #ifdef SCD4X_I2C_CLOCK_SPEED -#ifdef CAN_RECLOCK_I2C - uint32_t currentClock = reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, false); -#elif !HAS_SCREEN - reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, true); -#else - LOG_WARN("%s can't be used at this clock speed, with a screen", sensorName); - return; -#endif /* CAN_RECLOCK_I2C */ + LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD4X_I2C_CLOCK_SPEED); + uint32_t currentClock = reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, _port); #endif /* SCD4X_I2C_CLOCK_SPEED */ stopMeasurement(); -#if defined(SCD4X_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SCD4X_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SCD4X_I2C_CLOCK_SPEED */ } /** @@ -797,14 +806,8 @@ AdminMessageHandleResult SCD4XSensor::handleAdminMessage(const meshtastic_MeshPa AdminMessageHandleResult result; #ifdef SCD4X_I2C_CLOCK_SPEED -#ifdef CAN_RECLOCK_I2C - uint32_t currentClock = reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, false); -#elif !HAS_SCREEN - reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, true); -#else - LOG_WARN("%s can't be used at this clock speed, with a screen", sensorName); - return AdminMessageHandleResult::NOT_HANDLED; -#endif /* CAN_RECLOCK_I2C */ + LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SCD4X_I2C_CLOCK_SPEED); + uint32_t currentClock = reClockI2C(SCD4X_I2C_CLOCK_SPEED, _bus, _port); #endif /* SCD4X_I2C_CLOCK_SPEED */ // TODO: potentially add selftest command? @@ -907,9 +910,12 @@ AdminMessageHandleResult SCD4XSensor::handleAdminMessage(const meshtastic_MeshPa // Start measurement mode this->startMeasurement(); -#if defined(SCD4X_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SCD4X_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SCD4X_I2C_CLOCK_SPEED */ return result; } diff --git a/src/modules/Telemetry/Sensor/SCD4XSensor.h b/src/modules/Telemetry/Sensor/SCD4XSensor.h index 1ed86a183..76d36dda8 100644 --- a/src/modules/Telemetry/Sensor/SCD4XSensor.h +++ b/src/modules/Telemetry/Sensor/SCD4XSensor.h @@ -17,6 +17,7 @@ class SCD4XSensor : public TelemetrySensor SensirionI2cScd4x scd4x; TwoWire *_bus{}; uint8_t _address{}; + ScanI2C::I2CPort _port = ScanI2C::I2CPort::NO_I2C; bool performFRC(uint32_t targetCO2); bool setASCBaseline(uint32_t targetCO2); diff --git a/src/modules/Telemetry/Sensor/SEN5XSensor.cpp b/src/modules/Telemetry/Sensor/SEN5XSensor.cpp index b638bf47f..4dd9b5db6 100644 --- a/src/modules/Telemetry/Sensor/SEN5XSensor.cpp +++ b/src/modules/Telemetry/Sensor/SEN5XSensor.cpp @@ -134,14 +134,8 @@ bool SEN5XSensor::sendCommand(uint16_t command, uint8_t *buffer, uint8_t byteNum } #ifdef SEN5X_I2C_CLOCK_SPEED -#ifdef CAN_RECLOCK_I2C - uint32_t currentClock = reClockI2C(SEN5X_I2C_CLOCK_SPEED, _bus, false); -#elif !HAS_SCREEN - reClockI2C(SEN5X_I2C_CLOCK_SPEED, _bus, true); -#else - LOG_WARN("%s can't be used at this clock speed, with a screen", sensorName); - return false; -#endif /* CAN_RECLOCK_I2C */ + LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SEN5X_I2C_CLOCK_SPEED); + uint32_t currentClock = reClockI2C(SEN5X_I2C_CLOCK_SPEED, _bus, _port); #endif /* SEN5X_I2C_CLOCK_SPEED */ // Transmit the data @@ -152,9 +146,12 @@ bool SEN5XSensor::sendCommand(uint16_t command, uint8_t *buffer, uint8_t byteNum size_t writtenBytes = _bus->write(toSend, bufferSize); uint8_t i2c_error = _bus->endTransmission(); -#if defined(SEN5X_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SEN5X_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SEN5X_I2C_CLOCK_SPEED */ if (writtenBytes != bufferSize) { LOG_ERROR("SEN5X: Error writting on I2C bus"); @@ -171,14 +168,8 @@ bool SEN5XSensor::sendCommand(uint16_t command, uint8_t *buffer, uint8_t byteNum uint8_t SEN5XSensor::readBuffer(uint8_t *buffer, uint8_t byteNumber) { #ifdef SEN5X_I2C_CLOCK_SPEED -#ifdef CAN_RECLOCK_I2C - uint32_t currentClock = reClockI2C(SEN5X_I2C_CLOCK_SPEED, _bus, false); -#elif !HAS_SCREEN - reClockI2C(SEN5X_I2C_CLOCK_SPEED, _bus, true); -#else - LOG_WARN("%s can't be used at this clock speed, with a screen", sensorName); - return false; -#endif /* CAN_RECLOCK_I2C */ + LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SEN5X_I2C_CLOCK_SPEED); + uint32_t currentClock = reClockI2C(SEN5X_I2C_CLOCK_SPEED, _bus, _port); #endif /* SEN5X_I2C_CLOCK_SPEED */ size_t readBytes = _bus->requestFrom(_address, byteNumber); @@ -201,9 +192,13 @@ uint8_t SEN5XSensor::readBuffer(uint8_t *buffer, uint8_t byteNumber) readBytes -= 3; receivedBytes += 2; } -#if defined(SEN5X_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif + +#ifdef SEN5X_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SEN5X_I2C_CLOCK_SPEED */ return receivedBytes; } @@ -567,6 +562,7 @@ bool SEN5XSensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) _bus = bus; _address = dev->address.address; + _port = dev->address.port; delay(50); // without this there is an error on the deviceReset function diff --git a/src/modules/Telemetry/Sensor/SEN5XSensor.h b/src/modules/Telemetry/Sensor/SEN5XSensor.h index 9fb25fdd6..22b1c5846 100644 --- a/src/modules/Telemetry/Sensor/SEN5XSensor.h +++ b/src/modules/Telemetry/Sensor/SEN5XSensor.h @@ -62,6 +62,7 @@ class SEN5XSensor : public TelemetrySensor private: TwoWire *_bus{}; uint8_t _address{}; + ScanI2C::I2CPort _port = ScanI2C::I2CPort::NO_I2C; bool getVersion(); float firmwareVer = -1; diff --git a/src/modules/Telemetry/Sensor/SFA30Sensor.cpp b/src/modules/Telemetry/Sensor/SFA30Sensor.cpp index c5b5845d9..7c8a08544 100644 --- a/src/modules/Telemetry/Sensor/SFA30Sensor.cpp +++ b/src/modules/Telemetry/Sensor/SFA30Sensor.cpp @@ -14,41 +14,45 @@ bool SFA30Sensor::initDevice(TwoWire *bus, ScanI2C::FoundDevice *dev) _bus = bus; _address = dev->address.address; + _port = dev->address.port; #ifdef SFA30_I2C_CLOCK_SPEED -#ifdef CAN_RECLOCK_I2C - uint32_t currentClock = reClockI2C(SFA30_I2C_CLOCK_SPEED, _bus, false); -#elif !HAS_SCREEN - reClockI2C(SFA30_I2C_CLOCK_SPEED, _bus, true); -#else - LOG_WARN("%s can't be used at this clock speed, with a screen", sensorName); - return false; -#endif /* CAN_RECLOCK_I2C */ + LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SFA30_I2C_CLOCK_SPEED); + uint32_t currentClock = reClockI2C(SFA30_I2C_CLOCK_SPEED, _bus, _port); #endif /* SFA30_I2C_CLOCK_SPEED */ sfa30.begin(*_bus, _address); delay(20); if (this->isError(sfa30.deviceReset())) { -#if defined(SFA30_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SFA30_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SFA30_I2C_CLOCK_SPEED */ return false; } state = State::IDLE; if (this->isError(sfa30.startContinuousMeasurement())) { -#if defined(SFA30_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SFA30_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SFA30_I2C_CLOCK_SPEED */ return false; } LOG_INFO("%s starting measurement", sensorName); -#if defined(SFA30_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SFA30_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SFA30_I2C_CLOCK_SPEED */ status = 1; state = State::ACTIVE; @@ -72,14 +76,8 @@ bool SFA30Sensor::isError(uint16_t response) void SFA30Sensor::sleep() { #ifdef SFA30_I2C_CLOCK_SPEED -#ifdef CAN_RECLOCK_I2C - uint32_t currentClock = reClockI2C(SFA30_I2C_CLOCK_SPEED, _bus, false); -#elif !HAS_SCREEN - reClockI2C(SFA30_I2C_CLOCK_SPEED, _bus, true); -#else - LOG_WARN("%s can't be used at this clock speed, with a screen", sensorName); - return; -#endif /* CAN_RECLOCK_I2C */ + LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SFA30_I2C_CLOCK_SPEED); + uint32_t currentClock = reClockI2C(SFA30_I2C_CLOCK_SPEED, _bus, _port); #endif /* SFA30_I2C_CLOCK_SPEED */ // Note - not recommended for this sensor on a periodic basis @@ -87,9 +85,12 @@ void SFA30Sensor::sleep() LOG_ERROR("%s: can't stop measurement", sensorName); }; -#if defined(SFA30_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SFA30_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SFA30_I2C_CLOCK_SPEED */ LOG_INFO("%s: stop measurement", sensorName); state = State::IDLE; @@ -99,27 +100,27 @@ void SFA30Sensor::sleep() uint32_t SFA30Sensor::wakeUp() { #ifdef SFA30_I2C_CLOCK_SPEED -#ifdef CAN_RECLOCK_I2C - uint32_t currentClock = reClockI2C(SFA30_I2C_CLOCK_SPEED, _bus, false); -#elif !HAS_SCREEN - reClockI2C(SFA30_I2C_CLOCK_SPEED, _bus, true); -#else - LOG_WARN("%s can't be used at this clock speed, with a screen", sensorName); - return false; -#endif /* CAN_RECLOCK_I2C */ + LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SFA30_I2C_CLOCK_SPEED); + uint32_t currentClock = reClockI2C(SFA30_I2C_CLOCK_SPEED, _bus, _port); #endif /* SFA30_I2C_CLOCK_SPEED */ LOG_INFO("Waking up %s", sensorName); if (this->isError(sfa30.startContinuousMeasurement())) { -#if defined(SFA30_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SFA30_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SFA30_I2C_CLOCK_SPEED */ return 0; } -#if defined(SFA30_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SFA30_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SFA30_I2C_CLOCK_SPEED */ state = State::ACTIVE; measureStarted = getTime(); @@ -164,24 +165,27 @@ bool SFA30Sensor::getMetrics(meshtastic_Telemetry *measurement) float temperature = 0.0; #ifdef SFA30_I2C_CLOCK_SPEED -#ifdef CAN_RECLOCK_I2C - uint32_t currentClock = reClockI2C(SFA30_I2C_CLOCK_SPEED, _bus, false); -#elif !HAS_SCREEN - reClockI2C(SFA30_I2C_CLOCK_SPEED, _bus, true); -#else - LOG_WARN("%s can't be used at this clock speed, with a screen", sensorName); - return false; -#endif /* CAN_RECLOCK_I2C */ + LOG_INFO("%s attempting to reclock speed to %uHz", sensorName, SFA30_I2C_CLOCK_SPEED); + uint32_t currentClock = reClockI2C(SFA30_I2C_CLOCK_SPEED, _bus, _port); #endif /* SFA30_I2C_CLOCK_SPEED */ if (this->isError(sfa30.readMeasuredValues(hcho, humidity, temperature))) { LOG_WARN("%s: No values", sensorName); +#ifdef SFA30_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SFA30_I2C_CLOCK_SPEED */ return false; } -#if defined(SFA30_I2C_CLOCK_SPEED) && defined(CAN_RECLOCK_I2C) - reClockI2C(currentClock, _bus, false); -#endif +#ifdef SFA30_I2C_CLOCK_SPEED + if (currentClock) { + LOG_INFO("%s restoring clock speed to %uHz", sensorName, currentClock); + reClockI2C(currentClock, _bus, _port); + } +#endif /* SFA30_I2C_CLOCK_SPEED */ measurement->variant.air_quality_metrics.has_form_temperature = true; measurement->variant.air_quality_metrics.has_form_humidity = true; diff --git a/src/modules/Telemetry/Sensor/SFA30Sensor.h b/src/modules/Telemetry/Sensor/SFA30Sensor.h index 9fa9c85fc..038a70e1e 100644 --- a/src/modules/Telemetry/Sensor/SFA30Sensor.h +++ b/src/modules/Telemetry/Sensor/SFA30Sensor.h @@ -21,6 +21,8 @@ class SFA30Sensor : public TelemetrySensor SensirionI2cSfa3x sfa30; TwoWire *_bus{}; uint8_t _address{}; + ScanI2C::I2CPort _port = ScanI2C::I2CPort::NO_I2C; + bool isError(uint16_t response); public: