From b8b6598dd3ab47489767167aa85ce727c5823054 Mon Sep 17 00:00:00 2001 From: UltimateCodeWarrior Date: Mon, 22 Jun 2026 23:30:35 -0700 Subject: [PATCH] Fix blank OLED on T-Beam Supreme V3 (I2C bus + 0x3D address) The SH1106 OLED on the LilyGo T-Beam Supreme V3 never lights up because: 1. The primary I2C bus (Wire) that the OLED, BME280 and magnetometer share is never initialized. The PMU/RTC use Wire1 (via XPowersLib); nothing brings up Wire on PIN_BOARD_SDA/PIN_BOARD_SCL, so the display driver talks on the wrong default pins. 2. The OLED is at I2C address 0x3D on this board (0x3C is taken by the QMC6310 magnetometer), but SH1106Display::begin() only tried 0x3C. Initialize Wire for TBEAM_SUPREME_SX1262, and have SH1106Display::begin() prefer 0x3D (only ever used by the OLED) before falling back to 0x3C. Backwards-compatible for boards with the OLED at 0x3C. Closes #2609 --- src/helpers/esp32/TBeamBoard.cpp | 10 ++++++++++ src/helpers/ui/SH1106Display.cpp | 12 +++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/helpers/esp32/TBeamBoard.cpp b/src/helpers/esp32/TBeamBoard.cpp index 5f708d71d9..d9f6e02275 100644 --- a/src/helpers/esp32/TBeamBoard.cpp +++ b/src/helpers/esp32/TBeamBoard.cpp @@ -16,6 +16,16 @@ void TBeamBoard::begin() { ESP32Board::begin(); +#ifdef TBEAM_SUPREME_SX1262 + // On the T-Beam S3 Supreme the PMU + RTC sit on Wire1 (GPIO 42/41, brought + // up by XPowersLib), while the SH1106 OLED and the BME280/QMC6310 sensors + // sit on the primary bus, Wire (GPIO PIN_BOARD_SDA/PIN_BOARD_SCL). Nothing + // else initialises Wire on this board, so the display driver would + // otherwise talk on the wrong (default) pins and display.begin() fails, + // leaving the screen blank. Bring the OLED bus up here. + Wire.begin(PIN_BOARD_SDA, PIN_BOARD_SCL); +#endif + power_init(); //Configure user button diff --git a/src/helpers/ui/SH1106Display.cpp b/src/helpers/ui/SH1106Display.cpp index f383bb005d..86c6089bc2 100644 --- a/src/helpers/ui/SH1106Display.cpp +++ b/src/helpers/ui/SH1106Display.cpp @@ -11,7 +11,17 @@ bool SH1106Display::i2c_probe(TwoWire &wire, uint8_t addr) bool SH1106Display::begin() { - return display.begin(DISPLAY_ADDRESS, true) && i2c_probe(Wire, DISPLAY_ADDRESS); + // Address selection: on some board revisions (notably the LilyGo T-Beam + // Supreme V3) the OLED lives at 0x3D because 0x3C is occupied by a + // magnetometer (QMC6310N). 0x3D is only ever used by the OLED, so prefer it + // when present, otherwise fall back to the standard 0x3C (DISPLAY_ADDRESS). + uint8_t addr = 0; + if (i2c_probe(Wire, 0x3D)) { + addr = 0x3D; + } else if (i2c_probe(Wire, DISPLAY_ADDRESS)) { + addr = DISPLAY_ADDRESS; + } + return addr && display.begin(addr, true); } void SH1106Display::turnOn()