/* ****************************************************************************** * * @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" #include "adc.h" #include "display_ui.h" /******************************************************************************\ Macro definitions \******************************************************************************/ /******************************************************************************\ Variables definitions \******************************************************************************/ s_sys_state Systerm_State = {SLEEP_STATE,AWAKE_STATE,AWAKE_STATE}; uint8_t Step_Cnt; bit Wkup_Earphone_Flag; //保护消失后,需要升压唤醒耳机标志位 uint8_t Wkup_Source_Flag; //唤醒源标志 uint8_t Power_index; /******************************************************************************\ Functions definitions \******************************************************************************/ /* ******************************************************************************* * void PMU_ADC_GetValue_Machine(void) * * Description : PMU(xSen) ADC值获取函数,使能一个通道后,在中断中取值,每使能一个通道,需要运行一个UserAPP周期。 (5ms调用周期) * * Arguments : NONE * Returns : NONE * Notes : NONE * ******************************************************************************* */ void PMU_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; } } /* ******************************************************************************* * void System_Drivers_Machine(void) * * Description : 系统驱动相关程序处理。 (最小5ms调用周期) * * Arguments : NONE * Returns : NONE * Notes : NONE * ******************************************************************************* */ void System_Drivers_Machine(void) { #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 = FALSE; #if CHARGER_ENABLE Charger_Handler(); #endif #if DISCHARGE_ENABLE DisCharge_Handler(); #endif #if BAT_VALUE check_bat_level(); #endif #ifdef LED_DISPLAY LED_Display_App(); #endif #if VOX_ENABLE #ifdef VOX_ADT_ENABLE /*Vox 过流保护,两只耳机都每隔200ms打嗝一次*/ if( pmu_Info.pmu_Fault_STA2 & ( Fault_Sta2_VorOCP | Fault_Sta2_VolOCP ) ) { Vox_Output_Short_Flag = TRUE; } else { Vox_Output_Short_Flag = FALSE; #if VOX_ENABLE Vol_Det_Machine(); //耳机入盒自动识别充电处理 Vor_Det_Machine(); #endif #if VOX_FOLLOW_CHG if( !Vol_GetOut_Box_Flag || !Vor_GetOut_Box_Flag ) { if ( Vox_Fllow_Chg.Vox_Follow_Stop == OFF ) { Vox_Follow_Chg( &Vox_Fllow_Chg ); //跟随充处理。 } } #endif } #else Vox_Det_Machine(); #endif #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 *****************************************************************************/ 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、使能中断; */ Set_PMU_StandbyMode_Set(ON); //开启LDO #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 = FALSE; #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("Vntc:%d,Ivol:%d,Vbat:%d,Vin:%d,Vpmid:%d,Vor:%d,Vol:%d,Vdd:%d,Ivor:%d.\r\n",(u16)g_Vntc_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 if(Decnt_SleepDelay > 0) { Decnt_SleepDelay--; /*倒数进Sleep Mode过程中出现了中断,则重新计时。*/ if(Enter_Sleep_Cnt_Restart_Flag) { Enter_Sleep_Cnt_Restart_Flag = FALSE; 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 1 if(Check_Require_Sleep()) { #if VOX_ENABLE #ifdef VOX_ADT_ENABLE VOL_EN_Type(VOX_ADT_Mode); VOR_EN_Type(VOX_ADT_Mode); #else VOX_EN_Type(VOX_ADT_Mode); //VOX Enable 5V #endif #endif Set_PMU_Boost(OFF); Set_PMU_StandbyMode_Set(OFF); //关闭LDO Enter_Sleep(); } else { Systerm_State.Next_State = AWAKE_STATE; } #else Systerm_State.Next_State = AWAKE_STATE; #if VOX_ENABLE #ifdef VOX_ADT_ENABLE VOL_EN_Type(VOX_ADT_Mode); VOR_EN_Type(VOX_ADT_Mode); #else VOX_EN_Type(VOX_ADT_Mode); //VOX Enable 5V #endif #endif Set_PMU_Boost(OFF); Set_PMU_StandbyMode_Set(OFF); //关闭LDO #endif break; default: break; } } } /***************************************************************************** * Function : UserAPP * Description : main()中调用,系统分为4个状态机,各个状态机5ms调用周期。 * Input : None * Output : None * Return : None * Note : None *****************************************************************************/ void UserAPP(void) { if(F_sys_tim_5ms) { F_sys_tim_5ms = FALSE; switch( Step_Cnt++ ) { case 0: PMU_ADC_GetValue_Machine(); //用于获取PMUC(xSen)各个通道的ADC值程序 break; case 1: PMU_State_Machine(); //用于PMU处理。 break; case 2: ADC_NTC_Data(); //用于获取NTC ADC值。 break; case 3: System_Drivers_Machine(); //用于执行芯片驱动程序 break; case 4: SysTem_State_Machine(); //用于应用程序 Step_Cnt = 0; break; default: break; } } if ( F_sys_tim_10ms ) { F_sys_tim_10ms = FALSE; #ifdef LED_DISPLAY LED_Drv(); #endif } }