mirror of
https://github.com/meshtastic/firmware.git
synced 2025-09-05 02:59:11 +00:00

Introduces TEchoBacklight class to manage the backlight on the T-Echo device (BaseUI only)
175 lines
4.1 KiB
C++
175 lines
4.1 KiB
C++
#include "TEchoBacklight.h"
|
|
|
|
#if defined(TTGO_T_ECHO) && !defined(MESHTASTIC_INCLUDE_NICHE_GRAPHICS)
|
|
|
|
#include "RadioLibInterface.h"
|
|
#include "configuration.h"
|
|
|
|
TEchoBacklight *tEchoBacklight = nullptr;
|
|
|
|
TEchoBacklight::TEchoBacklight() : OSThread("TEchoBacklight")
|
|
{
|
|
setInterval(POLL_INTERVAL_MS);
|
|
OSThread::disable();
|
|
}
|
|
|
|
void TEchoBacklight::setPin(uint8_t pin)
|
|
{
|
|
pinMode(pin, OUTPUT);
|
|
off();
|
|
}
|
|
|
|
void TEchoBacklight::start()
|
|
{
|
|
pinMode(PIN_BUTTON_TOUCH, INPUT_PULLUP);
|
|
attachInterrupt(PIN_BUTTON_TOUCH, touchISR, FALLING);
|
|
}
|
|
|
|
int32_t TEchoBacklight::runOnce()
|
|
{
|
|
bool awaitingRelease = false;
|
|
|
|
switch (state) {
|
|
case REST:
|
|
break;
|
|
|
|
case IRQ:
|
|
if (!RadioLibInterface::instance || RadioLibInterface::instance->isSending()) {
|
|
LOG_INFO("TEchoBacklight: Touch ignored - radio transmitting");
|
|
state = REST;
|
|
break;
|
|
}
|
|
LOG_INFO("TEchoBacklight: Touch detected - peek()");
|
|
peek();
|
|
state = POLLING_UNFIRED;
|
|
awaitingRelease = true;
|
|
break;
|
|
|
|
case POLLING_UNFIRED: {
|
|
uint32_t length = millis() - irqAtMillis;
|
|
|
|
if (!isTouchPressed()) {
|
|
state = REST;
|
|
if (length > DEBOUNCE_MS && length < LATCH_TIME_MS) {
|
|
LOG_INFO("TEchoBacklight: Short press (%lums) - off()", length);
|
|
off();
|
|
} else {
|
|
LOG_INFO("TEchoBacklight: Touch released too quick (%lums) - debounced", length);
|
|
}
|
|
} else {
|
|
awaitingRelease = true;
|
|
if (length >= LATCH_TIME_MS) {
|
|
LOG_INFO("TEchoBacklight: Long press (%lums) - starting latch blink", length);
|
|
state = BLINKING;
|
|
blinkStartTime = millis();
|
|
blinkStep = 0;
|
|
setBacklight(false);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
case BLINKING: {
|
|
uint32_t elapsed = millis() - blinkStartTime;
|
|
if (elapsed >= BLINK_DELAY_MS) {
|
|
blinkStep++;
|
|
blinkStartTime = millis();
|
|
|
|
setBacklight(blinkStep % 2 == 1);
|
|
|
|
if (blinkStep == BLINK_STEPS) {
|
|
backlightLatched = true;
|
|
state = POLLING_FIRED;
|
|
LOG_INFO("TEchoBacklight: Blink complete - latched ON");
|
|
}
|
|
}
|
|
awaitingRelease = true;
|
|
break;
|
|
}
|
|
|
|
case POLLING_FIRED:
|
|
if (!isTouchPressed()) {
|
|
LOG_INFO("TEchoBacklight: Long press released");
|
|
state = REST;
|
|
} else {
|
|
awaitingRelease = true;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (!awaitingRelease) {
|
|
stopThread();
|
|
}
|
|
|
|
return POLL_INTERVAL_MS;
|
|
}
|
|
|
|
void TEchoBacklight::setBacklight(bool on)
|
|
{
|
|
digitalWrite(PIN_EINK_EN, on ? HIGH : LOW);
|
|
}
|
|
|
|
bool TEchoBacklight::isTouchPressed()
|
|
{
|
|
return digitalRead(PIN_BUTTON_TOUCH) == LOW;
|
|
}
|
|
|
|
void TEchoBacklight::peek()
|
|
{
|
|
setBacklight(true);
|
|
backlightLatched = false;
|
|
}
|
|
|
|
void TEchoBacklight::latch()
|
|
{
|
|
if (backlightLatched) {
|
|
LOG_INFO("TEchoBacklight: latch() - turning OFF");
|
|
backlightLatched = false;
|
|
setBacklight(false);
|
|
} else {
|
|
LOG_INFO("TEchoBacklight: latch() - turning ON");
|
|
backlightLatched = true;
|
|
setBacklight(true);
|
|
}
|
|
}
|
|
|
|
void TEchoBacklight::off()
|
|
{
|
|
backlightLatched = false;
|
|
setBacklight(false);
|
|
}
|
|
|
|
void TEchoBacklight::touchISR()
|
|
{
|
|
static volatile bool isrRunning = false;
|
|
|
|
if (!isrRunning && tEchoBacklight) {
|
|
isrRunning = true;
|
|
if (tEchoBacklight->state == REST) {
|
|
tEchoBacklight->state = IRQ;
|
|
tEchoBacklight->irqAtMillis = millis();
|
|
tEchoBacklight->startThread();
|
|
LOG_INFO("TEchoBacklight: ISR triggered - starting thread");
|
|
}
|
|
isrRunning = false;
|
|
}
|
|
}
|
|
|
|
void TEchoBacklight::startThread()
|
|
{
|
|
if (!OSThread::enabled) {
|
|
OSThread::setInterval(POLL_INTERVAL_MS);
|
|
OSThread::enabled = true;
|
|
}
|
|
}
|
|
|
|
void TEchoBacklight::stopThread()
|
|
{
|
|
if (OSThread::enabled) {
|
|
OSThread::disable();
|
|
}
|
|
state = REST;
|
|
}
|
|
|
|
#endif
|