From f119e294affbe5fe355196d35fc8fc73de0ac5aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=B6ttgens?= Date: Mon, 28 Mar 2022 16:55:58 +0200 Subject: [PATCH] Add CardKB, FACES and RAK14004 support to inputbroker/cannedmessages --- src/configuration.h | 8 +++++- src/debug/i2cScan.h | 8 ++++++ src/input/cardKbI2cImpl.cpp | 27 +++++++++++++++++++ src/input/cardKbI2cImpl.h | 21 +++++++++++++++ src/input/facesKbI2cImpl.cpp | 25 ++++++++++++++++++ src/input/facesKbI2cImpl.h | 21 +++++++++++++++ src/input/kbI2cBase.cpp | 50 ++++++++++++++++++++++++++++++++++++ src/input/kbI2cBase.h | 19 ++++++++++++++ src/main.cpp | 6 +++++ src/main.h | 3 +++ src/modules/Modules.cpp | 6 +++++ 11 files changed, 193 insertions(+), 1 deletion(-) create mode 100644 src/input/cardKbI2cImpl.cpp create mode 100644 src/input/cardKbI2cImpl.h create mode 100644 src/input/facesKbI2cImpl.cpp create mode 100644 src/input/facesKbI2cImpl.h create mode 100644 src/input/kbI2cBase.cpp create mode 100644 src/input/kbI2cBase.h diff --git a/src/configuration.h b/src/configuration.h index 0269daba3..6b9fc67a6 100644 --- a/src/configuration.h +++ b/src/configuration.h @@ -126,7 +126,7 @@ along with this program. If not, see . #endif // ----------------------------------------------------------------------------- -// OLED +// OLED & Input // ----------------------------------------------------------------------------- #define SSD1306_ADDRESS 0x3C @@ -143,6 +143,12 @@ along with this program. If not, see . // Define if screen should be mirrored left to right // #define SCREEN_MIRROR +// The m5stack I2C Keyboard (also RAK14004) +#define CARDKB_ADDR 0x5F + +// The older M5 Faces I2C Keyboard +#define FACESKB_ADDR 0x88 + // ----------------------------------------------------------------------------- // GPS // ----------------------------------------------------------------------------- diff --git a/src/debug/i2cScan.h b/src/debug/i2cScan.h index c1d1de7c9..94f3ef4db 100644 --- a/src/debug/i2cScan.h +++ b/src/debug/i2cScan.h @@ -47,6 +47,14 @@ void scanI2Cdevice(void) DEBUG_MSG("unknown display found\n"); } } + if (addr == CARDKB_ADDR) { + cardkb_found = addr; + DEBUG_MSG("m5 cardKB found\n"); + } + if (addr == FACESKB_ADDR) { + faceskb_found = addr; + DEBUG_MSG("m5 Faces found\n"); + } if (addr == ST7567_ADDRESS) { screen_found = addr; DEBUG_MSG("st7567 display found\n"); diff --git a/src/input/cardKbI2cImpl.cpp b/src/input/cardKbI2cImpl.cpp new file mode 100644 index 000000000..b4adc9038 --- /dev/null +++ b/src/input/cardKbI2cImpl.cpp @@ -0,0 +1,27 @@ +#include "cardKbI2cImpl.h" +#include "InputBroker.h" + +CardKbI2cImpl *cardKbI2cImpl; + +CardKbI2cImpl::CardKbI2cImpl() : + KbI2cBase("cardKB") +{ +} + +void CardKbI2cImpl::init() +{ + if (cardkb_found != CARDKB_ADDR) + { + // Input device is not detected. + return; + } + + DEBUG_MSG("registerSource\n"); + inputBroker->registerSource(this); +} + +void CardKbI2cImpl::handlePressed() +{ + DEBUG_MSG("handlePressed\n"); + cardKbI2cImpl->PressHandler(); +} diff --git a/src/input/cardKbI2cImpl.h b/src/input/cardKbI2cImpl.h new file mode 100644 index 000000000..a13998e59 --- /dev/null +++ b/src/input/cardKbI2cImpl.h @@ -0,0 +1,21 @@ +#pragma once +#include "kbI2cBase.h" +#include "main.h" + +/** + * @brief The idea behind this class to have static methods for the event handlers. + * Check attachInterrupt() at RotaryEncoderInteruptBase.cpp + * Technically you can have as many rotary encoders hardver attached + * to your device as you wish, but you always need to have separate event + * handlers, thus you need to have a RotaryEncoderInterrupt implementation. + */ +class CardKbI2cImpl : + public KbI2cBase +{ + public: + CardKbI2cImpl(); + void init(); + static void handlePressed(); +}; + +extern CardKbI2cImpl *cardKbI2cImpl; \ No newline at end of file diff --git a/src/input/facesKbI2cImpl.cpp b/src/input/facesKbI2cImpl.cpp new file mode 100644 index 000000000..348bfcf13 --- /dev/null +++ b/src/input/facesKbI2cImpl.cpp @@ -0,0 +1,25 @@ +#include "facesKbI2cImpl.h" +#include "InputBroker.h" + +FacesKbI2cImpl *facesKbI2cImpl; + +FacesKbI2cImpl::FacesKbI2cImpl() : + KbI2cBase("facesKB") +{ +} + +void FacesKbI2cImpl::init() +{ + if (faceskb_found != FACESKB_ADDR) + { + // Input device is not detected. + return; + } + + inputBroker->registerSource(this); +} + +void FacesKbI2cImpl::handlePressed() +{ + facesKbI2cImpl->PressHandler(); +} diff --git a/src/input/facesKbI2cImpl.h b/src/input/facesKbI2cImpl.h new file mode 100644 index 000000000..5510a5c34 --- /dev/null +++ b/src/input/facesKbI2cImpl.h @@ -0,0 +1,21 @@ +#pragma once +#include "kbI2cBase.h" +#include "main.h" + +/** + * @brief The idea behind this class to have static methods for the event handlers. + * Check attachInterrupt() at RotaryEncoderInteruptBase.cpp + * Technically you can have as many rotary encoders hardver attached + * to your device as you wish, but you always need to have separate event + * handlers, thus you need to have a RotaryEncoderInterrupt implementation. + */ +class FacesKbI2cImpl : + public KbI2cBase +{ + public: + FacesKbI2cImpl(); + void init(); + static void handlePressed(); +}; + +extern FacesKbI2cImpl *facesKbI2cImpl; \ No newline at end of file diff --git a/src/input/kbI2cBase.cpp b/src/input/kbI2cBase.cpp new file mode 100644 index 000000000..62719efee --- /dev/null +++ b/src/input/kbI2cBase.cpp @@ -0,0 +1,50 @@ +#include "configuration.h" +#include "kbI2cBase.h" +#include + +KbI2cBase::KbI2cBase(const char *name) : concurrency::OSThread(name) +{ + this->_originName = name; +} + +int32_t KbI2cBase::runOnce() +{ + InputEvent e; + e.inputEvent = InputEventChar_KEY_NONE; + e.source = this->_originName; + + Wire.requestFrom(CARDKB_ADDR, 1); + + while(Wire.available()) { + char c = Wire.read(); + switch(c) { + case 0x1b: // ESC + e.inputEvent = InputEventChar_KEY_CANCEL; + break; + case 0x08: // Back + e.inputEvent = InputEventChar_KEY_BACK; + break; + case 0xb5: // Up + e.inputEvent = InputEventChar_KEY_UP; + break; + case 0xb6: // Down + e.inputEvent = InputEventChar_KEY_DOWN; + break; + case 0xb4: // Left + e.inputEvent = InputEventChar_KEY_LEFT; + break; + case 0xb7: // Right + e.inputEvent = InputEventChar_KEY_RIGHT; + break; + case 0x0d: // Enter + e.inputEvent = InputEventChar_KEY_SELECT; + break; + } + } + + if (e.inputEvent != InputEventChar_KEY_NONE) + { + this->notifyObservers(&e); + } + return 500; +} diff --git a/src/input/kbI2cBase.h b/src/input/kbI2cBase.h new file mode 100644 index 000000000..c793811a1 --- /dev/null +++ b/src/input/kbI2cBase.h @@ -0,0 +1,19 @@ +#pragma once + +#include "SinglePortModule.h" // TODO: what header file to include? +#include "InputBroker.h" + +class KbI2cBase : + public Observable, + private concurrency::OSThread +{ + public: + explicit KbI2cBase(const char *name); + void PressHandler(); + + protected: + virtual int32_t runOnce() override; + + private: + const char *_originName; +}; diff --git a/src/main.cpp b/src/main.cpp index 0ec89a01d..d90bce00d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -72,6 +72,12 @@ meshtastic::NodeStatus *nodeStatus = new meshtastic::NodeStatus(); uint8_t screen_found; uint8_t screen_model; +// The I2C address of the cardkb or RAK14004 (if found) +uint8_t cardkb_found; + +// The I2C address of the Faces Keyboard (if found) +uint8_t faceskb_found; + bool axp192_found; Router *router = NULL; // Users of router don't care what sort of subclass implements that API diff --git a/src/main.h b/src/main.h index 6617cd770..c5fc62f32 100644 --- a/src/main.h +++ b/src/main.h @@ -7,6 +7,9 @@ extern uint8_t screen_found; extern uint8_t screen_model; +extern uint8_t cardkb_found; +extern uint8_t faceskb_found; + extern bool axp192_found; extern bool isCharging; extern bool isUSBPowered; diff --git a/src/modules/Modules.cpp b/src/modules/Modules.cpp index 3c90243cb..181cea1c8 100644 --- a/src/modules/Modules.cpp +++ b/src/modules/Modules.cpp @@ -2,6 +2,8 @@ #include "input/InputBroker.h" #include "input/RotaryEncoderInterruptImpl1.h" #include "input/UpDownInterruptImpl1.h" +#include "input/cardKbI2cImpl.h" +#include "input/facesKbI2cImpl.h" #include "modules/AdminModule.h" #include "modules/CannedMessageModule.h" #include "modules/ExternalNotificationModule.h" @@ -40,6 +42,10 @@ void setupModules() rotaryEncoderInterruptImpl1->init(); upDownInterruptImpl1 = new UpDownInterruptImpl1(); upDownInterruptImpl1->init(); + cardKbI2cImpl = new CardKbI2cImpl(); + cardKbI2cImpl->init(); + facesKbI2cImpl = new FacesKbI2cImpl(); + facesKbI2cImpl->init(); cannedMessageModule = new CannedMessageModule(); #ifndef PORTDUINO new TelemetryModule();