/* ****************************************************************************** * * @file UserApp.c * @brief UserApp module * * * @version 1.0 * @date 2023/03/27 15:00:40 * @author Alex Xu * * Copyright (c) 2013-2099,Tkplusemi Technology Co.,Ltd. * All Rights Reserved * * History: * Revision Date Author Desc * 1.0.0 2023/03/27 Alex build this file ******************************************************************************/ /*_____ I N C L U D E S ____________________________________________________*/ #include "userapp.h" #include "gpio.h" #include "adc.h" #include "hall.h" #include "key.h" #include "sleep.h" #include "system.h" #include "bat.h" #include "sys_tim.h" #include "charger_module.h" #include "discharge_module.h" #include "led.h" #include "vox_module.h" /******************************************************************************\ Macro definitions \******************************************************************************/ #if LED_188 #define LED_ON_CNT 10 //充满显示10s后熄灭 #define LED_BLINK_CNT 1 #define LED_NUM_UNIT_CNT 1 #define LED_COVER_CNT 4 //开关盖显示4s后熄灭 #define BATLEV_UPDATE_UINT_TIM_CHG0 20 //无输出充电时间 #define BATLEV_UPDATE_UINT_TIM_CHG1 30 //40mA输出充电时间。 #define BATLEV_UPDATE_UINT_TIM_CHG2 35 //80mA输出充电时间。 #define BATLEV_UPDATE_UINT_TIM_DISCHG0 80 //慢放电时间 #define BATLEV_UPDATE_UINT_TIM_DISCHG1 10 //放电快追时间 #define BATLEV_UPDATE_UINT_TIM_DISCHG2 50 //电量小于10%时的放电时间 #endif #define VOX_RST_CNT 3 //Vox软复位debounce时间 /******************************************************************************\ Variables definitions \******************************************************************************/ uint8_t bat_level_update = 188; uint8_t LED_On_Timer = 0; //led亮时间计时 uint8_t Vox_Rst_Debounce = 0; bit CHG_LED_Disp_Flag = 0; #if LED_188 uint8_t bat_level_Disp_Num = 0; bit LED_188_Disp_Flg = 0; uint8_t Disp_Vor_Lev = 0; uint8_t Disp_Vol_Lev = 0; #endif /******************************************************************************\ Functions definitions \******************************************************************************/ #if LED_188 /***************************************************************************** * Function : void LED_Display_App(void) * Description : 5000ms调用周期 * Input : None * Output : None * Return : None * Note : None *****************************************************************************/ /* 灯效 数码管: 充电:显示百分百比电量,个位数闪烁 放电:左右耳对应的图标跑马,从下往上,盒子电量常亮(边充边放时,耳机图标和百分比要同时变化)。 开盖:显示充电盒百分比电量4S后灭掉。 关盖:有耳机充电则参考“放电灯效”;没耳机则显示百分百比电量4S后灭掉。 */ bit Init_LED_Disp_Flag = 0; uint8_t BatLev_Update_Uint_Tim = BATLEV_UPDATE_UINT_TIM_DISCHG1; uint8_t BatLev_Update_Uint_CHG_Tim = 0; //uint8_t BatLev_Update_Uint_DisCHG_Tim = 0; bit g_188_Num_Dec = 0; void LED_188Display_App(void) { uint8_t i = 0; static uint8_t BatLev_Update_Uint_Cnt; if (bat_level_update != bat_level) //电量发生变化,不能立刻变化,需要缓慢变化 { bat_level_Disp_Num = 10 * bat_level; bat_level_update = bat_level; } else { BatLev_Update_Uint_Cnt++; if( BatLev_Update_Uint_Cnt > BatLev_Update_Uint_Tim ) { BatLev_Update_Uint_Cnt = 0; if ( CHIP_STA4 & 0x80 ) //充电中 { if( g_188_Num < (bat_level_Disp_Num + 9) ) { g_188_Num += 1; } BatLev_Update_Uint_Tim = BatLev_Update_Uint_CHG_Tim; //充电30s更新一次电量个位数 } else { if( ( Vor_Vout_Enable == ON ) || ( Vol_Vout_Enable == ON ) ) //有耳机充电,电量才减 { if ( bat_level_Disp_Num <= 10 ) { if( g_188_Num > 10 ) { BatLev_Update_Uint_Tim = BATLEV_UPDATE_UINT_TIM_DISCHG1; } else { BatLev_Update_Uint_Tim = BATLEV_UPDATE_UINT_TIM_DISCHG2; /* 2、当显示的电量小于10%,则60s变化一次。*/ } g_188_Num_Dec = 1; } else { if( g_188_Num > bat_level_Disp_Num ) { /* 1、当188数码管显示的电量比实际电量大,则数字快速变化。 */ if( ( g_188_Num - bat_level_Disp_Num ) > 5 ) { BatLev_Update_Uint_Tim = BATLEV_UPDATE_UINT_TIM_DISCHG1; } else { BatLev_Update_Uint_Tim = BATLEV_UPDATE_UINT_TIM_DISCHG0; /*3、当显示电量和实际电量差不多时则60s更新一次电量个位数 */ } g_188_Num_Dec = 1; } } if( g_188_Num_Dec ) { g_188_Num_Dec = 0; if( g_188_Num > 0 ) { g_188_Num -= 1; } } /*电量计数到0,但未出现低电告警,则电量显示1%.*/ if( (g_188_Num == 0) && !F_batlevel_protect ) { g_188_Num = 1; } } } if( g_188_Num > 100 ) { g_188_Num = 100; } } /*非充电条件下,出现电池低电报警,则电量显示0%*/ if( F_batlevel_protect && !( CHIP_STA4 & 0x80 ) ) { g_188_Num = 0; } } #ifdef NTC_ENABLE /*NTC保护*/ if( NTC_Pro_Flag ) { if( !LED_188_Disp_Flg ) { #if DISPLAY_6PIN_188 Set_NumLED_Down(); #endif #if DISPLAY_5PIN_188 Set_AllLed_Down(); #endif LED_188_Disp_Flg = 1; } else { Display_Show_Num(g_188_Num); LED_188_Disp_Flg = 0; } return; } #endif if( Init_LED_Disp_Flag ) { if ( CHIP_STA4 & 0x80 ) //充电中 { if ( Charger_Done ) // 充电完成,LED绿灯常亮 { if( LED_On_Timer < LED_ON_CNT ) { LED_On_Timer++; g_188_Num = 100; Display_Show_Num(g_188_Num); } else { Set_AllLed_Down(); } } else { /*188数码管个位数闪烁显示。*/ if( !LED_188_Disp_Flg ) { #if DISPLAY_6PIN_188 for(i=13;i<20;i++) { Display_Ram_Tab[i] = 0; } #endif #if DISPLAY_5PIN_188 for(i=9;i<16;i++) { Display_Ram_Tab[i] = 0; } #endif LED_188_Disp_Flg = 1; } else { if(g_188_Num >= 99) //未出现chg_done,则电量卡在99,各位数闪。 { g_188_Num = 99; } Display_Show_Num(g_188_Num); LED_188_Disp_Flg = 0; } } CHG_LED_Disp_Flag = 1; } else { if ( Vol_GetInto_Box_Flag || Vor_GetInto_Box_Flag || CHG_LED_Disp_Flag ) //耳机入盒,显示灯效 { if( ( Vor_Vout_Enable == OFF ) && ( Vol_Vout_Enable == OFF ) ) //盒子里没耳机则显示百分百比电量4S后灭掉 { if( LED_On_Timer < LED_COVER_CNT ) { LED_On_Timer++; Display_Show_Num(g_188_Num); } else { LED_On_Timer = 0; Vol_GetInto_Box_Flag = 0; Vor_GetInto_Box_Flag = 0; CHG_LED_Disp_Flag = 0; } } else //盒子里有耳机,则显示电量 { Display_Show_Num(g_188_Num); } } else { Set_AllLed_Down(); } } #if DISPLAY_6PIN_188 /*放电:左右耳对应的图标跑马,从下往上,盒子电量常亮*/ if( Vor_Vout_Enable == ON && !Vor_GetOut_Box_Flag ) { Display_Show_Vor(Disp_Vor_Lev); Disp_Vor_Lev++; if(Disp_Vor_Lev > 4) { Disp_Vor_Lev = 1; } /*1只耳机放电,设置充放电时间*/ // BatLev_Update_Uint_DisCHG_Tim = BATLEV_UPDATE_UINT_TIM_DISCHG1; BatLev_Update_Uint_CHG_Tim = BATLEV_UPDATE_UINT_TIM_CHG1; } else { Display_Show_Vor(0); } if( Vol_Vout_Enable == ON && !Vol_GetOut_Box_Flag ) { Display_Show_Vol(Disp_Vol_Lev); Disp_Vol_Lev++; if(Disp_Vol_Lev > 4) { Disp_Vol_Lev = 1; } /*1只耳机放电,设置充放电时间*/ // BatLev_Update_Uint_DisCHG_Tim = BATLEV_UPDATE_UINT_TIM_DISCHG1; BatLev_Update_Uint_CHG_Tim = BATLEV_UPDATE_UINT_TIM_CHG1; } else { Display_Show_Vol(0); } if( ( Vol_Vout_Enable == ON && !Vol_GetOut_Box_Flag ) && ( Vor_Vout_Enable == ON && !Vor_GetOut_Box_Flag ) ) { if( Disp_Vor_Lev != Disp_Vol_Lev ) { Disp_Vol_Lev = 1; Disp_Vor_Lev = 1; } /*2只耳机同时放电,设置充放电时间*/ // BatLev_Update_Uint_DisCHG_Tim = BATLEV_UPDATE_UINT_TIM_DISCHG0; BatLev_Update_Uint_CHG_Tim = BATLEV_UPDATE_UINT_TIM_CHG2; } #endif } } #endif /***************************************************************************** * Function : UserAPP * Description : 5ms调用周期 * Input : None * Output : None * Return : None * Note : None *****************************************************************************/ void UserAPP(void) { if(F_sys_tim_10ms) { F_sys_tim_10ms = 0; #if VOX_ENABLE /* 用于关Boost时耦合信号到VOX,出现loadon信号复位;在关boost后使用软件复位VOX30ms可解决。*/ if( (Vor_Vout_Enable == OFF) && (Vol_Vout_Enable == OFF) ) //无放电,关Boost。 { if( Vor_Vout_Close_Flag || Vol_Vout_Close_Flag ) { #if DISCHARGE_ENABLE BST_EN = 0; //Boost Disable #endif #ifdef _DEBUG_VOX printf("Close Boost.\r\n"); #endif if(Vox_Rst_Debounce < VOX_RST_CNT) { Vox_Rst_Debounce++; SFRADDR = VOX_CON0; SFRDATA |= 0x80; //使能VOX软件复位 VOX_CTL0 |= 0x0C; //VOX上拉使能复位 } else { Vor_Vout_Close_Flag = 0; Vol_Vout_Close_Flag = 0; Vox_Rst_Debounce = 0; SFRADDR = VOX_CON0; SFRDATA &= ~0x80; //使能VOX硬件复位 VOX_CTL0 &= ~0x0C; } } #if DISPLAY_6PIN_188 BatLev_Update_Uint_CHG_Tim = BATLEV_UPDATE_UINT_TIM_CHG0; #endif } #endif #ifdef LED_DISPLAY LED_Drv(); #endif } if(F_sys_tim_100ms) { F_sys_tim_100ms = 0; #if HALL_ENABLE Hall_Handler(); //开关盖检测 #endif #if DISCHARGE_ENABLE DisCharge_Handler(); //放电boost功能 #endif #if KEY_ENABLE Key_Handler(); //按键检测 #endif #if CHARGER_ENABLE Charger_Handler(); //充电功能 #endif #if ADC_ENABLE Vbat_Adc = Vbat_Value(); //获取Bat电压 #endif #if BAT_VALUE check_bat_level(); #endif #if VOX_ENABLE Vol_Det_Machine(); Vor_Det_Machine(); #endif } if( F_sys_tim_1s ) { F_sys_tim_1s = 0; #if LED_188 LED_188Display_App(); //LED 灯效 #endif #if SLEEP_ENABLE /*1、唤醒后工作Ns后进入Sleep Mode,N需要大于100ms。 2、有VIN存在的情况下,系不会进入sleep mode。 */ if( Decnt_SleepDelay > 0 ) /*能否在数字中实现此功能?*/ { Decnt_SleepDelay--; /*倒数进Sleep Mode过程中出现了KEY\HALL\Loadon\IOFF中断,则重新计时。*/ if( Enter_Sleep_Cnt_Restart_Flag ) { Enter_Sleep_Cnt_Restart_Flag = 0; Decnt_SleepDelay = ENTER_STANDBYMODE_CNT; } #ifdef _DEBUG_MAIN printf("sleep decnt:%d,STA0:0x%x,STA1:0x%x,STA2:0x%x,STA4:0x%x\r\n", (uint16_t)Decnt_SleepDelay,(uint16_t)CHIP_STA0,(uint16_t)CHIP_STA1,(uint16_t)CHIP_STA2,(uint16_t)CHIP_STA4); #endif return; } if( Check_Require_Sleep() ) { /* Enter Sleep */ SFRADDR = WKUP_EN3; //vox loadon wake up enable SFRDATA |= 0x3C; #ifdef _DEBUG_MAIN printf("Get Into Sleep.\r\n"); #endif /* InSleep Handler */ //Disable All IRQ #if TIMER1_ENABLE ET1 = 0; //timer1 IRQ Disable #endif #if UART0_ENABLE ES0 = 0; //UART0 IRQ Disable #endif EX2 = 0; ET0 = 0; //timer0 IRQ Disable SFRADDR = ADC_CTL0; SFRDATA &= ~0x80; //ADC Disable. #if LED_188 SFRADDR = P0_OE; SFRDATA &= 0xC0; #endif SFRADDR = PMU_CTL0; //芯片硬件需求,固定 SFRDATA &= ~0x30; PCON |= 0x02; //Enter StandbyMode, Only int0 or int1 can wake up system SFRADDR = PMU_CTL0; //芯片硬件需求,固定 SFRDATA |= 0x30; /* OutSleep Handler */ //Enable IRQ #if UART0_ENABLE ES0 = 1; //UART0 IRQ #endif EX2 = 1; ET0 = 1; //timer0 IRQ #if TIMER1_ENABLE ET1 = 1; //timer1 IRQ #endif Decnt_SleepDelay = ENTER_STANDBYMODE_CNT; } else { Decnt_SleepDelay = ENTER_STANDBYMODE_CNT; } #endif } }