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 = wire;
|
||||||
m_wire->begin();
|
m_wire->begin();
|
||||||
reset();
|
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)
|
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);
|
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)
|
void TCA8418KeyboardBase::pressed(uint8_t key)
|
||||||
@ -292,6 +309,8 @@ void TCA8418KeyboardBase::disableInterrupts()
|
|||||||
writeRegister(TCA8418_REG_CFG, value);
|
writeRegister(TCA8418_REG_CFG, value);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TCA8418KeyboardBase* TCA8418KeyboardBase::interruptInstance;
|
||||||
|
|
||||||
void TCA8418KeyboardBase::enableMatrixOverflow()
|
void TCA8418KeyboardBase::enableMatrixOverflow()
|
||||||
{
|
{
|
||||||
uint8_t value = readRegister(TCA8418_REG_CFG);
|
uint8_t value = readRegister(TCA8418_REG_CFG);
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
// Based on the MPR121 Keyboard and Adafruit TCA8418 library
|
// Based on the MPR121 Keyboard and Adafruit TCA8418 library
|
||||||
#include "configuration.h"
|
#include "configuration.h"
|
||||||
#include <Wire.h>
|
#include <Wire.h>
|
||||||
|
#include "kbInterrupt.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief TCA8418KeyboardBase is the base class for TCA8418 keyboard handling.
|
* @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.
|
* 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.
|
* It supports both I2C communication and function pointers for custom I2C operations.
|
||||||
*/
|
*/
|
||||||
class TCA8418KeyboardBase
|
class TCA8418KeyboardBase : public KbInterruptObservable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum TCA8418Key : uint8_t {
|
enum TCA8418Key : uint8_t {
|
||||||
@ -142,6 +143,7 @@ class TCA8418KeyboardBase
|
|||||||
// enable / disable interrupts for matrix and GPI pins
|
// enable / disable interrupts for matrix and GPI pins
|
||||||
void enableInterrupts();
|
void enableInterrupts();
|
||||||
void disableInterrupts();
|
void disableInterrupts();
|
||||||
|
static TCA8418KeyboardBase* interruptInstance;
|
||||||
|
|
||||||
// ignore key events when FIFO buffer is full or not.
|
// ignore key events when FIFO buffer is full or not.
|
||||||
void enableMatrixOverflow();
|
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 KbI2cBase::runOnce()
|
||||||
{
|
{
|
||||||
|
int32_t interval = 300;
|
||||||
if (!i2cBus) {
|
if (!i2cBus) {
|
||||||
switch (cardkb_found.port) {
|
switch (cardkb_found.port) {
|
||||||
case ScanI2C::WIRE1:
|
case ScanI2C::WIRE1:
|
||||||
@ -61,6 +62,7 @@ int32_t KbI2cBase::runOnce()
|
|||||||
}
|
}
|
||||||
if (cardkb_found.address == TCA8418_KB_ADDR) {
|
if (cardkb_found.address == TCA8418_KB_ADDR) {
|
||||||
TCAKeyboard.begin(TCA8418_KB_ADDR, &Wire1);
|
TCAKeyboard.begin(TCA8418_KB_ADDR, &Wire1);
|
||||||
|
observe(&TCAKeyboard);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
@ -76,6 +78,7 @@ int32_t KbI2cBase::runOnce()
|
|||||||
}
|
}
|
||||||
if (cardkb_found.address == TCA8418_KB_ADDR) {
|
if (cardkb_found.address == TCA8418_KB_ADDR) {
|
||||||
TCAKeyboard.begin(TCA8418_KB_ADDR, &Wire);
|
TCAKeyboard.begin(TCA8418_KB_ADDR, &Wire);
|
||||||
|
observe(&TCAKeyboard);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ScanI2C::NO_I2C:
|
case ScanI2C::NO_I2C:
|
||||||
@ -249,6 +252,7 @@ int32_t KbI2cBase::runOnce()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 0x84: { // Adafruit TCA8418
|
case 0x84: { // Adafruit TCA8418
|
||||||
|
interval = 3000; // Less polling, we have interrupts with onNotify()
|
||||||
TCAKeyboard.trigger();
|
TCAKeyboard.trigger();
|
||||||
InputEvent e;
|
InputEvent e;
|
||||||
while (TCAKeyboard.hasEvent()) {
|
while (TCAKeyboard.hasEvent()) {
|
||||||
@ -331,7 +335,6 @@ int32_t KbI2cBase::runOnce()
|
|||||||
LOG_DEBUG("TCA8418 Notifying: %i Char: %c", e.inputEvent, e.kbchar);
|
LOG_DEBUG("TCA8418 Notifying: %i Char: %c", e.inputEvent, e.kbchar);
|
||||||
this->notifyObservers(&e);
|
this->notifyObservers(&e);
|
||||||
}
|
}
|
||||||
TCAKeyboard.trigger();
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -518,5 +521,17 @@ int32_t KbI2cBase::runOnce()
|
|||||||
default:
|
default:
|
||||||
LOG_WARN("Unknown kb_model 0x%02x", kb_model);
|
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 "MPR121Keyboard.h"
|
||||||
#include "Wire.h"
|
#include "Wire.h"
|
||||||
#include "concurrency/OSThread.h"
|
#include "concurrency/OSThread.h"
|
||||||
|
#include "kbInterrupt.h"
|
||||||
|
|
||||||
class TCA8418KeyboardBase;
|
class TCA8418KeyboardBase;
|
||||||
|
|
||||||
class KbI2cBase : public Observable<const InputEvent *>, public concurrency::OSThread
|
class KbI2cBase : public Observable<const InputEvent *>, public KbInterruptObserver, public concurrency::OSThread
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit KbI2cBase(const char *name);
|
explicit KbI2cBase(const char *name);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual int32_t runOnce() override;
|
virtual int32_t runOnce() override;
|
||||||
|
virtual int onNotify(KbInterruptObservable* src) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const char *_originName;
|
const char *_originName;
|
||||||
@ -24,5 +26,6 @@ class KbI2cBase : public Observable<const InputEvent *>, public concurrency::OST
|
|||||||
BBQ10Keyboard Q10keyboard;
|
BBQ10Keyboard Q10keyboard;
|
||||||
MPR121Keyboard MPRkeyboard;
|
MPR121Keyboard MPRkeyboard;
|
||||||
TCA8418KeyboardBase &TCAKeyboard;
|
TCA8418KeyboardBase &TCAKeyboard;
|
||||||
|
volatile uint8_t pendingInterruptCount = 0;
|
||||||
bool is_sym = false;
|
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