bsp_key.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685
  1. #include "include.h"
  2. #define VBG_VOLTAGE sys_trim.vbg_volt
  3. extern adc_cb_t adc_cb;
  4. extern key_cb_t key_cb;
  5. extern u8 pwrkey_num[6];
  6. extern u8 adkey_num[8];
  7. extern u8 iokey_num[4];
  8. extern u8 iokey_gpio[4];
  9. extern adkey_tbl_t adkey_tbuf[7];
  10. //按键多击处理
  11. typedef struct {
  12. u8 strikes;
  13. u8 counter;
  14. u16 val;
  15. } key_multi_cb_t;
  16. extern key_multi_cb_t key_multi_cb;
  17. typedef struct {
  18. u16 vbat_max[2];
  19. u16 cnt;
  20. u16 max_cnt;
  21. u16 vbat_ret;
  22. } vbat_filter_cb_t;
  23. extern vbat_filter_cb_t vbat_filter_cb;
  24. bool get_adc_val(void);
  25. u16 get_vbat_val(void);
  26. u8 bsp_tkey_scan(void);
  27. bool check_key_return(u16 key_return);
  28. void dkey_mask_bits_init(void);
  29. bool mic_bias_trim_is_en(void);
  30. u8 get_adkey(void);
  31. u16 bsp_key_process(u16 key_val);
  32. bool bsp_key_pwron_filter(u16 key_val);
  33. u16 key_slide_press_process(u16 key_val);
  34. void bsp_key_wko10s_reset(void);
  35. bool is_poweron_first_bat_insert(u32 rtccon9);
  36. u8 bsp_tkey_slide_press_scan(void);
  37. void bsp_188led_disp_set_on(void);
  38. void vbat_peek_filter(u32 *vbat);
  39. u16 get_vbat_val_m(void);
  40. u16 bsp_tkey_slide_process(u16 key_val);
  41. u16 tkey_short_slide_process(u16 key_val);
  42. u8 bsp_short_slide_tkey_scan(void);
  43. AT(.com_rodata.multi.key)
  44. const u16 key_multi_tbl[6/*4*/] = {
  45. KEY_DOUBLE, KEY_THREE, KEY_FOUR, KEY_FIVE
  46. #if TRY_KEY_SWITCH && TRY_KSE_SYNC_DUT_SWITCH
  47. ,
  48. KEY_SIX,
  49. KEY_SEVEN
  50. #endif // TRY_KSE_SYNC_DUT_SWITCH
  51. };
  52. AT(.com_rodata.key.table)
  53. const key_filter_t key_filter_tbl = {
  54. .scan_cnt = KEY_SCAN_TIMES,
  55. .up_cnt = KEY_UP_TIMES,
  56. .long_cnt = KEY_LONG_TIMES,
  57. .hold_cnt = KEY_LONG_HOLD_TIMES,
  58. };
  59. AT(.com_text.port.vbat)
  60. u16 get_vbat_val(void)
  61. {
  62. #if LED_188LED_DISP_EN
  63. static u16 vbat_bak = 0;
  64. u32 vbat = (u32)adc_cb.vbat2 * VBG_VOLTAGE / adc_cb.bg;
  65. if (xcfg_cb.vbat_peak_filter_en) {
  66. vbat_peek_filter(&vbat);
  67. }
  68. adc_cb.vbat_total = adc_cb.vbat_total - adc_cb.vbat_val + vbat; //均值
  69. adc_cb.vbat_val = adc_cb.vbat_total>>5;
  70. if(adc_cb.vbat_val > vbat_bak) {
  71. vbat = adc_cb.vbat_val - vbat_bak;
  72. } else {
  73. vbat = vbat_bak - adc_cb.vbat_val;
  74. }
  75. if (vbat >= 10) { //偏差大于一定值则更新
  76. vbat_bak = adc_cb.vbat_val;
  77. //printf(bat_str, adc_cb.vbat_val/1000, adc_cb.vbat_val%1000);
  78. }
  79. #if FPGA_EN
  80. if (vbat_bak < 2000) {
  81. return 4200; //4.2v
  82. }
  83. #endif // FPGA_EN
  84. return vbat_bak;
  85. #else
  86. return get_vbat_val_m();
  87. #endif
  88. }
  89. ////返回值 1:低电关机, 2:低电语音播报, 0:不动作
  90. //int is_lowpower_vbat_warning(void)
  91. //{
  92. // u16 lpwr_warning_vbat = (u16)LPWR_WARNING_VBAT*100 + 2900;
  93. //
  94. // if (sys_cb.vbat <= ((u16)LPWR_OFF_VBAT*100+2800)) {
  95. // if (LPWR_OFF_VBAT) {
  96. // if (!sys_cb.lpwr_cnt) {
  97. // sys_cb.lpwr_cnt = 1; //低电关机计数
  98. // } else if (sys_cb.lpwr_cnt >= 10) {
  99. // return 1; //VBAT低电关机
  100. // }
  101. // }
  102. // return 0; //VBAT低电不关机
  103. // } else {
  104. // sys_cb.lpwr_cnt = 0;
  105. //#if WARNING_LOW_BATTERY
  106. // if (sys_cb.vbat < lpwr_warning_vbat) {
  107. // #if RLED_LOWBAT_EN
  108. // if (sys_led.lowbat_led_en) {
  109. // if (!CHARGE_DC_IN()) {
  110. // rled_lowbat();
  111. // } else {
  112. // rled_lowbat_recover();
  113. // }
  114. // }
  115. // #endif
  116. // if (LPWR_WARNING_VBAT) {
  117. // return 2; //低电压提示音播报
  118. // }
  119. // } else if (sys_cb.vbat > (lpwr_warning_vbat + (u16)sys_cb.lpwr_leave_vbat * 50)) { //电池离开低电报警电压0.10V以上, 关闭低电的显示状态
  120. // sys_cb.lpwr_warning_limit_cnt = 0;
  121. // #if RLED_LOWBAT_EN
  122. // if (sys_led.lowbat_led_en) {
  123. // rled_lowbat_recover();
  124. // }
  125. // #endif
  126. // }
  127. //#endif // WARNING_LOW_BATTERY
  128. // return 0;
  129. // }
  130. //}
  131. //充电过程中假关机处理
  132. AT(.text.bsp.power)
  133. u8 power_off_check(void)
  134. {
  135. u32 pwron_press_nms;
  136. int pwrkey_pressed_flag, ticks = 0, up_cnt = 0;
  137. u8 restart_chk_en = 1;
  138. pwrkey_pressed_flag = 0;
  139. pwron_press_nms = PWRON_PRESS_TIME;
  140. if (pwron_press_nms == 0) {
  141. pwron_press_nms = 15; //bootloader 80ms + 15ms, 最小开机时间在100ms左右
  142. }
  143. //要等PWRKEY开关释放后再次按下才能重新开机, 否则充电过程中5分钟关机, 低电关机等异常
  144. if ((PWRKEY_2_HW_PWRON) && (sys_cb.poweron_flag)) {
  145. restart_chk_en = 0;
  146. sys_cb.poweron_flag = 0;
  147. }
  148. while (1) {
  149. WDT_CLR();
  150. delay_ms(5);
  151. if ((bsp_key_pwr_scan() & K_PWR_MASK) == K_PWR) {
  152. up_cnt = 0;
  153. if (restart_chk_en) {
  154. if (!pwrkey_pressed_flag) {
  155. ticks = tick_get();
  156. pwrkey_pressed_flag = 1;
  157. sys_cb.ms_ticks = tick_get(); //记录PWRKEY按键按下的时刻
  158. sys_cb.pwrkey_5s_check = 1;
  159. }
  160. if (!sys_cb.poweron_flag) {
  161. if (tick_check_expire(ticks, pwron_press_nms)) { //长按开机时间配置
  162. sys_cb.poweron_flag = 1;
  163. sys_cb.pwrdwn_hw_flag = 0; //清PWRKEY硬开关的关机标志
  164. sys_cb.hall_2_pwrdwn_flag = 0; //清霍尔传感器的关机标志
  165. }
  166. }
  167. }
  168. } else {
  169. if (up_cnt < 3) {
  170. up_cnt++;
  171. }
  172. if (up_cnt == 3) {
  173. up_cnt = 10;
  174. sys_cb.poweron_flag = 0;
  175. pwrkey_pressed_flag = 0;
  176. restart_chk_en = 1;
  177. }
  178. }
  179. if (sys_cb.poweron_flag) {
  180. if ((CHARGE_DC_NOT_PWRON) && CHARGE_DC_IN()) {
  181. continue;
  182. }
  183. #if LINEIN_2_PWRDOWN_EN
  184. if ((xcfg_cb.linein_2_pwrdown_en) && (device_is_online(DEV_LINEIN))) {
  185. continue;
  186. }
  187. #endif // LINEIN_2_PWRDOWN_EN
  188. //长按PP/POWER开机
  189. // gui_display(DISP_POWERON);
  190. led_power_up();
  191. dac_restart();
  192. bsp_change_volume(sys_cb.vol);
  193. #if WARNING_POWER_ON
  194. sys_warning_play(T_WARNING_POWER_ON, PIANO_POWER_ON);
  195. #endif // WARNING_POWER_ON
  196. func_cb.sta = FUNC_BT;
  197. return 0;
  198. } else {
  199. if (CHARGE_DC_IN()) { //DC IN = 1
  200. continue;
  201. } else {
  202. return 1; //VUSB拔出关机
  203. }
  204. }
  205. }
  206. }
  207. AT(.text.bsp.power)
  208. static void power_on_check_do(void)
  209. {
  210. u8 chbox_sta = 1, chbox_out2pwr_en = 0;
  211. int pwrkey_pressed_flag = 0;
  212. u32 pwron_press_nms;
  213. u32 rtccon9 = RTCCON9; //wakeup pending
  214. u32 lvdcon = LVDCON;
  215. u8 key_val;
  216. RTCCON9 = 0xfff; //Clr pending
  217. #if CHARGE_PULL_OUT_FILTER_EN
  218. //因为没有时钟,所以RTCCON10 BIT(3)置上之后,清的操作就没有释放,导致DC_IN无法正确识别
  219. //由于5V复位功能打开,如果打开时钟后,去置RTCCON10 BIT(3),就会导致在5V插着的状态下,重新识别一次5V插入导致复位,所以不能清除该BIT(3)
  220. RTCCON0 |= BIT(0);
  221. RTCCON10 = 0xff7; //Clr pending
  222. #else
  223. RTCCON10 = 0xfff; //Clr pending
  224. #endif
  225. RTCCON1 &= ~BIT(6); //wko pin low level wakeup
  226. CRSTPND = 0x1ff0000; //clear reset pending
  227. LVDCON &= ~(0x1f << 8); //clear software reset
  228. if (lvdcon & BIT(19)) {
  229. if (IS_PWRKEY_PRESS()) {
  230. sys_cb.poweron_flag = 1;
  231. }
  232. return; //长按PWRKEY 10S复位后直接开机。
  233. }
  234. if ((sys_cb.sw_rst_flag == SW_RST_FLAG) ||
  235. #if VUSB_TBOX_QTEST_EN
  236. get_qtest_mode() //下面是charge低功耗的初始化,所以qtest需要返回
  237. #endif
  238. ){
  239. return;
  240. }
  241. if ((rtccon9 & BIT(4)) && (xcfg_cb.ch_out_auto_pwron_en)) { //charge inbox wakeup直接开机
  242. if (bsp_charge_outbox_stable_check()) {
  243. sys_cb.outbox_pwron_flag = 1;
  244. //printf("inbox wakeup\n");
  245. return;
  246. }
  247. }
  248. #if USER_PWRKEY
  249. int up_cnt = 0, ticks = 0;
  250. if (IS_PWRKEY_PRESS() || IS_TKEY_PRESS()) { //PWRKEY是否按下
  251. pwrkey_pressed_flag = 1;
  252. ticks = sys_cb.ms_ticks;
  253. }
  254. #endif // USER_PWRKEY
  255. pwron_press_nms = PWRON_PRESS_TIME;
  256. if (pwron_press_nms == 0) {
  257. pwron_press_nms = 15; //bootloader 80ms + 15ms, 最小开机时间在100ms左右
  258. }
  259. //是否充电复位决定是否要拿起开机
  260. if ((lvdcon & BIT(17)) || (rtccon9 & BIT(3)) || (sys_cb.sw_rst_flag == SW_RST_DC_IN) || (sys_cb.inbox_wken_flag)) {
  261. chbox_out2pwr_en = xcfg_cb.ch_out_auto_pwron_en;
  262. CRSTPND = BIT(17);
  263. }
  264. bsp_charge_box_enter(chbox_out2pwr_en);
  265. //第一次上电是否直接开机
  266. if (is_poweron_first_bat_insert(rtccon9) || (sys_cb.sw_rst_flag == SW_RST_BT_MDM)
  267. #if VUSB_TBOX_QTEST_EN
  268. || get_qtest_mode()
  269. #endif
  270. ) {
  271. bsp_charge_box_exit();
  272. return;
  273. }
  274. while (1) {
  275. WDT_CLR();
  276. delay_ms(5);
  277. key_val = key_scan();
  278. bsp_key_process(key_val);
  279. if ((bsp_key_pwr_scan() & K_PWR_MASK) == K_PWR) {
  280. up_cnt = 0;
  281. if (!pwrkey_pressed_flag) {
  282. ticks = tick_get();
  283. sys_cb.ms_ticks = ticks; //记录PWRKEY按键按下的时刻
  284. pwrkey_pressed_flag = 1;
  285. }
  286. if (!sys_cb.poweron_flag) {
  287. if (tick_check_expire(ticks, pwron_press_nms)) { //长按开机时间配置
  288. sys_cb.poweron_flag = 1;
  289. }
  290. }
  291. } else {
  292. if (up_cnt < 3) {
  293. up_cnt++;
  294. }
  295. if (up_cnt == 3) {
  296. up_cnt = 10;
  297. pwrkey_pressed_flag = 0;
  298. sys_cb.poweron_flag = 0;
  299. }
  300. }
  301. #if LINEIN_2_PWRDOWN_EN
  302. linein_detect();
  303. #endif // LINEIN_2_PWRDOWN_EN
  304. #if VBAT_DETECT_EN
  305. sys_cb.vbat = get_vbat_val();
  306. #endif // VBAT_DETECT_EN
  307. #if VUSB_TBOX_QTEST_EN
  308. if(sys_cb.qtest_flag){
  309. if(bsp_qtest_other_usage()){
  310. break;
  311. }
  312. }
  313. #endif
  314. #if CHARGE_EN
  315. if (xcfg_cb.charge_en) {
  316. #if TRY_CHARGEBOX_PWROFF
  317. sys_cb1.charge_flag = true;
  318. #endif // TRY_CHARGEBOX_PWROFF
  319. chbox_sta = bsp_charge_box_process();
  320. if (chbox_sta == 2) {
  321. break; //充电仓拿起开机
  322. }
  323. }
  324. #endif // CHARGE_EN
  325. if (sys_cb.poweron_flag) {
  326. #if VBAT_DETECT_EN
  327. if (sys_cb.vbat <= 2950) { //电压小于2.95v不开机
  328. continue;
  329. }
  330. #endif
  331. if ((CHARGE_DC_NOT_PWRON) && CHARGE_DC_IN()) {
  332. continue;
  333. }
  334. #if LINEIN_2_PWRDOWN_EN
  335. if ((xcfg_cb.linein_2_pwrdown_en) && (device_is_online(DEV_LINEIN))) {
  336. RTCCON10 = BIT(10); //clear pwrkey10s pending and counter
  337. continue;
  338. }
  339. #endif // LINEIN_2_PWRDOWN_EN
  340. break;
  341. } else {
  342. //PWKKEY已松开, 不在充电仓或未充电直接进行关机
  343. if ((!pwrkey_pressed_flag) && (chbox_sta)) {
  344. if ((!SOFT_POWER_ON_OFF) || ((!sys_cb.wko_pwrkey_en) && (!sys_cb.tkey_pwrdwn_en))) {
  345. break; //没有按键软开关机功能,不在充电状态直接开机
  346. }
  347. saradc_exit(adc_cb.channel);
  348. sfunc_pwrdown(1);
  349. }
  350. }
  351. }
  352. bsp_charge_box_exit();
  353. }
  354. AT(.text.bsp.power)
  355. void power_on_check(void)
  356. {
  357. bsp_key_wko10s_reset();
  358. power_on_check_do();
  359. bsp_charge_box_reinit();
  360. sys_cb.sw_rst_flag = 0;
  361. }
  362. AT(.text.bsp.key.init)
  363. void key_var_init(void)
  364. {
  365. memset(&key_cb, 0, sizeof(key_cb));
  366. dkey_mask_bits_init();
  367. }
  368. AT(.text.bsp.key.init)
  369. void key_init(void)
  370. {
  371. int adc_ch = 0;
  372. key_var_init();
  373. memcpy(&key_cb.filter, &key_filter_tbl, sizeof(key_filter_t));
  374. if (xcfg_cb.kl_time_sel) {
  375. key_cb.filter.long_cnt = KEY_LONG_TIMES + (u32)xcfg_cb.kl_time_sel*120; //配置长按时间
  376. key_cb.filter.hold_cnt = key_cb.filter.long_cnt + KEY_HOLD_TIMES;
  377. }
  378. key_cb.delay = ((u8)xcfg_cb.double_key_time + 2) * 20 + 1;
  379. key_cb.times = 5; //按键最多检测几击?
  380. key_cb.tbl = key_multi_tbl;
  381. memset(&key_multi_cb, 0, sizeof(key_multi_cb));
  382. memset(iokey_gpio, 0, sizeof(iokey_gpio));
  383. if (xcfg_cb.user_iokey_en) {
  384. iokey_gpio[0] = configure_gpio_tbl[xcfg_cb.iokey_io0];
  385. iokey_gpio[1] = configure_gpio_tbl[xcfg_cb.iokey_io1];
  386. iokey_num[0] = xcfg_cb.iokey_num0;
  387. iokey_num[1] = xcfg_cb.iokey_num1;
  388. iokey_num[2] = xcfg_cb.iokey_num2;
  389. io_key_init();
  390. }
  391. if (xcfg_cb.user_adkey_en) {
  392. memcpy(adkey_tbuf, adkey_table, sizeof(adkey_tbl_t)*7);
  393. if (xcfg_cb.user_adkey_pu10k_en) {
  394. adcch_io_pu10k_enable(ADKEY_CH);
  395. }
  396. adc_ch |= BIT(ADKEY_CH);
  397. if (xcfg_cb.adkey_config_en) {
  398. adkey_tbuf[0].usage_id = get_key_configure_val(xcfg_cb.adkey_num0);
  399. adkey_tbuf[1].usage_id = get_key_configure_val(xcfg_cb.adkey_num1);
  400. adkey_tbuf[2].usage_id = get_key_configure_val(xcfg_cb.adkey_num2);
  401. adkey_tbuf[3].usage_id = get_key_configure_val(xcfg_cb.adkey_num3);
  402. adkey_tbuf[4].usage_id = get_key_configure_val(xcfg_cb.adkey_num4);
  403. adkey_tbuf[5].usage_id = get_key_configure_val(xcfg_cb.adkey_num5);
  404. }
  405. if (xcfg_cb.adkey_adcv_config_en) {
  406. adkey_tbuf[0].adc_val = xcfg_cb.adcv_num0;
  407. adkey_tbuf[1].adc_val = xcfg_cb.adcv_num1;
  408. adkey_tbuf[2].adc_val = xcfg_cb.adcv_num2;
  409. ///配置ADC VALUE时,只能做3个ADC按键
  410. adkey_tbuf[3].adc_val = 0xff;
  411. adkey_tbuf[3].usage_id = NO_KEY;
  412. }
  413. }
  414. #if USER_ADKEY2
  415. if (xcfg_cb.user_adkey2_en) {
  416. adc_ch |= BIT(ADKEY2_CH);
  417. }
  418. #endif // USER_ADKEY2
  419. #if USER_NTC
  420. if (xcfg_cb.sys_ntc_en) {
  421. adc_ch |= BIT(NTC_ADCCH);
  422. ntc_gpio_inner_pu10k_init();
  423. }
  424. #endif // USER_NTC
  425. RTCCON11 |= BIT(4); //WKOPRT = 1
  426. uint rtccon1 = RTCCON1 & ~0x1f; //wko tkey需要关掉WKO上拉
  427. if (sys_cb.wko_pwrkey_en) {
  428. rtccon1 |= BIT(0) | BIT(2) | BIT(4); //WK 90K pull up enable
  429. adc_ch |= (BIT(ADCCH_VRTC) | BIT(ADCCH_WKO));
  430. key_cb.pwr10_val = pwrkey_table[0].usage_id; //支持PWRKEY 10S强制复位的按键
  431. if (xcfg_cb.pwrkey_config_en) {
  432. key_cb.pwr10_val = get_key_configure_val(xcfg_cb.pwrkey_num0);
  433. pwrkey_num[0] = xcfg_cb.pwrkey_num0;
  434. pwrkey_num[1] = xcfg_cb.pwrkey_num1;
  435. pwrkey_num[2] = xcfg_cb.pwrkey_num2;
  436. pwrkey_num[3] = xcfg_cb.pwrkey_num3;
  437. pwrkey_num[4] = xcfg_cb.pwrkey_num4;
  438. pwrkey_num[5] = NO_KEY;
  439. }
  440. }
  441. RTCCON1 = rtccon1;
  442. #if CHARGE_EN || VBAT_DETECT_EN
  443. adc_ch |= BIT(ADCCH_BGOP);
  444. #if VBAT_DETECT_EN
  445. adc_ch |= BIT(VBAT2_ADCCH);
  446. #endif // VBAT_DETECT_EN
  447. #endif
  448. if (mic_bias_trim_is_en()) {
  449. adc_ch |= BIT(ADCCH_MIC);
  450. }
  451. #if CHARGE_TSEN_DETECT
  452. PWRCON2 |= BIT(7) | BIT(6) | BIT(5); //DI_RES_X2 normal mode, DI_OE_TSEN enable, DI_EN_TSEN enable
  453. adc_ch |= BIT(ADCCH_VTSEN);
  454. #endif
  455. bsp_saradc_init(adc_ch);
  456. bsp_tkey_init();
  457. #if VUSB_TBOX_QTEST_EN
  458. bsp_qtest_init();
  459. #endif
  460. power_on_check();
  461. }
  462. #if (USER_MULTI_PRESS_EN && USER_TKEY_SLIDE)
  463. AT(.com_text.bsp.key)
  464. void key_multi_press_clr(void)
  465. {
  466. key_multi_cb_t *s = &key_multi_cb;
  467. s->counter = 0;
  468. s->strikes = 0;
  469. s->val = NO_KEY;
  470. }
  471. #endif
  472. #if USER_TKEY_SHORT_SLIDE
  473. AT(.com_text.bsp.key)
  474. u16 bsp_key_slide_process(u16 key_val)
  475. {
  476. u16 key_return = NO_KEY;
  477. key_return = key_process(key_val);
  478. key_return = tkey_short_slide_process(key_return);
  479. #if USER_MULTI_PRESS_EN
  480. if (key_cb.times > 1) {
  481. key_return = key_multi_press_process(key_return);
  482. }
  483. #endif
  484. return key_return;
  485. }
  486. #endif
  487. u8 bsp_key_pwr_scan(void)
  488. {
  489. u8 key_val = NO_KEY;
  490. #if USER_TKEY
  491. key_val = bsp_tkey_scan();
  492. #endif
  493. #if USER_PWRKEY
  494. if (key_val == NO_KEY) {
  495. key_val = get_pwrkey();
  496. }
  497. #endif // USER_PWRKEY
  498. return key_val;
  499. }
  500. AT(.com_text.port.key)
  501. void get_adc_val_hook(void)
  502. {
  503. #if CHARGE_TSEN_DETECT
  504. sys_cb1.adc_tsen_val = adc_cb.sfr[ADCCH_VTSEN] * 600 / adc_cb.sfr[ADCCH_BGOP];
  505. #endif
  506. }
  507. AT(.com_text.bsp.key)
  508. u8 key_scan(void)
  509. {
  510. u8 key_val = NO_KEY;
  511. if (!get_adc_val()) {
  512. return NO_KEY;
  513. }
  514. #if USER_TKEY
  515. #if USER_TKEY_SHORT_SLIDE
  516. key_val = bsp_short_slide_tkey_scan();
  517. #else
  518. key_val = bsp_tkey_scan();
  519. #endif
  520. #endif
  521. #if USER_ADKEY
  522. if (key_val == NO_KEY) {
  523. key_val = get_adkey();
  524. }
  525. #endif // USER_ADKEY
  526. #if USER_ADKEY2
  527. if (key_val == NO_KEY) {
  528. key_val = get_adkey2();
  529. }
  530. #endif // USER_ADKEY2
  531. #if USER_PWRKEY
  532. if ((key_val == NO_KEY) && (!PWRKEY_2_HW_PWRON)) {
  533. key_val = get_pwrkey();
  534. }
  535. #endif // USER_PWRKEY
  536. #if USER_IOKEY
  537. if (key_val == NO_KEY) {
  538. key_val = get_iokey();
  539. }
  540. #endif // USER_IOKEY
  541. #if (IRRX_SW_EN || IRRX_HW_EN)
  542. if (key_val == NO_KEY) {
  543. key_val = get_irkey();
  544. }
  545. #endif // (IRRX_SW_EN || IRRX_HW_EN)
  546. return key_val;
  547. }
  548. //AT(.com_rodata.key)
  549. //const char key_msg_str[] = "key msg: %04x\n";
  550. AT(.com_text.bsp.key)
  551. u8 bsp_key_scan(void)
  552. {
  553. u8 key_val;
  554. u16 key = NO_KEY;
  555. key_val = key_scan();
  556. #if VBAT_DETECT_EN
  557. sys_cb.vbat = get_vbat_val();
  558. #endif // VBAT_DETECT_EN
  559. #if USER_TKEY_SHORT_SLIDE
  560. key = bsp_key_slide_process(key_val);
  561. #else
  562. key = bsp_key_process(key_val);
  563. #endif
  564. #if USER_TKEY_SLIDE
  565. key = bsp_tkey_slide_process(key);
  566. #endif
  567. if ((key != NO_KEY) && (!bsp_key_pwron_filter(key))) {
  568. //防止enqueue多次HOLD消息
  569. if ((key & KEY_TYPE_MASK) == KEY_LONG) {
  570. sys_cb.kh_vol_msg = (key & 0xff) | KEY_HOLD;
  571. } else if ((key & KEY_TYPE_MASK) == KEY_LONG_UP) {
  572. msg_queue_detach(sys_cb.kh_vol_msg, 0);
  573. sys_cb.kh_vol_msg = NO_KEY;
  574. } else if (sys_cb.kh_vol_msg == key) {
  575. msg_queue_detach(key, 0);
  576. }
  577. #if WAV_KEY_VOICE_QUICK_EN
  578. if ((key == K_PLAY_PWR_USER_DEF || key == K_PLAY_PWR_USER_DEF) && bt_sbc_res_is_playing()) {
  579. // sys_cb.tws_res_brk = 1;
  580. return NO_KEY;
  581. }
  582. #endif
  583. #if LED_188LED_DISP_EN
  584. if (key == K_PLAY_PWR_USER_DEF) {
  585. bsp_188led_disp_set_on();
  586. }
  587. #endif
  588. // printf(key_msg_str, key);
  589. #if TRY_KH_VOL_CHANGE_INTERVAL
  590. if(sys_cb1.change_vol_flag && key == KH_PLAY_USER_DEF)
  591. {
  592. sys_cb1.key_hold_count++;
  593. if(sys_cb1.key_hold_count >= 7)
  594. {
  595. sys_cb1.key_hold_count = 0;
  596. msg_enqueue(key);
  597. }
  598. }
  599. else
  600. {
  601. msg_enqueue(key);
  602. }
  603. #else
  604. msg_enqueue(key);
  605. #endif // TRY_KH_VOL_CHANGE_INTERVAL
  606. }
  607. return key_val;
  608. }