Files
AutoFilm-ESP32/components/hal_input/hal_input_gt911.c

117 lines
3.2 KiB
C

#include "hal_input.h"
#include <string.h>
#include "board.h"
#include "driver/gpio.h"
#include "driver/i2c.h"
#include "esp_log.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#define TP_I2C I2C_NUM_0
#define TP_ADDR 0x5D
#define GT_REG_STAT 0x814E
#define GT_REG_PT0 0x8150
static const char *TAG = "gt911";
static bool s_have;
static ui_raw_touch_t s_last;
static uint8_t s_prev_stat;
static esp_err_t tp_write(uint16_t reg, const uint8_t *data, size_t n)
{
uint8_t buf[8];
if (n + 2 > sizeof(buf)) {
return ESP_ERR_INVALID_SIZE;
}
buf[0] = (uint8_t)(reg >> 8);
buf[1] = (uint8_t)reg;
if (n && data) {
memcpy(buf + 2, data, n);
}
return i2c_master_write_to_device(TP_I2C, TP_ADDR, buf, n + 2, pdMS_TO_TICKS(50));
}
static esp_err_t tp_read(uint16_t reg, uint8_t *data, size_t n)
{
uint8_t addr[2] = { (uint8_t)(reg >> 8), (uint8_t)reg };
return i2c_master_write_read_device(TP_I2C, TP_ADDR, addr, 2, data, n, pdMS_TO_TICKS(50));
}
void hal_input_init(void)
{
gpio_config_t io = {
.pin_bit_mask = (1ULL << board_pin_tp_rst()) | (1ULL << board_pin_tp_int()),
.mode = GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_DISABLE,
.pull_down_en = GPIO_PULLDOWN_DISABLE,
.intr_type = GPIO_INTR_DISABLE,
};
gpio_config(&io);
gpio_set_level(board_pin_tp_int(), 0);
gpio_set_level(board_pin_tp_rst(), 0);
vTaskDelay(pdMS_TO_TICKS(200));
gpio_set_level(board_pin_tp_rst(), 1);
vTaskDelay(pdMS_TO_TICKS(20));
io.mode = GPIO_MODE_INPUT;
io.pin_bit_mask = 1ULL << board_pin_tp_int();
gpio_config(&io);
i2c_config_t conf = {
.mode = I2C_MODE_MASTER,
.sda_io_num = board_pin_tp_sda(),
.scl_io_num = board_pin_tp_scl(),
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE,
.master.clk_speed = 400000,
};
i2c_param_config(TP_I2C, &conf);
i2c_driver_install(TP_I2C, conf.mode, 0, 0, 0);
ESP_LOGI(TAG, "GT911 addr=0x5D SDA=%d SCL=%d RST=%d INT=%d",
(int)board_pin_tp_sda(), (int)board_pin_tp_scl(),
(int)board_pin_tp_rst(), (int)board_pin_tp_int());
}
bool hal_input_pop_key(ui_raw_key_t *out)
{
(void)out;
return false;
}
bool hal_input_pop_touch(ui_raw_touch_t *out)
{
uint8_t stat = 0;
if (tp_read(GT_REG_STAT, &stat, 1) != ESP_OK) {
return false;
}
if ((stat & 0x80) == 0) {
return false;
}
uint8_t n = stat & 0x0F;
uint8_t raw[8];
if (n > 0 && tp_read(GT_REG_PT0, raw, 8) == ESP_OK) {
int16_t x = (int16_t)(raw[0] | ((uint16_t)raw[1] << 8));
int16_t y = (int16_t)(raw[2] | ((uint16_t)raw[3] << 8));
uint8_t zero = 0;
tp_write(GT_REG_STAT, &zero, 1);
/* Edge: report once per contact start. */
if (s_prev_stat == 0) {
s_last.x = x;
s_last.y = y;
s_prev_stat = n;
if (out) {
*out = s_last;
}
return true;
}
s_prev_stat = n;
return false;
}
uint8_t zero = 0;
tp_write(GT_REG_STAT, &zero, 1);
s_prev_stat = 0;
(void)s_have;
return false;
}