SY8837_Demo_For_OurSelf/UsrSrc/vox/vox_module.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

1921 lines
50 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 vox_module.c
* @brief VOL/R module
* @ic sy8837/8
*
* @version 1.0
* @date 2024/12/02 09:59: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
******************************************************************************
*/
#include "vox_module.h"
#include "led.h"
#include "system.h"
#include "discharge_module.h"
#include "sleep.h"
#include "bat.h"
#include "hall.h"
#include "key.h"
#include "sys_tim.h"
#include "adc.h"
#include "userapp.h"
#include "vox_comm.h"
#ifdef VOX_COVER_ENABLE
bit Vox_Vout_Enable; //Vox功率输出标志位
#else
bit Vor_Vout_Enable; //Vor功率输出标志位
bit Vol_Vout_Enable; //Vol功率输出标志位
#endif
bit Boost_Open_Flag;
bit Vox_Output_Short_Flag;
#if VOX_ENABLE
/******************************************************************************\
Macro definitions
\******************************************************************************/
#if VOX_FOLLOW_CHG
#define VOX_FOLLOW_CHG_NOWCURCHK_CNT 5
#define VOX_FOLLOW_CHG_VOLTAGE_ADJUST_CNT 2 //PMID调压周期
#endif
/******************************************************************************\
Variables definitions
\******************************************************************************/
#if VOX_FOLLOW_CHG
idata uint8_t Vox_Follow_Init_Deb;
idata uint16_t Vox_Follow_Chg_Debounce;
g_Vox_Fllow_Chg_Cfg Vox_Fllow_Chg;
e_Vox_Follow_Chg_Sta Follow_Chg_Sta;
#endif
idata uint8_t EarPhone_Num;
bit Vox_Ocp_Flag;
bit OpenCover_TX_Cmd_Flag;
/******************************************************************************\
Functions definitions
\******************************************************************************/
#ifdef VOX_ADT_ENABLE
/*
*******************************************************************************
* uint8_t VOL_EN_Type(VOL_Enable_Type_e VOL_Enable_Type)
*
* Description : VOL Open(EN_VO)
* 使能信号优先级
* EN_COM EN_VO EN_ADT PD1K VOX_STATE
* 1 X X X COMM
* 0 1 X X 5V
* 0 0 1 X Auto DET
* 0 0 0 1 PD1K
* Arguments :
* Returns :
* Notes :
*
*******************************************************************************
*/
void VOL_EN_Type(VOX_Enable_Mode_e VOL_Enable_Mode)
{
switch(VOL_Enable_Mode)
{
case VOX_TRANS_Mode: //关闭自动识别负载的上拉电阻。
break;
case VOX_COMM_Mode_Uart:
COMM_CTL |= Vol_EN_COMR | Vol_SWDR ; //开启VOX通讯使能选择UART通讯模式。
COMM_CTL &= ~( Vol_SW_MD | Vol_SWDT );
SFRADDR = COMM_CON; //Vox通讯电平选择3.0V打开50K上拉电阻。
SFRDATA &= ~0x0D;
SFRDATA |= VOX_COMM_VOLTAGE_SET | VOX_COMM_PULL_UP_SET;
break;
case VOX_COMM_Mode_Reg:
COMM_CTL |= Vol_EN_COMR | Vol_SW_MD; //开启VOX通讯使能选择寄存器通讯模式。
SFRADDR = COMM_CON; //Vox通讯电平选择5.0V关闭50K上拉电阻。
SFRDATA &= ~ VOX_COMM_PULL_UP_SET;
SFRDATA |= Vox_COMM_PULL_Vol_5_0;
break;
case VOX_VOUT_Mode: //Vox的通讯功能优先级比Vout 5V高。
COMM_CTL &= ~( Vol_EN_COMR );
VOX_CTL0 &=~( EN_VOL_VOUT );
VOX_CTL0 |= EN_VOL_VOUT;
break;
case VOX_ADT_Mode:
VOX_CTL0 &=~( EN_VOL_VOUT );
VOX_CTL0 |= EN_VOL_ADTL; //开启ADT模式
COMM_CTL &=~( Vol_EN_COMR );
break;
case VOX_PD1K_Mode:
VOX_CTL0 &=~( EN_VOL_VOUT | EN_VOL_ADTL );
COMM_CTL &=~( Vol_EN_COMR );
SFRADDR = VOX_CON0; //Vox通过1K电阻下拉到GND
SFRDATA |= Vol_Pull_Down;
break;
default:
break;
}
}
/*
*******************************************************************************
* void VOR_EN_Type(VOR_Enable_Type_e VOR_Enable_Type)
*
* Description : VOL Open(EN_VO)
* 使能信号优先级
* EN_COM EN_VO EN_ADT PD1K VOX_STATE
* 1 X X X COMM
* 0 1 X X 5V
* 0 0 1 X Auto DET
* 0 0 0 1 PD1K
* Arguments :
* Returns :
* Notes :
*
*******************************************************************************
*/
void VOR_EN_Type(VOX_Enable_Mode_e VOR_Enable_Mode)
{
switch(VOR_Enable_Mode)
{
case VOX_TRANS_Mode: //关闭自动识别负载的上拉电阻。
break;
case VOX_COMM_Mode_Uart:
COMM_CTL |= Vor_EN_COMR | Vor_SWDR ; //开启VOX通讯使能选择UART通讯模式。
COMM_CTL &= ~( Vor_SW_MD | Vor_SWDT );
SFRADDR = COMM_CON; //Vox通讯电平选择3.0V打开50K上拉电阻。
SFRDATA &= ~0x0D;
SFRDATA |= VOX_COMM_VOLTAGE_SET | VOX_COMM_PULL_UP_SET;
break;
case VOX_COMM_Mode_Reg:
COMM_CTL |= Vor_EN_COMR | Vor_SW_MD; //开启VOX通讯使能选择寄存器通讯模式。
SFRADDR = COMM_CON; //Vox通讯电平选择5.0V关闭50K上拉电阻。
SFRDATA &= ~ VOX_COMM_PULL_UP_SET;
SFRDATA |= Vox_COMM_PULL_Vol_5_0;
break;
case VOX_VOUT_Mode: //Vox的通讯功能优先级比Vout 5V高。
COMM_CTL &= ~( Vor_EN_COMR );
VOX_CTL0 &=~( EN_VOR_VOUT );
VOX_CTL0 |= EN_VOR_VOUT;
break;
case VOX_ADT_Mode:
VOX_CTL0 &=~( EN_VOR_VOUT );
VOX_CTL0 |= EN_VOR_ADTR ; //开启ADT模式
COMM_CTL &=~( Vor_EN_COMR );
break;
case VOX_PD1K_Mode:
VOX_CTL0 &=~( EN_VOR_VOUT | EN_VOR_ADTR );
COMM_CTL &=~( Vor_EN_COMR );
SFRADDR = VOX_CON0; //Vox通过1K电阻下拉到GND
SFRDATA |= Vor_Pull_Down ;
break;
default:
break;
}
}
#else
/*
*******************************************************************************
* void VOX_EN_Type(VOR_Enable_Type_e VOR_Enable_Type)
*
* Description : VOL Open(EN_VO)
* 使能信号优先级
* EN_COM EN_VO EN_ADT PD1K VOX_STATE
* 1 X X X COMM
* 0 1 X X 5V
* 0 0 1 X Auto DET
* 0 0 0 1 PD1K
* Arguments :
* Returns :
* Notes :
*
*******************************************************************************
*/
void VOX_EN_Type(VOX_Enable_Mode_e VOX_Enable_Mode)
{
switch(VOX_Enable_Mode)
{
case VOX_TRANS_Mode: //关闭自动识别负载的上拉电阻。
break;
case VOX_COMM_Mode_Uart:
COMM_CTL |= Vor_EN_COMR | Vol_EN_COMR | Vol_SWDR | Vor_SWDR; //开启VOX通讯使能选择UART通讯模式。
COMM_CTL &= ~( Vor_SW_MD | Vol_SW_MD | Vol_SWDT | Vor_SWDT );
SFRADDR = COMM_CON; //Vox通讯电平选择3.0V打开50K上拉电阻。
SFRDATA &= ~0x0D;
SFRDATA |= VOX_COMM_VOLTAGE_SET | VOX_COMM_PULL_UP_SET;
break;
case VOX_COMM_Mode_Reg:
COMM_CTL |= Vor_EN_COMR | Vol_EN_COMR | Vor_SW_MD | Vol_SW_MD; //开启VOX通讯使能选择寄存器通讯模式。
SFRADDR = COMM_CON; //Vox通讯电平选择5.0V关闭50K上拉电阻。
SFRDATA &= ~ VOX_COMM_PULL_UP_SET;
SFRDATA |= Vox_COMM_PULL_Vol_5_0;
break;
case VOX_VOUT_Mode: //Vox的通讯功能优先级比Vout 5V高。
COMM_CTL &= ~( Vor_EN_COMR | Vol_EN_COMR );
VOX_CTL0 &=~( EN_VOR_VOUT | EN_VOL_VOUT );
VOX_CTL0 |= EN_VOR_VOUT | EN_VOL_VOUT;
break;
case VOX_ADT_Mode:
VOX_CTL0 &=~( EN_VOR_VOUT | EN_VOL_VOUT );
VOX_CTL0 |= EN_VOR_ADTR | EN_VOL_ADTL; //开启ADT模式
COMM_CTL &=~( Vor_EN_COMR | Vol_EN_COMR );
break;
case VOX_PD1K_Mode:
VOX_CTL0 &=~( EN_VOR_VOUT | EN_VOL_VOUT | EN_VOR_ADTR | EN_VOL_ADTL );
COMM_CTL &=~( Vor_EN_COMR | Vol_EN_COMR );
SFRADDR = VOX_CON0; //Vox通过1K电阻下拉到GND
SFRDATA |= Vor_Pull_Down | Vol_Pull_Down;
break;
default:
break;
}
}
#endif
#ifdef VOX_ADT_ENABLE
#define VOX_LOADON_DET_DEBOUNCE 2 //Vox Loadon信号检测延时计数loadon信号软件数字滤波根据实际耳机进行调试
#define VOX_NO_LOADON_CNT 5 //耳机充满后,断内部下拉电阻延时计数,根据实际应用调整。
#define VOX_IOFF_DET_DEBOUNCE 50 //Vox Ioff检测延时5s重载转轻载延时计数。
Vox_State_e Vol_State;
bit Vol_GetOut_Box_Flag; //Vol 出盒标志,用于耳机抽电灯效。
/*
*******************************************************************************
* void Vol_Det_Machine(void)
*
* Description : Vol Detect:耳机识别。 (100ms调用周期)
*
* Arguments : NONE
* Returns : NONE
* Notes : NONE
*
*******************************************************************************
*/
void Vol_Det_Machine(void)
{
static uint8_t nVol_Loadon_Det_Debounce; //loadon标志检测延时计数
static uint8_t nVol_Output_Debounce; //Vox重载转轻载延时计数
static bit nVol_Chg_Full_Flag; //耳机充满标志
static bit nVol_GetOut_Box_Flag;
static bit nVol_Outbox_Disp_Flag;
static bit nVol_Intobox_Disp_Flag;
static bit nVol_Get_Chip_STA_Flag;
static uint8_t nCHIP_STA1_Vol;
if( gBoost_Prepared_Flag )
{
switch( Vol_State )
{
case VOX_GET_INTO_BOX: //耳机入仓
/*开启Vox Vout 5V前需要先开Boost。*/
if( !Boost_Open_Flag )
{
DisCharge_Boost_Open(OFF,BOOST_VOUT_MAX);
Boost_Open_Flag = TRUE;
#ifdef _DEBUG_VOX
printf("Boost Open.(line:%d)\r\n",(u16)__LINE__);
#endif
return;
}
VOL_EN_Type(VOX_VOUT_Mode); //Vox开启Vout 5V输出
Vol_Vout_Enable = ON;
Boost_Open_Flag = FALSE;
nVol_Chg_Full_Flag = FALSE;
nVol_GetOut_Box_Flag = FALSE;
nVol_Intobox_Disp_Flag = FALSE;
nVol_Outbox_Disp_Flag = FALSE;
nVol_Output_Debounce = 0;
/*重启跟随充*/
#if VOX_FOLLOW_CHG
Vox_Fllow_Chg.Vox_Follow_Start = OFF;
Vox_Fllow_Chg.Vox_Follow_Stop = OFF;
Follow_Chg_Sta = Vox_Follow_Chg_InitSta;
#endif
Vol_State = VOX_STAY_IN_BOX;
break;
case VOX_STAY_IN_BOX: //耳机在仓
if ( ( CHIP_STA1 & ( VOL_LoadOn | VOL_Ioff ) ) == ( VOL_LoadOn | VOL_Ioff ) ) //充电过程中出现只有IOFF则出现如下三种情况1、耳机出仓2、耳机电池充满3、耳机电池锂保。
{
if( nVol_Intobox_Disp_Flag ) //Vol耳机在正常充电过程中被拔出。
{
nVol_Outbox_Disp_Flag = TRUE;
nVol_Intobox_Disp_Flag = FALSE;
nVol_GetOut_Box_Flag = TRUE;
Vol_GetOut_Box_Flag = TRUE; //左耳出盒标志置1用于抽电灯效
#ifdef _DEBUG_VOX
printf("Vol Get Out.(line:%d)\r\n",(u16)__LINE__);
#endif
}
nVol_Output_Debounce++;
if( nVol_Output_Debounce >= VOX_IOFF_DET_DEBOUNCE ) //重载转轻载(耳机出仓后)需延时5sVox掉Vout 5V后转入ADT模式。
{
nVol_Output_Debounce = 0;
VOL_EN_Type(VOX_ADT_Mode);
nVol_Chg_Full_Flag = TRUE;
#ifdef _DEBUG_VOX
printf("Vol Full And In ADT.(line:%d)\r\n",(u16)__LINE__);
#endif
}
}
else
if ( ( CHIP_STA1 & ( VOL_LoadOn | VOL_Ioff ) ) == VOL_LoadOn ) //无IOFF有Loadon说明1、耳机出仓后4s内耳机再次入仓2、10分钟未满耳机电池退出锂保状态进入正常充电
{
nVol_Output_Debounce = 0;
nVol_Intobox_Disp_Flag = TRUE;
if( nVol_Chg_Full_Flag ) //Vox在ADT模式后检测到loadon标志则说明耳机已充满不再抽电等loadon消失判断耳机出盒。
{
Vol_Vout_Enable = OFF;
#ifdef _DEBUG_VOX
printf("Vol Full.(line:%d)\r\n",(u16)__LINE__);
#endif
}
else
{
if( nVol_Outbox_Disp_Flag ) //左耳4s内再次入盒左耳对应的入盒灯效闪一次。
{
nVol_Outbox_Disp_Flag = FALSE;
if( nVol_GetOut_Box_Flag )
{
nVol_GetOut_Box_Flag = FALSE;
/*重启跟随充*/
#if VOX_FOLLOW_CHG
Vox_Fllow_Chg.Vox_Follow_Start = OFF;
Vox_Fllow_Chg.Vox_Follow_Stop = OFF;
Follow_Chg_Sta = Vox_Follow_Chg_InitSta;
#endif
Earphone_Chg_Flag_led = TRUE; //用于灯效显示
#ifdef LED_DISPLAY
LED_On_Flag = TRUE;
#endif
#ifdef _DEBUG_VOX
printf("Vol Get In Again.(line:%d)\r\n",(u16)__LINE__);
#endif
}
}
Vol_Vout_Enable = ON; //正常充电标志置ON。
Vol_GetOut_Box_Flag = FALSE;
#ifdef _DEBUG_VOX
printf("Vol Ching.(line:%d)\r\n",(u16)__LINE__);
#endif
}
}
else
if ( !( CHIP_STA1 & VOL_LoadOn ) ) //无Loadon说明耳机出仓
{
nVol_Loadon_Det_Debounce++;
if( nVol_Loadon_Det_Debounce >= VOX_NO_LOADON_CNT ) //耳机充满后,断开内部下拉电阻延时计数,根据实际应用调整。
{
nVol_Loadon_Det_Debounce = 0;
nVol_Intobox_Disp_Flag = FALSE;
nVol_Outbox_Disp_Flag = FALSE;
nVol_GetOut_Box_Flag = FALSE;
Vol_State = VOX_NONE_IN_BOX;
#ifdef _DEBUG_VOX
printf("Vol Out Box.(line:%d)\r\n",(u16)__LINE__);
#endif
}
}
break;
case VOX_NONE_IN_BOX: //空仓
VOL_EN_Type(VOX_ADT_Mode);
Vol_Vout_Enable = OFF;
Vol_GetOut_Box_Flag = TRUE; //左耳出盒标志置1用于抽电灯效
if( CHIP_STA1 & VOL_LoadOn ) //adt模式下出现loadon信号则说明Vol通道有耳机入盒。
{
nVol_Loadon_Det_Debounce++;
if( nVol_Loadon_Det_Debounce >= VOX_LOADON_DET_DEBOUNCE ) //Vox Loadon信号检测延时计数loadon信号软件数字滤波根据实际耳机进行调试
{
nVol_Loadon_Det_Debounce = 0;
Vol_State = VOX_GET_INTO_BOX;
/*置灯效显示标志*/
Earphone_Chg_Flag_led = TRUE;
#ifdef LED_DISPLAY
LED_On_Flag = TRUE;
#endif
#ifdef _DEBUG_VOX
printf("Vol Det Loadon.(line:%d)\r\n",(u16)__LINE__);
#endif
}
}
else
{
nVol_Loadon_Det_Debounce = 0;
}
break;
default:
break;
}
}
else //bat保护后VOX恢复到最初状态。
{
Vol_State = VOX_GET_INTO_BOX;
Vol_Vout_Enable = OFF;
if( !nVol_Get_Chip_STA_Flag )
{
nVol_Get_Chip_STA_Flag = TRUE;
VOL_EN_Type(VOX_ADT_Mode); //VOL Disable 5V And Enable VOR ADT
nCHIP_STA1_Vol = CHIP_STA1 & VOL_LoadOn;
}
else
{
/*耳机出入盒判断*/
if( nCHIP_STA1_Vol != ( CHIP_STA1 & VOL_LoadOn ) ) //查询耳机loadon状态loadon状态改变则说明有耳机出入盒。
{
if( CHIP_STA1 & VOL_LoadOn ) //Vox入盒
{
Earphone_Chg_Flag_led = TRUE; //用于灯效显示
#ifdef LED_DISPLAY
LED_On_Flag = TRUE;
#endif
#ifdef _DEBUG_VOX
printf("VOL Get Into Box Bat Low.(line:%d)\r\n",(u16)__LINE__);
#endif
}
nCHIP_STA1_Vol = CHIP_STA1 & VOL_LoadOn;
}
}
}
}
Vox_State_e Vor_State;
bit Vor_GetOut_Box_Flag; //Vor 出盒标志,用于耳机抽电灯效。
/*
*******************************************************************************
* void Vor_Det_Machine(void)
*
* Description : Vor Detect:耳机识别。 (100ms调用周期)
*
* Arguments : NONE
* Returns : NONE
* Notes : NONE
*
*******************************************************************************
*/
void Vor_Det_Machine(void)
{
static uint8_t nVor_Loadon_Det_Debounce; //loadon标志检测延时计数
static uint8_t nVor_Output_Debounce; //Vox重载转轻载延时计数
static bit nVor_Chg_Full_Flag; //耳机充满标志
static bit nVor_GetOut_Box_Flag;
static bit nVor_Outbox_Disp_Flag;
static bit nVor_Intobox_Disp_Flag;
static bit nVor_Get_Chip_STA_Flag;
static uint8_t nCHIP_STA1_Vor;
if( gBoost_Prepared_Flag )
{
switch( Vor_State )
{
case VOX_GET_INTO_BOX: //耳机入仓
/*开启Vox Vout 5V前需要先开Boost。*/
if( !Boost_Open_Flag )
{
DisCharge_Boost_Open(OFF,BOOST_VOUT_MAX);
Boost_Open_Flag = TRUE;
#ifdef _DEBUG_VOX
printf("Boost Open.(line:%d)\r\n",(u16)__LINE__);
#endif
return;
}
VOR_EN_Type(VOX_VOUT_Mode); //Vox开启Vout 5V输出
Vor_Vout_Enable = ON;
Boost_Open_Flag = FALSE;
nVor_Chg_Full_Flag = FALSE;
nVor_GetOut_Box_Flag = FALSE;
nVor_Intobox_Disp_Flag = FALSE;
nVor_Outbox_Disp_Flag = FALSE;
nVor_Output_Debounce = 0;
/*重启跟随充*/
#if VOX_FOLLOW_CHG
Vox_Fllow_Chg.Vox_Follow_Start = OFF;
Vox_Fllow_Chg.Vox_Follow_Stop = OFF;
Follow_Chg_Sta = Vox_Follow_Chg_InitSta;
#endif
#ifdef _DEBUG_VOX
printf("Vor Get Into Box.(line:%d)\r\n",(u16)__LINE__);
#endif
Vor_State = VOX_STAY_IN_BOX;
break;
case VOX_STAY_IN_BOX: //耳机在仓
if ( ( CHIP_STA1 & ( VOR_LoadOn | VOR_Ioff ) ) == ( VOR_LoadOn | VOR_Ioff ) ) //充电过程中出现只有IOFF则出现如下三种情况1、耳机出仓2、耳机电池充满3、耳机电池锂保。
{
if( nVor_Intobox_Disp_Flag ) //Vor耳机在正常充电过程中被拔出。
{
nVor_Outbox_Disp_Flag = TRUE;
nVor_Intobox_Disp_Flag = FALSE;
nVor_GetOut_Box_Flag = TRUE;
Vor_GetOut_Box_Flag = TRUE; //右耳出盒标志置1用于抽电灯效
#ifdef _DEBUG_VOX
printf("Vor Get Out.(line:%d)\r\n",(u16)__LINE__);
#endif
}
nVor_Output_Debounce++;
if( nVor_Output_Debounce >= VOX_IOFF_DET_DEBOUNCE ) //重载转轻载(耳机出仓后)需延时5sVox掉Vout 5V后转入ADT模式。
{
nVor_Output_Debounce = 0;
VOR_EN_Type(VOX_ADT_Mode);
nVor_Chg_Full_Flag = TRUE;
#ifdef _DEBUG_VOX
printf("Vor Full And In ADT.(line:%d)\r\n",(u16)__LINE__);
#endif
}
}
else
if ( ( CHIP_STA1 & ( VOR_LoadOn | VOR_Ioff ) ) == VOR_LoadOn ) //无IOFF有Loadon说明1、耳机出仓后4s内耳机再次入仓2、10分钟未满耳机电池退出锂保状态进入正常充电
{
nVor_Output_Debounce = 0;
nVor_Intobox_Disp_Flag = TRUE;
if( nVor_Chg_Full_Flag ) //Vox在ADT模式后检测到loadon标志则说明耳机已充满不再抽电等loadon消失判断耳机出盒。
{
Vor_Vout_Enable = OFF;
#ifdef _DEBUG_VOX
printf("Vor Full.(line:%d)\r\n",(u16)__LINE__);
#endif
}
else
{
if( nVor_Outbox_Disp_Flag ) //左耳4s内再次入盒左耳对应的入盒灯效闪一次。
{
nVor_Outbox_Disp_Flag = FALSE;
if( nVor_GetOut_Box_Flag )
{
nVor_GetOut_Box_Flag = FALSE;
/*重启跟随充*/
#if VOX_FOLLOW_CHG
Vox_Fllow_Chg.Vox_Follow_Start = OFF;
Vox_Fllow_Chg.Vox_Follow_Stop = OFF;
Follow_Chg_Sta = Vox_Follow_Chg_InitSta;
#endif
Earphone_Chg_Flag_led = TRUE; //用于灯效显示
#ifdef LED_DISPLAY
LED_On_Flag = TRUE;
#endif
#ifdef _DEBUG_VOX
printf("Vor Get In Again.(line:%d)\r\n",(u16)__LINE__);
#endif
}
}
Vor_Vout_Enable = ON; //正常充电标志置ON。
Vor_GetOut_Box_Flag = FALSE;
#ifdef _DEBUG_VOX
printf("Vor Ching.(line:%d)\r\n",(u16)__LINE__);
#endif
}
}
else
if ( !( CHIP_STA1 & VOR_LoadOn ) ) //无Loadon说明耳机出仓
{
nVor_Loadon_Det_Debounce++;
if( nVor_Loadon_Det_Debounce >= VOX_NO_LOADON_CNT ) //耳机充满后,断开内部下拉电阻延时计数,根据实际应用调整。
{
nVor_Loadon_Det_Debounce = 0;
nVor_Intobox_Disp_Flag = FALSE;
nVor_Outbox_Disp_Flag = FALSE;
nVor_GetOut_Box_Flag = FALSE;
Vor_State = VOX_NONE_IN_BOX;
#ifdef _DEBUG_VOX
printf("Vor Out Box.(line:%d)\r\n",(u16)__LINE__);
#endif
}
}
else
{
nVor_Loadon_Det_Debounce = 0;
}
break;
case VOX_NONE_IN_BOX: //空仓
VOR_EN_Type(VOX_ADT_Mode);
Vor_Vout_Enable = OFF;
Vor_GetOut_Box_Flag = TRUE; //右耳出盒标志置1用于抽电灯效
if( CHIP_STA1 & VOR_LoadOn ) //adt模式下出现loadon信号则说明Vor通道有耳机入盒。
{
nVor_Loadon_Det_Debounce++;
if( nVor_Loadon_Det_Debounce >= VOX_LOADON_DET_DEBOUNCE ) //Vox Loadon信号检测延时计数loadon信号软件数字滤波根据实际耳机进行调试
{
nVor_Loadon_Det_Debounce = 0;
Vor_State = VOX_GET_INTO_BOX;
/*置灯效显示标志*/
Earphone_Chg_Flag_led = TRUE;
#ifdef LED_DISPLAY
LED_On_Flag = TRUE;
#endif
#ifdef _DEBUG_VOX
printf("Vor Det Loadon.(line:%d)\r\n",(u16)__LINE__);
#endif
}
}
break;
default:
break;
}
}
else //bat保护后VOX恢复到最初状态。
{
Vor_State = VOX_GET_INTO_BOX;
Vor_Vout_Enable = OFF;
if( !nVor_Get_Chip_STA_Flag )
{
nVor_Get_Chip_STA_Flag = TRUE;
VOR_EN_Type(VOX_ADT_Mode); //VOR Disable 5V And Enable VOR ADT
nCHIP_STA1_Vor = CHIP_STA1 & VOR_LoadOn;
}
else
{
/*耳机出入盒判断*/
if( nCHIP_STA1_Vor != ( CHIP_STA1 & VOR_LoadOn ) ) //查询耳机loadon状态loadon状态改变则说明有耳机出入盒。
{
if( CHIP_STA1 & VOR_LoadOn ) //Vox入盒
{
Earphone_Chg_Flag_led = TRUE; //用于灯效显示
#ifdef LED_DISPLAY
LED_On_Flag = TRUE;
#endif
#ifdef _DEBUG_VOX
printf("VOR Get Into Box Bat Low.(line:%d)\r\n",(u16)__LINE__);
#endif
}
nCHIP_STA1_Vor = CHIP_STA1 & VOR_LoadOn;
}
}
}
}
#else
/*
*******************************************************************************
* void Vox_Det_Machine(void)
*
* Description : Vox Detect:耳机识别。 (100ms调用周期)
*
* Arguments : NONE
* Returns : NONE
* Notes : NONE
*
*******************************************************************************
*/
/*
1、关盖开启Boost denounce一段时间ms级延时后开启Vox 5v显示灯效。
2、开盖开启Boost denounce一段时间ms级延时后开启Vox 5v至少500ms用于唤醒耳机后发送开盖指令持续10s间隔250-300ms。
3、发送开盖指令间隔250-300ms期间Vox转入ADT模式检测都Loadon状态需要有灯效。
4、两只耳机电池都充满或仓低电则发送关机指令。
*/
void Vox_Det_Machine(void)
{
static bit Get_CHIP_STA1_Flag0;
static bit nVox_Comm_Flag;
static bit nVox_Comm_Over_Flag;
static bit Cover_Close_Flag;
static bit Cover_Close_Flag1;
static bit Cover_Close_Force_Vout_Flag;
static bit Cover_Open_Flag;
static bit Cover_Open_5V_Flag;
static bit Bat_Low_Pro_Flag;
static bit Vox_Chg_Full_Flag;
static bit Vox_Getinto_Sleep_Flag;
static uint8_t CHIP_STA1_BK;
static uint8_t Vox_Voltage_Hold_Timer;
static uint8_t Vox_TX_Timer;
static bit Vox_Chn_Select;
static uint8_t Vox_Output_Debounce;
static uint8_t Vox_Output_Cnt;
static bit CoverEvent_Flg1;
static bit Vox_Vol_Up_Flg;
if( gBoost_Prepared_Flag )
{
if( CoverEvent_Flg ) //Hall事件触发。
{
if( !Boost_Open_Flag )
{
DisCharge_Boost_Open(OFF,BOOST_VOUT_MAX); //开关盖Boost输出5.2V保证耳机一定能被唤醒。Boost Enable异常时由硬件主动关闭。开启Boost开启Vox 5v会在开启Boost之后100ms延时
Boost_Open_Flag = TRUE;
return;
}
VOX_EN_Type(VOX_VOUT_Mode); //VOX Enable 5V
Vox_Output_Debounce = 0;
Vox_Voltage_Hold_Timer = 0; //关盖清0开盖使用
Vox_TX_Timer = 0;
Get_CHIP_STA1_Flag0 = FALSE;
nVox_Comm_Flag = FALSE;
nVox_Comm_Over_Flag = FALSE;
CoverEvent_Flg1 = TRUE;
if( CoverStatus == CLOSE ) //1、关盖关闭COM_CTRL显示灯效。无需查询Loadon、IOFF状态无论耳机是否在仓Vox 5V输出。
{
Earphone_Chg_Flag_led = FALSE; //关盖取消耳机入盒灯效,显示关盖灯效。
Cover_Close_Flag = TRUE;
Cover_Close_Flag1 = TRUE;
Cover_Open_Flag = FALSE;
Vox_Chg_Full_Flag = FALSE;
Cover_Close_Force_Vout_Flag = FALSE;
Vox_Getinto_Sleep_Flag = FALSE;
Vox_Chn_Select = FALSE;
Vox_Vout_Enable = ON;
Wkup_Earphone_Flag = FALSE;
#if VOX_FOLLOW_CHG
Vox_Fllow_Chg.Vox_Follow_Start = OFF;
Vox_Fllow_Chg.Vox_Follow_Stop = OFF;
Follow_Chg_Sta = Vox_Follow_Chg_InitSta;
#endif
#ifdef _DEBUG_VOX
printf("Box Close.(line:%d)\r\n",(u16)__LINE__);
#endif
}
else //2、开盖处理5v 500ms 转0V 500ms后转ADT模式。
{
Cover_Close_Flag = FALSE;
Cover_Close_Flag1 = FALSE;
Cover_Open_Flag = TRUE;
Cover_Open_5V_Flag = FALSE;
#ifdef _DEBUG_VOX
printf("Box Open.(line:%d)\r\n",(u16)__LINE__);
#endif
}
Boost_Open_Flag = FALSE;
Vox_Output_Short_Flag = FALSE;
Vox_Ocp_Flag = FALSE;
CoverEvent_Flg = FALSE;
}
/* 开关盖后VOX先升压5.2V 一段时间唤醒耳机后转入ADT获取盒内耳机数量。 */
if( Vox_Voltage_Hold_Timer < HALL_EVENT_VOX_5V_DEBOUNCE ) //开盖后5V N00ms。
{
Vox_Voltage_Hold_Timer++;
return;
}
if ( CoverEvent_Flg1 )
{
CoverEvent_Flg1 = FALSE;
VOX_EN_Type(VOX_ADT_Mode);
return;
}
else
{
if ( !Get_CHIP_STA1_Flag0 ) //获取耳机在盒数量。
{
Get_CHIP_STA1_Flag0 = TRUE;
if ( CHIP_STA1 & ( VOR_LoadOn | VOL_LoadOn ) )
{
if ( ( CHIP_STA1 & ( VOR_LoadOn | VOL_LoadOn ) ) == ( VOR_LoadOn | VOL_LoadOn ) )
{
EarPhone_Num = 2;
}
else
{
EarPhone_Num = 1;
}
}
else
{
EarPhone_Num = 0;
}
#ifdef _DEBUG_VOX
printf( "Open/Close Box,Earphones In Box(Num:%d)(VoxSta:0x%x).\r\n",(u16)EarPhone_Num, (u16)(CHIP_STA1) );
#endif
}
}
/* 发送开盖指令*/
if( Cover_Open_Flag ) /*开盖后5V持续N00ms后0V持续N00ms保证耳机能被唤醒之后发开盖码。*/
{
#if VOX_0V_WAKEUP_EAR
if( Vox_TX_Timer < HALL_OPEN_VOX_0V_DEBOUNCE ) //转0V N00ms
{
VOX_EN_Type(VOX_PD1K_Mode);
Vox_TX_Timer++;
}
else
#endif
{
#ifdef VOX_COMM_ENABLE
/* 双向通讯,开盖发码。 */
if( !nVox_Comm_Flag )
{
Vox_Comm_Cfg_Clear();
gVox_Comm.Cover_Open_Flag = TRUE; //置开盖发码标志位
nVox_Comm_Flag = TRUE;
#ifdef _DEBUG_VOX
printf("TX Comm Cover Open.(line:%d)\r\n ", (u16)__LINE__);
#endif
return;
}
else
#endif
{
#ifdef VOX_COMM_ENABLE
if( !gVox_Comm.Cover_Open_Flag ) //开盖发码完成
#endif
{
if ( !nVox_Comm_Over_Flag )
{
nVox_Comm_Over_Flag = TRUE;
VOX_EN_Type(VOX_ADT_Mode);
OpenCover_TX_Cmd_Flag = TRUE;
Vox_Vout_Enable = OFF;
#ifdef _DEBUG_VOX
printf("Open Box CMD TX Over.\r\n");
#endif
}
}
else
{
return;
}
}
if( Event_key == KEY_EVENT_Empty )
{
if( OpenCover_TX_Cmd_Flag )
{
OpenCover_TX_Cmd_Flag = FALSE;
nVox_Comm_Over_Flag = TRUE;
CHIP_STA1_BK = CHIP_STA1 & ( VOR_LoadOn | VOL_LoadOn );
}
else
{
if( nVox_Comm_Over_Flag )
{
/*耳机出入盒判断*/
if( CHIP_STA1_BK != ( CHIP_STA1 & ( VOR_LoadOn | VOL_LoadOn ) ) ) //查询耳机loadon状态loadon状态改变则说明有耳机出入盒。
{
if ( CHIP_STA1 & ( VOR_LoadOn | VOL_LoadOn ) )
{
Earphone_Chg_Flag_led = TRUE;
#ifdef LED_DISPLAY
LED_On_Flag = TRUE;
#endif
}
#ifdef _DEBUG_VOX
printf( "Open Box And Earphone GetIn(Num:%d)(VoxSta:0x%x).\r\n",(u16)EarPhone_Num, (u16)(CHIP_STA1) );
#endif
CHIP_STA1_BK = ( CHIP_STA1 & ( VOR_LoadOn | VOL_LoadOn ) );
}
}
}
}
}
}
if( Cover_Close_Flag )
{
if( Wkup_Earphone_Flag ) //保护、断充电后VOX需自动升压唤醒耳机。
{
if( !Boost_Open_Flag )
{
DisCharge_Boost_Open(OFF, BOOST_VOUT_MAX); //Boost Enable异常时由硬件主动关闭。开启Boost开启Vox 5v会在开启Boost之后100ms延时
Boost_Open_Flag = TRUE;
Vox_Vout_Enable = ON;
#if VOX_FOLLOW_CHG
Vox_Fllow_Chg.Vox_Follow_Start = OFF;
Vox_Fllow_Chg.Vox_Follow_Stop = OFF;
Follow_Chg_Sta = Vox_Follow_Chg_InitSta;
#endif
Vox_Voltage_Hold_Timer = 0;
Vox_Chg_Full_Flag = FALSE;
CoverEvent_Flg1 = TRUE;
Get_CHIP_STA1_Flag0 = FALSE;
Cover_Close_Force_Vout_Flag = TRUE;
Vox_Vol_Up_Flg = TRUE;
return;
}
if( Vox_Vol_Up_Flg ) //VOX VOUT 5V只开一次。
{
Vox_Vol_Up_Flg = FALSE;
VOX_EN_Type(VOX_VOUT_Mode); //VOX Enable 5V
}
#ifdef _DEBUG_VOX
printf("Close Box And Force Voltage Up.\r\n ");
#endif
Boost_Open_Flag = FALSE;
Cover_Close_Flag1 = TRUE;
if( Vox_Voltage_Hold_Timer <= HALL_CLOSE_VOX_5V_HOLD_CNT ) //关盖Boost VOUT 5V保持时间。
{
Vox_Voltage_Hold_Timer++;
return;
}
Wkup_Earphone_Flag = FALSE;
}
else
{
#ifdef VOX_COMM_ENABLE
if( !Cover_Close_Force_Vout_Flag )
{
#if VOX_0V_WAKEUP_EAR /*关盖后5V持续N00ms后0V持续N00ms保证耳机能被唤醒之后发关盖码。*/
if( Vox_TX_Timer < HALL_CLOSE_VOX_0V_DEBOUNCE ) //转0V N00ms
{
VOX_EN_Type(VOX_PD1K_Mode);
Vox_TX_Timer++;
}
else
#endif
{
/* 双向通讯,关盖发码。 */
if( !nVox_Comm_Flag )
{
Vox_Comm_Cfg_Clear();
gVox_Comm.Cover_Close_Flag = TRUE; //置关盖发码标志位
nVox_Comm_Flag = TRUE;
#ifdef _DEBUG_VOX
printf("TX Comm Cover Close.(line:%d)\r\n ", (u16)__LINE__);
#endif
return;
}
else
{
if( gVox_Comm.Cover_Close_Flag ) //关盖发码中
{
return;
}
}
}
}
#endif
}
/*Vox 过流保护两只耳机都每隔500ms打嗝一次*/
if( IRQ_FLAG0 & ( VOR_OutPut_Short | VOL_OutPut_Short ) )
{
if( !Vox_Ocp_Flag )
{
Vox_Output_Debounce++;
if( Vox_Output_Debounce >= VOX_OCP_HICUUP_DEBOUNCE )
{
Vox_Output_Debounce = 0;
IRQ_FLAG0 = VOR_OutPut_Short | VOL_OutPut_Short;
VOX_EN_Type(VOX_VOUT_Mode);
Vox_Output_Short_Flag = TRUE;
Vox_Vout_Enable = OFF;
}
}
else
{
VOX_EN_Type(VOX_ADT_Mode);
}
return;
}
Vox_Output_Short_Flag = FALSE;
Vox_Ocp_Flag = FALSE;
/* 发完关盖码后开启VOX VOUT 5V输出。 */
if( Cover_Close_Flag1 )
{
VOX_EN_Type(VOX_VOUT_Mode); //VOX Enable 5V
#ifdef _DEBUG_VOX
printf("VOX Vout 5V(STA1:0x%x,line:%d).\r\n",(uint16_t)CHIP_STA1, (uint16_t)__LINE__);
#endif
Cover_Close_Flag1 = FALSE;
Vox_Voltage_Hold_Timer = 0;
}
else
{
if( !Vox_Chg_Full_Flag )
{
//if( ( CHIP_STA1 & ( VOR_Ioff | VOL_Ioff | VOL_LoadOn | VOR_LoadOn ) == ( VOR_Ioff | VOL_Ioff | VOL_LoadOn | VOR_LoadOn ) ) || F_batlevel_low ) //耳机充满、VOX无负载、盒子低电则关闭Vout输出通路关闭Boost。
if( ( (CHIP_STA1 & 0xAC) == 0xAC ) || F_batlevel_low )
{
if( Vox_Voltage_Hold_Timer <= VOX_CHG_FULL_5V_LEAST_CNT ) //重载转轻载延时5s后关闭Boost输出。
{
Vox_Voltage_Hold_Timer++;
return;
}
#ifdef _DEBUG_VOX
printf("VOX CHG Full.\r\n");
#endif
Vox_Chg_Full_Flag = TRUE;
Vox_Output_Cnt = 0;
Vox_Voltage_Hold_Timer = 0;
Vox_Getinto_Sleep_Flag = FALSE;
VOX_EN_Type(VOX_ADT_Mode); //VOX Enable ADT
}
else
{
#if VOX_FOLLOW_CHG
if ( Vox_Fllow_Chg.Vox_Follow_Stop == OFF )
{
Vox_Follow_Chg( &Vox_Fllow_Chg ); //跟随充处理。
}
#endif
}
}
else
{
#ifdef VOX_COMM_ENABLE
if( !Vox_Getinto_Sleep_Flag )
{
Vox_Getinto_Sleep_Flag = TRUE;
Vox_Comm_Cfg_Clear();
gVox_Comm.Vox_Chg_Full_Flag = TRUE;
#ifdef _DEBUG_VOX
printf("TX Comm Vox Chg Full.(line:%d)\r\n ", (u16)__LINE__);
#endif
}
else
#endif
{
#ifdef VOX_COMM_ENABLE
if( !gVox_Comm.Vox_Chg_Full_Flag )
#endif
{
if ( !nVox_Comm_Over_Flag )
{
nVox_Comm_Over_Flag = TRUE;
VOX_EN_Type(VOX_ADT_Mode);
Vox_Vout_Enable = OFF;
#ifdef _DEBUG_VOX
printf("VOX Get Into Sleep.\r\n");
#endif
}
}
}
}
}
}
Bat_Low_Pro_Flag = FALSE;
}
else
{
if( !Bat_Low_Pro_Flag ) //低电保护后VOX开启ADT模式。判断耳机出入盒并显示相应的灯效。
{
Bat_Low_Pro_Flag = TRUE;
VOX_EN_Type(VOX_ADT_Mode);
Vox_Vout_Enable = OFF;
CHIP_STA1_BK = CHIP_STA1 & ( VOR_LoadOn | VOL_LoadOn );
return;
}
/*耳机出入盒判断*/
if( CHIP_STA1_BK != ( CHIP_STA1 & ( VOR_LoadOn | VOL_LoadOn ) ) ) //查询耳机loadon状态loadon状态改变则说明有耳机出入盒。
{
if( CHIP_STA1 & ( VOR_LoadOn | VOL_LoadOn ) )
{
Earphone_Chg_Flag_led = TRUE;
#ifdef LED_DISPLAY
LED_On_Flag = TRUE;
#endif
}
CHIP_STA1_BK = ( CHIP_STA1 & ( VOR_LoadOn | VOL_LoadOn ) );
}
}
}
#endif
#if VOX_FOLLOW_CHG
/*
*******************************************************************************
* void Vox_Follow_Chg( g_Vox_Fllow_Chg_Cfg *g_Vox_Fllow_Chg )
*
* Description : Vox 跟随充处理函数。 (100ms调用周期)
*
* Arguments : g_Vox_Fllow_Chg_Cfg *g_Vox_Fllow_Chg
* Returns : NONE
* Notes : NONE
*
*******************************************************************************
*/
void Vox_Follow_Chg( g_Vox_Fllow_Chg_Cfg *n_Vox_Fllow_Chg )
{
static bit nVpmid_Value_Setting;
switch ( Follow_Chg_Sta )
{
case Vox_Follow_Chg_InitSta: //STA0:PMID=5.2V可以保证耳机一定能进入充电状态,并持续一段时间保证耳机能开始抽电。
if( (n_Vox_Fllow_Chg->Vox_Follow_Stop == OFF) ) //启动跟随充
{
if( Vox_Follow_Init_Deb <= VOX_FOLLOW_CHG_INIT_CNT )
{
Vox_Follow_Init_Deb++;
n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present = VOUT_MAX_THD;
if( !nVpmid_Value_Setting )
{
DisCharge_Boost_Open(OFF,n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present);
#ifdef _DEBUG_FOLLOW
printf("Follow CHG InitSta Set Max Vpmid.(Vox_sta:0x%x)(line:%d)\r\n",(uint16_t)CHIP_STA1, (uint16_t)__LINE__);
#endif
nVpmid_Value_Setting = TRUE;
}
}
else
{
Vox_Follow_Init_Deb = 0;
/* 参数初始化。 */
nVpmid_Value_Setting = FALSE;
n_Vox_Fllow_Chg->Vpmid_AddSta[VOR_TYPE] = OFF;
n_Vox_Fllow_Chg->Vpmid_AddSta[VOL_TYPE] = OFF;
n_Vox_Fllow_Chg->Vpmid_SubSta[VOR_TYPE] = OFF;
n_Vox_Fllow_Chg->Vpmid_SubSta[VOL_TYPE] = OFF;
n_Vox_Fllow_Chg->IVox_TC_Mode[VOR_TYPE] = OFF;
n_Vox_Fllow_Chg->IVox_TC_Mode[VOL_TYPE] = OFF;
n_Vox_Fllow_Chg->Vox_InBox_Sta[VOR_TYPE] = OFF;
n_Vox_Fllow_Chg->Vox_InBox_Sta[VOL_TYPE] = OFF;
n_Vox_Fllow_Chg->IVox_At_Present[VOR_TYPE] = 0;
n_Vox_Fllow_Chg->IVox_At_Present[VOL_TYPE] = 0;
n_Vox_Fllow_Chg->Vpmid_Threshold_Neg = VOUT_MIN_THD;
n_Vox_Fllow_Chg->Vpmid_Threshold_Pos = VOUT_MAX_THD;
Follow_Chg_Sta = Vox_Follow_Chg_Sta1;
Vox_Follow_Chg_Debounce = 0;
#ifdef _DEBUG_FOLLOW
printf("Follow CHG InitSta.(Vox_sta:0x%x)(line:%d)\r\n",(uint16_t)CHIP_STA1, (uint16_t)__LINE__);
#endif
}
}
break;
case Vox_Follow_Chg_Sta1: //STA1:获取耳机当前抽电电流和设置Vox上下限电流阈值。
if ( ( CHIP_STA1 & VOR_Ioff ) && ( CHIP_STA1 & VOL_Ioff ) ) //VOL、VOR耳机无抽电则说明耳机已充满无需再继续跟随充。
{
n_Vox_Fllow_Chg->Vox_Follow_Stop = ON;
Follow_Chg_Sta = Vox_Follow_Chg_InitSta;
#ifdef _DEBUG_FOLLOW
printf("Follow CHG Sta1,No EarPhone In Box.(line:%d)\r\n",(uint16_t)__LINE__);
#endif
}
else
{
/*获取当前Ivox。Vox开启功率且Ioff处于重载状态。*/
if( !( CHIP_STA1 & VOR_Ioff ) )
{
n_Vox_Fllow_Chg->IVox_Init[VOR_TYPE] = g_pmu_Adc_Ivor;
n_Vox_Fllow_Chg->IVox_Threshold_Neg[VOR_TYPE] = IVOR_Threshold_Neg(g_pmu_Adc_Ivor); //Ivox_Threshold_Neg = IVox_Init * 80%
n_Vox_Fllow_Chg->IVox_Threshold_Pos[VOR_TYPE] = IVOR_Threshold_Pos(g_pmu_Adc_Ivor); //Ivox_Threshold_Neg = IVox_Init * 2
#ifdef _DEBUG_FOLLOW
printf("Follow CHG Sta1,VOR Chging(Ivor:%dmA).(line:%d)\r\n",(u16)g_pmu_Adc_Ivor,(uint16_t)__LINE__);
#endif
}
if( !( CHIP_STA1 & VOL_Ioff ) )
{
n_Vox_Fllow_Chg->IVox_Init[VOL_TYPE] = g_pmu_Adc_Ivol;
n_Vox_Fllow_Chg->IVox_Threshold_Neg[VOL_TYPE] = IVOL_Threshold_Neg(g_pmu_Adc_Ivol); //Ivox_Threshold_Neg = IVox_Init * 80%
n_Vox_Fllow_Chg->IVox_Threshold_Pos[VOL_TYPE] = IVOL_Threshold_Pos(g_pmu_Adc_Ivol); //Ivox_Threshold_Neg = IVox_Init * 2
#ifdef _DEBUG_FOLLOW
printf("Follow CHG Sta1,VOL Chging(Ivol:%dmA).(line:%d)\r\n",(u16)g_pmu_Adc_Ivol,(uint16_t)__LINE__);
#endif
}
n_Vox_Fllow_Chg->Vox_Follow_Start = ON;
Follow_Chg_Sta = Vox_Follow_Chg_Sta2;
}
break;
case Vox_Follow_Chg_Sta2: //STA2:获取当前Vox电流等待IVOX电流稳定检测当前电流IVox_At_Present。
if( Vox_Follow_Chg_Debounce <= VOX_FOLLOW_CHG_NOWCURCHK_CNT )
{
Vox_Follow_Chg_Debounce++;
}
else
{
Vox_Follow_Chg_Debounce = 0;
if ( !( CHIP_STA1 & VOR_Ioff ) )
{
n_Vox_Fllow_Chg->IVox_At_Present[VOR_TYPE] = g_pmu_Adc_Ivor;
n_Vox_Fllow_Chg->Vox_InBox_Sta[VOR_TYPE] = ON; //判断VOR有耳机在盒正常抽电
#ifdef _DEBUG_FOLLOW
printf("Follow CHG Sta2,Get IVOR:%dmA.(line:%d)\r\n",(uint16_t)g_pmu_Adc_Ivor,(u16)__LINE__);
#endif
}
if ( !( CHIP_STA1 & VOL_Ioff) )
{
n_Vox_Fllow_Chg->IVox_At_Present[VOL_TYPE] = g_pmu_Adc_Ivol;
n_Vox_Fllow_Chg->Vox_InBox_Sta[VOL_TYPE] = ON; //判断VOL有耳机在盒正常抽电
#ifdef _DEBUG_FOLLOW
printf("Follow CHG Sta2,Get IVOL:%dmA.(line:%d)\r\n",(uint16_t)g_pmu_Adc_Ivol,(u16)__LINE__);
#endif
}
Follow_Chg_Sta = Vox_Follow_Chg_Sta3;
}
break;
case Vox_Follow_Chg_Sta3: //STA3:根据Ivox电流判断PMID是否需要降低。
if( Vox_Follow_Chg_Debounce <= VOX_FOLLOW_CHG_VOLTAGE_ADJUST_CNT )
{
Vox_Follow_Chg_Debounce++;
}
else
{
Vox_Follow_Chg_Debounce = 0;
if ( ( n_Vox_Fllow_Chg->IVox_At_Present[VOR_TYPE] > n_Vox_Fllow_Chg->IVox_Threshold_Pos[VOR_TYPE] ) || \
( n_Vox_Fllow_Chg->IVox_At_Present[VOL_TYPE] > n_Vox_Fllow_Chg->IVox_Threshold_Pos[VOL_TYPE] ) ) //当前电流大于THP阈值电流则说明耳机状态发生改变TC跳转到CC或Recharge复充需要重启跟随充。
{
Follow_Chg_Sta = Vox_Follow_Chg_InitSta;
n_Vox_Fllow_Chg->Vox_Follow_Start = OFF; //重启动跟随充
#ifdef _DEBUG_FOLLOW
printf("Follow CHG Sta3,VOX Chg ReInit.(line:%d)\r\n",(uint16_t)__LINE__);
#endif
}
else
{
if ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOR_TYPE] == ON )
{
if ( n_Vox_Fllow_Chg->IVox_At_Present[VOR_TYPE] <= VOX_CV_TC_CURRENT ) //检测到Ivor小于CV/TC电流阈值则说明耳机进入CV/TC阶段
{
if ( CHIP_STA1 & VOR_Ioff ) //检测到Ivor Ioff则VPMID升档。
{
n_Vox_Fllow_Chg->Vpmid_AddSta[VOR_TYPE] = ON;
if ( n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present >= VOUT_MAX_THD ) //Vpmid电压升到最大并且IOFF标志存在则说明耳机充满。
{
n_Vox_Fllow_Chg->Vox_InBox_Sta[VOR_TYPE] = OFF;
}
#ifdef _DEBUG_FOLLOW
printf("Follow CHG Sta3(CV),VOR Vpmid AddSta(Ivor:%dmA).(line:%d)\r\n",n_Vox_Fllow_Chg->IVox_At_Present[VOR_TYPE],(u16)__LINE__);
#endif
}
else //未检测到Ivor Ioff则Vpmid降档
{
n_Vox_Fllow_Chg->Vpmid_SubSta[VOR_TYPE] = ON;
#ifdef _DEBUG_FOLLOW
printf("Follow CHG Sta3(CV),VOR Vpmid SubSta(Ivor:%dmA).(line:%d)\r\n",n_Vox_Fllow_Chg->IVox_At_Present[VOR_TYPE],(u16)__LINE__);
#endif
}
}
else
{
if ( n_Vox_Fllow_Chg->IVox_At_Present[VOR_TYPE] > n_Vox_Fllow_Chg->IVox_Threshold_Neg[VOR_TYPE] )
{
n_Vox_Fllow_Chg->Vpmid_SubSta[VOR_TYPE] = ON;
#ifdef _DEBUG_FOLLOW
printf("Follow CHG Sta3(CC),VOR Vpmid SubSta(Ivor:%dmA).(line:%d)\r\n",n_Vox_Fllow_Chg->IVox_At_Present[VOR_TYPE],(u16)__LINE__);
#endif
}
else
{
n_Vox_Fllow_Chg->Vpmid_AddSta[VOR_TYPE] = ON;
#ifdef _DEBUG_FOLLOW
printf("Follow CHG Sta3(CC),VOR Vpmid AddSta(Ivor:%dmA).(line:%d)\r\n",n_Vox_Fllow_Chg->IVox_At_Present[VOR_TYPE],(u16)__LINE__);
#endif
}
}
}
if ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOL_TYPE] == ON )
{
if ( n_Vox_Fllow_Chg->IVox_At_Present[VOL_TYPE] <= VOX_CV_TC_CURRENT ) //检测到Ivol小于CV/TC电流阈值则说明耳机进入CV/TC阶段
{
if ( CHIP_STA1 & VOL_Ioff ) //检测到Ivol Ioff则VPMID升档。
{
n_Vox_Fllow_Chg->Vpmid_AddSta[VOL_TYPE] = ON;
if ( n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present >= VOUT_MAX_THD ) //Vpmid电压升到最大并且IOFF标志存在则说明耳机充满。
{
n_Vox_Fllow_Chg->Vox_InBox_Sta[VOL_TYPE] = OFF;
}
#ifdef _DEBUG_FOLLOW
printf("Follow CHG Sta3(CV),VOL Vpmid AddSta(Ivol:%dmA).(line:%d)\r\n",n_Vox_Fllow_Chg->IVox_At_Present[VOL_TYPE],(u16)__LINE__);
#endif
}
else //未检测到Ivol Ioff则Vpmid降档
{
n_Vox_Fllow_Chg->Vpmid_SubSta[VOL_TYPE] = ON;
#ifdef _DEBUG_FOLLOW
printf("Follow CHG Sta3(CV),VOL Vpmid SubSta(Ivol:%dmA).(line:%d)\r\n",n_Vox_Fllow_Chg->IVox_At_Present[VOL_TYPE],(u16)__LINE__);
#endif
}
}
else
{
if ( n_Vox_Fllow_Chg->IVox_At_Present[VOL_TYPE] > n_Vox_Fllow_Chg->IVox_Threshold_Neg[VOL_TYPE] )
{
n_Vox_Fllow_Chg->Vpmid_SubSta[VOL_TYPE] = ON;
#ifdef _DEBUG_FOLLOW
printf("Follow CHG Sta3(CC),VOL Vpmid SubSta(Ivol:%dmA).(line:%d)\r\n",n_Vox_Fllow_Chg->IVox_At_Present[VOL_TYPE],(u16)__LINE__);
#endif
}
else
{
n_Vox_Fllow_Chg->Vpmid_AddSta[VOL_TYPE] = ON;
#ifdef _DEBUG_FOLLOW
printf("Follow CHG Sta3(CC),VOL Vpmid AddSta(Ivol:%dmA).(line:%d)\r\n",n_Vox_Fllow_Chg->IVox_At_Present[VOL_TYPE],(u16)__LINE__);
#endif
}
}
}
}
}
break;
case Vox_Follow_Chg_Sta4: //STA4:根据IVOX电流判断PMID是否升高1、在此状态下每2s检测一次IVOX电流2、当检测到 IVOX < IVOX_THN or IVOX > IVOX_THP,则PMID 升高一个step或N个step根据实际测试设定。
if( Vox_Follow_Chg_Debounce <= VOX_FOLLOW_CHG_PMID_UP_CNT )
{
/* 每2s检测一次IVOX电流。 */
Vox_Follow_Chg_Debounce++;
n_Vox_Fllow_Chg->IVox_At_Present[VOR_TYPE] = g_pmu_Adc_Ivor;
n_Vox_Fllow_Chg->IVox_At_Present[VOL_TYPE] = g_pmu_Adc_Ivol;
}
else
{
Vox_Follow_Chg_Debounce = 0;
/* 充电效率优先 */
#ifdef FOLLOW_CHG_EFFICIENCY
if ( ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOR_TYPE] == ON ) && ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOL_TYPE] == ON ) )
{
if ( ( ( n_Vox_Fllow_Chg->IVox_At_Present[VOR_TYPE] < n_Vox_Fllow_Chg->IVox_Threshold_Neg[VOR_TYPE] ) || \
( n_Vox_Fllow_Chg->IVox_At_Present[VOR_TYPE] > n_Vox_Fllow_Chg->IVox_Threshold_Pos[VOR_TYPE] ) ) && \
( ( n_Vox_Fllow_Chg->IVox_At_Present[VOL_TYPE] < n_Vox_Fllow_Chg->IVox_Threshold_Neg[VOL_TYPE] ) || \
( n_Vox_Fllow_Chg->IVox_At_Present[VOL_TYPE] > n_Vox_Fllow_Chg->IVox_Threshold_Pos[VOL_TYPE] ) ) )
{
n_Vox_Fllow_Chg->Vpmid_AddSta[VOR_TYPE] = ON;
n_Vox_Fllow_Chg->Vpmid_AddSta[VOL_TYPE] = ON;
Follow_Chg_Sta = Vox_Follow_Chg_Sta2;
#ifdef _DEBUG_FOLLOW
printf("Follow CHG Sta4,VOx Vpmid AddSta(Vout:0x%x,Ivol:%dmA,Ivor:%dmA)(line:%d).\r\n",(uint16_t)n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present,(uint16_t)g_pmu_Adc_Ivol,(uint16_t)g_pmu_Adc_Ivor,(u16)__LINE__);
#endif
}
#ifdef _DEBUG_FOLLOW
else
{
printf("Follow CHG Sta4,VOx Ching(Vout:0x%x,Ivol:%dmA,Ivor:%dmA)(line:%d).\r\n",(uint16_t)n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present,(uint16_t)g_pmu_Adc_Ivol,(uint16_t)g_pmu_Adc_Ivor,(u16)__LINE__);
}
#endif
}
else
#endif
{
/* 充电速度优先 */
if ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOR_TYPE] == ON )
{
/* 当检测到 IVOX < IVOX_THN or IVOX > IVOX_THP,则PMID 升高一个step或N个step根据实际测试设定。 */
if ( ( n_Vox_Fllow_Chg->IVox_At_Present[VOR_TYPE] < n_Vox_Fllow_Chg->IVox_Threshold_Neg[VOR_TYPE] ) || \
( n_Vox_Fllow_Chg->IVox_At_Present[VOR_TYPE] > n_Vox_Fllow_Chg->IVox_Threshold_Pos[VOR_TYPE] ) )
{
n_Vox_Fllow_Chg->Vpmid_AddSta[VOR_TYPE] = ON;
Follow_Chg_Sta = Vox_Follow_Chg_Sta2;
#ifdef _DEBUG_FOLLOW
printf("Follow CHG Sta4,VOR Vpmid AddSta(Vout:0x%x,Ivor:%dmA)(line:%d).\r\n",(uint16_t)n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present,(uint16_t)g_pmu_Adc_Ivor,(u16)__LINE__);
#endif
}
#ifdef _DEBUG_FOLLOW
else
{
printf("Follow CHG Sta4,VOR Ching(Vout:0x%x,Ivor:%dmA)(line:%d).\r\n",(uint16_t)n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present,(uint16_t)g_pmu_Adc_Ivor,(u16)__LINE__);
}
#endif
}
if ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOL_TYPE] == ON )
{
if ( ( n_Vox_Fllow_Chg->IVox_At_Present[VOL_TYPE] > n_Vox_Fllow_Chg->IVox_Threshold_Pos[VOL_TYPE] ) || \
( n_Vox_Fllow_Chg->IVox_At_Present[VOL_TYPE] < n_Vox_Fllow_Chg->IVox_Threshold_Neg[VOL_TYPE] ) )
{
n_Vox_Fllow_Chg->Vpmid_AddSta[VOL_TYPE] = ON;
Follow_Chg_Sta = Vox_Follow_Chg_Sta2;
#ifdef _DEBUG_FOLLOW
printf("Follow CHG Sta4,VOL Vpmid AddSta(Vout:0x%x,Ivol:%dmA)(line:%d).\r\n",(uint16_t)n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present,(uint16_t)g_pmu_Adc_Ivol,(u16)__LINE__);
#endif
}
#ifdef _DEBUG_FOLLOW
else
{
printf("Follow CHG Sta4,VOL Ching(Vout:0x%x,Ivol:%dmA)(line:%d).\r\n",(uint16_t)n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present,(uint16_t)g_pmu_Adc_Ivol,(u16)__LINE__);
}
#endif
}
}
}
break;
default:
break;
}
if( ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOR_TYPE] == ON ) || ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOL_TYPE] == ON ) )
{
if( ( n_Vox_Fllow_Chg->Vpmid_SubSta[VOR_TYPE] == ON ) || ( n_Vox_Fllow_Chg->Vpmid_SubSta[VOL_TYPE] == ON ) ) //当需要降压Vpmid则每降一次档位都会充电至少2s。
{
if( ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOR_TYPE] == ON ) && ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOL_TYPE] == ON ) )
{
if( ( n_Vox_Fllow_Chg->Vpmid_SubSta[VOR_TYPE] == ON ) && ( n_Vox_Fllow_Chg->Vpmid_SubSta[VOR_TYPE] == ON ) )
{
n_Vox_Fllow_Chg->Vpmid_SubSta_Flag = ON;
#ifdef _DEBUG_FOLLOW
printf("Follow CHG SubSta,VOL/VOR(line:%d).\r\n",(uint16_t)__LINE__);
#endif
}
}
if( ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOR_TYPE] == ON ) && ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOL_TYPE] == OFF ) )
{
if( n_Vox_Fllow_Chg->Vpmid_SubSta[VOR_TYPE] == ON )
{
n_Vox_Fllow_Chg->Vpmid_SubSta_Flag = ON;
#ifdef _DEBUG_FOLLOW
printf("Follow CHG SubSta,VOR(line:%d).\r\n",(uint16_t)__LINE__);
#endif
}
}
else
if( ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOR_TYPE] == OFF ) && ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOL_TYPE] == ON ) )
{
if( n_Vox_Fllow_Chg->Vpmid_SubSta[VOL_TYPE] == ON )
{
n_Vox_Fllow_Chg->Vpmid_SubSta_Flag = ON;
#ifdef _DEBUG_FOLLOW
printf("Follow CHG SubSta,VOL(line:%d).\r\n",(uint16_t)__LINE__);
#endif
}
}
n_Vox_Fllow_Chg->Vpmid_SubSta[VOR_TYPE] = OFF;
n_Vox_Fllow_Chg->Vpmid_SubSta[VOL_TYPE] = OFF;
if ( n_Vox_Fllow_Chg->Vpmid_SubSta_Flag == ON )
{
if( n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present > VOUT_MIN_THD )
{
n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present = n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present - VOX_FOLLOW_CHG_PMID_DOWN_STEPS;
}
/* 1、当Vpmid降档到到下限阈值则开始升压。2、Boost 直通模式使能条件判断VOUT - VBAT > 200mV。*/
if( ( n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present <= n_Vox_Fllow_Chg->Vpmid_Threshold_Neg ) || \
( g_pmu_Adc_Vout < ( g_Vbat_Adc + Vox_FOLLOW_CHG_PTM_THD ) ) )
{
if( n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present <= n_Vox_Fllow_Chg->Vpmid_Threshold_Neg )
{
n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present = n_Vox_Fllow_Chg->Vpmid_Threshold_Neg;
n_Vox_Fllow_Chg->Vox_PTM_Type = OFF;
}
else
{
n_Vox_Fllow_Chg->Vox_PTM_Type = ON;
n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present = n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present + VOX_FOLLOW_CHG_PMID_DOWN_STEPS;
#ifdef _DEBUG_FOLLOW
printf("Follow CHG PTM ON,(STA:0x%x,Vpmid:0x%x,PTM:%d,Vbat:%d,Vout:%d)(line:%d)\r\n",(uint16_t)Follow_Chg_Sta,(uint16_t)n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present,(uint16_t)n_Vox_Fllow_Chg->Vox_PTM_Type,(uint16_t)g_Vbat_Adc,(uint16_t)g_pmu_Adc_Vout,(uint16_t)__LINE__);
#endif
}
Follow_Chg_Sta = Vox_Follow_Chg_Sta4;
}
else
{
Follow_Chg_Sta = Vox_Follow_Chg_Sta2;
n_Vox_Fllow_Chg->Vox_PTM_Type = OFF;
}
Vox_Follow_Chg_Debounce = 0;
n_Vox_Fllow_Chg->Vpmid_SubSta_Flag = OFF;
#ifdef _DEBUG_FOLLOW
printf("Follow CHG SubSta,(STA:0x%x,Vpmid:0x%x,PTM:%d,Vbat:%d,Vout:%d)(line:%d)\r\n",(uint16_t)Follow_Chg_Sta,(uint16_t)n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present,(uint16_t)n_Vox_Fllow_Chg->Vox_PTM_Type,(uint16_t)g_Vbat_Adc,(uint16_t)g_pmu_Adc_Vout,(uint16_t)__LINE__);
#endif
DisCharge_Boost_Open(n_Vox_Fllow_Chg->Vox_PTM_Type, n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present );
}
}
else
{
/* PMID > PMID_THP且VOL和VOR的任意一支路电流超过阈值Ivol_THN > Ivol > Ivol_THP 或 Ivor_THN > Ivor > Ivor_THP。*/
if( ( n_Vox_Fllow_Chg->Vpmid_AddSta[VOR_TYPE] == ON ) || ( n_Vox_Fllow_Chg->Vpmid_AddSta[VOL_TYPE] == ON ) )
{
n_Vox_Fllow_Chg->Vpmid_AddSta[VOR_TYPE] = OFF;
n_Vox_Fllow_Chg->Vpmid_AddSta[VOL_TYPE] = OFF;
if( n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present < VOUT_MAX_THD )
{
n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present = n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present + VOX_FOLLOW_CHG_PMID_UP_STEPS;
}
Follow_Chg_Sta = Vox_Follow_Chg_Sta4; //当有需要升压Vpmid则需要重回Sta4。
/* 当VPMID 上升到上限阈值则说明本轮跟随充调整结束则重回StaInit。 */
if( n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present >= n_Vox_Fllow_Chg->Vpmid_Threshold_Pos )
{
n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present = n_Vox_Fllow_Chg->Vpmid_Threshold_Pos;
Follow_Chg_Sta = Vox_Follow_Chg_Sta1;
}
#ifdef _DEBUG_FOLLOW
printf("Follow CHG AddSta,(STA:0x%x,Vpmid:0x%x)(line:%d)\r\n",(uint16_t)Follow_Chg_Sta,(uint16_t)n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present,(uint16_t)__LINE__);
#endif
DisCharge_Boost_Open(OFF, n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present);
}
}
}
else
{
if( Follow_Chg_Sta > Vox_Follow_Chg_Sta2 )
{
Follow_Chg_Sta = Vox_Follow_Chg_InitSta;
n_Vox_Fllow_Chg->Vox_Follow_Stop = ON;
}
}
}
#endif
#endif