mirror of
https://github.com/meshtastic/firmware.git
synced 2025-09-03 10:13:44 +00:00
Merge c461038d5a
into 6c7cff7de2
This commit is contained in:
commit
a57ca88e41
17
src/main.cpp
17
src/main.cpp
@ -108,6 +108,10 @@ NRF52Bluetooth *nrf52Bluetooth = nullptr;
|
||||
ButtonThread *TouchButtonThread = nullptr;
|
||||
#endif
|
||||
|
||||
#if defined(TTGO_T_ECHO) && !defined(MESHTASTIC_INCLUDE_NICHE_GRAPHICS)
|
||||
#include "../variants/nrf52840/t-echo/TEchoBacklight.h"
|
||||
#endif
|
||||
|
||||
#if defined(BUTTON_PIN) || defined(ARCH_PORTDUINO)
|
||||
ButtonThread *UserButtonThread = nullptr;
|
||||
#endif
|
||||
@ -1016,8 +1020,13 @@ void setup()
|
||||
BaseType_t higherWake = 0;
|
||||
mainDelay.interruptFromISR(&higherWake);
|
||||
};
|
||||
#if defined(TTGO_T_ECHO) && !defined(MESHTASTIC_INCLUDE_NICHE_GRAPHICS)
|
||||
touchConfig.singlePress = INPUT_BROKER_NONE;
|
||||
touchConfig.longPress = INPUT_BROKER_NONE;
|
||||
#else
|
||||
touchConfig.singlePress = INPUT_BROKER_NONE;
|
||||
touchConfig.longPress = INPUT_BROKER_BACK;
|
||||
#endif
|
||||
TouchButtonThread->initButton(touchConfig);
|
||||
#endif
|
||||
|
||||
@ -1491,6 +1500,14 @@ void setup()
|
||||
|
||||
// We manually run this to update the NodeStatus
|
||||
nodeDB->notifyObservers(true);
|
||||
|
||||
#if defined(TTGO_T_ECHO) && !defined(MESHTASTIC_INCLUDE_NICHE_GRAPHICS)
|
||||
if (!tEchoBacklight) {
|
||||
tEchoBacklight = new TEchoBacklight();
|
||||
tEchoBacklight->setPin(PIN_EINK_EN);
|
||||
tEchoBacklight->start();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif
|
||||
|
174
variants/nrf52840/t-echo/TEchoBacklight.cpp
Normal file
174
variants/nrf52840/t-echo/TEchoBacklight.cpp
Normal file
@ -0,0 +1,174 @@
|
||||
#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
|
43
variants/nrf52840/t-echo/TEchoBacklight.h
Normal file
43
variants/nrf52840/t-echo/TEchoBacklight.h
Normal file
@ -0,0 +1,43 @@
|
||||
#pragma once
|
||||
#include "configuration.h"
|
||||
|
||||
#if defined(TTGO_T_ECHO) && !defined(MESHTASTIC_INCLUDE_NICHE_GRAPHICS)
|
||||
|
||||
#include "concurrency/OSThread.h"
|
||||
|
||||
class TEchoBacklight : public concurrency::OSThread
|
||||
{
|
||||
public:
|
||||
TEchoBacklight();
|
||||
int32_t runOnce() override;
|
||||
void setPin(uint8_t pin);
|
||||
void start();
|
||||
void peek();
|
||||
void latch();
|
||||
void off();
|
||||
|
||||
private:
|
||||
static constexpr uint32_t LATCH_TIME_MS = 5000;
|
||||
static constexpr uint32_t POLL_INTERVAL_MS = 10;
|
||||
static constexpr uint32_t DEBOUNCE_MS = 50;
|
||||
static constexpr uint32_t BLINK_DELAY_MS = 25;
|
||||
static constexpr uint8_t BLINK_STEPS = 3;
|
||||
|
||||
enum State { REST, IRQ, POLLING_UNFIRED, POLLING_FIRED, BLINKING };
|
||||
|
||||
bool backlightLatched = false;
|
||||
uint32_t irqAtMillis = 0;
|
||||
State state = REST;
|
||||
uint32_t blinkStartTime = 0;
|
||||
uint8_t blinkStep = 0;
|
||||
|
||||
void setBacklight(bool on);
|
||||
bool isTouchPressed();
|
||||
static void touchISR();
|
||||
void startThread();
|
||||
void stopThread();
|
||||
};
|
||||
|
||||
extern TEchoBacklight *tEchoBacklight;
|
||||
|
||||
#endif
|
@ -22,6 +22,7 @@
|
||||
#include "nrf.h"
|
||||
#include "wiring_constants.h"
|
||||
#include "wiring_digital.h"
|
||||
#include "TEchoBacklight.h"
|
||||
|
||||
const uint32_t g_ADigitalPinMap[] = {
|
||||
// P0 - pins 0 and 1 are hardwired for xtal and should never be enabled
|
||||
|
Loading…
Reference in New Issue
Block a user