/* ****************************************************************************** * * @file userApp.c * @brief userApp module * @ic sy8837/8 * * @version 1.0 * @date 2024/12/02 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/12/02 Alex build this file ******************************************************************************/ /*_____ I N C L U D E S ____________________________________________________*/ #include "userapp.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 "display_ui.h" #include "vox_comm.h" /******************************************************************************\ Macro definitions \******************************************************************************/ /******************************************************************************\ Variables definitions \******************************************************************************/ s_sys_state Systerm_State = {SLEEP_STATE,AWAKE_STATE,AWAKE_STATE}; uint8_t Step_Cnt; uint8_t Power_index; bit Wkup_Earphone_Flag; //保护消失后,需要升压唤醒耳机标志位 /******************************************************************************\ Functions definitions \******************************************************************************/ /* ******************************************************************************* * void ADC_GetValue_Machine(void) * * Description : ADC值获取函数,使能一个通道后,在中断中取值,每使能一个通道,需要运行一个UserAPP周期。 (5ms调用周期) * * Arguments : NONE * Returns : NONE * Notes : NONE * ******************************************************************************* */ void ADC_GetValue_Machine(void) { PMU_ADC_Chn_Data( ADC_Chn_Num++ ); if( ADC_Chn_Num == ADC_REF ) { ADC_Chn_Num++; } if( ADC_Chn_Num >= ADC_MAX ) { ADC_Chn_Num = ADC_NTC; } } /* ******************************************************************************* * 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_COMM_ENABLE /*双向通讯功能处理函数*/ Vox_Comm_Handle(); #endif #ifdef VOX_ADT_ENABLE /*Vox 过流保护,两只耳机都每隔200ms打嗝一次*/ if( IRQ_FLAG0 & ( VOR_OutPut_Short | VOL_OutPut_Short ) ) //Vox短路、过流保护,100ms周期打嗝。 { IRQ_FLAG0 = ( VOR_OutPut_Short | VOL_OutPut_Short ); VOL_EN_Type(VOX_VOUT_Mode); VOR_EN_Type(VOX_VOUT_Mode); 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 : 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、使能中断; */ if( Vox_Ocp_Flag ) //Vox OCP 保护,出休眠后需要将Vox设置为ADT模式。 { CoverEvent_Flg = TRUE; IRQ_FLAG0 = 0x0C; Vox_Output_Short_Flag = FALSE; Vox_Ocp_Flag = FALSE; } #ifdef _DEBUG_MAIN // printf("Awake Source:WP_Flag0:0x%x,WP_Flag1:0x%x,WP_Flag3:0x%x.(line:%d)\r\n",(uint16_t)WKUP_FLAG0, (uint16_t)WKUP_FLAG1, (uint16_t)WKUP_FLAG3,(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 >= 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: if( WKUP_FLAG0 || WKUP_FLAG1 || WKUP_FLAG3 || RST_FLAG ) { Systerm_State.Next_State = NORMAL_STATE; if( ( WKUP_FLAG0 & ( TMR_WK_FLAG | HALL_WK_FLAG | KEY_WK_FLAG | VIN_PRESENT_WK_FLAG ) ) == TMR_WK_FLAG ) //除Timer Wake Up 外其它唤醒都需要重新进倒数计时。 { Systerm_State.Next_State = SLEEP_STATE; } RST_FLAG = 0x1F; WKUP_FLAG0 = 0x0F; WKUP_FLAG1 = 0xFC; WKUP_FLAG3 = 0xBC; } else { 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 SFRADDR = ST_VOX; ret = SFRDATA; printf("CHG_STA:%d,ST_VOX:0x%x,STA0:0x%x,STA1:0x%x,STA2:0x%x,STA3:0x%x,STA4:0x%x.Dec_Sleep:%d\r\n",(uint16_t)ChgStatus,(uint16_t)ret,(uint16_t)(CHIP_STA0),(uint16_t)(CHIP_STA1),(uint16_t)(CHIP_STA2),(uint16_t)(CHIP_STA3),(uint16_t)(CHIP_STA4),(uint16_t)Decnt_SleepDelay); // printf("CHIP_STA1_f:0x%x,0x%x.\r\n",(uint16_t)( CHIP_STA1 & ( VOR_Ioff | VOL_Ioff | VOL_LoadOn | VOR_LoadOn ) ),(uint16_t)( VOR_Ioff | VOL_Ioff | VOL_LoadOn | VOR_LoadOn ) ); // printf("adc chn:%d,adc_value:%d,Ivol:%d,Vbat:%d,Vout:%d,Ivor:%d,Vntc:%d.\r\n",(uint16_t)ADC_Chn_Num,(uint16_t)g_Value_Adc_Avg,(uint16_t)g_pmu_Adc_Ivol,(uint16_t)g_Vbat_Adc,(uint16_t)g_pmu_Adc_Vout,(uint16_t)g_pmu_Adc_Ivor,(uint16_t)g_Vntc_Adc); #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 /*清标志位*/ } } #endif break; case SLEEP_STATE: /* 1、检测唤醒源,是否需要唤醒系统; 2、定时唤醒,更新电池电量; */ #if SLEEP_ENABLE if(Check_Require_Sleep()) { WakeUp_Init_Set(); #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 DisCharge_Boost_Close(); #ifdef LED_DISPLAY Display_AllOff(); #endif 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 *****************************************************************************/ void UserAPP(void) { if(F_sys_tim_5ms) { F_sys_tim_5ms = FALSE; switch( Step_Cnt++ ) { case 0: ADC_GetValue_Machine(); //用于获取各个通道的ADC值程序 break; case 1: System_Drivers_Machine(); //用于执行芯片驱动程序 break; case 2: 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 } }