2、增加VOX持续输出0V以唤醒耳机的情况; 3、解决超长按后,双向通讯一直发码的问题;(松开按键后Key_Press_ll_irq设为FALSE) 4、解决关盖上电时,不亮灯和不发码的问题(即把Hall_Sta_bk初始化); 5、长按发配对码时,主副耳的选择提取到config.h中;
470 lines
10 KiB
C
470 lines
10 KiB
C
/*
|
||
******************************************************************************
|
||
*
|
||
* @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
|
||
}
|
||
|
||
}
|
||
|