115 lines
3.2 KiB
C
115 lines
3.2 KiB
C
#include "touch.h"
|
|
|
|
#include "board_config.h"
|
|
|
|
#include "driver/gpio.h"
|
|
#include "driver/i2c_master.h"
|
|
#include "esp_lcd_io_i2c.h"
|
|
#include "esp_lcd_panel_io.h"
|
|
#include "esp_lcd_touch.h"
|
|
#include "esp_lcd_touch_cst816s.h"
|
|
#include "esp_log.h"
|
|
#include "freertos/FreeRTOS.h"
|
|
#include "freertos/semphr.h"
|
|
#include "freertos/task.h"
|
|
|
|
static const char *TAG = "touch";
|
|
|
|
#if BOARD_TOUCH_ENABLED
|
|
|
|
static i2c_master_bus_handle_t s_touch_i2c_bus;
|
|
static esp_lcd_touch_handle_t s_touch_handle;
|
|
static SemaphoreHandle_t s_touch_mux;
|
|
|
|
static void touch_isr_cb(esp_lcd_touch_handle_t tp)
|
|
{
|
|
BaseType_t task_woken = pdFALSE;
|
|
(void)tp;
|
|
xSemaphoreGiveFromISR(s_touch_mux, &task_woken);
|
|
if (task_woken) {
|
|
portYIELD_FROM_ISR();
|
|
}
|
|
}
|
|
|
|
static void lvgl_touch_read_cb(lv_indev_t *indev, lv_indev_data_t *data)
|
|
{
|
|
esp_lcd_touch_handle_t tp = lv_indev_get_user_data(indev);
|
|
|
|
if (xSemaphoreTake(s_touch_mux, 0) == pdTRUE) {
|
|
esp_lcd_touch_read_data(tp);
|
|
}
|
|
|
|
esp_lcd_touch_point_data_t points[1];
|
|
uint8_t point_cnt = 0;
|
|
if (esp_lcd_touch_get_data(tp, points, &point_cnt, 1) == ESP_OK && point_cnt > 0) {
|
|
data->point.x = points[0].x;
|
|
data->point.y = points[0].y;
|
|
data->state = LV_INDEV_STATE_PRESSED;
|
|
} else {
|
|
data->state = LV_INDEV_STATE_RELEASED;
|
|
}
|
|
}
|
|
|
|
esp_err_t touch_init(lv_display_t *display)
|
|
{
|
|
ESP_LOGI(TAG, "Initialize I2C for touch");
|
|
i2c_master_bus_config_t bus_config = {
|
|
.clk_source = I2C_CLK_SRC_DEFAULT,
|
|
.i2c_port = BOARD_TOUCH_I2C_NUM,
|
|
.sda_io_num = BOARD_PIN_TOUCH_SDA,
|
|
.scl_io_num = BOARD_PIN_TOUCH_SCL,
|
|
.glitch_ignore_cnt = 7,
|
|
.flags.enable_internal_pullup = true,
|
|
};
|
|
ESP_ERROR_CHECK(i2c_new_master_bus(&bus_config, &s_touch_i2c_bus));
|
|
|
|
s_touch_mux = xSemaphoreCreateBinary();
|
|
if (s_touch_mux == NULL) {
|
|
ESP_LOGE(TAG, "Failed to create touch semaphore");
|
|
return ESP_ERR_NO_MEM;
|
|
}
|
|
|
|
ESP_LOGI(TAG, "Initialize touch panel IO (CST816S)");
|
|
esp_lcd_panel_io_handle_t tp_io_handle = NULL;
|
|
esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_CST816S_CONFIG();
|
|
tp_io_config.scl_speed_hz = BOARD_TOUCH_I2C_FREQ_HZ;
|
|
ESP_ERROR_CHECK(esp_lcd_new_panel_io_i2c(s_touch_i2c_bus, &tp_io_config, &tp_io_handle));
|
|
|
|
ESP_LOGI(TAG, "Initialize touch controller CST816S");
|
|
esp_lcd_touch_config_t tp_cfg = {
|
|
.x_max = BOARD_LCD_H_RES,
|
|
.y_max = BOARD_LCD_V_RES,
|
|
.rst_gpio_num = BOARD_PIN_TOUCH_RST,
|
|
.int_gpio_num = BOARD_PIN_TOUCH_INT,
|
|
.levels = {
|
|
.reset = 0,
|
|
.interrupt = 0,
|
|
},
|
|
.flags = {
|
|
.swap_xy = BOARD_TOUCH_SWAP_XY,
|
|
.mirror_x = BOARD_TOUCH_MIRROR_X,
|
|
.mirror_y = BOARD_TOUCH_MIRROR_Y,
|
|
},
|
|
.interrupt_callback = touch_isr_cb,
|
|
};
|
|
ESP_ERROR_CHECK(esp_lcd_touch_new_i2c_cst816s(tp_io_handle, &tp_cfg, &s_touch_handle));
|
|
|
|
lv_indev_t *indev = lv_indev_create();
|
|
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
|
|
lv_indev_set_display(indev, display);
|
|
lv_indev_set_user_data(indev, s_touch_handle);
|
|
lv_indev_set_read_cb(indev, lvgl_touch_read_cb);
|
|
|
|
return ESP_OK;
|
|
}
|
|
|
|
#else
|
|
|
|
esp_err_t touch_init(lv_display_t *display)
|
|
{
|
|
(void)display;
|
|
return ESP_OK;
|
|
}
|
|
|
|
#endif
|