Make reclock function aware of screen-set I2C speeds

This commit is contained in:
oscgonfer
2026-06-14 14:48:40 +02:00
parent 1a1f906b7a
commit 0200d45241
12 changed files with 280 additions and 265 deletions
+28 -15
View File
@@ -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);
}
+4 -1
View File
@@ -2,10 +2,13 @@
#ifndef RECLOCK_I2C_
#define RECLOCK_I2C_
#include "../graphics/Screen.h"
#include "ScanI2CTwoWire.h"
#include <Wire.h>
#include <stdint.h>
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