mirror of
https://github.com/meshtastic/firmware.git
synced 2025-10-29 07:36:46 +00:00
Properly handle TCA8418 interrupts in sleep mode
This commit is contained in:
parent
696a391cb8
commit
a37133214f
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "TCA8418KeyboardBase.h"
|
#include "TCA8418KeyboardBase.h"
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
|
#include "sleep.h"
|
||||||
|
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
|
|
||||||
@ -44,14 +45,18 @@ void TCA8418KeyboardBase::begin(uint8_t addr, TwoWire *wire)
|
|||||||
reset();
|
reset();
|
||||||
|
|
||||||
#ifdef KB_INT
|
#ifdef KB_INT
|
||||||
interruptInstance = this;
|
|
||||||
auto interruptHandler = []() { interruptInstance->notifyObservers(interruptInstance); };
|
|
||||||
|
|
||||||
::pinMode(KB_INT, INPUT_PULLUP);
|
::pinMode(KB_INT, INPUT_PULLUP);
|
||||||
attachInterrupt(KB_INT, interruptHandler, FALLING);
|
attachInterruptHandler();
|
||||||
|
|
||||||
enableInterrupts();
|
enableInterrupts();
|
||||||
#endif
|
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
// Register callbacks for before and after lightsleep
|
||||||
|
// Used to detach and reattach interrupts
|
||||||
|
lsObserver.observe(¬ifyLightSleep);
|
||||||
|
lsEndObserver.observe(¬ifyLightSleepEnd);
|
||||||
|
#endif // ARCH_ESP32
|
||||||
|
|
||||||
|
#endif // KB_INT
|
||||||
}
|
}
|
||||||
|
|
||||||
void TCA8418KeyboardBase::begin(i2c_com_fptr_t r, i2c_com_fptr_t w, uint8_t addr)
|
void TCA8418KeyboardBase::begin(i2c_com_fptr_t r, i2c_com_fptr_t w, uint8_t addr)
|
||||||
@ -93,6 +98,41 @@ void TCA8418KeyboardBase::reset()
|
|||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef KB_INT
|
||||||
|
void TCA8418KeyboardBase::attachInterruptHandler()
|
||||||
|
{
|
||||||
|
interruptInstance = this;
|
||||||
|
auto interruptHandler = []() { interruptInstance->notifyObservers(interruptInstance); };
|
||||||
|
attachInterrupt(KB_INT, interruptHandler, FALLING);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TCA8418KeyboardBase::detachInterruptHandler()
|
||||||
|
{
|
||||||
|
detachInterrupt(KB_INT);
|
||||||
|
interruptInstance = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
// Detach our class' interrupts before lightsleep
|
||||||
|
// Allows sleep.cpp to configure its own interrupts, which wake the device on user-button press
|
||||||
|
int TCA8418KeyboardBase::beforeLightSleep(void *unused)
|
||||||
|
{
|
||||||
|
detachInterruptHandler();
|
||||||
|
return 0; // Indicates success
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reconfigure our interrupts
|
||||||
|
// Our class' interrupts were disconnected during sleep, to allow the user button to wake the device from sleep
|
||||||
|
int TCA8418KeyboardBase::afterLightSleep(esp_sleep_wakeup_cause_t cause)
|
||||||
|
{
|
||||||
|
attachInterruptHandler();
|
||||||
|
this->notifyObservers(this); // Trigger a one-off poll in case a keypress woke us
|
||||||
|
return 0; // Indicates success
|
||||||
|
}
|
||||||
|
#endif // ARCH_ESP32
|
||||||
|
|
||||||
|
#endif // KB_INT
|
||||||
|
|
||||||
bool TCA8418KeyboardBase::matrix(uint8_t rows, uint8_t columns)
|
bool TCA8418KeyboardBase::matrix(uint8_t rows, uint8_t columns)
|
||||||
{
|
{
|
||||||
if (rows < 1 || rows > 8 || columns < 1 || columns > 10)
|
if (rows < 1 || rows > 8 || columns < 1 || columns > 10)
|
||||||
@ -169,7 +209,7 @@ void TCA8418KeyboardBase::trigger()
|
|||||||
|
|
||||||
#ifdef KB_INT
|
#ifdef KB_INT
|
||||||
// Reset interrupt mask so we can receive future interrupts
|
// Reset interrupt mask so we can receive future interrupts
|
||||||
writeRegister(TCA8418_REG_INT_STAT, 3);
|
clearInt();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -163,9 +163,29 @@ class TCA8418KeyboardBase : public KbInterruptObservable
|
|||||||
uint8_t columns;
|
uint8_t columns;
|
||||||
String queue;
|
String queue;
|
||||||
|
|
||||||
|
#ifdef KB_INT
|
||||||
|
void attachInterruptHandler();
|
||||||
|
void detachInterruptHandler();
|
||||||
|
|
||||||
|
#ifdef ARCH_ESP32
|
||||||
|
// Disconnect and reconnect interrupts for light sleep
|
||||||
|
int beforeLightSleep(void *unused);
|
||||||
|
int afterLightSleep(esp_sleep_wakeup_cause_t cause);
|
||||||
|
#endif // ARCH_ESP32
|
||||||
|
|
||||||
|
#endif // KB_INT
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TwoWire *m_wire;
|
TwoWire *m_wire;
|
||||||
uint8_t m_addr;
|
uint8_t m_addr;
|
||||||
i2c_com_fptr_t readCallback;
|
i2c_com_fptr_t readCallback;
|
||||||
i2c_com_fptr_t writeCallback;
|
i2c_com_fptr_t writeCallback;
|
||||||
|
|
||||||
|
#if defined(KB_INT) && defined(ARCH_ESP32)
|
||||||
|
// Get notified when lightsleep begins and ends
|
||||||
|
CallbackObserver<TCA8418KeyboardBase, void *> lsObserver =
|
||||||
|
CallbackObserver<TCA8418KeyboardBase, void *>(this, &TCA8418KeyboardBase::beforeLightSleep);
|
||||||
|
CallbackObserver<TCA8418KeyboardBase, esp_sleep_wakeup_cause_t> lsEndObserver =
|
||||||
|
CallbackObserver<TCA8418KeyboardBase, esp_sleep_wakeup_cause_t>(this, &TCA8418KeyboardBase::afterLightSleep);
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|||||||
@ -441,7 +441,6 @@ int32_t KbI2cBase::runOnce()
|
|||||||
this->notifyObservers(&e);
|
this->notifyObservers(&e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TCAKeyboard.clearInt();
|
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user