Both_Way_Comm_SY8833/TP3310_Demo.si4project/Backup/vox_module(6283).c

1161 lines
26 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

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

/*
******************************************************************************
*
* @file VOX_Module.c
* @brief VOL/R module
*
*
* @version 1.0
* @date 2022/07/18 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 2022/07/18 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"
bit Vox_Vout_Enable = OFF; //Vox功率输出标志位
#if VOX_ENABLE
/******************************************************************************\
Macro definitions
\******************************************************************************/
#define EARPHONR_WKUP_CNT 2
#define BES_RST_PULS_CNT 20
#define Vox_TX_Interval 2 //Vox定时发送指令时间间隔
#define BOOST_VOUT_HIGH_CNT 100 //关盖发完指令后Boost Vout输出5.15V时间。
#define BES_ADDR_EXCHG_TIMOUT 30 //关盖5s后耳机蓝牙地址置换3s重发一次。直到10次后超时。
#define BES_ADDR_EXCHG_CNT 5
/******************************************************************************\
Variables definitions
\******************************************************************************/
bit BES_Rst_Puls_Flag = 0;
bit BES_Addr_Exchg_Flag = 0;
bit Cover_Close_Flag = 0;
bit Cover_Open_Flag = 0;
bit EarPhone_ShutDown_Flag = 0; //耳机关机标志位
bit Boost_Open_Flag = 0; //用于开启Boost后延时开启Vox 5V。
uint8_t Vox_Output_Short_Debounce = 0;
uint16_t Boost_Open_Atleast_Tim_Cnt = 0;
uint8_t Box_To_Bes_Comm_Debounce = 0;
uint8_t Box_To_Bes_Comm_Cnt = 0;
bit Boost_Vout_Change_Flag = 0;
#ifdef VOX_RX
uint8_t Vox_Pairing_State[2] = {0}; //耳机配对状态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]VOLVox_Bes_Addr[1][6]VOR
#if defined(XIAOMI)
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}; //耳机静默升级状态10没有
idata uint8_t Bes_Set_SN_State[2] = {0}; //耳机应答仓写入SN是否成功。1成功0失败
idata uint8_t SN_Num[22] = {0}; //SN码需要从OTP的固定位置获取。
uint8_t SN_Num_Start = 0; //SN码发送起始位置有开盖动作时清零。
bit gShip_Mode_Flag = 0; //船运模式标志位0正常关机1船运模式
#define COVER_OPEN_CNT 600 //1分钟
uint16_t Vox_TX_Timer = 0; //VOX发送指令持续时间计数,在Hall_Handler检测中清0.
#define VOX_TX_CNT 50 //VOX发送指令时间5s
#elif defined(QIANCHENG)
uint8_t Vox_TX_Timer = 0; //VOX发送指令持续时间计数,在Hall_Handler检测中清0.
#define COVER_OPEN_CNT 0xff
#define VOX_TX_CNT 30 //VOX发送指令时间3s
#endif
#endif
/******************************************************************************\
Functions definitions
\******************************************************************************/
/*
*******************************************************************************
* void VOX_EN_Type(VOR_Enable_Type_e VOR_Enable_Type)
*
* Description : VOL Open(EN_VO)
* Arguments :
* Returns :
* Notes :
*
*******************************************************************************
*/
void VOX_EN_Type(VOX_Enable_Mode_e VOX_Enable_Mode)
{
COM_CTRL = ON;
#if 1
if( VOX_Enable_Mode == VOX_VOUT_Mode)
{
VOX_CTL0 &= ~0x30; //VOX Disable 5V And Disable VOX ADT
VOX_CTL0 |= 0x30; //VOX Enable 5V
}
else
{
VOX_CTL0 &= ~0x30; //VOX 5v Off
}
#else
switch(VOX_Enable_Mode)
{
case VOX_VOUT_Mode:
VOX_CTL0 &= ~0x30; //VOX Disable 5V And Disable VOX ADT
VOX_CTL0 |= 0x30; //VOX Enable 5V
break;
case VOX_ADT_Mode:
VOX_CTL0 &= ~0x30; //VOX 5v Off
// VOX_CTL0 |= 0x03; //VOX load detect On
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)
{
/*Vox 过流保护两只耳机都每隔200ms打嗝一次(28Bytes)*/
if( IRQ_FLAG0 & 0x0C )
{
Vox_Output_Short_Debounce++;
if( Vox_Output_Short_Debounce >= 2 ) //Vox短路保护200ms后重新开启Vox 5V。
{
Vox_Output_Short_Debounce = 0;
IRQ_FLAG0 = 0x0C;
VOX_EN_Type(VOX_VOUT_Mode);
return;
}
}
if( CoverEvent_Flg ) //Hall事件。
{
#if 0
if(gBoost_Prepared_Flag && ( CHIP_STA1 & 0xA0 ) ) //1、Boost开启条件不满足则Vox一直处于ADT模式。2、存在loadon有耳机在仓开启Vox 5V输出
#else
if( gBoost_Prepared_Flag )
#endif
{
if( !Boost_Open_Flag )
{
BST_EN = 1; //Boost Enable异常时由硬件主动关闭。开启Boost开启Vox 5v会在开启Boost之后100ms延时
Boost_Open_Flag = 1;
return;
}
Vox_Pairing_State[VOL_CHAN] = 0;
Vox_Pairing_State[VOR_CHAN] = 0;
BES_Rst_Puls_Flag = 0;
EarPhone_ShutDown_Flag = 0;
Boost_Open_Atleast_Tim_Cnt = 0;
if( CoverStatus == CLOSE ) //1、关盖关闭COM_CTRL显示灯效。无需查询Loadon、IOFF状态无论耳机是否在仓关盖发送指令间隔300ms持续10s间隔之间关闭COM_CTRL。
{
Cover_Close_Flag = 1;
Cover_Open_Flag = 0;
CoverEvent_Flg = 0;
Vox_Vout_Enable = ON;
Boost_Open_Flag = 0;
COM_CTRL = OFF;
//VOX_EN_Type(VOX_VOUT_Mode);
VOX_CTL0 |= 0x30; //VOX Enable 5V开启VOX端的NMOS
}
else //2、开盖处理Vox 5V输出500ms用于唤醒耳机500ms后vox设置为ADT模式关Boost。
{
Cover_Close_Flag = 0;
BES_Addr_Exchg_Flag = 0;
/*开启VOUT 500ms用于唤醒耳机。*/
if( Vox_TX_Timer < EARPHONR_WKUP_CNT ) //debounce 500ms
{
VOX_EN_Type(VOX_VOUT_Mode);
Vox_TX_Timer++;
}
else
{
BST_EN = 0; //Boost Disable
Cover_Open_Flag = 1;
CoverEvent_Flg = 0;
Boost_Open_Flag = 0;
Vox_TX_Timer = 0;
}
}
}
else
{
VOX_EN_Type(VOX_ADT_Mode);
}
}
/* 发送开盖指令*/
if( Cover_Open_Flag ) /*开盖后每隔200-300ms发送一次开盖指令并且接收耳机配对状态信息。*/
{
if( Vox_TX_Timer < COVER_OPEN_CNT )
{
if( (Vox_TX_Timer % Vox_TX_Interval) == 0 ) //200ms发送一次
{
#ifdef VOX_TX
#if defined(QIANCHENG) //岍丞
HandleTxCommand(CMD_BOX_OPEN,VOL_CHAN); //左耳发开盖指令,区分耳机通道。
#elif defined(XIAOMI) //小米
HandleTxCommand(CMD_HEARTBEAT,VOL_CHAN);
#endif
#endif
}
else
{
#ifdef VOX_TX
#if defined(QIANCHENG) //岍丞
HandleTxCommand(CMD_BOX_OPEN,VOR_CHAN); //左耳发开盖指令,区分耳机通道。
#elif defined(XIAOMI) //小米
HandleTxCommand(CMD_HEARTBEAT,VOR_CHAN);
#endif
#endif
}
Vox_TX_Timer++;
}
#ifdef XIAOMI
else
{
VOX_EN_Type(VOX_VOUT_Mode);
}
#endif
}
/* 发送开、关盖指令*/
if( Cover_Close_Flag || EarPhone_ShutDown_Flag )
{
/*间隔300ms发送指令持续3s关盖间隔之间开启VOUT;开盖间隔之间开启ADT。*/
if( Vox_TX_Timer < VOX_TX_CNT )
{
#if 0
if( (Vox_TX_Timer % Vox_TX_Interval) == 0 ) //200ms发送一次
{
if( EarPhone_ShutDown_Flag )
{
#ifdef VOX_TX
HandleTxCommand(CMD_SHUT_DOWN,VOX_BOTH); /*耳机电池充满或仓处于低电,发关机指令*/
#endif
}
else
if( CoverStatus == CLOSE )
{
#ifdef VOX_TX
HandleTxCommand(CMD_BOX_CLOSE,VOX_BOTH); //发送关盖指令 ,不区分耳机通道。
#endif
}
}
#else
if( (Vox_TX_Timer % Vox_TX_Interval) == 0 ) //200ms发送一次
{
if( EarPhone_ShutDown_Flag )
{
#ifdef VOX_TX
HandleTxCommand(CMD_SHUT_DOWN,VOL_CHAN); /*耳机电池充满或仓处于低电,发关机指令*/
#endif
}
else
if( CoverStatus == CLOSE )
{
#ifdef VOX_TX
#if defined(QIANCHENG) //岍丞
HandleTxCommand(CMD_BOX_CLOSE,VOL_CHAN); //左耳发关盖指令,区分耳机通道。
#elif defined(XIAOMI) //小米
HandleTxCommand(CMD_HEARTBEAT,VOL_CHAN);
#endif
#endif
}
}
else
{
if( EarPhone_ShutDown_Flag )
{
#ifdef VOX_TX
HandleTxCommand(CMD_SHUT_DOWN,VOR_CHAN); /*耳机电池充满或仓处于低电,发关机指令*/
#endif
}
else
if( CoverStatus == CLOSE )
{
#ifdef VOX_TX
#if defined(QIANCHENG) //岍丞
HandleTxCommand(CMD_BOX_CLOSE,VOR_CHAN); //左耳发开盖指令,区分耳机通道。
#elif defined(XIAOMI) //小米
HandleTxCommand(CMD_HEARTBEAT,VOR_CHAN);
#endif
#endif
}
}
#endif
Vox_TX_Timer++;
}
else //5s后清标志位。
{
if( EarPhone_ShutDown_Flag )
{
EarPhone_ShutDown_Flag = 0;
Cover_Close_Flag = 0;
Vox_Vout_Enable = OFF;
BST_EN = 0; //Boost Disable
VOX_EN_Type(VOX_ADT_Mode);
}
else
if( Cover_Close_Flag ) //关盖发送完相应的指令后VOX 5V充电等待耳机电池充满。充满
{
if( ((CHIP_STA1 & 0xAC) == 0xAC) || F_batlevel_low ) //一、loadon和ioff状态同时存在说明1、耳机电池充满2、耳机锂保3、盒中没耳机二、盒电池低电。两种情况都发SHUT_DOWN。等待开盖重新插拔耳机。
{
if( Boost_Open_Atleast_Tim_Cnt >= TIM_SHUTDOWN_DEBOUNCE ) //Boost必须工作满10分钟软件才允许关机原因给耳机电池处于锂保状态进行充电。
{
EarPhone_ShutDown_Flag = 1;
Vox_TX_Timer = 0; //为了后面发送SHUT_DOWN指令。
}
}
if( !BES_Rst_Puls_Flag )
{
Vox_TX_Timer++;
if( Vox_TX_Timer > (BES_RST_PULS_CNT + VOX_TX_CNT) ) //关盖后3+2s后发送BES 复位 pattern
{
BES_Rst_Puls_Flag = 1; //发完复位Pattern后开始蓝牙地址置换。
BES_Addr_Exchg_Flag = 1;
Box_To_Bes_Comm_Debounce = 0;
Box_To_Bes_Comm_Cnt = 0;
COM_CTRL = ON;
#ifdef VOX_TX
HandleTxCommand(BES_RESET,VOX_BOTH); //发送BES Reset脉冲只发一次。 23*5=115ms
#endif
return; /*return的原因Vox_Det_Machine() 100ms调用周期BES_RESET在Timer1中5ms调用。整个复位Pattern需要115ms
在此处return可以保证在200ms内只有BES 复位pattern在操作COM_CTRL。*/
}
}
/*蓝牙地址交互*/
// if( BES_Addr_Exchg_Flag && ( CHIP_STA1 & 0xA0 ) == 0xA0 ) /*1、关盖2、有双耳机在盒。关盖5s后发完关盖指令。*/
if( BES_Addr_Exchg_Flag )
{
if( Box_To_Bes_Comm_Debounce < 1 )
{
#ifdef VOX_TX
HandleTxCommand(CMD_BES_PAIRING,VOL_CHAN); /*关盖5s后左耳发送配对指令获取左耳蓝牙地址。*/
#endif
Vox_Get_BES_Addr_Flag[VOL_CHAN] = 0x00;
Vox_Get_BES_Addr_Flag[VOR_CHAN] = 0x00;
}
else
{
if(Box_To_Bes_Comm_Cnt > BES_ADDR_EXCHG_CNT) //耳机蓝牙地址置换超时20s关闭蓝牙地址置换开启VOX 5V。
{
// Box_To_Bes_Comm_Cnt = 0;
BES_Addr_Exchg_Flag = 0;
Boost_Vout_Change_Flag = 1;
Box_To_Bes_Comm_Debounce = 0;
VOX_EN_Type(VOX_VOUT_Mode);
return;
}
else
{
if( Vox_Get_BES_Addr_Flag[VOL_CHAN] != 0x00 ) /*收到左耳回复的蓝牙地址*/
{
if( Vox_Get_BES_Addr_Flag[VOR_CHAN] != 0x00 )
{
// Box_To_Bes_Comm_Cnt = 0;
BES_Addr_Exchg_Flag = 0;
Boost_Vout_Change_Flag = 1;
Box_To_Bes_Comm_Debounce = 0;
VOX_EN_Type(VOX_VOUT_Mode);
return;
}
else
{
#ifdef VOX_TX
HandleTxCommand(CMD_BES_PAIRING,VOR_CHAN); /*发右耳配对指令,获取右耳蓝牙地址。*/
#endif
Vox_Get_BES_Addr_Flag[VOL_CHAN] = 0x00;
}
}
else
if( Vox_Get_BES_Addr_Flag[VOR_CHAN] != 0x00 ) /*收到右耳回复的蓝牙地址,再将右蓝牙地址发给左耳。*/
{
#ifdef VOX_TX
HandleTxCommand(CMD_BES_PAIRING,VOL_CHAN);
#endif
}
}
}
if(Box_To_Bes_Comm_Debounce > BES_ADDR_EXCHG_TIMOUT) //3s重发一次。重发5次后超时
{
Box_To_Bes_Comm_Cnt++;
Box_To_Bes_Comm_Debounce = 0;
}
else
{
Box_To_Bes_Comm_Debounce++;
}
}
/* 关盖发完指令后Boost Vout输出5.15V时间1s。*/
if( Boost_Vout_Change_Flag )
{
if( Box_To_Bes_Comm_Debounce < BOOST_VOUT_HIGH_CNT )
{
SFRADDR = BST_CTL0; //设置输出5.15V
SFRDATA |= 0x03;
Box_To_Bes_Comm_Debounce++;
}
else
{
Boost_Vout_Change_Flag = 0;
Box_To_Bes_Comm_Debounce = 0;
SFRADDR = BST_CTL0; //设置输出5.05V
SFRDATA &= ~0x03;
SFRDATA |= 0x01;
}
}
}
}
}
}
#if defined(ZHONGKELANXUN)
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;
}
#elif defined(XIAOMI)
/******************************************************************************\
Functions definitions
\******************************************************************************/
/*
*******************************************************************************
* u16 CalCheckCrc16(u8 * pucFrame, u16 usLen)
*
* Description : 校验和的计算
*
*
* Arguments : u8 *pucFrame: 数据存放地址
u16 usLen: 数据长度, 以byte为单位
* Returns :
*
* Notes :
*
*******************************************************************************
*/
uint16_t CalCheckCrc16(uint8_t *pucFrame, unsigned int usLen)
{
uint16_t wCRCin = 0x0000;
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);
}
#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)
{
#if defined(QIANCHENG) //岍丞
uint8_t tx_pData[11] = 0;
uint8_t i = 0;
/*数据包头*/
tx_pData[0] = BOXHEADER;
/*耳机通道*/
tx_pData[2] = nVox_Chn_Select;
/*指令编号*/
tx_pData[3] = TxCommand;
switch(TxCommand)
{
case CMD_BOX_OPEN:
case CMD_BOX_CLOSE:
#if 0
/*Data Length*/
tx_pData[4] = 0x02;
tx_pData[5] = bat_level;
tx_pData[6] = FW_VER;
break;
#endif
case CMD_SHUT_DOWN:
/*Data Length*/
tx_pData[4] = 0x02;
tx_pData[5] = bat_level;
tx_pData[6] = FW_VER;
break;
case CMD_BES_PAIRING:
/*Data Length*/
tx_pData[4] = 0x06;
for(i=0;i<6;i++)
{
tx_pData[5+i] = BES_Addr[i]; //发送耳机蓝牙地址。
}
break;
case BES_RESET: //BES 复位patten
SFRADDR = MFP_CTL0; //Set P01 Pinmux As GPIO Function
SFRDATA &= ~0x0C;
for(i=0;i<6;i++)
{
BES_Addr[i] = 0; //清本地耳机蓝牙地址。
}
BES_Puls_Start = 1;
return;
default:
break;
}
for(i=2;i<(tx_pData[4] + 5);i++) //datalen + side + cmd
{
tx_pData[1] += tx_pData[i]; //求校验和
}
COM_CTRL = OFF; //VOX切换到通讯TX功能模式1.8V)。
SFRADDR = MFP_CTL0;
SFRDATA |= 0x04; //P01 as UART's TX
#if UART0_ENABLE
Uart0SendPacket(tx_pData[4] + 6, tx_pData); //+6的原因多加一个字节发送后面要设置TX为GPIO会导致最后一个字节没来得及发出去。
#endif
SFRADDR = MFP_CTL0; //Set P01 Pinmux As GPIO Function,原因TX和RX连在一起要保证RX能正常接收到数据TX需设置为GPIO模式并浮空或输入模式。
SFRDATA &= ~0x0C;
#elif defined(ZHONGKELANXUN) //中科蓝讯
uint8_t tx_pData[11] = 0;
uint8_t i = 0;
/*数据包头*/
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:
/*Data Length*/
tx_pData[4] = 0x03;
tx_pData[6] = (CHIP_STA4 & 0x80) | bat_level; //bit 0~6 表示充电仓电量值 0~100bit 7 为 1 表示在给充电仓充电,为 0 表示没有给充电仓充电;
tx_pData[7] = 0x03; //ear_vbat:对耳电量,例如充电仓从左耳获取到耳机电量,将该电量 bit7 置 1 发送给右耳,如
//果没有获取到,但是知道对耳在仓内都要将 bit7 置 1
break;
case VHOUSE_CMD_PAIR: //长按充电仓按键3s充电仓发送配对指令。
/*Data Length*/
tx_pData[4] = 0x01;
break;
case VHOUSE_CMD_GET_TWS_BTADDR:
break;
case CMD_BES_PAIRING:
/*Data Length*/
tx_pData[4] = 0x06;
for(i=0;i<6;i++)
{
tx_pData[5+i] = BES_Addr[nVox_Chn_Select][i]; //获取耳机蓝牙地址。
}
break;
case BES_RESET: //BES 复位patten
BES_Puls_Start = 1;
return;
default:
break;
}
#elif defined(XIAOMI) //小米
/*
*/
uint8_t tx_pData[11] = 0;
uint8_t i = 0;
uint16_t Checksum = 0;
uint16_t DataLen = 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_PAIR: //获取耳机MAC地址
/*Data Length*/
tx_pData[5] = 0x00; //小端模式低位在前长2Bytes。
tx_pData[6] = 0x00;
break;
case CMD_TWS_BTADDR_EXCH:
/*Data Length*/
tx_pData[5] = 0x0E; //小端模式低位在前长2Bytes。
tx_pData[6] = 0x00;
for(i=0;i<6;i++)
{
tx_pData[7+i] = BES_Addr[i]; //发送耳机蓝牙地址。
}
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] = (CHIP_STA4 & 0x80) | 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: //BES 复位patten
BES_Puls_Start = 1;
return;
default:
break;
}
DataLen = tx_pData[5] | (tx_pData[6] << 8) + 7;
Checksum = CalCheckCrc16( tx_pData, DataLen ); //计算检验和
tx_pData[1 + DataLen] = Checksum;
tx_pData[2 + DataLen] = Checksum >> 8;
COM_CTRL = OFF; //VOX切换到通讯TX功能模式1.8V)。
SFRADDR = MFP_CTL0;
SFRDATA |= 0x04; //P01 as UART's TX
#if UART0_ENABLE
Uart0SendPacket(10 + DataLen, tx_pData);
#endif
SFRADDR = MFP_CTL0; //Set P01 Pinmux As GPIO Function,原因TX和RX连在一起要保证RX能正常接收到数据TX需设置为GPIO模式并浮空或输入模式。
SFRDATA &= ~0x0C;
#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;
#if defined(QIANCHENG) //岍丞
switch(RxCommand)
{
case CMD_BOX_OPEN:
case CMD_BOX_CLOSE:
if( RX0_Buffer[2] == VOL_CHAN ) //根据耳机Side参数
{
Vox_Pairing_State[VOL_CHAN] = RX0_Buffer[5]; //获取左耳机配对状态
}
else
{
Vox_Pairing_State[VOR_CHAN] = RX0_Buffer[5]; //获取右耳机配对状态
}
break;
case CMD_SHUT_DOWN:
break;
case CMD_BES_PAIRING:
if( RX0_Buffer[2] == VOL_CHAN ) //根据耳机Side参数
{
Vox_Get_BES_Addr_Flag[VOL_CHAN] = 1; //获取到左耳机蓝牙地址状态
}
else
{
Vox_Get_BES_Addr_Flag[VOR_CHAN] = 1; //获取到右耳机蓝牙地址状态
}
for(i=0;i<6;i++)
{
BES_Addr[i] = RX0_Buffer[i+5]; //获取左耳机蓝牙地址。
}
break;
default:
break;
}
#elif defined(XIAOMI) //小米
uint8_t CMD_Type = 0;
CMD_Type = RX0_Buffer[1] >> 4;
if( CMD_Type & TWS_PC ) //PC/工装->盒子
{
}
else //耳机->盒子
{
switch(RxCommand)
{
case CMD_TWS_PAIR:
for(i=0;i<RX0_Buffer[5];i++)
{
BES_Addr[i] = RX0_Buffer[i+7]; //获取耳机MAC地址。
}
break;
case CMD_SHUT_DOWN:
break;
case CMD_TWS_BTADDR_EXCH:
if( CMD_Type == TWS_VOL ) //根据耳机Side参数
{
Vox_Get_BES_Addr_Flag[0] = RX0_Buffer[7]; //左耳机蓝牙地址写入是否成功状态标志
}
else
{
Vox_Get_BES_Addr_Flag[1] = RX0_Buffer[7]; //右耳机蓝牙地址写入是否成功状态标志
}
break;
case CMD_CLEAR_PAIR: //按键长按10s发送此命令。
break;
case CMD_HEARTBEAT:
if( CMD_Type == TWS_VOL ) //根据耳机Side参数
{
Bes_Bet_Level[0] = RX0_Buffer[9]&0x7F; //获取耳机电量
Bes_Chg_Full[0] = RX0_Buffer[9] >> 7; //获取耳机是否满电
Vox_Pairing_State[0] = RX0_Buffer[10]; //获取耳机配对状态;
Tws_Paired_Record[0] = RX0_Buffer[11] & 0x01; //bit0:0有TWS配对记录1没有TWS配对记录bit1:0有与手机配对记录1没有和手机配对记录。
Phone_Paired_Record[0] = (RX0_Buffer[11] >> 1) & 0x01;
Bes_OTA_State[0] = RX0_Buffer[12];
}
else
{
Bes_Bet_Level[1] = RX0_Buffer[9]&0x7F;
Bes_Chg_Full[1] = RX0_Buffer[9] >> 7;
Vox_Pairing_State[1] = RX0_Buffer[10];
Tws_Paired_Record[1] = RX0_Buffer[11] & 0x01;
Phone_Paired_Record[1] = (RX0_Buffer[11] >> 1) & 0x01;
Bes_OTA_State[1] = RX0_Buffer[12];
}
break;
case CMD_SN:
if( CMD_Type == TWS_VOL ) //根据耳机Side参数
{
Bes_Set_SN_State[0] = RX0_Buffer[7]; //左耳机SN写入是否成功状态标志
}
else
{
Bes_Set_SN_State[1] = RX0_Buffer[7]; //右耳机SN写入是否成功状态标志
}
break;
case CMD_GET_INTO_PAIR:
break;
case CMD_PAIRING_IMD:
break;
default:
break;
}
}
#endif
}
/*
*******************************************************************************
* void HandleVoxCommMsg(void)
*
* Description : Vox 通讯功能处理函数100ms定时调用。由于和耳机通信前需要打开耳机端的TRX功能并且每次通信只能一只耳机。通过切换VOL/VOR通信开关进行通信
*
* Arguments : NONE
* Returns : NONE
* Notes : NONE
*
*******************************************************************************
*/
void HandleVoxCommMsg(void)
{
#if defined(QIANCHENG) //岍丞
uint8_t CrcCheckSum = 0;
#elif defined(ZHONGKELANXUN) //中科蓝讯
uint8_t CrcCheckSum = 0;
#elif defined(XIAOMI)
uint16_t CrcCheckSum = 0;
uint16_t Data_Len = 0;
#endif
uint8_t i = 0;
/*RX数据处理*/
if( Uart0_RX_Finish_Flag )
{
Uart0_RX_Finish_Flag = 0;
#if defined(QIANCHENG) //岍丞
for(i=2 ;i<(RX0_Buffer[4] + 5);i++) //计算校验和
{
CrcCheckSum += RX0_Buffer[i]; //求校验和
}
if( CrcCheckSum == RX0_Buffer[1] )
{
HandleRxMsg((VOX_BES_COMMAND_E)RX0_Buffer[3]);
}
else
{
return;
}
#elif defined(XIAOMI) //小米
Data_Len = RX0_Buffer[5] | (RX0_Buffer[6] << 8) + 7;
CrcCheckSum = CalCheckCrc16( RX0_Buffer, Data_Len); //计算检验和
if( CrcCheckSum == (uint16_t)(RX0_Buffer[Data_Len+1] | RX0_Buffer[Data_Len+2] << 8) ) //校验和小端模式,低位在前。
{
HandleRxMsg((VOX_BES_COMMAND_E)RX0_Buffer[2]);
}
else
{
return;
}
#endif
}
}
#endif
#endif