123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568 |
- #include "include.h"
- #include "func.h"
- void user_tmr_set_enable(bool tmr5ms, bool tmr1ms);
- void bsp_set_stop_time(u16 stop_time);
- u8 power_off_check(void);
- uint32_t sleep_timer(void); //休眠定时器,500ms进一次(返回值: 1->关机 2->退出sleep)
- void sfunc_lowbat(void);
- void sfunc_pwrdown(u8 vusb_wakeup_en);
- void sfunc_power_save_enter(void);
- void delay_15us(void);
- bool led_bt_sleep_tws_sync(void);
- extern u32 __sleep_comm_vma, __sleep_comm_lma, __sleep_comm_size;
- extern u32 __pwrdwn_comm_vma, __pwrdwn_comm_lma, __pwrdwn_comm_size;
- #define RI_VRTC(bit) RTCCON4 = (RTCCON4 & ~(3<<24)) | ((bit)<<24)
- //休眠定时器,500ms进一次(返回值: 1->关机 2->退出sleep)
- AT(.text.sleep_com.timer)
- uint32_t sleep_timer(void)
- {
- uint32_t ret = 0;
- sys_cb.sleep_counter++;
- #if CHARGE_EN
- //定时检测charge状态
- if (xcfg_cb.charge_en) {
- charge_detect();
- if ((sys_cb.sleep_counter % 2) == 0) { //1秒调用一次
- bsp_charge_bled_ctrl();
- }
- if (!port_2led_is_sleep_en()) { //1个IO推两个灯, 充电状态需要退出休眠, 否则充电灯指示不正常
- ret = 2;
- }
- }
- #endif // CHARGE_EN
- #if VBAT_DETECT_EN || USER_NTC || CHARGE_TSEN_DETECT
- //定时检测电池电量, 低电需要唤醒
- if (sys_cb.sleep_counter == 10) {
- sys_cb.sleep_counter = 0;
- bsp_bcnt_temp_calibration();
- bsp_saradc_init(adc_cb.channel);
- if ((LPWR_WARNING_VBAT) && (sys_cb.vbat < ((u16)LPWR_WARNING_VBAT*100 + 2850))) {
- //低电需要唤醒sniff mode
- ret = 2;
- }
- #if USER_NTC
- if ((xcfg_cb.sys_ntc_en) && (adc_cb.ntc_val <= xcfg_cb.ntc_thd_val)) {
- ret = 2;
- }
- #endif
- #if CHARGE_TSEN_DETECT
- charge_tsen_check(1);
- #endif
- saradc_exit(adc_cb.channel);
- }
- #endif // VBAT_DETECT_EN
- #if BT_TWS_SLEEP_LED_SYNC_EN
- if (led_bt_sleep_tws_sync()) {
- sys_cb.sleep_wakeup_time = 50000 / 312;
- } else {
- sys_cb.sleep_wakeup_time = -1L;
- }
- #else
- sys_cb.sleep_wakeup_time = led_bt_sleep(xcfg_cb.led_bt_sleep_sel);
- #endif
- if ((sys_cb.pwroff_delay != -1L) && (sys_cb.sleep_wakeup_time == -1L)) {
- if(sys_cb.pwroff_delay > 5) {
- sys_cb.pwroff_delay -= 5;
- } else {
- sys_cb.pwroff_delay = 0;
- return 1;
- }
- }
- if ((PWRKEY_2_HW_PWRON) && (!IS_PWRKEY_PRESS())){
- ret = 1;
- }
- return ret;
- }
- AT(.text.lowpwr.sleep)
- static void sfunc_sleep_dac_off(u8 off)
- {
- #if ANC_EN
- if (sys_cb.anc_start) {
- return;
- }
- #endif
- if (off) {
- #if ANC_EN
- bsp_anc_stop();
- #endif
- #if TINY_TRANSPARENCY_EN
- bsp_ttp_stop();
- #endif
- dac_power_off(); //dac power down
- if(!SLEEP_DAC_OFF_EN) {
- dac_power_off_pulldown_daclr();
- }
- } else {
- if(!SLEEP_DAC_OFF_EN) {
- dac_power_off_restore_daclr();
- }
- dac_restart();
- #if ANC_EN || TINY_TRANSPARENCY_EN
- bsp_anc_set_mode(sys_cb.anc_user_mode);
- #endif
- }
- }
- #if USER_LED_SLEEP_EN
- void sys_sleep_cb(u8 lpclk_type)
- {
- u32 clkgat0 = CLKGAT0;
- u32 clkcon0 = CLKCON0;
- u32 clkcon2 = CLKCON2;
- u32 clkcon1 = CLKCON1;
- u32 xo26mcon = XO26MCON;
- RI_VIO_TC(0); //减小VDDIO尾电流, 减小功耗
- CLKCON2 = (CLKCON2&0x00ffffff) | (25<<24); //div26, x26m_div_clk=1m
- CLKCON0 |= BIT(2) | BIT(3); //select x26m_div_clk as sysclk
- asm("nop");asm("nop");
- if (!sys_cb.sleep_aupll_en) {
- RSTCON0 &= ~BIT(7); //reset adda_clk48_a
- CLKGAT0 &= ~(BIT(12) | BIT(22)); //disable dac_clk, sdadcl_clk gate
- CLKCON1 &= ~0x3; //disable dac clk
- }
- asm("nop");asm("nop");
- // CLKGAT0 &= ~BIT(20); //disable bt 52m clock
- XO26MCON &= ~BIT(5); //DI_EN_CCKOUT_X2
- asm("nop");asm("nop");
- // LPMCON |= BIT(2); //system sniff
- asm("nop");asm("nop");
- asm("nop");asm("nop");
- //wakeup now
- XO26MCON = xo26mcon;
- delay_15us();
- if (!sys_cb.sleep_aupll_en) {
- CLKCON1 = clkcon1; //recover dac clk
- delay_15us();
- CLKGAT0 |= (BIT(12) | BIT(22)); //enable dac_clk, sdadcl_clk gate
- delay_15us();
- RSTCON0 |= BIT(7); //release adda_clk48_a
- }
- asm("nop"); asm("nop");
- CLKGAT0 = clkgat0; //enable bt 52m clock
- CLKCON2 = clkcon2;
- CLKCON0 = clkcon0;
- RI_VIO_TC(3);
- }
- #endif // USER_LED_SLEEP_EN
- AT(.text.sleep_com.process)
- u32 sfunc_sleep_process(void)
- {
- uint32_t status, ret = 0;
- u32 wkupedg;
- bsp_gpiode_reinit_save(); //io analog input
- loudspeaker_gpiode_set(); //sleep维持mute脚状态
- atmosphere_led_gpiode_set(); //sleep维持氛围灯状态
- #if BT_EARIN_DETECT_EN
- earin_sniff_gpiode_set(); //sleep维持入耳检测IO状态
- #endif
- // if(xcfg_cb.bb_rxtx_sync_dbg_en) {
- // GPIOADE |= BIT(7) | BIT(6);
- // GPIOBDE |= BIT(4);
- // }
- #if USER_NTC
- if (xcfg_cb.sys_ntc_en) {
- adc_cb.channel |= BIT(NTC_ADCCH);
- ntc_gpio_inner_pu10k_init(); //sleep维持ntc检测
- }
- #endif
- #if CHARGE_TSEN_DETECT
- adc_cb.channel |= BIT(ADCCH_VTSEN); //sleep维持tsen检测
- #endif
- #if CHARGE_EN
- if (CHARGE_DC_IN()) { //保持充电灯的IO状态
- if (sys_cb.charge_sta == 1) {
- charge_led_on();
- } else if (sys_cb.charge_full_bled_flag == 1) {
- charge_bled_on();
- }
- }
- bsp_set_stop_time(3600);
- #endif // CHARGE_EN
- WKUPEDG = 0;
- WKUPCON = 0;
- PORTINTEDG = 0;
- PORTINTEN = 0;
- sys_cb.sleep_wakeup_time = -1L;
- sys_cb.sleep_counter = 0;
- sleep_wakeup_config();
- while(bt_is_sleep()) {
- WDT_CLR();
- status = bt_sleep_proc();
- if(status == 1) {
- ret = sleep_timer();
- if(ret) {
- if (ret == 1) {
- sys_cb.pwrdwn_tone_en = 1;
- func_cb.sta = FUNC_PWROFF;
- }
- break;
- }
- }
- // printf("WKUPEDG:%x\n", WKUPEDG);
- if (WKUPEDG & (0xff << 16)) {
- break;
- }
- #if BT_TWS_AUTO_SWITCH
- if((sys_cb.dc_rst_flag != 0) && CHARGE_DC_IN()) {
- break;
- }
- #endif // BT_TWS_AUTO_SWITCH
- if (bsp_chbox_type_is_maintain_volt() && CHARGE_INBOX()) {
- break;
- }
- #if USER_TKEY
- if (tkey_is_pressed()) {
- break;
- }
- #endif
- #if BT_EARIN_DETECT_EN
- if (earin_is_wakeup() || touchear_is_wakeup()) {
- break;
- }
- #endif
- }
- wkupedg = WKUPEDG;
- WKUPCPND = 0xff << 16;
- WKUPCON = 0;
- WDT_CLR();
- bsp_gpiode_recover();
- return wkupedg;
- }
- AT(.text.lowpwr.sleep)
- void sfunc_sleep(void)
- {
- uint32_t sysclk;
- u32 wkupedg;
- u16 adc_ch;
- #if VBAT_DETECT_EN
- if (is_lowpower_vbat_warning() || sys_cb.breathe_led_sta) { //低电或呼吸灯不进sniff mode
- return;
- }
- #endif // VBAT_DETECT_EN
- #if LOUDSPEAKER_MUTE_MUX_RLED_EN
- if (sys_cb1.unmute_rled_on) {
- return;
- }
- #endif
- printf("sleep\n");
- #if !USER_LED_SLEEP_EN
- bt_enter_sleep();
- led_off();
- rled_off();
- #endif
- #if DAC_DNR_EN
- u8 sta = dac_dnr_get_sta();
- dac_dnr_set_sta(0);
- #endif
- sfunc_sleep_dac_off(1);
- saradc_exit(adc_cb.channel); //close saradc及相关通路模拟
- #if !USER_LED_SLEEP_EN
- user_tmr_set_enable(0, 0);
- #endif
- sysclk = sys_clk_get();
- sys_clk_set(SYS_26M);
- bsp_bcnt_temp_calibration_start();
- if (!sys_cb.sleep_aupll_en) {
- adpll_disable();
- }
- adc_ch = adc_cb.channel;
- adc_cb.channel = BIT(ADCCH_VBAT) | BIT(ADCCH_BGOP);
- memcpy(&__sleep_comm_vma, &__sleep_comm_lma, (u32)&__sleep_comm_size); //Load sleep comm
- wkupedg = sfunc_sleep_process(); //不能切Flash
- if (!sys_cb.sleep_aupll_en) {
- adpll_init(DAC_OUT_SPR); //enable adpll
- }
- dac_clk_source_sel(1); //dac clk select adpll_div(PLL0)
- bsp_bcnt_temp_calibration_stop();
- adc_cb.channel = adc_ch;
- bsp_saradc_init(adc_cb.channel);
- if (wkupedg & BIT(16 + 5)) { //pwrkey wakeup, 加快第一次短按检测
- u16 key_val = get_pwrkey();
- if (key_val != NO_KEY) {
- bsp_key_process(key_val);
- key_cb.cnt = key_cb.filter.scan_cnt - 2;
- }
- }
- #if CHARGE_EN
- bsp_set_stop_time(18000);
- #endif // CHARGE_EN
- sys_clk_set(sysclk);
- user_tmr_set_enable(1, 1);
- sfunc_sleep_dac_off(0);
- bsp_change_volume(sys_cb.vol);
- #if DAC_DNR_EN
- dac_dnr_set_sta(sta);
- #endif
- bt_exit_sleep();
- #if BT_DISP_LOW_VBAT_EN
- sys_cb1.disp_low_vbat_flag = 1;
- #endif
- printf("wakeup\n");
- }
- AT(.text.bfunc.sleep)
- bool sleep_process(is_sleep_func is_sleep)
- {
- if ((*is_sleep)()) {
- if ((!sys_cb.sleep_en) || (!port_2led_is_sleep_en())) {
- reset_sleep_delay();
- return false;
- }
- if(sys_cb.sleep_delay == 0) {
- sfunc_sleep();
- reset_sleep_delay();
- return true;
- }
- } else {
- reset_sleep_delay();
- }
- return false;
- }
- extern const u8 chg_timeout_tbl[4];
- ///解决充满关机后按充电仓按键不能唤醒进入充电的问题(5V掉电但有维持电压的仓类型)
- AT(.text.pwrdwn.vusb)
- static u8 sfunc_pwrdown_w4_vusb_offline(void)
- {
- u32 off_cnt = 0;
- u32 timeout = (u32)chg_timeout_tbl[xcfg_cb.ch_w4_off_sel] * 200;
- if ((xcfg_cb.ch_box_type_sel != 1) && timeout) {
- if (xcfg_cb.led_charge_fully_xcfg == 1) {
- charge_bled_on();
- }
- while (timeout--) {
- WDT_CLR();
- delay(1700); //5ms
- if (!CHARGE_DC_IN()) {
- off_cnt++;
- } else {
- off_cnt = 0;
- }
- if (off_cnt > 5) {
- return 1; //VUSB已掉线,打开VUSB唤醒
- }
- }
- }
- return 0;
- }
- AT(.text.pwrdwn.lowbat)
- void sfunc_lowbat_do(void)
- {
- sfunc_power_save_enter();
- WDT_DIS();
- LPMCON |= BIT(0); //Sleep mode enable
- asm("nop");asm("nop");asm("nop");
- while(1);
- }
- //硬开关方案,低电时,进入省电状态
- void sfunc_lowbat(void)
- {
- memcpy(&__pwrdwn_comm_vma, &__pwrdwn_comm_lma, (u32)&__pwrdwn_comm_size); //Load pwrdwn comm
- sfunc_lowbat_do();
- }
- //软开关方案,POWER键/低电时,进入关机状态
- AT(.text.pwrdwn)
- void sfunc_pwrdown_do(u8 vusb_wakeup_en)
- {
- printf("%s:%d\n", __func__, vusb_wakeup_en);
- u32 tkey_wakeup_en = sys_cb.tkey_pwrdwn_en;
- u32 wakeup_bit = 0;
- WDT_CLR();
- vusb_delay_rst_dis();
- if (sys_cb.vbat < 3050) {
- tkey_wakeup_en = 0; //低电关机, 关掉触模唤醒
- }
- RTCCON4 &= ~BIT(15); //RI_VIO_PD(0)
- RTCCON8 &= ~BIT(15); //RI_EN_VUSBDIV = 0
- RTCCON1 &= ~(BIT(5) | BIT(7)); //BIT(7): VRTC voltage for ADC, BIT(5):WK pin analog
- RTCCON9 = 0xfff; //Clr pending
- if (!vusb_wakeup_en && xcfg_cb.ch_box_type_sel == 3) { //5V完全掉电的仓
- RTCCON3 &= ~BIT(12); //RTCCON3[12], INBOX Wakeup disable
- }
- if (sys_cb.pdn_boat_flag) { //船运模式关机, 只保留5V唤醒。
- RTCCON3 &= ~BIT(12); //RTCCON3[12], INBOX Wakeup disable
- tkey_wakeup_en = 0; //disable tkey wakeup
- }
- if (!(RTCCON3 & BIT(12))) { //非仓内关机, 开下漏电
- bsp_charge_leakage_set(1, 0);
- } else {
- if (bsp_chbox_type_is_maintain_volt()) { //有维持电压的充电仓关闭leakage漏电
- bsp_charge_leakage_set(0, 0);
- }
- }
- if ((RTCCON3 & BIT(12)) || sys_cb.lowpwr_dwn_flag || xcfg_cb.user_tkey_wakeup_dis) { //仓内关机或低电关机?
- tkey_wakeup_en = 0; //disable tkey wakeup
- }
- if ((tkey_wakeup_en) && (!xcfg_cb.user_tkey_alarm_dis)) {
- RTCCON0 |= BIT(21); //BGUV reset TKSWRSTN
- RTCCON8 |= BIT(29); //RI_EN_BGUVT = 1, rtc bgp undervoltage detect enable
- }
- sfunc_power_save_enter();
- if (!vusb_wakeup_en || sys_cb.chstop_pwrwn_en) {
- RTCCON8 = (RTCCON8 & ~BIT(6)) | BIT(1); //disable charger function
- }
- if (!vusb_wakeup_en) { //充满关机
- vusb_wakeup_en = sfunc_pwrdown_w4_vusb_offline();
- }
- RTCCON11 = (RTCCON11 & ~0x03) | BIT(2); //WK PIN filter select 8ms
- uint rtccon3 = RTCCON3 & ~BIT(11);
- #if CHARGE_EN
- if (((xcfg_cb.charge_en) && (vusb_wakeup_en))||get_qtest_mode()) {
- rtccon3 |= BIT(11); //VUSB wakeup enable
- #if CHARGE_PULL_OUT_FILTER_EN
- RTCCON &= ~BIT(6); //VUSB insert reset system disable
- asm("nop"); asm("nop");
- RTCCON3 |= BIT(11); //VUSB wakeup enable
- RTCCON11 |= BIT(6); //VUSB pull out filter VUSB拔出滤波
- delay_us(100);
- RTCCON10 = BIT(3);
- #endif
- }
- #endif
- RTCCON3 = rtccon3 & ~(BIT(10) | BIT(14)); //关WK PIN,再打开,以清除Pending
- wakeup_bit = RTCCON3 & (0xff << 8); //备份wakeup
- if ((TKCON1 & BIT(13)) && tkey_wakeup_en) { //TK is enable?
- pmu_vdd11_select_vrtc11();
- RTCCON3 |= BIT(14); //Touch key long press wakeup
- wakeup_bit |= BIT(14);
- RTCCON0 &= ~BIT(4); //TKITF_EN disable
- } else {
- RTCCON0 |= BIT(4);
- INPCPND = BIT(0);
- RTCCON0 &= ~BIT(5); //touch key reset
- RTCCON0 &= ~BIT(0); //RING2M_RTC Disable
- RTCCON0 &= ~BIT(4); //TKITF_EN disable
- }
- uint rtccon1 = RTCCON1 & ~0x1f;
- rtccon3 = RTCCON3 & ~0x17; //Disable VDDCORE, buck
- rtccon3 |= BIT(6); //Core power down enable, VDDCORE short disable
- #if USER_PWRKEY
- if (sys_cb.wko_pwrkey_en) {
- if (!sys_cb.pdn_boat_flag) {
- wakeup_bit |= BIT(10);
- rtccon3 |= BIT(10); //WK pin wake up enable
- }
- rtccon1 |= BIT(0) | BIT(2) | BIT(4); //WK 90K pull up enable
- rtccon3 &= ~BIT(5); //RI_EN_PG_2CORE = 0, vddcore-vdd11 short disable
- }
- #endif
- WDT_DIS();
- RTCCON |= BIT(5); //PowerDown Reset,如果有Pending,则马上Reset
- RTCCON1 = rtccon1;
- RTCCON3 = rtccon3 | wakeup_bit;
- LPMCON |= BIT(0);
- LPMCON |= BIT(1); //idle mode
- asm("nop");asm("nop");asm("nop");
- while (1);
- }
- void sfunc_pwrdown(u8 vusb_wakeup_en)
- {
- memcpy(&__pwrdwn_comm_vma, &__pwrdwn_comm_lma, (u32)&__pwrdwn_comm_size); //Load pwrdwn comm
- sfunc_pwrdown_do(vusb_wakeup_en);
- }
- AT(.text.lowpwr.pwroff)
- void func_pwroff(int pwroff_tone_en)
- {
- printf("%s\n", __func__);
- #if VUSB_SMART_VBAT_HOUSE_EN
- if (vhouse_cb.inbox_sta) {
- bsp_charge_inbox_wakeup_enable();
- }
- #endif
- vusb_delay_rst_dis();
- led_power_down();
- motor_enable(MOTOR_PWROFF, T_MOTOR_PWROFF_SEL);
- #if WARNING_POWER_OFF
- if ((pwroff_tone_en) && (SOFT_POWER_ON_OFF)) {
- sys_warning_play(T_WARNING_POWER_OFF, PIANO_POWER_OFF);
- }
- #endif // WARNING_POWER_OFF
- dac_power_off(); //dac power down
- motor_disable();
- if (SOFT_POWER_ON_OFF) {
- if (!PWRKEY_2_HW_PWRON) {
- u8 dcin_cnt = 0;
- #if USER_TKEY
- tkey_press_timeout_clr();
- #endif
- while (IS_PWRKEY_PRESS() || IS_TKEY_PRESS()) { //等待PWRKWY松开
- if (CHARGE_DC_IN()) {
- dcin_cnt++;
- if (dcin_cnt > 3) {
- sw_reset_kick(SW_RST_DC_IN); //直接复位进入充电
- }
- } else {
- dcin_cnt = 0;
- }
- #if USER_TKEY
- if (sys_cb.tkey_pwrdwn_en) {
- tkey_press_timeout_process();
- }
- #endif
- delay_5ms(2);
- WDT_CLR();
- }
- }
- led_power_down_w4_done();
- if (CHARGE_DC_IN() && (xcfg_cb.chbox_en == 0)) {
- if (!power_off_check()) {
- return; //pwrkey按下,再次开机
- }
- }
- saradc_exit(adc_cb.channel); //close saradc及相关通路模拟
- if ((PWRKEY_2_HW_PWRON) && (sys_cb.poweron_flag)) {
- RTCCON1 |= BIT(6); //WK PIN High level wakeup
- }
- sfunc_pwrdown(2);
- } else {
- saradc_exit(adc_cb.channel); //close saradc及相关通路模拟
- led_power_down_w4_done();
- sfunc_lowbat(); //低电关机进入Sleep Mode
- }
- }
|