From cef16147706f370678264856f5c0fe27750e6f47 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Thu, 24 Mar 2022 17:36:56 +0100 Subject: [PATCH] Autodetect OLED Controller 1306/1106 (#1317) * Autodetect OLED Controller 1306/1106 and make #define NO_SCREEN work again * fix epaper with autodetect * Try kicking CI - NFC --- platformio.ini | 2 +- src/debug/i2cScan.h | 30 +++++++++++++++++++++++++++++- src/graphics/EInkDisplay2.cpp | 5 +++++ src/graphics/EInkDisplay2.h | 6 ++++++ src/graphics/Screen.cpp | 4 ++++ src/graphics/Screen.h | 14 ++++++-------- src/main.cpp | 1 + src/main.h | 1 + 8 files changed, 53 insertions(+), 10 deletions(-) diff --git a/platformio.ini b/platformio.ini index 244c86cc..4fa73a94 100644 --- a/platformio.ini +++ b/platformio.ini @@ -40,7 +40,7 @@ build_flags = -Wno-missing-field-initializers monitor_speed = 921600 lib_deps = - https://github.com/meshtastic/esp8266-oled-ssd1306.git#d90231dedbb2f52bd7a32fb8ed8edec52cf4a8cb ; ESP8266_SSD1306 + https://github.com/meshtastic/esp8266-oled-ssd1306.git ; ESP8266_SSD1306 mathertel/OneButton@^2.0.3 ; OneButton library for non-blocking button debounce 1202 ; CRC32, explicitly needed because dependency is missing in the ble ota update lib https://github.com/meshtastic/arduino-fsm.git diff --git a/src/debug/i2cScan.h b/src/debug/i2cScan.h index 4752bf0b..c1d1de7c 100644 --- a/src/debug/i2cScan.h +++ b/src/debug/i2cScan.h @@ -3,6 +3,27 @@ #include #ifndef NO_WIRE +uint8_t oled_probe(byte addr) +{ + uint8_t r = 0; + uint8_t o_probe = 0; + Wire.beginTransmission(addr); + Wire.write(0x00); + Wire.endTransmission(); + Wire.requestFrom((int)addr, 1); + if (Wire.available()) { + r = Wire.read(); + } + r &= 0x0f; + if (r == 0x08) { + o_probe = 2; // SH1106 + } else if ( r == 0x06 || r == 0x07) { + o_probe = 1; // SSD1306 + } + DEBUG_MSG("0x%x subtype probed\n", r); + return o_probe; +} + void scanI2Cdevice(void) { byte err, addr; @@ -17,7 +38,14 @@ void scanI2Cdevice(void) if (addr == SSD1306_ADDRESS) { screen_found = addr; - DEBUG_MSG("ssd1306 display found\n"); + screen_model = oled_probe(addr); + if (screen_model == 1){ + DEBUG_MSG("ssd1306 display found\n"); + } else if (screen_model == 2){ + DEBUG_MSG("sh1106 display found\n"); + } else { + DEBUG_MSG("unknown display found\n"); + } } if (addr == ST7567_ADDRESS) { screen_found = addr; diff --git a/src/graphics/EInkDisplay2.cpp b/src/graphics/EInkDisplay2.cpp index 4c030b60..adb284a7 100644 --- a/src/graphics/EInkDisplay2.cpp +++ b/src/graphics/EInkDisplay2.cpp @@ -131,6 +131,11 @@ void EInkDisplay::sendCommand(uint8_t com) // Drop all commands to device (we just update the buffer) } +void EInkDisplay::setDetected(uint8_t detected) +{ + (void)detected; +} + // Connect to the display bool EInkDisplay::connect() { diff --git a/src/graphics/EInkDisplay2.h b/src/graphics/EInkDisplay2.h index 76b2dc39..727132d0 100644 --- a/src/graphics/EInkDisplay2.h +++ b/src/graphics/EInkDisplay2.h @@ -34,6 +34,12 @@ class EInkDisplay : public OLEDDisplay */ bool forceDisplay(uint32_t msecLimit = 1000); + /** + * shim to make the abstraction happy + * + */ + void setDetected(uint8_t detected); + protected: // the header size of the buffer used, e.g. for the SPI command header virtual int getBufferOffset(void) override { return 0; } diff --git a/src/graphics/Screen.cpp b/src/graphics/Screen.cpp index 94d997a8..8b4801ef 100644 --- a/src/graphics/Screen.cpp +++ b/src/graphics/Screen.cpp @@ -765,6 +765,10 @@ void Screen::setup() // is never found when probing i2c and therefore we don't call setup and never want to do (invalid) accesses to this device. useDisplay = true; +#ifdef AutoOLEDWire_h + dispdev.setDetected(screen_model); +#endif + // I think this is not needed - redundant with ui.init // dispdev.resetOrientation(); diff --git a/src/graphics/Screen.h b/src/graphics/Screen.h index 2b0e3209..2242532d 100644 --- a/src/graphics/Screen.h +++ b/src/graphics/Screen.h @@ -14,6 +14,7 @@ class Screen void print(const char*){} void adjustBrightness(){} void doDeepSleep() {} + void forceDisplay() {} }; } @@ -24,12 +25,11 @@ class Screen #include "../configuration.h" -#ifdef USE_SH1106 -#include -#elif defined(USE_ST7567) +#ifdef USE_ST7567 #include #else -#include +// the SH1106/SSD1306 variant is auto-detected +#include #endif #include "EInkDisplay2.h" @@ -295,18 +295,16 @@ class Screen : public concurrency::OSThread /// Holds state for debug information DebugInfo debugInfo; - /// Display device + /// Display device /** FIXME cleanup display abstraction */ #ifdef ST7735_CS TFTDisplay dispdev; #elif defined(HAS_EINK) EInkDisplay dispdev; -#elif defined(USE_SH1106) - SH1106Wire dispdev; #elif defined(USE_ST7567) ST7567Wire dispdev; #else - SSD1306Wire dispdev; + AutoOLEDWire dispdev; #endif /// UI helper for rendering to frames and switching between them OLEDDisplayUi ui; diff --git a/src/main.cpp b/src/main.cpp index ffa6b92a..0ec89a01 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -70,6 +70,7 @@ meshtastic::NodeStatus *nodeStatus = new meshtastic::NodeStatus(); /// The I2C address of our display (if found) uint8_t screen_found; +uint8_t screen_model; bool axp192_found; diff --git a/src/main.h b/src/main.h index b87b1886..6617cd77 100644 --- a/src/main.h +++ b/src/main.h @@ -6,6 +6,7 @@ #include "graphics/Screen.h" extern uint8_t screen_found; +extern uint8_t screen_model; extern bool axp192_found; extern bool isCharging; extern bool isUSBPowered;