M5Unit-KEYBOARD 0.1.0 git rev:b58d024
Loading...
Searching...
No Matches
m5::unit::UnitTab5Keyboard Class Reference

Tab5 built-in keyboard unit connected via I2C ExtPort1. More...

#include <unit_Tab5Keyboard.hpp>

Inheritance diagram for m5::unit::UnitTab5Keyboard:
m5::unit::UnitKeyboard

Classes

struct  config_t
 Settings for begin. More...
 

Public Member Functions

 UnitTab5Keyboard (const uint8_t addr=DEFAULT_ADDRESS)
 
virtual bool begin () override
 
virtual void update (const bool force=false) override
 
uint8_t firmwareVersion () const
 Get the firmware version cached by begin()
 
Settings for begin
config_t config () const
 Gets the configuration.
 
void config (const config_t &cfg)
 Sets the configuration.
 
Interrupt enable / status
bool writeInterruptEnable (const bool normal, const bool hid, const bool character)
 Configure per-mode interrupt enable (REG_INT_CFG 0x00)
 
bool readInterruptEnable (bool &normal, bool &hid, bool &character)
 Read per-mode interrupt enable bits from REG_INT_CFG (0x00)
 
bool readInterruptStatus (bool &normal, bool &hid, bool &character)
 Read per-mode interrupt pending status from REG_INT_STAT (0x01)
 
bool clearInterrupt ()
 Clear all interrupt status bits in REG_INT_STAT (0x01) by writing 0x00.
 
bool clearEventQueue ()
 Clear the current-mode event queue and release INT signal.
 
Firmware / device info
bool readFirmwareVersion (uint8_t &ver)
 Read the firmware version from REG_FIRMWARE_VERSION (0xFE)
 
bool readI2CAddress (uint8_t &addr)
 Read the current I2C address stored in flash (REG_I2C_ADDRESS 0xFF)
 
bool changeI2CAddress (const uint8_t i2c_address)
 Write a new I2C address to flash and update the active bus address.
 
Keyboard mode
bool readMode (tab5_keyboard::Mode &mode)
 Read the keyboard operation mode from REG_MODE_KEYBOARD (0x10)
 
bool writeMode (const tab5_keyboard::Mode mode)
 Write the keyboard operation mode to REG_MODE_KEYBOARD (0x10)
 
bool readRgbMode (tab5_keyboard::RgbMode &mode)
 Read the RGB LED operation mode from REG_MODE_RGB (0x11)
 
bool writeRgbMode (const tab5_keyboard::RgbMode mode)
 Write the RGB LED operation mode to REG_MODE_RGB (0x11)
 
Event reading
bool readEventCount (uint8_t &count)
 Read the pending event count from REG_EVENT_NUM (0x02)
 
RGB LED control (custom mode only)
bool writeRgb (const uint8_t idx, const uint8_t r, const uint8_t g, const uint8_t b)
 Write RGB color for one LED.
 
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.
 
Brightness
bool writeBrightness (const uint8_t pct)
 Write global RGB brightness to REG_BRIGHTNESS (0x03)
 
bool readBrightness (uint8_t &pct)
 Read current RGB global brightness from REG_BRIGHTNESS (0x03)
 
Bitwise key state (Normal mode only)
const tab5_keyboard::key_status_bits_tnowBits () const
 Per-key state tracking exposed as std::bitset<KEY_COUNT> snapshots. HID and Character modes never update these bitsets, so all queries return empty / false in those modes.
 
const tab5_keyboard::key_status_bits_tpreviousBits () const
 Snapshot of nowBits() taken at the end of the previous update()
 
const tab5_keyboard::key_status_bits_tpressedBits () const
 Bits of keys that transitioned from released to pressed this update.
 
const tab5_keyboard::key_status_bits_treleasedBits () const
 Bits of keys that transitioned from pressed to released this update.
 
const tab5_keyboard::key_status_bits_tholdingBits () const
 Bits of keys whose press duration has reached holding_threshold_ms.
 
const tab5_keyboard::key_status_bits_twasHoldBits () const
 Bits of keys that became "holding" during this update (one-shot)
 
const tab5_keyboard::key_status_bits_trepeatingBits () const
 Bits of keys for which a software-repeat tick fired this update.
 
Any-key state queries (no arguments)
bool isPressed () const
 Is any key currently pressed?
 
bool wasPressed () const
 Did any key get pressed (released-to-pressed transition) this update?
 
bool wasReleased () const
 Did any key get released (pressed-to-released transition) this update?
 
bool isHolding () const
 Is any key currently being held (press duration >= holding_threshold_ms)?
 
bool wasHold () const
 Did any key become "holding" during this update? (one-shot)
 
bool isRepeating () const
 Did any key fire a software-repeat tick during this update?
 
Per-key state queries (by flat key index)
bool isPressed (const uint8_t kidx) const
 Returns false when kidx >= KEY_COUNT (defensive, no assert).
 
bool wasPressed (const uint8_t kidx) const
 Did the specified key get pressed this update?
 
bool wasReleased (const uint8_t kidx) const
 Did the specified key get released this update?
 
bool isHolding (const uint8_t kidx) const
 Is the specified key currently being held?
 
bool wasHold (const uint8_t kidx) const
 Did the specified key become "holding" during this update?
 
bool isRepeating (const uint8_t kidx) const
 Did the specified key fire a software-repeat tick during this update?
 
Per-key state queries (by (row, col))
bool isPressed (const uint8_t row, const uint8_t col) const
 Is the specified key currently pressed?
 
bool wasPressed (const uint8_t row, const uint8_t col) const
 Did the specified key get pressed this update?
 
bool wasReleased (const uint8_t row, const uint8_t col) const
 Did the specified key get released this update?
 
bool isHolding (const uint8_t row, const uint8_t col) const
 Is the specified key currently being held?
 
bool wasHold (const uint8_t row, const uint8_t col) const
 Did the specified key become "holding" during this update?
 
bool isRepeating (const uint8_t row, const uint8_t col) const
 Did the specified key fire a software-repeat tick during this update?
 
Modifier shortcuts (Normal mode only)
bool isSym () const
 Equivalent to isPressed(KIDX_<name>). Guarded by bitwise_active(), so these return false in HID/Character modes (where _state is not tracked).
 
bool isAa () const
 Is the Aa modifier currently pressed?
 
bool isCtrl () const
 Is the Ctrl modifier currently pressed?
 
bool isAlt () const
 Is the Alt modifier currently pressed?
 
(row, col) → ASCII conversion (Normal mode only)
char keyMatrixToChar (const uint8_t row, const uint8_t col) const
 Convenience wrappers that combine the static HID lookup tables (keyMatrixToHidBase / keyMatrixToHidSym) with the current Sym/Aa state stored in nowBits() and dispatch through hidUsageToChar().
 
char keyMatrixToChar (const uint8_t kidx) const
 Convert a flat key index (0..KEY_COUNT-1) to its ASCII character.
 
- Public Member Functions inherited from m5::unit::UnitKeyboard
 UnitKeyboard (const uint8_t addr=DEFAULT_ADDRESS)
 
virtual char getchar () const
 Gets the input character.
 
virtual uint8_t released () const
 Gets the released key character code if updated.
 

Protected Member Functions

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.
 
bool start_periodic_measurement ()
 
bool stop_periodic_measurement ()
 
bool configure_irq_pin ()
 Configure gpio_config + isr_handler_add for _cfg.irq_pin.
 
void remove_irq_pin (const int8_t pin)
 Remove isr_handler and reset _irq_pin_configured for a given pin.
 

Static Protected Member Functions

static void IRAM_ATTR isr_handler (void *arg)
 ESP-IDF GPIO ISR handler (IRAM-safe, minimal work)
 

Friends

class ::TestTab5Keyboard
 

Detailed Description

Tab5 built-in keyboard unit connected via I2C ExtPort1.

The Tab5 Keyboard provides a 5-row x 14-column key matrix with three operation modes: Normal (coordinate), HID (modifier+keycode), and Character (modifier+string). Two RGB indicator LEDs and an active-low INT pin are also provided.

INT pin usage is optional. When configured via config_t::irq_pin, begin() installs an ESP-IDF GPIO ISR (NEGEDGE) that sets _irq_pending. update() reads events when _irq_pending is true or gpio_get_level() == 0 (level still asserted). Without a configured pin, update() polls unconditionally.

Note
Modifiers: Sym / Aa / Ctrl / Alt (no Fn key).
Default I2C address 0x6D (range 0x08-0x77, datasheet-configurable via REG_I2C_ADDRESS).
ExtPort1 pin assignment: INT=GPIO50, SDA=GPIO0, SCL=GPIO1.
Multiple UnitTab5Keyboard instances share the same gpio_install_isr_service(); already-installed state is treated as OK (ESP_ERR_INVALID_STATE accepted).

Member Function Documentation

◆ begin()

bool m5::unit::UnitTab5Keyboard::begin ( )
overridevirtual

Reimplemented from m5::unit::UnitKeyboard.

◆ changeI2CAddress()

bool m5::unit::UnitTab5Keyboard::changeI2CAddress ( const uint8_t i2c_address)

Write a new I2C address to flash and update the active bus address.

Parameters
i2c_addressNew I2C address (0x08-0x77)
Returns
True if successful
Note
Flash storage must be erased before writing (~20 ms). This function blocks for I2C_ADDRESS_WRITE_DELAY_MS after writing. The new address takes effect immediately and is stored in the internal Flash.
Warning
To prolong Flash lifetime, avoid frequent writes. The firmware skips the actual write if the value matches the current Flash contents.

◆ clearEventQueue()

bool m5::unit::UnitTab5Keyboard::clearEventQueue ( )

Clear the current-mode event queue and release INT signal.

Writes 0 to REG_EVENT_NUM (0x02). Per datasheet: "writing 0 clears current mode queue and releases interrupt signal". Internal CircularBuffer is also flushed for consistency.

Returns
True if I2C write succeeded

◆ clearInterrupt()

bool m5::unit::UnitTab5Keyboard::clearInterrupt ( )

Clear all interrupt status bits in REG_INT_STAT (0x01) by writing 0x00.

Returns
True if successful
Note
Datasheet: writing 0 releases the INT signal and clears the status. This call clears all pending modes (Normal, HID, Character) in a single write.

◆ configure_irq_pin()

bool m5::unit::UnitTab5Keyboard::configure_irq_pin ( )
protected

Configure gpio_config + isr_handler_add for _cfg.irq_pin.

Returns
true if successful; false on failure (caller should fallback to polling)

◆ firmwareVersion()

uint8_t m5::unit::UnitTab5Keyboard::firmwareVersion ( ) const
inline

Get the firmware version cached by begin()

Return values
Firmwareversion byte (0 if begin() has not yet succeeded)

◆ isHolding()

bool m5::unit::UnitTab5Keyboard::isHolding ( const uint8_t kidx) const
inline

Is the specified key currently being held?

Parameters
kidxFlat key index (0..KEY_COUNT-1)
Returns
True if the key has passed the hold threshold and is still held

◆ isPressed()

bool m5::unit::UnitTab5Keyboard::isPressed ( const uint8_t kidx) const
inline

Returns false when kidx >= KEY_COUNT (defensive, no assert).

Is the specified key currently pressed?

Parameters
kidxFlat key index (0..KEY_COUNT-1)
Returns
True if the key is currently held down

◆ isr_handler()

void m5::unit::UnitTab5Keyboard::isr_handler ( void * arg)
staticprotected

ESP-IDF GPIO ISR handler (IRAM-safe, minimal work)

Parameters
argPointer to the owning UnitTab5Keyboard instance

◆ isRepeating()

bool m5::unit::UnitTab5Keyboard::isRepeating ( const uint8_t kidx) const
inline

Did the specified key fire a software-repeat tick during this update?

Parameters
kidxFlat key index (0..KEY_COUNT-1)
Returns
True if a software repeat event fired this update

◆ isSym()

bool m5::unit::UnitTab5Keyboard::isSym ( ) const
inline

Equivalent to isPressed(KIDX_<name>). Guarded by bitwise_active(), so these return false in HID/Character modes (where _state is not tracked).

Is the Sym modifier currently pressed?

◆ keyMatrixToChar() [1/2]

char m5::unit::UnitTab5Keyboard::keyMatrixToChar ( const uint8_t kidx) const

Convert a flat key index (0..KEY_COUNT-1) to its ASCII character.

Parameters
kidxFlat key index
Return values
!=0Printable / whitespace ASCII character
0Out-of-range, modifier key, or non-printable HID code

◆ keyMatrixToChar() [2/2]

char m5::unit::UnitTab5Keyboard::keyMatrixToChar ( const uint8_t row,
const uint8_t col ) const

Convenience wrappers that combine the static HID lookup tables (keyMatrixToHidBase / keyMatrixToHidSym) with the current Sym/Aa state stored in nowBits() and dispatch through hidUsageToChar().

Convert a matrix coordinate to its ASCII character using the currently-held modifier state.

Parameters
rowMatrix row (0..4)
colMatrix column (0..13)
Return values
!=0Printable / whitespace ASCII character
0Out-of-range, modifier key, or non-printable HID code
Note
Reads nowBits() to determine Sym/Aa state. In HID and Character modes nowBits() stays empty, so this always returns 0 there.
Aa is treated as Shift (OR 0x02 into the HID modifier byte). Sym selects the alternate (Sym) lookup table.

◆ nowBits()

const tab5_keyboard::key_status_bits_t & m5::unit::UnitTab5Keyboard::nowBits ( ) const
inline

Per-key state tracking exposed as std::bitset<KEY_COUNT> snapshots. HID and Character modes never update these bitsets, so all queries return empty / false in those modes.

Bits of the keys currently pressed

◆ read_event_for_mode()

bool m5::unit::UnitTab5Keyboard::read_event_for_mode ( const tab5_keyboard::Mode mode,
tab5_keyboard::Event & evt )
protected

Read one event from device for the given mode, fill evt. Returns false on I/O error.

Note
If queue is empty, sets evt.type = EventType::None and returns true.

◆ readBrightness()

bool m5::unit::UnitTab5Keyboard::readBrightness ( uint8_t & pct)

Read current RGB global brightness from REG_BRIGHTNESS (0x03)

Parameters
[out]pctBrightness 0-100 (default 20 per datasheet)
Returns
True if I2C read succeeded

◆ readEventCount()

bool m5::unit::UnitTab5Keyboard::readEventCount ( uint8_t & count)

Read the pending event count from REG_EVENT_NUM (0x02)

Parameters
[out]countNumber of pending events in the current mode's queue (0-32)
Returns
True if successful

◆ readFirmwareVersion()

bool m5::unit::UnitTab5Keyboard::readFirmwareVersion ( uint8_t & ver)

Read the firmware version from REG_FIRMWARE_VERSION (0xFE)

Parameters
[out]verFirmware version byte
Returns
True if successful

◆ readI2CAddress()

bool m5::unit::UnitTab5Keyboard::readI2CAddress ( uint8_t & addr)

Read the current I2C address stored in flash (REG_I2C_ADDRESS 0xFF)

Parameters
[out]addrI2C address (0x08-0x77)
Returns
True if successful

◆ readInterruptEnable()

bool m5::unit::UnitTab5Keyboard::readInterruptEnable ( bool & normal,
bool & hid,
bool & character )

Read per-mode interrupt enable bits from REG_INT_CFG (0x00)

Parameters
[out]normalTrue if Normal mode INT enabled (bit 0)
[out]hidTrue if HID mode INT enabled (bit 1)
[out]characterTrue if Character mode INT enabled (bit 2)
Returns
True if I2C read succeeded

◆ readInterruptStatus()

bool m5::unit::UnitTab5Keyboard::readInterruptStatus ( bool & normal,
bool & hid,
bool & character )

Read per-mode interrupt pending status from REG_INT_STAT (0x01)

Parameters
[out]normalTrue if a Normal mode interrupt is pending (bit 0)
[out]hidTrue if a HID mode interrupt is pending (bit 1)
[out]characterTrue if a Character mode interrupt is pending (bit 2)
Returns
True if I2C read succeeded
Note
REG_INT_STAT (pending) is distinct from REG_INT_CFG (enable, see readInterruptEnable()).

◆ readMode()

bool m5::unit::UnitTab5Keyboard::readMode ( tab5_keyboard::Mode & mode)

Read the keyboard operation mode from REG_MODE_KEYBOARD (0x10)

Parameters
[out]modeCurrent keyboard mode
Returns
True if successful

◆ readRgb()

bool m5::unit::UnitTab5Keyboard::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.

Parameters
idxLED index: 0 = RGB1 (left), 1 = RGB2 (right)
[out]rRed component (0-255)
[out]gGreen component (0-255)
[out]bBlue component (0-255)
Returns
True if idx valid and I2C reads succeeded
Note
Reads from REG_RGB1_B/G/R or REG_RGB2_B/G/R (skipping 0x63 gap)

◆ readRgbMode()

bool m5::unit::UnitTab5Keyboard::readRgbMode ( tab5_keyboard::RgbMode & mode)

Read the RGB LED operation mode from REG_MODE_RGB (0x11)

Parameters
[out]modeCurrent RGB mode
Returns
True if successful

◆ remove_irq_pin()

void m5::unit::UnitTab5Keyboard::remove_irq_pin ( const int8_t pin)
protected

Remove isr_handler and reset _irq_pin_configured for a given pin.

Parameters
pinPin to remove (-1 is a no-op)

◆ update()

void m5::unit::UnitTab5Keyboard::update ( const bool force = false)
overridevirtual

Reimplemented from m5::unit::UnitKeyboard.

◆ wasHold()

bool m5::unit::UnitTab5Keyboard::wasHold ( const uint8_t kidx) const
inline

Did the specified key become "holding" during this update?

Parameters
kidxFlat key index (0..KEY_COUNT-1)
Returns
True if the hold threshold was crossed this update

◆ wasPressed()

bool m5::unit::UnitTab5Keyboard::wasPressed ( const uint8_t kidx) const
inline

Did the specified key get pressed this update?

Parameters
kidxFlat key index (0..KEY_COUNT-1)
Returns
True if a press transition occurred this update

◆ wasReleased()

bool m5::unit::UnitTab5Keyboard::wasReleased ( const uint8_t kidx) const
inline

Did the specified key get released this update?

Parameters
kidxFlat key index (0..KEY_COUNT-1)
Returns
True if a release transition occurred this update

◆ writeBrightness()

bool m5::unit::UnitTab5Keyboard::writeBrightness ( const uint8_t pct)

Write global RGB brightness to REG_BRIGHTNESS (0x03)

Parameters
pctBrightness percentage (0-100)
Returns
True if successful

◆ writeInterruptEnable()

bool m5::unit::UnitTab5Keyboard::writeInterruptEnable ( const bool normal,
const bool hid,
const bool character )

Configure per-mode interrupt enable (REG_INT_CFG 0x00)

Parameters
normalEnable INT for Normal mode events (bit 0)
hidEnable INT for HID mode events (bit 1)
characterEnable INT for Character mode events (bit 2)
Returns
True if successful
Note
Default register value is 0x07 (all modes enabled).

◆ writeMode()

bool m5::unit::UnitTab5Keyboard::writeMode ( const tab5_keyboard::Mode mode)

Write the keyboard operation mode to REG_MODE_KEYBOARD (0x10)

Parameters
modeTarget keyboard mode
Returns
True if successful
Note
Mode switch clears the previous mode's event queue and releases the INT signal.

◆ writeRgb()

bool m5::unit::UnitTab5Keyboard::writeRgb ( const uint8_t idx,
const uint8_t r,
const uint8_t g,
const uint8_t b )

Write RGB color for one LED.

Parameters
idxLED index: 0 = RGB1 (left, base address 0x60), 1 = RGB2 (right, base address 0x64)
rRed component (0-255)
gGreen component (0-255)
bBlue component (0-255)
Returns
True if successful
Note
Effective only when RgbMode::Custom is active.
Register layout: RGB1 uses 0x60(B)/0x61(G)/0x62(R); RGB2 uses 0x64(B)/0x65(G)/0x66(R). 0x63 is unused (gap between RGB1 and RGB2).
The B/G/R byte order follows the datasheet register map. Verify on actual hardware if colors appear incorrect (possible R/B swap in firmware).

◆ writeRgbMode()

bool m5::unit::UnitTab5Keyboard::writeRgbMode ( const tab5_keyboard::RgbMode mode)

Write the RGB LED operation mode to REG_MODE_RGB (0x11)

Parameters
modeTarget RGB mode
Returns
True if successful