mcu_hi3321_watch/tjd/driver/tp/tp_port_ctrl.c
2025-05-26 20:15:20 +08:00

451 lines
12 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*----------------------------------------------------------------------------
* 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;
}