451 lines
12 KiB
C
451 lines
12 KiB
C
/*----------------------------------------------------------------------------
|
||
* Copyright (c) TJD Technologies Co., Ltd. 2024. All rights reserved.
|
||
*
|
||
* Description: tp_port_ctrl.c
|
||
*
|
||
* Author: luziquan@ss-tjd.com
|
||
*
|
||
* Create: 2024-04-22
|
||
*--------------------------------------------------------------------------*/
|
||
|
||
#include "tp_port_ctrl.h"
|
||
#include "app_at_process.h"
|
||
#include "cmsis_os2.h"
|
||
#include "common_def.h"
|
||
#include "common_i2c.h"
|
||
#include "common_pm.h"
|
||
#include "hal_gpio.h"
|
||
#include "input_app.h"
|
||
#include "osal_addr.h"
|
||
#include "pm_definition.h"
|
||
#include "product.h"
|
||
#include "rtc.h"
|
||
#include "sql_setting.h"
|
||
#include "sys_config.h"
|
||
#include "task_driver_event.h"
|
||
#include "touch_screen_def.h"
|
||
#include "tp_api.h"
|
||
|
||
#ifdef HAS_TP_DRV_FT6146
|
||
#include "tp_drv_ft6146.h"
|
||
#endif
|
||
#ifdef HAS_TP_DRV_CST820
|
||
#include "tp_drv_cst820.h"
|
||
#endif
|
||
|
||
#define ENABLE_PRINT_INFO 1
|
||
#if ENABLE_PRINT_INFO
|
||
#define static_print_info(...) sys_tp_log_i(__VA_ARGS__) // 一般信息打印宏控制
|
||
#define static_print_warn(...) sys_tp_log_w(__VA_ARGS__) // 警告信息打印一般常开
|
||
#define static_print_error(...) sys_tp_log_e(__VA_ARGS__) // 错误信息打印一般常开
|
||
#else
|
||
#define static_print_info(...)
|
||
#define static_print_warn(...)
|
||
#define static_print_error(...)
|
||
#endif
|
||
|
||
typedef struct
|
||
{
|
||
signed int (*func_event_handler)(void *param); // 事件处理函数
|
||
void *param; // 事件处理函数入参
|
||
void (*func_event_debug)(char *str, ...); // 打印
|
||
void *payload;
|
||
} tp_driver_event_info_t;
|
||
|
||
static bool g_tp_host_dev_init_flag = TD_FALSE;
|
||
static touch_callback g_tp_callback = NULL;
|
||
static tp_touch_event g_touch_callback = NULL;
|
||
|
||
static uint8_t g_tp_send_buf[4] = {0};
|
||
static uint8_t g_tp_recv_buf[TP_INPUT_SIZE] = {0};
|
||
|
||
void tp_delay(uint32_t ms) { osDelay(ms); }
|
||
|
||
void tp_open(void)
|
||
{
|
||
const struct power_manager_class_ops *power_manager_ops = tjd_driver_common_pm_get_ops();
|
||
power_manager_ops->set_model_power_status(POWER_MODEL_SCREEN_ID, PM_POWER_STATUS_ON);
|
||
tp_delay(300);
|
||
static_print_info("TOUCH: tp open success!");
|
||
}
|
||
|
||
void tp_close(void)
|
||
{
|
||
// const struct power_manager_class_ops *power_manager_ops = tjd_driver_common_pm_get_ops();
|
||
// power_manager_ops->set_model_power_status(POWER_MODEL_SCREEN_ID, PM_POWER_STATUS_OFF);
|
||
tp_delay(100);
|
||
static_print_info("TOUCH: tp close success!");
|
||
}
|
||
|
||
void tp_reset(void)
|
||
{
|
||
uapi_gpio_set_val(TP_RESET_GPIO, GPIO_LEVEL_LOW);
|
||
tp_delay(15);
|
||
uapi_gpio_set_val(TP_RESET_GPIO, GPIO_LEVEL_HIGH);
|
||
tp_delay(100);
|
||
}
|
||
|
||
static ext_errno tp_peripheral_init_status_check(void)
|
||
{
|
||
if (g_tp_host_dev_init_flag != TD_TRUE) {
|
||
return EXT_ERR_TP_DEV_INFO_NOT_REGISTER;
|
||
}
|
||
|
||
return EXT_ERR_SUCCESS;
|
||
}
|
||
|
||
void tjd_driver_tp_set_wakeup_enable(uint8_t enable)
|
||
{
|
||
#if (TJD_TP_FT6146)
|
||
// TODO: 没调ft6146的设置接口
|
||
// ft6146_set_gesture_wakeup_enable(enable);
|
||
#elif (TJD_TP_CST820)
|
||
cst820_set_gesture_wakeup_enable(enable);
|
||
#endif
|
||
}
|
||
|
||
void tjd_driver_tp_register_touch_event(tp_touch_event func) { g_touch_callback = func; }
|
||
|
||
void tjd_driver_tp_unregister_touch_event(void) { g_touch_callback = NULL; };
|
||
|
||
ext_errno device_touch_init(void *attr)
|
||
{
|
||
ext_errno ret = EXT_ERR_SUCCESS;
|
||
tp_ctrl_ops *tp_ops = (tp_ctrl_ops *)tjd_driver_tp_get_peri_attr();
|
||
ret = tp_ops->bus_init(&tp_ops->attr);
|
||
|
||
#if (TJD_TP_FT6146)
|
||
ret = ft6146_init();
|
||
if (ret != EXT_ERR_SUCCESS) {
|
||
static_print_error("TOUCH: ft6146 init fail! ret=0x%x", ret);
|
||
return ret;
|
||
}
|
||
#elif (TJD_TP_CST820)
|
||
ret = cst820_init();
|
||
if (ret != EXT_ERR_SUCCESS) {
|
||
static_print_error("TOUCH: cst820 init fail! ret=0x%x", ret);
|
||
return ret;
|
||
}
|
||
#endif
|
||
return EXT_ERR_SUCCESS;
|
||
}
|
||
|
||
#if defined(TJD_BOARD_ENABLE)
|
||
static uint16_t last_dev_addr = 0;
|
||
static void check_dev_addr(uint16_t dev_addr)
|
||
{
|
||
if (last_dev_addr != dev_addr) {
|
||
last_dev_addr = dev_addr;
|
||
tjd_driver_common_i2c_get_ops()->set_dev_addr(I2C_MODEL_TP_ID, dev_addr);
|
||
}
|
||
}
|
||
|
||
ext_errno tp_i2c_cmd_write(uint16_t dev_addr, uint8_t cmd)
|
||
{
|
||
errcode_t ret;
|
||
uint8_t retry;
|
||
i2c_data_t data;
|
||
check_dev_addr(dev_addr);
|
||
|
||
ret = tp_peripheral_init_status_check();
|
||
if (ret != EXT_ERR_SUCCESS) {
|
||
static_print_error("TOUCH: host peripheral not init! ret=0x%x", ret);
|
||
return ret;
|
||
}
|
||
g_tp_send_buf[TP_I2C_SEND_INDEX0] = cmd;
|
||
|
||
data.send_buf = g_tp_send_buf;
|
||
data.send_len = 1;
|
||
data.receive_buf = NULL;
|
||
data.receive_len = 0;
|
||
|
||
for (retry = 0; retry < TP_I2C_TIME_MAX; retry++) {
|
||
ret = tjd_driver_common_i2c_get_ops()->write(I2C_MODEL_TP_ID, &data);
|
||
if (ret == ERRCODE_SUCC) {
|
||
break;
|
||
}
|
||
}
|
||
if (ret != ERRCODE_SUCC) {
|
||
return ret;
|
||
}
|
||
return EXT_ERR_SUCCESS;
|
||
}
|
||
|
||
ext_errno tp_i2c_data_write(uint16_t dev_addr, uint8_t reg_addr, uint8_t *data_buf, uint32_t data_len)
|
||
{
|
||
errcode_t ret;
|
||
uint8_t retry;
|
||
i2c_data_t data;
|
||
uint32_t send_len;
|
||
uint8_t *write_data = NULL;
|
||
check_dev_addr(dev_addr);
|
||
|
||
ret = tp_peripheral_init_status_check();
|
||
if (ret != 0) {
|
||
static_print_error("TOUCH: host peripheral not init! ret=0x%x", ret);
|
||
return ret;
|
||
}
|
||
|
||
send_len = data_len + sizeof(uint8_t);
|
||
|
||
write_data = (uint8_t *)osal_kmalloc(send_len, OSAL_GFP_KERNEL);
|
||
if (write_data == NULL) {
|
||
static_print_error("TOUCH: tp send buff malloc fail!");
|
||
return EXT_ERR_MALLOC_FAILURE;
|
||
}
|
||
|
||
write_data[TP_I2C_SEND_INDEX0] = reg_addr;
|
||
|
||
ret = (uint32_t)memcpy_s(write_data + sizeof(uint8_t), send_len - sizeof(uint8_t), data_buf, data_len);
|
||
if (ret != EOK) {
|
||
static_print_error("TOUCH: tp send_buf content copy fail! ret=0x%x", ret);
|
||
osal_kfree(write_data);
|
||
return ret;
|
||
}
|
||
|
||
data.send_buf = write_data;
|
||
data.send_len = send_len;
|
||
data.receive_buf = NULL;
|
||
data.receive_len = 0;
|
||
|
||
for (retry = 0; retry < TP_I2C_TIME_MAX; retry++) {
|
||
ret = tjd_driver_common_i2c_get_ops()->write(I2C_MODEL_TP_ID, &data);
|
||
if (ret == ERRCODE_SUCC) {
|
||
break;
|
||
}
|
||
}
|
||
if (ret != ERRCODE_SUCC) {
|
||
osal_kfree(write_data);
|
||
return ret;
|
||
}
|
||
|
||
osal_kfree(write_data);
|
||
return EXT_ERR_SUCCESS;
|
||
}
|
||
|
||
ext_errno tp_i2c_package_write(uint16_t dev_addr, uint8_t *data_buf, uint32_t data_len)
|
||
{
|
||
errcode_t ret;
|
||
uint8_t retry;
|
||
check_dev_addr(dev_addr);
|
||
ret = tp_peripheral_init_status_check();
|
||
if (ret != 0) {
|
||
static_print_error("TOUCH: host peripheral not init! ret=0x%x", ret);
|
||
return ret;
|
||
}
|
||
|
||
i2c_data_t data = {.send_buf = data_buf, .send_len = data_len};
|
||
|
||
for (retry = 0; retry < TP_I2C_TIME_MAX; retry++) {
|
||
ret = tjd_driver_common_i2c_get_ops()->write(I2C_MODEL_TP_ID, &data);
|
||
if (ret == ERRCODE_SUCC) {
|
||
break;
|
||
}
|
||
}
|
||
|
||
if (ret != EXT_ERR_SUCCESS) {
|
||
return ret;
|
||
}
|
||
return EXT_ERR_SUCCESS;
|
||
}
|
||
|
||
ext_errno tp_i2c_reg_write(uint16_t dev_addr, uint32_t reg_addr, uint8_t reg_len, uint8_t reg_cfg)
|
||
{
|
||
errcode_t ret;
|
||
uint32_t retry;
|
||
i2c_data_t data;
|
||
check_dev_addr(dev_addr);
|
||
|
||
ret = tp_peripheral_init_status_check();
|
||
if (ret != 0) {
|
||
static_print_error("TOUCH: host peripheral not init! ret=0x%x", ret);
|
||
return ret;
|
||
}
|
||
|
||
reg_len = reg_len & 0x0F;
|
||
memset(g_tp_send_buf, 0, sizeof(g_tp_send_buf));
|
||
int i = reg_len;
|
||
while (i) {
|
||
i--;
|
||
g_tp_send_buf[i] = reg_addr;
|
||
reg_addr >>= 8;
|
||
}
|
||
g_tp_send_buf[reg_len] = reg_cfg;
|
||
reg_len += 1;
|
||
|
||
data.send_buf = g_tp_send_buf;
|
||
data.send_len = reg_len;
|
||
data.receive_buf = NULL;
|
||
data.receive_len = 0;
|
||
|
||
for (retry = 0; retry < TP_I2C_TIME_MAX; retry++) {
|
||
ret = tjd_driver_common_i2c_get_ops()->write(I2C_MODEL_TP_ID, &data);
|
||
if (ret == EXT_ERR_SUCCESS) {
|
||
break;
|
||
}
|
||
}
|
||
if (ret != EXT_ERR_SUCCESS) {
|
||
return ret;
|
||
}
|
||
|
||
return EXT_ERR_SUCCESS;
|
||
}
|
||
|
||
ext_errno tp_i2c_data_read(uint16_t dev_addr, uint32_t reg_addr, uint8_t reg_len, uint8_t *data_buf, uint16_t data_len)
|
||
{
|
||
errcode_t ret;
|
||
uint32_t retry;
|
||
i2c_data_t data;
|
||
check_dev_addr(dev_addr);
|
||
|
||
ret = tp_peripheral_init_status_check();
|
||
if (ret != 0) {
|
||
static_print_error("TOUCH: host peripheral not init! ret=0x%x", ret);
|
||
return ret;
|
||
}
|
||
|
||
reg_len = reg_len & 0x0F;
|
||
memset(g_tp_send_buf, 0, sizeof(g_tp_send_buf));
|
||
|
||
if (memset_s(g_tp_recv_buf, data_len, 0, data_len) != EOK) {
|
||
static_print_error("TOUCH: tp read buff set fail! ret=0x%x", ret);
|
||
return EXT_ERR_FAILURE;
|
||
}
|
||
|
||
int i = reg_len;
|
||
while (i) {
|
||
i--;
|
||
g_tp_send_buf[i] = reg_addr;
|
||
reg_addr >>= 8;
|
||
}
|
||
|
||
data.send_buf = g_tp_send_buf;
|
||
data.send_len = reg_len;
|
||
data.receive_buf = g_tp_recv_buf;
|
||
data.receive_len = data_len;
|
||
|
||
for (retry = 0; retry < TP_I2C_TIME_MAX; retry++) {
|
||
ret = tjd_driver_common_i2c_get_ops()->writeread(I2C_MODEL_TP_ID, &data);
|
||
if (ret == EXT_ERR_SUCCESS) {
|
||
break;
|
||
}
|
||
}
|
||
if (ret != EXT_ERR_SUCCESS) {
|
||
return ret;
|
||
}
|
||
|
||
ret = (uint32_t)memcpy_s(data_buf, data_len, g_tp_recv_buf, data_len);
|
||
if (ret != EOK) {
|
||
static_print_error("TOUCH: tp data buf content copy fail! ret=0x%x", ret);
|
||
return ret;
|
||
}
|
||
|
||
return EXT_ERR_SUCCESS;
|
||
}
|
||
#endif
|
||
|
||
static void tp_gpio_isr_handle(pin_t pin, uintptr_t param)
|
||
{
|
||
unused(pin);
|
||
unused(param);
|
||
if (g_tp_callback != NULL) {
|
||
g_tp_callback();
|
||
}
|
||
}
|
||
|
||
ext_errno tp_register_handle(const tp_ctrl_ops *peri_data, void *func)
|
||
{
|
||
unused(peri_data);
|
||
ext_errno ret;
|
||
|
||
g_tp_callback = func;
|
||
tp_print("register int io interrupt handler");
|
||
|
||
/* register int io interrupt handler */
|
||
uapi_gpio_init();
|
||
gpio_select_core(TP_INT_GPIO, CORE);
|
||
uapi_gpio_set_dir(TP_INT_GPIO, GPIO_DIRECTION_INPUT);
|
||
ret = uapi_gpio_register_isr_func(TP_INT_GPIO, GPIO_INTERRUPT_FALLING_EDGE, tp_gpio_isr_handle);
|
||
if (ret != 0) {
|
||
static_print_error("TOUCH: tp int callback register fail! ret=0x%x", ret);
|
||
return ret;
|
||
}
|
||
|
||
return EXT_ERR_SUCCESS;
|
||
}
|
||
|
||
ext_errno tp_unregister_handle(const tp_ctrl_ops *peri_data)
|
||
{
|
||
unused(peri_data);
|
||
ext_errno ret;
|
||
|
||
/* unregister interrupt handler */
|
||
uapi_gpio_unregister_isr_func(TP_INT_GPIO);
|
||
g_tp_callback = NULL;
|
||
|
||
return EXT_ERR_SUCCESS;
|
||
}
|
||
|
||
ext_errno tp_irq_callback(uint8_t *data_buf, uint8_t data_len)
|
||
{
|
||
ext_errno ret = EXT_ERR_SUCCESS;
|
||
|
||
/* 防止盖手息屏后的报点行为 */
|
||
const power_display_svr_api_t *display_api = power_display_svr_get_api();
|
||
if (display_api->get_screen_state() == SCREEN_OFF) {
|
||
return EXT_ERR_SUCCESS;
|
||
}
|
||
#if (TJD_TP_FT6146)
|
||
ret = ft6146_irq_callback(data_buf, data_len);
|
||
#elif (TJD_TP_CST820)
|
||
ret = cst820_irq_callback(data_buf, data_len);
|
||
#endif
|
||
return ret;
|
||
}
|
||
|
||
static ext_errno tp_ctrl_attr_check(const tp_ctrl_attr *device_attr)
|
||
{
|
||
unused(device_attr);
|
||
return EXT_ERR_SUCCESS;
|
||
}
|
||
|
||
ext_errno tp_host_peripheral_init(tp_ctrl_attr *attr)
|
||
{
|
||
ext_errno ret;
|
||
|
||
if (attr == NULL) {
|
||
static_print_error("TOUCH: tp communication interface cfg is empty!");
|
||
return EXT_ERR_FAILURE;
|
||
}
|
||
ret = tp_ctrl_attr_check(attr);
|
||
if (ret != EXT_ERR_SUCCESS) {
|
||
static_print_error("TOUCH: tp invalid dev attr! ret=0x%x", ret);
|
||
return ret;
|
||
}
|
||
|
||
/* 上电前RESET INT保持为LOW */
|
||
uapi_gpio_set_dir(TP_RESET_GPIO, GPIO_DIRECTION_OUTPUT);
|
||
uapi_gpio_set_val(TP_RESET_GPIO, GPIO_LEVEL_LOW);
|
||
tp_delay(5);
|
||
|
||
static uint16_t i2c_addr = 0;
|
||
#if (TJD_TP_FT6146)
|
||
i2c_addr = FT6146_I2C_ADDR;
|
||
#elif (TJD_TP_CST820)
|
||
i2c_addr = CST820_I2C_ADDR;
|
||
#endif
|
||
/* init i2c */
|
||
last_dev_addr = i2c_addr;
|
||
ret = tjd_driver_common_i2c_get_ops()->open(I2C_MODEL_TP_ID, attr->i2c_id, i2c_addr, attr->i2c_speed);
|
||
if (ret != EXT_ERR_SUCCESS) {
|
||
static_print_error("TOUCH: tp i2c init fail! ret=0x%x", ret);
|
||
}
|
||
|
||
g_tp_host_dev_init_flag = true;
|
||
|
||
/* 上电,并延迟300ms */
|
||
tp_open();
|
||
|
||
return EXT_ERR_SUCCESS;
|
||
}
|