Implement new I2C driver (#531)
This commit is contained in:
committed by
GitHub
parent
8dd9bee8d0
commit
8dabda2b5b
@@ -14,11 +14,12 @@ using namespace tt::hal;
|
||||
static constexpr auto* TAG = "Tab5";
|
||||
|
||||
static DeviceVector createDevices() {
|
||||
::Device* i2c2 = device_find_by_name("i2c2");
|
||||
return {
|
||||
createPower(),
|
||||
createDisplay(),
|
||||
createSdCard(),
|
||||
std::make_shared<Tab5Keyboard>()
|
||||
std::make_shared<Tab5Keyboard>(i2c2)
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -13,7 +13,9 @@
|
||||
|
||||
static const auto LOGGER = tt::Logger("Tab5Display");
|
||||
|
||||
constexpr auto LCD_PIN_RESET = GPIO_NUM_0; // Match P4 EV board reset line
|
||||
// LCD reset is wired to the PI4IOE5V6408 IO expander (io_expander0, bit 4), pulsed in
|
||||
// Configuration.cpp's initExpander0() before display creation - not a direct SoC GPIO.
|
||||
constexpr auto LCD_PIN_RESET = GPIO_NUM_NC;
|
||||
constexpr auto LCD_PIN_BACKLIGHT = GPIO_NUM_22;
|
||||
|
||||
static std::shared_ptr<tt::hal::touch::TouchDevice> createGt911Touch() {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#include "Tab5Keyboard.h"
|
||||
#include <Tactility/app/App.h>
|
||||
#include <tactility/drivers/i2c_controller.h>
|
||||
#include <tactility/log.h>
|
||||
#include <esp_timer.h>
|
||||
#include <lvgl.h>
|
||||
|
||||
@@ -135,19 +137,14 @@ static uint32_t tab5TranslateKey(uint8_t keycode, uint8_t modifier, bool ctrl) {
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// I2C helpers - direct i2c_master API (LP_I2C_NUM_0, GPIO 0/1)
|
||||
// I2C helpers - use Tactility I2C controller API
|
||||
// ---------------------------------------------------------------------------
|
||||
bool Tab5Keyboard::readReg(uint8_t reg, uint8_t& value) const {
|
||||
if (!i2cDev) return false;
|
||||
const esp_err_t err = i2c_master_transmit_receive(i2cDev, ®, 1, &value, 1, pdMS_TO_TICKS(50));
|
||||
return err == ESP_OK;
|
||||
bool Tab5Keyboard::readReg(uint8_t reg, uint8_t& value) {
|
||||
return i2c_controller_read_register(i2cController, I2C_ADDRESS, reg, &value, 1, pdMS_TO_TICKS(50)) == ERROR_NONE;
|
||||
}
|
||||
|
||||
bool Tab5Keyboard::writeReg(uint8_t reg, uint8_t value) const {
|
||||
if (!i2cDev) return false;
|
||||
const uint8_t buf[2] = { reg, value };
|
||||
const esp_err_t err = i2c_master_transmit(i2cDev, buf, 2, pdMS_TO_TICKS(50));
|
||||
return err == ESP_OK;
|
||||
bool Tab5Keyboard::writeReg(uint8_t reg, uint8_t value) {
|
||||
return i2c_controller_write_register(i2cController, I2C_ADDRESS, reg, &value, 1, pdMS_TO_TICKS(50)) == ERROR_NONE;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -161,11 +158,7 @@ void Tab5Keyboard::updateLeds() {
|
||||
0x00, 0x00, aaSticky ? uint8_t(0xA0) : uint8_t(0x00), // LED1: red if Aa latched
|
||||
};
|
||||
// Write 7-byte block starting at REG_RGB_BASE
|
||||
const uint8_t reg = REG_RGB_BASE;
|
||||
uint8_t tx[8];
|
||||
tx[0] = reg;
|
||||
for (int i = 0; i < 7; i++) tx[i + 1] = buf[i];
|
||||
i2c_master_transmit(i2cDev, tx, 8, pdMS_TO_TICKS(50));
|
||||
i2c_controller_write_register(i2cController, I2C_ADDRESS, REG_RGB_BASE, buf, 7, pdMS_TO_TICKS(50));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -371,41 +364,10 @@ bool Tab5Keyboard::startLvgl(lv_display_t* display) {
|
||||
LOG_E("Tab5Keyboard", "Input queue allocation failed — cannot start");
|
||||
return false;
|
||||
}
|
||||
// Create LP I2C master bus (LP_I2C_NUM_0, GPIO 0/1) via new i2c_master API
|
||||
i2c_master_bus_config_t bus_cfg = {
|
||||
.i2c_port = LP_I2C_NUM_0,
|
||||
.sda_io_num = GPIO_NUM_0,
|
||||
.scl_io_num = GPIO_NUM_1,
|
||||
.clk_source = static_cast<i2c_clock_source_t>(LP_I2C_SCLK_DEFAULT),
|
||||
.glitch_ignore_cnt = 7,
|
||||
.intr_priority = 0,
|
||||
.trans_queue_depth = 0,
|
||||
.flags = { .enable_internal_pullup = true },
|
||||
};
|
||||
if (i2c_new_master_bus(&bus_cfg, &i2cBus) != ESP_OK) {
|
||||
LOG_E("Tab5Keyboard", "Failed to create LP I2C master bus");
|
||||
return false;
|
||||
}
|
||||
|
||||
i2c_device_config_t dev_cfg = {
|
||||
.dev_addr_length = I2C_ADDR_BIT_LEN_7,
|
||||
.device_address = I2C_ADDRESS,
|
||||
.scl_speed_hz = 100000,
|
||||
};
|
||||
if (i2c_master_bus_add_device(i2cBus, &dev_cfg, &i2cDev) != ESP_OK) {
|
||||
LOG_E("Tab5Keyboard", "Failed to add keyboard device to LP I2C bus");
|
||||
i2c_del_master_bus(i2cBus);
|
||||
i2cBus = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Set Normal mode explicitly — device may power up in a different mode
|
||||
if (!writeReg(REG_KEYBOARD_MODE, 0x00)) {
|
||||
LOG_E("Tab5Keyboard", "Failed to set keyboard mode");
|
||||
i2c_master_bus_rm_device(i2cDev);
|
||||
i2c_del_master_bus(i2cBus);
|
||||
i2cDev = nullptr;
|
||||
i2cBus = nullptr;
|
||||
return false;
|
||||
}
|
||||
writeReg(REG_EVENT_NUM, 0x00); // flush event queue
|
||||
@@ -426,10 +388,6 @@ bool Tab5Keyboard::startLvgl(lv_display_t* display) {
|
||||
// Enable Normal-mode interrupt (bit 0)
|
||||
if (!writeReg(REG_INT_CFG, 0x01)) {
|
||||
LOG_E("Tab5Keyboard", "Failed to configure interrupt register");
|
||||
i2c_master_bus_rm_device(i2cDev);
|
||||
i2c_del_master_bus(i2cBus);
|
||||
i2cDev = nullptr;
|
||||
i2cBus = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -470,38 +428,9 @@ bool Tab5Keyboard::stopLvgl() {
|
||||
lv_indev_delete(kbHandle);
|
||||
kbHandle = nullptr;
|
||||
|
||||
if (i2cDev) {
|
||||
i2c_master_bus_rm_device(i2cDev);
|
||||
i2cDev = nullptr;
|
||||
}
|
||||
if (i2cBus) {
|
||||
i2c_del_master_bus(i2cBus);
|
||||
i2cBus = nullptr;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Tab5Keyboard::isAttached() const {
|
||||
// If already started, just probe via the open bus handle
|
||||
if (i2cBus) {
|
||||
return i2c_master_probe(i2cBus, I2C_ADDRESS, pdMS_TO_TICKS(100)) == ESP_OK;
|
||||
}
|
||||
// Otherwise open a temporary bus to probe (LP I2C is not accessible via legacy API)
|
||||
i2c_master_bus_config_t bus_cfg = {
|
||||
.i2c_port = LP_I2C_NUM_0,
|
||||
.sda_io_num = GPIO_NUM_0,
|
||||
.scl_io_num = GPIO_NUM_1,
|
||||
.clk_source = static_cast<i2c_clock_source_t>(LP_I2C_SCLK_DEFAULT),
|
||||
.glitch_ignore_cnt = 7,
|
||||
.intr_priority = 0,
|
||||
.trans_queue_depth = 0,
|
||||
.flags = { .enable_internal_pullup = true },
|
||||
};
|
||||
i2c_master_bus_handle_t probe_bus = nullptr;
|
||||
if (i2c_new_master_bus(&bus_cfg, &probe_bus) != ESP_OK) {
|
||||
return false;
|
||||
}
|
||||
const esp_err_t ret = i2c_master_probe(probe_bus, I2C_ADDRESS, pdMS_TO_TICKS(100));
|
||||
i2c_del_master_bus(probe_bus);
|
||||
return ret == ESP_OK;
|
||||
return i2c_controller_has_device_at_address(i2cController, I2C_ADDRESS, pdMS_TO_TICKS(100)) == ERROR_NONE;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include <Tactility/hal/keyboard/KeyboardDevice.h>
|
||||
#include <Tactility/Timer.h>
|
||||
#include <driver/i2c_master.h>
|
||||
#include <tactility/device.h>
|
||||
#include <driver/gpio.h>
|
||||
#include <freertos/queue.h>
|
||||
|
||||
@@ -13,8 +13,7 @@ class Tab5Keyboard final : public tt::hal::keyboard::KeyboardDevice {
|
||||
static constexpr uint32_t REPEAT_INITIAL_MS = 400;
|
||||
static constexpr uint32_t REPEAT_RATE_MS = 80;
|
||||
|
||||
i2c_master_bus_handle_t i2cBus = nullptr;
|
||||
i2c_master_dev_handle_t i2cDev = nullptr;
|
||||
::Device* i2cController = nullptr;
|
||||
|
||||
lv_indev_t* kbHandle = nullptr;
|
||||
QueueHandle_t queue = nullptr;
|
||||
@@ -37,8 +36,8 @@ class Tab5Keyboard final : public tt::hal::keyboard::KeyboardDevice {
|
||||
uint32_t repeatStartMs = 0;
|
||||
uint32_t repeatLastMs = 0;
|
||||
|
||||
bool readReg(uint8_t reg, uint8_t& value) const;
|
||||
bool writeReg(uint8_t reg, uint8_t value) const;
|
||||
bool readReg(uint8_t reg, uint8_t& value);
|
||||
bool writeReg(uint8_t reg, uint8_t value);
|
||||
void updateLeds();
|
||||
|
||||
bool configureIrqPin();
|
||||
@@ -50,7 +49,7 @@ class Tab5Keyboard final : public tt::hal::keyboard::KeyboardDevice {
|
||||
static void readCallback(lv_indev_t* indev, lv_indev_data_t* data);
|
||||
|
||||
public:
|
||||
Tab5Keyboard() {
|
||||
explicit Tab5Keyboard(::Device* i2cController) : i2cController(i2cController) {
|
||||
queue = xQueueCreate(20, sizeof(uint32_t));
|
||||
// queue == nullptr on OOM; startLvgl() checks and refuses to start
|
||||
}
|
||||
|
||||
@@ -49,5 +49,3 @@ CONFIG_CACHE_L2_CACHE_256KB=y
|
||||
CONFIG_LVGL_PORT_ENABLE_PPA=y
|
||||
CONFIG_LV_DRAW_BUF_ALIGN=64
|
||||
CONFIG_LV_DEF_REFR_PERIOD=15
|
||||
# Allow new i2c_master API (used by Tab5Keyboard for LP_I2C_NUM_0) to coexist with legacy i2c driver
|
||||
CONFIG_I2C_SKIP_LEGACY_CONFLICT_CHECK=y
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include <tactility/bindings/esp32_ble.h>
|
||||
#include <tactility/bindings/esp32_gpio.h>
|
||||
#include <tactility/bindings/esp32_i2c.h>
|
||||
#include <tactility/bindings/esp32_i2c_master.h>
|
||||
#include <tactility/bindings/esp32_i2s.h>
|
||||
#include <tactility/bindings/esp32_spi.h>
|
||||
#include <tactility/bindings/esp32_uart.h>
|
||||
@@ -68,6 +69,15 @@
|
||||
pin-scl = <&gpio0 54 GPIO_FLAG_NONE>;
|
||||
};
|
||||
|
||||
i2c_keyboard: i2c2 {
|
||||
compatible = "espressif,esp32-i2c-master";
|
||||
port = <LP_I2C_NUM_0>;
|
||||
clock-frequency = <100000>;
|
||||
clock-source = <LP_I2C_SCLK_DEFAULT>;
|
||||
pin-sda = <&gpio0 0 GPIO_FLAG_PULL_UP>;
|
||||
pin-scl = <&gpio0 1 GPIO_FLAG_PULL_UP>;
|
||||
};
|
||||
|
||||
sdcard_spi: spi0 {
|
||||
compatible = "espressif,esp32-spi";
|
||||
host = <SPI2_HOST>;
|
||||
|
||||
Reference in New Issue
Block a user