mirror of
https://github.com/meshtastic/firmware.git
synced 2025-10-29 15:46:46 +00:00
TCA8418: Interrupt based notify of new key events
This commit is contained in:
parent
4816f45552
commit
63468df93f
@ -43,6 +43,18 @@ void TCA8418KeyboardBase::begin(uint8_t addr, TwoWire *wire)
|
||||
m_wire = wire;
|
||||
m_wire->begin();
|
||||
reset();
|
||||
|
||||
#ifdef KB_INT
|
||||
interruptInstance = this;
|
||||
auto interruptHandler = []() {
|
||||
interruptInstance->notifyObservers(interruptInstance);
|
||||
};
|
||||
|
||||
::pinMode(KB_INT, INPUT_PULLUP);
|
||||
attachInterrupt(KB_INT, interruptHandler, FALLING);
|
||||
|
||||
enableInterrupts();
|
||||
#endif
|
||||
}
|
||||
|
||||
void TCA8418KeyboardBase::begin(i2c_com_fptr_t r, i2c_com_fptr_t w, uint8_t addr)
|
||||
@ -157,6 +169,11 @@ void TCA8418KeyboardBase::trigger()
|
||||
released(key);
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef KB_INT
|
||||
// Reset interrupt mask so we can receive future interrupts
|
||||
writeRegister(TCA8418_REG_INT_STAT, 3);
|
||||
#endif
|
||||
}
|
||||
|
||||
void TCA8418KeyboardBase::pressed(uint8_t key)
|
||||
@ -292,6 +309,8 @@ void TCA8418KeyboardBase::disableInterrupts()
|
||||
writeRegister(TCA8418_REG_CFG, value);
|
||||
};
|
||||
|
||||
TCA8418KeyboardBase* TCA8418KeyboardBase::interruptInstance;
|
||||
|
||||
void TCA8418KeyboardBase::enableMatrixOverflow()
|
||||
{
|
||||
uint8_t value = readRegister(TCA8418_REG_CFG);
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
// Based on the MPR121 Keyboard and Adafruit TCA8418 library
|
||||
#include "configuration.h"
|
||||
#include <Wire.h>
|
||||
#include "kbInterrupt.h"
|
||||
|
||||
/**
|
||||
* @brief TCA8418KeyboardBase is the base class for TCA8418 keyboard handling.
|
||||
@ -8,7 +9,7 @@
|
||||
* and handling key states. It is designed to be extended for specific keyboard implementations.
|
||||
* It supports both I2C communication and function pointers for custom I2C operations.
|
||||
*/
|
||||
class TCA8418KeyboardBase
|
||||
class TCA8418KeyboardBase : public KbInterruptObservable
|
||||
{
|
||||
public:
|
||||
enum TCA8418Key : uint8_t {
|
||||
@ -142,6 +143,7 @@ class TCA8418KeyboardBase
|
||||
// enable / disable interrupts for matrix and GPI pins
|
||||
void enableInterrupts();
|
||||
void disableInterrupts();
|
||||
static TCA8418KeyboardBase* interruptInstance;
|
||||
|
||||
// ignore key events when FIFO buffer is full or not.
|
||||
void enableMatrixOverflow();
|
||||
|
||||
@ -46,6 +46,7 @@ uint8_t read_from_14004(TwoWire *i2cBus, uint8_t reg, uint8_t *data, uint8_t len
|
||||
|
||||
int32_t KbI2cBase::runOnce()
|
||||
{
|
||||
int32_t interval = 300;
|
||||
if (!i2cBus) {
|
||||
switch (cardkb_found.port) {
|
||||
case ScanI2C::WIRE1:
|
||||
@ -61,6 +62,7 @@ int32_t KbI2cBase::runOnce()
|
||||
}
|
||||
if (cardkb_found.address == TCA8418_KB_ADDR) {
|
||||
TCAKeyboard.begin(TCA8418_KB_ADDR, &Wire1);
|
||||
observe(&TCAKeyboard);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
@ -76,6 +78,7 @@ int32_t KbI2cBase::runOnce()
|
||||
}
|
||||
if (cardkb_found.address == TCA8418_KB_ADDR) {
|
||||
TCAKeyboard.begin(TCA8418_KB_ADDR, &Wire);
|
||||
observe(&TCAKeyboard);
|
||||
}
|
||||
break;
|
||||
case ScanI2C::NO_I2C:
|
||||
@ -249,6 +252,7 @@ int32_t KbI2cBase::runOnce()
|
||||
break;
|
||||
}
|
||||
case 0x84: { // Adafruit TCA8418
|
||||
interval = 3000; // Less polling, we have interrupts with onNotify()
|
||||
TCAKeyboard.trigger();
|
||||
InputEvent e;
|
||||
while (TCAKeyboard.hasEvent()) {
|
||||
@ -331,7 +335,6 @@ int32_t KbI2cBase::runOnce()
|
||||
LOG_DEBUG("TCA8418 Notifying: %i Char: %c", e.inputEvent, e.kbchar);
|
||||
this->notifyObservers(&e);
|
||||
}
|
||||
TCAKeyboard.trigger();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -518,5 +521,17 @@ int32_t KbI2cBase::runOnce()
|
||||
default:
|
||||
LOG_WARN("Unknown kb_model 0x%02x", kb_model);
|
||||
}
|
||||
return 300;
|
||||
|
||||
// If new interrupt triggered while we were processing the previous, reinvoke with 0 interval right away
|
||||
if (pendingInterruptCount) pendingInterruptCount--;
|
||||
if (pendingInterruptCount) return 0;
|
||||
|
||||
return interval;
|
||||
}
|
||||
|
||||
int KbI2cBase::onNotify(KbInterruptObservable* src)
|
||||
{
|
||||
pendingInterruptCount++;
|
||||
setInterval(0);
|
||||
return 0;
|
||||
}
|
||||
@ -5,16 +5,18 @@
|
||||
#include "MPR121Keyboard.h"
|
||||
#include "Wire.h"
|
||||
#include "concurrency/OSThread.h"
|
||||
#include "kbInterrupt.h"
|
||||
|
||||
class TCA8418KeyboardBase;
|
||||
|
||||
class KbI2cBase : public Observable<const InputEvent *>, public concurrency::OSThread
|
||||
class KbI2cBase : public Observable<const InputEvent *>, public KbInterruptObserver, public concurrency::OSThread
|
||||
{
|
||||
public:
|
||||
explicit KbI2cBase(const char *name);
|
||||
|
||||
protected:
|
||||
virtual int32_t runOnce() override;
|
||||
virtual int onNotify(KbInterruptObservable* src) override;
|
||||
|
||||
private:
|
||||
const char *_originName;
|
||||
@ -24,5 +26,6 @@ class KbI2cBase : public Observable<const InputEvent *>, public concurrency::OST
|
||||
BBQ10Keyboard Q10keyboard;
|
||||
MPR121Keyboard MPRkeyboard;
|
||||
TCA8418KeyboardBase &TCAKeyboard;
|
||||
volatile uint8_t pendingInterruptCount = 0;
|
||||
bool is_sym = false;
|
||||
};
|
||||
11
src/input/kbInterrupt.h
Normal file
11
src/input/kbInterrupt.h
Normal file
@ -0,0 +1,11 @@
|
||||
#pragma once
|
||||
|
||||
#include "Observer.h"
|
||||
|
||||
class KbInterruptObservable : public Observable<KbInterruptObservable*>
|
||||
{
|
||||
};
|
||||
|
||||
class KbInterruptObserver : public Observer<KbInterruptObservable*>
|
||||
{
|
||||
};
|
||||
Loading…
Reference in New Issue
Block a user