Compare commits
2 Commits
main
...
crosspoint
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
be6ba1b62b | ||
|
|
dede09001c |
@ -42,9 +42,9 @@ class EInkDisplay {
|
|||||||
void cleanupGrayscaleBuffers(const uint8_t* bwBuffer);
|
void cleanupGrayscaleBuffers(const uint8_t* bwBuffer);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void displayBuffer(RefreshMode mode = FAST_REFRESH);
|
void displayBuffer(RefreshMode mode = FAST_REFRESH, bool turnOffScreen = false);
|
||||||
// EXPERIMENTAL: Windowed update - display only a rectangular region
|
// EXPERIMENTAL: Windowed update - display only a rectangular region
|
||||||
void displayWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h);
|
void displayWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h, bool turnOffScreen = false);
|
||||||
void displayGrayBuffer(bool turnOffScreen = false);
|
void displayGrayBuffer(bool turnOffScreen = false);
|
||||||
|
|
||||||
void refreshDisplay(RefreshMode mode = FAST_REFRESH, bool turnOffScreen = false);
|
void refreshDisplay(RefreshMode mode = FAST_REFRESH, bool turnOffScreen = false);
|
||||||
|
|||||||
@ -399,25 +399,34 @@ void EInkDisplay::copyGrayscaleBuffers(const uint8_t* lsbBuffer, const uint8_t*
|
|||||||
#ifdef EINK_DISPLAY_SINGLE_BUFFER_MODE
|
#ifdef EINK_DISPLAY_SINGLE_BUFFER_MODE
|
||||||
/**
|
/**
|
||||||
* In single buffer mode, this should be called with the previously written BW buffer
|
* In single buffer mode, this should be called with the previously written BW buffer
|
||||||
* to reconstruct the RED buffer for proper differential fast refreshes following a
|
* to restore proper BW state after a grayscale display.
|
||||||
* grayscale display.
|
*
|
||||||
|
* The approach: Don't call grayscaleRevert() at all. Instead, just sync the RAMs with
|
||||||
|
* BW data and clear the grayscale mode flag. The physical pixels will stay in their
|
||||||
|
* current grayscale states, but subsequent refreshes will naturally transition them
|
||||||
|
* as the new BW content is displayed.
|
||||||
*/
|
*/
|
||||||
void EInkDisplay::cleanupGrayscaleBuffers(const uint8_t* bwBuffer) {
|
void EInkDisplay::cleanupGrayscaleBuffers(const uint8_t* bwBuffer) {
|
||||||
|
// Clear grayscale mode - we don't want grayscaleRevert to be called later
|
||||||
|
// because the RAMs won't have valid grayscale data anymore
|
||||||
|
inGrayscaleMode = false;
|
||||||
|
|
||||||
|
// Sync both RAMs with BW content for proper fast refresh behavior
|
||||||
setRamArea(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT);
|
setRamArea(0, 0, DISPLAY_WIDTH, DISPLAY_HEIGHT);
|
||||||
|
writeRamBuffer(CMD_WRITE_RAM_BW, bwBuffer, BUFFER_SIZE);
|
||||||
writeRamBuffer(CMD_WRITE_RAM_RED, bwBuffer, BUFFER_SIZE);
|
writeRamBuffer(CMD_WRITE_RAM_RED, bwBuffer, BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void EInkDisplay::displayBuffer(RefreshMode mode) {
|
void EInkDisplay::displayBuffer(RefreshMode mode, const bool turnOffScreen) {
|
||||||
if (!isScreenOn) {
|
if (!isScreenOn && !turnOffScreen) {
|
||||||
// Force half refresh if screen is off
|
// Force half refresh if screen is off
|
||||||
mode = HALF_REFRESH;
|
mode = HALF_REFRESH;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If currently in grayscale mode, revert first to black/white
|
// If currently in grayscale mode, revert first to black/white
|
||||||
if (inGrayscaleMode) {
|
if (inGrayscaleMode) {
|
||||||
inGrayscaleMode = false;
|
grayscaleRevert(); // grayscaleRevert() sets inGrayscaleMode = false internally
|
||||||
grayscaleRevert();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up full screen RAM area
|
// Set up full screen RAM area
|
||||||
@ -442,7 +451,7 @@ void EInkDisplay::displayBuffer(RefreshMode mode) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Refresh the display
|
// Refresh the display
|
||||||
refreshDisplay(mode);
|
refreshDisplay(mode, turnOffScreen);
|
||||||
|
|
||||||
#ifdef EINK_DISPLAY_SINGLE_BUFFER_MODE
|
#ifdef EINK_DISPLAY_SINGLE_BUFFER_MODE
|
||||||
// In single buffer mode always sync RED RAM after refresh to prepare for next fast refresh
|
// In single buffer mode always sync RED RAM after refresh to prepare for next fast refresh
|
||||||
@ -455,7 +464,7 @@ void EInkDisplay::displayBuffer(RefreshMode mode) {
|
|||||||
// EXPERIMENTAL: Windowed update support
|
// EXPERIMENTAL: Windowed update support
|
||||||
// Displays only a rectangular region of the frame buffer, preserving the rest of the screen.
|
// Displays only a rectangular region of the frame buffer, preserving the rest of the screen.
|
||||||
// Requirements: x and w must be byte-aligned (multiples of 8 pixels)
|
// Requirements: x and w must be byte-aligned (multiples of 8 pixels)
|
||||||
void EInkDisplay::displayWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h) {
|
void EInkDisplay::displayWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h, const bool turnOffScreen) {
|
||||||
Serial.printf("[%lu] Displaying window at (%d,%d) size (%dx%d)\n", millis(), x, y, w, h);
|
Serial.printf("[%lu] Displaying window at (%d,%d) size (%dx%d)\n", millis(), x, y, w, h);
|
||||||
|
|
||||||
// Validate bounds
|
// Validate bounds
|
||||||
@ -477,8 +486,7 @@ void EInkDisplay::displayWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
|
|||||||
|
|
||||||
// displayWindow is not supported while the rest of the screen has grayscale content, revert it
|
// displayWindow is not supported while the rest of the screen has grayscale content, revert it
|
||||||
if (inGrayscaleMode) {
|
if (inGrayscaleMode) {
|
||||||
inGrayscaleMode = false;
|
grayscaleRevert(); // grayscaleRevert() sets inGrayscaleMode = false internally
|
||||||
grayscaleRevert();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate window buffer size
|
// Calculate window buffer size
|
||||||
@ -517,7 +525,7 @@ void EInkDisplay::displayWindow(uint16_t x, uint16_t y, uint16_t w, uint16_t h)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Perform fast refresh
|
// Perform fast refresh
|
||||||
refreshDisplay(FAST_REFRESH);
|
refreshDisplay(FAST_REFRESH, turnOffScreen);
|
||||||
|
|
||||||
#ifdef EINK_DISPLAY_SINGLE_BUFFER_MODE
|
#ifdef EINK_DISPLAY_SINGLE_BUFFER_MODE
|
||||||
// Post-refresh: Sync RED RAM with current window (for next fast refresh)
|
// Post-refresh: Sync RED RAM with current window (for next fast refresh)
|
||||||
|
|||||||
@ -29,6 +29,7 @@ class SDCardManager {
|
|||||||
bool exists(const char* path) { return sd.exists(path); }
|
bool exists(const char* path) { return sd.exists(path); }
|
||||||
bool remove(const char* path) { return sd.remove(path); }
|
bool remove(const char* path) { return sd.remove(path); }
|
||||||
bool rmdir(const char* path) { return sd.rmdir(path); }
|
bool rmdir(const char* path) { return sd.rmdir(path); }
|
||||||
|
bool rename(const char* oldPath, const char* newPath) { return sd.rename(oldPath, newPath); }
|
||||||
|
|
||||||
bool openFileForRead(const char* moduleName, const char* path, FsFile& file);
|
bool openFileForRead(const char* moduleName, const char* path, FsFile& file);
|
||||||
bool openFileForRead(const char* moduleName, const std::string& path, FsFile& file);
|
bool openFileForRead(const char* moduleName, const std::string& path, FsFile& file);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user