735 lines
14 KiB
C
735 lines
14 KiB
C
/*
|
||
******************************************************************************
|
||
*
|
||
* @file UserApp.c
|
||
* @brief UserApp module
|
||
* @ic sy8837
|
||
*
|
||
* @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"
|
||
|
||
/******************************************************************************\
|
||
Macro definitions
|
||
\******************************************************************************/
|
||
#define LED_ON_CNT 100 //10s
|
||
|
||
#define LED_PRO_TIM 40
|
||
|
||
#define LED_OFF_CNT 1
|
||
|
||
/******************************************************************************\
|
||
Variables definitions
|
||
\******************************************************************************/
|
||
|
||
s_sys_state Systerm_State = {SLEEP_STATE,AWAKE_STATE,AWAKE_STATE};
|
||
|
||
uint8_t Step_Cnt = 0;
|
||
|
||
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;
|
||
|
||
if( LED_On_Flag )
|
||
{
|
||
LED_On_Flag = 0;
|
||
|
||
LED_On_Timer = 0;
|
||
|
||
offset_bat_level = 0;
|
||
|
||
Display_AllOff();
|
||
|
||
#if SLEEP_ENABLE
|
||
Enter_Sleep_Cnt_Restart_Flag = 1;
|
||
#endif
|
||
return;
|
||
}
|
||
|
||
#ifdef NTC_ENABLE
|
||
/*NTC保护,4灯一直快闪(2Hz)*/
|
||
if( CHG_NTC_Pro_Flag || Boost_NTC_Pro_Flag || ( Vox_Output_Short_Flag && !Vox_Ocp_Flag ) )
|
||
{
|
||
if( !LED_On_Flag1 )
|
||
{
|
||
LED_On_Flag1 = 1;
|
||
|
||
LED_On_Flag = 1;
|
||
}
|
||
else
|
||
{
|
||
if( Display_RSta != LED_FLASH )
|
||
{
|
||
Display_Red_Flash(20,10);
|
||
}
|
||
|
||
if( Display_GSta != LED_FLASH )
|
||
{
|
||
Display_Green_Flash(20,10);
|
||
}
|
||
|
||
if( Display_YSta != LED_FLASH )
|
||
{
|
||
Display_Yellow_Flash(20,10);
|
||
}
|
||
|
||
if( Display_BSta != LED_FLASH )
|
||
{
|
||
Display_Blue_Flash(20,10);
|
||
}
|
||
|
||
if( Vox_Output_Short_Flag )
|
||
{
|
||
if( LED_On_Timer < LED_PRO_TIM )
|
||
{
|
||
LED_On_Timer++;
|
||
}
|
||
else
|
||
{
|
||
Vox_Ocp_Flag = 1;
|
||
|
||
LED_On_Flag = 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
/* 保护消失后,需要开启5V升压一段时间。 */
|
||
if( LED_On_Flag1 )
|
||
{
|
||
LED_On_Flag1 = 0;
|
||
|
||
LED_On_ChgDone_Flag = 0;
|
||
|
||
LED_On_Chg_Flag = 0;
|
||
|
||
CoverEvent_Flg_led = 0;
|
||
|
||
Earphone_Chg_Flag = 0;
|
||
|
||
Wkup_Earphone_Flag = 1;
|
||
}
|
||
|
||
#endif
|
||
|
||
if (ChgStatus != CHG_NONE)
|
||
{
|
||
if ( ChgStatus == CHG_STA_COMPLETED ) // 充电完成,4个LED常亮
|
||
{
|
||
if( !LED_On_ChgDone_Flag )
|
||
{
|
||
LED_On_ChgDone_Flag = 1;
|
||
|
||
LED_On_Chg_Flag = 0;
|
||
|
||
LED_Breating_Light_Off();
|
||
|
||
return;
|
||
}
|
||
|
||
Display_AllOn();
|
||
}
|
||
else
|
||
{
|
||
if( !LED_On_Chg_Flag )
|
||
{
|
||
LED_On_Chg_Flag = 1;
|
||
|
||
LED_On_ChgDone_Flag = 0;
|
||
|
||
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( 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显示10s后灭。
|
||
{
|
||
LED_On_Timer++;
|
||
|
||
/*电量显示,25%电量左侧第1个灯闪;25%-50%电量2个灯常亮;50%-75%电量3个灯常亮;75%-100%电量4个灯常量。*/
|
||
if( F_batlevel_25p )
|
||
{
|
||
if (Display_RSta != LED_KEEP_FLASHING)
|
||
{
|
||
Display_Red_KeepFlash(100);
|
||
Display_Green_Off();
|
||
Display_Yellow_Off();
|
||
Display_Blue_Off();
|
||
}
|
||
}
|
||
else
|
||
if( F_batlevel_50p )
|
||
{
|
||
Display_Red_On();
|
||
Display_Green_On();
|
||
Display_Yellow_Off();
|
||
Display_Blue_Off();
|
||
}
|
||
else
|
||
if( F_batlevel_75p )
|
||
{
|
||
Display_Red_On();
|
||
Display_Green_On();
|
||
Display_Yellow_On();
|
||
Display_Blue_Off();
|
||
}
|
||
else
|
||
{
|
||
Display_AllOn();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
CoverEvent_Flg_led = 0;
|
||
|
||
Disp_Bat_Lev = 0;
|
||
|
||
Earphone_Chg_Flag = 0;
|
||
|
||
Key_Press_short_irq = 0;
|
||
|
||
Display_AllOff(); //清LED显示
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
#endif
|
||
|
||
/*
|
||
*******************************************************************************
|
||
* 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 = 0;
|
||
|
||
#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
|
||
Vox_Det_Machine();
|
||
#endif
|
||
}
|
||
}
|
||
|
||
/*****************************************************************************
|
||
* 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、使能中断;
|
||
*/
|
||
if( Vox_Ocp_Flag ) //Vox OCP 保护,出休眠后需要将Vox设置为ADT模式。
|
||
{
|
||
CoverEvent_Flg = 1;
|
||
|
||
IRQ_FLAG0 = 0x0C;
|
||
|
||
Vox_Output_Short_Flag = 0;
|
||
|
||
Vox_Ocp_Flag = 0;
|
||
}
|
||
|
||
#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 = 0;
|
||
|
||
#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 ) );
|
||
#endif
|
||
#ifdef _DEBUG_ADC
|
||
printf("adc chn:%d,Ivol:%d,Vbat:%d,Vout:%d,Ivor:%d,Vntc:%d.\r\n",(uint16_t)ADC_Chn_Num,(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 = 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
|
||
|
||
/*清标志位*/
|
||
|
||
}
|
||
}
|
||
|
||
#endif
|
||
break;
|
||
|
||
case SLEEP_STATE:
|
||
|
||
/*
|
||
1、检测唤醒源,是否需要唤醒系统;
|
||
2、定时唤醒,更新电池电量;
|
||
*/
|
||
#if SLEEP_ENABLE
|
||
|
||
if(Check_Require_Sleep())
|
||
{
|
||
WakeUp_Init_Set();
|
||
|
||
VOX_EN_Type(VOX_ADT_Mode);
|
||
|
||
DisCharge_Boost_Close();
|
||
|
||
Display_AllOff();
|
||
|
||
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 = 0;
|
||
|
||
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 = 0;
|
||
#ifdef LED_DISPLAY
|
||
LED_Drv();
|
||
#endif
|
||
}
|
||
|
||
}
|
||
|