Files
mikecarper 64a068506b Merge PR #26: add M5Stack Cardputer-Adv support
Integrate mjgodat's keyboard/display Companion, USB Companion, Repeater and
Room Server support for Cardputer-Adv with Cap LoRa-1262.

Fix UI retry dispatch and ACK ownership, packet/storage bounds, numeric
input validation, sparse channel selection, optional-display shutdown,
keyboard layout limits, reserved GPIOs and Windows cross-drive includes.
Retain all 350 contacts and queue capacity using the existing contact cache;
account for the custom UI's runtime allocations in the RAM admission gate.
Carry the MultiMote and DejaVu notices with firmware packages and add CI
coverage for all four board roles plus the shared T-Deck Companion.

Validation: all four Cardputer roles and the T-Deck BLE Companion build;
Cardputer sanitizer, UI, layout, ownership, licensing and storage tests;
65 RAM-policy tests and 14 contact-cache tests. PlatformIO ran serially.

PR: https://github.com/mikecarper/MeshCore/pull/26
2026-10-27 22:25:35 -07:00

71 lines
1.7 KiB
C++

#include "CardputerKeyboard.h"
#include "globals.h"
#include <Wire.h>
bool CardputerKeyboard::isModifier(Keyboard::Key key) {
return key == Keyboard::KEY_SHIFT || key == Keyboard::KEY_OPT ||
key == Keyboard::KEY_ALT || key == Keyboard::KEY_CTRL ||
key == Keyboard::KEY_FN;
}
void CardputerKeyboard::updateModifier(Keyboard::Key key, bool down) {
switch (key) {
case Keyboard::KEY_SHIFT:
// Sticky: each press toggles (like caps lock), releases are ignored
if (down) modifiers.shift = !modifiers.shift;
break;
case Keyboard::KEY_OPT:
modifiers.opt = down;
break;
case Keyboard::KEY_ALT:
modifiers.alt = down;
break;
case Keyboard::KEY_CTRL:
modifiers.ctrl = down;
break;
case Keyboard::KEY_FN:
// One-shot: a press arms Fn for the next key (press again to cancel)
if (down) modifiers.fn = !modifiers.fn;
break;
}
}
void CardputerKeyboard::begin() {
tio.begin(KEYBOARD_I2C_ADDRESS, &Wire1);
tio.matrix(7, 8);
tio.flush();
tio.enableInterrupts();
}
Keyboard::Event CardputerKeyboard::poll() {
Keyboard::Event result;
result.changed = tio.available() > 0;
if (result.changed) {
uint8_t e = tio.getEvent();
bool down = (e & 0x80);
tio.writeRegister(TCA8418_REG_INT_STAT, 1);
e &= 0x7F;
// Normalize key code to remove gaps
uint8_t key_index = ((e - 1) / 10) * 8 + ((e - 1) % 10) + 1;
Keyboard::Key key = static_cast<Keyboard::Key>(key_index);
result.down = down;
if (isModifier(key)) {
updateModifier(key, down);
} else {
result.key = key;
}
}
result.modifiers = modifiers;
if (result.key != Keyboard::KEY_NONE && result.down) {
modifiers.fn = false; // Fn applies to this one key only
}
return result;
}