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

1439 lines
30 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
******************************************************************************
*
* @file vox_comm.c
* @brief VOX Communicate module
* @ic sy8837/8/9
*
* @version 1.0
* @date 2025/02/13 017:40:40
* @author Alex Xu
*
* Copyright (c) 2013-2099,Tkplusemi Technology Co.,Ltd.
* All Rights Reserved
*
* History:
* Revision Date Author Desc
* 1.0.0 2025/02/13 Alex build this file
******************************************************************************
*/
/*_____ I N C L U D E S ____________________________________________________*/
#include "vox_module.h"
#include "vox_comm.h"
#include "system.h"
#include "bat.h"
#include "hall.h"
#include "key.h"
/******************************************************************************\
Macro definitions
\******************************************************************************/
#define MAX_PACKET_SIZE 0x20
/******************************************************************************\
Variables definitions
\******************************************************************************/
#if XUANHENG
idata uint8_t Vox_Pairing_State[2]; //耳机配对状态0是无效1是正在配对2是配对成功3不处理保持当前状态。
uint8_t Vox_Set_BES_Addr_Flag[2];
idata uint8_t BES_Addr[6]; //蓝牙耳机地址Vox_Bes_Addr[0][6]VOLVox_Bes_Addr[1][6]VOR
idata uint8_t Random_Data[8];
uint8_t Bes_Bet_Level[2]; //对耳电池电量信息Bes_Bet_Level[0]左耳Bes_Bet_Level[1]:右耳
uint8_t Bes_Chg_Full[2]; //对耳硬件是否满电0非满电1满电。
uint8_t Tws_Paired_Record[2]; //TWS配对记录0有TWS配对记录1没有TWS配对记录
uint8_t Phone_Paired_Record[2]; //手机配对记录0有与手机配对记录1没有和手机配对记录。
uint8_t Bes_OTA_State[2]; //耳机静默升级状态10没有
uint8_t Bes_Set_SN_State[2]; //耳机应答仓写入SN是否成功。1成功0失败
uint8_t Bes_In_Pair_State[2]; //耳机进入配对状态标志位
uint8_t Vox_Clear_Pair_Flag[2];
bit Vol_Bes_Addr_Flag;
bit Vor_Bes_Addr_Flag;
idata uint8_t SN_Num[22]; //SN码需要从OTP的固定位置获取。
idata uint8_t SN_Num_Start; //SN码发送起始位置有开盖动作时清零。
bit gShip_Mode_Flag; //船运模式标志位0正常关机1船运模式
#elif JIELI
idata uint8_t Vox_Type;
uint8_t Net_Info[2][13];
idata uint8_t MAC_Addr[2][18];
idata uint8_t Earphone_Vbat[2]; //对耳电量
#endif
#ifdef VOX_RX
idata uint8_t Vox_Get_Vbat_Flag[2]; //耳机配对状态VOL:低4bitVOR:高4bit。0是无效1是正在配对2是配对成功3不处理保持当前状态。
idata uint8_t Vox_Get_BES_Addr_Flag[2];
//idata uint8_t BES_Addr[6] = {0}; //蓝牙耳机地址Vox_Bes_Addr[0][6]VOLVox_Bes_Addr[1][6]VOR
#endif
#ifdef VOX_COMM_ENABLE
/* 双向通讯功能参数。 */
Vox_Comm_Cfg gVox_Comm;
/******************************************************************************\
Functions definitions
\******************************************************************************/
/*
*******************************************************************************
* void Vox_Comm_Cfg_Init(void)
*
* Description : Vox 双向通讯参数初始化函数。 (系统初始化调用周期)
*
* Arguments : NONE
* Returns : NONE
* Notes : NONE
*
*******************************************************************************
*/
void Vox_Comm_Cfg_Clear(void)
{
#ifdef VOX_COVER_ENABLE
gVox_Comm.Cover_Close_Flag = FALSE;
gVox_Comm.Cover_Open_Flag = FALSE;
gVox_Comm.Vox_Chg_Full_Flag = FALSE;
#else
gVox_Comm.Vol_GetInto_Box_Flag = FALSE;
gVox_Comm.Vor_GetInto_Box_Flag = FALSE;
gVox_Comm.Vol_Chg_Full_Flag = FALSE;
gVox_Comm.Vor_Chg_Full_Flag = FALSE;
#endif
gVox_Comm.Key_L_2S_Flag = FALSE;
gVox_Comm.Key_LL_8s_Flag = FALSE;
/*发码相关计时器*/
gVox_Comm.Msg_TX_Debounce = 0;
gVox_Comm.Msg_TX_Debounce1 = 0;
/*按键发码相关计时器*/
gVox_Comm.Key_TWS_Pair_Tim = 0;
gVox_Comm.Key_TWS_Clear_Pair_Tim= 0;
gVox_Comm.Key_TWS_Pair_Cnt = 0;
}
/*
*******************************************************************************
* void Vox_Comm_Handle(void)
*
* Description : Vox 双向通讯处理函数。 (100ms调用周期)
*
* Arguments : NONE
* Returns : NONE
* Notes : NONE
*
*******************************************************************************
*/
void Vox_Comm_Handle(void)
{
if( gVox_Comm.Cover_Open_Flag ) /* 发码:开盖码。 */
{
if( gVox_Comm.Msg_TX_Debounce <= Vox_COM_MSG_Tim )
{
if( ( gVox_Comm.Msg_TX_Debounce % Vox_TX_Interval_2 ) == 0 ) //200ms发送一次
{
#ifdef VOX_TX
#if JIELI
HandleTxCommand(VHOUSE_CMD_OPEN_BOX,VOL_CHAN); //左耳发开盖指令,区分耳机通道。
#elif ZHONGKE
HandleTxCommand(VHOUSE_CMD_OPEN_WINDOW,VOL_CHAN); //左耳发开盖指令,区分耳机通道。
#elif XUANHENG
HandleTxCommand(CMD_HEARTBEAT,VOL_CHAN);
#endif
#endif
}
else
if( ( gVox_Comm.Msg_TX_Debounce % Vox_TX_Interval ) == 0 ) //200ms发送一次
{
#ifdef VOX_TX
#if JIELI
HandleTxCommand(VHOUSE_CMD_OPEN_BOX,VOR_CHAN); //右耳发开盖指令,区分耳机通道。
#elif ZHONGKE
HandleTxCommand(VHOUSE_CMD_OPEN_WINDOW,VOR_CHAN); //右耳发开盖指令,区分耳机通道。
#elif XUANHENG
HandleTxCommand(CMD_HEARTBEAT,VOR_CHAN);
#endif
#endif
}
gVox_Comm.Msg_TX_Debounce++;
}
else
{
Vox_Comm_Cfg_Clear();
}
}
else
if( gVox_Comm.Cover_Close_Flag ) /*发码:关盖码*/
{
if( gVox_Comm.Msg_TX_Debounce <= Vox_COM_MSG_Tim ) //发送关盖指令。
{
if( (gVox_Comm.Msg_TX_Debounce % 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( (gVox_Comm.Msg_TX_Debounce % 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
}
gVox_Comm.Msg_TX_Debounce++;
return;
}
/*发码:获取耳机电量码*/
if( gVox_Comm.Msg_TX_Debounce1 <= Vox_COM_MSG_Tim ) //关盖后5s发送获取电量命令。
{
if( (gVox_Comm.Msg_TX_Debounce1 % 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_CLOSE_WIN_GET_VBAT,VOL_CHAN); //左耳发开盖指令,区分耳机通道。
#elif XUANHENG
HandleTxCommand(CMD_TWS_GET_BTADDR,VOL_CHAN);
#endif
#endif
}
else
if( (gVox_Comm.Msg_TX_Debounce1 % Vox_TX_Interval) == 0 ) //200ms发送一次
{
#ifdef VOX_TX
#if JIELI
HandleTxCommand(VHOUSE_CMD_CLOSE_WIN_GET_VBAT,VOR_CHAN); //右耳发开盖指令,区分耳机通道。
#elif ZHONGKE
HandleTxCommand(VHOUSE_CMD_CLOSE_WIN_GET_VBAT,VOR_CHAN); //右耳发开盖指令,区分耳机通道。
#elif XUANHENG
HandleTxCommand(CMD_TWS_GET_BTADDR,VOR_CHAN);
#endif
#endif
}
gVox_Comm.Msg_TX_Debounce1++;
return;
}
Vox_Comm_Cfg_Clear();
}
else
if( gVox_Comm.Vox_Chg_Full_Flag ) /* 发码Vox耳机充满发关机码。 */
{
if( gVox_Comm.Msg_TX_Debounce <= Vox_COM_MSG_Tim )
{
if( (gVox_Comm.Msg_TX_Debounce % 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( (gVox_Comm.Msg_TX_Debounce % 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
}
gVox_Comm.Msg_TX_Debounce++;
}
else
{
Vox_Comm_Cfg_Clear();
}
}
else
if( gVox_Comm.Key_L_2S_Flag ) /*按键2s发码配对码*/
{
if ( CoverStatus == OPEN )
{
if( gVox_Comm.Key_TWS_Pair_Tim < 1 )
{
#ifdef VOX_TX
#if XUANHENG
HandleTxCommand(CMD_TWS_GET_BTADDR,MASTER_SIDE);
#else
HandleTxCommand(VHOUSE_CMD_PAIR,MASTER_SIDE); //右耳发配对指令,区分耳机通道。
#endif
#endif
Vox_Get_BES_Addr_Flag[SLAVE_TYPE] = 0x00;
Vox_Get_BES_Addr_Flag[MASTER_TYPE] = 0x00;
#ifdef _DEBUG_KEY
printf("Key Pair TX MASTER(line:%d).\r\n",(uint16_t)__LINE__);
#endif
}
else
{
if(gVox_Comm.Key_TWS_Pair_Cnt > KEY_TWS_PAIR_CNT) //耳机蓝牙地址置换超时10s关闭蓝牙地址置换开启VOX 5V。
{
gVox_Comm.Key_TWS_Pair_Cnt = 0;
#if XUANHENG
HandleTxCommand(CMD_PAIRING_IMD,MASTER_SIDE);
HandleTxCommand(CMD_PAIRING_IMD,SLAVE_SIDE);
#endif
Event_key = KEY_EVENT_Empty;
gVox_Comm.Key_L_2S_Flag = FALSE;
OpenCover_TX_Cmd_Flag = TRUE;
#if VOX_ENABLE
#ifdef VOX_ADT_ENABLE
Vol_State = VOX_GET_INTO_BOX;
Vor_State = VOX_GET_INTO_BOX;
#else
VOX_EN_Type(VOX_VOUT_Mode); //VOX Enable 5V
#endif
#endif
#ifdef _DEBUG_KEY
printf("Key Pair TimeOut(line:%d).\r\n",(uint16_t)__LINE__);
#endif
return;
}
else
{
if( Vox_Get_BES_Addr_Flag[MASTER_TYPE] == 0x01 ) /*收到右耳回复的CMD3指令。*/
{
#ifdef VOX_TX
#if JIELI
HandleTxCommand(VHOUSE_CMD_EXCH_TWS_BTADDR,SLAVE_SIDE); /*获取到右耳回复的CMD3指令转发给左耳。*/
#elif ZHONGKE
HandleTxCommand( VHOUSE_CMD_GET_TWS_BTADDR, SLAVE_SIDE ); /*获取到右耳回复的CMD3指令转发给左耳。*/
#elif XUANHENG
HandleTxCommand( CMD_TWS_SET_BTADDR, SLAVE_SIDE );
#endif
#endif
Vox_Get_BES_Addr_Flag[MASTER_TYPE] = 0x02;
#ifdef _DEBUG_KEY
printf("Key Pair Get SLAVE(line:%d).\r\n",(uint16_t)__LINE__);
#endif
}
else
if( Vox_Get_BES_Addr_Flag[MASTER_TYPE] == 0x02 )
{
if( Vox_Get_BES_Addr_Flag[SLAVE_TYPE] != 0x00 )
{
#ifdef VOX_TX
#if JIELI
HandleTxCommand(VHOUSE_CMD_EXCH_TWS_BTADDR,MASTER_SIDE); /*获取到右耳回复的CMD3指令转发给左耳。*/
#elif ZHONGKE
HandleTxCommand( VHOUSE_CMD_GET_TWS_BTADDR, MASTER_SIDE ); /*获取到右耳回复的CMD3指令转发给左耳。*/
#elif XUANHENG
HandleTxCommand( CMD_TWS_SET_BTADDR, MASTER_SIDE );
#endif
#endif
Vox_Get_BES_Addr_Flag[MASTER_TYPE] = 0x00;
Vox_Get_BES_Addr_Flag[SLAVE_TYPE] = 0x00;
gVox_Comm.Key_TWS_Pair_Tim = 0;
gVox_Comm.Key_TWS_Pair_Cnt = 0;
Event_key = KEY_EVENT_Empty;
gVox_Comm.Key_L_2S_Flag = FALSE;
OpenCover_TX_Cmd_Flag = TRUE;
#if VOX_ENABLE
#ifdef VOX_ADT_ENABLE
Vol_State = VOX_NONE_IN_BOX;
Vor_State = VOX_NONE_IN_BOX;
#else
VOX_EN_Type(VOX_ADT_Mode); //VOX Enable 5V
#endif
#endif
#ifdef _DEBUG_KEY
printf("Key Pair Get MASTER(line:%d).\r\n",(uint16_t)__LINE__);
#endif
return;
}
else
{
#ifdef VOX_TX
#if XUANHENG
HandleTxCommand(CMD_TWS_GET_BTADDR,SLAVE_SIDE);
#else
HandleTxCommand(VHOUSE_CMD_PAIR,SLAVE_SIDE); //右耳发配对指令,区分耳机通道。
#endif
#endif
#ifdef _DEBUG_KEY
printf("Key Pair TX SLAVE(line:%d).\r\n",(uint16_t)__LINE__);
#endif
}
}
}
}
if(gVox_Comm.Key_TWS_Pair_Tim >= KEY_TWS_PAIR_TIMER) //3s重发一次。重发5次后超时
{
gVox_Comm.Key_TWS_Pair_Cnt++;
gVox_Comm.Key_TWS_Pair_Tim = 0;
#ifdef _DEBUG_KEY
printf("Key Pair Cnt:%d.(line:%d)\r\n",(uint16_t)gVox_Comm.Key_TWS_Pair_Cnt,(uint16_t)__LINE__);
#endif
}
else
{
gVox_Comm.Key_TWS_Pair_Tim++;
}
}
else
{
Vox_Comm_Cfg_Clear();
}
}
else
if( gVox_Comm.Key_LL_8s_Flag ) /*按键8s发码清配对码*/
{
if( gVox_Comm.Key_TWS_Clear_Pair_Tim < Vox_COM_MSG_Tim ) //每隔200ms发送一次持续时间3s。
{
if( !( gVox_Comm.Key_TWS_Clear_Pair_Tim % Vox_TX_Interval_2 ) )
{
#ifdef VOX_TX
#if XUANHENG
HandleTxCommand(CMD_CLEAR_PAIR,VOR_CHAN);
#else
HandleTxCommand(VHOUSE_CMD_CLEAR_PAIR,VOR_CHAN);
#endif
#endif
}
else
if( !( gVox_Comm.Key_TWS_Clear_Pair_Tim % Vox_TX_Interval ) )
{
#ifdef VOX_TX
#if XUANHENG
HandleTxCommand(CMD_CLEAR_PAIR,VOL_CHAN);
#else
HandleTxCommand(VHOUSE_CMD_CLEAR_PAIR,VOL_CHAN);
#endif
#endif
}
gVox_Comm.Key_TWS_Clear_Pair_Tim++;
}
else
{
Event_key = KEY_EVENT_Empty;
OpenCover_TX_Cmd_Flag = TRUE;
Vox_Comm_Cfg_Clear();
#if VOX_ENABLE
#ifdef VOX_ADT_ENABLE
Vol_State = VOX_NONE_IN_BOX;
Vor_State = VOX_NONE_IN_BOX;
#else
VOX_EN_Type(VOX_ADT_Mode); //VOX Enable 5V
#endif
#endif
}
}
}
#endif
#ifdef VOX_TX
#if XUANHENG
/*
*******************************************************************************
* u16 CalCheckCrc16(u8 * pucFrame, u16 usLen)
*
* Description : 校验和的计算(CRC-16-CCITT-FALSE)
*
*
* Arguments : u8 *pucFrame: 数据存放地址
u16 usLen: 数据长度, 以byte为单位
* Returns :
*
* Notes :
*
*******************************************************************************
*/
static 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 :
*
*******************************************************************************
*/
static 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
/*
*******************************************************************************
* 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;
uint8_t Exch_BtAddr = 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;
if( nVox_Chn_Select == VOL_CHAN )
{
Exch_BtAddr = VOR_CHAN;
}
else
if( nVox_Chn_Select == VOR_CHAN )
{
Exch_BtAddr = VOL_CHAN;
}
for(i=5;i<23;i++)
{
tx_pData[i] = MAC_Addr[Exch_BtAddr][i-5];
}
for(i=23;i<36;i++)
{
tx_pData[i] = Net_Info[Exch_BtAddr][i-23];
}
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~100bit 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<COM1_Data_Lenth;i++)
{
tx_pData[i] = RX1_Buffer[i];
}
#endif
break;
case VHOUSE_CMD_CLEAR_PAIR:
/*Data Length*/
tx_pData[4] = 0x01;
break;
case VHOUSE_CMD_CLOSE_WINDOW:
/*Data Length*/
tx_pData[4] = 0x01;
break;
case VHOUSE_CMD_PWROFF:
/*Data Length*/
tx_pData[4] = 0x01;
break;
default:
break;
}
dataLen = tx_pData[4] + 5;
tx_pData[dataLen] = Crc8Maxim(tx_pData,dataLen);
#elif XUANHENG
uint16_t Checksum = 0;
/*数据包头*/
tx_pData[0] = BOXHEADER;
/*耳机通道*/
tx_pData[1] = nVox_Chn_Select; /*传输方向Bit0-3接收端Bit4-7发送端
1双耳
2充电盒
3PC/工装
4左耳
5右耳
*/
/*指令编号*/
tx_pData[2] = TxCommand;
tx_pData[3] = TxCommand >> 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、D12Bytes构成充电盒的版本信息D0的高4bit为充电盒硬件PCBA版本号D0低4bit和D1构成充电盒软件版本号。
2、D21Byte构成充电盒电量和充电状态D2的bit7为是否有PG接入D2的低7位表示充电盒电量信息范围0-100;
3、D31Byte构成对耳电量信息根据协议中的Side信息区分左右耳电量信息。
4、D41Byte耳机静默升级充电盒默认发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模式*/
#ifdef VOX_ADT_ENABLE
if(nVox_Chn_Select == VOL_CHAN)
{
VOL_EN_Type( VOX_COMM_Mode_Uart );
}
else
{
VOR_EN_Type( VOX_COMM_Mode_Uart );
}
#else
VOX_EN_Type( VOX_COMM_Mode_Uart );
#endif
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 :
*
*******************************************************************************
*/
static 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<13;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<RX1_Buffer[5];i++)
{
BES_Addr[i] = RX1_Buffer[i+7]; //获取耳机MAC地址。
}
if( CMD_Type == TWS_VOL ) //根据耳机Side参数
{
Vox_Get_BES_Addr_Flag[VOL_TYPE] = 1; //左耳机蓝牙地址写入是否成功状态标志
}
else
{
Vox_Get_BES_Addr_Flag[VOR_TYPE] = 1; //右耳机蓝牙地址写入是否成功状态标志
}
break;
case CMD_SHUT_DOWN:
break;
case CMD_TWS_SET_BTADDR:
if( CMD_Type == TWS_VOL ) //根据耳机Side参数
{
Vox_Set_BES_Addr_Flag[VOL_TYPE] = RX1_Buffer[7]; //左耳机蓝牙地址写入是否成功状态标志
}
else
{
Vox_Set_BES_Addr_Flag[VOR_TYPE] = RX1_Buffer[7]; //右耳机蓝牙地址写入是否成功状态标志
}
break;
case CMD_CLEAR_PAIR: //按键长按10s发送此命令。
if( CMD_Type == TWS_VOL ) //根据耳机Side参数
{
Vox_Clear_Pair_Flag[VOL_TYPE] = 1; //左耳机蓝牙地址写入是否成功状态标志
}
else
{
Vox_Clear_Pair_Flag[VOR_TYPE] = 1; //右耳机蓝牙地址写入是否成功状态标志
}
break;
case CMD_HEARTBEAT:
if( CMD_Type == TWS_VOL ) //根据耳机Side参数
{
Bes_Bet_Level[VOL_TYPE] = RX1_Buffer[9] & 0x7F; //获取耳机电量
Bes_Chg_Full[VOL_TYPE] = RX1_Buffer[9] >> 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)
{
uint8_t i = 0;
#if XUANHENG
uint16_t CrcCheckSum = 0;
uint16_t Data_Len = 0;
#else
uint8_t CrcCheckSum = 0;
#endif
/*RX数据处理*/
if( Uart1_RX_Finish_Flag )
{
Uart1_RX_Finish_Flag = FALSE;
#ifdef _DEBUG_VOX
// printf("RX0_Buffer[0]:0x%x,RX0_Buffer[1]:0x%x,RX0_Buffer[2]:0x%x,RX0_Buffer[3]:0x%x,RX0_Buffer[4]:0x%x,RX0_Buffer[5]:0x%x,RX0_Buffer[6]:0x%x,RX0_Buffer[7]:0x%x,RX0_Buffer[8]:0x%x,RX0_Buffer[9]:0x%x,RX0_Buffer[10]:0x%x,RX0_Buffer[11]:0x%x,line:%d\r\n",(u16)RX0_Buffer[0],(u16)RX0_Buffer[1],(u16)RX0_Buffer[2],(u16)RX0_Buffer[3],(u16)RX0_Buffer[4],(u16)RX0_Buffer[5],(u16)RX0_Buffer[6],(u16)RX0_Buffer[7],(u16)RX0_Buffer[8],(u16)RX0_Buffer[9],(u16)RX0_Buffer[10],(u16)RX0_Buffer[11],(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