/* ****************************************************************************** * * @file VOX_Module.c * @brief VOL/R module * @ic sy8837 * * @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 "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_COM_MSG_Tim 20 #define MAX_PACKET_SIZE 0x20 #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 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 uint8_t EarPhone_Num = 0; bit Vox_Ocp_Flag = 0; bit OpenCover_TX_Cmd_Flag = 0; #if XUANHENG idata uint8_t Vox_Pairing_State[2] = {0}; //耳机配对状态,0是无效,1是正在配对,2是配对成功,3不处理,保持当前状态。 idata uint8_t Vox_Set_BES_Addr_Flag[2] = {0}; idata uint8_t BES_Addr[6] = {0}; //蓝牙耳机地址,Vox_Bes_Addr[0][6]:VOL;Vox_Bes_Addr[1][6]:VOR idata uint8_t Random_Data[8] = {0}; idata uint8_t Bes_Bet_Level[2] = {0}; //对耳电池电量信息,Bes_Bet_Level[0]:左耳;Bes_Bet_Level[1]:右耳 idata uint8_t Bes_Chg_Full[2] = {0}; //对耳硬件是否满电:0非满电;1:满电。 idata uint8_t Tws_Paired_Record[2] = {0}; //TWS配对记录;0:有TWS配对记录;1:没有TWS配对记录; idata uint8_t Phone_Paired_Record[2] = {0}; //手机配对记录;0:有与手机配对记录;1:没有和手机配对记录。 idata uint8_t Bes_OTA_State[2] = {0}; //耳机静默升级状态;1:有;0:没有 idata uint8_t Bes_Set_SN_State[2] = {0}; //耳机应答仓写入SN是否成功。1:成功;0:失败 idata uint8_t Bes_In_Pair_State[2] = {0}; //耳机进入配对状态标志位 idata uint8_t Vox_Clear_Pair_Flag[2] = {0}; bit Vol_Bes_Addr_Flag = 0; bit Vor_Bes_Addr_Flag = 0; idata uint8_t SN_Num[22] = {0}; //SN码,需要从OTP的固定位置获取。 idata uint8_t SN_Num_Start = 0; //SN码发送起始位置,有开盖动作时清零。 bit gShip_Mode_Flag = 0; //船运模式标志位:0:正常关机;1:船运模式 #else idata uint8_t Net_Info[2][13] = {0}; idata uint8_t MAC_Addr[2][18] = {0}; xdata uint8_t Earphone_Vbat[2] = 0; //对耳电量 #endif /******************************************************************************\ Functions definitions \******************************************************************************/ #if 0 /* ******************************************************************************* * 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; //开启VOX通讯使能,选择UART通讯模式。 COMM_CTL &= ~( Vol_SW_MD ); SFRADDR = COMM_CON; //Vox通讯电平选择,3.0V,打开50K上拉电阻。 SFRDATA &= ~0x0D; SFRDATA |= VOX_COM_VOLTAGE_SET | VOX_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_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; //开启VOX通讯使能,选择UART通讯模式。 COMM_CTL &= ~( Vor_SW_MD ); SFRADDR = COMM_CON; //Vox通讯电平选择,3.0V,打开50K上拉电阻。 SFRDATA &= ~0x0D; SFRDATA |= VOX_COM_VOLTAGE_SET | VOX_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_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 ; //开启VOX通讯使能,选择UART通讯模式。 COMM_CTL &= ~( Vor_SW_MD | Vol_SW_MD ); SFRADDR = COMM_CON; //Vox通讯电平选择,3.0V,打开50K上拉电阻。 SFRDATA &= ~0x0D; SFRDATA |= VOX_COM_VOLTAGE_SET | VOX_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_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 /* ******************************************************************************* * 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 Get_CHIP_STA1_Flag1; 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; 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 = 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_Flag0 = 0; Get_CHIP_STA1_Flag1 = 0; CoverEvent_Flg1 = 1; if( CoverStatus == CLOSE ) //1、关盖关闭COM_CTRL;显示灯效。(无需查询Loadon、IOFF状态,无论耳机是否在仓,Vox 5V输出。) { Earphone_Chg_Flag = 0; //关盖取消耳机入盒灯效,显示关盖灯效。 Cover_Close_Flag = 1; Cover_Close_Flag1 = 1; Cover_Open_Flag = 0; Vox_Chg_Full_Flag = 0; Cover_Close_Force_Vout_Flag = 0; Vox_Getinto_Sleep_Flag = 0; Vox_Chn_Select = 0; 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.(line:%d)\r\n",(u16)__LINE__); #endif } else //2、开盖处理:5v 500ms 转0V 500ms,后转ADT模式。 { Cover_Close_Flag = 0; Cover_Close_Flag1 = 0; Cover_Open_Flag = 1; Cover_Open_5V_Flag = 0; #ifdef _DEBUG_VOX printf("Box Open.(line:%d)\r\n",(u16)__LINE__); #endif } Boost_Open_Flag = 0; Vox_Output_Short_Flag = 0; Vox_Ocp_Flag = 0; CoverEvent_Flg = 0; } /* 开关盖后,VOX先升压5.2V 一段时间,唤醒耳机,后转入ADT,获取盒内耳机数量。 */ if( Vox_Voltage_Hold_Timer < VOX_OPEN_VOUT_5V_DEBOUNCE ) //开盖后5V N00ms。 { Vox_Voltage_Hold_Timer++; return; } if ( CoverEvent_Flg1 ) { CoverEvent_Flg1 = 0; VOX_EN_Type(VOX_ADT_Mode); return; } else { if ( !Get_CHIP_STA1_Flag0 ) //获取耳机在盒数量。 { Get_CHIP_STA1_Flag0 = 1; 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 1 if( Vox_TX_Timer < VOX_OPEN_VOUT_0V_DEBOUNCE ) //转0V N00ms { VOX_EN_Type(VOX_PD1K_Mode); Vox_TX_Timer++; } else #endif { if( !Get_CHIP_STA1_Flag1 ) { if( Vox_Output_Debounce <= Vox_COM_MSG_Tim ) { if( ( Vox_Output_Debounce % Vox_TX_Interval_2 ) == 0 ) //200ms发送一次 { #ifdef VOX_TX #if JIELI HandleTxCommand(VHOUSE_CMD_OPEN_BOX,VOL_CHAN); //左耳发开盖指令,区分耳机通道。 #elif ZHONGKE HandleTxCommand(VHOUSE_CMD_GET_VBAT,VOL_CHAN); //左耳发开盖指令,区分耳机通道。 #elif XUANHENG HandleTxCommand(CMD_HEARTBEAT,VOL_CHAN); #endif #endif } else if( ( Vox_Output_Debounce % Vox_TX_Interval ) == 0 ) //200ms发送一次 { #ifdef VOX_TX #if JIELI HandleTxCommand(VHOUSE_CMD_OPEN_BOX,VOR_CHAN); //右耳发开盖指令,区分耳机通道。 #elif ZHONGKE HandleTxCommand(VHOUSE_CMD_GET_VBAT,VOR_CHAN); //右耳发开盖指令,区分耳机通道。 #elif XUANHENG HandleTxCommand(CMD_HEARTBEAT,VOR_CHAN); #endif #endif } Vox_Output_Debounce++; } else { VOX_EN_Type(VOX_ADT_Mode); Vox_Output_Debounce = 0; Get_CHIP_STA1_Flag1 = 1; OpenCover_TX_Cmd_Flag = 1; Vox_Vout_Enable = OFF; #ifdef _DEBUG_VOX printf("Open Box CMD TX Over.\r\n"); #endif } } else { if( Event_key == KEY_EVENT_Empty ) { if( OpenCover_TX_Cmd_Flag ) { OpenCover_TX_Cmd_Flag = 0; CHIP_STA1_BK = CHIP_STA1 & ( VOR_LoadOn | VOL_LoadOn ); } else { /*耳机出入盒判断*/ if( CHIP_STA1_BK != ( CHIP_STA1 & ( VOR_LoadOn | VOL_LoadOn ) ) ) //查询耳机loadon状态,loadon状态改变,则说明有耳机出入盒。 { if ( CHIP_STA1 & ( 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(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 = 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_Voltage_Hold_Timer = 0; Vox_Chg_Full_Flag = 0; CoverEvent_Flg1 = 1; Get_CHIP_STA1_Flag0 = 0; Cover_Close_Force_Vout_Flag = 1; return; } 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 = 0; Cover_Close_Flag1 = 1; if( Vox_Voltage_Hold_Timer <= VOX_CLOSE_5V_HOLD_CNT ) //关盖Boost VOUT 5V保持时间。 { Vox_Voltage_Hold_Timer++; return; } Wkup_Earphone_Flag = 0; } else { if( !Cover_Close_Force_Vout_Flag ) { /*发码*/ if( Vox_TX_Timer <= Vox_COM_MSG_Tim ) //发送关盖指令。 { if( (Vox_TX_Timer % Vox_TX_Interval_2) == 0 ) //200ms发送一次 { #ifdef VOX_TX #if JIELI HandleTxCommand(VHOUSE_CMD_CLOSE_BOX,VOL_CHAN); //左耳发开盖指令,区分耳机通道。 #elif ZHONGKE HandleTxCommand(VHOUSE_CMD_CLOSE_WINDOW,VOL_CHAN); //左耳发开盖指令,区分耳机通道。 #elif XUANHENG HandleTxCommand(CMD_HEARTBEAT,VOL_CHAN); #endif #endif } else if( (Vox_TX_Timer % Vox_TX_Interval) == 0 ) //200ms发送一次 { #ifdef VOX_TX #if JIELI HandleTxCommand(VHOUSE_CMD_CLOSE_BOX,VOR_CHAN); //右耳发开盖指令,区分耳机通道。 #elif ZHONGKE HandleTxCommand(VHOUSE_CMD_CLOSE_WINDOW,VOR_CHAN); //右耳发开盖指令,区分耳机通道。 #elif XUANHENG HandleTxCommand(CMD_HEARTBEAT,VOR_CHAN); #endif #endif } Vox_TX_Timer++; return; } if( Vox_Output_Debounce <= Vox_COM_MSG_Tim ) //关盖后5s发送获取电量命令。 { if( (Vox_Output_Debounce % Vox_TX_Interval_2) == 0 ) //200ms发送一次 { #ifdef VOX_TX #if JIELI HandleTxCommand(VHOUSE_CMD_CLOSE_WIN_GET_VBAT,VOL_CHAN); //左耳发开盖指令,区分耳机通道。 #elif ZHONGKE HandleTxCommand(VHOUSE_CMD_GET_TWS_BTADDR,VOL_CHAN); //左耳发开盖指令,区分耳机通道。 #elif XUANHENG HandleTxCommand(CMD_TWS_GET_BTADDR,VOL_CHAN); #endif #endif } else if( (Vox_Output_Debounce % Vox_TX_Interval) == 0 ) //200ms发送一次 { #ifdef VOX_TX #if JIELI HandleTxCommand(VHOUSE_CMD_CLOSE_WIN_GET_VBAT,VOR_CHAN); //右耳发开盖指令,区分耳机通道。 #elif ZHONGKE HandleTxCommand(VHOUSE_CMD_GET_TWS_BTADDR,VOR_CHAN); //右耳发开盖指令,区分耳机通道。 #elif XUANHENG HandleTxCommand(CMD_TWS_GET_BTADDR,VOR_CHAN); #endif #endif } Vox_Output_Debounce++; return; } } } /*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 = 1; Vox_Vout_Enable = OFF; } } else { VOX_EN_Type(VOX_ADT_Mode); } return; } Vox_Output_Short_Flag = 0; Vox_Ocp_Flag = 0; /* 发完关盖码后,开启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 = 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 = 1; Vox_Output_Cnt = 0; Vox_Voltage_Hold_Timer = 0; Vox_Getinto_Sleep_Flag = 0; 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 { if( Vox_Output_Cnt <= Vox_COM_MSG_Tim ) { if( (Vox_Output_Cnt % Vox_TX_Interval_2) == 0 ) //200ms发送一次 { #ifdef VOX_TX #if XUANHENG HandleTxCommand(CMD_SHUT_DOWN,VOL_CHAN); //左耳发关机指令,区分耳机通道。 #else HandleTxCommand(VHOUSE_CMD_PWROFF,VOL_CHAN); //左耳发关机指令,区分耳机通道。 #endif #endif } else if( (Vox_Output_Cnt % Vox_TX_Interval) == 0 ) //200ms发送一次 { #ifdef VOX_TX #if XUANHENG HandleTxCommand(CMD_SHUT_DOWN,VOR_CHAN); //右耳发关机指令,区分耳机通道。 #else HandleTxCommand(VHOUSE_CMD_PWROFF,VOR_CHAN); //右耳发关机指令,区分耳机通道。 #endif #endif } Vox_Output_Cnt++; } 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 = 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 = 1; #ifdef LED_DISPLAY LED_On_Flag = 1; #endif } CHIP_STA1_BK = ( CHIP_STA1 & ( 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 : g_Vox_Fllow_Chg_Cfg *g_Vox_Fllow_Chg * Returns : NONE * Notes : NONE * ******************************************************************************* */ idata uint8_t Vox_Follow_Init_Deb = 0; 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 = 1; } } else { Vox_Follow_Init_Deb = 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->IVox_At_Present[VOR_CHAN] = 0; n_Vox_Fllow_Chg->IVox_At_Present[VOL_CHAN] = 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_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_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_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_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_CHAN] = g_pmu_Adc_Ivor; n_Vox_Fllow_Chg->Vox_InBox_Sta[VOR_CHAN] = 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_CHAN] = g_pmu_Adc_Ivol; n_Vox_Fllow_Chg->Vox_InBox_Sta[VOL_CHAN] = 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_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_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_CHAN] == ON ) { if ( n_Vox_Fllow_Chg->IVox_At_Present[VOR_CHAN] <= VOX_CV_TC_CURRENT ) //检测到Ivor小于CV/TC电流阈值,则说明耳机进入CV/TC阶段 { if ( CHIP_STA1 & VOR_Ioff ) //检测到Ivor Ioff,则VPMID升档。 { n_Vox_Fllow_Chg->Vpmid_AddSta[VOR_CHAN] = ON; if ( n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present >= VOUT_MAX_THD ) //Vpmid电压升到最大,并且IOFF标志存在,则说明耳机充满。 { n_Vox_Fllow_Chg->Vox_InBox_Sta[VOR_CHAN] = 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_CHAN],(u16)__LINE__); #endif } else //未检测到Ivor Ioff,则Vpmid降档 { n_Vox_Fllow_Chg->Vpmid_SubSta[VOR_CHAN] = 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_CHAN],(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_FOLLOW printf("Follow CHG Sta3(CC),VOR Vpmid SubSta(Ivor:%dmA).(line:%d)\r\n",n_Vox_Fllow_Chg->IVox_At_Present[VOR_CHAN],(u16)__LINE__); #endif } else { n_Vox_Fllow_Chg->Vpmid_AddSta[VOR_CHAN] = 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_CHAN],(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 ( CHIP_STA1 & VOL_Ioff ) //检测到Ivol Ioff,则VPMID升档。 { n_Vox_Fllow_Chg->Vpmid_AddSta[VOL_CHAN] = ON; if ( n_Vox_Fllow_Chg->Vpmid_Threshold_At_Present >= VOUT_MAX_THD ) //Vpmid电压升到最大,并且IOFF标志存在,则说明耳机充满。 { n_Vox_Fllow_Chg->Vox_InBox_Sta[VOL_CHAN] = 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_CHAN],(u16)__LINE__); #endif } else //未检测到Ivol Ioff,则Vpmid降档 { n_Vox_Fllow_Chg->Vpmid_SubSta[VOL_CHAN] = 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_CHAN],(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_FOLLOW printf("Follow CHG Sta3(CC),VOL Vpmid SubSta(Ivol:%dmA).(line:%d)\r\n",n_Vox_Fllow_Chg->IVox_At_Present[VOL_CHAN],(u16)__LINE__); #endif } else { n_Vox_Fllow_Chg->Vpmid_AddSta[VOL_CHAN] = 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_CHAN],(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; /* 充电效率优先 */ #ifdef FOLLOW_CHG_EFFICIENCY 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->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->IVox_At_Present[VOL_CHAN] < n_Vox_Fllow_Chg->IVox_Threshold_Neg[VOL_CHAN] ) || \ ( n_Vox_Fllow_Chg->IVox_At_Present[VOL_CHAN] > n_Vox_Fllow_Chg->IVox_Threshold_Pos[VOL_CHAN] ) ) ) { n_Vox_Fllow_Chg->Vpmid_AddSta[VOR_CHAN] = ON; n_Vox_Fllow_Chg->Vpmid_AddSta[VOL_CHAN] = 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_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_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_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_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_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_FOLLOW printf("Follow CHG SubSta,VOL/VOR(line:%d).\r\n",(uint16_t)__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_FOLLOW printf("Follow CHG SubSta,VOR(line:%d).\r\n",(uint16_t)__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_FOLLOW printf("Follow CHG SubSta,VOL(line:%d).\r\n",(uint16_t)__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 > 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_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 < 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 #if XUANHENG /* ******************************************************************************* * u16 CalCheckCrc16(u8 * pucFrame, u16 usLen) * * Description : 校验和的计算(CRC-16-CCITT-FALSE) * * * Arguments : u8 *pucFrame: 数据存放地址 u16 usLen: 数据长度, 以byte为单位 * Returns : * * Notes : * ******************************************************************************* */ uint16_t CalCheckCrc16(uint8_t *pucFrame, unsigned int usLen) { uint16_t wCRCin = 0xFFFF; uint16_t wCPoly = 0x1021; uint8_t wChar = 0; unsigned int i; while (usLen--) { wChar = *(pucFrame++); wCRCin ^= (wChar << 8); for(i = 0;i < 8;i++) { if(wCRCin & 0x8000) { wCRCin = (wCRCin << 1) ^ wCPoly; } else { wCRCin = wCRCin << 1; } } } return (wCRCin); } #else /* ******************************************************************************* * 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; } #endif #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 : * ******************************************************************************* */ void HandleTxCommand(VOX_BES_COMMAND_E TxCommand, e_Vox_Chan nVox_Chn_Select) { uint16_t dataLen = 0; uint8_t tx_pData[COM1_Data_Lenth] = 0; uint8_t i = 0; #if JIELI /*数据包头*/ 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] = MAX_PACKET_SIZE; for(i=5;i<18;i++) { tx_pData[i] = MAC_Addr[nVox_Chn_Select][i]; } for(i=23;i<13;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 * 5; //电仓电量值 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); #elif ZHONGKE /*数据包头*/ tx_pData[0] = BOXHEADER>>8; tx_pData[1] = BOXHEADER; /*充电仓识别码*/ tx_pData[2] = BOXIDCODE; /*耳机通道*/ tx_pData[5] = nVox_Chn_Select; /*指令编号*/ tx_pData[3] = TxCommand; switch(TxCommand) { case VHOUSE_CMD_GET_VBAT: case VHOUSE_CMD_OPEN_WINDOW: case VHOUSE_CMD_CLOSE_WIN_GET_VBAT: /*Data Length*/ tx_pData[4] = 0x03; tx_pData[6] = ( ( ChgStatus & CHG_STA_ING ) << 6 ) | bat_level; //bit 0~6 表示充电仓电量值 0~100;bit 7 为 1 表示在给充电仓充电,为 0 表示没有给充电仓充电; tx_pData[7] = 0x00; break; case VHOUSE_CMD_PAIR: //长按充电仓按键3s,充电仓发送配对指令。 /* 发送给右耳 CMD2,右耳接收到,发送 CMD3 指令给充电仓,充电仓 copy 该指令给 左耳,充电仓可随即发送 CMD2 指令给左耳,左耳会发送 CMD=0x03 给充电仓,充电仓直接 copy CMD3 给右耳即可,右耳接收到发送 VHOUSE_CMD_SUCCES 指令给充电仓。 */ /*Data Length*/ tx_pData[4] = 0x01; break; case VHOUSE_CMD_GET_TWS_BTADDR: //将收到的CMD3转发给对耳。 #ifdef VOX_RX for(i=0;i> 8; /*小端模式:低字节在前 Bit0-7:命令号 Bit8-14:预留 Bit15:包类型 0:REQ 1:ACK */ tx_pData[4] = CoverStatus; //开关盒状态 switch(TxCommand) { case CMD_TWS_GET_BTADDR: //获取耳机MAC地址 /*Data Length*/ tx_pData[5] = 0x00; //小端模式,低位在前,长2Bytes。 tx_pData[6] = 0x00; #ifdef VOX_RX for(i=0;i<6;i++) { BES_Addr[i] = 0; //清本地耳机蓝牙地址。 } #endif break; case CMD_TWS_SET_BTADDR: /*Data Length*/ tx_pData[5] = 0x0E; //小端模式,低位在前,长2Bytes。 tx_pData[6] = 0x00; #ifdef VOX_RX for(i=0;i<6;i++) { tx_pData[7+i] = BES_Addr[i]; //发送耳机蓝牙地址。 } #endif for(i=0;i<8;i++) { tx_pData[13+i] = Random_Data[i]; //发送随机数。 } break; case CMD_SHUT_DOWN: /*Data Length*/ tx_pData[5] = 0x01; //小端模式,低位在前,长2Bytes。 tx_pData[6] = 0x00; tx_pData[7] = gShip_Mode_Flag; //船运模式:0:正常关机;1:船运模式 break; case CMD_PAIRING_IMD: //立即执行TWS配对 /*Data Length*/ tx_pData[5] = 0x00; //小端模式,低位在前,长2Bytes。 tx_pData[6] = 0x00; break; case CMD_CLEAR_PAIR: /*Data Length*/ tx_pData[5] = 0x00; //小端模式,低位在前,长2Bytes。 tx_pData[6] = 0x00; break; case CMD_HEARTBEAT: /*Data Length*/ tx_pData[5] = 0x05; //小端模式,低位在前,长2Bytes。 tx_pData[6] = 0x00; /* data定义: 1、D0、D1(2Bytes)构成充电盒的版本信息,D0的高4bit为充电盒硬件PCBA版本号,D0低4bit和D1构成充电盒软件版本号。 2、D2(1Byte)构成充电盒电量和充电状态,D2的bit7为是否有PG接入;D2的低7位表示充电盒电量信息,范围0-100; 3、D3(1Byte)构成对耳电量信息,根据协议中的Side信息区分左右耳电量信息。 4、D4(1Byte)耳机静默升级,充电盒默认发0x00 */ tx_pData[7] = HW_VER << 4; tx_pData[7] |= FW_VER >> 8; tx_pData[8] = FW_VER; tx_pData[9] = ( ( ChgStatus & CHG_STA_ING ) << 6 ) | ( 5 * bat_level ); if(nVox_Chn_Select == VOL_CHAN) { tx_pData[10] = Bes_Bet_Level[0]; } else if(nVox_Chn_Select == VOR_CHAN) { tx_pData[10] = Bes_Bet_Level[1]; } tx_pData[11] = 0x00; break; case CMD_SN: //由于SN码较长,充电盒需分多次发送,D0表示充第几位开始发送,一次固定发送9Bytes。最后一包SN数据不够9Bytes的补0或0xff。 /*Data Length*/ tx_pData[5] = 0x0A; //小端模式,低位在前,长2Bytes。 tx_pData[6] = 0x00; tx_pData[7] = SN_Num_Start; for(i=0;i<9;i++) { if( (SN_Num_Start + i) > 22 ) { tx_pData[8+i] = 0xFF; } else { tx_pData[8+i] = SN_Num[ SN_Num_Start + i ]; //发送随机数。 } } SN_Num_Start += 9; break; case CMD_GET_INTO_PAIR: /*Data Length*/ tx_pData[5] = 0x01; //小端模式,低位在前,长2Bytes。 tx_pData[6] = 0x00; tx_pData[7] = 0x01; //01进入配对状态 break; case BES_RESET: //复位patten return; default: break; } dataLen = (uint16_t)( tx_pData[5] | ( tx_pData[6] << 8 ) ) + 7; Checksum = CalCheckCrc16( tx_pData, dataLen ); //计算检验和 tx_pData[ dataLen ] = Checksum; tx_pData[ ++dataLen ] = Checksum >> 8; #endif /* vor、vol都使用uart1进行分时通讯,设置TX模式*/ VOX_EN_Type( VOX_COMM_Mode_Uart ); if(nVox_Chn_Select == VOL_CHAN) { COMM_CTL |= Vol_SWDT; COMM_CTL &= ~Vol_SWDR; } else if(nVox_Chn_Select == VOR_CHAN) { COMM_CTL |= Vor_SWDT; COMM_CTL &= ~Vor_SWDR; } else if(nVox_Chn_Select == VOX_BOTH) { COMM_CTL |= Vor_SWDT | Vol_SWDT; COMM_CTL &= ~( Vor_SWDR |Vol_SWDR ); } #if UART1_ENABLE Uart1SendPacket(dataLen + 2, tx_pData); #endif /* 设置RX模式。 */ if(nVox_Chn_Select == VOL_CHAN) { COMM_CTL &= ~ Vol_SWDT; COMM_CTL |= Vol_SWDR; } else if(nVox_Chn_Select == VOR_CHAN) { COMM_CTL &= ~Vor_SWDT; COMM_CTL |= Vor_SWDR; } else if(nVox_Chn_Select == VOX_BOTH) { COMM_CTL &= ~Vor_SWDT | Vol_SWDT; COMM_CTL |= ( Vor_SWDR |Vol_SWDR ); } } #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; #if JIELI switch(RxCommand) { case VHOUSE_CMD_PAIR: for(i=0;i<18;i++) { MAC_Addr[Vox_Type][i] = RX1_Buffer[4+i]; } for(i=0;i<8;i++) { Net_Info[Vox_Type][i] = RX1_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( RX1_Buffer[4] == 0xE3 ) //根据耳机Side参数 { Vox_Get_Vbat_Flag[VOL_TYPE] = 1; //获取左耳机发的Vbat Earphone_Vbat[VOL_CHAN] = RX1_Buffer[5]; } else { Vox_Get_Vbat_Flag[VOR_TYPE] = 1; //获取右耳机发的Vbat Earphone_Vbat[VOR_CHAN] = RX1_Buffer[5]; } break; case VHOUSE_CMD_CLOSE_BOX: break; case VHOUSE_CMD_PWROFF: break; default: break; } #elif ZHONGKE switch(RxCommand) { case VHOUSE_CMD_GET_VBAT: case VHOUSE_CMD_CLOSE_WINDOW: case VHOUSE_CMD_OPEN_WINDOW: case VHOUSE_CMD_CLOSE_WIN_GET_VBAT: break; case VHOUSE_CMD_SUCCESS: break; case VHOUSE_CMD_GET_TWS_BTADDR: if( RX1_Buffer[5] == 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_SYS_RST: //系统复位,耳机->充电仓 break; default: break; } #elif XUANHENG uint8_t CMD_Type = 0; CMD_Type = RX1_Buffer[1] >> 4; if( CMD_Type & TWS_PC ) //PC/工装->盒子 { } else //耳机->盒子 { switch(RxCommand) { case CMD_TWS_GET_BTADDR: for(i=0;i> 7; //获取耳机是否满电 Vox_Pairing_State[VOL_TYPE] = RX1_Buffer[10]; //获取耳机配对状态; Tws_Paired_Record[VOL_TYPE] = RX1_Buffer[11] & 0x01; //bit0:0:有TWS配对记录;1:没有TWS配对记录;bit1:0:有与手机配对记录;1:没有和手机配对记录。 Phone_Paired_Record[VOL_TYPE] = ( RX1_Buffer[11] >> 1 ) & 0x01; Bes_OTA_State[VOL_TYPE] = RX1_Buffer[12]; } else { Bes_Bet_Level[VOR_TYPE] = RX1_Buffer[9] & 0x7F; Bes_Chg_Full[VOR_TYPE] = RX1_Buffer[9] >> 7; Vox_Pairing_State[VOR_TYPE] = RX1_Buffer[10]; Tws_Paired_Record[VOR_TYPE] = RX1_Buffer[11] & 0x01; Phone_Paired_Record[VOR_TYPE] = (RX1_Buffer[11] >> 1) & 0x01; Bes_OTA_State[VOR_TYPE] = RX1_Buffer[12]; } break; case CMD_SN: if( CMD_Type == TWS_VOL ) //根据耳机Side参数 { Bes_Set_SN_State[VOL_TYPE] = RX1_Buffer[7]; //左耳机SN写入是否成功状态标志 } else { Bes_Set_SN_State[VOR_TYPE] = RX1_Buffer[7]; //右耳机SN写入是否成功状态标志 } break; case CMD_GET_INTO_PAIR: if( CMD_Type == TWS_VOL ) //根据耳机Side参数 { Bes_In_Pair_State[VOL_TYPE] = RX1_Buffer[7]; //左耳机是否进入配对状态成功状态标志 } else { Bes_In_Pair_State[VOR_TYPE] = RX1_Buffer[7]; //右耳机是否进入配对状态成功状态标志 } break; case CMD_PAIRING_IMD: if( CMD_Type == TWS_VOL ) //根据耳机Side参数 { Bes_In_Pair_State[VOL_TYPE] = 1; //左耳机是否进入配对状态成功状态标志 } else { Bes_In_Pair_State[VOR_TYPE] = 1; //右耳机是否进入配对状态成功状态标志 } break; default: break; } } #endif } /* ******************************************************************************* * void HandleVoxCommMsg(void) * * Description : Vox 通讯功能处理函数,100ms定时调用。由于和耳机通信前需要打开耳机端的TRX功能,并且每次通信只能一只耳机。通过切换VOL/VOR通信开关进行通信 * * Arguments : NONE * Returns : NONE * Notes : NONE * ******************************************************************************* */ void HandleVoxCommMsg(void) { uint16_t CrcCheckSum = 0; uint8_t i = 0; #if XUANHENG uint16_t Data_Len = 0; #endif /*RX数据处理*/ if( Uart1_RX_Finish_Flag ) { Uart1_RX_Finish_Flag = 0; #ifdef _DEBUG_VOX printf("RX1_Buffer[0]:0x%x,RX1_Buffer[1]:0x%x,RX1_Buffer[2]:0x%x,RX1_Buffer[3]:0x%x,RX1_Buffer[4]:0x%x,RX1_Buffer[5]:0x%x,RX1_Buffer[6]:0x%x,line:%d\r\n",(u16)RX1_Buffer[0],(u16)RX1_Buffer[1],(u16)RX1_Buffer[2],(u16)RX1_Buffer[3],(u16)RX1_Buffer[4],(u16)RX1_Buffer[5],(u16)RX1_Buffer[6],(u16)__LINE__); #endif #if JIELI CrcCheckSum = Crc8Maxim(RX1_Buffer, RX1_Buffer[2] + 3); //求校验和 if( CrcCheckSum == RX1_Buffer[RX1_Buffer[2] + 3] ) #elif ZHONGKE CrcCheckSum = Crc8Maxim( RX1_Buffer, RX1_Buffer[4] + 5 ); if( CrcCheckSum == RX1_Buffer[ RX1_Buffer[4] + 5 ] ) #elif XUANHENG Data_Len = RX1_Buffer[5] | ( RX1_Buffer[6] << 8 ) + 7; CrcCheckSum = CalCheckCrc16( RX1_Buffer, Data_Len); //计算检验和 if( CrcCheckSum == (uint16_t)(RX1_Buffer[ Data_Len + 1 ] | RX1_Buffer[ Data_Len + 2 ] << 8) ) //校验和小端模式,低位在前。 #endif { #if XUANHENG HandleRxMsg((VOX_BES_COMMAND_E)RX1_Buffer[2]); #else HandleRxMsg((VOX_BES_COMMAND_E)RX1_Buffer[3]); #endif } else { return; } } } #endif #endif