-
-
Notifications
You must be signed in to change notification settings - Fork 25
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
LilyGo T-Deck keyboard support & display driver improvements (#19)
* LilyGo T-Deck keyboard support * reverse logic * docs and readability * cleanup * optimize driver buffer * cleanup
- Loading branch information
1 parent
14eb432
commit ccbe6b7
Showing
21 changed files
with
302 additions
and
73 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,61 @@ | ||
#include "esp_log.h" | ||
#include "driver/gpio.h" | ||
#include "config.h" | ||
#include "keyboard.h" | ||
#include "kernel.h" | ||
#include "esp_lvgl_port.h" | ||
#include "log.h" | ||
|
||
#define TAG "lilygo_tdeck_bootstrap" | ||
#define TDECK_PERI_POWERON GPIO_NUM_10 | ||
#define TAG "tdeck_bootstrap" | ||
|
||
lv_disp_t* lilygo_tdeck_init_display(); | ||
|
||
static void tdeck_power_on() { | ||
static bool tdeck_power_on() { | ||
ESP_LOGI(TAG, "power on"); | ||
gpio_config_t device_power_signal_config = { | ||
.pin_bit_mask = BIT64(TDECK_PERI_POWERON), | ||
.pin_bit_mask = BIT64(TDECK_POWERON_GPIO), | ||
.mode = GPIO_MODE_OUTPUT, | ||
.pull_up_en = GPIO_PULLUP_DISABLE, | ||
.pull_down_en = GPIO_PULLDOWN_DISABLE, | ||
.intr_type = GPIO_INTR_DISABLE, | ||
}; | ||
gpio_config(&device_power_signal_config); | ||
gpio_set_level(TDECK_PERI_POWERON, 1); | ||
|
||
if (gpio_config(&device_power_signal_config) != ESP_OK) { | ||
return false; | ||
} | ||
|
||
if (gpio_set_level(TDECK_POWERON_GPIO, 1) != ESP_OK) { | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
void lilygo_tdeck_bootstrap() { | ||
tdeck_power_on(); | ||
static bool init_i2c() { | ||
const i2c_config_t i2c_conf = { | ||
.mode = I2C_MODE_MASTER, | ||
.sda_io_num = GPIO_NUM_18, | ||
.sda_pullup_en = GPIO_PULLUP_DISABLE, | ||
.scl_io_num = GPIO_NUM_8, | ||
.scl_pullup_en = GPIO_PULLUP_DISABLE, | ||
.master.clk_speed = 400000 | ||
}; | ||
|
||
return i2c_param_config(TDECK_I2C_BUS_HANDLE, &i2c_conf) == ESP_OK | ||
&& i2c_driver_install(TDECK_I2C_BUS_HANDLE, i2c_conf.mode, 0, 0, 0) == ESP_OK; | ||
} | ||
|
||
bool lilygo_tdeck_bootstrap() { | ||
if (!tdeck_power_on()) { | ||
TT_LOG_E(TAG, "failed to power on device"); | ||
} | ||
|
||
// Give keyboard's ESP time to boot | ||
// It uses I2C and seems to interfere with the touch driver | ||
tt_delay_ms(500); | ||
|
||
if (!init_i2c()) { | ||
TT_LOG_E(TAG, "failed to init I2C"); | ||
} | ||
|
||
keyboard_wait_for_response(); | ||
|
||
return true; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#pragma once | ||
|
||
#include "driver/i2c.h" | ||
#include "driver/gpio.h" | ||
|
||
#define TDECK_I2C_BUS_HANDLE (0) | ||
#define TDECK_POWERON_GPIO GPIO_NUM_10 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
#include "keyboard.h" | ||
#include "config.h" | ||
#include "hal/lv_hal.h" | ||
#include "tactility_core.h" | ||
#include "ui/lvgl_keypad.h" | ||
#include <driver/i2c.h> | ||
|
||
#define TAG "tdeck_keyboard" | ||
#define KEYBOARD_SLAVE_ADDRESS 0x55 | ||
|
||
typedef struct { | ||
lv_indev_drv_t* driver; | ||
lv_indev_t* device; | ||
} KeyboardData; | ||
|
||
static inline esp_err_t keyboard_i2c_read(uint8_t* output) { | ||
return i2c_master_read_from_device( | ||
TDECK_I2C_BUS_HANDLE, | ||
KEYBOARD_SLAVE_ADDRESS, | ||
output, | ||
1, | ||
configTICK_RATE_HZ / 10 | ||
); | ||
} | ||
|
||
void keyboard_wait_for_response() { | ||
TT_LOG_I(TAG, "wake await..."); | ||
bool awake = false; | ||
uint8_t read_buffer = 0x00; | ||
do { | ||
awake = keyboard_i2c_read(&read_buffer) == ESP_OK; | ||
if (!awake) { | ||
tt_delay_ms(100); | ||
} | ||
} while (!awake); | ||
TT_LOG_I(TAG, "awake"); | ||
} | ||
|
||
/** | ||
* The callback simulates press and release events, because the T-Deck | ||
* keyboard only publishes press events on I2C. | ||
* LVGL currently works without those extra release events, but they | ||
* are implemented for correctness and future compatibility. | ||
* | ||
* @param indev_drv | ||
* @param data | ||
*/ | ||
static void keyboard_read_callback(TT_UNUSED struct _lv_indev_drv_t* indev_drv, lv_indev_data_t* data) { | ||
static uint8_t last_buffer = 0x00; | ||
uint8_t read_buffer = 0x00; | ||
|
||
// Defaults | ||
data->key = 0; | ||
data->state = LV_INDEV_STATE_RELEASED; | ||
|
||
if (keyboard_i2c_read(&read_buffer) == ESP_OK) { | ||
if (read_buffer == 0 && read_buffer != last_buffer) { | ||
TT_LOG_I(TAG, "released %d", last_buffer); | ||
data->key = last_buffer; | ||
data->state = LV_INDEV_STATE_RELEASED; | ||
} else if (read_buffer != 0) { | ||
TT_LOG_I(TAG, "pressed %d", read_buffer); | ||
data->key = read_buffer; | ||
data->state = LV_INDEV_STATE_PRESSED; | ||
} | ||
} | ||
|
||
last_buffer = read_buffer; | ||
} | ||
|
||
Keyboard keyboard_alloc(_Nullable lv_disp_t* display) { | ||
KeyboardData* data = malloc(sizeof(KeyboardData)); | ||
|
||
data->driver = malloc(sizeof(lv_indev_drv_t)); | ||
memset(data->driver, 0, sizeof(lv_indev_drv_t)); | ||
lv_indev_drv_init(data->driver); | ||
|
||
data->driver->type = LV_INDEV_TYPE_KEYPAD; | ||
data->driver->read_cb = &keyboard_read_callback; | ||
data->driver->disp = display; | ||
|
||
data->device = lv_indev_drv_register(data->driver); | ||
tt_check(data->device != NULL); | ||
|
||
tt_lvgl_keypad_set_indev(data->device); | ||
|
||
return data; | ||
} | ||
|
||
void keyboard_free(Keyboard keyboard) { | ||
KeyboardData* data = (KeyboardData*)keyboard; | ||
lv_indev_delete(data->device); | ||
free(data->driver); | ||
free(data); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#pragma once | ||
|
||
#include "lvgl.h" | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
void keyboard_wait_for_response(); | ||
|
||
typedef void* Keyboard; | ||
|
||
Keyboard keyboard_alloc(_Nullable lv_disp_t* display); | ||
void keyboard_free(Keyboard keyboard); | ||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.