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

693 lines
17 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_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"
bit Vox_Vout_Enable = OFF; //Vox功率输出标志位
#if VOX_ENABLE
/******************************************************************************\
Macro definitions
\******************************************************************************/
#define VOX_TX_CNT 50 //VOX发送指令时间
#define EARPHONR_WKUP_CNT 2
#define BES_RST_PULS_CNT 20
#define Vox_TX_Interval 2 //Vox定时发送指令时间间隔
#define TIM_SHUTDOWN_DEBOUNCE 300 //关机前debounce时间
/******************************************************************************\
Variables definitions
\******************************************************************************/
uint8_t BES_Puls_Cnt = 0; //BES Reset脉冲计数
bit BES_Puls_Start = 0; //开启BES Reset脉冲信号
uint8_t Vox_TX_Timer = 0; //VOX发送指令持续时间计数,在Hall_Handler检测中清0.
uint8_t BES_Rst_Puls_Timer = 0; //关盖15s后发送BES Reset 脉冲
bit BES_Rst_Puls_Flag = 0;
uint8_t WkUp_EarPhone_Debounce = 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;
/******************************************************************************\
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;
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;
}
}
/*
*******************************************************************************
* 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;
}
BES_Rst_Puls_Flag = 0;
BES_Rst_Puls_Timer = 0;
EarPhone_ShutDown_Flag = 0;
Vox_TX_Timer = 0;
SFRADDR = MFP_CTL0;
SFRDATA |= 0x04; //P01 as UART's TX
if( CoverStatus == CLOSE ) //1、关盖关闭COM_CTRL显示灯效。无需查询Loadon、IOFF状态无论耳机是否在仓关盖发送指令间隔300ms持续10s间隔之间关闭COM_CTRL。
{
WkUp_EarPhone_Debounce = 0;
Cover_Close_Flag = 1;
Cover_Open_Flag = 0;
CoverEvent_Flg = 0;
Vox_Vout_Enable = ON;
Boost_Open_Flag = 0;
Boost_Open_Atleast_Tim_Cnt = 0;
COM_CTRL = OFF;
}
else //2、开盖处理Vox 5V输出500ms用于唤醒耳机500ms后vox设置为ADT模式关Boost。
{
Cover_Close_Flag = 0;
/*开启VOUT 500ms用于唤醒耳机。*/
if( WkUp_EarPhone_Debounce < EARPHONR_WKUP_CNT ) //debounce 500ms
{
if( (VOX_CTL0 & 0x30) != 0x30 ) //1、当前已经开启了VOUT则无需重复开启原因在使能VOUT前需要先关闭VOUT使能如果连续开会出现一段时间断开的情况。
{
VOX_EN_Type(VOX_VOUT_Mode);
}
WkUp_EarPhone_Debounce++;
}
else
{
BST_EN = 0; //Boost Disable
Cover_Open_Flag = 1;
CoverEvent_Flg = 0;
Boost_Open_Flag = 0;
VOX_EN_Type(VOX_ADT_Mode);
}
}
}
else
{
VOX_EN_Type(VOX_ADT_Mode);
}
}
if( Cover_Open_Flag || Cover_Close_Flag || EarPhone_ShutDown_Flag )
{
/*间隔300ms发送指令持续5s关盖间隔之间开启VOUT;开盖间隔之间开启ADT。*/
if(Vox_TX_Timer < VOX_TX_CNT)
{
if( (Vox_TX_Timer % Vox_TX_Interval) == 0 ) //200ms发送一次
{
if( EarPhone_ShutDown_Flag )
{
#ifdef VOX_TX
HandleTxCommand(CMD_SHUT_DOWN,VOX_BOTH); /*耳机电池充满或仓处于低电,发关机指令*/
#endif
#ifdef _DEBUG_VOX
printf("Shut Down,Cnt:%d\r\n",(uint16_t)Vox_TX_Timer);
#endif
}
else
if( CoverStatus == CLOSE )
{
#ifdef VOX_TX
HandleTxCommand(CMD_BOX_CLOSE,VOL_CHAN); //发送关盖指令 ,按耳机通道发。
#endif
#ifdef _DEBUG_VOX
printf("Cover Close,Cnt:%d\r\n",(uint16_t)Vox_TX_Timer);
#endif
}
else
if( CoverStatus == OPEN )
{
#ifdef VOX_TX
HandleTxCommand(CMD_BOX_OPEN,VOX_BOTH); //发开盖指令,不区分耳机通道。
#endif
#ifdef _DEBUG_VOX
printf("Cover Open,Cnt:%d\r\n",(uint16_t)Vox_TX_Timer);
#endif
}
}
else
if( (Vox_TX_Timer % (Vox_TX_Interval + 1) ) == 0 ) //300ms发送一次
{
if( CoverStatus == CLOSE )
{
#ifdef VOX_TX
HandleTxCommand(CMD_BOX_CLOSE,VOR_CHAN); //发送关盖指令 ,按耳机通道发。
#endif
}
}
else
{
if( CoverStatus == OPEN ) //Vox处于ADT模式开启COM_CTRL用于识别耳机入仓。
{
COM_CTRL = ON;
}
}
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( CoverStatus == CLOSE ) //关盖发送完相应的指令后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; //为了后面10s发送SHUT_DOWN指令。
}
}
if( !BES_Rst_Puls_Flag )
{
BES_Rst_Puls_Timer++;
if( BES_Rst_Puls_Timer > BES_RST_PULS_CNT ) //关盖后5+2s后发送BES 复位 pattern
{
BES_Rst_Puls_Flag = 1;
#ifdef _DEBUG_VOX
printf("Bes Reset.\r\n");
#endif
#ifdef VOX_TX
SFRADDR = MFP_CTL0; //Set P01 Pinmux As GPIO Function,目的保证BES Reset Pattern低电平能拉到0V
SFRDATA &= ~0x0C;
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( (VOX_CTL0 & 0x30) != 0x30 ) //1、当前已经开启了VOUT则无需重复开启原因在使能VOUT前需要先关闭VOUT使能如果连续开会出现一段时间断开的情况。
{
VOX_EN_Type(VOX_VOUT_Mode);
}
}
else
if( CoverStatus == OPEN )
{
Cover_Open_Flag = 0;
#ifdef VOX_TX
// HandleTxCommand(CMD_BES_HEARTBEAT,VOX_BOTH); //发心跳包指令,不区分耳机通道。心跳包指令如何发?间隔多久发一次?发多久?
#endif
}
COM_CTRL = ON;
}
}
}
#ifdef VOX_TX
/*
*******************************************************************************
* void HandleTxCommand(VOX_BES_COMMAND_E RxCommand, e_Vox_Chan nVox_Chn_Select)
*
* Description : 发送数据包的封装,并打开相应的双向通信通道
* Command payload
* --Header--cmd----len_h---len_l-----Data------CRC16
* 4bytes 2byte 1byte 1byte Len bytes 1byte
*
* Arguments : VOX_BES_COMMAND_E TxCommand: , e_Vox_Chan nVox_Chn_Select
* Returns :
*
* Notes :
*
*******************************************************************************
*/
uint8_t BES_ShutDown_State = 0; //耳机关机状态0耳机满电1盒子低电
uint8_t BES_Addr[2][6] = 0; //耳机蓝牙地址BES_Addr[0][6]左耳BES_Addr[1][6]:右耳。
void HandleTxCommand(VOX_BES_COMMAND_E TxCommand, e_Vox_Chan nVox_Chn_Select)
{
uint8_t tx_pData[14] = 0;
uint8_t i = 0;
/*数据包头*/
tx_pData[0] = BOXHEADER>>8;
tx_pData[1] = BOXHEADER;
/*耳机通道*/
tx_pData[3] = nVox_Chn_Select;
/*指令编号*/
tx_pData[4] = TxCommand;
/*RW*/
tx_pData[5] = 0x00;
switch(TxCommand)
{
case CMD_BOX_OPEN:
/*Data Length*/
tx_pData[6] = 0x02;
tx_pData[7] = bat_level;
tx_pData[8] = FW_VER;
break;
case CMD_BOX_CLOSE:
/*Data Length*/
tx_pData[6] = 0x08;
tx_pData[7] = bat_level;
tx_pData[8] = FW_VER;
for(i=0 ;i<6;i++)
{
tx_pData[9] += BES_Addr[nVox_Chn_Select][i]; //获取耳机蓝牙地址。
}
break;
case CMD_SHUT_DOWN:
/*Data Length*/
tx_pData[6] = 0x03;
tx_pData[7] = bat_level;
tx_pData[8] = FW_VER;
tx_pData[9] = BES_ShutDown_State;
break;
case CMD_BES_PAIRING:
/*Data Length*/
tx_pData[6] = 0x08;
for(i=0 ;i<6;i++)
{
tx_pData[7] += BES_Addr[nVox_Chn_Select][i]; //获取耳机蓝牙地址。
}
tx_pData[13] = 0x03; //是否重新让耳机配对
tx_pData[14] = 0x03; //耳机在和的个数
break;
case CMD_BES_CLEAN:
break;
#if 0
case CMD_BES_HEARTBEAT:
/*Data Length*/
tx_pData[6] = 0x03;
tx_pData[7] = bat_level;
tx_pData[8] = FW_VER;
break;
case CMD_OTA:
/*Data Length*/
tx_pData[6] = 0x03;
tx_pData[7] = bat_level;
tx_pData[8] = FW_VER;
break;
#endif
case BES_RESET: //BES 复位patten
BES_Puls_Start = 1;
return;
default:
break;
}
for(i=3 ;i<(tx_pData[6] + 4);i++)
{
tx_pData[2] += tx_pData[i]; //求校验和
}
COM_CTRL = OFF; //VOX切换到通讯TX功能模式1.8V)。
#if UART0_ENABLE
Uart0SendPacket(tx_pData[6] + 6, tx_pData);
#endif
}
#endif
#ifdef VOX_RX
/*
*******************************************************************************
* char HandleRxCommand(ACK_TYPE_E RxCommand)
*
* Description : 耳机端发送的数据包的解析及处理
* Ack payload:
* Header cmd Ack type len_h len_l Data CRC16
* 4bytes 2byte 1byte 1byte 1byte Len bytes 1byte
*
* Arguments : ACK_TYPE_E RxCommand:
* Returns :
*
* Notes :
*
*******************************************************************************
*/
uint8_t Vox_BatLevel[2] = 0; //耳机电量Vox_BatLevel[0]:VOL;Vox_BatLevel[1]:VOR
uint8_t Vox_Pairing_State[2] = 0; //耳机配对状态0是无效1是正在配对2是配对成功3不处理保持当前状态。
uint8_t Vox_Paired_State[2] = 0; //耳机配对记录1是有过配对记录0是没有
uint8_t Bes_OTA_Ver[2] = 0; //耳机OTA版本号
char HandleRxMsg(VOX_BES_COMMAND_E RxCommand)
{
uint8_t i = 0;
uint8_t j = 0;
switch(RxCommand)
{
case CMD_BOX_OPEN:
if( RX0_Buffer[3] == VOL_CHAN ) //根据耳机Side参数
{
Vox_BatLevel[VOL_CHAN] = RX0_Buffer[7]; //获取左耳机电量
Vox_Pairing_State[VOL_CHAN] = RX0_Buffer[8]; //获取左耳机配对状态
Vox_Paired_State[VOL_CHAN] = RX0_Buffer[9]; //获取左耳机配对记录
}
else
{
Vox_BatLevel[VOR_CHAN] = RX0_Buffer[7]; //获取右耳机电量
Vox_Pairing_State[VOR_CHAN] = RX0_Buffer[8]; //获取右耳机配对状态
Vox_Paired_State[VOR_CHAN] = RX0_Buffer[9]; //获取右耳机配对记录
}
break;
case CMD_BOX_CLOSE:
if( RX0_Buffer[3] == VOL_CHAN ) //根据耳机Side参数
{
Vox_BatLevel[VOL_CHAN] = RX0_Buffer[7]; //获取左耳机电量
Vox_Pairing_State[VOL_CHAN] = RX0_Buffer[8]; //获取左耳机配对状态
Vox_Paired_State[VOL_CHAN] = RX0_Buffer[9]; //获取左耳机配对记录
for(i=10 ;i<6;i++)
{
BES_Addr[VOL_CHAN][i-10] += RX0_Buffer[i]; //获取左耳机蓝牙地址。
}
Bes_OTA_Ver[VOL_CHAN] = RX0_Buffer[16]; //获取左耳机OTA版本。
}
else
{
Vox_BatLevel[VOR_CHAN] = RX0_Buffer[7]; //获取右耳机电量
Vox_Pairing_State[VOR_CHAN] = RX0_Buffer[8]; //获取右耳机配对状态
Vox_Paired_State[VOR_CHAN] = RX0_Buffer[9]; //获取右耳机配对记录
for(i=10 ;i<6;i++)
{
BES_Addr[VOR_CHAN][i-10] += RX0_Buffer[i]; //获取右耳机蓝牙地址。
}
Bes_OTA_Ver[VOR_CHAN] = RX0_Buffer[16]; //获取右耳机OTA版本。
}
break;
case CMD_SHUT_DOWN:
break;
case CMD_BES_PAIRING:
if( RX0_Buffer[3] == VOL_CHAN ) //根据耳机Side参数
{
for(i=7 ;i<6;i++)
{
BES_Addr[VOL_CHAN][i-7] += RX0_Buffer[i]; //获取左耳机蓝牙地址。
}
Vox_Pairing_State[VOL_CHAN] = RX0_Buffer[13]; //获取左耳机配对状态
Vox_BatLevel[VOL_CHAN] = RX0_Buffer[14]; //获取左耳机电量
}
else
{
for(i=7 ;i<6;i++)
{
BES_Addr[VOR_CHAN][i-7] += RX0_Buffer[i]; //获取右耳机蓝牙地址。
}
Vox_Pairing_State[VOR_CHAN] = RX0_Buffer[13]; //获取右耳机配对状态
Vox_BatLevel[VOR_CHAN] = RX0_Buffer[14]; //获取右耳机电量
}
break;
case CMD_BES_CLEAN:
break;
#if 0
case CMD_BES_HEARTBEAT:
if( RX0_Buffer[3] == VOL_CHAN ) //根据耳机Side参数
{
Vox_BatLevel[VOL_CHAN] = RX0_Buffer[7]; //获取左耳机电量
Vox_Pairing_State[VOL_CHAN] = RX0_Buffer[8]; //获取左耳机配对状态
Vox_Paired_State[VOL_CHAN] = RX0_Buffer[9]; //获取左耳机配对记录
}
else
{
Vox_BatLevel[VOR_CHAN] = RX0_Buffer[7]; //获取右耳机电量
Vox_Pairing_State[VOR_CHAN] = RX0_Buffer[8]; //获取右耳机配对状态
Vox_Paired_State[VOR_CHAN] = RX0_Buffer[9]; //获取右耳机配对记录
}
break;
#endif
default:
break;
}
return 1;
}
/*
*******************************************************************************
* void HandleVoxCommMsg(void)
*
* Description : Vox 通讯功能处理函数10ms定时调用。由于和耳机通信前需要打开耳机端的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 == 1)
{
Uart0_RX_Finish_Flag = 0;
for(i=3 ;i<(RX0_Buffer[6] + 4);i++) //计算校验和
{
CrcCheckSum += RX0_Buffer[i]; //求校验和
}
if( CrcCheckSum == RX0_Buffer[2] )
{
HandleRxMsg((VOX_BES_COMMAND_E)RX0_Buffer[4]);
}
}
}
#endif
#ifdef VOX_TX
/*
*******************************************************************************
* void BES_Reset_Puls(void)
*
* Description : BES Reset用于产生蓝牙耳机复位时序。 (5ms调用周期)
* Vox TX BES PlusVOX发送如下时序给耳机端。
* 5T Low + 1T High + 1T lOW + 1T High + 1T Low + 1T High + 1T Low + 1T High + 1T Low + 2T Low + 2T High + 1T Low + 1T High + 1T Low + 1T High + 1T Low + 1T High + 1T Low
* _ _ _ _ _ _ _ _ _
*0 0 0 0 0 |1|0|1|0|1|0|1|0 0|1 1|0|1|0|1|0|1|0
*__________| |_| |_|_|_|_|___|___|_|_|_|_|_|_|_______
* Arguments : NONE
* Returns : NONE
* Notes : NONE
*
*******************************************************************************
*/
void BES_Reset_Puls(void)
{
if(BES_Puls_Start)
{
if(BES_Puls_Cnt <= 4) //持续5个低电平后加一高电平
{
COM_CTRL = OFF;
}
else
{
if(BES_Puls_Cnt%2)
{
if(BES_Puls_Cnt == 13)
{
COM_CTRL = OFF;
}
else
{
COM_CTRL = ON;
}
}
else
{
if(BES_Puls_Cnt == 14)
{
COM_CTRL = ON;
}
else
{
COM_CTRL = OFF;
}
}
}
BES_Puls_Cnt++;
if(BES_Puls_Cnt >= 23)
{
BES_Puls_Start = 0;
BES_Puls_Cnt = 0;
}
}
}
#endif
#endif