690 lines
14 KiB
C
690 lines
14 KiB
C
/*
|
||
******************************************************************************
|
||
*
|
||
* @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_PMU
|
||
|
||
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;
|
||
printf("Decnt_SleepDelay Reload.\r\n");
|
||
}
|
||
}
|
||
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();
|
||
}
|
||
|
||
}
|
||
|