/* ****************************************************************************** * * @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 //关盖发码前保持时间 /******************************************************************************\ Variables definitions \******************************************************************************/ #if VOX_FOLLOW_CHG bit Vor_In_Box_Flag = 0; bit Vol_In_Box_Flag = 0; bit Boost_VoxVout_Follow_Flag = 0; int8 Boost_Vout_Value = 0; bit Boost_Up_Flag = 0; #endif #ifdef VOX_RX uint8_t Vox_Get_Vbat_Flag[2] = {0}; //耳机配对状态,VOL:低4bit;VOR:高4bit。0是无效,1是正在配对,2是配对成功,3不处理,保持当前状态。 idata 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 uint8_t Earphone_Vbat[2] = 0; //对耳电量 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; #if VOX_FOLLOW_CHG static bit Follow_Chg_Start_Flag; #endif 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; #if VOX_FOLLOW_CHG Follow_Chg_Start_Flag = 0; Boost_VoxVout_Follow_Flag = 0; #endif Vox_Chn_Select = 0; Vox_Get_BES_Addr_Flag[VOL_TYPE] = 0x00; Vox_Get_BES_Addr_Flag[VOR_TYPE] = 0x00; Vox_Vout_Enable = ON; } else //2、开盖处理:5v 500ms 转0V 500ms,后转ADT模式。 { Cover_Close_Flag = 0; Cover_Open_Flag = 1; Cover_Open_5V_Flag = 0; } 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; } } 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 } 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; 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 Wkup_Earphone_Flag = 0; } else { if( Vox_Voltage_Hold_Timer <= VOX_VOLTAGE_HOLD_CNT ) //关盖Boost VPMID保持时间。 { Vox_Voltage_Hold_Timer++; return; } #if 0 /* 关盖后,盒子里有耳机。则获取当前的Ivol和Ivor,作为本轮PMID电压调整的初始化电量Init_Ivol和Init_Ivor。 */ if( pmu_Info.pmu_VOX_STA & ( VOR_LoadOn | VOL_LoadOn ) ) { } #endif 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( !F_batlevel_low && !Follow_Chg_Start_Flag ) { //if( !Follow_Chg_Start_Flag ) { /*跟随充逻辑*/ if( !Boost_VoxVout_Follow_Flag ) { Boost_Vout_Value = 0x03; Boost_Up_Flag = 0; SFRADDR = VOX_CON0; //IOFF选择高电流档10/15/20/25mA SFRDATA |= 0x20; SFRADDR = VOX_CON2; SFRDATA &= ~0xC0; SFRDATA |= 0x80; //IOFF 20mA Boost_VoxVout_Follow_Flag = 1; } else { if( Vox_Voltage_Hold_Timer < VOX_FOLLOW_CHG_CNT ) //等耳机抽电。 { Vox_Voltage_Hold_Timer++; return; } Vox_Voltage_Hold_Timer = 0; if ( CHIP_STA1 & 0x0C ) //是否存在IOFF标志,存在,则Boost上升一个step,否则,Boost下降一个step。 { Boost_Vout_Value += 1; //Boost 输出上升一个step Boost_Up_Flag = 1; if( Boost_Vout_Value >= BOOST_VOUT_MAX ) //Boost输出达到电压上限值,则结束跟随充。 { Boost_Vout_Value = BOOST_VOUT_MAX; Boost_VoxVout_Follow_Flag = 0; Follow_Chg_Start_Flag = 1; SFRADDR = VOX_CON0; //IOFF选择低电流档2/3/4/5mA SFRDATA &= ~0x20; SFRADDR = VOX_CON2; SFRDATA &= ~0xC0; SFRDATA |= 0x40; //IOFF 3mA } } else { if( !Boost_Up_Flag ) //只在初始化找最低轻载电压时执行 { Boost_Vout_Value -= 1; //Boost 输出下降一个step if( Boost_Vout_Value <= 0 ) { Boost_Vout_Value = 0; } } } SFRADDR = OTP_KEY; SFRDATA = 0x69; SFRADDR = BST_CTL0; //Boost 输出 SFRDATA &= ~0x03; SFRDATA |= Boost_Vout_Value; SFRADDR = OTP_KEY; SFRDATA = 0x01; } } } #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 0 uint16_t Vox_Follow_Chg_Debounce = 0; #define VOX_FOLLOW_CHG_INIT_CNT 3 void Vox_Follow_Chg( e_Vox_Chan_Set Vox_Chn, e_Vox_Follow_Chg_Sta Follow_Chg_Sta ) { switch (Follow_Chg_Sta) { case Vox_Follow_Chg_InitSta: if( Vox_Follow_Chg_Debounce <= VOX_FOLLOW_CHG_INIT_CNT ) { Vox_Follow_Chg_Debounce++; Set_PMU_Boost_Vout(BOOST_VPMID_5_2V); } else { Vox_Follow_Chg_Debounce = 0; Follow_Chg_Sta = Vox_Follow_Chg_Sta1; } break; case Vox_Follow_Chg_Sta1: $end$ break; default: break; } } #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