1833 lines
60 KiB
C
Raw Normal View History

#include "includes.h"
#include "asm/power/p11.h"
#include "asm/power/p33.h"
#include "asm/lp_touch_key_api.h"
#include "asm/lp_touch_key_alog.h"
#include "asm/lp_touch_key_hw.h"
#include "device/key_driver.h"
#include "bt_tws.h"
#include "classic/tws_api.h"
#include "key_event_deal.h"
#include "btstack/avctp_user.h"
#include "app_config.h"
#define LOG_TAG_CONST LP_KEY
#define LOG_TAG "[LP_KEY]"
/* #define LOG_ERROR_ENABLE */
/* #define LOG_DEBUG_ENABLE */
#define LOG_INFO_ENABLE
#define LOG_DUMP_ENABLE
#define LOG_CLI_ENABLE
#include "debug.h"
#if (TCFG_LP_TOUCH_KEY_ENABLE || TCFG_LP_EARTCH_KEY_ENABLE)
//需要开debug的情况
//1.内置触摸调试工具
//2.入耳检测
#define CTMU_CH0_MODULE_DEBUG 1
#define CTMU_CH1_MODULE_DEBUG 0
#define TWS_FUNC_ID_VOL_LP_KEY TWS_FUNC_ID('L', 'K', 'E', 'Y')
#define TWS_BT_SEND_CH0_RES_DATA_ENABLE 0
#define TWS_BT_SEND_CH1_RES_DATA_ENABLE 0
#define TWS_BT_SEND_EVENT_ENABLE 0
#define LP_TOUCH_KEY_TIMER_MAGIC_NUM 0xFFFF
#if TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE
#ifdef CTMU_RESET_TIME_CONFIG
#undef CTMU_RESET_TIME_CONFIG
#define CTMU_RESET_TIME_CONFIG 0
#endif /* #ifdef CTMU_RESET_TIME_CONFIG */
#endif /* #if TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE */
struct ctmu_key {
u8 init;
u8 ch_init;
u8 click_cnt;
u8 last_key;
u8 last_ear_in_state;
u8 ch0_msg_lock;
u8 softoff_mode;
u16 ch0_msg_lock_timer;
u16 short_timer;
u16 long_timer;
u16 ear_in_timer;
u32 lrc_hz;
u8 ch1_inear_ok;
u16 ch1_trim_value;
u16 ch1_trim_flag;
const struct lp_touch_key_platform_data *config;
};
enum ctmu_key_event {
CTMU_KEY_NULL,
CTMU_KEY_SHORT_CLICK,
CTMU_KEY_LONG_CLICK,
CTMU_KEY_HOLD_CLICK,
};
enum ch1_event_list {
CH1_EAR_IN,
CH1_EAR_OUT,
};
enum LP_TOUCH_SOFTOFF_MODE {
LP_TOUCH_SOFTOFF_MODE_LEGACY = 0, //普通关机
LP_TOUCH_SOFTOFF_MODE_ADVANCE = 1, //带触摸关机
};
static struct ctmu_key _ctmu_key = {
.click_cnt = 0,
.last_ear_in_state = CH1_EAR_OUT,
.short_timer = LP_TOUCH_KEY_TIMER_MAGIC_NUM,
.long_timer = LP_TOUCH_KEY_TIMER_MAGIC_NUM,
.ear_in_timer = LP_TOUCH_KEY_TIMER_MAGIC_NUM,
.last_key = CTMU_KEY_NULL,
};
struct ch_ana_cfg {
u8 isel;
u8 vhsel;
u8 vlsel;
};
struct ch_adjust_table {
u16 cfg0;
u16 cfg1;
u16 cfg2;
};
//cap(电容)检测灵敏度级数配置
//模具厚度, 触摸片面积有关
//模具越厚, 触摸片面积越大, 触摸时电容变化量
//cap检测灵敏度级数配置建议从级数0开始调, 选取合适的灵敏度;
const static struct ch_adjust_table ch0_sensitivity_table[] = {
/* cfg0 cfg1 cfg2 */
{20, 30, 550}, //cap检测灵敏度级数0
{15, 20, 270}, //cap检测灵敏度级数1
{15, 20, 240}, //cap检测灵敏度级数2
{15, 20, 210}, //cap检测灵敏度级数3
{15, 20, 180}, //cap检测灵敏度级数4
{15, 20, 150}, //cap检测灵敏度级数5
{15, 20, 120}, //cap检测灵敏度级数6
{15, 20, 90}, //cap检测灵敏度级数7
{10, 15, 60}, //cap检测灵敏度级数8
{10, 15, 30}, //cap检测灵敏度级数9
};
const static struct ch_adjust_table ch1_sensitivity_table[] = {
/* cfg0 cfg1 cfg2 */
{15, 20, 230}, //cap检测灵敏度级数0
{15, 20, 210}, //cap检测灵敏度级数1
{15, 20, 190}, //cap检测灵敏度级数2
{15, 20, 170}, //cap检测灵敏度级数3
{15, 20, 150}, //cap检测灵敏度级数4
{15, 20, 130}, //cap检测灵敏度级数5
{15, 20, 110}, //cap检测灵敏度级数6
{15, 20, 80}, //cap检测灵敏度级数7
{10, 15, 70}, //cap检测灵敏度级数8
{10, 15, 50}, //cap检测灵敏度级数9
};
#define LPCTMU_VH_LEVEL 3 // 上限电压档位
#define LPCTMU_VL_LEVEL 0 // 下限电压档位
#define LPCTMU_CUR_LEVEL 7 // 充放电电流档位
static const u8 lpctmu_ana_vh_table[4] = {
LPCTMU_VH_065V,
LPCTMU_VH_070V,
LPCTMU_VH_075V,
LPCTMU_VH_080V,
};
static const u8 lpctmu_ana_vl_table[4] = {
LPCTMU_VL_020V,
LPCTMU_VL_025V,
LPCTMU_VL_030V,
LPCTMU_VL_035V,
};
static const u8 lpctmu_ana_cur_table[8] = {
LPCTMU_ISEL_008UA,
LPCTMU_ISEL_024UA,
LPCTMU_ISEL_040UA,
LPCTMU_ISEL_056UA,
LPCTMU_ISEL_072UA,
LPCTMU_ISEL_088UA,
LPCTMU_ISEL_104UA,
LPCTMU_ISEL_120UA
};
u8 get_lpctmu_ana_level(void)
{
return ((lpctmu_ana_vh_table[LPCTMU_VH_LEVEL]) | \
(lpctmu_ana_vl_table[LPCTMU_VL_LEVEL]) | \
(lpctmu_ana_cur_table[LPCTMU_CUR_LEVEL]));
}
struct lp_touch_key_alog_cfg {
u16 ready_flag;
u16 range;
s32 sigma;
};
static struct lp_touch_key_alog_cfg alog_cfg = {
.ready_flag = 0,
.range = 0,
.sigma = 0,
};
static u16 res_stable_cnt = 0;
static u8 ch0_range_sensity = 7;
static u16 ctmu_ch0_res_scan_time_add = 0;
static u16 save_alog_cfg_time_out = 0;
#define TOUCH_RANGE_MIN 50
#define TOUCH_RANGE_MAX 500
#define CH1_SOFT_INEAR_VAL 180
#define CH1_SOFT_OUTEAR_VAL 120
int eartch_event_deal_init(void);
#define __this (&_ctmu_key)
#if TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE
static int lp_touch_key_online_debug_init(void);
static int lp_touch_key_online_debug_send(u8 ch, u16 val);
static int lp_touch_key_online_debug_key_event_handle(u8 ch_index, struct sys_event *event);
#endif /* #if TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE */
static volatile u8 is_lpkey_active = 0;
//init io HZ
static void ctmu_port_init(u8 port)
{
gpio_set_die(port, 0);
gpio_set_dieh(port, 0);
gpio_set_direction(port, 1);
gpio_set_pull_down(port, 0);
gpio_set_pull_up(port, 0);
}
static void lp_touch_key_send_cmd(enum CTMU_M2P_CMD cmd)
{
M2P_CTMU_CMD = cmd;
P11_M2P_INT_SET = BIT(M2P_CTMU_INDEX);
}
static u32 lp_touch_key_get_lrc_hz(void)
{
ASSERT(__this->lrc_hz, "lrc_hz is ZERO");
return __this->lrc_hz;
}
#if TCFG_LP_EARTCH_KEY_ENABLE
void eartch_hardware_recover(void)
{
lp_touch_key_send_cmd(CTMU_M2P_CH1_ENABLE);
}
void eartch_hardware_suspend(void)
{
__this->ch_init &= ~BIT(1);
lp_touch_key_send_cmd(CTMU_M2P_CH1_DISABLE);
}
#endif /* #if TCFG_LP_EARTCH_KEY_ENABLE */
//=========================================//
//模块配置顺序: Select ctmu clk --> Enable --> Reset --> 配置参数 --> Run
static void __lpctmu_reset(u8 para_reset)
{
LP_CTMU_CLK_SEL(LP_CTMU_CLK_SEL_P11_SYS_CLK); //sel sys_clk 12M, 加快配置速度
LP_CTMU_MODULE_EN(1); //lctm en
LP_CTMU_RUN(0); //lctm run (内部状态机复位)
if (para_reset) {
LP_CTMU_CFG_RESET(0); //lctm 配置参数reset
}
delay(100);
LP_CTMU_CFG_RESET(1); //lctm reset
}
//=========================================//
#if !TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE
void lp_touch_key_save_alog_cfg(void *priv)
{
int ret = syscfg_write(VM_LP_TOUCH_KEY_ALOG_CFG, (void *)&alog_cfg, sizeof(struct lp_touch_key_alog_cfg));
if (ret != sizeof(struct lp_touch_key_alog_cfg)) {
log_info("write vm alog cfg ready flag error !\n");
}
save_alog_cfg_time_out = 0;
}
void lp_touch_key_ctmu_ch0_cfg2_check_update(u16 cfg2_new)
{
u16 cfg2_old = (M2P_CTMU_CH0_CFG2H << 8) | M2P_CTMU_CH0_CFG2L;
if (cfg2_old != cfg2_new) {
printf("ctmu ch0 cfg2_old = %d cfg_new = %d\n", cfg2_old, cfg2_new);
printf("change ctmu ch0 cfg2 !\n");
M2P_CTMU_CH0_CFG2H = (cfg2_new >> 8) & 0xff;
M2P_CTMU_CH0_CFG2L = (cfg2_new >> 0) & 0xff;
}
}
static void lp_touch_key_ctmu_ch0_res_scan(void *priv)
{
if (M2P_CTMU_CH0_RES_SEND) {
return;
}
u16 ctmu_ch0_res0;
u16 ctmu_ch0_res1;
__read_res:
ctmu_ch0_res0 = (P2M_CTMU_CH0_H_RES << 8) | P2M_CTMU_CH0_L_RES;
delay(100);
ctmu_ch0_res1 = (P2M_CTMU_CH0_H_RES << 8) | P2M_CTMU_CH0_L_RES;
if (ctmu_ch0_res0 != ctmu_ch0_res1) {
goto __read_res;
}
#if 1
if ((ctmu_ch0_res0 < 2000) || (ctmu_ch0_res0 > 20000)) {
return;
}
if (res_stable_cnt < 50) {
res_stable_cnt ++;
return;
}
TouchAlgo_Update(0, ctmu_ch0_res0);
u8 range_valid = 0;
u16 touch_range = TouchAlgo_GetRange(0, (u8 *)&range_valid);
s32 touch_sigma = TouchAlgo_GetSigma(0);
/* printf("res:%d range:%d val:%d sigma:%d\n", ctmu_ch0_res0, touch_range, range_valid, touch_sigma); */
if ((range_valid) && (touch_range > TOUCH_RANGE_MIN) && (touch_range < TOUCH_RANGE_MAX)) {
u16 cfg2_new = touch_range * (10 - ch0_range_sensity) / 10;
lp_touch_key_ctmu_ch0_cfg2_check_update(cfg2_new);
if (touch_range != alog_cfg.range) {
alog_cfg.range = touch_range;
alog_cfg.sigma = touch_sigma;
if (save_alog_cfg_time_out == 0) {
save_alog_cfg_time_out = sys_timeout_add(NULL, lp_touch_key_save_alog_cfg, 1);
}
}
} else if ((range_valid) && (touch_range > TOUCH_RANGE_MAX)) {
TouchAlgo_SetRange(0, alog_cfg.range);
}
#endif
}
void lp_touch_key_alog_ready_flag_check_and_set(void)
{
alog_cfg.ready_flag = 0;
syscfg_read(VM_LP_TOUCH_KEY_ALOG_CFG, (void *)&alog_cfg, sizeof(struct lp_touch_key_alog_cfg));
if (alog_cfg.ready_flag == 0) {
alog_cfg.ready_flag = 1;
lp_touch_key_save_alog_cfg(NULL);
}
}
void lp_touch_key_alog_init(u8 cfg2_sensity)
{
TouchAlgo_Init(0, TOUCH_RANGE_MIN, TOUCH_RANGE_MAX);
res_stable_cnt = 0;
ch0_range_sensity = cfg2_sensity;
int ret = syscfg_read(VM_LP_TOUCH_KEY_ALOG_CFG, (void *)&alog_cfg, sizeof(struct lp_touch_key_alog_cfg));
if ((ret == (sizeof(struct lp_touch_key_alog_cfg))) && (alog_cfg.range > TOUCH_RANGE_MIN) && (alog_cfg.range < TOUCH_RANGE_MAX) && (alog_cfg.ready_flag)) {
log_info("vm read alog ready_flag:%d sigma:%d range:%d\n", alog_cfg.ready_flag, alog_cfg.sigma, alog_cfg.range);
TouchAlgo_SetSigma(0, alog_cfg.sigma);
TouchAlgo_SetRange(0, alog_cfg.range);
u16 new_cfg2 = alog_cfg.range * (10 - ch0_range_sensity) / 10;
LP_CTMU_CH0_EDGE_TH(new_cfg2);
}
#if 1 //触摸算法要尽可能的在装完整机之后开始跑而这里是耳机生产流程中获取它第一次在舱内开机的时候在vm标记一个变量从此开始跑算法。
if (get_charge_online_flag()) {
log_info("check charge online !\n");
lp_touch_key_alog_ready_flag_check_and_set();//如果有其他好的位置,请将该函数移到那个位置执行。
}
#endif
if ((alog_cfg.ready_flag) && (ctmu_ch0_res_scan_time_add == 0)) {
ctmu_ch0_res_scan_time_add = usr_timer_add(NULL, lp_touch_key_ctmu_ch0_res_scan, 20, 0);
}
}
#endif
#define IO_PORT_RESET_PORT_LDOIN LINDT_IN//IO编号
#define IO_RESET_PORTB_01 11
void lp_touch_key_init(const struct lp_touch_key_platform_data *config)
{
log_info("%s >>>>", __func__);
ASSERT(config && (__this->init == 0));
__this->config = config;
M2P_CTMU_MSG = 0;
//长按复位检测
u8 pinr_io;
if (P33_CON_GET(P3_PINR_CON) & BIT(0)) {
pinr_io = P33_CON_GET(P3_PORT_SEL0);
if (pinr_io == IO_RESET_PORTB_01) {
P33_CON_SET(P3_PINR_CON, 0, 1, 0);
p33_tx_1byte(P3_PORT_SEL0, IO_PORT_RESET_PORT_LDOIN);
P33_CON_SET(P3_PINR_CON, 2, 1, 1);
P33_CON_SET(P3_PINR_CON, 0, 1, 1);
log_info("reset pin change: old: %d, new: %d, P33_PINR_CON = 0x%x", pinr_io, P33_CON_GET(P3_PORT_SEL0), P33_CON_GET(P3_PINR_CON));
}
}
u8 ch0_sensity = __this->config->ch0.sensitivity;
u8 ch1_sensity = __this->config->ch1.sensitivity;
LP_TOUCH_KEY_CONFIG tool_cfg;
int ret = syscfg_read(CFG_LP_TOUCH_KEY_ID, &tool_cfg, sizeof(LP_TOUCH_KEY_CONFIG));
if (ret > 0) {
log_info("cfg_en: %d, ch0_sensity_cfg: %d, ch1_sensity_cfg: %d", tool_cfg.cfg_en, tool_cfg.touch_key_sensity_class, tool_cfg.earin_key_sensity_class);
if (tool_cfg.cfg_en) {
ch0_sensity = tool_cfg.touch_key_sensity_class;
ch1_sensity = tool_cfg.earin_key_sensity_class;
}
} else {
log_error("touch key cfg not exist");
}
log_info("ch0_sensity: %d, ch1_sensity: %d", ch0_sensity, ch1_sensity);
//==============================================================//
// CH0 初始化 //
//==============================================================//
__lpctmu_reset(1); //模块复位
LP_CTMU_SWITCH_STABLE_TIME_SET();
//CTMU 时基配置:
u16 time_prd = 0;
if (__this->lrc_hz) {
time_prd = (__this->lrc_hz * CTMU_TIME_BASE) / 1000 - 1;
} else {
time_prd = CFG_M2P_CTMU_BASE_TIME_PRD;
}
LP_CTMU_TIMER_BASE_CONFIG(time_prd);
log_info("LRC_HZ = %d, time_prd = %d", __this->lrc_hz, time_prd);
if (__this->config->ch0.enable) {
//PB1和PB2通道互换IO:
if (__this->config->ch0.port == IO_PORTB_02) {
LP_CTMU_IO_INV(1);
} else {
LP_CTMU_IO_INV(0);
ASSERT(__this->config->ch0.port == IO_PORTB_01);
}
M2P_CTMU_MSG |= CTMU_INIT_CH0_ENABLE;
ctmu_port_init(__this->config->ch0.port);
//模拟参数配置:
LP_CTMU_CH0_ANA_CFG(get_lpctmu_ana_level());
//通用配置:
LP_CTMU_CH0_ENABLE(1); //通道0使能
LP_CTMU_CH0_FILTER_LEVEL(1); //通道0滤波级数
LP_CTMU_CH0_FILTER_EN(1); //通道0滤波使能
LP_CTMU_CH0_EDGE_EN(1); //通道0边沿检测使能
LP_CTMU_CH0_EDGE_TEMP_EN(1); //fixed
LP_CTMU_CH0_FIRST_RISE_MASK(0); //屏蔽第一个上升沿
//上升沿中断:
LP_CTMU_CH0_FALL_PENDING_CLR();
LP_CTMU_CH0_FALL_PENDING_IE(1);
LP_CTMU_CH0_FALL_PENDING_SEL(0);
//下升沿中断:
LP_CTMU_CH0_RISE_PENDING_CLR();
LP_CTMU_CH0_RISE_PENDING_IE(1);
LP_CTMU_CH0_RISE_PENDING_SEL(0);
//多击模式:
LP_CTMU_CH0_SHORT_KEY_MODE(1);
#if CTMU_CH0_MODULE_DEBUG
LP_CTMU_CH0_RES_PENDING_IE(1);
M2P_CTMU_MSG |= CTMU_INIT_CH0_DEBUG;
#endif /* #if CTMU_CH0_MODULE_DEBUG */
LP_CTMU_CH0_SHORT_KEY_TRIGGER(0);
LP_CTMU_CH0_SHORT_PENDING_CLR();
LP_CTMU_CH0_SHORT_PENDING_IE(0);
LP_CTMU_CH0_LONG_PENDING_CLR();
LP_CTMU_CH0_LONG_PENDING_IE(1);
LP_CTMU_CH0_HOLD_PENDING_CLR();
LP_CTMU_CH0_HOLD_PENDING_IE(1);
LP_CTMU_CH0_HOLD_EN(1);
LP_CTMU_CH0_KEY_MODE_ENABLE(1);
//快速 & 低速扫描周期
LP_CTMU_CH0_HIGH_SPEED_PRD(CFG_CTMU_CH0_HS_PERIOD_VALUE);
LP_CTMU_CH0_LOW_SPEED_PRD(CFG_CTMU_CH0_LS_PERIOD_VALUE);
//采样窗口时间
LP_CTMU_CH0_DET_TIME(CFG_CTMU_CH0_WINDOW_TIME_VALUE);
ASSERT(ch0_sensity < ARRAY_SIZE(ch0_sensitivity_table));
//CH0阈值:
LP_CTMU_CH0_TEMP_TH(ch0_sensitivity_table[ch0_sensity].cfg0);
LP_CTMU_CH0_STABLE_TH(ch0_sensitivity_table[ch0_sensity].cfg0 + 5);
LP_CTMU_CH0_EDGE_TH(ch0_sensitivity_table[ch0_sensity].cfg2);
M2P_CTMU_CH0_CFG2H = (ch0_sensitivity_table[ch0_sensity].cfg2 >> 8) & 0xff;
M2P_CTMU_CH0_CFG2L = (ch0_sensitivity_table[ch0_sensity].cfg2 >> 0) & 0xff;
//CH0 按键时间:
LP_CTMU_CH0_SHORT_KEY_TIME(CFG_M2P_CTMU_CH0_SHORT_TIME_VALUE);
LP_CTMU_CH0_LONG_KEY_TIME(CFG_M2P_CTMU_CH0_LONG_TIME_VALUE);
LP_CTMU_CH0_HOLD_KEY_TIME(CFG_M2P_CTMU_CH0_HOLD_TIME_VALUE);
LP_CTMU_CH0_IE(1);
//长按开机时间配置
M2P_CTMU_CH0_SOFTOFF_LONG_TIMEL = (CFG_M2P_CTMU_CH0_SOFTOFF_LONG_TIME & 0xFF);
M2P_CTMU_CH0_SOFTOFF_LONG_TIMEH = ((CFG_M2P_CTMU_CH0_SOFTOFF_LONG_TIME >> 8) & 0xFF);
log_info("P11_LCTM_CON = 0x%x", P11_LCTM_CON);
log_info("LCTM_MOD = 0x%x", LCTM_MOD);
log_info("LCTM_TMR = 0x%x", LCTM_TMR);
log_info("LCTM_TIME_BASE_H = 0x%x", LCTM_TIME_BASE_H);
log_info("LCTM_TIME_BASE_L = 0x%x", LCTM_TIME_BASE_L);
log_info("LCTM_CHL0_ANA = 0x%x", LCTM_CHL0_ANA);
log_info("LCTM_CHL0_CON0 = 0x%x", LCTM_CHL0_CON0);
log_info("LCTM_CHL0_CON1 = 0x%x", LCTM_CHL0_CON1);
log_info("LCTM_CHL0_CON2 = 0x%x", LCTM_CHL0_CON2);
log_info("LCTM_CHL0_CON3 = 0x%x", LCTM_CHL0_CON3);
log_info("LCTM_CHL0_HS_PRD = 0x%x", LCTM_CHL0_HS_PRD);
log_info("LCTM_CHL0_LS_PRD = 0x%x", LCTM_CHL0_LS_PRD);
log_info("LCTM_CHL0_DET_TIME_H = 0x%x", LCTM_CHL0_DET_TIME_H);
log_info("LCTM_CHL0_DET_TIME_L = 0x%x", LCTM_CHL0_DET_TIME_L);
log_info("LCTM_CHL0_TEMP_H = 0x%x", LCTM_CHL0_TEMP_H);
log_info("LCTM_CHL0_TEMP_L = 0x%x", LCTM_CHL0_TEMP_L);
log_info("LCTM_CHL0_STA_H = 0x%x", LCTM_CHL0_STA_H);
log_info("LCTM_CHL0_STA_L = 0x%x", LCTM_CHL0_STA_L);
log_info("LCTM_CHL0_EDGE_H = 0x%x", LCTM_CHL0_EDGE_H);
log_info("LCTM_CHL0_EDGE_L = 0x%x", LCTM_CHL0_EDGE_L);
log_info("LCTM_CHL0_SHORT_H = 0x%x", LCTM_CHL0_SHORT_H);
log_info("LCTM_CHL0_SHORT_L = 0x%x", LCTM_CHL0_SHORT_L);
log_info("LCTM_CHL0_LONG_H = 0x%x", LCTM_CHL0_LONG_H);
log_info("LCTM_CHL0_LONG_L = 0x%x", LCTM_CHL0_LONG_L);
log_info("LCTM_CHL0_HOLD_H = 0x%x", LCTM_CHL0_HOLD_H);
log_info("LCTM_CHL0_HOLD_L = 0x%x", LCTM_CHL0_HOLD_L);
#if TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE
M2P_CTMU_CH0_RES_SEND = 1;
#else
M2P_CTMU_CH0_RES_SEND = 0;
#endif
#if CTMU_CH0_MODULE_DEBUG
#if !TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE
if (!M2P_CTMU_CH0_RES_SEND) {
lp_touch_key_alog_init(ch0_sensity);
}
#endif
#endif
}
//==============================================================//
// CH1 初始化 //
//==============================================================//
if (__this->config->ch1.enable) {
if (__this->config->ch1.port == IO_PORTB_01) {
LP_CTMU_IO_INV(1);
} else {
LP_CTMU_IO_INV(0);
ASSERT(__this->config->ch1.port == IO_PORTB_02);
}
M2P_CTMU_MSG |= CTMU_INIT_CH1_ENABLE;
ctmu_port_init(__this->config->ch1.port);
//模拟参数配置:
LP_CTMU_CH1_ANA_CFG(get_lpctmu_ana_level());
//通用配置:
LP_CTMU_CH1_ENABLE(1); //通道0使能
LP_CTMU_CH1_FILTER_LEVEL(1); //通道0滤波级数
LP_CTMU_CH1_FILTER_EN(1); //通道0滤波使能
LP_CTMU_CH1_EDGE_EN(1); //通道0边沿检测使能
LP_CTMU_CH1_EDGE_TEMP_EN(1); //fixed
LP_CTMU_CH1_FIRST_RISE_MASK(0); //屏蔽第一个上升沿
//上升沿中断:
LP_CTMU_CH1_FALL_PENDING_CLR();
LP_CTMU_CH1_FALL_PENDING_IE(1);
LP_CTMU_CH1_FALL_PENDING_SEL(0);
//下升沿中断:
LP_CTMU_CH1_RISE_PENDING_CLR();
LP_CTMU_CH1_RISE_PENDING_IE(1);
LP_CTMU_CH1_RISE_PENDING_SEL(0);
#if CTMU_CH1_MODULE_DEBUG
LP_CTMU_CH1_RES_PENDING_IE(1);
M2P_CTMU_MSG |= CTMU_INIT_CH1_DEBUG;
#endif /* #if CTMU_CH1_MODULE_DEBUG */
//快速 & 低速扫描周期
LP_CTMU_CH1_HIGH_SPEED_PRD(CFG_CTMU_CH1_HS_PERIOD_VALUE);
LP_CTMU_CH1_LOW_SPEED_PRD(CFG_CTMU_CH1_LS_PERIOD_VALUE);
//采样窗口时间
LP_CTMU_CH1_DET_TIME(CFG_CTMU_CH1_WINDOW_TIME_VALUE);
ASSERT(ch1_sensity < ARRAY_SIZE(ch1_sensitivity_table));
//CH1阈值:
LP_CTMU_CH1_TEMP_TH(ch1_sensitivity_table[ch1_sensity].cfg0);
LP_CTMU_CH1_STABLE_TH(ch1_sensitivity_table[ch1_sensity].cfg0 + 5);
LP_CTMU_CH1_EDGE_TH(ch1_sensitivity_table[ch1_sensity].cfg2);
LP_CTMU_CH1_IE(1);
log_info("P11_LCTM_CON = 0x%x", P11_LCTM_CON);
log_info("LCTM_MOD = 0x%x", LCTM_MOD);
log_info("LCTM_TMR = 0x%x", LCTM_TMR);
log_info("LCTM_TIME_BASE_H = 0x%x", LCTM_TIME_BASE_H);
log_info("LCTM_TIME_BASE_L = 0x%x", LCTM_TIME_BASE_L);
log_info("LCTM_CHL1_ANA = 0x%x", LCTM_CHL1_ANA);
log_info("LCTM_CHL1_CON0 = 0x%x", LCTM_CHL1_CON0);
log_info("LCTM_CHL1_CON1 = 0x%x", LCTM_CHL1_CON1);
log_info("LCTM_CHL1_CON2 = 0x%x", LCTM_CHL1_CON2);
log_info("LCTM_CHL1_HS_PRD = 0x%x", LCTM_CHL1_HS_PRD);
log_info("LCTM_CHL1_LS_PRD = 0x%x", LCTM_CHL1_LS_PRD);
log_info("LCTM_CHL1_DET_TIME_H = 0x%x", LCTM_CHL1_DET_TIME_H);
log_info("LCTM_CHL1_DET_TIME_L = 0x%x", LCTM_CHL1_DET_TIME_L);
log_info("LCTM_CHL1_TEMP_H = 0x%x", LCTM_CHL1_TEMP_H);
log_info("LCTM_CHL1_TEMP_L = 0x%x", LCTM_CHL1_TEMP_L);
log_info("LCTM_CHL1_STA_H = 0x%x", LCTM_CHL1_STA_H);
log_info("LCTM_CHL1_STA_L = 0x%x", LCTM_CHL1_STA_L);
log_info("LCTM_CHL1_EDGE_H = 0x%x", LCTM_CHL1_EDGE_H);
log_info("LCTM_CHL1_EDGE_L = 0x%x", LCTM_CHL1_EDGE_L);
#if (TCFG_EARTCH_EVENT_HANDLE_ENABLE && TCFG_LP_EARTCH_KEY_ENABLE)
if (eartch_event_deal_init() == 0) {
sys_timeout_add(NULL, eartch_hardware_suspend, 500);
}
#endif /* #if (TCFG_EARTCH_EVENT_HANDLE_ENABLE && TCFG_LP_EARTCH_KEY_ENABLE) */
#if TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE
M2P_CTMU_CH1_RES_SEND = 1;
#else
M2P_CTMU_CH1_RES_SEND = 0;
#endif
u16 trim_value;
int ret = syscfg_read(LP_KEY_EARTCH_TRIM_VALUE, &trim_value, sizeof(trim_value));
__this->ch1_trim_flag = 0;
__this->ch1_inear_ok = 0;
if (ret > 0) {
__this->ch1_trim_value = trim_value;
M2P_CTMU_CH1_TRIM_VALUE_L = (__this->ch1_trim_value & 0xFF);
M2P_CTMU_CH1_TRIM_VALUE_H = ((__this->ch1_trim_value >> 8) & 0xFF);
__this->ch1_inear_ok = 1;
log_info("ch1_trim_value = %d", __this->ch1_trim_value);
} else {
__this->ch1_trim_value = 0;
//没有trim的情况下用不了
M2P_CTMU_CH1_TRIM_VALUE_L = (10000 & 0xFF);
M2P_CTMU_CH1_TRIM_VALUE_H = ((10000 >> 8) & 0xFF);
}
//软件触摸灵敏度调试
M2P_CTM_INEAR_VALUE_L = CH1_SOFT_INEAR_VAL & 0xFF;
M2P_CTM_INEAR_VALUE_H = CH1_SOFT_INEAR_VAL >> 8;
M2P_CTM_OUTEAR_VALUE_L = CH1_SOFT_OUTEAR_VAL & 0xFF;
M2P_CTM_OUTEAR_VALUE_H = CH1_SOFT_OUTEAR_VAL >> 8;
}
//CTMU 初始化命令
lp_touch_key_send_cmd(CTMU_M2P_INIT);
__this->softoff_mode = LP_TOUCH_SOFTOFF_MODE_ADVANCE;
__this->init = 1;
#if TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE
lp_touch_key_online_debug_init();
#endif /* #if TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE */
}
int __attribute__((weak)) lp_touch_key_event_remap(struct sys_event *e)
{
return true;
}
static void __ctmu_notify_key_event(struct sys_event *event)
{
event->type = SYS_KEY_EVENT;
event->u.key.type = KEY_DRIVER_TYPE_CTMU_TOUCH; //区分按键类型
event->arg = (void *)DEVICE_EVENT_FROM_KEY;
if ((event->u.key.value == __this->config->ch0.key_value) && (__this->ch0_msg_lock)
#if ((defined CFG_EAROUT_NOTIFY_CH0_ONE_CLICK_EVNET) && (CFG_EAROUT_NOTIFY_CH0_ONE_CLICK_EVNET == 0))
&& (event->u.key.event == KEY_EVENT_CLICK)
#endif /* #if (CFG_EAROUT_NOTIFY_CH0_ONE_CLICK_EVNET == 0) */
) {
return;
}
if (__this->config->ch1.enable) {
#if (CFG_EAROUT_NOTIFY_CH0_EVENT_SEL == CFG_EAROUT_NO_NOTIFY_CH0_ALL_EVENT)
if ((event->u.key.value == __this->config->ch0.key_value) && (__this->last_ear_in_state == CH1_EAR_OUT)) {
return;
}
#elif (CFG_EAROUT_NOTIFY_CH0_EVENT_SEL == CFG_EAROUT_NO_NOTIFY_CH0_CLICK_EVENT)
if ((event->u.key.value == __this->config->ch0.key_value) && (__this->last_ear_in_state == CH1_EAR_OUT) &&
((event->u.key.event == KEY_EVENT_CLICK) ||
(event->u.key.event == KEY_EVENT_DOUBLE_CLICK) ||
(event->u.key.event == KEY_EVENT_TRIPLE_CLICK)
)) {
return;
}
#else
//TODO:
#endif
}
#if TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE
if (lp_touch_key_online_debug_key_event_handle(0, event)) {
return;
}
#endif /* #if TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE */
if (lp_touch_key_event_remap(event)) {
sys_event_notify(event);
}
}
__attribute__((weak)) u8 remap_ctmu_short_click_event(u8 click_cnt, u8 event)
{
return event;
}
static void __ctmu_short_click_time_out_handle(void *priv)
{
struct sys_event e;
switch (__this->click_cnt) {
case 0:
return;
break;
case 1:
e.u.key.event = KEY_EVENT_CLICK;
break;
case 2:
e.u.key.event = KEY_EVENT_DOUBLE_CLICK;
break;
case 3:
e.u.key.event = KEY_EVENT_TRIPLE_CLICK;
break;
default:
e.u.key.event = KEY_EVENT_TRIPLE_CLICK;
break;
}
e.u.key.event = remap_ctmu_short_click_event(__this->click_cnt, e.u.key.event);
e.u.key.value = __this->config->ch0.key_value;
__this->short_timer = LP_TOUCH_KEY_TIMER_MAGIC_NUM;
__this->last_key = CTMU_KEY_NULL;
log_debug("notify key short event, cnt: %d", __this->click_cnt);
__ctmu_notify_key_event(&e);
}
static void __ctmu_short_click_time_test(void *priv)
{
return;
}
static void __ctmu_short_click_handle(void)
{
__this->last_key = CTMU_KEY_SHORT_CLICK;
u8 click_cnt = LP_CTMU_CH0_SHORT_KEY_CNT_GET();
__this->click_cnt = click_cnt;
log_debug("click_cnt = %d", click_cnt);
__ctmu_short_click_time_out_handle(NULL);
}
static void ctmu_short_click_handle(void)
{
__this->last_key = CTMU_KEY_SHORT_CLICK;
if (__this->short_timer == LP_TOUCH_KEY_TIMER_MAGIC_NUM) {
__this->click_cnt = 1;
__this->short_timer = usr_timeout_add(NULL, __ctmu_short_click_time_out_handle, CTMU_SHORT_CLICK_DELAY_TIME, 1);
} else {
__this->click_cnt++;
usr_timer_modify(__this->short_timer, CTMU_SHORT_CLICK_DELAY_TIME);
}
}
static void ctmu_raise_click_handle(void)
{
struct sys_event e = {0};
if (__this->last_key >= CTMU_KEY_LONG_CLICK) {
#if 0
if (__this->long_timer != LP_TOUCH_KEY_TIMER_MAGIC_NUM) {
usr_timer_del(__this->long_timer);
__this->long_timer = LP_TOUCH_KEY_TIMER_MAGIC_NUM;
}
#endif
e.u.key.event = KEY_EVENT_UP;
e.u.key.value = __this->config->ch0.key_value;
__ctmu_notify_key_event(&e);
__this->last_key = CTMU_KEY_NULL;
log_debug("notify key HOLD UP event");
} else {
ctmu_short_click_handle();
}
}
static void ctmu_long_click_handle(void)
{
__this->last_key = CTMU_KEY_LONG_CLICK;
struct sys_event e;
e.u.key.event = KEY_EVENT_LONG;
e.u.key.value = __this->config->ch0.key_value;
__ctmu_notify_key_event(&e);
}
static void ctmu_hold_click_handle(void)
{
__this->last_key = CTMU_KEY_HOLD_CLICK;
struct sys_event e;
e.u.key.event = KEY_EVENT_HOLD;
e.u.key.value = __this->config->ch0.key_value;
__ctmu_notify_key_event(&e);
}
__attribute__((weak))
void ear_lptouch_update_state(u8 state)
{
return;
}
extern void ear_lptouch_update_state(u8 state);
extern void eartch_state_update(u8 state);
static void __ctmu_ear_in_timeout_handle(void *priv)
{
u8 state;
__this->ear_in_timer = 0xFFFF;
if (__this->config->ch1.key_value == 0xFF) {
//使用外部自定义流程
if (__this->last_ear_in_state == CH1_EAR_IN) {
ear_lptouch_update_state(0);
} else {
ear_lptouch_update_state(1);
}
return;
}
#if TCFG_EARTCH_EVENT_HANDLE_ENABLE
if (__this->last_ear_in_state == CH1_EAR_IN) {
state = EARTCH_STATE_IN;
} else if (__this->last_ear_in_state == CH1_EAR_OUT) {
state = EARTCH_STATE_OUT;
} else {
return;
}
eartch_state_update(state);
#endif /* #if TCFG_EARTCH_EVENT_HANDLE_ENABLE */
}
static void __ctmu_ch0_unlock_timeout_handle(void *priv)
{
__this->ch0_msg_lock = false;
__this->ch0_msg_lock_timer = 0;
}
static void ctmu_ch1_event_handle(u8 ch1_event)
{
__this->last_ear_in_state = ch1_event;
#if TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE
struct sys_event event;
if (ch1_event == CH1_EAR_IN) {
event.u.key.event = 10;
} else if (ch1_event == CH1_EAR_OUT) {
event.u.key.event = 11;
}
if (lp_touch_key_online_debug_key_event_handle(1, &event)) {
return;
}
#endif /* #if TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE */
__this->ch0_msg_lock = true;
if (__this->ch0_msg_lock_timer == 0) {
__this->ch0_msg_lock_timer = sys_hi_timeout_add(NULL, __ctmu_ch0_unlock_timeout_handle, 3000);
} else {
sys_hi_timer_modify(__this->ch0_msg_lock_timer, 3000);
}
__ctmu_ear_in_timeout_handle(NULL);
}
static int tws_api_send_data_test(void *data, int len, u32 func_id);
static void tws_send_event_data(int msg, int type)
{
u32 event_data[4];
if (tws_api_get_tws_state() & TWS_STA_SIBLING_CONNECTED) {
event_data[0] = type;
event_data[1] = jiffies_to_msecs(jiffies);
event_data[2] = msg;
tws_api_send_data_test(event_data, 3 * sizeof(int), TWS_FUNC_ID_VOL_LP_KEY);
}
}
void tws_send_vddio_data(u8 data)
{
tws_send_event_data(data, BT_EVENT_VDDIO);
}
static void tws_send_res_data(int data1, int data2, int data3, int type)
{
u32 event_data[4];
if (tws_api_get_tws_state() & TWS_STA_SIBLING_CONNECTED) {
event_data[0] = type;
event_data[1] = data1;
event_data[2] = data2;
event_data[3] = data3;
tws_api_send_data_test(event_data, 4 * sizeof(int), TWS_FUNC_ID_VOL_LP_KEY);
}
}
__attribute__((weak))
u32 user_send_cmd_prepare(USER_CMD_TYPE cmd, u16 param_len, u8 *param)
{
return 0;
}
static u8 lp_touch_key_testbox_remote_test(u8 event)
{
u8 ret = true;
u8 key_report = 0;
switch (event) {
case CTMU_P2M_CH0_FALLING_EVENT:
key_report = 0xF1;
log_info("Notify testbox CH0 Down");
break;
case CTMU_P2M_CH0_RAISING_EVENT:
key_report = 0xF2;
log_info("Notify testbox CH0 Up");
break;
case CTMU_P2M_CH0_LONG_KEY_EVENT:
case CTMU_P2M_CH0_SHORT_KEY_EVENT:
case CTMU_P2M_CH0_HOLD_KEY_EVENT:
break;
default:
ret = false;
break;
}
if (key_report) {
user_send_cmd_prepare(USER_CTRL_TEST_KEY, 1, &key_report); //音量加
}
return ret;
}
void lp_touch_key_testbox_inear_trim(u8 flag)
{
#if (!TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE)
if (flag == 1) {
__this->ch1_trim_flag = 1;
__this->ch1_inear_ok = 0;
__this->ch1_trim_value == 0;
M2P_CTMU_CH1_RES_SEND = 1;
log_info("__this->ch1_trim_flag = %d", __this->ch1_trim_flag);
is_lpkey_active = 1;
} else {
__this->ch1_trim_flag = 0;
M2P_CTMU_CH1_RES_SEND = 0;
log_info("__this->ch1_trim_flag = %d", __this->ch1_trim_flag);
}
#endif
}
//======================================================//
// 测试盒测试标志接口 //
//======================================================//
extern u8 testbox_get_key_action_test_flag(void *priv);
u8 last_state = CTMU_P2M_CH1_OUT_EVENT;
//extern void spp_printf(const char *format, ...);
void p33_ctmu_key_event_irq_handler()
{
u8 ctmu_event = P2M_CTMU_KEY_EVENT;
int res = 0;
static u32 cnt0 = 0;
static u32 cnt1 = 0;
u8 ret = 0;
u16 ch0_res = 0, ch1_res = 0, ch0_iir = 0, ch1_diff = 0, ch1_trim = 0;
if (testbox_get_key_action_test_flag(NULL)) {
ret = lp_touch_key_testbox_remote_test(ctmu_event);
if (ret == true) {
return;
}
}
//log_debug("ctmu msg: 0x%x", ctmu_event);
switch (ctmu_event) {
case CTMU_P2M_CH0_RES_EVENT:
ch0_res = LP_CTMU_CH0_RES_GET();
ch0_iir = ((P2M_CTMU_CH0_H_IIR_VALUE << 8) | P2M_CTMU_CH0_L_IIR_VALUE);
/*printf("ch0_res: %d, ch0_iir: %d\n", ch0_res, ch0_iir);*/
//log_debug("CH0: debug, RES = %08d", res);
//log_debug("CH0: debug %08d, RES = %08d", cnt0++, res);
#if TWS_BT_SEND_CH0_RES_DATA_ENABLE
tws_send_res_data(((ch0_res << 16) | ch0_iir), 0, 0, BT_CH0_RES_MSG);
#endif /* #if TWS_BT_SEND_CH0_RES_DATA_ENABLE */
#if TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE
lp_touch_key_online_debug_send(0, ch0_res);
#endif /* #if TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE */
break;
case CTMU_P2M_CH1_RES_EVENT:
ch1_res = LP_CTMU_CH1_RES_GET();
ch1_diff = ((P2M_CTMU_CH1_H_DIFF_VALUE << 8) | P2M_CTMU_CH1_L_DIFF_VALUE);
ch1_trim = ((P2M_CTMU_CH1_H_TRIM_VALUE << 8) | P2M_CTMU_CH1_L_TRIM_VALUE);
ch0_res = ((P2M_CTMU_CH0_H_RES << 8) | P2M_CTMU_CH0_L_RES);
ch0_iir = (P2M_CTMU_CH0_H_IIR_VALUE << 8 | P2M_CTMU_CH0_L_IIR_VALUE);
/*printf("ch1_diff: %d, ch1_trim: %d, ch0_res: %d, ch1_res: %d, ch0_iir: %d\n", ch1_diff, ch1_trim, ch0_res, ch1_res, ch0_iir);*/
////////////////////////////////////////////////////////////////////////////////////////////////////////
#if!TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE
if (__this->ch1_trim_flag) {
if (__this->ch1_trim_value == 0) {
__this->ch1_trim_value = ch1_diff;
} else {
__this->ch1_trim_value = ((ch1_diff + __this->ch1_trim_value) >> 1);
}
if (__this->ch1_trim_flag++ > 20) {
__this->ch1_trim_flag = 0;
M2P_CTMU_CH1_RES_SEND = 0;
int ret = syscfg_write(LP_KEY_EARTCH_TRIM_VALUE, &(__this->ch1_trim_value), sizeof(__this->ch1_trim_value));
log_info("write ret = %d", ret);
if (ret > 0) {
M2P_CTMU_CH1_TRIM_VALUE_L = (__this->ch1_trim_value & 0xFF);
M2P_CTMU_CH1_TRIM_VALUE_H = ((__this->ch1_trim_value >> 8) & 0xFF);
__this->ch1_inear_ok = 1;
#if TCFG_EARTCH_EVENT_HANDLE_ENABLE
eartch_state_update(EARTCH_STATE_TRIM_OK);
#endif
log_info("trim: %d\n", __this->ch1_inear_ok);
is_lpkey_active = 0;
} else {
__this->ch1_inear_ok = 0;
#if TCFG_EARTCH_EVENT_HANDLE_ENABLE
eartch_state_update(EARTCH_STATE_TRIM_ERR);
#endif
log_info("trim: %d\n", __this->ch1_inear_ok);
is_lpkey_active = 0;
}
}
log_debug("ch1 trim value: %d, res = %d", __this->ch1_trim_value, ch1_diff);
}
#endif
///////////////////////////////////////////////////////////////////////////////////////////////////////////
#if TWS_BT_SEND_CH1_RES_DATA_ENABLE
tws_send_res_data(((ch1_trim << 16) | ch0_res), ((ch0_iir << 16) | ch1_res), ch1_diff, BT_CH1_RES_MSG);
#endif /* #if TWS_BT_SEND_CH1_RES_DATA_ENABLE */
//////////////////////////////////////////////////////////////////////////////////////////////////////////
#if TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE
lp_touch_key_online_debug_send(1, ch1_res);
#endif /* #if TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE */
/////////////////////////////////////////////////////////////////////////////////////////////////////////
if (P2M_CTMU_CTMU_KEY_CNT != last_state) {
last_state = P2M_CTMU_CTMU_KEY_CNT;
if (last_state == CTMU_P2M_CH1_IN_EVENT) {
#if TWS_BT_SEND_EVENT_ENABLE
tws_send_event_data(CH1_EAR_IN, BT_EVENT_SW_MSG);
#endif /* #if TWS_BT_SEND_EVENT_ENABLE */
if (__this->ch1_inear_ok) {
ctmu_ch1_event_handle(CH1_EAR_IN);
}
} else if (last_state == CTMU_P2M_CH1_OUT_EVENT) {
#if TWS_BT_SEND_EVENT_ENABLE
tws_send_event_data(CH1_EAR_OUT, BT_EVENT_SW_MSG);
#endif /* #if TWS_BT_SEND_EVENT_ENABLE */
if (__this->ch1_inear_ok) {
ctmu_ch1_event_handle(CH1_EAR_OUT);
}
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////
break;
case CTMU_P2M_CH0_SHORT_KEY_EVENT:
log_debug("CH0: SHORT click");
//__ctmu_short_click_handle();
break;
case CTMU_P2M_CH0_LONG_KEY_EVENT:
log_debug("CH0: LONG click");
ctmu_long_click_handle();
break;
case CTMU_P2M_CH0_HOLD_KEY_EVENT:
log_debug("CH0: HOLD click");
ctmu_hold_click_handle();
break;
case CTMU_P2M_CH0_FALLING_EVENT:
log_debug("CH0: FALLING");
break;
case CTMU_P2M_CH0_RAISING_EVENT:
if (!(__this->ch_init & BIT(0))) {
__this->ch_init |= BIT(0);
load_p11_bank_code2ram(1, 1);
return;
}
log_debug("CH0: RAISING");
ctmu_raise_click_handle();
break;
case CTMU_P2M_CH1_IN_EVENT:
#if TWS_BT_SEND_EVENT_ENABLE
tws_send_event_data(CH1_EAR_IN, BT_EVENT_HW_MSG);
#endif /* #if TWS_BT_SEND_EVENT_ENABLE */
log_debug("CH1 HW: IN");
break;
case CTMU_P2M_CH1_OUT_EVENT:
if (!(__this->ch_init & BIT(1))) {
__this->ch_init |= BIT(1);
return;
}
#if TWS_BT_SEND_EVENT_ENABLE
tws_send_event_data(CH1_EAR_OUT, BT_EVENT_HW_MSG);
#endif /* #if TWS_BT_SEND_EVENT_ENABLE */
log_debug("CH1 HW: OUT");
break;
default:
break;
}
}
void lp_touch_key_trace_lrc_hook(u32 lrc_hz)
{
static u8 first_time = 0;
if (first_time) {
return;
}
first_time = 1;
log_debug("%s", __func__);
__this->lrc_hz = lrc_hz;
u16 cnt = (CTMU_RESET_TIMER_PRD_VALUE * lrc_hz) / (1000L * 64);
#if CTMU_RESET_TIME_CONFIG
M2P_LCTM_RESET_PCNT_PRD1 = cnt >> 8;
M2P_LCTM_RESET_PCNT_PRD0 = cnt & 0xff;
M2P_LCTM_RESET_PCNT_VALUE = (CTMU_RESET_TIME_CONFIG - CTMU_LONG_KEY_DELAY_TIME) / CTMU_RESET_TIMER_PRD_VALUE;
#else
M2P_LCTM_RESET_PCNT_VALUE = 0;
#endif /* #if CTMU_RESET_TIME_CONFIG */
log_debug("lp timer cnt = %d, lrc_hz = %d, RESET_PCNT = %d", cnt, lrc_hz, M2P_LCTM_RESET_PCNT_VALUE);
#if 0
if (__this->init) {
u16 time_prd = 0;
time_prd = (__this->lrc_hz * CTMU_TIME_BASE) / 1000 - 1;
M2P_CTMU_BASE_TIME_PRD_L = (time_prd & 0xFF);
M2P_CTMU_BASE_TIME_PRD_H = ((time_prd >> 8) & 0xFF);
lp_touch_key_send_cmd(CTMU_M2P_UPDATE_BASE_TIME);
}
#endif
}
u8 lp_touch_key_power_on_status()
{
extern u8 power_reset_flag;
u8 sfr = power_reset_flag;
static u8 power_on_flag = 0;
log_debug("P3_RST_SRC = %x, P2M_CTMU_CTMU_WKUP_MSG = 0x%x", sfr, P2M_CTMU_CTMU_WKUP_MSG);
if ((sfr & BIT(0)) || (sfr & BIT(1))) {
return 0;
}
if (P2M_CTMU_CTMU_WKUP_MSG & BIT(0)) {
power_on_flag = 1;
P2M_CTMU_CTMU_WKUP_MSG &= (~(BIT(0)));
}
return power_on_flag;
}
void lp_touch_key_disable(void)
{
log_debug("%s", __func__);
while (!__this->ch_init & BIT(0)) {
asm volatile("nop");
}
P2M_CTMU_CTMU_WKUP_MSG &= (~(BIT(1)));
lp_touch_key_send_cmd(CTMU_M2P_DISABLE);
while (!(P2M_CTMU_CTMU_WKUP_MSG & BIT(1)));
__this->softoff_mode = LP_TOUCH_SOFTOFF_MODE_LEGACY;
}
void lp_touch_key_enable(void)
{
log_debug("%s", __func__);
lp_touch_key_send_cmd(CTMU_M2P_ENABLE);
__this->softoff_mode = LP_TOUCH_SOFTOFF_MODE_ADVANCE;
}
void lp_touch_key_charge_mode_enter()
{
#if (!LP_TOUCH_KEY_CHARGE_MODE_SW_DISABLE)
while (!__this->ch_init & BIT(0)) {
asm volatile("nop");
}
log_debug("%s", __func__);
P2M_CTMU_CTMU_WKUP_MSG &= (~(BIT(1)));
lp_touch_key_send_cmd(CTMU_M2P_CHARGE_ENTER_MODE);
while (!(P2M_CTMU_CTMU_WKUP_MSG & BIT(1)));
__this->softoff_mode = LP_TOUCH_SOFTOFF_MODE_LEGACY;
#endif
}
void lp_touch_key_charge_mode_exit()
{
#if (!LP_TOUCH_KEY_CHARGE_MODE_SW_DISABLE)
log_debug("%s", __func__);
lp_touch_key_send_cmd(CTMU_M2P_CHARGE_EXIT_MODE);
__this->softoff_mode = LP_TOUCH_SOFTOFF_MODE_ADVANCE;
#endif
}
//=============================================//
//NOTE: 该函数为进关机时被库里面回调
//在板级配置struct low_power_param power_param中变量lpctmu_en配置为TCFG_LP_TOUCH_KEY_ENABLE时:
//该函数在决定softoff进触摸模式还是普通模式:
// return 1: 进触摸模式关机(LP_TOUCH_SOFTOFF_MODE_ADVANCE);
// return 0: 进普通模式关机(触摸关闭)(LP_TOUCH_SOFTOFF_MODE_LEGACY);
//使用场景:
// 1)在充电舱外关机, 需要触摸开机, 进带触摸关机模式;
// 2)在充电舱内关机,可以关闭触摸模块, 进普通关机模式, 关机功耗进一步降低.
//=============================================//
u8 lp_touch_key_softoff_mode_query(void)
{
return __this->softoff_mode;
}
//================ bt tws debug ====================//
int tws_api_send_data_to_sibling(void *data, u16 len, u32 func_id);
static int tws_api_send_data_test(void *data, int len, u32 func_id)
{
int ret = -EINVAL;
local_irq_disable();
ret = tws_api_send_data_to_sibling(data, len, func_id);
local_irq_enable();
return ret;
}
static void res_receive_handle(void *_data, u16 len, bool rx)
{
static u32 cnt0 = 0;
static u32 cnt1 = 0;
u32 *data = _data;
if (rx) {
if (data[0] == BT_CH0_RES_MSG) {
/*log_debug("len = %d, RES0 = %08d", len, data[1]);*/
log_debug("cnt: %08d, ch0: %08d, iir: %08d\n", cnt1++, (data[1] >> 16), (data[1] & 0xffff));
} else if (data[0] == BT_CH1_RES_MSG) {
/*log_debug("RES1 ORIGIN = %08d", data[1] & 0xFFFF);*/
log_debug("cnt: %08d, trim: %08d, ch0: %08d, ch0_iir: %08d, ch1: %08d, ch0-ch1 %08d", cnt1++, (data[1] >> 16), data[1] & 0xFFFF, (data[2] >> 16), data[2] & 0xFFFF, (data[3] & 0xFFFF));
} else if (data[0] == BT_EVENT_SW_MSG) {
log_debug("len = %d, %d ms", len, data[1]);
if (data[2] == EPD_IN) {
log_debug("SW: IN");
} else if (data[2] == EPD_OUT) {
log_debug("SW: OUT");
}
} else if (data[0] == BT_EVENT_HW_MSG) {
log_debug("len = %d, %d ms", len, data[1]);
if (data[2] == CH1_EAR_IN) {
log_debug("HW: IN");
} else if (data[2] == CH1_EAR_OUT) {
log_debug("HW: OUT");
}
} else if (data[0] == BT_EVENT_VDDIO) {
log_debug("BT_EVENT_VDDIO: %d", data[2]);
}
}
}
REGISTER_TWS_FUNC_STUB(lp_touch_res_sync_stub) = {
.func_id = TWS_FUNC_ID_VOL_LP_KEY,
.func = res_receive_handle, //handle
};
//==================================================//
//============== 在线调节灵敏度参数表 ==========//
//==================================================//
#if TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE
#include "online_db_deal.h"
//LP KEY在线调试工具版本号管理
const u8 lp_key_sdk_name[16] = "AC698N";
const u8 lp_key_bt_ver[4] = {0, 0, 1, 0};
struct lp_key_ver_info {
char sdkname[16];
u8 lp_key_ver[4];
};
#if TCFG_LP_EARTCH_KEY_ENABLE
//版本号 按键事件个数 按键事件个数
const char ch_content[] = {0x01, 'c', 'h', '0', '\0', 6, 0, 1, 2, 3, 4, 5, 'c', 'h', '1', '\0', 2, 10, 11}; //ch0 & ch1
#else
const char ch_content[] = {0x01, 'c', 'h', '0', '\0', 6, 0, 1, 2, 3, 4, 5}; //only ch0
#endif /* #if TCFG_LP_EARTCH_KEY_ENABLE */
enum {
TOUCH_RECORD_GET_VERSION = 0x05,
TOUCH_RECORD_GET_CH_SIZE = 0x0B,
TOUCH_RECORD_GET_CH_CONTENT = 0x0C,
TOUCH_RECORD_CHANGE_MODE = 0x0E,
TOUCH_RECORD_COUNT = 0x200,
TOUCH_RECORD_START,
TOUCH_RECORD_STOP,
ONLINE_OP_QUERY_RECORD_PACKAGE_LENGTH,
TOUCH_CH_CFG_UPDATE = 0x3000,
TOUCH_CH_VOL_CFG_UPDATE = 0x3001,
TOUCH_CH_CFG_CONFIRM = 0x3100,
};
enum {
LP_KEY_ONLINE_ST_INIT,
LP_KEY_ONLINE_ST_READY,
LP_KEY_ONLINE_ST_CH_RES_DEBUG_START,
LP_KEY_ONLINE_ST_CH_RES_DEBUG_STOP,
LP_KEY_ONLINE_ST_CH_KEY_DEBUG_START,
LP_KEY_ONLINE_ST_CH_KEY_DEBUG_CONFIRM,
};
//小机接收命令包格式, 使用DB_PKT_TYPE_TOUCH通道接收
typedef struct {
int cmd_id;
int mode;
int data[];
} touch_receive_cmd_t;
//小机发送按键消息格式, 使用DB_PKT_TYPE_TOUCH通道发送
typedef struct {
u32 cmd_id;
u32 mode;
u32 key_event;
} lp_touch_online_key_event_t;
typedef struct {
u8 state;
u8 current_record_ch;
u16 res_packet;
struct ch_adjust_table ch0_debug_cfg;
struct ch_adjust_table ch1_debug_cfg;
lp_touch_online_key_event_t online_key_event;
struct ch_ana_cfg ch0_ana;
struct ch_ana_cfg ch1_ana;
} lp_touch_key_online;
static lp_touch_key_online lp_key_online = {0};
static int lp_touch_key_online_debug_key_event_handle(u8 ch_index, struct sys_event *event)
{
int err = 0;
if ((lp_key_online.state == LP_KEY_ONLINE_ST_CH_KEY_DEBUG_START) && (lp_key_online.current_record_ch == ch_index)) {
lp_key_online.online_key_event.cmd_id = 0x3100;
lp_key_online.online_key_event.mode = 0;
lp_key_online.online_key_event.key_event = event->u.key.event;
log_debug("send %d event to PC", lp_key_online.online_key_event.key_event);
err = app_online_db_send(DB_PKT_TYPE_TOUCH, (u8 *)(&(lp_key_online.online_key_event)), sizeof(lp_touch_online_key_event_t));
}
if ((lp_key_online.state == LP_KEY_ONLINE_ST_CH_KEY_DEBUG_CONFIRM) ||
(lp_key_online.state <= LP_KEY_ONLINE_ST_READY)) {
return 0;
}
return 1;
}
static int lp_touch_key_debug_reinit_config(void)
{
//==============================================================//
// CH0 初始化 //
//==============================================================//
__lpctmu_reset(1); //模块复位
LP_CTMU_SWITCH_STABLE_TIME_SET();
//CTMU 时基配置:
u16 time_prd = 0;
if (__this->lrc_hz) {
time_prd = (__this->lrc_hz * CTMU_TIME_BASE) / 1000 - 1;
} else {
time_prd = CFG_M2P_CTMU_BASE_TIME_PRD;
}
LP_CTMU_TIMER_BASE_CONFIG(time_prd);
log_info("LRC_HZ = %d, time_prd = %d", __this->lrc_hz, time_prd);
if (__this->config->ch0.enable) {
//PB1和PB2通道互换IO:
if (__this->config->ch0.port == IO_PORTB_02) {
LP_CTMU_IO_INV(1);
} else {
LP_CTMU_IO_INV(0);
ASSERT(__this->config->ch0.port == IO_PORTB_01);
}
M2P_CTMU_MSG |= CTMU_INIT_CH0_ENABLE;
ctmu_port_init(__this->config->ch0.port);
//模拟参数配置:
if (lp_key_online.ch0_ana.isel) {
LP_CTMU_CH0_ANA_CFG(((lp_key_online.ch0_ana.vlsel << 5) | (lp_key_online.ch0_ana.vhsel << 3) | (lp_key_online.ch0_ana.isel << 0)));
} else {
LP_CTMU_CH0_ANA_CFG(get_lpctmu_ana_level());
}
//通用配置:
LP_CTMU_CH0_ENABLE(1); //通道0使能
LP_CTMU_CH0_FILTER_LEVEL(1); //通道0滤波级数
LP_CTMU_CH0_FILTER_EN(1); //通道0滤波使能
LP_CTMU_CH0_EDGE_EN(1); //通道0边沿检测使能
LP_CTMU_CH0_EDGE_TEMP_EN(1); //fixed
LP_CTMU_CH0_FIRST_RISE_MASK(0); //屏蔽第一个上升沿
//上升沿中断:
LP_CTMU_CH0_FALL_PENDING_CLR();
LP_CTMU_CH0_FALL_PENDING_IE(1);
LP_CTMU_CH0_FALL_PENDING_SEL(0);
//下升沿中断:
LP_CTMU_CH0_RISE_PENDING_CLR();
LP_CTMU_CH0_RISE_PENDING_IE(1);
LP_CTMU_CH0_RISE_PENDING_SEL(0);
//多击模式:
LP_CTMU_CH0_SHORT_KEY_MODE(1);
if (M2P_CTMU_MSG & CTMU_INIT_CH0_DEBUG) {
LP_CTMU_CH0_RES_PENDING_IE(1);
}
LP_CTMU_CH0_SHORT_KEY_TRIGGER(0);
LP_CTMU_CH0_SHORT_PENDING_CLR();
LP_CTMU_CH0_SHORT_PENDING_IE(0);
LP_CTMU_CH0_LONG_PENDING_CLR();
LP_CTMU_CH0_LONG_PENDING_IE(1);
LP_CTMU_CH0_HOLD_PENDING_CLR();
LP_CTMU_CH0_HOLD_PENDING_IE(1);
LP_CTMU_CH0_HOLD_EN(1);
LP_CTMU_CH0_KEY_MODE_ENABLE(1);
//快速 & 低速扫描周期
LP_CTMU_CH0_HIGH_SPEED_PRD(CFG_CTMU_CH0_HS_PERIOD_VALUE);
LP_CTMU_CH0_LOW_SPEED_PRD(CFG_CTMU_CH0_LS_PERIOD_VALUE);
//采样窗口时间
LP_CTMU_CH0_DET_TIME(CFG_CTMU_CH0_WINDOW_TIME_VALUE);
//CH0阈值:
LP_CTMU_CH0_TEMP_TH(lp_key_online.ch0_debug_cfg.cfg0);
LP_CTMU_CH0_STABLE_TH(lp_key_online.ch0_debug_cfg.cfg0 + 5);
LP_CTMU_CH0_EDGE_TH(lp_key_online.ch0_debug_cfg.cfg2);
M2P_CTMU_CH0_CFG2H = (lp_key_online.ch0_debug_cfg.cfg2 >> 8) & 0xff;
M2P_CTMU_CH0_CFG2L = (lp_key_online.ch0_debug_cfg.cfg2 >> 0) & 0xff;
//CH0 按键时间:
LP_CTMU_CH0_SHORT_KEY_TIME(CFG_M2P_CTMU_CH0_SHORT_TIME_VALUE);
LP_CTMU_CH0_LONG_KEY_TIME(CFG_M2P_CTMU_CH0_LONG_TIME_VALUE);
LP_CTMU_CH0_HOLD_KEY_TIME(CFG_M2P_CTMU_CH0_HOLD_TIME_VALUE);
LP_CTMU_CH0_IE(1);
//长按开机时间配置
M2P_CTMU_CH0_SOFTOFF_LONG_TIMEL = (CFG_M2P_CTMU_CH0_SOFTOFF_LONG_TIME & 0xFF);
M2P_CTMU_CH0_SOFTOFF_LONG_TIMEH = ((CFG_M2P_CTMU_CH0_SOFTOFF_LONG_TIME >> 8) & 0xFF);
#if 0
log_info("P11_LCTM_CON = 0x%x", P11_LCTM_CON);
log_info("LCTM_MOD = 0x%x", LCTM_MOD);
log_info("LCTM_TMR = 0x%x", LCTM_TMR);
log_info("LCTM_TIME_BASE_H = 0x%x", LCTM_TIME_BASE_H);
log_info("LCTM_TIME_BASE_L = 0x%x", LCTM_TIME_BASE_L);
log_info("LCTM_CHL0_ANA = 0x%x", LCTM_CHL0_ANA);
log_info("LCTM_CHL0_CON0 = 0x%x", LCTM_CHL0_CON0);
log_info("LCTM_CHL0_CON1 = 0x%x", LCTM_CHL0_CON1);
log_info("LCTM_CHL0_CON2 = 0x%x", LCTM_CHL0_CON2);
log_info("LCTM_CHL0_CON3 = 0x%x", LCTM_CHL0_CON3);
log_info("LCTM_CHL0_HS_PRD = 0x%x", LCTM_CHL0_HS_PRD);
log_info("LCTM_CHL0_LS_PRD = 0x%x", LCTM_CHL0_LS_PRD);
log_info("LCTM_CHL0_DET_TIME_H = 0x%x", LCTM_CHL0_DET_TIME_H);
log_info("LCTM_CHL0_DET_TIME_L = 0x%x", LCTM_CHL0_DET_TIME_L);
log_info("LCTM_CHL0_TEMP_H = 0x%x", LCTM_CHL0_TEMP_H);
log_info("LCTM_CHL0_TEMP_L = 0x%x", LCTM_CHL0_TEMP_L);
log_info("LCTM_CHL0_STA_H = 0x%x", LCTM_CHL0_STA_H);
log_info("LCTM_CHL0_STA_L = 0x%x", LCTM_CHL0_STA_L);
log_info("LCTM_CHL0_EDGE_H = 0x%x", LCTM_CHL0_EDGE_H);
log_info("LCTM_CHL0_EDGE_L = 0x%x", LCTM_CHL0_EDGE_L);
log_info("LCTM_CHL0_SHORT_H = 0x%x", LCTM_CHL0_SHORT_H);
log_info("LCTM_CHL0_SHORT_L = 0x%x", LCTM_CHL0_SHORT_L);
log_info("LCTM_CHL0_LONG_H = 0x%x", LCTM_CHL0_LONG_H);
log_info("LCTM_CHL0_LONG_L = 0x%x", LCTM_CHL0_LONG_L);
log_info("LCTM_CHL0_HOLD_H = 0x%x", LCTM_CHL0_HOLD_H);
log_info("LCTM_CHL0_HOLD_L = 0x%x", LCTM_CHL0_HOLD_L);
#endif
}
//==============================================================//
// CH1 初始化 //
//==============================================================//
if (__this->config->ch1.enable) {
if (__this->config->ch1.port == IO_PORTB_01) {
LP_CTMU_IO_INV(1);
} else {
LP_CTMU_IO_INV(0);
ASSERT(__this->config->ch1.port == IO_PORTB_02);
}
M2P_CTMU_MSG |= CTMU_INIT_CH1_ENABLE;
ctmu_port_init(__this->config->ch1.port);
//模拟参数配置:
if (lp_key_online.ch1_ana.isel) {
LP_CTMU_CH1_ANA_CFG(((lp_key_online.ch1_ana.vlsel << 5) | (lp_key_online.ch1_ana.vhsel << 3) | (lp_key_online.ch1_ana.isel << 0)));
} else {
LP_CTMU_CH1_ANA_CFG(get_lpctmu_ana_level());
}
//通用配置:
LP_CTMU_CH1_ENABLE(1); //通道0使能
LP_CTMU_CH1_FILTER_LEVEL(1); //通道0滤波级数
LP_CTMU_CH1_FILTER_EN(1); //通道0滤波使能
LP_CTMU_CH1_EDGE_EN(1); //通道0边沿检测使能
LP_CTMU_CH1_EDGE_TEMP_EN(1); //fixed
LP_CTMU_CH1_FIRST_RISE_MASK(0); //屏蔽第一个上升沿
//上升沿中断:
LP_CTMU_CH1_FALL_PENDING_CLR();
LP_CTMU_CH1_FALL_PENDING_IE(1);
LP_CTMU_CH1_FALL_PENDING_SEL(0);
//下升沿中断:
LP_CTMU_CH1_RISE_PENDING_CLR();
LP_CTMU_CH1_RISE_PENDING_IE(1);
LP_CTMU_CH1_RISE_PENDING_SEL(0);
if (M2P_CTMU_MSG & CTMU_INIT_CH1_DEBUG) {
LP_CTMU_CH1_RES_PENDING_IE(1);
}
//快速 & 低速扫描周期
LP_CTMU_CH1_HIGH_SPEED_PRD(CFG_CTMU_CH1_HS_PERIOD_VALUE);
LP_CTMU_CH1_LOW_SPEED_PRD(CFG_CTMU_CH1_LS_PERIOD_VALUE);
//采样窗口时间
LP_CTMU_CH1_DET_TIME(CFG_CTMU_CH1_WINDOW_TIME_VALUE);
//CH1阈值:
LP_CTMU_CH1_TEMP_TH(lp_key_online.ch1_debug_cfg.cfg0);
LP_CTMU_CH1_STABLE_TH(lp_key_online.ch1_debug_cfg.cfg0 + 5);
LP_CTMU_CH1_EDGE_TH(lp_key_online.ch1_debug_cfg.cfg2);
LP_CTMU_CH1_IE(1);
#if 0
log_info("P11_LCTM_CON = 0x%x", P11_LCTM_CON);
log_info("LCTM_MOD = 0x%x", LCTM_MOD);
log_info("LCTM_TMR = 0x%x", LCTM_TMR);
log_info("LCTM_TIME_BASE_H = 0x%x", LCTM_TIME_BASE_H);
log_info("LCTM_TIME_BASE_L = 0x%x", LCTM_TIME_BASE_L);
log_info("LCTM_CHL1_ANA = 0x%x", LCTM_CHL1_ANA);
log_info("LCTM_CHL1_CON0 = 0x%x", LCTM_CHL1_CON0);
log_info("LCTM_CHL1_CON1 = 0x%x", LCTM_CHL1_CON1);
log_info("LCTM_CHL1_CON2 = 0x%x", LCTM_CHL1_CON2);
log_info("LCTM_CHL1_HS_PRD = 0x%x", LCTM_CHL1_HS_PRD);
log_info("LCTM_CHL1_LS_PRD = 0x%x", LCTM_CHL1_LS_PRD);
log_info("LCTM_CHL1_DET_TIME_H = 0x%x", LCTM_CHL1_DET_TIME_H);
log_info("LCTM_CHL1_DET_TIME_L = 0x%x", LCTM_CHL1_DET_TIME_L);
log_info("LCTM_CHL1_TEMP_H = 0x%x", LCTM_CHL1_TEMP_H);
log_info("LCTM_CHL1_TEMP_L = 0x%x", LCTM_CHL1_TEMP_L);
log_info("LCTM_CHL1_STA_H = 0x%x", LCTM_CHL1_STA_H);
log_info("LCTM_CHL1_STA_L = 0x%x", LCTM_CHL1_STA_L);
log_info("LCTM_CHL1_EDGE_H = 0x%x", LCTM_CHL1_EDGE_H);
log_info("LCTM_CHL1_EDGE_L = 0x%x", LCTM_CHL1_EDGE_L);
#endif
}
load_p11_bank_code2ram(1, 0);
//CTMU 初始化命令
lp_touch_key_send_cmd(CTMU_M2P_INIT);
return 0;
}
static int lp_touch_key_debug_reinit(u8 update_state)
{
log_debug("%s, current_record_ch = %d", __func__, lp_key_online.current_record_ch);
switch (update_state) {
case LP_KEY_ONLINE_ST_CH_RES_DEBUG_START:
if (lp_key_online.current_record_ch == 0) {
M2P_CTMU_MSG &= ~(CTMU_INIT_CH1_DEBUG);
M2P_CTMU_MSG |= CTMU_INIT_CH0_DEBUG;
} else if (lp_key_online.current_record_ch == 1) {
M2P_CTMU_MSG &= ~(CTMU_INIT_CH0_DEBUG);
M2P_CTMU_MSG |= CTMU_INIT_CH1_DEBUG;
}
break;
case LP_KEY_ONLINE_ST_CH_RES_DEBUG_STOP:
M2P_CTMU_MSG &= ~(CTMU_INIT_CH0_DEBUG);
M2P_CTMU_MSG &= ~(CTMU_INIT_CH1_DEBUG);
break;
case LP_KEY_ONLINE_ST_CH_KEY_DEBUG_START:
M2P_CTMU_MSG &= ~(CTMU_INIT_CH0_DEBUG);
M2P_CTMU_MSG &= ~(CTMU_INIT_CH1_DEBUG);
break;
case LP_KEY_ONLINE_ST_CH_KEY_DEBUG_CONFIRM:
M2P_CTMU_MSG &= ~(CTMU_INIT_CH0_DEBUG);
M2P_CTMU_MSG &= ~(CTMU_INIT_CH1_DEBUG);
break;
default:
break;
}
if (__this->short_timer != 0xFFFF) {
usr_timer_del(__this->short_timer);
__this->short_timer = 0xFFFF;
}
/* if (__this->long_timer != 0xFFFF) { */
/* usr_timer_del(__this->long_timer); */
/* __this->long_timer = 0xFFFF; */
/* } */
__this->last_key = CTMU_KEY_NULL;
lp_touch_key_debug_reinit_config();
return 0;
}
static int lp_touch_key_online_debug_parse(u8 *packet, u8 size, u8 *ext_data, u16 ext_size)
{
int res_data = 0;
touch_receive_cmd_t *touch_cmd;
int err = 0;
u8 parse_seq = ext_data[1];
struct ch_adjust_table *receive_cfg;
struct ch_ana_cfg *ana_cfg;
struct lp_key_ver_info ver_info = {0};
res_data = 4;
log_debug("%s", __func__);
put_buf(packet, size);
put_buf(ext_data, ext_size);
//memcpy(&touch_cmd, packet, sizeof(touch_receive_cmd_t));
touch_cmd = (touch_receive_cmd_t *)packet;
switch (touch_cmd->cmd_id) {
/* case TOUCH_RECORD_COUNT: */
/* log_debug("TOUCH_RECORD_COUNT"); */
/* err = app_online_db_ack(parse_seq, (u8 *)&res_data, 4); */
/* break; */
case TOUCH_RECORD_START:
log_debug("TOUCH_RECORD_START");
err = app_online_db_ack(parse_seq, (u8 *)&res_data, 1); //该命令随便ack一个byte即可
lp_key_online.state = LP_KEY_ONLINE_ST_CH_RES_DEBUG_START;
lp_touch_key_debug_reinit(lp_key_online.state);
break;
case TOUCH_RECORD_STOP:
log_debug("TOUCH_RECORD_STOP");
app_online_db_ack(parse_seq, (u8 *)&res_data, 1); //该命令随便ack一个byte即可
lp_key_online.state = LP_KEY_ONLINE_ST_CH_RES_DEBUG_STOP;
lp_touch_key_debug_reinit(lp_key_online.state);
break;
/* case ONLINE_OP_QUERY_RECORD_PACKAGE_LENGTH: */
/* log_debug("ONLINE_OP_QUERY_RECORD_PACKAGE_LENGTH"); */
/* err = app_online_db_ack(parse_seq, (u8 *)&res_data, 4); //回复对应的通道数据长度 */
/* break; */
case TOUCH_CH_CFG_UPDATE:
log_debug("TOUCH_CH_CFG_UPDATE");
app_online_db_ack(parse_seq, (u8 *)"OK", 2); //该命令随便ack "OK"字符串
lp_key_online.state = LP_KEY_ONLINE_ST_CH_KEY_DEBUG_START;
receive_cfg = (struct ch_adjust_table *)(touch_cmd->data);
if (lp_key_online.current_record_ch == 0) {
lp_key_online.ch0_debug_cfg.cfg0 = receive_cfg->cfg0;
lp_key_online.ch0_debug_cfg.cfg1 = receive_cfg->cfg1;
lp_key_online.ch0_debug_cfg.cfg2 = receive_cfg->cfg2;
} else if (lp_key_online.current_record_ch == 1) {
lp_key_online.ch1_debug_cfg.cfg0 = receive_cfg->cfg0;
lp_key_online.ch1_debug_cfg.cfg1 = receive_cfg->cfg1;
lp_key_online.ch1_debug_cfg.cfg2 = receive_cfg->cfg2;
}
log_debug("update CH %d, cfg0 = %d, cfg1 = %d, cfg2 = %d", lp_key_online.current_record_ch, receive_cfg->cfg0, receive_cfg->cfg1, receive_cfg->cfg2);
lp_touch_key_debug_reinit(lp_key_online.state);
break;
case TOUCH_CH_VOL_CFG_UPDATE:
log_debug("TOUCH_CH_VOL_CFG_UPDATE");
app_online_db_ack(parse_seq, (u8 *)"OK", 2); //回"OK"字符串
ana_cfg = (struct ch_ana_cfg *)(touch_cmd->data);
if (lp_key_online.current_record_ch == 0) {
lp_key_online.ch0_ana.isel = ana_cfg->isel;
lp_key_online.ch0_ana.vhsel = ana_cfg->vhsel;
lp_key_online.ch0_ana.vlsel = ana_cfg->vlsel;
} else if (lp_key_online.current_record_ch == 1) {
lp_key_online.ch1_ana.isel = ana_cfg->isel;
lp_key_online.ch1_ana.vhsel = ana_cfg->vhsel;
lp_key_online.ch1_ana.vlsel = ana_cfg->vlsel;
}
log_debug("update, isel = %d, vhsel = %d, vlsel = %d", lp_key_online.ch_ana.isel, lp_key_online.ch_ana.vhsel, lp_key_online.ch_ana.vlsel);
break;
case TOUCH_CH_CFG_CONFIRM:
log_debug("TOUCH_CH_CFG_CONFIRM");
app_online_db_ack(parse_seq, (u8 *)"OK", 2); //回"OK"字符串
lp_key_online.state = LP_KEY_ONLINE_ST_CH_KEY_DEBUG_CONFIRM;
break;
case TOUCH_RECORD_GET_VERSION:
log_debug("TOUCH_RECORD_GET_VERSION");
memcpy(ver_info.sdkname, lp_key_sdk_name, sizeof(lp_key_sdk_name));
memcpy(ver_info.lp_key_ver, lp_key_bt_ver, sizeof(lp_key_bt_ver));
app_online_db_ack(parse_seq, (u8 *)(&ver_info), sizeof(ver_info)); //回复版本号数据结构
break;
case TOUCH_RECORD_GET_CH_SIZE:
log_debug("TOUCH_RECORD_GET_CH_SIZE");
res_data = sizeof(ch_content);
err = app_online_db_ack(parse_seq, (u8 *)&res_data, 4); //回复对应的通道数据长度
break;
case TOUCH_RECORD_GET_CH_CONTENT:
log_debug("TOUCH_RECORD_GET_CH_CONTENT");
app_online_db_ack(parse_seq, (u8 *)(&ch_content), sizeof(ch_content));
break;
case TOUCH_RECORD_CHANGE_MODE:
log_debug("TOUCH_RECORD_CHANGE_MODE, cmd_mode = %d", touch_cmd->mode);
lp_key_online.current_record_ch = touch_cmd->mode;
if (lp_key_online.current_record_ch == 0) {
lp_key_online.ch0_ana.isel = 0;
} else if (lp_key_online.current_record_ch == 1) {
lp_key_online.ch1_ana.isel = 0;
}
app_online_db_ack(parse_seq, (u8 *)"OK", 2); //回"OK"字符串
break;
default:
break;
}
return 0;
}
static int lp_touch_key_online_debug_send(u8 ch, u16 val)
{
int err = 0;
putchar('s');
if (lp_key_online.state == LP_KEY_ONLINE_ST_CH_RES_DEBUG_START) {
lp_key_online.res_packet = val;
err = app_online_db_send(DB_PKT_TYPE_DAT_CH0, (u8 *)(&(lp_key_online.res_packet)), 2);
}
return err;
}
static int lp_touch_key_online_debug_init(void)
{
log_debug("%s", __func__);
app_online_db_register_handle(DB_PKT_TYPE_TOUCH, lp_touch_key_online_debug_parse);
lp_key_online.state = LP_KEY_ONLINE_ST_READY;
u8 ch0_sensity = __this->config->ch0.sensitivity;
u8 ch1_sensity = __this->config->ch1.sensitivity;
if (__this->config->ch0.enable) {
lp_key_online.ch0_debug_cfg.cfg0 = ch0_sensitivity_table[ch0_sensity].cfg0;
lp_key_online.ch0_debug_cfg.cfg1 = ch0_sensitivity_table[ch0_sensity].cfg1;
lp_key_online.ch0_debug_cfg.cfg2 = ch0_sensitivity_table[ch0_sensity].cfg2;
}
if (__this->config->ch1.enable) {
lp_key_online.ch1_debug_cfg.cfg0 = ch1_sensitivity_table[ch1_sensity].cfg0;
lp_key_online.ch1_debug_cfg.cfg1 = ch1_sensitivity_table[ch1_sensity].cfg1;
lp_key_online.ch1_debug_cfg.cfg2 = ch1_sensitivity_table[ch1_sensity].cfg2;
}
return 0;
}
int lp_touch_key_online_debug_exit(void)
{
return 0;
}
#endif /* #if TCFG_LP_TOUCH_KEY_BT_TOOL_ENABLE */
#endif