Fix Heltec E213 and E290 e-ink board builds

This commit is contained in:
Wessel Nieboer
2026-03-06 02:58:39 +01:00
parent ba71820691
commit 696323c11b
10 changed files with 132 additions and 37 deletions

View File

@@ -59,44 +59,55 @@ bool E213Display::begin() {
}
void E213Display::powerOn() {
if (_periph_power) {
_periph_power->claim();
} else {
#ifdef PIN_VEXT_EN
pinMode(PIN_VEXT_EN, OUTPUT);
pinMode(PIN_VEXT_EN, OUTPUT);
#ifdef PIN_VEXT_EN_ACTIVE
digitalWrite(PIN_VEXT_EN, PIN_VEXT_EN_ACTIVE);
digitalWrite(PIN_VEXT_EN, PIN_VEXT_EN_ACTIVE);
#else
digitalWrite(PIN_VEXT_EN, LOW); // Active low
digitalWrite(PIN_VEXT_EN, LOW); // Active low
#endif
#endif
}
delay(50); // Allow power to stabilize
#endif
}
void E213Display::powerOff() {
if (_periph_power) {
_periph_power->release();
} else {
#ifdef PIN_VEXT_EN
#ifdef PIN_VEXT_EN_ACTIVE
digitalWrite(PIN_VEXT_EN, !PIN_VEXT_EN_ACTIVE);
digitalWrite(PIN_VEXT_EN, !PIN_VEXT_EN_ACTIVE);
#else
digitalWrite(PIN_VEXT_EN, HIGH); // Turn off power
digitalWrite(PIN_VEXT_EN, HIGH); // Turn off power
#endif
#endif
}
}
void E213Display::turnOn() {
if (!_init) begin();
powerOn();
else if (!_isOn) powerOn();
_isOn = true;
}
void E213Display::turnOff() {
powerOff();
_isOn = false;
if (_isOn) {
powerOff();
_isOn = false;
}
}
void E213Display::clear() {
display->clear();
}
void E213Display::startFrame(Color bkg) {
display_crc.reset();
// Fill screen with white first to ensure clean background
display->fillRect(0, 0, width(), height(), WHITE);
@@ -107,31 +118,50 @@ void E213Display::startFrame(Color bkg) {
}
void E213Display::setTextSize(int sz) {
display_crc.update<int>(sz);
// The library handles text size internally
display->setTextSize(sz);
}
void E213Display::setColor(Color c) {
display_crc.update<Color>(c);
// implemented in individual display methods
}
void E213Display::setCursor(int x, int y) {
display_crc.update<int>(x);
display_crc.update<int>(y);
display->setCursor(x, y);
}
void E213Display::print(const char *str) {
display_crc.update<char>(str, strlen(str));
display->print(str);
}
void E213Display::fillRect(int x, int y, int w, int h) {
display_crc.update<int>(x);
display_crc.update<int>(y);
display_crc.update<int>(w);
display_crc.update<int>(h);
display->fillRect(x, y, w, h, BLACK);
}
void E213Display::drawRect(int x, int y, int w, int h) {
display_crc.update<int>(x);
display_crc.update<int>(y);
display_crc.update<int>(w);
display_crc.update<int>(h);
display->drawRect(x, y, w, h, BLACK);
}
void E213Display::drawXbm(int x, int y, const uint8_t *bits, int w, int h) {
display_crc.update<int>(x);
display_crc.update<int>(y);
display_crc.update<int>(w);
display_crc.update<int>(h);
display_crc.update<uint8_t>(bits, w * h / 8);
// Width in bytes for bitmap processing
uint16_t widthInBytes = (w + 7) / 8;
@@ -160,5 +190,9 @@ uint16_t E213Display::getTextWidth(const char *str) {
}
void E213Display::endFrame() {
uint32_t crc = display_crc.finalize();
if (crc != last_display_crc_value) {
display->update();
last_display_crc_value = crc;
}
}

View File

@@ -5,15 +5,20 @@
#include <SPI.h>
#include <Wire.h>
#include <heltec-eink-modules.h>
#include <CRC32.h>
#include <helpers/RefCountedDigitalPin.h>
// Display driver for E213 e-ink display
class E213Display : public DisplayDriver {
BaseDisplay* display=NULL;
bool _init = false;
bool _isOn = false;
RefCountedDigitalPin* _periph_power;
CRC32 display_crc;
uint32_t last_display_crc_value = 0;
public:
E213Display() : DisplayDriver(250, 122) {}
E213Display(RefCountedDigitalPin* periph_power = NULL) : DisplayDriver(250, 122), _periph_power(periph_power) {}
~E213Display(){
if(display!=NULL) {
delete display;
@@ -39,4 +44,4 @@ private:
BaseDisplay* detectEInk();
void powerOn();
void powerOff();
};
};

View File

@@ -21,28 +21,38 @@ bool E290Display::begin() {
}
void E290Display::powerOn() {
if (_periph_power) {
_periph_power->claim();
} else {
#ifdef PIN_VEXT_EN
pinMode(PIN_VEXT_EN, OUTPUT);
digitalWrite(PIN_VEXT_EN, PIN_VEXT_EN_ACTIVE);
delay(50); // Allow power to stabilize
pinMode(PIN_VEXT_EN, OUTPUT);
digitalWrite(PIN_VEXT_EN, PIN_VEXT_EN_ACTIVE);
#endif
}
delay(50); // Allow power to stabilize
}
void E290Display::powerOff() {
if (_periph_power) {
_periph_power->release();
} else {
#ifdef PIN_VEXT_EN
digitalWrite(PIN_VEXT_EN, !PIN_VEXT_EN_ACTIVE); // Turn off power
digitalWrite(PIN_VEXT_EN, !PIN_VEXT_EN_ACTIVE); // Turn off power
#endif
}
}
void E290Display::turnOn() {
if (!_init) begin();
powerOn();
else if (!_isOn) powerOn();
_isOn = true;
}
void E290Display::turnOff() {
powerOff();
_isOn = false;
if (_isOn) {
powerOff();
_isOn = false;
}
}
void E290Display::clear() {
@@ -50,6 +60,8 @@ void E290Display::clear() {
}
void E290Display::startFrame(Color bkg) {
display_crc.reset();
// Fill screen with white first to ensure clean background
display.fillRect(0, 0, width(), height(), WHITE);
if (bkg == LIGHT) {
@@ -59,31 +71,50 @@ void E290Display::startFrame(Color bkg) {
}
void E290Display::setTextSize(int sz) {
display_crc.update<int>(sz);
// The library handles text size internally
display.setTextSize(sz);
}
void E290Display::setColor(Color c) {
display_crc.update<Color>(c);
// implemented in individual display methods
}
void E290Display::setCursor(int x, int y) {
display_crc.update<int>(x);
display_crc.update<int>(y);
display.setCursor(x, y);
}
void E290Display::print(const char *str) {
display_crc.update<char>(str, strlen(str));
display.print(str);
}
void E290Display::fillRect(int x, int y, int w, int h) {
display_crc.update<int>(x);
display_crc.update<int>(y);
display_crc.update<int>(w);
display_crc.update<int>(h);
display.fillRect(x, y, w, h, BLACK);
}
void E290Display::drawRect(int x, int y, int w, int h) {
display_crc.update<int>(x);
display_crc.update<int>(y);
display_crc.update<int>(w);
display_crc.update<int>(h);
display.drawRect(x, y, w, h, BLACK);
}
void E290Display::drawXbm(int x, int y, const uint8_t *bits, int w, int h) {
display_crc.update<int>(x);
display_crc.update<int>(y);
display_crc.update<int>(w);
display_crc.update<int>(h);
display_crc.update<uint8_t>(bits, w * h / 8);
// Width in bytes for bitmap processing
uint16_t widthInBytes = (w + 7) / 8;
@@ -112,5 +143,9 @@ uint16_t E290Display::getTextWidth(const char *str) {
}
void E290Display::endFrame() {
display.update();
uint32_t crc = display_crc.finalize();
if (crc != last_display_crc_value) {
display.update();
last_display_crc_value = crc;
}
}

View File

@@ -5,15 +5,20 @@
#include <SPI.h>
#include <Wire.h>
#include <heltec-eink-modules.h>
#include <CRC32.h>
#include <helpers/RefCountedDigitalPin.h>
// Display driver for E290 e-ink display
class E290Display : public DisplayDriver {
EInkDisplay_VisionMasterE290 display;
bool _init = false;
bool _isOn = false;
RefCountedDigitalPin* _periph_power;
CRC32 display_crc;
uint32_t last_display_crc_value = 0;
public:
E290Display() : DisplayDriver(296, 128) {}
E290Display(RefCountedDigitalPin* periph_power = NULL) : DisplayDriver(296, 128), _periph_power(periph_power) {}
bool begin();
bool isOn() override { return _isOn; }
@@ -34,4 +39,4 @@ public:
private:
void powerOn();
void powerOff();
};
};

View File

@@ -40,7 +40,7 @@ lib_deps =
${esp32_base.lib_deps}
https://github.com/Quency-D/heltec-eink-modules/archive/563dd41fd850a1bc3039b8723da4f3a20fe1c800.zip
[env:Heltec_E213_companion_radio_ble_]
[env:Heltec_E213_companion_radio_ble]
extends = Heltec_E213_base
build_flags =
${Heltec_E213_base.build_flags}
@@ -59,8 +59,9 @@ build_src_filter = ${Heltec_E213_base.build_src_filter}
lib_deps =
${Heltec_E213_base.lib_deps}
densaugeo/base64 @ ~1.4.0
bakercp/CRC32 @ ^2.0.0
[env:Heltec_E213_companion_radio_usb_]
[env:Heltec_E213_companion_radio_usb]
extends = Heltec_E213_base
build_flags =
${Heltec_E213_base.build_flags}
@@ -77,8 +78,9 @@ build_src_filter = ${Heltec_E213_base.build_src_filter}
lib_deps =
${Heltec_E213_base.lib_deps}
densaugeo/base64 @ ~1.4.0
bakercp/CRC32 @ ^2.0.0
[env:Heltec_E213_repeater_]
[env:Heltec_E213_repeater]
extends = Heltec_E213_base
build_flags =
${Heltec_E213_base.build_flags}
@@ -94,8 +96,9 @@ build_src_filter = ${Heltec_E213_base.build_src_filter}
lib_deps =
${Heltec_E213_base.lib_deps}
${esp32_ota.lib_deps}
bakercp/CRC32 @ ^2.0.0
; [env:Heltec_E213_repeater_bridge_rs232_]
; [env:Heltec_E213_repeater_bridge_rs232]
; extends = Heltec_E213_base
; build_flags =
; ${Heltec_E213_base.build_flags}
@@ -118,8 +121,9 @@ lib_deps =
; lib_deps =
; ${Heltec_E213_base.lib_deps}
; ${esp32_ota.lib_deps}
; bakercp/CRC32 @ ^2.0.0
[env:Heltec_E213_repeater_bridge_espnow_]
[env:Heltec_E213_repeater_bridge_espnow]
extends = Heltec_E213_base
build_flags =
${Heltec_E213_base.build_flags}
@@ -140,8 +144,9 @@ build_src_filter = ${Heltec_E213_base.build_src_filter}
lib_deps =
${Heltec_E213_base.lib_deps}
${esp32_ota.lib_deps}
bakercp/CRC32 @ ^2.0.0
[env:Heltec_E213_room_server_]
[env:Heltec_E213_room_server]
extends = Heltec_E213_base
build_flags =
${Heltec_E213_base.build_flags}
@@ -157,3 +162,4 @@ build_src_filter = ${Heltec_E213_base.build_src_filter}
lib_deps =
${Heltec_E213_base.lib_deps}
${esp32_ota.lib_deps}
bakercp/CRC32 @ ^2.0.0

View File

@@ -18,7 +18,7 @@ AutoDiscoverRTCClock rtc_clock(fallback_clock);
SensorManager sensors;
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display;
DISPLAY_CLASS display(&board.periph_power);
MomentaryButton user_btn(PIN_USER_BTN, 1000, true);
#endif

View File

@@ -10,7 +10,7 @@ class HeltecE290Board : public ESP32Board {
public:
RefCountedDigitalPin periph_power;
HeltecE290Board() : periph_power(PIN_VEXT_EN) { }
HeltecE290Board() : periph_power(PIN_VEXT_EN, PIN_VEXT_EN_ACTIVE) { }
void begin();
void enterDeepSleep(uint32_t secs, int pin_wake_btn = -1);

View File

@@ -34,7 +34,7 @@ lib_deps =
${esp32_base.lib_deps}
https://github.com/Quency-D/heltec-eink-modules/archive/563dd41fd850a1bc3039b8723da4f3a20fe1c800.zip
[env:Heltec_E290_companion_ble_]
[env:Heltec_E290_companion_ble]
extends = Heltec_E290_base
build_flags =
${Heltec_E290_base.build_flags}
@@ -53,8 +53,9 @@ build_src_filter = ${Heltec_E290_base.build_src_filter}
lib_deps =
${Heltec_E290_base.lib_deps}
densaugeo/base64 @ ~1.4.0
bakercp/CRC32 @ ^2.0.0
[env:Heltec_E290_companion_usb_]
[env:Heltec_E290_companion_usb]
extends = Heltec_E290_base
build_flags =
${Heltec_E290_base.build_flags}
@@ -73,8 +74,9 @@ build_src_filter = ${Heltec_E290_base.build_src_filter}
lib_deps =
${Heltec_E290_base.lib_deps}
densaugeo/base64 @ ~1.4.0
bakercp/CRC32 @ ^2.0.0
[env:Heltec_E290_repeater_]
[env:Heltec_E290_repeater]
extends = Heltec_E290_base
build_flags =
${Heltec_E290_base.build_flags}
@@ -90,8 +92,9 @@ build_src_filter = ${Heltec_E290_base.build_src_filter}
lib_deps =
${Heltec_E290_base.lib_deps}
${esp32_ota.lib_deps}
bakercp/CRC32 @ ^2.0.0
; [env:Heltec_E290_repeater_bridge_rs232_]
; [env:Heltec_E290_repeater_bridge_rs232]
; extends = Heltec_E290_base
; build_flags =
; ${Heltec_E290_base.build_flags}
@@ -114,8 +117,9 @@ lib_deps =
; lib_deps =
; ${Heltec_E290_base.lib_deps}
; ${esp32_ota.lib_deps}
; bakercp/CRC32 @ ^2.0.0
[env:Heltec_E290_repeater_bridge_espnow_]
[env:Heltec_E290_repeater_bridge_espnow]
extends = Heltec_E290_base
build_flags =
${Heltec_E290_base.build_flags}
@@ -136,8 +140,9 @@ build_src_filter = ${Heltec_E290_base.build_src_filter}
lib_deps =
${Heltec_E290_base.lib_deps}
${esp32_ota.lib_deps}
bakercp/CRC32 @ ^2.0.0
[env:Heltec_E290_room_server_]
[env:Heltec_E290_room_server]
extends = Heltec_E290_base
build_flags =
${Heltec_E290_base.build_flags}
@@ -153,3 +158,4 @@ build_src_filter = ${Heltec_E290_base.build_src_filter}
lib_deps =
${Heltec_E290_base.lib_deps}
${esp32_ota.lib_deps}
bakercp/CRC32 @ ^2.0.0

View File

@@ -18,7 +18,7 @@ AutoDiscoverRTCClock rtc_clock(fallback_clock);
SensorManager sensors;
#ifdef DISPLAY_CLASS
DISPLAY_CLASS display;
DISPLAY_CLASS display(&board.periph_power);
MomentaryButton user_btn(PIN_USER_BTN, 1000, true);
#endif

View File

@@ -60,6 +60,7 @@ build_src_filter = ${Heltec_Wireless_Paper_base.build_src_filter}
lib_deps =
${Heltec_Wireless_Paper_base.lib_deps}
densaugeo/base64 @ ~1.4.0
bakercp/CRC32 @ ^2.0.0
[env:Heltec_Wireless_Paper_repeater]
extends = Heltec_Wireless_Paper_base
@@ -77,6 +78,7 @@ build_src_filter = ${Heltec_Wireless_Paper_base.build_src_filter}
lib_deps =
${Heltec_Wireless_Paper_base.lib_deps}
${esp32_ota.lib_deps}
bakercp/CRC32 @ ^2.0.0
; [env:Heltec_Wireless_Paper_repeater_bridge_rs232]
; extends = Heltec_Wireless_Paper_base
@@ -123,6 +125,7 @@ build_src_filter = ${Heltec_Wireless_Paper_base.build_src_filter}
lib_deps =
${Heltec_Wireless_Paper_base.lib_deps}
${esp32_ota.lib_deps}
bakercp/CRC32 @ ^2.0.0
[env:Heltec_Wireless_Paper_room_server]
extends = Heltec_Wireless_Paper_base
@@ -140,3 +143,4 @@ build_src_filter = ${Heltec_Wireless_Paper_base.build_src_filter}
lib_deps =
${Heltec_Wireless_Paper_base.lib_deps}
${esp32_ota.lib_deps}
bakercp/CRC32 @ ^2.0.0