diff --git a/lib/GfxRenderer/GfxRenderer.cpp b/lib/GfxRenderer/GfxRenderer.cpp index d1225f0..69a20fe 100644 --- a/lib/GfxRenderer/GfxRenderer.cpp +++ b/lib/GfxRenderer/GfxRenderer.cpp @@ -531,7 +531,9 @@ void GfxRenderer::invertScreen() const { } } -void GfxRenderer::displayBuffer(const HalDisplay::RefreshMode refreshMode) const { display.displayBuffer(refreshMode); } +void GfxRenderer::displayBuffer(const HalDisplay::RefreshMode refreshMode) const { + display.displayBuffer(refreshMode, fadingFix); +} std::string GfxRenderer::truncatedText(const int fontId, const char* text, const int maxWidth, const EpdFontFamily::Style style) const { @@ -910,7 +912,7 @@ void GfxRenderer::copyGrayscaleLsbBuffers() const { display.copyGrayscaleLsbBuff void GfxRenderer::copyGrayscaleMsbBuffers() const { display.copyGrayscaleMsbBuffers(display.getFrameBuffer()); } -void GfxRenderer::displayGrayBuffer() const { display.displayGrayBuffer(); } +void GfxRenderer::displayGrayBuffer() const { display.displayGrayBuffer(fadingFix); } void GfxRenderer::freeBwBufferChunks() { for (auto& bwBufferChunk : bwBufferChunks) { diff --git a/lib/GfxRenderer/GfxRenderer.h b/lib/GfxRenderer/GfxRenderer.h index 9e38638..21f51bf 100644 --- a/lib/GfxRenderer/GfxRenderer.h +++ b/lib/GfxRenderer/GfxRenderer.h @@ -37,6 +37,7 @@ class GfxRenderer { HalDisplay& display; RenderMode renderMode; Orientation orientation; + bool fadingFix = false; // Sunlight fading fix - turn off screen after refresh int bezelCompensation = 0; // Pixels to add for bezel defect compensation int bezelEdge = 0; // Which physical edge (0=bottom, 1=top, 2=left, 3=right in portrait) uint8_t* bwBufferChunks[BW_BUFFER_NUM_CHUNKS] = {nullptr}; @@ -76,6 +77,9 @@ class GfxRenderer { void setOrientation(const Orientation o) { orientation = o; } Orientation getOrientation() const { return orientation; } + // Fading fix control + void setFadingFix(const bool enabled) { fadingFix = enabled; } + // Screen ops int getScreenWidth() const; int getScreenHeight() const; diff --git a/lib/hal/HalDisplay.cpp b/lib/hal/HalDisplay.cpp index 6f69d7f..0fafdbb 100644 --- a/lib/hal/HalDisplay.cpp +++ b/lib/hal/HalDisplay.cpp @@ -28,7 +28,9 @@ EInkDisplay::RefreshMode convertRefreshMode(HalDisplay::RefreshMode mode) { } } -void HalDisplay::displayBuffer(HalDisplay::RefreshMode mode) { einkDisplay.displayBuffer(convertRefreshMode(mode)); } +void HalDisplay::displayBuffer(HalDisplay::RefreshMode mode, bool turnOffScreen) { + einkDisplay.displayBuffer(convertRefreshMode(mode), turnOffScreen); +} void HalDisplay::refreshDisplay(HalDisplay::RefreshMode mode, bool turnOffScreen) { einkDisplay.refreshDisplay(convertRefreshMode(mode), turnOffScreen); @@ -48,4 +50,4 @@ void HalDisplay::copyGrayscaleMsbBuffers(const uint8_t* msbBuffer) { einkDisplay void HalDisplay::cleanupGrayscaleBuffers(const uint8_t* bwBuffer) { einkDisplay.cleanupGrayscaleBuffers(bwBuffer); } -void HalDisplay::displayGrayBuffer() { einkDisplay.displayGrayBuffer(); } +void HalDisplay::displayGrayBuffer(bool turnOffScreen) { einkDisplay.displayGrayBuffer(turnOffScreen); } diff --git a/lib/hal/HalDisplay.h b/lib/hal/HalDisplay.h index 6eb7156..238832b 100644 --- a/lib/hal/HalDisplay.h +++ b/lib/hal/HalDisplay.h @@ -31,7 +31,7 @@ class HalDisplay { void drawImage(const uint8_t* imageData, uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool fromProgmem = false) const; - void displayBuffer(RefreshMode mode = RefreshMode::FAST_REFRESH); + void displayBuffer(RefreshMode mode = RefreshMode::FAST_REFRESH, bool turnOffScreen = false); void refreshDisplay(RefreshMode mode = RefreshMode::FAST_REFRESH, bool turnOffScreen = false); // Power management @@ -45,7 +45,7 @@ class HalDisplay { void copyGrayscaleMsbBuffers(const uint8_t* msbBuffer); void cleanupGrayscaleBuffers(const uint8_t* bwBuffer); - void displayGrayBuffer(); + void displayGrayBuffer(bool turnOffScreen = false); private: EInkDisplay einkDisplay; diff --git a/open-x4-sdk b/open-x4-sdk index dede090..be6ba1b 160000 --- a/open-x4-sdk +++ b/open-x4-sdk @@ -1 +1 @@ -Subproject commit dede09001c4c7bc96bd3616716cdf80913f57658 +Subproject commit be6ba1b62b1262929cded6ccdae774a098d33010 diff --git a/src/CrossPointSettings.cpp b/src/CrossPointSettings.cpp index c47d632..00a5795 100644 --- a/src/CrossPointSettings.cpp +++ b/src/CrossPointSettings.cpp @@ -23,7 +23,7 @@ void readAndValidate(FsFile& file, uint8_t& member, const uint8_t maxValue) { namespace { constexpr uint8_t SETTINGS_FILE_VERSION = 1; // Increment this when adding new persisted settings fields -constexpr uint8_t SETTINGS_COUNT = 29; // 28 + bezelCompensationEdge +constexpr uint8_t SETTINGS_COUNT = 30; // 29 + fadingFix constexpr char SETTINGS_FILE[] = "/.crosspoint/settings.bin"; } // namespace @@ -72,6 +72,8 @@ bool CrossPointSettings::saveToFile() const { serialization::writePod(outputFile, bezelCompensation); // Which physical edge needs bezel compensation serialization::writePod(outputFile, bezelCompensationEdge); + // Sunlight fading fix + serialization::writePod(outputFile, fadingFix); // New fields added at end for backward compatibility outputFile.close(); @@ -182,6 +184,9 @@ bool CrossPointSettings::loadFromFile() { // Which physical edge needs bezel compensation readAndValidate(inputFile, bezelCompensationEdge, BEZEL_EDGE_COUNT); if (++settingsRead >= fileSettingsCount) break; + // Sunlight fading fix + serialization::readPod(inputFile, fadingFix); + if (++settingsRead >= fileSettingsCount) break; // New fields added at end for backward compatibility } while (false); diff --git a/src/CrossPointSettings.h b/src/CrossPointSettings.h index 45a20bc..390fa73 100644 --- a/src/CrossPointSettings.h +++ b/src/CrossPointSettings.h @@ -144,6 +144,8 @@ class CrossPointSettings { uint8_t hideBatteryPercentage = HIDE_NEVER; // Long-press chapter skip on side buttons uint8_t longPressChapterSkip = 1; + // Sunlight fading compensation (0 = off, 1 = on) + uint8_t fadingFix = 0; // System-wide display contrast (0 = normal, 1 = high) uint8_t displayContrast = 0; // Bezel compensation - extra margin for physical screen edge defects (0-10px) diff --git a/src/activities/settings/SettingsActivity.cpp b/src/activities/settings/SettingsActivity.cpp index 93af6e7..46fa889 100644 --- a/src/activities/settings/SettingsActivity.cpp +++ b/src/activities/settings/SettingsActivity.cpp @@ -15,7 +15,7 @@ namespace { // Visibility condition for bezel edge setting (only show when compensation > 0) bool isBezelCompensationEnabled() { return SETTINGS.bezelCompensation > 0; } -constexpr int displaySettingsCount = 9; +constexpr int displaySettingsCount = 10; const SettingInfo displaySettings[displaySettingsCount] = { // Should match with SLEEP_SCREEN_MODE SettingInfo::Enum("Sleep Screen", &CrossPointSettings::sleepScreen, {"Dark", "Light", "Custom", "Cover", "None"}), @@ -28,6 +28,7 @@ const SettingInfo displaySettings[displaySettingsCount] = { SettingInfo::Enum("Hide Battery %", &CrossPointSettings::hideBatteryPercentage, {"Never", "In Reader", "Always"}), SettingInfo::Enum("Refresh Frequency", &CrossPointSettings::refreshFrequency, {"1 page", "5 pages", "10 pages", "15 pages", "30 pages"}), + SettingInfo::Enum("Sunlight Fading Fix", &CrossPointSettings::fadingFix, {"OFF", "ON"}), SettingInfo::Value("Bezel Compensation", &CrossPointSettings::bezelCompensation, {0, 10, 1}), SettingInfo::Enum("Bezel Edge", &CrossPointSettings::bezelCompensationEdge, {"Bottom", "Top", "Left", "Right"}, isBezelCompensationEnabled)}; diff --git a/src/main.cpp b/src/main.cpp index 04c3bc0..4d8d80a 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -524,6 +524,8 @@ void loop() { gpio.update(); + renderer.setFadingFix(SETTINGS.fadingFix); + if (Serial && millis() - lastMemPrint >= 10000) { // Basic heap info Serial.printf("[%lu] [MEM] Free: %d bytes, Total: %d bytes, Min Free: %d bytes\n", millis(), ESP.getFreeHeap(),