10static constexpr uint32_t POLL_INTERVAL_MS = 50;
17 if (!this->
read_byte(TCA8418_REG_CFG, &config)) {
18 ESP_LOGE(TAG,
"Failed to read from device - check wiring / address");
24 ESP_LOGE(TAG,
"Failed to configure pins");
30 if (!this->
write_byte(TCA8418_REG_CFG, TCA8418_CFG_KEY_INT_EN | TCA8418_CFG_INT_CFG)) {
31 ESP_LOGE(TAG,
"Failed to write the configuration register");
46 ESP_LOGE(TAG,
"Failed to clear the event queue");
59 uint8_t matrix[3] = {0, 0, 0};
60 if (this->
rows_ > 0) {
61 matrix[0] =
static_cast<uint8_t
>((1U << this->
rows_) - 1U);
63 matrix[1] =
static_cast<uint8_t
>((1U << low_columns) - 1U);
65 matrix[2] =
static_cast<uint8_t
>((1U << (this->
columns_ - 8U)) - 1U);
70 const uint8_t gpi[3] = {
71 static_cast<uint8_t
>(this->
gpi_events_ ? ~matrix[0] : 0),
72 static_cast<uint8_t
>(this->
gpi_events_ ? ~matrix[1] : 0),
73 static_cast<uint8_t
>(this->
gpi_events_ ? (0x03 & ~matrix[2]) : 0),
76 for (uint8_t i = 0; i < 3; i++) {
79 if (!this->
write_byte(TCA8418_REG_GPIO_PULL1 + i, 0x00) || !this->
write_byte(TCA8418_REG_KP_GPIO1 + i, matrix[i]) ||
80 !this->
write_byte(TCA8418_REG_GPI_EM1 + i, gpi[i]) || !this->
write_byte(TCA8418_REG_GPIO_INT_EN1 + i, gpi[i])) {
108 count &= TCA8418_EVENT_COUNT_MASK;
113 if (dispatch &&
count >= TCA8418_FIFO_DEPTH) {
114 ESP_LOGW(TAG,
"Event queue is full - some key presses may have been lost");
118 for (uint8_t i = 0; i <
count; i++) {
119 if (!this->
read_byte(TCA8418_REG_KEY_EVENT_A, &event))
122 this->
dispatch_(event & TCA8418_KEY_CODE_MASK, (event & TCA8418_KEY_PRESSED) != 0);
124 return this->
write_byte(TCA8418_REG_INT_STAT, TCA8418_INT_STAT_ALL);
134 ESP_LOGV(TAG,
"Key %u %s", key, pressed ? LOG_STR_LITERAL(
"pressed") : LOG_STR_LITERAL(
"released"));
136#ifdef TCA8418_LISTENER_COUNT
139 listener->key_pressed(key);
141 listener->key_released(key);
151 const uint8_t key_char = this->
key_char_(key);
152 this->
send_key_(key_char != 0 ? key_char : key);
158 " Individual inputs: %s",
160 if (this->
rows_ > 0) {
161 ESP_LOGCONFIG(TAG,
" Key matrix: %u rows x %u columns", this->
rows_, this->
columns_);
164 LOG_I2C_DEVICE(
this);
166 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
uint32_t IRAM_ATTR HOT get_loop_component_start_time() const
Get the cached time in milliseconds from when the current component started its loop execution.
void mark_failed()
Mark this component as failed.
void status_set_warning()
void enable_loop_soon_any_context()
Thread and ISR-safe version of enable_loop() that can be called from any context.
void disable_loop()
Disable this component's loop.
void status_clear_warning()
void attach_interrupt(void(*func)(T *), T *arg, gpio::InterruptType type) const
bool digital_read() override
bool write_byte(uint8_t a_register, uint8_t data) const
bool read_byte(uint8_t a_register, uint8_t *data)
void send_key_(uint8_t key)
static void IRAM_ATTR interrupt_handler(TCA8418Component *arg)
Wakes the loop so queued events are read. Runs in interrupt context.
bool configure_pins_()
Write the matrix / individual-input pin configuration. Returns false on I2C failure.
InternalGPIOPin * interrupt_pin_
StaticVector< TCA8418Listener *, TCA8418_LISTENER_COUNT > listeners_
bool drain_events_(bool dispatch)
Read every queued key event, dispatching them if asked, then clear the interrupt flags.
uint8_t key_char_(uint8_t key) const
The character mapped to a matrix key, or 0 when it has none.
void dispatch_(uint8_t key, bool pressed)
void dump_config() override
ESPHOME_LOG_TAG(TAG, "tca8418")
Application App
Global storage of Application pointer - only one Application can exist.
uint8_t progmem_read_byte(const uint8_t *addr)