func_lowpwr.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796
  1. #include "include.h"
  2. #include "func.h"
  3. #if HLW_UI
  4. #include "hlw_func.h"
  5. #endif
  6. bool power_off_check(void);
  7. void lock_code_pwrsave(void);
  8. void unlock_code_pwrsave(void);
  9. void lock_code_vad(void);
  10. void unlock_code_vad(void);
  11. bool bt_is_pre_wakeup(void);
  12. AT(.com_text.sleep)
  13. void lowpwr_tout_ticks(void)
  14. {
  15. if(sys_cb.sleep_delay != -1L && sys_cb.sleep_delay > 0) {
  16. sys_cb.sleep_delay--;
  17. }
  18. if(sys_cb.pwroff_delay != -1L && sys_cb.pwroff_delay > 0) {
  19. sys_cb.pwroff_delay--;
  20. }
  21. }
  22. AT(.com_text.sleep)
  23. bool sys_sleep_check(u32 *sleep_time)
  24. {
  25. if(*sleep_time > sys_cb.sleep_wakeup_time) {
  26. *sleep_time = sys_cb.sleep_wakeup_time;
  27. return true;
  28. }
  29. return false;
  30. }
  31. AT(.sleep_text.sleep)
  32. void sys_sleep_cb(u8 lpclk_type)
  33. {
  34. //注意!!!!!!!!!!!!!!!!!
  35. //此函数只能调用sleep_text或com_text函数
  36. #if ASR_EN && VAD_EN
  37. if (sys_cb.asr_enable && bsp_asr_get_statue()) {
  38. PICCONSET = BIT(0);
  39. while (!bt_is_pre_wakeup()) {
  40. WDT_CLR();
  41. }
  42. PICCONCLR = BIT(0);
  43. } else {
  44. // //此处关掉影响功耗的模块
  45. u32 gpiogde = GPIOGDE;
  46. GPIOGDE = BIT(2) | BIT(4); //SPICS, SPICLK
  47. sys_sleep_proc(lpclk_type); //enter sleep
  48. //唤醒后,恢复模块功能
  49. GPIOGDE = gpiogde;
  50. }
  51. #else
  52. //此处关掉影响功耗的模块
  53. u32 gpiogde = GPIOGDE;
  54. GPIOGDE = BIT(2) | BIT(4); //SPICS, SPICLK
  55. sys_sleep_proc(lpclk_type); //enter sleep
  56. //唤醒后,恢复模块功能
  57. GPIOGDE = gpiogde;
  58. #endif
  59. }
  60. #if USER_INEAR_DETECT_EN
  61. //INEAR状态发生变化,需要唤醒sniff mode
  62. AT(.sleep_text.earin)
  63. bool earin_is_wakeup(void)
  64. {
  65. if (INEAR_IS_ONLINE()) {
  66. if (sys_cb.loc_ear_sta) {
  67. return true;
  68. }
  69. } else {
  70. if (!sys_cb.loc_ear_sta) {
  71. return true;
  72. }
  73. }
  74. return false;
  75. }
  76. #endif // USER_INEAR_DETECT_EN
  77. //休眠定时器,500ms进一次
  78. AT(.sleep_text.sleep)
  79. uint32_t sleep_timer(void)
  80. {
  81. uint32_t ret = 0;
  82. app_sleep_mode_process();
  83. #if CHARGE_EN
  84. if (xcfg_cb.charge_en) {
  85. charge_detect(0);
  86. }
  87. #endif // CHARGE_EN
  88. if (led_bt_sleep()) {
  89. sys_cb.sleep_wakeup_time = 50000/312;
  90. #if VBAT_DETECT_EN
  91. bsp_saradc_init();
  92. if ((xcfg_cb.lowpower_warning_en) && (sys_cb.vbat < ((u16)LPWR_WARNING_VBAT*100 + 2750))) {
  93. //低电需要唤醒sniff mode
  94. ret = 2;
  95. }
  96. bsp_saradc_exit();
  97. #endif // VBAT_DETECT_EN
  98. #if CHARGE_EN
  99. if (!port_2led_is_sleep_en()) {
  100. ret = 2;
  101. }
  102. #endif // CHARGE_EN
  103. } else {
  104. sys_cb.sleep_wakeup_time = -1L;
  105. }
  106. if(sys_cb.pwroff_delay != -1L) {
  107. if(sys_cb.pwroff_delay > 5) {
  108. sys_cb.pwroff_delay -= 5;
  109. } else {
  110. sys_cb.pwroff_delay = 0;
  111. return 1;
  112. }
  113. }
  114. if ((PWRKEY_2_HW_PWRON) && (!PWRKEY_IS_PRESS())){
  115. ret = 1;
  116. }
  117. return ret;
  118. }
  119. AT(.text.lowpwr.sleep)
  120. static void sfunc_sleep_dac_off(u8 off)
  121. {
  122. #if ANC_EN
  123. if (sys_cb.anc_start) {
  124. return;
  125. }
  126. #endif
  127. if (off) {
  128. #if ANC_EN
  129. bsp_anc_stop();
  130. bsp_anc_exit(); //关闭所有mic通路,降低功耗
  131. #endif
  132. #if TINY_TRANSPARENCY_EN
  133. bsp_ttp_stop();
  134. #endif
  135. if (SLEEP_DAC_OFF_EN) {
  136. dac_power_off(); //dac power down
  137. } else {
  138. dac_channel_disable(); //only dac channel master disable
  139. }
  140. } else {
  141. if (SLEEP_DAC_OFF_EN) {
  142. dac_restart();
  143. } else {
  144. dac_channel_enable();
  145. }
  146. #if DAC_DNC_EN
  147. dac_dnc_init();
  148. dac_dnc_start();
  149. #endif
  150. #if TINY_TRANSPARENCY_EN
  151. bsp_ttp_init();
  152. #endif
  153. #if ANC_EN
  154. bsp_anc_init();
  155. bsp_anc_set_mode(sys_cb.anc_user_mode);
  156. #endif
  157. }
  158. }
  159. AT(.text.lowpwr.sleep)
  160. static void sfunc_sleep(void)
  161. {
  162. uint32_t status, ret, sysclk;
  163. uint32_t usbcon0, usbcon1;
  164. u16 pa_de, pb_de, pe_de, pg_de, pf_de;
  165. u16 adc_ch;
  166. #if VBAT_DETECT_EN
  167. if (is_lowpower_vbat_warning()) { //低电不进sniff mode
  168. return;
  169. }
  170. #endif // VBAT_DETECT_EN
  171. #if ANC_ALG_EN
  172. if (sys_cb.anc_alg_en == 1) {
  173. return; //开启ANC算法不进休眠
  174. }
  175. #endif // ANC_ALG_EN
  176. #if ABP_EN
  177. if (abp_is_playing()) {
  178. #if ABP_PLAY_WAKE_EN
  179. return;
  180. #else
  181. abp_stop();
  182. #endif // ABP_PLAY_WAKE_EN
  183. }
  184. #endif // ABP_EN
  185. #if ASR_EN
  186. #if VAD_EN
  187. if (sys_cb.asr_enable && vad_is_wake()) { //VAD唤醒中不进休眠
  188. return;
  189. }
  190. vad_sleep_config(1);
  191. lock_code_vad();
  192. #else
  193. return; //没有vad的语音识别不进休眠
  194. #endif
  195. #endif
  196. printf("%s\n", __func__);
  197. bt_audio_bypass();
  198. app_enter_sleep();
  199. #if SYS_KARAOK_EN
  200. bsp_karaok_exit(AUDIO_PATH_KARAOK);
  201. #endif
  202. #if BT_MUSIC_EFFECT_EN
  203. music_effect_sfunc_sleep_do(1);
  204. #endif // BT_MUSIC_EFFECT_EN
  205. bt_enter_sleep();
  206. gui_off();
  207. led_off();
  208. rled_off();
  209. sfunc_sleep_dac_off(1);
  210. sys_set_tmr_enable(0, 0);
  211. #if SYS_SLEEP_LEVEL > 2
  212. sys_set_tmr_tick(0);
  213. #endif
  214. sys_clk_free_all(); //释放其它模块sys_clk_req的系统时钟
  215. sysclk = sys_clk_get();
  216. sys_clk_set(SYS_24M);
  217. adc_ch = bsp_saradc_exit(); //close saradc及相关通路模拟
  218. saradc_set_channel(BIT(ADCCH_VBAT) | BIT(ADCCH_BGOP));
  219. #if CHARGE_EN
  220. charge_set_stop_time(3600);
  221. lock_code_charge();
  222. #endif
  223. #if MUSIC_UDISK_EN
  224. if (dev_is_online(DEV_UDISK)) {
  225. udisk_insert(); //udisk需要重新enum
  226. }
  227. #endif
  228. usbcon0 = USBCON0; //需要先关中断再保存
  229. usbcon1 = USBCON1;
  230. USBCON0 = BIT(5);
  231. USBCON1 = 0;
  232. #if ANC_EN
  233. if (!sys_cb.anc_start)
  234. #endif
  235. {
  236. DACDIGCON0 &= ~BIT(0); //disable digital dac
  237. dac_clk_source_sel(2); //dac clk select xosc26m_clk
  238. #if VAD_EN
  239. if (!vad_is_start())
  240. #endif
  241. {
  242. //close pll0
  243. PLL0CON0 &= ~(BIT(18) | BIT(6)); //pll0 sdm & analog disable
  244. // RSTCON0 &= ~BIT(4); //pllsdm disable
  245. }
  246. }
  247. //io analog input
  248. pa_de = GPIOADE;
  249. pb_de = GPIOBDE;
  250. pe_de = GPIOEDE;
  251. pg_de = GPIOGDE;
  252. pf_de = GPIOFDE;
  253. GPIOADE = 0;
  254. GPIOBDE = pb_de & BIT(5); //保留PB5(wko)的配置
  255. u16 pe_de_t = 0;
  256. #if CHARGE_EN
  257. if (CHARGE_DC_IN() && (xcfg_cb.rled_io_sel == IO_PE0)) {
  258. pe_de_t = BIT(0); //PE0做充电指示灯,保持IO数字输出
  259. }
  260. #endif
  261. #if VAD_EN
  262. if (vad_mic_pwr_sel_io() == 1) { //PF0
  263. GPIOEDE = pe_de_t;
  264. GPIOGDE = 0x3F; //MCP FLASH
  265. GPIOFDE = BIT(0);
  266. } else if (vad_mic_pwr_sel_io() == 2) {//PF1
  267. GPIOEDE = pe_de_t;
  268. GPIOGDE = 0x3F; //MCP FLASH
  269. GPIOFDE = BIT(1);
  270. } else if (vad_mic_pwr_sel_io() == 3) {//PE7
  271. GPIOEDE = pe_de_t & BIT(7);
  272. GPIOGDE = 0x3F; //MCP FLASH
  273. GPIOFDE = 0;
  274. }
  275. #else
  276. GPIOEDE = pe_de_t;
  277. GPIOGDE = 0x3F; //MCP FLASH
  278. GPIOFDE = 0;
  279. #endif
  280. #if USER_INEAR_DET_OPT
  281. INEAR_OPT_PORT_INIT();
  282. #endif
  283. wakeup_disable();
  284. sleep_wakeup_config();
  285. sys_cb.sleep_wakeup_time = -1L;
  286. while(bt_is_sleep()) {
  287. WDT_CLR();
  288. vusb_reset_clr();
  289. bt_thread_check_trigger();
  290. status = bt_sleep_proc();
  291. #if SYS_SLEEP_LEVEL > 2
  292. bb_run_loop();
  293. #endif
  294. if(status == 1) {
  295. ret = sleep_timer();
  296. if(ret) {
  297. if (ret == 1) {
  298. sys_cb.pwrdwn_tone_en = 1;
  299. func_cb.sta = FUNC_PWROFF;
  300. }
  301. break;
  302. }
  303. }
  304. if (wakeup_get_status()) {
  305. break;
  306. }
  307. #if USER_TKEY
  308. if (tkey_is_pressed()) {
  309. break;
  310. }
  311. #endif
  312. #if USER_INEAR_DETECT_EN
  313. if (earin_is_wakeup()) {
  314. break;
  315. }
  316. #endif
  317. #if VAD_EN
  318. if (vad_is_wake()) {
  319. break;
  320. }
  321. #endif
  322. #if (CHARGE_EN || QTEST_EN) && (UART0_PRINTF_SEL != PRINTF_VUSB)
  323. if (xcfg_cb.charge_en && CHARGE_INBOX()) {
  324. break;
  325. }
  326. #endif // CHARGE_EN
  327. if(app_need_wakeup()){
  328. break;
  329. }
  330. if(le_popup_need_wakeup()){
  331. break;
  332. }
  333. }
  334. GPIOADE = pa_de;
  335. GPIOBDE = pb_de;
  336. GPIOEDE = pe_de;
  337. GPIOGDE = pg_de;
  338. GPIOFDE = pf_de;
  339. printf("wakeup: %d\n", wakeup_gpio_get_status(IO_PA7));
  340. wakeup_disable();
  341. USBCON0 = usbcon0;
  342. USBCON1 = usbcon1;
  343. #if ANC_EN
  344. if (!sys_cb.anc_start)
  345. #endif
  346. {
  347. adpll_init(DAC_OUT_SPR); //enable adpll
  348. dac_clk_source_sel(1); //dac clk select adda_clk48
  349. }
  350. saradc_set_channel(adc_ch);
  351. bsp_saradc_init();
  352. #if VAD_EN
  353. vad_sleep_config(0);
  354. unlock_code_vad();
  355. #endif
  356. #if CHARGE_EN
  357. charge_set_stop_time(18000);
  358. charge_status(sys_cb.charge_sta); //update充灯状态
  359. unlock_code_charge();
  360. #endif // CHARGE_EN
  361. sys_clk_set(sysclk);
  362. #if SYS_SLEEP_LEVEL > 2
  363. sys_set_tmr_tick(1);
  364. #endif
  365. sys_set_tmr_enable(1, 1);
  366. #if BT_MUSIC_EFFECT_EN
  367. music_effect_sfunc_sleep_do(0);
  368. #endif // BT_MUSIC_EFFECT_EN
  369. if (DAC_FAST_SETUP_EN) {
  370. bsp_loudspeaker_mute();
  371. delay_5ms(2);
  372. }
  373. sfunc_sleep_dac_off(0);
  374. bsp_change_volume(sys_cb.vol);
  375. bt_exit_sleep();
  376. bt_audio_enable();
  377. #if SYS_KARAOK_EN
  378. bsp_karaok_init(AUDIO_PATH_KARAOK, func_cb.sta);
  379. #endif
  380. #if ABP_EN && !ABP_PLAY_WAKE_EN
  381. if (sys_cb.abp_mode) {
  382. bsp_abp_set_mode(sys_cb.abp_mode);
  383. }
  384. #endif
  385. gsensor_wakeup();
  386. app_exit_sleep();
  387. printf("sleep_exit\n");
  388. }
  389. AT(.text.lowpwr.sleep)
  390. bool sleep_process(is_sleep_func is_sleep)
  391. {
  392. if(app_need_wakeup()){
  393. reset_sleep_delay();
  394. reset_pwroff_delay();
  395. return false;
  396. }
  397. #if CHARGE_EN && (UART0_PRINTF_SEL != PRINTF_VUSB)
  398. if (xcfg_cb.charge_en && CHARGE_INBOX()) {
  399. #if (CHARGE_BOX_TYPE == CBOX_NOR)
  400. if((sys_cb.pwroff_delay == -1L)){
  401. en_auto_pwroff();
  402. }
  403. #endif
  404. return false;
  405. }
  406. #endif // CHARGE_EN
  407. if ((*is_sleep)()) {
  408. if ((!sys_cb.sleep_en) || (!port_2led_is_sleep_en())) {
  409. reset_sleep_delay();
  410. return false;
  411. }
  412. if(sys_cb.sleep_delay == 0) {
  413. #if HLW_UI
  414. reset_sleep_delay();
  415. return false;
  416. #else
  417. sfunc_sleep();
  418. reset_sleep_delay();
  419. reset_pwroff_delay();
  420. return true;
  421. #endif
  422. }
  423. } else {
  424. reset_sleep_delay();
  425. }
  426. return false;
  427. }
  428. AT(.text.pwroff.save)
  429. void sfunc_power_save_enter(void)
  430. {
  431. CLKCON0 |= BIT(0); //enable RC
  432. delay_us(200);
  433. LOUDSPEAKER_MUTE_DIS();
  434. #if CHARGE_EN
  435. if (xcfg_cb.charge_en) {
  436. charge_off();
  437. }
  438. #endif // CHARGE_EN
  439. pmu_set_mode(0);
  440. //usb_disable();
  441. GPIOADE = 0;
  442. GPIOBDE = BIT(5); //pwrkey
  443. GPIOEDE = 0;
  444. GPIOFDE = 0;
  445. GPIOGDE = 0x3F; //MCP FLASH
  446. PICCONCLR = BIT(0); //Globle IE disable
  447. CLKCON0 = (CLKCON0 & ~(0x3 << 2)); //system clk select RC
  448. PLL0CON0 &= ~BIT(18); //pll10 sdm enable disable
  449. PLL0CON0 &= ~BIT(6); //pll0 analog diable
  450. PLL0CON0 &= ~BIT(12); //pll0 ldo disable
  451. XOSCCON &= ~(0xf<<24); //X26 output DIS
  452. XOSCCON &= ~BIT(10); //X26 DIS
  453. }
  454. ///充满关机前等待仓休眠5V掉电
  455. AT(.text.pwroff)
  456. u8 sfunc_pwrdown_w4_vusb_offline(void)
  457. {
  458. u32 timeout = 12000, off_cnt = 0;
  459. if (xcfg_cb.ch_box_type_sel != 1) {
  460. while (timeout--) {
  461. delay_us(330); //5ms
  462. if (!CHARGE_DC_IN()) {
  463. off_cnt++;
  464. } else {
  465. off_cnt = 0;
  466. }
  467. if (off_cnt > 5) {
  468. return 1; //VUSB已掉线,打开VUSB唤醒
  469. }
  470. WDT_CLR();
  471. }
  472. }
  473. return 0;
  474. }
  475. //硬开关方案,低电时,进入省电状态
  476. AT(.text.pwroff)
  477. void sfunc_lowbat(void)
  478. {
  479. sfunc_power_save_enter();
  480. WDT_DIS();
  481. asm("nop");asm("nop");asm("nop");
  482. LPMCON |= BIT(0); //Sleep mode enable
  483. asm("nop");asm("nop");asm("nop");
  484. while(1);
  485. }
  486. //软开关方案,POWER键/低电时,进入关机状态
  487. AT(.text.pwroff)
  488. void sfunc_pwrdown_do(u8 vusb_wakeup_en)
  489. {
  490. #if USER_TKEY
  491. u32 tkey_wakeup_en = sys_cb.tkey_pwrdwn_en;
  492. #if QTEST_EN
  493. if (qtest_cb.pdn_boat_flag) {
  494. tkey_wakeup_en = 0;
  495. }
  496. #endif
  497. #endif
  498. printf("pwrdwn: %d\n", vusb_wakeup_en);
  499. vusb_reset_clr();
  500. if (vusb_wakeup_en == 0) {
  501. RTCCON11 &= ~BIT(4); //充满关机关掉4s复位,防止5v维持电压的仓反复复位
  502. }
  503. BTCON2 &= ~BIT(10); //OSC wk up sniff mode disable
  504. RTCCON3 &= ~BIT(8); //rtc alarm wakeup disable
  505. RTCCON8 &= ~BIT(15); //RI_EN_VUSBDIV = 0
  506. RTCCON9 = 0xffff; //Clr pending
  507. #if USER_TKEY_LOWPWR_WAKEUP_DIS //电池无保护板且有内置触摸开关机功能方案,需要打开此宏
  508. if (sys_cb.vbat < 3050) {
  509. tkey_wakeup_en = 0; //低电关机, 关掉触模唤醒
  510. }
  511. if (tkey_wakeup_en) {
  512. RTCALM = RTCCNT + 300; //定时5分钟唤醒检查电池电量
  513. RTCCON3 |= BIT(8);
  514. }
  515. #endif
  516. sfunc_power_save_enter();
  517. if (!vusb_wakeup_en) {
  518. RTCCON8 = (RTCCON8 & ~BIT(6)) | BIT(1); //disable charger function
  519. #if (CHARGE_BOX_TYPE == CBOX_NOR)
  520. vusb_wakeup_en = sfunc_pwrdown_w4_vusb_offline();
  521. if (xcfg_cb.ch_box_type_sel == 3) { //5V完全掉电的仓
  522. RTCCON3 &= ~BIT(12); //RTCCON3[12], INBOX Wakeup disable
  523. }
  524. #endif
  525. }
  526. RTCCON11 = (RTCCON11 & ~0x03) | BIT(2); //WK PIN filter select 8ms
  527. uint rtccon3 = RTCCON3 & ~BIT(11);
  528. uint rtccon13 = RTCCON13 & ~(0xf << 12); //WK pin5~0 wakeup disable
  529. uint rtccon4 = RTCCON4 & ~(0x7 << 22);
  530. #if CHARGE_EN
  531. if ((xcfg_cb.charge_en) && (vusb_wakeup_en)) {
  532. rtccon3 |= BIT(11); //VUSB wakeup enable
  533. RTCCON3 |= BIT(11); //VUSB wakeup enable
  534. RTCCON11 |= BIT(6); //VUSB pull out filter VUSB拔出滤波
  535. delay_us(100);
  536. RTCCON10 = BIT(3);
  537. }
  538. #endif
  539. RTCCON3 = rtccon3 & ~(BIT(10) | BIT(14)); //关WK PIN,再打开,以清除Pending
  540. PWRCON1 &= ~(0x1F<<14); //disable Flash Power Gate
  541. PWRCON1 |= BIT(18); //pdown flash power gate
  542. #if USER_TKEY
  543. if ((RTCCON3 & BIT(12)) || sys_cb.lowbat_flag) {//仓内或低电关机?
  544. tkey_wakeup_en = 0;
  545. }
  546. if (tkey_wakeup_en) {
  547. RTCCON1 |= BIT(9); //tk digital voltage enable
  548. RTCCON3 |= BIT(14); //Touch key long press wakeup
  549. rtccon4 |= 0x4 << 22; //VRTC 0.96V
  550. TKCON |= BIT(14); //touch key auto enable(低功耗模式,扫描完自动开关)
  551. } else {
  552. //保持电源,保证tkey通道能顺利关闭
  553. RTCCON0 |= BIT(5); //tk rst disable
  554. TKACON0 = 0;
  555. TKACON1 = 0;
  556. RTCCON0 &= ~BIT(4); //tk interface disable
  557. RTCCON0 &= ~BIT(0); //RC2M_RTC Disable
  558. RTCCON0 &= ~BIT(5); //tk rst enable
  559. RTCCON1 &= ~BIT(9); //tk digital voltage disable
  560. rtccon4 |= 0x2 << 22; //VRTC 0.82V
  561. }
  562. #else
  563. RTCCON0 &= ~BIT(0); //RC2M_RTC Disable
  564. rtccon4 |= 0x2 << 22; //VRTC 0.82V
  565. #endif
  566. RTCCON4 = rtccon4;
  567. RTCCON0 &= ~(BIT(22) | BIT(23));
  568. rtccon3 = RTCCON3 & ~0x17; //Disable VDDCORE VDDIO VDDBUCK, VDDXOEN
  569. rtccon3 |= BIT(6); //Core power down enable, VDDCORE short disable
  570. rtccon3 &= ~BIT(22); //LVCORE_DIS
  571. RTCCON3 &= ~BIT(22); //LVCORE_DIS, lvcore掉电
  572. rtccon3 |= BIT(7); //RI_EN_VDDIO_AON RTC 2.9V LDO enable
  573. #if USER_PWRKEY
  574. if (sys_cb.wko_pwrkey_en) {
  575. rtccon3 |= BIT(10); //WK pin wake up enable
  576. rtccon13 |= BIT(0) | BIT(4) | BIT(12); //wk pin0 wakeup, input, pullup10k enable
  577. }
  578. #endif // USER_PWRKEY
  579. #if QTEST_EN
  580. if (qtest_cb.pdn_boat_flag) { //若船运模式关机,只保留5V唤醒
  581. rtccon3 &= ~(BIT(14) | BIT(12) | BIT(10) | BIT(9) | BIT(8)); //touch key long press, inbox, wk pin, RTC one second, RTC alarm wakeup disable
  582. rtccon3 |= BIT(11); //VUSB wakeup enable
  583. }
  584. #endif
  585. WDT_DIS();
  586. RTCCON &= ~(3 << 1); //rtc选择sys_clk div2, 避免关机时rtc配置来不及生效,导致关机功耗偏大1.5uA
  587. RTCCON |= BIT(5); //PowerDown Reset,如果有Pending,则马上Reset
  588. RTCCON13 = rtccon13;
  589. RTCCON3 = rtccon3;
  590. LPMCON |= BIT(0); //sleep mode
  591. LPMCON |= BIT(1); //idle mode
  592. asm("nop");asm("nop");asm("nop");
  593. while (1);
  594. }
  595. void sfunc_pwrdown(u8 vusb_wakeup_en)
  596. {
  597. #if (CHARGE_BOX_TYPE == CBOX_SSW) || QTEST_EN
  598. bsp_vusb_uart_dis();
  599. #endif
  600. #if HLW_UI
  601. sys_pe4_power_gate_set(0);
  602. #endif
  603. lock_code_pwrsave();
  604. sfunc_pwrdown_do(vusb_wakeup_en);
  605. }
  606. AT(.text.lowpwr.pwroff)
  607. void func_pwroff(int pwroff_tone_en)
  608. {
  609. printf("%s: %d\n", __func__, pwroff_tone_en);
  610. bsp_res_set_enable(false);
  611. while(bsp_res_is_playing()) {
  612. bt_thread_check_trigger();
  613. bsp_res_process();
  614. }
  615. bsp_res_cleanup();
  616. #if (CHARGE_BOX_TYPE == CBOX_SSW)
  617. if (vhouse_cb.inbox_sta) {
  618. charge_box_inbox_wakeup_enable();
  619. }
  620. #endif
  621. #if HLW_UI
  622. if((!hlw_cb.charging_flag)&&(!hlw_cb.clear_pairlist_flag))
  623. {
  624. led_power_down();
  625. }
  626. #else
  627. led_power_down();
  628. #endif
  629. #if WARNING_POWER_OFF
  630. if (SOFT_POWER_ON_OFF) {
  631. if (pwroff_tone_en == 1) {
  632. #if WARNING_WSBC_EN
  633. wsbc_res_play(RES_BUF_POWEROFF, RES_LEN_POWEROFF);
  634. #else
  635. mp3_res_play(RES_BUF_POWEROFF, RES_LEN_POWEROFF);
  636. #endif
  637. } else if (pwroff_tone_en == 2) {
  638. #if WARNING_FUNC_AUX
  639. mp3_res_play(RES_BUF_AUX_MODE_MP3, RES_LEN_AUX_MODE_MP3);
  640. #endif // WARNING_POWER_OFF
  641. }
  642. }
  643. #endif // WARNING_POWER_OFF
  644. gui_off();
  645. if (SOFT_POWER_ON_OFF) {
  646. if (!PWRKEY_2_HW_PWRON) {
  647. u8 dcin_cnt = 0;
  648. #if USER_TKEY
  649. tkey_press_timeout_clr();
  650. #endif
  651. while (PWRKEY_IS_PRESS() || TKEY_IS_PRESS()) { //等待PWRKWY松开
  652. if (CHARGE_DC_IN()) {
  653. dcin_cnt++;
  654. if (dcin_cnt > 3) {
  655. sw_reset_kick(SW_RST_DC_IN); //直接复位进入充电
  656. }
  657. } else {
  658. dcin_cnt = 0;
  659. }
  660. #if USER_TKEY
  661. if (sys_cb.tkey_pwrdwn_en) {
  662. tkey_press_timeout_process();
  663. }
  664. #endif
  665. delay_5ms(2);
  666. WDT_CLR();
  667. }
  668. }
  669. #if SYS_KARAOK_EN
  670. bsp_karaok_exit(AUDIO_PATH_KARAOK);
  671. #endif
  672. dac_power_off(); //dac power down
  673. #if !HLW_UI
  674. //去掉这里是因为关机提示音太长,如果再次插入5V,会出现异常
  675. if (CHARGE_DC_IN()) {
  676. if (power_off_check()) {
  677. return;
  678. }
  679. }
  680. #endif // HLW_UI
  681. bsp_saradc_exit(); //close saradc及相关通路模拟
  682. #if HLW_UI
  683. if((hlw_cb.clear_pairlist_flag)&&(hlw_cb.need_reset_flag))
  684. {
  685. hlw_cb.need_reset_flag = false;
  686. hlw_cb.clear_pairlist_flag = false;
  687. sw_reset_kick(SW_RST_CLEAR_PAIRLIST);
  688. }
  689. else if(hlw_cb.need_reset_flag)
  690. {
  691. hlw_cb.need_reset_flag = false;
  692. sw_reset_kick(SW_RST_FLAG);
  693. }
  694. #endif
  695. if ((PWRKEY_2_HW_PWRON) && (sys_cb.poweron_flag)) {
  696. RTCCON13 |= BIT(16); //WK PIN0 High level wakeup
  697. }
  698. gsensor_lowpwr();
  699. sfunc_pwrdown(1);
  700. } else {
  701. #if SYS_KARAOK_EN
  702. bsp_karaok_exit(AUDIO_PATH_KARAOK);
  703. #endif
  704. dac_power_off(); //dac power down
  705. bsp_saradc_exit(); //close saradc及相关通路模拟
  706. sfunc_lowbat(); //低电关机进入Sleep Mode
  707. }
  708. }