/* ****************************************************************************** * * @file UserApp.c * @brief UserApp module * @ic sy8835 * * @version 1.0 * @date 2024/11/01 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 2024/11/01 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 \******************************************************************************/ #define LED_ON_CNT 100 //10s #define LED_PRO_TIM 40 #define LED_OFF_CNT 1 /******************************************************************************\ Variables definitions \******************************************************************************/ xdata s_sys_state Systerm_State = {SLEEP_STATE,AWAKE_STATE,AWAKE_STATE}; uint8_t LED_On_Timer = 0; //led亮时间计时 bit LED_On_Flag = 0; bit Wkup_Earphone_Flag = 0; //保护消失后,需要升压唤醒耳机标志位 uint8_t Wkup_Source_Flag = 0; //唤醒源标志 #ifdef PWM_ENABLE uint8_t Breathing_Light_Cnt = 0; #endif /******************************************************************************\ Functions definitions \******************************************************************************/ /***************************************************************************** * Function : void LED_Display_App(void) * Description : 100ms调用周期 * Input : None * Output : None * Return : None * Note : None *****************************************************************************/ /* 充电: 1、充电中,无其它行为打断时,开关盒状态下都显示充电常亮灯效(1Hz闪烁); 2、充满,常亮;可被其它灯效打断; 非充电: 1、首次使用开盖灯效:①高电:亮4s后灭;②低电:1Hz闪4s后灭; 2、非首次使用开盖灯效:①耳机在盒:亮4s后灭;②耳机不在盒:???? ③充电中,开盖闪一下,如何闪?亮多久后灭? 3、关盖灯效,高电:亮4s后灭;低电:1Hz闪4s后灭; 4、关盒状态下无灯效显示; */ #ifdef LED_DISPLAY void LED_Breating_Light_Off(void) { #ifdef PWM_ENABLE LED_R_BREATHING_LIGHT(SHOW_NONE); LED_G_BREATHING_LIGHT(SHOW_NONE); LED_Y_BREATHING_LIGHT(SHOW_NONE); LED_B_BREATHING_LIGHT(SHOW_NONE); #endif } void LED_Display_App(void) { #ifdef NTC_ENABLE static bit LED_On_Flag1; #endif static bit LED_On_Chg_Flag; static bit LED_On_ChgDone_Flag; static bit Disp_Bat_Lev; #ifdef NTC_ENABLE /*NTC保护,4灯一直快闪(2Hz)*/ if( NTC_Pro_Flag || Vox_Output_Short_Flag ) { if( !LED_On_Flag1 ) { LED_On_Flag1 = 1; LED_On_Flag = 1; } else { if( Display_RSta != LED_KEEP_FLASHING ) { Display_Red_Flash(20,10); } if( Display_GSta != LED_KEEP_FLASHING ) { Display_Green_Flash(20,10); } if( Display_YSta != LED_KEEP_FLASHING ) { Display_Yellow_Flash(20,10); } if( Display_BSta != LED_KEEP_FLASHING ) { Display_Blue_Flash(20,10); } } #if SLEEP_ENABLE Enter_Sleep_Cnt_Restart_Flag = 1; #endif return; } /* 保护消失后,需要开启5V升压一段时间。 */ if( LED_On_Flag1 ) { LED_On_Flag1 = 0; LED_On_ChgDone_Flag = 0; LED_On_Chg_Flag = 0; Wkup_Earphone_Flag = 1; } #endif if (ChgStatus == CHG_STA_ING) //ChgStatus = CHG_STA_ING { if ( Charger_Done ) // 充电完成,4个LED常亮 { if( !LED_On_ChgDone_Flag ) { LED_On_ChgDone_Flag = 1; LED_Breating_Light_Off(); } Display_AllOn(); } else { if( !LED_On_Chg_Flag ) { LED_On_Chg_Flag = 1; LED_On_Flag = 1; Breathing_Light_Cnt = LED_R; } else { #ifdef PWM_ENABLE if( LED_On_Timer < LED_OFF_CNT ) { LED_On_Timer++; switch ( Breathing_Light_Cnt ) { case LED_R: if( Display_RSta != LED_BREATHING_LIGHT ) { LED_R_BREATHING_LIGHT(SLOW_DARK); } break; case LED_G: if( Display_GSta != LED_BREATHING_LIGHT ) { LED_G_BREATHING_LIGHT(SLOW_DARK); } break; case LED_Y: if( Display_YSta != LED_BREATHING_LIGHT ) { LED_Y_BREATHING_LIGHT(SLOW_DARK); } break; case LED_B: if( Display_BSta != LED_BREATHING_LIGHT ) { LED_B_BREATHING_LIGHT(SLOW_DARK); } break; default: break; } } else if( LED_On_Timer < 15 ) //LED显示1.5s。 { LED_On_Timer++; } else { LED_On_Timer = 0; Breathing_Light_Cnt++; if( Breathing_Light_Cnt >= LED_ID_MAX ) { Breathing_Light_Cnt = LED_R; } } #endif } } CoverEvent_Flg_led = 0; Earphone_Chg_Flag = 0; Key_Press_short_irq = 0; Disp_Bat_Lev = 1; } else { if( LED_On_Chg_Flag ) { LED_On_Chg_Flag = 0; LED_Breating_Light_Off(); LED_On_Flag = 1; Wkup_Earphone_Flag = 1; return; } if( LED_On_Flag ) { LED_On_Timer = 0; LED_On_Flag = 0; Display_AllOff(); return; } if( CoverEvent_Flg_led || Disp_Bat_Lev || Earphone_Chg_Flag || Key_Press_short_irq ) { if( LED_On_Timer < LED_OFF_CNT ) { LED_On_Timer++; } else if( LED_On_Timer < LED_ON_CNT ) //LED显示5s后灭。 { LED_On_Timer++; /*电量显示,25%电量左侧第1个灯闪;25%-50%电量2个灯常亮;50%-75%电量3个灯常亮;75%-100%电量4个灯常量。*/ if(bat_level_Pec < 25) { if (Display_RSta != LED_KEEP_FLASHING) { Display_Red_KeepFlash(100); Display_Green_Off(); Display_Yellow_Off(); Display_Blue_Off(); } } else if(bat_level_Pec < 50) { Display_Red_On(); Display_Green_On(); Display_Yellow_Off(); Display_Blue_Off(); } else if(bat_level_Pec < 75) { Display_Red_On(); Display_Green_On(); Display_Yellow_On(); Display_Blue_Off(); } else if(bat_level_Pec < 100) { Display_AllOn(); } } else { CoverEvent_Flg_led = 0; Disp_Bat_Lev = 0; Earphone_Chg_Flag = 0; Key_Press_short_irq = 0; LED_On_Flag = 1; //清LED显示 } } } } #endif /* ******************************************************************************* * uint8_t ADC_GetValue_Machine(void) * * Description : ADC值获取函数,使能一个通道后,在中断中取值,每使能一个通道,需要运行一个UserAPP周期。 (5ms调用周期) * * Arguments : NONE * Returns : 1:完成一次全通道采样; * Notes : NONE * ******************************************************************************* */ uint8_t ADC_GetValue_Machine(void) { #ifdef _DEBUG_ADC printf("adc chn:%d,pmu:%d,Ivol:%d,Vbat:%d,Vin:%d,Vpmid:%d,Vor:%d,Vol:%d,Vdd:%d,Ivor:%d.\r\n",(u16)ADC_Chn_Num,(u16)g_Vpmu_Adc,(u16)g_pmu_Adc_Ivol,(u16)Vbat_Adc,(u16)g_pmu_Adc_Vin,(u16)g_pmu_Adc_Vpmid,(u16)g_pmu_Adc_Vor,(u16)g_pmu_Adc_Vol,(u16)g_pmu_Adc_Vdd,(u16)g_pmu_Adc_Ivor); #endif PMU_ADC_Chn_Data(ADC_Chn_Num++); if( ADC_Chn_Num >= pmu_ADC_MAX ) { ADC_Chn_Num = 0; return 1; } return 0; } /* ******************************************************************************* * void System_Drivers_Machine(void) * * Description : 系统驱动相关程序处理。 (最小5ms调用周期) * * Arguments : NONE * Returns : NONE * Notes : NONE * ******************************************************************************* */ void System_Drivers_Machine(void) { #if CHARGER_ENABLE Charger_Handler(); #endif #if DISCHARGE_ENABLE DisCharge_Handler(); #endif #if HALL_ENABLE Hall_Handler(); #endif #if KEY_ENABLE Key_Handler(); #endif #ifdef VOX_RX HandleVoxCommMsg(); #endif if ( F_sys_tim_100ms ) { F_sys_tim_100ms = 0; #if BAT_VALUE check_bat_level(); #endif #ifdef LED_DISPLAY LED_Display_App(); #endif #if VOX_ENABLE Vox_Det_Machine(); #endif } } /***************************************************************************** * Function : PMU_State_Machine * Description : PMU Handle * Input : None * Output : None * Return : None * Note : None *****************************************************************************/ void PMU_State_Machine(void) { Get_PMU_Info( &pmu_Info ); //获取pmu状态 } /***************************************************************************** * Function : SysTerm_State_Machine * Description : System State Handle * Input : None * Output : None * Return : None * Note : None *****************************************************************************/ uint8_t Power_index = 0; void SysTem_State_Machine(void) { uint8_t ret = 0; if(Systerm_State.Current_State != Systerm_State.Next_State) { Systerm_State.Pre_State = Systerm_State.Current_State ; Systerm_State.Current_State = Systerm_State.Next_State ; switch(Systerm_State.Current_State) { case POWER_ON_STATE: /* 系统上电初始化相关处理逻辑 例如:LED显示UI、和耳机通信等功能; 在这里进行简单示例,两个LED显示闪烁2次。 */ #ifdef LED_DISPLAY LED_R_FLASH(100,3); LED_G_FLASH(100,3); #endif #ifdef _DEBUG_MAIN printf("Power On State!Hall(0x%x) (line:%d)\r\n", (uint16_t)CoverStatus,(uint16_t)__LINE__); #endif break; case AWAKE_STATE: /* 系统唤醒后需要处理的功能; 1、使能中断; */ #ifdef _DEBUG_MAIN printf("Awake State (line:%d)\r\n", (uint16_t)__LINE__); #endif break; case NORMAL_STATE: /*系统正常工作中需要处理的功能; 1、初始化进入Sleep的定时器; */ #if SLEEP_ENABLE Decnt_SleepDelay = ENTER_STANDBYMODE_CNT; #endif #ifdef _DEBUG_MAIN printf("Normal State (line:%d)\r\n", (uint16_t)__LINE__); #endif break; case SLEEP_STATE: /* 进入Sleep模式前的一些准备工作; 1、使能唤醒中断; */ #ifdef _DEBUG_MAIN printf("Sleep State (line:%d)\r\n", (uint16_t)__LINE__); #endif break; default: break; } } else { switch(Systerm_State.Current_State) { case POWER_ON_STATE: /*上电初始化需要处理的功能; 1、处理电池电量; 2、获取shipmode唤醒后的唤醒标志位; */ Power_index++; if( Power_index >= pmu_ADC_MAX ) //上电启动后,需要采集完ADC所有通道的值后,再进去下一个状态机 { Systerm_State.Next_State = AWAKE_STATE; Power_index = 0; } else { return; } if(bat_level == 0) { Systerm_State.Next_State = SLEEP_STATE; //电量为0,进入睡眠模式。 } break; case AWAKE_STATE: Systerm_State.Next_State = NORMAL_STATE; break; case NORMAL_STATE: /*1、唤醒后工作N ms后进入Sleep Mode,N需要大于100ms。 2、有VIN存在、VOX放电、唤醒源中断的情况下,系不会进入sleep mode。 */ #if SLEEP_ENABLE if(F_sys_tim_1s) { F_sys_tim_1s = 0; #ifdef _DEBUG_MAIN printf("STA0:0x%x,STA1:0x%x,STA2:0x%x,Chip_STA:0x%x,VOX_STA:0x%x.Dec_Sleep:%d\r\n",(u16)(pmu_Info.pmu_Fault_STA0),(u16)(pmu_Info.pmu_Fault_STA1),(u16)(pmu_Info.pmu_Fault_STA2),(u16)(pmu_Info.pmu_Chip_STA),(u16)(pmu_Info.pmu_VOX_STA),(u16)Decnt_SleepDelay); // printf("Chg Sta:0x%x.,batPec:%d.\r\n",(u16)ChgStatus,(u16)bat_level_Pec); // printf("Ivol:%d,Vbat:%d,Vin:%d,Vpmid:%d,Vor:%d,Vol:%d,Vdd:%d,Ivor:%d.\r\n",(u16)g_pmu_Adc_Ivol,(u16)Vbat_Adc,(u16)g_pmu_Adc_Vin,(u16)g_pmu_Adc_Vpmid,(u16)g_pmu_Adc_Vor,(u16)g_pmu_Adc_Vol,(u16)g_pmu_Adc_Vdd,(u16)g_pmu_Adc_Ivor); #endif if(Decnt_SleepDelay > 0) { Decnt_SleepDelay--; /*倒数进Sleep Mode过程中出现了中断,则重新计时。*/ if(Enter_Sleep_Cnt_Restart_Flag) { Enter_Sleep_Cnt_Restart_Flag = 0; Decnt_SleepDelay = ENTER_STANDBYMODE_CNT; #ifdef _DEBUG_MAIN printf("Decnt_SleepDelay Reload.\r\n"); #endif } } else { #ifdef _DEBUG_MAIN printf("Enter Standby Mode!\r\n"); #endif Systerm_State.Next_State = SLEEP_STATE; //进入Sleep Mode Enter_ShipMode_Debounce = 0; /*清标志位*/ } } #endif break; case SLEEP_STATE: /* 1、检测唤醒源,是否需要唤醒系统; 2、定时唤醒,更新电池电量; */ #if SLEEP_ENABLE if(Check_Require_Sleep()) { Enter_Sleep(); } else { Systerm_State.Next_State = AWAKE_STATE; } #endif break; default: break; } } } /***************************************************************************** * Function : UserAPP * Description : main()中调用,系统分为4个状态机,各个状态机5ms调用周期。 * Input : None * Output : None * Return : None * Note : None *****************************************************************************/ uint8_t Step_Cnt = 0; void UserAPP(void) { //static uint8_t Step_Cnt; if(F_sys_tim_5ms) { F_sys_tim_5ms = 0; switch( Step_Cnt++ ) { case 0: ADC_GetValue_Machine(); //用于获取各个通道的ADC值程序 break; case 1: PMU_State_Machine(); //用于PMU处理。 break; case 2: System_Drivers_Machine(); //用于执行芯片驱动程序 break; case 3: SysTem_State_Machine(); //用于应用程序 Step_Cnt = 0; break; default: break; } } if ( F_sys_tim_10ms ) { F_sys_tim_10ms = 0; LED_Drv(); } }