SY8837_Demo_For_OurSelf/UsrSrc/userapp/userapp.c
rb_peng c743af0aa6 1、将双向通信的具体场景提到vox_Comm_Handle函数中
2、增加VOX持续输出0V以唤醒耳机的情况;
3、解决超长按后,双向通讯一直发码的问题;(松开按键后Key_Press_ll_irq设为FALSE)
4、解决关盖上电时,不亮灯和不发码的问题(即把Hall_Sta_bk初始化);
5、长按发配对码时,主副耳的选择提取到config.h中;
2025-02-21 17:24:44 +08:00

470 lines
10 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 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
}
}