SY8835_For_Demo_Ourself/UsrSrc/userapp/userapp.c

690 lines
14 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
******************************************************************************
*
* @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();
}
}