mirror of
https://github.com/alexhopeoconnor/firmware.git
synced 2026-10-16 00:21:35 +10:00
- t5s3-epaper: the board's 3.3V octal (AP_3v3) PSRAM is unreliable at the qio_opi
default of 80MHz (Total PSRAM reads 0, display dead / boot-loop); clock it at 40MHz.
- EInkParallelDisplay: skip EInk init and no-op display ops when the PSRAM framebuffer
is unavailable, so the node boots headless instead of hard-faulting on a NULL buffer.
- src/platform/esp32: weak software __atomic_*_{1,2,4} so esp32s3 links on toolchains
(e.g. macOS) that lack the sized libcalls GCC emits under -mdisable-hardware-atomics.
73 lines
1.9 KiB
C++
73 lines
1.9 KiB
C++
#pragma once
|
|
|
|
#include "configuration.h"
|
|
|
|
#ifdef USE_EINK_PARALLELDISPLAY
|
|
#include <OLEDDisplay.h>
|
|
|
|
#include <atomic>
|
|
#include <freertos/FreeRTOS.h>
|
|
#include <freertos/task.h>
|
|
|
|
class FASTEPD;
|
|
|
|
/**
|
|
* Adapter for E-Ink 8-bit parallel displays (EPD), specifically devices supported by FastEPD library
|
|
*/
|
|
class EInkParallelDisplay : public OLEDDisplay
|
|
{
|
|
public:
|
|
enum EpdRotation {
|
|
EPD_ROT_LANDSCAPE = 0,
|
|
EPD_ROT_PORTRAIT = 90,
|
|
EPD_ROT_INVERTED_LANDSCAPE = 180,
|
|
EPD_ROT_INVERTED_PORTRAIT = 270,
|
|
};
|
|
|
|
EInkParallelDisplay(uint16_t width, uint16_t height, EpdRotation rotation);
|
|
virtual ~EInkParallelDisplay();
|
|
|
|
// OLEDDisplay virtuals
|
|
bool connect() override;
|
|
void sendCommand(uint8_t com) override;
|
|
int getBufferOffset(void) override { return 0; }
|
|
|
|
void display(void) override;
|
|
bool forceDisplay(uint32_t msecLimit = 1000);
|
|
void endUpdate();
|
|
|
|
protected:
|
|
uint32_t lastDrawMsec = 0;
|
|
FASTEPD *epaper;
|
|
|
|
// Set only when connect() fully succeeds; framebuffer-touching methods no-op while false.
|
|
bool displayReady = false;
|
|
|
|
private:
|
|
// Async full-refresh support
|
|
std::atomic<bool> asyncFullRunning{false};
|
|
TaskHandle_t asyncTaskHandle = nullptr;
|
|
void startAsyncFullUpdate(int clearMode);
|
|
static void asyncFullUpdateTask(void *pvParameters);
|
|
|
|
#ifdef EINK_LIMIT_GHOSTING_PX
|
|
// helpers
|
|
void resetGhostPixelTracking();
|
|
void markDirtyBits(const uint8_t *prevBuf, uint32_t pos, uint8_t mask, uint8_t out);
|
|
void countGhostPixelsAndMaybePromote(int &newTop, int &newBottom, bool &forceFull);
|
|
|
|
// per-bit dirty buffer (same format as epaper buffers): one bit == one pixel
|
|
uint8_t *dirtyPixels = nullptr;
|
|
size_t dirtyPixelsSize = 0;
|
|
uint32_t ghostPixelCount = 0;
|
|
uint32_t ghostPixelLimit = EINK_LIMIT_GHOSTING_PX;
|
|
#endif
|
|
|
|
EpdRotation rotation;
|
|
uint32_t previousImageHash = 0;
|
|
uint32_t lastUpdateMs = 0;
|
|
int fastRefreshCount = 0;
|
|
};
|
|
|
|
#endif
|