diff --git a/src/helpers/ui/AutoDetectDisplay.cpp b/src/helpers/ui/AutoDetectDisplay.cpp new file mode 100644 index 000000000..e3537ab25 --- /dev/null +++ b/src/helpers/ui/AutoDetectDisplay.cpp @@ -0,0 +1,45 @@ +#include "AutoDetectDisplay.h" +#include + +int AutoDetectDisplay::getDisplayStatus(TwoWire& wire, uint8_t addr) { + int status = -1; + for(int i = 0; i < 4; i++){ + + // request display status + wire.beginTransmission(addr); + wire.write((uint8_t)0x00); + + // ensure response received + if (wire.endTransmission() != 0) return -1; // expect success + if (wire.requestFrom((int)addr, 1) == 0) return -1; // expect at least 1 byte + + // ensure two consecutive reads are the same + int previous = status; + status = wire.read() & 0x0F; + if(status == previous){ + break; + } + + } + return status; +} + +bool AutoDetectDisplay::begin() { + + // request status from display address + int status = getDisplayStatus(Wire, DISPLAY_ADDRESS); + MESH_DEBUG_PRINTLN("AutoDetectDisplay: status=0x%02X", status); + + // detect SH1106 + if(status == 0x00 || status == 0x08){ + MESH_DEBUG_PRINTLN("AutoDetectDisplay: SH1106 detected"); + _impl = &_sh1106; + return _sh1106.begin(); + } + + // fallback to SSD1306 + MESH_DEBUG_PRINTLN("AutoDetectDisplay: falling back to SSD1306"); + _impl = &_ssd1306; + return _ssd1306.begin(); + +} diff --git a/src/helpers/ui/AutoDetectDisplay.h b/src/helpers/ui/AutoDetectDisplay.h new file mode 100644 index 000000000..7208d4f59 --- /dev/null +++ b/src/helpers/ui/AutoDetectDisplay.h @@ -0,0 +1,32 @@ +#pragma once + +#include "DisplayDriver.h" +#include "SSD1306Display.h" +#include "SH1106Display.h" + +// Auto detects SH1106 display at runtime, otherwise falls back to using SSD1306 +class AutoDetectDisplay : public DisplayDriver { + DisplayDriver* _impl; + SSD1306Display _ssd1306; + SH1106Display _sh1106; + + int getDisplayStatus(TwoWire& wire, uint8_t addr); +public: + AutoDetectDisplay() : DisplayDriver(128, 64), _impl(&_ssd1306) { } + bool begin(); + + bool isOn() override { return _impl->isOn(); } + void turnOn() override { _impl->turnOn(); } + void turnOff() override { _impl->turnOff(); } + void clear() override { _impl->clear(); } + void startFrame(ColorVal bkg = UIColor::window_bkg) override { _impl->startFrame(bkg); } + void setTextSize(int sz) override { _impl->setTextSize(sz); } + void setColor(ColorVal c) override { _impl->setColor(c); } + void setCursor(int x, int y) override { _impl->setCursor(x, y); } + void print(const char* str) override { _impl->print(str); } + void fillRect(int x, int y, int w, int h) override { _impl->fillRect(x, y, w, h); } + void drawRect(int x, int y, int w, int h) override { _impl->drawRect(x, y, w, h); } + void drawXbm(int x, int y, const uint8_t* bits, int w, int h) override { _impl->drawXbm(x, y, bits, w, h); } + uint16_t getTextWidth(const char* str) override { return _impl->getTextWidth(str); } + void endFrame() override { _impl->endFrame(); } +}; diff --git a/src/helpers/ui/SH1106Display.cpp b/src/helpers/ui/SH1106Display.cpp index 8b91d857c..e290b3556 100644 --- a/src/helpers/ui/SH1106Display.cpp +++ b/src/helpers/ui/SH1106Display.cpp @@ -10,15 +10,15 @@ bool SH1106Display::i2c_probe(TwoWire &wire, uint8_t addr) } // Color scheme -ColorVal UIColor::window_bkg = SH110X_BLACK; -ColorVal UIColor::title_bkg = SH110X_BLACK; -ColorVal UIColor::title_txt = SH110X_WHITE; -ColorVal UIColor::primary_txt = SH110X_WHITE; -ColorVal UIColor::secondary_txt = SH110X_WHITE; -ColorVal UIColor::warning_txt = SH110X_WHITE; -ColorVal UIColor::popup_bkg = SH110X_BLACK; -ColorVal UIColor::popup_txt = SH110X_WHITE; -ColorVal UIColor::corp_blue = SH110X_WHITE; +__attribute__((weak)) ColorVal UIColor::window_bkg = SH110X_BLACK; +__attribute__((weak)) ColorVal UIColor::title_bkg = SH110X_BLACK; +__attribute__((weak)) ColorVal UIColor::title_txt = SH110X_WHITE; +__attribute__((weak)) ColorVal UIColor::primary_txt = SH110X_WHITE; +__attribute__((weak)) ColorVal UIColor::secondary_txt = SH110X_WHITE; +__attribute__((weak)) ColorVal UIColor::warning_txt = SH110X_WHITE; +__attribute__((weak)) ColorVal UIColor::popup_bkg = SH110X_BLACK; +__attribute__((weak)) ColorVal UIColor::popup_txt = SH110X_WHITE; +__attribute__((weak)) ColorVal UIColor::corp_blue = SH110X_WHITE; bool SH1106Display::begin() { diff --git a/variants/rak4631/platformio.ini b/variants/rak4631/platformio.ini index d2781d9fa..4c13b0d74 100644 --- a/variants/rak4631/platformio.ini +++ b/variants/rak4631/platformio.ini @@ -28,11 +28,14 @@ build_src_filter = ${nrf52_base.build_src_filter} +<../variants/rak4631> + + + + + + + lib_deps = ${nrf52_base.lib_deps} ${sensor_base.lib_deps} adafruit/Adafruit SSD1306 @ ^2.5.13 + adafruit/Adafruit SH110X @ ^2.1.13 sparkfun/SparkFun u-blox GNSS Arduino Library@^2.2.27 boschsensortec/BSEC Software Library @ ^1.8.1492 @@ -40,7 +43,7 @@ lib_deps = extends = rak4631 build_flags = ${rak4631.build_flags} - -D DISPLAY_CLASS=SSD1306Display + -D DISPLAY_CLASS=AutoDetectDisplay -D ADVERT_NAME='"RAK4631 Repeater"' -D ADVERT_LAT=0.0 -D ADVERT_LON=0.0 @@ -56,7 +59,7 @@ build_src_filter = ${rak4631.build_src_filter} extends = rak4631 build_flags = ${rak4631.build_flags} - -D DISPLAY_CLASS=SSD1306Display + -D DISPLAY_CLASS=AutoDetectDisplay -D ADVERT_NAME='"RAK4631 Repeater"' -D ADVERT_LAT=0.0 -D ADVERT_LON=0.0 @@ -75,7 +78,7 @@ lib_deps = extends = rak4631 build_flags = ${rak4631.build_flags} - -D DISPLAY_CLASS=SSD1306Display + -D DISPLAY_CLASS=AutoDetectDisplay -D ADVERT_NAME='"RS232 Bridge"' -D ADVERT_LAT=0.0 -D ADVERT_LON=0.0 @@ -98,7 +101,7 @@ build_src_filter = ${rak4631.build_src_filter} extends = rak4631 build_flags = ${rak4631.build_flags} - -D DISPLAY_CLASS=SSD1306Display + -D DISPLAY_CLASS=AutoDetectDisplay -D ADVERT_NAME='"RS232 Bridge"' -D ADVERT_LAT=0.0 -D ADVERT_LON=0.0 @@ -121,7 +124,7 @@ build_src_filter = ${rak4631.build_src_filter} extends = rak4631 build_flags = ${rak4631.build_flags} - -D DISPLAY_CLASS=SSD1306Display + -D DISPLAY_CLASS=AutoDetectDisplay -D ADVERT_NAME='"Test Room"' -D ADVERT_LAT=0.0 -D ADVERT_LON=0.0 @@ -137,7 +140,7 @@ build_src_filter = ${rak4631.build_src_filter} extends = rak4631 build_flags = ${rak4631.build_flags} - -D DISPLAY_CLASS=SSD1306Display + -D DISPLAY_CLASS=AutoDetectDisplay -D ADVERT_NAME='"RAK4631 Room Server"' -D ADVERT_LAT=0.0 -D ADVERT_LON=0.0 @@ -161,7 +164,7 @@ build_flags = -I examples/companion_radio/ui-new -D PIN_USER_BTN=9 -D PIN_USER_BTN_ANA=31 - -D DISPLAY_CLASS=SSD1306Display + -D DISPLAY_CLASS=AutoDetectDisplay -D MAX_CONTACTS=350 -D MAX_GROUP_CHANNELS=40 -D ENABLE_USB_INTERFACE @@ -186,7 +189,7 @@ build_flags = -I examples/companion_radio/ui-new -D PIN_USER_BTN=9 -D PIN_USER_BTN_ANA=31 - -D DISPLAY_CLASS=SSD1306Display + -D DISPLAY_CLASS=AutoDetectDisplay -D MAX_CONTACTS=350 -D MAX_GROUP_CHANNELS=40 -D ETHERNET_ENABLED=1 @@ -215,7 +218,7 @@ build_flags = -I examples/companion_radio/ui-new -D PIN_USER_BTN=9 -D PIN_USER_BTN_ANA=31 - -D DISPLAY_CLASS=SSD1306Display + -D DISPLAY_CLASS=AutoDetectDisplay -D MAX_CONTACTS=350 -D MAX_GROUP_CHANNELS=40 -D BLE_PIN_CODE=123456 @@ -251,7 +254,7 @@ lib_deps = extends = rak4631 build_flags = ${rak4631.build_flags} - -D DISPLAY_CLASS=SSD1306Display + -D DISPLAY_CLASS=AutoDetectDisplay -D ADVERT_NAME='"RAK4631 Sensor"' -D ADVERT_LAT=0.0 -D ADVERT_LON=0.0 diff --git a/variants/rak4631/target.h b/variants/rak4631/target.h index 1529f9042..c04cd4e48 100644 --- a/variants/rak4631/target.h +++ b/variants/rak4631/target.h @@ -9,7 +9,7 @@ #include #ifdef DISPLAY_CLASS - #include + #include extern DISPLAY_CLASS display; #include extern MomentaryButton user_btn;