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