10#ifndef M5_UNIT_KEYBOARD_UNIT_TAB5_KEYBOARD_HPP
11#define M5_UNIT_KEYBOARD_UNIT_TAB5_KEYBOARD_HPP
16class TestTab5Keyboard;
25#if defined(ARDUINO_ARCH_ESP32) || defined(ESP_PLATFORM)
26#include "driver/gpio.h"
40constexpr uint8_t REG_INT_CFG{0x00};
41constexpr uint8_t REG_INT_STAT{0x01};
42constexpr uint8_t REG_EVENT_NUM{
44constexpr uint8_t REG_BRIGHTNESS{0x03};
45constexpr uint8_t REG_MODE_KEYBOARD{0x10};
46constexpr uint8_t REG_MODE_RGB{0x11};
47constexpr uint8_t REG_KEY_EVENT{0x20};
48constexpr uint8_t REG_HID_EVENT{0x30};
49constexpr uint8_t REG_CHAR_EVENT_LENGTH{0x40};
50constexpr uint8_t REG_CHAR_EVENT{0x50};
51constexpr uint8_t REG_RGB1_B{0x60};
52constexpr uint8_t REG_RGB1_G{0x61};
53constexpr uint8_t REG_RGB1_R{0x62};
54constexpr uint8_t REG_RGB2_B{0x64};
55constexpr uint8_t REG_RGB2_G{0x65};
56constexpr uint8_t REG_RGB2_R{0x66};
57constexpr uint8_t REG_FIRMWARE_VERSION{0xFE};
58constexpr uint8_t REG_I2C_ADDRESS{0xFF};
124inline uint8_t
toKeyIndex(
const uint8_t row,
const uint8_t col)
270constexpr uint8_t CMD_INT_CFG{REG_INT_CFG};
271constexpr uint8_t CMD_INT_STAT{REG_INT_STAT};
272constexpr uint8_t CMD_EVENT_NUM{REG_EVENT_NUM};
273constexpr uint8_t CMD_BRIGHTNESS{REG_BRIGHTNESS};
274constexpr uint8_t CMD_MODE_KEYBOARD{REG_MODE_KEYBOARD};
275constexpr uint8_t CMD_MODE_RGB{REG_MODE_RGB};
276constexpr uint8_t CMD_KEY_EVENT{REG_KEY_EVENT};
277constexpr uint8_t CMD_HID_EVENT{REG_HID_EVENT};
278constexpr uint8_t CMD_CHAR_EVENT_LENGTH{REG_CHAR_EVENT_LENGTH};
279constexpr uint8_t CMD_CHAR_EVENT{REG_CHAR_EVENT};
280constexpr uint8_t CMD_RGB1_B{REG_RGB1_B};
281constexpr uint8_t CMD_FIRMWARE_VERSION{REG_FIRMWARE_VERSION};
282constexpr uint8_t CMD_I2C_ADDRESS{REG_I2C_ADDRESS};
306class UnitTab5Keyboard :
public UnitKeyboard,
307 public PeriodicMeasurementAdapter<UnitTab5Keyboard, tab5_keyboard::Event> {
308 M5_UNIT_COMPONENT_HPP_BUILDER(UnitTab5Keyboard, 0x6D);
309 M5_UNIT_COMPONENT_PERIODIC_MEASUREMENT_ADAPTER_HPP_BUILDER(UnitTab5Keyboard, tab5_keyboard::Event);
310 friend class ::TestTab5Keyboard;
358 auto ccfg = component_config();
359 ccfg.clock = 400 * 1000U;
360 ccfg.stored_size = tab5_keyboard::DEFAULT_STORED_SIZE;
361 component_config(ccfg);
363 virtual ~UnitTab5Keyboard();
380 virtual bool begin()
override;
382 virtual void update(
const bool force =
false)
override;
519 bool writeRgb(
const uint8_t idx,
const uint8_t r,
const uint8_t g,
const uint8_t b);
530 bool readRgb(
const uint8_t idx, uint8_t& r, uint8_t& g, uint8_t& b);
556 return _firmware_version;
577 return _state.pressed;
582 return _state.released;
587 return _state.holding;
592 return _state.was_hold;
597 return _state.repeating;
606 return bitwise_active() && _state.now.any();
611 return bitwise_active() && _state.pressed.any();
616 return bitwise_active() && _state.released.any();
621 return bitwise_active() && _state.holding.any();
626 return bitwise_active() && _state.was_hold.any();
631 return bitwise_active() && _state.repeating.any();
645 return bitwise_active() && kidx < tab5_keyboard::KEY_COUNT && _state.now.test(kidx);
654 return bitwise_active() && kidx < tab5_keyboard::KEY_COUNT && _state.pressed.test(kidx);
663 return bitwise_active() && kidx < tab5_keyboard::KEY_COUNT && _state.released.test(kidx);
672 return bitwise_active() && kidx < tab5_keyboard::KEY_COUNT && _state.holding.test(kidx);
681 return bitwise_active() && kidx < tab5_keyboard::KEY_COUNT && _state.was_hold.test(kidx);
690 return bitwise_active() && kidx < tab5_keyboard::KEY_COUNT && _state.repeating.test(kidx);
697 inline bool isPressed(
const uint8_t row,
const uint8_t col)
const
699 return isPressed(tab5_keyboard::toKeyIndex(row, col));
702 inline bool wasPressed(
const uint8_t row,
const uint8_t col)
const
704 return wasPressed(tab5_keyboard::toKeyIndex(row, col));
707 inline bool wasReleased(
const uint8_t row,
const uint8_t col)
const
709 return wasReleased(tab5_keyboard::toKeyIndex(row, col));
712 inline bool isHolding(
const uint8_t row,
const uint8_t col)
const
714 return isHolding(tab5_keyboard::toKeyIndex(row, col));
717 inline bool wasHold(
const uint8_t row,
const uint8_t col)
const
719 return wasHold(tab5_keyboard::toKeyIndex(row, col));
722 inline bool isRepeating(
const uint8_t row,
const uint8_t col)
const
724 return isRepeating(tab5_keyboard::toKeyIndex(row, col));
735 return bitwise_active() && _state.now.test(tab5_keyboard::KIDX_SYM);
740 return bitwise_active() && _state.now.test(tab5_keyboard::KIDX_AA);
745 return bitwise_active() && _state.now.test(tab5_keyboard::KIDX_CTRL);
750 return bitwise_active() && _state.now.test(tab5_keyboard::KIDX_ALT);
795 bool read_key_event(uint8_t& row, uint8_t& col,
bool& pressed);
804 bool read_hid_event(uint8_t& modifier, uint8_t& keycode);
818 bool read_char_event(uint8_t& modifier, std::string& chars);
827 bool start_periodic_measurement();
828 bool stop_periodic_measurement();
852 inline bool bitwise_active()
const
854 return _mode == tab5_keyboard::Mode::Normal;
861 bool ready_to_measure(
const bool force);
862 bool ready_to_measure_irq(
const bool force);
863 bool ready_to_measure_polling(
const bool force);
865 void drain_events(
const tab5_keyboard::Mode mode);
867 void process_normal_state();
869 std::unique_ptr<m5::container::CircularBuffer<tab5_keyboard::Event>> _data{};
873 bool _irq_pin_configured{
false};
876 bool _int_enabled{
false};
880 tab5_keyboard::Mode _mode{tab5_keyboard::Mode::Normal};
883 m5::unit::keyboard_bitwise::BitwiseState<tab5_keyboard::KEY_COUNT> _state;
885 uint8_t _firmware_version{};
887 volatile bool _irq_pending{
false};
Generic bit-map state tracking for keyboard-like devices.
Base class of the Keyboard Unit.
Tab5 built-in keyboard unit connected via I2C ExtPort1.
bool wasHold(const uint8_t kidx) const
Did the specified key become "holding" during this update?
Definition unit_Tab5Keyboard.hpp:679
bool isCtrl() const
Is the Ctrl modifier currently pressed?
Definition unit_Tab5Keyboard.hpp:743
bool changeI2CAddress(const uint8_t i2c_address)
Write a new I2C address to flash and update the active bus address.
Definition unit_Tab5Keyboard.cpp:642
bool readInterruptStatus(bool &normal, bool &hid, bool &character)
Read per-mode interrupt pending status from REG_INT_STAT (0x01)
Definition unit_Tab5Keyboard.cpp:592
bool read_event_for_mode(const tab5_keyboard::Mode mode, tab5_keyboard::Event &evt)
Read one event from device for the given mode, fill evt. Returns false on I/O error.
Definition unit_Tab5Keyboard.cpp:899
bool isRepeating() const
Did any key fire a software-repeat tick during this update?
Definition unit_Tab5Keyboard.hpp:629
bool readRgb(const uint8_t idx, uint8_t &r, uint8_t &g, uint8_t &b)
Read current RGB color of one LED in Custom mode buffer.
Definition unit_Tab5Keyboard.cpp:841
bool wasPressed(const uint8_t kidx) const
Did the specified key get pressed this update?
Definition unit_Tab5Keyboard.hpp:652
void remove_irq_pin(const int8_t pin)
Remove isr_handler and reset _irq_pin_configured for a given pin.
Definition unit_Tab5Keyboard.cpp:373
bool readI2CAddress(uint8_t &addr)
Read the current I2C address stored in flash (REG_I2C_ADDRESS 0xFF)
Definition unit_Tab5Keyboard.cpp:636
bool readFirmwareVersion(uint8_t &ver)
Read the firmware version from REG_FIRMWARE_VERSION (0xFE)
Definition unit_Tab5Keyboard.cpp:630
bool isPressed(const uint8_t kidx) const
Returns false when kidx >= KEY_COUNT (defensive, no assert).
Definition unit_Tab5Keyboard.hpp:643
bool readEventCount(uint8_t &count)
Read the pending event count from REG_EVENT_NUM (0x02)
Definition unit_Tab5Keyboard.cpp:802
char keyMatrixToChar(const uint8_t row, const uint8_t col) const
Convenience wrappers that combine the static HID lookup tables (keyMatrixToHidBase / keyMatrixToHidSy...
Definition unit_Tab5Keyboard.cpp:258
bool readMode(tab5_keyboard::Mode &mode)
Read the keyboard operation mode from REG_MODE_KEYBOARD (0x10)
Definition unit_Tab5Keyboard.cpp:662
void config(const config_t &cfg)
Sets the configuration.
Definition unit_Tab5Keyboard.hpp:373
bool isRepeating(const uint8_t kidx) const
Did the specified key fire a software-repeat tick during this update?
Definition unit_Tab5Keyboard.hpp:688
bool wasPressed(const uint8_t row, const uint8_t col) const
Did the specified key get pressed this update?
Definition unit_Tab5Keyboard.hpp:702
bool configure_irq_pin()
Configure gpio_config + isr_handler_add for _cfg.irq_pin.
Definition unit_Tab5Keyboard.cpp:369
const tab5_keyboard::key_status_bits_t & previousBits() const
Snapshot of nowBits() taken at the end of the previous update()
Definition unit_Tab5Keyboard.hpp:570
bool isHolding() const
Is any key currently being held (press duration >= holding_threshold_ms)?
Definition unit_Tab5Keyboard.hpp:619
const tab5_keyboard::key_status_bits_t & holdingBits() const
Bits of keys whose press duration has reached holding_threshold_ms.
Definition unit_Tab5Keyboard.hpp:585
virtual void update(const bool force=false) override
Definition unit_Tab5Keyboard.cpp:522
const tab5_keyboard::key_status_bits_t & wasHoldBits() const
Bits of keys that became "holding" during this update (one-shot)
Definition unit_Tab5Keyboard.hpp:590
bool wasReleased(const uint8_t row, const uint8_t col) const
Did the specified key get released this update?
Definition unit_Tab5Keyboard.hpp:707
const tab5_keyboard::key_status_bits_t & releasedBits() const
Bits of keys that transitioned from pressed to released this update.
Definition unit_Tab5Keyboard.hpp:580
bool wasReleased() const
Did any key get released (pressed-to-released transition) this update?
Definition unit_Tab5Keyboard.hpp:614
const tab5_keyboard::key_status_bits_t & pressedBits() const
Bits of keys that transitioned from released to pressed this update.
Definition unit_Tab5Keyboard.hpp:575
bool isPressed(const uint8_t row, const uint8_t col) const
Is the specified key currently pressed?
Definition unit_Tab5Keyboard.hpp:697
bool writeBrightness(const uint8_t pct)
Write global RGB brightness to REG_BRIGHTNESS (0x03)
Definition unit_Tab5Keyboard.cpp:826
bool wasReleased(const uint8_t kidx) const
Did the specified key get released this update?
Definition unit_Tab5Keyboard.hpp:661
bool readRgbMode(tab5_keyboard::RgbMode &mode)
Read the RGB LED operation mode from REG_MODE_RGB (0x11)
Definition unit_Tab5Keyboard.cpp:698
virtual bool begin() override
Definition unit_Tab5Keyboard.cpp:383
bool wasHold() const
Did any key become "holding" during this update? (one-shot)
Definition unit_Tab5Keyboard.hpp:624
bool wasHold(const uint8_t row, const uint8_t col) const
Did the specified key become "holding" during this update?
Definition unit_Tab5Keyboard.hpp:717
bool isSym() const
Equivalent to isPressed(KIDX_<name>). Guarded by bitwise_active(), so these return false in HID/Chara...
Definition unit_Tab5Keyboard.hpp:733
bool writeRgbMode(const tab5_keyboard::RgbMode mode)
Write the RGB LED operation mode to REG_MODE_RGB (0x11)
Definition unit_Tab5Keyboard.cpp:714
static void IRAM_ATTR isr_handler(void *arg)
ESP-IDF GPIO ISR handler (IRAM-safe, minimal work)
Definition unit_Tab5Keyboard.cpp:366
bool isHolding(const uint8_t row, const uint8_t col) const
Is the specified key currently being held?
Definition unit_Tab5Keyboard.hpp:712
const tab5_keyboard::key_status_bits_t & nowBits() const
Per-key state tracking exposed as std::bitset<KEY_COUNT> snapshots. HID and Character modes never upd...
Definition unit_Tab5Keyboard.hpp:565
bool writeRgb(const uint8_t idx, const uint8_t r, const uint8_t g, const uint8_t b)
Write RGB color for one LED.
Definition unit_Tab5Keyboard.cpp:812
bool isRepeating(const uint8_t row, const uint8_t col) const
Did the specified key fire a software-repeat tick during this update?
Definition unit_Tab5Keyboard.hpp:722
bool writeMode(const tab5_keyboard::Mode mode)
Write the keyboard operation mode to REG_MODE_KEYBOARD (0x10)
Definition unit_Tab5Keyboard.cpp:679
bool writeInterruptEnable(const bool normal, const bool hid, const bool character)
Configure per-mode interrupt enable (REG_INT_CFG 0x00)
Definition unit_Tab5Keyboard.cpp:564
bool readBrightness(uint8_t &pct)
Read current RGB global brightness from REG_BRIGHTNESS (0x03)
Definition unit_Tab5Keyboard.cpp:835
bool isAa() const
Is the Aa modifier currently pressed?
Definition unit_Tab5Keyboard.hpp:738
config_t config() const
Gets the configuration.
Definition unit_Tab5Keyboard.hpp:368
bool isAlt() const
Is the Alt modifier currently pressed?
Definition unit_Tab5Keyboard.hpp:748
bool readInterruptEnable(bool &normal, bool &hid, bool &character)
Read per-mode interrupt enable bits from REG_INT_CFG (0x00)
Definition unit_Tab5Keyboard.cpp:575
bool clearInterrupt()
Clear all interrupt status bits in REG_INT_STAT (0x01) by writing 0x00.
Definition unit_Tab5Keyboard.cpp:609
bool isPressed() const
Is any key currently pressed?
Definition unit_Tab5Keyboard.hpp:604
const tab5_keyboard::key_status_bits_t & repeatingBits() const
Bits of keys for which a software-repeat tick fired this update.
Definition unit_Tab5Keyboard.hpp:595
bool wasPressed() const
Did any key get pressed (released-to-pressed transition) this update?
Definition unit_Tab5Keyboard.hpp:609
bool clearEventQueue()
Clear the current-mode event queue and release INT signal.
Definition unit_Tab5Keyboard.cpp:615
bool isHolding(const uint8_t kidx) const
Is the specified key currently being held?
Definition unit_Tab5Keyboard.hpp:670
uint8_t firmwareVersion() const
Get the firmware version cached by begin()
Definition unit_Tab5Keyboard.hpp:554
Top level namespace of M5Stack.
Constants and types for Tab5 Keyboard.
Settings for begin.
Definition unit_Tab5Keyboard.hpp:317
bool software_repeat
Definition unit_Tab5Keyboard.hpp:341
uint32_t interval_ms
Definition unit_Tab5Keyboard.hpp:335
uint32_t repeat_initial_ms
Definition unit_Tab5Keyboard.hpp:345
tab5_keyboard::Mode mode
Definition unit_Tab5Keyboard.hpp:325
uint32_t repeat_rate_ms
Interval between subsequent repeat events (milliseconds).
Definition unit_Tab5Keyboard.hpp:347
bool start_periodic
Definition unit_Tab5Keyboard.hpp:322
uint32_t holding_threshold_ms
Definition unit_Tab5Keyboard.hpp:351
int8_t irq_pin
Definition unit_Tab5Keyboard.hpp:330
Unified event payload for all 3 operation modes (tagged union, POD)
Definition unit_Tab5Keyboard.hpp:187
char chars[CHAR_EVENT_MAX_CHARS+1]
Always NUL-terminated; printf("%s") safe.
Definition unit_Tab5Keyboard.hpp:199
struct m5::unit::tab5_keyboard::Event::@0::@2 chr
Character mode payload.
struct m5::unit::tab5_keyboard::Event::@0::@4 hid
HID mode payload.
bool isAlt() const
True if the Alt modifier is held (modifier bit 0x04 or 0x40)
Definition unit_Tab5Keyboard.hpp:232
bool repeat
True when this event was synthesized by software auto-repeat.
Definition unit_Tab5Keyboard.hpp:194
uint8_t length
Number of valid bytes in chars (0..CHAR_EVENT_MAX_CHARS)
Definition unit_Tab5Keyboard.hpp:198
bool isCtrl() const
True if the Ctrl modifier is held (modifier bit 0x01 or 0x10)
Definition unit_Tab5Keyboard.hpp:215
bool isShift() const
True if a Shift modifier is held (modifier bit 0x02 or 0x20)
Definition unit_Tab5Keyboard.hpp:224
struct m5::unit::tab5_keyboard::Event::@0::@3 key
Normal mode payload.
uint8_t modifier
Definition unit_Tab5Keyboard.hpp:189
HID Usage Code + base modifier byte for a Tab5 Keyboard matrix position.
Definition unit_Tab5Keyboard.hpp:145
uint8_t keycode
HID Usage Code (USB HID Keyboard Page 0x07); 0 = unmapped.
Definition unit_Tab5Keyboard.hpp:146
uint8_t modifier
Base HID modifier byte (e.g. 0x02 if firmware forces shift)
Definition unit_Tab5Keyboard.hpp:147
HidMapping keyMatrixToHidBase(const uint8_t row, const uint8_t col)
Base (no Sym held) HID mapping for the given (row, col)
Definition unit_Tab5Keyboard.cpp:231
HidMapping keyMatrixToHidSym(const uint8_t row, const uint8_t col)
Sym-held variant of the HID mapping for the given (row, col)
Definition unit_Tab5Keyboard.cpp:239
constexpr uint8_t MODIFIER_KEY_ROW_CTRL
Ctrl key row.
Definition unit_Tab5Keyboard.hpp:86
constexpr uint8_t KIDX_ALT
57 (Alt)
Definition unit_Tab5Keyboard.hpp:134
constexpr uint8_t KEY_COUNT
Total number of keys in the Tab5 Keyboard matrix (5 rows x 14 cols)
Definition unit_Tab5Keyboard.hpp:109
uint8_t toKeyIndex(const uint8_t row, const uint8_t col)
Convert (row, col) to flat key index (0..KEY_COUNT-1)
Definition unit_Tab5Keyboard.hpp:124
constexpr uint8_t KIDX_AA
43 (Aa)
Definition unit_Tab5Keyboard.hpp:132
constexpr uint8_t MODIFIER_KEY_COL_ALT
Alt key column.
Definition unit_Tab5Keyboard.hpp:89
Mode
Keyboard operation mode (REG_MODE_KEYBOARD 0x10)
Definition unit_Tab5Keyboard.hpp:245
@ HID
HID mode: returns HID modifier + keycode.
@ Normal
Normal mode: returns matrix coordinate events (5 rows x 14 cols)
EventType
Discriminator for tab5_keyboard::Event tagged union.
Definition unit_Tab5Keyboard.hpp:175
@ None
No event (queue empty sentinel)
@ Character
Character mode: modifier + UTF-8 string (<=9 bytes)
@ Key
Normal mode: matrix coordinate event.
@ Hid
HID mode: modifier + keycode.
constexpr uint8_t MODIFIER_KEY_COL_AA
Aa key column.
Definition unit_Tab5Keyboard.hpp:85
constexpr uint32_t DEFAULT_STORED_SIZE
Default internal CircularBuffer<Event> capacity (~256 bytes total)
Definition unit_Tab5Keyboard.hpp:239
constexpr uint8_t MODIFIER_KEY_ROW_SYM
Hardware-confirmed (row, col) of the four modifier keys. In Normal mode these arrive as ordinary Key ...
Definition unit_Tab5Keyboard.hpp:82
constexpr uint32_t I2C_ADDRESS_WRITE_DELAY_MS
Milliseconds to wait after writing I2C address to REG_I2C_ADDRESS (datasheet: Flash erase ~20 ms; use...
Definition unit_Tab5Keyboard.hpp:72
constexpr uint8_t KIDX_SYM
42 (Sym)
Definition unit_Tab5Keyboard.hpp:131
constexpr uint8_t KEY_EVENT_EMPTY
Sentinel value returned when the Normal-mode event queue is empty.
Definition unit_Tab5Keyboard.hpp:65
constexpr uint8_t CHAR_EVENT_MAX_CHARS
Maximum character payload length in one CHAR_EVENT (char0..char8)
Definition unit_Tab5Keyboard.hpp:68
std::bitset< KEY_COUNT > key_status_bits_t
Bitset type for tracking per-key state (Normal mode)
Definition unit_Tab5Keyboard.hpp:115
constexpr uint8_t RGB_LED_COUNT
Number of RGB LEDs on the device.
Definition unit_Tab5Keyboard.hpp:75
constexpr uint8_t MODIFIER_KEY_COL_CTRL
Ctrl key column.
Definition unit_Tab5Keyboard.hpp:87
RgbMode
RGB LED operation mode (REG_MODE_RGB 0x11)
Definition unit_Tab5Keyboard.hpp:255
constexpr uint8_t MODIFIER_KEY_COL_SYM
Sym key column.
Definition unit_Tab5Keyboard.hpp:83
constexpr uint8_t MODIFIER_KEY_ROW_AA
Aa key row.
Definition unit_Tab5Keyboard.hpp:84
constexpr uint8_t MODIFIER_KEY_ROW_ALT
Alt key row.
Definition unit_Tab5Keyboard.hpp:88
constexpr uint8_t KIDX_CTRL
56 (Ctrl)
Definition unit_Tab5Keyboard.hpp:133
bool isModifierKey(const uint8_t row, const uint8_t col)
True if the given (row, col) corresponds to a modifier key (Sym/Aa/Ctrl/Alt)
Definition unit_Tab5Keyboard.hpp:100
constexpr uint8_t KEY_COL_COUNT
Number of columns in the Tab5 Keyboard matrix.
Definition unit_Tab5Keyboard.hpp:112