/* ****************************************************************************** * * @file VOX_Module.c * @brief VOL/R module * @ic sy8835 * * @version 1.0 * @date 2024/11/01 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/11/01 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 "sys_tim.h" #include "adc.h" #include "userapp.h" bit Vox_Vout_Enable = OFF; //Vox功率输出标志位 bit Earphone_Chg_Flag = 0; //耳机出入盒标志位 bit Boost_Open_Flag = 0; uint8_t Vox_Type = 0xFF; bit Vox_Output_Short_Flag = 0; #if VOX_ENABLE /******************************************************************************\ Macro definitions \******************************************************************************/ /*100ms调用周期*/ #define VOX_OUTPUT_SHORT_CNT 2 #define VOX_LOW_BAT_CNT 25 //关盖前,盒子低电保护,Vox 5V持续2.5s #define VOX_VOUT_5V_LEAST_CNT 50 #define VOX_VOUT_5V_DEBOUNCE 5 #define VOX_VOUT_0V_DEBOUNCE 5 #define VOX_ADT_HOLD_CNT 3 #define Vox_TX_Pattern_Cnt 3 #define VOX_VOLTAGE_HOLD_CNT 3 #define BOOST_VOUT_MAX 2 //跟随充Boost输出电压上限值:0:4.6V,1:4.7V,2:4.8V,3:5.05V. #define Vox_TX_Pattern_Tim 11 #define Vox_TX_Interval 2 //Vox定时发送指令时间间隔 #define Vox_TX_Interval_2 3 #define VOX_IOFF_HOLD_CNT 50 #define VOX_FOLLOW_CHG_CNT 10 #define VOX_CLOSE_HOLD_CNT 50 //关盖发码前保持时间 #if VOX_FOLLOW_CHG #define VOX_FOLLOW_CHG_INIT_CNT 3 #define VOX_FOLLOW_CHG_NOWCURCHK_CNT 5 #define VOX_FOLLOW_CHG_VOLTAGE_ADJUST_CNT 2 //PMID调压周期 #define VOX_FOLLOW_CHG_PMID_UP_CNT 20 //PMID上升调节周期(2s) #define VOX_FOLLOW_CHG_PMID_UP_STEPS 2 //PMID上升调节档位数。 #define VOX_FOLLOW_CHG_PMID_DOWN_STEPS 2 //PMID下降调节档位数。 #define VPMID_MAX_THD 0x3C #define VPMID_MIN_THD 0x00 #define VOX_CV_TC_CURRENT 20 //耳机充电处于CV/TC阶段的电流值,单位mA。 #endif /******************************************************************************\ Variables definitions \******************************************************************************/ #if VOX_FOLLOW_CHG xdata uint16_t Vox_Follow_Chg_Debounce = 0; g_Vox_Fllow_Chg_Cfg xdata Vox_Fllow_Chg; e_Vox_Follow_Chg_Sta Follow_Chg_Sta; #endif #ifdef VOX_RX xdata uint8_t Vox_Get_Vbat_Flag[2] = {0}; //耳机配对状态,VOL:低4bit;VOR:高4bit。0是无效,1是正在配对,2是配对成功,3不处理,保持当前状态。 xdata uint8_t Vox_Get_BES_Addr_Flag[2] = {0}; //idata uint8_t BES_Addr[6] = {0}; //蓝牙耳机地址,Vox_Bes_Addr[0][6]:VOL;Vox_Bes_Addr[1][6]:VOR #endif xdata uint8_t Earphone_Vbat[2] = 0; //对耳电量 xdata uint8_t Vox_Online_State[2] = {0}; //耳机在线标志位 #define KEY_TWS_PAIR_TIMER 2 #define KEY_TWS_PAIR_CNT 6 #define KEY_TWS_PAIR_CLEAR_CNT 30 /******************************************************************************\ Functions definitions \******************************************************************************/ #if 0 /* ******************************************************************************* * uint8_t VOL_EN_Type(VOL_Enable_Type_e VOL_Enable_Type) * * Description : VOL Open(EN_VO) * 使能信号优先级 * EN_TRAN EN_COM EN_VO EN_ADT PD1K VOX_STATE * 1 X X X X TRAN * 0 1 X X X COMM * 0 0 1 X X 5V * 0 0 0 1 X LOAD DET * 0 0 0 0 1 PD1K * 0 0 0 0 0 HIZ * Arguments : * Returns : * Notes : * ******************************************************************************* */ void VOL_EN_Type(VOX_Enable_Mode_e VOL_Enable_Mode) { uint8_t Bst_VOX_Comm_EN = 0; uint8_t VOX_Confg = 0; Bst_VOX_Comm_EN = I2cSfr_Read( BST_COMM_EN ); VOX_Confg = I2cSfr_Read( VOX_CFG ); switch(VOL_Enable_Mode) { case VOX_TRANS_Mode: //关闭自动识别负载的上拉电阻。 break; case VOX_COMM_Mode_Uart: VOX_Confg |= VOX_CFG_Comx_Rup_10K |VOX_CFG_Vox_Rup_10K | VOX_CFG_Vox_Vup_1_8V; Bst_VOX_Comm_EN |= BST_COMM_EN_Vol_Comm_En; break; case VOX_COMM_Mode_Reg: break; case VOX_VOUT_Mode: //Vox的通讯功能优先级比Vout 5V高。 Bst_VOX_Comm_EN |= BST_COMM_EN_Vol_En; Bst_VOX_Comm_EN &= ~BST_COMM_EN_Vol_Comm_En; break; case VOX_ADT_Mode: VOX_Confg &= ~VOX_CFG_Vox_DisAdt; //开启ADT模式 Bst_VOX_Comm_EN &= ~( BST_COMM_EN_Vol_Comm_En | BST_COMM_EN_Vol_En ); break; case VOX_PD1K_Mode: VOX_Confg |= VOX_CFG_Vox_DisAdt; VOX_Confg &= ~VOX_CFG_Vox_Floating; //Vox通过1K电阻下拉到GND Bst_VOX_Comm_EN &= ~( BST_COMM_EN_Vol_Comm_En | BST_COMM_EN_Vol_En ); break; default: break; } I2cSfr_Write( BST_COMM_EN, Bst_VOX_Comm_EN ); I2cSfr_Write( VOX_CFG, VOX_Confg ); } /* ******************************************************************************* * void VOR_EN_Type(VOR_Enable_Type_e VOR_Enable_Type) * * Description : VOL Open(EN_VO) * 使能信号优先级 * EN_TRAN EN_COM EN_VO EN_ADT PD1K VOX_STATE * 1 X X X X TRAN * 0 1 X X X COMM * 0 0 1 X X 5V * 0 0 0 1 X LOAD DET * 0 0 0 0 1 PD1K * 0 0 0 0 0 HIZ * Arguments : * Returns : * Notes : * ******************************************************************************* */ void VOR_EN_Type(VOX_Enable_Mode_e VOR_Enable_Mode) { uint8_t Bst_VOX_Comm_EN = 0; uint8_t VOX_Confg = 0; Bst_VOX_Comm_EN = I2cSfr_Read( BST_COMM_EN ); VOX_Confg = I2cSfr_Read( VOX_CFG ); switch(VOR_Enable_Mode) { case VOX_TRANS_Mode: //关闭自动识别负载的上拉电阻。 break; case VOX_COMM_Mode_Uart: VOX_Confg |= VOX_CFG_Comx_Rup_10K |VOX_CFG_Vox_Rup_10K | VOX_CFG_Vox_Vup_1_8V; Bst_VOX_Comm_EN |= BST_COMM_EN_Vor_Comm_En; break; case VOX_COMM_Mode_Reg: break; case VOX_VOUT_Mode: //Vox的通讯功能优先级比Vout 5V高。 Bst_VOX_Comm_EN |= BST_COMM_EN_Vor_En; Bst_VOX_Comm_EN &= ~BST_COMM_EN_Vor_Comm_En; break; case VOX_ADT_Mode: VOX_Confg &= ~VOX_CFG_Vox_DisAdt; //开启ADT模式 Bst_VOX_Comm_EN &= ~( BST_COMM_EN_Vor_Comm_En | BST_COMM_EN_Vor_En ); break; case VOX_PD1K_Mode: VOX_Confg |= VOX_CFG_Vox_DisAdt; VOX_Confg &= ~VOX_CFG_Vox_Floating; //Vox通过1K电阻下拉到GND Bst_VOX_Comm_EN &= ~( BST_COMM_EN_Vor_Comm_En | BST_COMM_EN_Vor_En ); break; default: break; } I2cSfr_Write( BST_COMM_EN, Bst_VOX_Comm_EN ); I2cSfr_Write( VOX_CFG, VOX_Confg ); } #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) { uint8_t Bst_VOX_Comm_EN = 0; uint8_t VOX_Confg = 0; Bst_VOX_Comm_EN = I2cSfr_Read( BST_COMM_EN ); VOX_Confg = I2cSfr_Read( VOX_CFG ); switch(VOX_Enable_Mode) { case VOX_TRANS_Mode: //关闭自动识别负载的上拉电阻。 break; case VOX_COMM_Mode_Uart: VOX_Confg |= VOX_CFG_Comx_Rup_2K |VOX_CFG_Vox_Rup_2K | VOX_CFG_Vox_Vup_VOXS; Bst_VOX_Comm_EN |= BST_COMM_EN_Gate_Ctrl | ( BST_COMM_EN_Vor_Comm_En | BST_COMM_EN_Vol_Comm_En ); break; case VOX_COMM_Mode_Reg: break; case VOX_VOUT_Mode: //Vox的通讯功能优先级比Vout 5V高。 Bst_VOX_Comm_EN |= ( BST_COMM_EN_Vor_En | BST_COMM_EN_Vol_En ); Bst_VOX_Comm_EN &= ~( BST_COMM_EN_Vor_Comm_En | BST_COMM_EN_Vol_Comm_En ); break; case VOX_ADT_Mode: VOX_Confg &= ~VOX_CFG_Vox_DisAdt; //开启ADT模式 Bst_VOX_Comm_EN &= ~( BST_COMM_EN_Vor_Comm_En | BST_COMM_EN_Vor_En | BST_COMM_EN_Vol_Comm_En | BST_COMM_EN_Vol_En ); break; case VOX_PD1K_Mode: VOX_Confg |= VOX_CFG_Vox_DisAdt; VOX_Confg &= ~VOX_CFG_Vox_Floating; //Vox通过1K电阻下拉到GND Bst_VOX_Comm_EN &= ~( BST_COMM_EN_Vor_Comm_En | BST_COMM_EN_Vor_En | BST_COMM_EN_Vol_Comm_En | BST_COMM_EN_Vol_En ); break; default: break; } I2cSfr_Write( BST_COMM_EN, Bst_VOX_Comm_EN ); I2cSfr_Write( VOX_CFG, VOX_Confg ); } #endif /* ******************************************************************************* * 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_Flag1; static bit Cover_Close_Flag; static bit Cover_Open_Flag; static bit TX_Cmd_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; /*Vox 过流保护,两只耳机都每隔200ms打嗝一次*/ if( pmu_Info.pmu_Fault_STA2 & ( Fault_Sta2_VorOCP | Fault_Sta2_VolOCP ) ) { Vox_Output_Short_Flag = 1; return; } Vox_Output_Short_Flag = 0; if( gBoost_Prepared_Flag ) { if( CoverEvent_Flg ) //Hall事件触发。 { if( !Boost_Open_Flag ) { Set_PMU_Boost_Vout(BOOST_VPMID_5_2V); //开关盖Boost输出5.2V,保证耳机一定能被唤醒。 Set_PMU_Boost(ON); //Boost Enable;异常时由硬件主动关闭。开启Boost,开启Vox 5v会在开启Boost之后(100ms延时)。 Boost_Open_Flag = 1; 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_Flag1 = 0; if( CoverStatus == CLOSE ) //1、关盖关闭COM_CTRL;显示灯效。(无需查询Loadon、IOFF状态,无论耳机是否在仓,Vox 5V输出。) { Earphone_Chg_Flag = 0; //关盖取消耳机入盒灯效,显示关盖灯效。 Cover_Close_Flag = 1; Cover_Open_Flag = 0; Vox_Chg_Full_Flag = 0; Vox_Getinto_Sleep_Flag = 0; Vox_Chn_Select = 0; Vox_Get_BES_Addr_Flag[VOL_TYPE] = 0x00; Vox_Get_BES_Addr_Flag[VOR_TYPE] = 0x00; Vox_Vout_Enable = ON; Wkup_Earphone_Flag = 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("Box Close.\r\n"); #endif } else //2、开盖处理:5v 500ms 转0V 500ms,后转ADT模式。 { Cover_Close_Flag = 0; Cover_Open_Flag = 1; Cover_Open_5V_Flag = 0; #ifdef _DEBUG_VOX printf("Box Open.\r\n"); #endif } CoverEvent_Flg = 0; } /* 发送开盖指令*/ if( Cover_Open_Flag ) /*开盖后,5V持续N00ms后0V持续N00ms,保证耳机能被唤醒;之后发开盖码。*/ { if( Vox_Voltage_Hold_Timer < VOX_VOUT_5V_DEBOUNCE ) //开盖后5V N00ms。 { Vox_Voltage_Hold_Timer++; return; } if( Vox_TX_Timer < VOX_VOUT_0V_DEBOUNCE ) //转0V N00ms { VOX_EN_Type(VOX_PD1K_Mode); Vox_TX_Timer++; } else { if( !Get_CHIP_STA1_Flag1 ) { if( Vox_Output_Debounce <= Vox_TX_Pattern_Tim ) { if( ( Vox_Output_Debounce % Vox_TX_Interval_2 ) == 0 ) //200ms发送一次 { #ifdef VOX_TX HandleTxCommand(VHOUSE_CMD_OPEN_BOX,VOL_CHAN); //左耳发开盖指令,区分耳机通道。 #endif } else if( ( Vox_Output_Debounce % Vox_TX_Interval ) == 0 ) //200ms发送一次 { #ifdef VOX_TX HandleTxCommand(VHOUSE_CMD_OPEN_BOX,VOR_CHAN); //右耳发开盖指令,区分耳机通道。 #endif } Vox_Output_Debounce++; } else { VOX_EN_Type(VOX_ADT_Mode); Vox_Output_Debounce = 0; Get_CHIP_STA1_Flag1 = 1; TX_Cmd_Flag = 1; Boost_Open_Flag = 0; Vox_Vout_Enable = OFF; #ifdef _DEBUG_VOX printf("Open Box CMD TX Over.\r\n"); #endif } } else { if( TX_Cmd_Flag ) { TX_Cmd_Flag = 0; CHIP_STA1_BK = pmu_Info.pmu_VOX_STA & ( VOR_LoadOn | VOL_LoadOn ); } else { /*耳机出入盒判断*/ if( CHIP_STA1_BK != ( pmu_Info.pmu_VOX_STA & ( VOR_LoadOn | VOL_LoadOn ) ) ) //查询耳机loadon状态,loadon状态改变,则说明有耳机出入盒。 { if( pmu_Info.pmu_VOX_STA & ( VOR_LoadOn | VOL_LoadOn ) ) { Earphone_Chg_Flag = 1; #ifdef LED_DISPLAY LED_On_Flag = 1; #endif #ifdef _DEBUG_VOX printf("Open Box And Earphone GetIn.\r\n"); #endif } CHIP_STA1_BK = ( pmu_Info.pmu_VOX_STA & ( VOR_LoadOn | VOL_LoadOn ) ); } } } } } if( Cover_Close_Flag ) { if( Wkup_Earphone_Flag ) //保护、断充电后,VOX需自动升压唤醒耳机。 { if( !Boost_Open_Flag ) { Set_PMU_Boost(ON); //Boost Enable;异常时由硬件主动关闭。开启Boost,开启Vox 5v会在开启Boost之后(100ms延时)。 Boost_Open_Flag = 1; 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_TX_Timer = 0; Vox_Voltage_Hold_Timer = 0; Vox_Output_Debounce = 0; Vox_Chg_Full_Flag = 0; return; } VOX_EN_Type(VOX_VOUT_Mode); //VOX Enable 5V #ifdef _DEBUG_VOX printf("Close Box And Force Voltage Up.\r\n"); #endif Wkup_Earphone_Flag = 0; } else { if( Vox_Voltage_Hold_Timer <= VOX_VOLTAGE_HOLD_CNT ) //关盖Boost VPMID保持时间。 { Vox_Voltage_Hold_Timer++; return; } if( Vox_TX_Timer <= Vox_TX_Pattern_Tim ) //发送关盖指令。 { if( (Vox_TX_Timer % Vox_TX_Interval_2) == 0 ) //200ms发送一次 { #ifdef VOX_TX HandleTxCommand(VHOUSE_CMD_CLOSE_BOX,VOL_CHAN); //左耳发开盖指令,区分耳机通道。 #endif } else if( (Vox_TX_Timer % Vox_TX_Interval) == 0 ) //200ms发送一次 { #ifdef VOX_TX HandleTxCommand(VHOUSE_CMD_CLOSE_BOX,VOR_CHAN); //右耳发开盖指令,区分耳机通道。 #endif } Vox_TX_Timer++; return; } } if( Vox_Output_Debounce <= VOX_CLOSE_HOLD_CNT ) //关盖后5s发送获取电量命令。 { if( (Vox_Output_Debounce % Vox_TX_Interval_2) == 0 ) //200ms发送一次 { #ifdef VOX_TX HandleTxCommand(VHOUSE_CMD_CLOSE_WIN_GET_VBAT,VOL_CHAN); //左耳发开盖指令,区分耳机通道。 #endif } else if( (Vox_Output_Debounce % Vox_TX_Interval) == 0 ) //200ms发送一次 { #ifdef VOX_TX HandleTxCommand(VHOUSE_CMD_CLOSE_WIN_GET_VBAT,VOR_CHAN); //右耳发开盖指令,区分耳机通道。 #endif } Vox_Output_Debounce++; return; } #if VOX_FOLLOW_CHG if ( Vox_Fllow_Chg.Vox_Follow_Stop == OFF ) { Vox_Follow_Chg( &Vox_Fllow_Chg ); //跟随充处理。 } else #endif { if( !Vox_Chg_Full_Flag ) { if( ( (pmu_Info.pmu_VOX_STA & ( VOR_Ioff | VOL_Ioff ) ) == ( VOR_Ioff | VOL_Ioff ) )|| !(pmu_Info.pmu_VOX_STA & ( VOL_LoadOn | VOR_LoadOn ) ) || F_batlevel_low ) //耳机充满、VOX无负载、盒子低电,则关闭Vout输出通路,关闭Boost。 { if( Vox_Voltage_Hold_Timer < VOX_VOUT_5V_LEAST_CNT ) //重载转轻载延时5s后关闭Boost输出。 { Vox_Voltage_Hold_Timer++; return; } #ifdef _DEBUG_VOX printf("VOX CHG Full.\r\n"); #endif Vox_Chg_Full_Flag = 1; Boost_Open_Flag = 0; VOX_EN_Type(VOX_ADT_Mode); //VOX Enable ADT } } else { if( Vox_Output_Debounce <= Vox_TX_Pattern_Tim ) { if( (Vox_Output_Debounce % Vox_TX_Interval_2) == 0 ) //200ms发送一次 { #ifdef VOX_TX HandleTxCommand(VHOUSE_CMD_PWROFF,VOL_CHAN); //左耳发开盖指令,区分耳机通道。 #endif } else if( (Vox_Output_Debounce % Vox_TX_Interval) == 0 ) //200ms发送一次 { #ifdef VOX_TX HandleTxCommand(VHOUSE_CMD_PWROFF,VOR_CHAN); //右耳发开盖指令,区分耳机通道。 #endif } Vox_Output_Debounce++; } else { if( !Vox_Getinto_Sleep_Flag ) { Vox_Getinto_Sleep_Flag = 1; 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 = 0; } else { if( !Bat_Low_Pro_Flag ) //低电保护后,VOX开启ADT模式。判断耳机出入盒,并显示相应的灯效。 { Bat_Low_Pro_Flag = 1; VOX_EN_Type(VOX_ADT_Mode); Vox_Vout_Enable = OFF; CHIP_STA1_BK = pmu_Info.pmu_VOX_STA & ( VOR_LoadOn | VOL_LoadOn ); return; } /*耳机出入盒判断*/ if( CHIP_STA1_BK != ( pmu_Info.pmu_VOX_STA & ( VOR_LoadOn | VOL_LoadOn ) ) ) //查询耳机loadon状态,loadon状态改变,则说明有耳机出入盒。 { if( pmu_Info.pmu_VOX_STA & ( VOR_LoadOn | VOL_LoadOn ) ) { Earphone_Chg_Flag = 1; #ifdef LED_DISPLAY LED_On_Flag = 1; #endif } CHIP_STA1_BK = ( pmu_Info.pmu_VOX_STA & ( VOR_LoadOn | VOL_LoadOn ) ); } } } #if VOX_FOLLOW_CHG /* ******************************************************************************* * void Vox_Follow_Chg( g_Vox_Fllow_Chg_Cfg *g_Vox_Fllow_Chg ) * * Description : Vox 跟随充处理函数。 (40ms调用周期) * * Arguments : NONE * Returns : NONE * Notes : NONE * ******************************************************************************* */ void Vox_Follow_Chg( g_Vox_Fllow_Chg_Cfg *n_Vox_Fllow_Chg ) { static bit nVpmid_Value_Setting; #ifdef _DEBUG_VOX //printf("Follow CHG Sta:0x%x.(Vox_sta:0x%x)(line:%d)\r\n",(u16)Follow_Chg_Sta,(u16)pmu_Info.pmu_VOX_STA, (u16)__LINE__); #endif 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_Chg_Debounce <= VOX_FOLLOW_CHG_INIT_CNT ) { Vox_Follow_Chg_Debounce++; n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present = BOOST_VPMID_5_2V; if( !nVpmid_Value_Setting ) { Set_PMU_Boost_Vout(n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present); #ifdef _DEBUG_VOX printf("Follow CHG InitSta Set Max Vpmid.(Vox_sta:0x%x)(line:%d)\r\n",(u16)pmu_Info.pmu_VOX_STA, (u16)__LINE__); #endif nVpmid_Value_Setting = 1; } } else { Vox_Follow_Chg_Debounce = 0; nVpmid_Value_Setting = 0; n_Vox_Fllow_Chg->Vpmid_AddSta[VOR_CHAN] = OFF; n_Vox_Fllow_Chg->Vpmid_AddSta[VOL_CHAN] = OFF; n_Vox_Fllow_Chg->Vpmid_SubSta[VOR_CHAN] = OFF; n_Vox_Fllow_Chg->Vpmid_SubSta[VOL_CHAN] = OFF; n_Vox_Fllow_Chg->IVox_TC_Mode[VOR_CHAN] = OFF; n_Vox_Fllow_Chg->IVox_TC_Mode[VOL_CHAN] = OFF; n_Vox_Fllow_Chg->Vox_InBox_Sta[VOR_CHAN] = OFF; n_Vox_Fllow_Chg->Vox_InBox_Sta[VOL_CHAN] = OFF; n_Vox_Fllow_Chg->Vpmid_Threshold_Neg = VPMID_MIN_THD; n_Vox_Fllow_Chg->Vpmid_Threshold_Pos = VPMID_MAX_THD; Follow_Chg_Sta = Vox_Follow_Chg_Sta1; #ifdef _DEBUG_VOX printf("Follow CHG InitSta.(Vox_sta:0x%x)(line:%d)\r\n",(u16)pmu_Info.pmu_VOX_STA, (u16)__LINE__); #endif } } break; case Vox_Follow_Chg_Sta1: //STA1:获取耳机当前抽电电流和设置Vox上下限电流阈值。 if ( ( pmu_Info.pmu_VOX_STA & VOR_Ioff ) && ( pmu_Info.pmu_VOX_STA & VOL_Ioff ) ) //VOL、VOR耳机无抽电,则说明耳机已充满,无需再继续跟随充。 { n_Vox_Fllow_Chg->Vox_Follow_Stop = ON; Follow_Chg_Sta = Vox_Follow_Chg_InitSta; #ifdef _DEBUG_VOX printf("Follow CHG Sta1,No EarPhone In Box.(line:%d)\r\n",(u16)__LINE__); #endif } else { /*获取当前Ivox。Vox开启功率,且Ioff处于重载状态。*/ if( !(pmu_Info.pmu_VOX_STA & VOR_Ioff) ) { n_Vox_Fllow_Chg->IVox_Init[VOR_CHAN] = g_pmu_Adc_Ivor; n_Vox_Fllow_Chg->IVox_Threshold_Neg[VOR_CHAN] = ( g_pmu_Adc_Ivor / 5 ) << 2; //Ivox_Threshold_Neg = IVox_Init * 80% n_Vox_Fllow_Chg->IVox_Threshold_Pos[VOR_CHAN] = g_pmu_Adc_Ivor << 1; //Ivox_Threshold_Neg = IVox_Init * 2 #ifdef _DEBUG_VOX printf("Follow CHG Sta1,VOR Chging(Ivor:%d).(line:%d)\r\n",g_pmu_Adc_Ivor,(u16)__LINE__); #endif } if( !(pmu_Info.pmu_VOX_STA & VOL_Ioff) ) { n_Vox_Fllow_Chg->IVox_Init[VOL_CHAN] = g_pmu_Adc_Ivol; n_Vox_Fllow_Chg->IVox_Threshold_Neg[VOL_CHAN] = ( g_pmu_Adc_Ivol / 5 ) << 2; //Ivox_Threshold_Neg = IVox_Init * 80% n_Vox_Fllow_Chg->IVox_Threshold_Pos[VOL_CHAN] = g_pmu_Adc_Ivol << 1; //Ivox_Threshold_Neg = IVox_Init * 2 #ifdef _DEBUG_VOX printf("Follow CHG Sta1,VOL Chging(Ivol:%d).(line:%d)\r\n",g_pmu_Adc_Ivol,(u16)__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 ( !(pmu_Info.pmu_VOX_STA & VOR_Ioff) ) { n_Vox_Fllow_Chg->IVox_At_Present[VOR_CHAN] = g_pmu_Adc_Ivor; n_Vox_Fllow_Chg->Vox_InBox_Sta[VOR_CHAN] = ON; //判断VOR有耳机在盒正常抽电 #ifdef _DEBUG_VOX printf("Follow CHG Sta2,Get IVOR.(line:%d)\r\n",(u16)__LINE__); #endif } if ( !(pmu_Info.pmu_VOX_STA & VOL_Ioff) ) { n_Vox_Fllow_Chg->IVox_At_Present[VOL_CHAN] = g_pmu_Adc_Ivol; n_Vox_Fllow_Chg->Vox_InBox_Sta[VOL_CHAN] = ON; //判断VOL有耳机在盒正常抽电 #ifdef _DEBUG_VOX printf("Follow CHG Sta2,Get IVOL.(line:%d)\r\n",(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_CHAN] > n_Vox_Fllow_Chg->IVox_Threshold_Pos[VOR_CHAN] ) || \ ( n_Vox_Fllow_Chg->IVox_At_Present[VOL_CHAN] > n_Vox_Fllow_Chg->IVox_Threshold_Pos[VOL_CHAN] ) ) //当前电流大于THP阈值电流,则说明耳机状态发生改变(TC跳转到CC或Recharge复充),需要重启跟随充。 { Follow_Chg_Sta = Vox_Follow_Chg_InitSta; n_Vox_Fllow_Chg->Vox_Follow_Start = OFF; //重启动跟随充 #ifdef _DEBUG_VOX printf("Follow CHG Sta3,VOX Chg ReInit.(line:%d)\r\n",(u16)__LINE__); #endif } else { if ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOR_CHAN] == ON ) { if ( n_Vox_Fllow_Chg->IVox_At_Present[VOR_CHAN] <= VOX_CV_TC_CURRENT ) //检测到Ivor小于CV/TC电流阈值,则说明耳机进入CV/TC阶段 { if ( pmu_Info.pmu_VOX_STA & VOR_Ioff ) //检测到Ivor Ioff,则VPMID升档。 { n_Vox_Fllow_Chg->Vpmid_AddSta[VOR_CHAN] = ON; n_Vox_Fllow_Chg->Vox_InBox_Sta[VOR_CHAN] = OFF; #ifdef _DEBUG_VOX printf("Follow CHG Sta3(CV),VOR Vpmid AddSta.(line:%d)\r\n",(u16)__LINE__); #endif } else //未检测到Ivor Ioff,则Vpmid降档 { n_Vox_Fllow_Chg->Vpmid_SubSta[VOR_CHAN] = ON; #ifdef _DEBUG_VOX printf("Follow CHG Sta3(CV),VOR Vpmid SubSta.(line:%d)\r\n",(u16)__LINE__); #endif } } else { if ( n_Vox_Fllow_Chg->IVox_At_Present[VOR_CHAN] > n_Vox_Fllow_Chg->IVox_Threshold_Neg[VOR_CHAN] ) { n_Vox_Fllow_Chg->Vpmid_SubSta[VOR_CHAN] = ON; #ifdef _DEBUG_VOX printf("Follow CHG Sta3(CC),VOR Vpmid SubSta.(line:%d)\r\n",(u16)__LINE__); #endif } else { n_Vox_Fllow_Chg->Vpmid_AddSta[VOR_CHAN] = ON; #ifdef _DEBUG_VOX printf("Follow CHG Sta3(CC),VOR Vpmid AddSta.(line:%d)\r\n",(u16)__LINE__); #endif } } } if ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOL_CHAN] == ON ) { if ( n_Vox_Fllow_Chg->IVox_At_Present[VOL_CHAN] <= VOX_CV_TC_CURRENT ) //检测到Ivol小于CV/TC电流阈值,则说明耳机进入CV/TC阶段 { if ( pmu_Info.pmu_VOX_STA & VOL_Ioff ) //检测到Ivol Ioff,则VPMID升档。 { n_Vox_Fllow_Chg->Vpmid_AddSta[VOL_CHAN] = ON; n_Vox_Fllow_Chg->Vox_InBox_Sta[VOL_CHAN] = OFF; #ifdef _DEBUG_VOX printf("Follow CHG Sta3(CV),VOL Vpmid AddSta.(line:%d)\r\n",(u16)__LINE__); #endif } else //未检测到Ivol Ioff,则Vpmid降档 { n_Vox_Fllow_Chg->Vpmid_SubSta[VOL_CHAN] = ON; #ifdef _DEBUG_VOX printf("Follow CHG Sta3(CV),VOL Vpmid SubSta.(line:%d)\r\n",(u16)__LINE__); #endif } } else { if ( n_Vox_Fllow_Chg->IVox_At_Present[VOL_CHAN] > n_Vox_Fllow_Chg->IVox_Threshold_Neg[VOL_CHAN] ) { n_Vox_Fllow_Chg->Vpmid_SubSta[VOL_CHAN] = ON; #ifdef _DEBUG_VOX printf("Follow CHG Sta3(CC),VOL Vpmid SubSta.(line:%d)\r\n",(u16)__LINE__); #endif } else { n_Vox_Fllow_Chg->Vpmid_AddSta[VOL_CHAN] = ON; #ifdef _DEBUG_VOX printf("Follow CHG Sta3(CC),VOL Vpmid AddSta.(line:%d)\r\n",(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_CHAN] = g_pmu_Adc_Ivor; n_Vox_Fllow_Chg->IVox_At_Present[VOL_CHAN] = g_pmu_Adc_Ivol; } else { Vox_Follow_Chg_Debounce = 0; if ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOR_CHAN] == ON ) { /* 当检测到 IVOX < IVOX_THN or IVOX > IVOX_THP,则PMID 升高一个step(或N个step,根据实际测试设定。) */ if ( ( n_Vox_Fllow_Chg->IVox_At_Present[VOR_CHAN] < n_Vox_Fllow_Chg->IVox_Threshold_Neg[VOR_CHAN] ) || \ ( n_Vox_Fllow_Chg->IVox_At_Present[VOR_CHAN] > n_Vox_Fllow_Chg->IVox_Threshold_Pos[VOR_CHAN] ) ) { n_Vox_Fllow_Chg->Vpmid_AddSta[VOR_CHAN] = ON; Follow_Chg_Sta = Vox_Follow_Chg_Sta2; #ifdef _DEBUG_VOX printf("Follow CHG Sta4,VOR Vpmid AddSta(line:%d).\r\n",(u16)__LINE__); #endif } #ifdef _DEBUG_VOX else { printf("Follow CHG Sta4,VOR Ching(line:%d).\r\n",(u16)__LINE__); } #endif } if ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOL_CHAN] == ON ) { if ( ( n_Vox_Fllow_Chg->IVox_At_Present[VOL_CHAN] > n_Vox_Fllow_Chg->IVox_Threshold_Pos[VOL_CHAN] ) || \ ( n_Vox_Fllow_Chg->IVox_At_Present[VOL_CHAN] < n_Vox_Fllow_Chg->IVox_Threshold_Neg[VOL_CHAN] ) ) { n_Vox_Fllow_Chg->Vpmid_AddSta[VOL_CHAN] = ON; Follow_Chg_Sta = Vox_Follow_Chg_Sta2; #ifdef _DEBUG_VOX printf("Follow CHG Sta4,VOL Vpmid AddSta(line:%d).\r\n",(u16)__LINE__); #endif } #ifdef _DEBUG_VOX else { printf("Follow CHG Sta4,VOL Ching(line:%d).\r\n",(u16)__LINE__); } #endif } } break; default: break; } if( ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOR_CHAN] == ON ) || ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOL_CHAN] == ON ) ) { if( ( n_Vox_Fllow_Chg->Vpmid_SubSta[VOR_CHAN] == ON ) || ( n_Vox_Fllow_Chg->Vpmid_SubSta[VOL_CHAN] == ON ) ) //当需要降压Vpmid,则每降一次档位,都会充电至少2s。 { if( ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOR_CHAN] == ON ) && ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOL_CHAN] == ON ) ) { if( ( n_Vox_Fllow_Chg->Vpmid_SubSta[VOR_CHAN] == ON ) && ( n_Vox_Fllow_Chg->Vpmid_SubSta[VOR_CHAN] == ON ) ) { n_Vox_Fllow_Chg->Vpmid_SubSta_Flag = ON; #ifdef _DEBUG_VOX printf("Follow CHG SubSta,VOL/VOR(line:%d).\r\n",(u16)__LINE__); #endif } } if( ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOR_CHAN] == ON ) && ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOL_CHAN] == OFF ) ) { if( n_Vox_Fllow_Chg->Vpmid_SubSta[VOR_CHAN] == ON ) { n_Vox_Fllow_Chg->Vpmid_SubSta_Flag = ON; #ifdef _DEBUG_VOX printf("Follow CHG SubSta,VOR(line:%d).\r\n",(u16)__LINE__); #endif } } else if( ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOR_CHAN] == OFF ) && ( n_Vox_Fllow_Chg->Vox_InBox_Sta[VOL_CHAN] == ON ) ) { if( n_Vox_Fllow_Chg->Vpmid_SubSta[VOL_CHAN] == ON ) { n_Vox_Fllow_Chg->Vpmid_SubSta_Flag = ON; #ifdef _DEBUG_VOX printf("Follow CHG SubSta,VOL(line:%d).\r\n",(u16)__LINE__); #endif } } n_Vox_Fllow_Chg->Vpmid_SubSta[VOR_CHAN] = OFF; n_Vox_Fllow_Chg->Vpmid_SubSta[VOL_CHAN] = OFF; if ( n_Vox_Fllow_Chg->Vpmid_SubSta_Flag == ON ) { if( n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present > VPMID_MIN_THD ) { n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present = n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present - VOX_FOLLOW_CHG_PMID_DOWN_STEPS; } if( n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present <= n_Vox_Fllow_Chg->Vpmid_Threshold_Neg ) //当Vpmid降档到到下限阈值,则开始升压。 { n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present = n_Vox_Fllow_Chg->Vpmid_Threshold_Neg; Follow_Chg_Sta = Vox_Follow_Chg_Sta4; } else { Follow_Chg_Sta = Vox_Follow_Chg_Sta2; } Vox_Follow_Chg_Debounce = 0; n_Vox_Fllow_Chg->Vpmid_SubSta_Flag = OFF; #ifdef _DEBUG_VOX printf("Follow CHG SubSta,(STA:0x%x,Vpmid:0x%x)(line:%d)\r\n",(u16)Follow_Chg_Sta,(u16)n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present,(u16)__LINE__); #endif Set_PMU_Boost_Vout( 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_CHAN] == ON ) || ( n_Vox_Fllow_Chg->Vpmid_AddSta[VOL_CHAN] == ON ) ) { n_Vox_Fllow_Chg->Vpmid_AddSta[VOR_CHAN] = OFF; n_Vox_Fllow_Chg->Vpmid_AddSta[VOL_CHAN] = OFF; if( n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present < VPMID_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_InitSta; n_Vox_Fllow_Chg->Vox_Follow_Stop = ON; } #ifdef _DEBUG_VOX printf("Follow CHG AddSta,(STA:0x%x,Vpmid:0x%x)(line:%d)\r\n",(u16)Follow_Chg_Sta,(u16)n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present,(u16)__LINE__); #endif Set_PMU_Boost_Vout(n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present); } #if 0 else //当无需升压Vpmid,则重回Sta3。 { Follow_Chg_Sta = Vox_Follow_Chg_Sta3; } #endif } } #if 1 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 /* ******************************************************************************* * uint8_t Crc8Maxim(u8 *buf, u8 length) * * Description : 校验和的计算 * * * Arguments : u8 *buf: 数据存放地址 u8 length: 数据长度, 以byte为单位 * Returns : * * Notes : * ******************************************************************************* */ uint8_t Crc8Maxim(u8 *buf, u8 length) { u8 i; u8 crc = 0; while(length--) { crc ^= *buf++; for(i=0;i<8;i++) { if( crc&1 ) { crc = (crc >> 1)^0x8c; } else { crc >>= 1; } } } return crc; } #ifdef VOX_TX /* ******************************************************************************* * void HandleTxCommand(VOX_BES_COMMAND_E RxCommand, e_Vox_Chan nVox_Chn_Select) * * Description : 发送数据包的封装,并打开相应的双向通信通道 * Command payload * Header checksum side cmd len Data * 1bytes 1byte 1byte 1byte 1byte Len bytes * * Arguments : VOX_BES_COMMAND_E TxCommand: , e_Vox_Chan nVox_Chn_Select * Returns : * * Notes : * ******************************************************************************* */ idata uint8_t Net_Info[2][8] = {0}; idata uint8_t MAC_Addr[2][18] = {0}; uint8_t EarPhone_Num = 0; #define MAX_PACKET_SIZE 0x20 void HandleTxCommand(VOX_BES_COMMAND_E TxCommand, e_Vox_Chan nVox_Chn_Select) { uint8_t dataLen = 0; uint8_t tx_pData[COM0_Data_Lenth] = 0; uint8_t i = 0; /*数据包头*/ tx_pData[0] = 0x00; tx_pData[1] = BOXHEADER>>8; tx_pData[2] = BOXHEADER; /*指令编号*/ tx_pData[4] = TxCommand; Vox_Type = nVox_Chn_Select; switch(TxCommand) { case VHOUSE_CMD_PAIR: /*Data Length*/ tx_pData[3] = 0x02; if( nVox_Chn_Select == VOL_CHAN ) { tx_pData[5] = 0x02; Vox_Get_BES_Addr_Flag[VOL_TYPE] = 0; } else if( nVox_Chn_Select == VOR_CHAN ) { tx_pData[5] = 0x01; Vox_Get_BES_Addr_Flag[VOR_TYPE] = 0; } break; case VHOUSE_CMD_EXCH_TWS_BTADDR: /*Data Length*/ tx_pData[3] = 0x1B; for(i=5;i<18;i++) { tx_pData[i] = MAC_Addr[nVox_Chn_Select][i]; } for(i=23;i<8;i++) { tx_pData[i] = Net_Info[nVox_Chn_Select][i]; } break; case VHOUSE_CMD_CLEAR_PAIR: /*Data Length*/ tx_pData[3] = 0x02; tx_pData[5] = 0x03; break; case VHOUSE_CMD_CLOSE_WIN_GET_VBAT: //和开盖命令一样。 case VHOUSE_CMD_OPEN_BOX: //开盖获取电量命令 /*Data Length*/ tx_pData[3] = 0x05; tx_pData[5] = FW_VER; //Version tx_pData[6] = bat_level_Pec; //电仓电量值 0~100; tx_pData[7] = MAX_PACKET_SIZE; //max_packet_size:0x20 if( nVox_Chn_Select == VOL_CHAN ) { if( Earphone_Vbat[VOL_CHAN] == 0 ) { tx_pData[8] = 0xFF; } else { tx_pData[8] = Earphone_Vbat[VOR_CHAN]; } } else if( nVox_Chn_Select == VOR_CHAN ) { if( Earphone_Vbat[VOR_CHAN] == 0 ) { tx_pData[8] = 0xFF; } else { tx_pData[8] = Earphone_Vbat[VOL_CHAN]; } } break; case VHOUSE_CMD_PWROFF: /*Data Length*/ tx_pData[3] = 0x01; break; case VHOUSE_CMD_CLOSE_BOX: //关盖指令 /*Data Length*/ tx_pData[3] = 0x02; tx_pData[5] = EarPhone_Num; //耳机个数 break; default: break; } dataLen = 4 + tx_pData[3]; tx_pData[dataLen] = Crc8Maxim(tx_pData,dataLen); #if 0 /* vor、vol使用不同uart进行通讯 */ if(nVox_Chn_Select == VOL_CHAN) { VOL_EN_Type(VOX_COMM_Mode_Uart); #if UART1_ENABLE Uart1SendPacket(tx_pData[4] + 6, tx_pData); #endif VOL_EN_Type(VOX_VOUT_Mode); } else if(nVox_Chn_Select == VOR_CHAN) { VOR_EN_Type(VOX_COMM_Mode_Uart); #if UART0_ENABLE Uart0SendPacket(tx_pData[4] + 6, tx_pData); #endif VOR_EN_Type(VOX_VOUT_Mode); } #else /* vor、vol都使用uart0进行分时通讯。 */ VOX_EN_Type( VOX_COMM_Mode_Uart ); if(nVox_Chn_Select == VOL_CHAN) { SFRADDR = MFP_CTL0; //关闭VOR到UART0的开关,配置P02为GPIO,P03为UART0。 SFRDATA &=~ 0x0F; SFRDATA |= 0x08; } else if(nVox_Chn_Select == VOR_CHAN) { SFRADDR = MFP_CTL0; //关闭VOL到UART0的开关,配置P03为GPIO,P02为UART0。 SFRDATA &=~ 0x0F; SFRDATA |= 0x01; } #if UART0_ENABLE Uart0SendPacket(dataLen + 1, tx_pData); #endif VOX_EN_Type( VOX_VOUT_Mode ); #endif } #endif #ifdef VOX_RX /* ******************************************************************************* * void HandleRxCommand(VOX_BES_COMMAND_E RxCommand) * * Description : 耳机端发送的数据包的解析及处理 * Ack payload: * Header checksum side cmd len Data * 1bytes 1byte 1byte 1byte 1byte Len bytes * * Arguments : VOX_BES_COMMAND_E RxCommand: * Returns : * * Notes : * ******************************************************************************* */ void HandleRxMsg(VOX_BES_COMMAND_E RxCommand) { uint8_t i = 0; switch(RxCommand) { case VHOUSE_CMD_PAIR: for(i=0;i<18;i++) { MAC_Addr[Vox_Type][i] = RX0_Buffer[4+i]; } for(i=0;i<8;i++) { Net_Info[Vox_Type][i] = RX0_Buffer[22+i]; } if( Vox_Type == VOL_CHAN ) //根据耳机Side参数 { Vox_Get_BES_Addr_Flag[VOL_TYPE] = 1; //获取左耳机发的CMD3 } else { Vox_Get_BES_Addr_Flag[VOR_TYPE] = 1; //获取右耳机发的CMD3 } break; case VHOUSE_CMD_EXCH_TWS_BTADDR: break; case VHOUSE_CMD_OPEN_BOX: case VHOUSE_CMD_CLOSE_WIN_GET_VBAT: if( RX0_Buffer[4] == 0xE3 ) //根据耳机Side参数 { Vox_Get_Vbat_Flag[VOL_TYPE] = 1; //获取左耳机发的Vbat Earphone_Vbat[VOL_CHAN] = RX0_Buffer[5]; } else { Vox_Get_Vbat_Flag[VOR_TYPE] = 1; //获取右耳机发的Vbat Earphone_Vbat[VOR_CHAN] = RX0_Buffer[5]; } break; case VHOUSE_CMD_CLOSE_BOX: break; case VHOUSE_CMD_PWROFF: break; default: break; } } /* ******************************************************************************* * void HandleVoxCommMsg(void) * * Description : Vox 通讯功能处理函数,100ms定时调用。由于和耳机通信前需要打开耳机端的TRX功能,并且每次通信只能一只耳机。通过切换VOL/VOR通信开关进行通信 * * Arguments : NONE * Returns : NONE * Notes : NONE * ******************************************************************************* */ void HandleVoxCommMsg(void) { uint8_t CrcCheckSum = 0; uint8_t i = 0; /*RX数据处理*/ if( Uart0_RX_Finish_Flag ) { Uart0_RX_Finish_Flag = 0; CrcCheckSum = Crc8Maxim(RX0_Buffer, RX0_Buffer[2] + 3); //求校验和 if( CrcCheckSum == RX0_Buffer[RX0_Buffer[2] + 3] ) { HandleRxMsg((VOX_BES_COMMAND_E)RX0_Buffer[3]); } else { return; } } } #endif #endif