bsp_tkey.c 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947
  1. #include "include.h"
  2. #define USER_TKEY_MROM_EN 1 //使用rom tkey process
  3. extern tk_cb_t tk_cb;
  4. extern tk_cb_t te_cb;
  5. extern te_cali_cb_t te_cali_cb;
  6. extern u16 tkcnt_tmr[4]; //每个通路的实时TKCNT
  7. extern u8 tk_ch_temp;
  8. extern tk_cb_t tk1_cb;
  9. #if (USER_TKEY_SLIDE || USER_TKEY_SHORT_SLIDE || USER_TKEY_MULTI_EN)
  10. u32 tkbcnt_tmr[3];
  11. tk_multi_cb_t tk_multi_cb;
  12. tk_multi_cb_t tk1_multi_cb;
  13. #endif
  14. #if USER_TKEY_PB3_EN
  15. tk_cb_t tk2_cb;
  16. tk_multi_cb_t tk2_multi_cb;
  17. #endif
  18. #if USER_TKEY_PA7_EN
  19. tk_cb_t tk3_cb;
  20. tk_multi_cb_t tk3_multi_cb;
  21. #endif
  22. #if USER_TKEY_SLIDE
  23. key_slide_cb_t key_slide_cb;
  24. #endif
  25. int s_abs(int x);
  26. void tkey_slide_msg(u8 silde_up);
  27. u8 tkey_slide_is_pressed(tk_cb_t *s, tk_cb_t *p);
  28. void bsp_charge_bcnt_calibration_m(u32 min_avg_cnt);
  29. u8 tkey_multi_is_pressed(void);
  30. void tkey_bcnt_range_exception_fix(tk_multi_cb_t *tkm, u16 tkcnt, u8 tk_flag);
  31. void bsp_tkey_spp_tx_m(void);
  32. bool tkey_is_pressed_m(void);
  33. u8 bsp_tkey_scan_m(void);
  34. void key_multi_press_clr(void);
  35. void tkey_slide_up_down_check(tk_slide_cb_t *ts, tk_slide_cb_t *tp);
  36. u8 bsp_short_slide_tkey_scan(void);
  37. AT(.rodata.tkey)
  38. const char tk_fil_high_tbl[8] = {
  39. 4, 6, 8, 10, 12, 13, 14, 15
  40. };
  41. #if USER_TKEY
  42. #if (USER_TKEY_SLIDE || USER_TKEY_SHORT_SLIDE)
  43. AT(.com_text.tkey.isr)
  44. void tkey_slide_message_do(tk_cb_t *tkey_slide)
  45. {
  46. tk_multi_cb_t *tkm = slide_cb[0].tk_slide;
  47. if (tkey_slide->ch == tkm->tkey->ch) {
  48. tkey_slide_msg(1); //上滑
  49. } else {
  50. tkey_slide_msg(0);
  51. }
  52. }
  53. AT(.com_text.tkey.isr)
  54. void tkey_slide_set_release(tk_multi_cb_t *tkm)
  55. {
  56. tk_slide_cb_t *ts0 = &slide_cb[0];
  57. tk_slide_cb_t *ts1 = &slide_cb[1];
  58. if (ts0->tk_slide == tkm) {
  59. ts0->release_tick = tick_get();
  60. ts0->release = 1;
  61. } else if (ts1->tk_slide == tkm) {
  62. ts1->release_tick = tick_get();
  63. ts1->release = 1;
  64. }
  65. }
  66. #endif
  67. #if USER_TKEY_SHORT_SLIDE
  68. #if USER_TKEY_SHORT_SLIDE_DEBUG_EN
  69. AT(.rodata.tkey)
  70. const char tkcnt_str[] = "[TK] State(%01x), TKBCNT(%03x):\n";
  71. AT(.rodata.tkey)
  72. const char tecnt_str[] = "[TE] State(%01x), TEBCNT(%03x):\n";
  73. AT(.rodata.tkey)
  74. const char tk1cnt_str[] = "[TK1] State(%01x), TKBCNT(%03x):\n";
  75. //通过蓝牙SPP打印输出, 避免UART飞线干扰
  76. void spp_slide_tkcnt_tx(void)
  77. {
  78. u16 tk_buf[8], te_buf[8];
  79. int c_len = 0, i;
  80. if (spp_tkcb.tk_print_sta) {
  81. memset(spp_tkcb.spp_buf, 0, sizeof(spp_tkcb.spp_buf));
  82. memcpy(tk_buf, &spp_tkcb.tk_buf[(spp_tkcb.tk_print_sta - 1)*8], 16);
  83. memcpy(te_buf, &spp_tkcb.te_buf[(spp_tkcb.tk_print_sta - 1)*8], 16);
  84. spp_tkcb.tk_print_sta = 0;
  85. if (tk_cb.ch != 0xff) {
  86. c_len += sprintf(spp_tkcb.spp_buf + c_len, tkcnt_str, tk_multi_cb.tkey_sta, (u16)(TKBCNT & 0xfff));
  87. for (i = 0; i < 8; i++) {
  88. c_len += sprintf(spp_tkcb.spp_buf + c_len, "%03x ", tk_buf[i] & 0xfff);
  89. }
  90. c_len += sprintf(spp_tkcb.spp_buf + c_len, "\n");
  91. }
  92. if (tk1_cb.ch != 0xff) {
  93. c_len += sprintf(spp_tkcb.spp_buf + c_len, tk1cnt_str, tk1_multi_cb.tkey_sta, (u16)(tk1_cb.bcnt_sfr[0] & 0xfff));
  94. for (i = 0; i < 8; i++) {
  95. c_len += sprintf(spp_tkcb.spp_buf + c_len, "%03x ", tk1_cb.buf[i] & 0xfff);
  96. }
  97. c_len += sprintf(spp_tkcb.spp_buf + c_len, "\n");
  98. }
  99. //#if USER_TKEY_INEAR
  100. // if (te_cb.ch != 0xff) {
  101. // c_len += sprintf(spp_tkcb.spp_buf + c_len, tecnt_str, tkey_is_inear(), (u16)(TEBCNT & 0xfff));
  102. // for (i = 0; i < 8; i++) {
  103. // c_len += sprintf(spp_tkcb.spp_buf + c_len, "%03x ", te_buf[i] & 0xfff);
  104. // }
  105. // c_len += sprintf(spp_tkcb.spp_buf + c_len, "\n");
  106. // }
  107. //#endif
  108. bt_spp_tx((uint8_t *)spp_tkcb.spp_buf, c_len);
  109. }
  110. }
  111. void bsp_slide_tkey_spp_tx(void)
  112. {
  113. if (xcfg_cb.user_tkey_debug_en) {
  114. spp_slide_tkcnt_tx(); //输出TKCNT
  115. // if (tick_check_expire(spp_tkcb.ticks, 100)) {
  116. // spp_tkcb.ticks = tick_get();
  117. // spp_inpcon_tx(); //输出一些状态
  118. // }
  119. }
  120. }
  121. #endif
  122. //AT(.com_rodata.text)
  123. //const char print_release_str[] = "===> tkey_release_ticks (%d)\n";
  124. AT(.com_text.bsp.key)
  125. u16 tkey_short_slide_process(u16 key_val)
  126. {
  127. u16 key_return = NO_KEY;
  128. tk_slide_cb_t *ts = &slide_cb[0];
  129. tk_slide_cb_t *tp = &slide_cb[1];
  130. tk_multi_cb_t *s = slide_cb[0].tk_slide;
  131. tk_multi_cb_t *p = slide_cb[1].tk_slide;
  132. static u8 slide_press_flag = 0;
  133. static u32 slide_press_ticks = 0;
  134. if ((s->tkey->ch == 0xff) || (p->tkey->ch == 0xff)) {
  135. return key_val;
  136. }
  137. //多击判断时间内不判断滑动
  138. if (slide_press_flag) {
  139. if (tick_check_expire(slide_press_ticks, xcfg_cb.double_key_time * 100 + 200)) {
  140. slide_press_flag = 0; //多击判断后清flag
  141. slide_press_ticks = 0;
  142. } else if (key_val) {
  143. slide_press_ticks = tick_get();
  144. }
  145. return key_val;
  146. }
  147. if (ts->release_tick < tp->release_tick) {
  148. ts = &slide_cb[1];
  149. tp = &slide_cb[0];
  150. s = slide_cb[1].tk_slide;
  151. p = slide_cb[0].tk_slide;
  152. }
  153. u32 tkey_release_ticks = ts->release_tick - tp->release_tick;
  154. if (((key_val & 0xff00) == KEY_SHORT_UP) && (!slide_press_flag)) {
  155. if (tkey_release_ticks > ts->slide_interval_min && tkey_release_ticks < ts->slide_interval_max * 2) {
  156. tkey_slide_message_do(s->tkey);
  157. } else if (tkey_release_ticks < ts->press_interval) {
  158. key_return = key_val;
  159. slide_press_flag = 1; //控制多击判断时间内不判断滑动
  160. slide_press_ticks = tick_get();
  161. }
  162. // printf(print_release_str, tkey_release_ticks);
  163. } else {
  164. key_return = key_val;
  165. }
  166. //添加按键提示音
  167. // if (key_return == KU_PLAY_PWR_USER_DEF) {
  168. // msg_enqueue(EVT_KEY_VOICE);
  169. // }
  170. return key_return;
  171. }
  172. #endif
  173. #if USER_TKEY_SLIDE
  174. AT(.com_text.bsp.key)
  175. void tkey_slide_clr_all_param(tk_slide_cb_t *ts)
  176. {
  177. ts->tk_slide->tkey_ticks = 0;
  178. ts->release = 0;
  179. ts->press_flag = 0;
  180. ts->slide = 0;
  181. }
  182. //AT(.com_rodata.text)
  183. //const char slide_press_str1[] = "==> slide save (%x)\n";
  184. //AT(.com_rodata.text)
  185. //const char slide_press_str2[] = "==> slide timeout\n";
  186. //AT(.com_rodata.text)
  187. //const char slide_press_str4[] = "==> slide timeout release (0x%04x)\n";
  188. //AT(.com_rodata.text)
  189. //const char slide_press_str5[] = "==> slide press\n";
  190. //AT(.com_rodata.text)
  191. //const char slide_press_str6[] = "==> slide cnt reint\n";
  192. //滑动按键检测
  193. AT(.com_text.bsp.key)
  194. u16 bsp_tkey_slide_process(u16 key_val)
  195. {
  196. u16 key_return = NO_KEY;
  197. u8 slide_clr = 0;
  198. tk_slide_cb_t *ts, *tp;
  199. ts = &slide_cb[0];
  200. tp = &slide_cb[1];
  201. if (!ts->press_flag && !tp->press_flag) {
  202. return key_val; //非滑动的IO直接返回值
  203. }
  204. if (key_val) {
  205. if (key_val & 0xff00) {
  206. if (((key_val & 0xff00) == KEY_LONG) || ((key_val & 0xff00) == KEY_LONG_UP) || ((key_val & 0xff00) == KEY_HOLD) || ((key_val & 0xff00) == KEY_LHOLD)) {
  207. key_return = key_val; //长按抬起直接返回键值
  208. slide_clr = 1;
  209. } else {
  210. key_slide_cb.key_val = key_val; //非长按抬起, 先保存下来
  211. // printf(slide_press_str1, key_slide_cb.key_val);
  212. }
  213. } else {
  214. key_return = key_val; //按下未抬起, 直接返回
  215. if (key_slide_cb.slide_cnt) {
  216. key_slide_cb.slide_cnt = key_slide_cb.delay; //刷新超时时间, 多击情况需要
  217. // printf(slide_press_str6);
  218. }
  219. }
  220. }
  221. if (key_slide_cb.slide_cnt) {
  222. key_slide_cb.slide_cnt--;
  223. }
  224. if (key_slide_cb.slide_cnt == 1) {
  225. key_slide_cb.slide_timeout = 1; //超时未判断到滑动,返回保存的值
  226. // printf(slide_press_str2);
  227. }
  228. if (key_slide_cb.slide_timeout) {
  229. if ((ts->press_flag && ts->release) || (tp->press_flag && tp->release)) {
  230. slide_clr = 1;
  231. if (ts->slide || tp->slide) {
  232. #if USER_MULTI_PRESS_EN
  233. key_multi_press_clr(); //清掉多击判断
  234. #endif
  235. } else {
  236. key_return = key_slide_cb.key_val; //超时没有判断滑动,返回保存的抬起按键
  237. // printf(slide_press_str4, key_return);
  238. }
  239. }
  240. }
  241. //第一个IO抬起后才开始计时滑动
  242. if ((ts->press_flag && ts->release) || (tp->press_flag && tp->release)) {
  243. if (key_slide_cb.slide_cnt == 0) {
  244. key_slide_cb.slide_cnt = key_slide_cb.delay; //重置滑动超时时间
  245. key_slide_cb.key_val = NO_KEY;
  246. #if USER_MULTI_PRESS_EN
  247. key_multi_press_clr(); //清掉多击判断
  248. #endif
  249. // printf(slide_press_str5);
  250. }
  251. }
  252. if (slide_clr) {
  253. key_slide_cb.slide_cnt = 0;
  254. key_slide_cb.slide_timeout = 0;
  255. key_slide_cb.key_val = NO_KEY;
  256. tkey_slide_clr_all_param(ts);
  257. tkey_slide_clr_all_param(tp);
  258. }
  259. return key_return;
  260. }
  261. #endif
  262. #if (USER_TKEY_MULTI_DEBUG_EN || USER_TKEY_SLIDE_DEBUG_EN)
  263. //AT(.com_rodata.text)
  264. //const char print_multi_tkey_str[] = "TKM -> CH[%d], STA[%d], TKCNT[0x%04x], TKBCNT[0x%04x]\n";
  265. AT(.com_text.tkey.debug)
  266. void tkey_multi_debug_info(u32 tk_ch, u16 tkcnt)
  267. {
  268. // static u32 tkey_print_cnt = 0;
  269. //
  270. // tkey_print_cnt++;
  271. // if (tkey_print_cnt % 11 == 0) {
  272. // tkey_print_cnt = 0;
  273. // spp_tkcb.tk_print_sta = 1;
  274. // u16 tkbcnt = TKBCNT & 0xfff;
  275. // if (tk_ch) {
  276. // tkbcnt = tkbcnt_tmr[tk_ch - 1];
  277. // }
  278. // printf(print_multi_tkey_str, tk_ch, tkey_multi_is_pressed(), tkcnt, tkbcnt);
  279. // }
  280. }
  281. AT(.rodata.tkey)
  282. const char tkcnt_str[] = "[TK%d] Sta %01x TKB %03x\n";
  283. AT(.rodata.tkey)
  284. const char tecnt_str[] = "[TE] Sta %01x TEB %03x\n";
  285. //通过蓝牙SPP打印输出, 避免UART飞线干扰
  286. void spp_multi_tkcnt_tx(void)
  287. {
  288. int c_len = 0, i;
  289. if (spp_tkcb.tk_print_sta) {
  290. memset(spp_tkcb.spp_buf, 0, sizeof(spp_tkcb.spp_buf));
  291. spp_tkcb.tk_print_sta = 0;
  292. if (tk_cb.ch != 0xff) {
  293. c_len += sprintf(spp_tkcb.spp_buf + c_len, tkcnt_str, tk_cb.ch, tkey_get_key(), (u16)(TKBCNT & 0xfff));
  294. for (i = 0; i < 2; i++) {
  295. c_len += sprintf(spp_tkcb.spp_buf + c_len, "%03x ", tk_cb.buf[i] & 0xfff);
  296. }
  297. c_len += sprintf(spp_tkcb.spp_buf + c_len, "\n");
  298. }
  299. #if (USER_TKEY_PB4_EN || USER_TKEY_SLIDE_DEBUG_EN)
  300. if (tk1_cb.ch != 0xff) {
  301. c_len += sprintf(spp_tkcb.spp_buf + c_len, tkcnt_str, tk1_cb.ch, tkey_multi_is_pressed(), (u16)(tk1_cb.bcnt_sfr[0] & 0xfff));
  302. for (i = 0; i < 2; i++) {
  303. c_len += sprintf(spp_tkcb.spp_buf + c_len, "%03x ", tk1_cb.buf[i] & 0xfff);
  304. }
  305. c_len += sprintf(spp_tkcb.spp_buf + c_len, "\n");
  306. }
  307. #endif
  308. #if USER_TKEY_PB3_EN
  309. if (tk2_cb.ch != 0xff) {
  310. c_len += sprintf(spp_tkcb.spp_buf + c_len, tkcnt_str, tk2_cb.ch, tkey_multi_is_pressed(), (u16)(tk2_cb.bcnt_sfr[0] & 0xfff));
  311. for (i = 0; i < 2; i++) {
  312. c_len += sprintf(spp_tkcb.spp_buf + c_len, "%03x ", tk2_cb.buf[i] & 0xfff);
  313. }
  314. c_len += sprintf(spp_tkcb.spp_buf + c_len, "\n");
  315. }
  316. #endif
  317. #if USER_TKEY_PA7_EN
  318. if (tk3_cb.ch != 0xff) {
  319. c_len += sprintf(spp_tkcb.spp_buf + c_len, tkcnt_str, tk3_cb.ch, tkey_multi_is_pressed(), (u16)(tk3_cb.bcnt_sfr[0] & 0xfff));
  320. for (i = 0; i < 2; i++) {
  321. c_len += sprintf(spp_tkcb.spp_buf + c_len, "%03x ", tk3_cb.buf[i] & 0xfff);
  322. }
  323. c_len += sprintf(spp_tkcb.spp_buf + c_len, "\n");
  324. }
  325. #endif
  326. //#if USER_TKEY_INEAR
  327. // if (te_cb.ch != 0xff) {
  328. // c_len += sprintf(spp_tkcb.spp_buf + c_len, tecnt_str, tkey_is_inear(), (u16)(TEBCNT & 0xfff));
  329. // for (i = 0; i < 4; i++) {
  330. // c_len += sprintf(spp_tkcb.spp_buf + c_len, "%03x ", te_cb.buf[i] & 0xfff);
  331. // }
  332. // c_len += sprintf(spp_tkcb.spp_buf + c_len, "\n");
  333. // }
  334. //#endif
  335. // printf("---> spp_tx : len (%d)\n", c_len);
  336. bt_spp_tx((uint8_t *)spp_tkcb.spp_buf, c_len);
  337. }
  338. }
  339. void bsp_multi_tkey_spp_tx(void)
  340. {
  341. if (xcfg_cb.user_tkey_debug_en) {
  342. spp_multi_tkcnt_tx(); //输出TKCNT
  343. // if (tick_check_expire(spp_tkcb.ticks, 100)) {
  344. // spp_tkcb.ticks = tick_get();
  345. // spp_inpcon_tx(); //输出一些状态
  346. // }
  347. }
  348. }
  349. #endif
  350. void bsp_tkey_spp_tx(void)
  351. {
  352. #if (USER_TKEY_MULTI_DEBUG_EN || USER_TKEY_SLIDE_DEBUG_EN)
  353. bsp_multi_tkey_spp_tx();
  354. #elif USER_TKEY_SHORT_SLIDE_DEBUG_EN
  355. bsp_slide_tkey_spp_tx();
  356. #else
  357. bsp_tkey_spp_tx_m();
  358. #endif
  359. }
  360. //中断回调函数
  361. AT(.com_text.tkey.isr)
  362. int tkey_tkcnt_isr_hook(u32 tk_ch, u16 tkcnt)
  363. {
  364. #if (USER_TKEY_SLIDE || USER_TKEY_SHORT_SLIDE || USER_TKEY_MULTI_EN)
  365. if (tk_ch == te_cb.ch) {
  366. tkey_bcnt_range_exception(&te_cb, tkcnt);
  367. #if USER_TKEY_DEBUG_EN
  368. spp_tkcb.te_buf[spp_tkcb.tk_idx] = tkcnt;
  369. #endif
  370. } else if (tk_ch == tk_cb.ch) {
  371. tkey_bcnt_range_exception_fix(&tk_multi_cb, tkcnt, 1);
  372. #if USER_TKEY_DEBUG_EN
  373. spp_tkcb.tk_buf[spp_tkcb.tk_idx] = tkcnt;
  374. #endif
  375. } else if (tk_ch == tk1_cb.ch) {
  376. tkey_bcnt_range_exception_fix(&tk1_multi_cb, tkcnt, 0);
  377. }
  378. #if USER_TKEY_PB3_EN
  379. else if (tk_ch == tk2_cb.ch) {
  380. tkey_bcnt_range_exception_fix(&tk2_multi_cb, tkcnt, 0);
  381. }
  382. #endif
  383. #if USER_TKEY_PA7_EN
  384. else if (tk_ch == tk3_cb.ch) {
  385. tkey_bcnt_range_exception_fix(&tk3_multi_cb, tkcnt, 0);
  386. }
  387. #endif
  388. #if USER_TKEY_SLIDE
  389. if (tk_ch == slide_cb[0].tk_slide->tkey->ch) {
  390. tkey_slide_up_down_check(&slide_cb[0], &slide_cb[1]);
  391. } else if (tk_ch == slide_cb[1].tk_slide->tkey->ch) {
  392. tkey_slide_up_down_check(&slide_cb[1], &slide_cb[0]);
  393. }
  394. #endif
  395. #if USER_TKEY_DEBUG_EN
  396. if (tk_ch == spp_tkcb.ch) {
  397. spp_tkcb.tk_idx++;
  398. if (spp_tkcb.tk_idx == 8) {
  399. spp_tkcb.tk_print_sta = 1;
  400. } else if (spp_tkcb.tk_idx >= 16) {
  401. spp_tkcb.tk_print_sta = 2;
  402. spp_tkcb.tk_idx = 0;
  403. }
  404. }
  405. #endif
  406. #if USER_TKEY_MULTI_DEBUG_EN
  407. tkey_multi_debug_info(tk_ch, tkcnt);
  408. #endif
  409. return 1;
  410. #elif !USER_TKEY_MROM_EN
  411. if (tk_ch == te_cb.ch) {
  412. tkey_bcnt_range_exception(&te_cb, tkcnt);
  413. #if USER_TKEY_DEBUG_EN
  414. spp_tkcb.te_buf[spp_tkcb.tk_idx] = tkcnt;
  415. #endif
  416. } else if (tk_ch == tk_cb.ch) {
  417. tkey_bcnt_range_exception(&tk_cb, tkcnt);
  418. tkey_timeout_calibration(&tk_cb, tkcnt);
  419. #if USER_TKEY_DEBUG_EN
  420. spp_tkcb.tk_buf[spp_tkcb.tk_idx] = tkcnt;
  421. #endif
  422. }
  423. #if USER_TKEY_SLIDE_OLD
  424. else if (tk_ch == tk1_cb.ch) {
  425. tkey_bcnt_range_exception(&tk1_cb, tkcnt);
  426. }
  427. #endif
  428. #if USER_TKEY_DEBUG_EN
  429. if (tk_ch == spp_tkcb.ch) {
  430. spp_tkcb.tk_idx++;
  431. if (spp_tkcb.tk_idx == 8) {
  432. spp_tkcb.tk_print_sta = 1;
  433. } else if (spp_tkcb.tk_idx >= 16) {
  434. spp_tkcb.tk_print_sta = 2;
  435. spp_tkcb.tk_idx = 0;
  436. }
  437. }
  438. #endif
  439. return 1;
  440. #else
  441. return 0;
  442. #endif
  443. }
  444. #if (USER_TKEY_SLIDE || USER_TKEY_MULTI_EN)
  445. AT(.com_text.bsp.tkey)
  446. u8 tkey_multi_is_pressed(void)
  447. {
  448. u8 multi_press = 0;
  449. if (tk1_multi_cb.tkey_sta) {
  450. multi_press = 1;
  451. }
  452. #if USER_TKEY_PB3_EN
  453. if (tk2_multi_cb.tkey_sta) {
  454. multi_press = 2;
  455. }
  456. #endif
  457. #if USER_TKEY_PA7_EN
  458. if (tk3_multi_cb.tkey_sta) {
  459. multi_press = 3;
  460. }
  461. #endif
  462. return multi_press;
  463. }
  464. //设置触摸通道的键值
  465. AT(.com_text.bsp.tkey)
  466. u8 bsp_tkey_multi_scan(void)
  467. {
  468. u8 key = NO_KEY;
  469. u8 multi_press = tkey_multi_is_pressed();
  470. if (multi_press == 1) {
  471. // key = KEY_PLAY_USER_DEF;
  472. key = NO_KEY; //TK1(PB4)
  473. }
  474. #if USER_TKEY_PB3_EN
  475. if (multi_press == 2) {
  476. key = NO_KEY; //TK2(PB3)
  477. }
  478. #endif
  479. #if USER_TKEY_PA7_EN
  480. if (multi_press == 3) {
  481. key = NO_KEY; //TK3(PA7)
  482. }
  483. #endif
  484. return key;
  485. }
  486. #endif
  487. #if (USER_TKEY_SLIDE || USER_TKEY_SHORT_SLIDE || USER_TKEY_MULTI_EN)
  488. AT(.com_text.tkey)
  489. bool tkey_is_pressed(void)
  490. {
  491. if (tk_cb.ch == 0xff) {
  492. return false;
  493. }
  494. if (!tkey_get_key()) {
  495. return false;
  496. }
  497. return true;
  498. }
  499. AT(.com_text.bsp.tkey)
  500. u8 bsp_tkey_scan(void)
  501. {
  502. u8 key = NO_KEY;
  503. if (tkey_is_pressed()) {
  504. key = (sys_cb.tkey_pwrdwn_en) ? KEY_PLAY_PWR_USER_DEF : KEY_PLAY_USER_DEF; //wko
  505. }
  506. #if (USER_TKEY_SLIDE || USER_TKEY_MULTI_EN)
  507. else {
  508. key = bsp_tkey_multi_scan();
  509. }
  510. #endif
  511. return key;
  512. }
  513. #if USER_TKEY_SHORT_SLIDE
  514. AT(.com_text.tkey)
  515. u8 tkey_short_slide_is_pressed(void)
  516. {
  517. tk_multi_cb_t *s = slide_cb[0].tk_slide;
  518. tk_multi_cb_t *p = slide_cb[1].tk_slide;
  519. if (s->tkey->ch == 0xff || p->tkey->ch == 0xff) {
  520. return 0;
  521. }
  522. if (s->tkey_sta && p->tkey_sta) {
  523. return 2; //同时按下判断按下
  524. }
  525. if (!s->tkey_sta && !p->tkey_sta) {
  526. return 0; //同时释放判断释放
  527. }
  528. return 1;
  529. }
  530. AT(.com_text.bsp.tkey)
  531. u8 bsp_short_slide_tkey_scan(void)
  532. {
  533. static u8 key_scan_val = NO_KEY;
  534. if (tkey_short_slide_is_pressed() == 2) {
  535. key_scan_val = (sys_cb.tkey_pwrdwn_en) ? KEY_PLAY_PWR_USER_DEF : KEY_PLAY_USER_DEF; //wko
  536. } else if (tkey_short_slide_is_pressed() == 0) {
  537. key_scan_val = NO_KEY;
  538. }
  539. return key_scan_val;
  540. }
  541. #endif
  542. #else
  543. AT(.com_text.tkey)
  544. bool tkey_is_pressed(void)
  545. {
  546. return tkey_is_pressed_m();
  547. }
  548. AT(.com_text.bsp.tkey)
  549. u8 bsp_tkey_scan(void)
  550. {
  551. return bsp_tkey_scan_m();
  552. }
  553. #endif
  554. AT(.text.bsp.tkey)
  555. void bsp_charge_bcnt_calibration(u32 min_avg_cnt)
  556. {
  557. bsp_charge_bcnt_calibration_m(min_avg_cnt);
  558. #if (USER_TKEY_SLIDE || USER_TKEY_SHORT_SLIDE || USER_TKEY_MULTI_EN)
  559. u16 tkbcnt;
  560. if (tk1_cb.ch != 0xff) {
  561. if (tk1_cb.anov_cnt > min_avg_cnt) { //tkcnt是否稳定?
  562. tkbcnt = tk1_cb.bcnt_sfr[0] & 0xfff;
  563. if (s_abs((s16)tkbcnt - (s16)tk1_cb.avg) > 2) {
  564. tk1_cb.bcnt_sfr[0] = tk1_cb.avg;
  565. }
  566. }
  567. }
  568. #if USER_TKEY_PB3_EN
  569. if (tk2_cb.ch != 0xff) {
  570. if (tk2_cb.anov_cnt > min_avg_cnt) { //tkcnt是否稳定?
  571. tkbcnt = tk2_cb.bcnt_sfr[0] & 0xfff;
  572. if (s_abs((s16)tkbcnt - (s16)tk2_cb.avg) > 2) {
  573. tk2_cb.bcnt_sfr[0] = tk2_cb.avg;
  574. }
  575. }
  576. }
  577. #endif
  578. #if USER_TKEY_PA7_EN
  579. if (tk3_cb.ch != 0xff) {
  580. if (tk3_cb.anov_cnt > min_avg_cnt) { //tkcnt是否稳定?
  581. tkbcnt = tk3_cb.bcnt_sfr[0] & 0xfff;
  582. if (s_abs((s16)tkbcnt - (s16)tk3_cb.avg) > 2) {
  583. tk3_cb.bcnt_sfr[0] = tk3_cb.avg;
  584. }
  585. }
  586. }
  587. #endif
  588. #endif
  589. }
  590. void bsp_tkey_channel_set(void)
  591. {
  592. int i;
  593. #if !USER_TKEY_PWRKEY_EN
  594. if (xcfg_cb.user_tkey)
  595. #endif
  596. {
  597. tk_cb.ch = USER_TKEY_CH_SEL; //wko
  598. spp_tkcb.ch = USER_TKEY_CH_SEL;
  599. }
  600. #if USER_TKEY_PB5_DISABLE
  601. tk_cb.ch = 0; //初始化需要
  602. #endif
  603. #if USER_TKEY_INEAR
  604. if (xcfg_cb.user_tkey_inear) {
  605. if (xcfg_cb.earin_gpio_sel == 2) { //PA7
  606. te_cb.ch = 3;
  607. } else if (xcfg_cb.earin_gpio_sel == 3) { //PB3
  608. te_cb.ch = 2;
  609. } else if (xcfg_cb.earin_gpio_sel == 4) { //PB4
  610. te_cb.ch = 1;
  611. }
  612. }
  613. #endif
  614. #if USER_TKEY_SLIDE_OLD
  615. u8 tk1_ch = 0xff;
  616. if (xcfg_cb.tkey_slide_gpio_sel) {
  617. if (xcfg_cb.tkey_slide_gpio_sel == 1) { //PA7
  618. tk1_ch = 3;
  619. } else if (xcfg_cb.tkey_slide_gpio_sel == 2) { //PB3
  620. tk1_ch = 2;
  621. } else if (xcfg_cb.tkey_slide_gpio_sel == 3) { //PB4
  622. tk1_ch = 1;
  623. }
  624. tk1_cb.ch = tk1_ch;
  625. if (tk1_ch != 0xff) {
  626. tk_cb.slide_ch = 0;
  627. tk1_cb.slide_ch = 1;
  628. }
  629. }
  630. #endif
  631. #if (USER_TKEY_SLIDE || USER_TKEY_SHORT_SLIDE)
  632. if (xcfg_cb.tkey_slide_gpio_sel) {
  633. if (xcfg_cb.tkey_slide_gpio_sel == 1) { //PA7
  634. tk1_cb.ch = 3;
  635. } else if (xcfg_cb.tkey_slide_gpio_sel == 2) { //PB3
  636. tk1_cb.ch = 2;
  637. } else if (xcfg_cb.tkey_slide_gpio_sel == 3) { //PB4
  638. tk1_cb.ch = 1;
  639. }
  640. }
  641. #endif
  642. #if USER_TKEY_MULTI_EN
  643. tk1_cb.ch = 0xff; //去掉滑动配置
  644. #endif
  645. #if USER_TKEY_PB4_EN
  646. tk1_cb.ch = 1;
  647. #endif
  648. #if USER_TKEY_PB3_EN
  649. tk2_cb.ch = 2;
  650. #endif
  651. #if USER_TKEY_PA7_EN
  652. tk3_cb.ch = 3;
  653. #endif
  654. if (te_cb.ch != 0xff) { //入耳多开一个内部通路用于校准
  655. spp_tkcb.ch = te_cb.ch;
  656. for (i = 0; i < 4; i++) {
  657. if (i != te_cb.ch && i != tk_cb.ch && i != tk1_cb.ch
  658. #if USER_TKEY_PB5_DISABLE
  659. && i //PowerKey不能开TouchKey
  660. #endif
  661. #if USER_TKEY_PB3_EN
  662. && i != tk2_cb.ch
  663. #endif
  664. #if USER_TKEY_PA7_EN
  665. && i != tk3_cb.ch
  666. #endif
  667. ) {
  668. tk_ch_temp = i;
  669. }
  670. }
  671. }
  672. }
  673. void bsp_tkey_var_init(void)
  674. {
  675. memset(&tk_cb, 0, sizeof(tk_cb));
  676. memset(&tk1_cb, 0, sizeof(tk_cb));
  677. #if (USER_TKEY_SLIDE || USER_TKEY_SHORT_SLIDE || USER_TKEY_MULTI_EN)
  678. memset(&tkbcnt_tmr, 0, sizeof(tkbcnt_tmr));
  679. memset(&tk_multi_cb, 0, sizeof(tk_multi_cb_t));
  680. memset(&tk1_multi_cb, 0, sizeof(tk_multi_cb_t));
  681. tk_multi_cb.tkey = &tk_cb;
  682. tk1_multi_cb.tkey = &tk1_cb;
  683. #if USER_TKEY_SLIDE
  684. memset(&key_slide_cb, 0, sizeof(key_slide_cb));
  685. #endif
  686. #endif
  687. #if USER_TKEY_PB3_EN
  688. memset(&tk2_cb, 0, sizeof(tk2_cb));
  689. memset(&tk2_multi_cb, 0, sizeof(tk_multi_cb_t));
  690. tk2_multi_cb.tkey = &tk2_cb;
  691. #endif
  692. #if USER_TKEY_PA7_EN
  693. memset(&tk3_cb, 0, sizeof(tk3_cb));
  694. memset(&tk3_multi_cb, 0, sizeof(tk_multi_cb_t));
  695. tk3_multi_cb.tkey = &tk3_cb;
  696. #endif
  697. memset(&te_cb, 0, sizeof(te_cb));
  698. memset(&te_cali_cb, 0, sizeof(te_cali_cb));
  699. #if USER_TKEY_DEBUG_EN
  700. memset(&spp_tkcb, 0, sizeof(spp_tkcb));
  701. spp_tkcb.ch = 0xff;
  702. #endif
  703. tk_cb.limit = 32;
  704. tk_cb.range_thresh = (u8)xcfg_cb.tkrthresh * 2 - 1; //TKRTHRESH;
  705. tk_cb.ch = 0xff;
  706. tk_cb.slide_ch = 0xff;
  707. tk_cb.fil_except = FIL_EXCEPT;
  708. tk_cb.bcnt_sfr = (psfr_t)(&TKBCNT);
  709. tk_cb.range_en = 0; //使用硬件的校准
  710. tk_cb.to_cnt = TO_EXCEPT; //10秒
  711. if (xcfg_cb.bt_pwrkey_nsec_discover > 4) {
  712. tk_cb.to_cnt = 1875; //15秒
  713. }
  714. #if USER_TKEY_SLIDE_OLD
  715. memset(&slide_cb[0], 0, sizeof(tk_slide_cb_t) * 2);
  716. slide_cb[0].slide_interval_min = xcfg_cb.tkey_slide_interval_min_sel * 5 + 15;
  717. slide_cb[0].slide_interval_max = 250; //250ms
  718. slide_cb[1].slide_interval_min = slide_cb[0].slide_interval_min;
  719. slide_cb[1].slide_interval_max = slide_cb[0].slide_interval_max;
  720. #endif
  721. #if (USER_TKEY_SLIDE || USER_TKEY_SHORT_SLIDE)
  722. memset(&slide_cb[0], 0, sizeof(tk_slide_cb_t) * 2);
  723. slide_cb[0].slide_interval_min = xcfg_cb.tkey_slide_interval_min_sel * 5 + 15;
  724. slide_cb[0].slide_interval_max = 125; //250ms, 单位2ms
  725. slide_cb[0].press_interval = 10;
  726. memcpy(&slide_cb[1], &slide_cb[0], sizeof(tk_slide_cb_t));
  727. slide_cb[0].tk_slide = &tk_multi_cb;
  728. slide_cb[1].tk_slide = &tk1_multi_cb;
  729. #if USER_TKEY_SLIDE
  730. key_slide_cb.delay = key_cb.delay + key_cb.delay / 2;
  731. #endif
  732. #endif
  733. memcpy(&tk1_cb, &tk_cb, sizeof(tk_cb_t));
  734. #if USER_TKEY_PB3_EN
  735. memcpy(&tk2_cb, &tk_cb, sizeof(tk_cb_t));
  736. #endif
  737. #if USER_TKEY_PA7_EN
  738. memcpy(&tk3_cb, &tk_cb, sizeof(tk_cb_t));
  739. #endif
  740. te_cb.limit = 36;
  741. te_cb.te_flag = 1;
  742. te_cb.range_thresh = (u8)xcfg_cb.terthresh * 2 - 2; //TERTHRESH - 2
  743. te_cb.ch = 0xff;
  744. te_cb.slide_ch = 0xff;
  745. te_cb.bcnt_sfr = (psfr_t)(&TEBCNT);
  746. te_cb.fil_except = EAR_FIL_EXCEPT;
  747. te_cb.range_en = 1;
  748. tk_ch_temp = 0xff;
  749. }
  750. #endif // USER_TKEY
  751. void bsp_tkey_init(void)
  752. {
  753. int res;
  754. bsp_tkey_var_init();
  755. #if USER_TKEY
  756. bsp_tkey_channel_set();
  757. if (POWKEY_10S_RESET && tk_cb.ch == 0) {
  758. tk_cb.to_cnt = 1875; //15秒
  759. }
  760. if ((tk_cb.ch != 0xff) || (te_cb.ch != 0xff)) {
  761. tkey_cfg_t tkey_cfg_v;
  762. tkey_ch_t tk_ch_cfg, te_ch_cfg, tp_ch_cfg;
  763. tkey_ch_t tk1_ch_cfg;
  764. #if USER_TKEY_PB3_EN
  765. tkey_ch_t tk2_ch_cfg;
  766. #endif
  767. #if USER_TKEY_PA7_EN
  768. tkey_ch_t tk3_ch_cfg;
  769. #endif
  770. memcpy(&tk_ch_cfg, &tkey0, sizeof(tkey_ch_t));
  771. memcpy(&te_ch_cfg, &tkey_inear, sizeof(tkey_ch_t));
  772. memcpy(&tkey_cfg_v, &tkey_cfg, sizeof(tkey_cfg_t));
  773. if (tk_cb.ch != 0xff) { //touch key configure
  774. tk_ch_cfg.cdpr = (u16)xcfg_cb.tkey_cdpr * 10 + 40;
  775. tk_ch_cfg.itrim = (u32)xcfg_cb.tk_charge_current;
  776. tkey_cfg_v.key[tk_cb.ch] = &tk_ch_cfg;
  777. tkey_cfg_v.fil_high = tk_fil_high_tbl[xcfg_cb.tkey_fil_high];
  778. tkey_cfg_v.tkpthd = (u8)xcfg_cb.tkpthresh * 2; //TKPTHRESH
  779. tkey_cfg_v.tkrthd = (u8)xcfg_cb.tkrthresh * 2; //TKRTHRESH
  780. tkey_cfg_v.tklthd = tkey_cfg_v.tkpthd * 10; //LARGETHD
  781. tkey_cfg_v.to_except = tk_cb.to_cnt; //timeout except time
  782. tkey_cfg_v.tkvthd = tk_cb.limit;
  783. tkey_cfg_v.tkarthd = tk_cb.range_thresh;
  784. tk_cb.avg_exp_en = xcfg_cb.tk_avg_exp_en;
  785. tk_cb.thd_save = tkey_cfg_v.reg_tkpthd;
  786. tk_cb.thd_avg = 8;
  787. if (tkey_cfg_v.tkrthd > 10) {
  788. tk_cb.thd_avg = tkey_cfg_v.tkrthd - 2;
  789. }
  790. tk_cb.thd_delta = tk_cb.thd_avg - 3;
  791. if (tk1_cb.ch != 0xff) {
  792. memcpy(&tk1_ch_cfg, &tk_ch_cfg, sizeof(tkey_ch_t));
  793. tk1_ch_cfg.type = 3;
  794. tkey_cfg_v.key[tk1_cb.ch] = &tk1_ch_cfg;
  795. tk1_cb.to_cnt = tk_cb.to_cnt;
  796. #if (USER_TKEY_SLIDE || USER_TKEY_SHORT_SLIDE || USER_TKEY_MULTI_EN)
  797. tk1_cb.bcnt_sfr = &tkbcnt_tmr[tk1_cb.ch - 1];
  798. #endif
  799. }
  800. #if USER_TKEY_PB3_EN
  801. if (tk2_cb.ch != 0xff) {
  802. memcpy(&tk2_ch_cfg, &tk_ch_cfg, sizeof(tkey_ch_t));
  803. tk2_ch_cfg.type = 3;
  804. tkey_cfg_v.key[tk2_cb.ch] = &tk2_ch_cfg;
  805. tk2_cb.to_cnt = tk_cb.to_cnt;
  806. tk2_cb.bcnt_sfr = &tkbcnt_tmr[tk2_cb.ch - 1];
  807. }
  808. #endif
  809. #if USER_TKEY_PA7_EN
  810. if (tk3_cb.ch != 0xff) {
  811. memcpy(&tk3_ch_cfg, &tk_ch_cfg, sizeof(tkey_ch_t));
  812. tk3_ch_cfg.type = 3;
  813. tkey_cfg_v.key[tk3_cb.ch] = &tk3_ch_cfg;
  814. tk3_cb.to_cnt = tk_cb.to_cnt;
  815. tk3_cb.bcnt_sfr = &tkbcnt_tmr[tk3_cb.ch - 1];
  816. }
  817. #endif
  818. }
  819. if (te_cb.ch != 0xff) { //touch ear configure
  820. te_ch_cfg.cdpr = (u16)xcfg_cb.te_cdpr * 20;
  821. te_ch_cfg.itrim = (u32)xcfg_cb.te_charge_current;
  822. tkey_cfg_v.key[te_cb.ch] = &te_ch_cfg;
  823. tkey_cfg_v.tepthd = (u8)xcfg_cb.tepthresh * 2; //TEPTHRESH
  824. tkey_cfg_v.terthd = (u8)xcfg_cb.terthresh * 2; //TERTHRESH
  825. tkey_cfg_v.tefathd = (u8)xcfg_cb.terthresh * 2; //TERTHRESH
  826. tkey_cfg_v.telthd = tkey_cfg_v.tepthd * 10; //TE_LARGETHD
  827. }
  828. if (tk_ch_temp != 0xff) {
  829. memcpy(&tp_ch_cfg, &tkey_temp_cali_ch, sizeof(tkey_ch_t));
  830. tp_ch_cfg.itrim = (u32)xcfg_cb.te_charge_current;
  831. tkey_cfg_v.key[tk_ch_temp] = &tp_ch_cfg;
  832. }
  833. #if USER_TKEY_PB5_DISABLE
  834. tk_cb.ch = 0xff;
  835. #endif
  836. #if (USER_TKEY_PB5_DISABLE || USER_TKEY_PWRKEY_EN)
  837. tkey_cfg_v.key[0] = NULL; //关PB5的TouchKey
  838. #endif
  839. res = tkey_init((void *)&tkey_cfg_v, sys_cb.rtc_first_pwron);
  840. TKCON &= ~BIT(26);
  841. if (tk_cb.ch != 0xff) {
  842. if (!res || sys_cb.inbox_wken_flag || (RTCCON9 & BIT(4)) || (!(RTCCON9 & BIT(6)))) {
  843. delay_5ms(5);
  844. TKBCNT = tkcnt_tmr[tk_cb.ch];
  845. }
  846. }
  847. #if (USER_TKEY_SLIDE || USER_TKEY_SHORT_SLIDE || USER_TKEY_MULTI_EN)
  848. delay_5ms(5);
  849. if (tk1_cb.ch != 0xff) {
  850. tk1_cb.bcnt_sfr[0] = tkcnt_tmr[tk1_cb.ch];
  851. }
  852. #endif
  853. #if USER_TKEY_PB3_EN
  854. if (tk2_cb.ch != 0xff) {
  855. tk2_cb.bcnt_sfr[0] = tkcnt_tmr[tk2_cb.ch];
  856. }
  857. #endif
  858. #if USER_TKEY_PA7_EN
  859. if (tk3_cb.ch != 0xff) {
  860. tk3_cb.bcnt_sfr[0] = tkcnt_tmr[tk3_cb.ch];
  861. }
  862. #endif
  863. if (te_cb.ch != 0xff) {
  864. delay_5ms(4);
  865. TEBCNT = tkcnt_tmr[te_cb.ch];
  866. }
  867. } else {
  868. tkey_sw_reset();
  869. }
  870. #else
  871. tkey_sw_reset();
  872. #endif // USER_TKEY
  873. }