/*
 ******************************************************************************
 *
 * @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 "adc.h"
#include "gpio_comm.h"
#include "userapp.h"
#include "key.h"

bit Vox_Vout_Enable = OFF;						//Vox功率输出标志位
bit Earphone_Chg_Flag = 0;						//耳机出入盒标志位
uint8_t Vox_TX_Timer = 0;						//VOX发送指令持续时间计数,在Hall_Handler检测中清0.

#if VOX_ENABLE

/******************************************************************************\
                          Macro definitions
\******************************************************************************/
/*100ms调用周期*/
#define VOX_OUTPUT_SHORT_CNT		2
#define VOX_LOW_BAT_CNT				25					//关盖前，盒子低电保护，Vox 5V持续2.5s  	
#define VOX_VOUT_5V_LEAST_CNT		50	

#define VOX_VOUT_5V_DEBOUNCE		5					
#define VOX_ADT_HOLD_CNT			3
#define Vox_TX_Pattern_Cnt			3

#define BOOST_VOUT_MAX				2					//跟随充Boost输出电压上限值：0:4.6V,1:4.7V,2:4.8V,3:5.05V.

#define Vox_TX_Pattern_Tim			10

#define Vox_TX_Interval				2  					//Vox定时发送指令时间间隔

/******************************************************************************\
                             Variables definitions
\******************************************************************************/


uint8_t Vox_Vol_Hold_Timer = 0;

bit Cover_Close_Flag = 0;
bit Cover_Close_Flag1 = 0;

bit Cover_Open_Flag = 0;
bit Vox_Vout_5V_Flag = 0;

uint8_t Vox_Output_Debounce = 0;

bit Get_CHIP_STA1_Flag = 0;

bit Pattern_TX_Over_Flag = 0;

uint8_t CHIP_STA1_BK = 0;

bit Cover_Open_5V_Flag = 0;

#if VOX_FOLLOW_CHG

bit Boost_VoxVout_Follow_Flag = 0;
int8 Boost_Vout_Value = 0;
bit Boost_Up_Flag = 0;

#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( 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 	
	}
}
/*
*******************************************************************************
*			 void Vox_Det_Machine(void)
*
* Description : Vox Detect:耳机识别。 (100ms调用周期)
*
* Arguments	 : NONE

* Returns	 : NONE

* Notes		 : NONE
*
*******************************************************************************
*/
void Vox_Det_Machine(void)
{
	/*Vox 过流保护，两只耳机都每隔200ms打嗝一次*/
	if( IRQ_FLAG0 & 0x0C )
	{		
		Vox_Output_Debounce++;
		if( Vox_Output_Debounce >= VOX_OUTPUT_SHORT_CNT )		//Vox短路保护200ms后，重新开启Vox 5V。
		{
			Vox_Output_Debounce = 0;
			IRQ_FLAG0 = 0x0C;
			VOX_EN_Type(VOX_VOUT_Mode);	
			return;
		}
	}	

	if( CoverEvent_Flg )								//Hall事件触发。
	{	
		if( gBoost_Prepared_Flag )
		{				
			COM_CTRL = ON;
			
			if( !F_batlevel_low )                    //电压低于3.3V不升压，但需要走开关盖逻辑，用于灯效显示。
			{
				if( !BST_EN )
				{			
					BST_EN = 1; 
					return;
				}	

				VOX_EN_Type(VOX_VOUT_Mode);		 		//VOX Enable 5V，开启VOX端的NMOS			
			}
			
			if( CoverStatus == CLOSE )    				//1、关盖关闭COM_CTRL；显示灯效。（无需查询Loadon、IOFF状态，无论耳机是否在仓，Vox 5V输出。）
			{
#if VOX_FOLLOW_CHG
			
				if( BST_EN )
				{		
					/*跟随充逻辑*/
					SFRADDR = BST_CTL0;									//Boost 5V输出
					SFRDATA |= 0x03;
					Boost_Vout_Value = 0x03;
					Boost_Up_Flag = 0;
					
					SFRADDR = VOX_CON0;									//IOFF选择高电流档10/15/20/25mA
					SFRDATA |= 0x20;	

					SFRADDR = VOX_CON2;									 
					SFRDATA &= ~0xC0;
					SFRDATA |= 0x80;									//IOFF 20mA		
				}	
				
#endif
			
				Cover_Close_Flag = 1;
								
				CoverEvent_Flg = 0;		
				
				Vox_Vout_Enable = ON;
				
				Cover_Open_Flag = 0;

				Vox_Vol_Hold_Timer = 0;					//关盖清0，开盖使用
				
#if VOX_FOLLOW_CHG
				Boost_VoxVout_Follow_Flag = 1;
#endif				

			}
			else										//2、开盖处理：5v 500ms 转0V 500ms，后转ADT模式。
			{			
				
				Cover_Close_Flag = 0;
				
				Vox_Vol_Hold_Timer = 0;
				
				Cover_Open_Flag = 1;

				Get_CHIP_STA1_Flag = 0;

				CoverEvent_Flg = 0;		

				Cover_Open_5V_Flag = 0;	

				Vox_Output_Debounce = 0;	

			}		
		} 
		else
		{			
			VOX_EN_Type(VOX_ADT_Mode);

			Vox_Vout_Enable = OFF;

			CoverEvent_Flg = 0;	
		}
	}

	/* 发送开盖指令*/
	if( Cover_Open_Flag )										/*开盖后，5V持续500ms后0V持续500ms，Vox转入adt模式，等待耳机出入盒，并显示相应的灯效。*/
	{
		if( Vox_Vol_Hold_Timer < VOX_VOUT_5V_DEBOUNCE )						//开盖后5V 500ms。
		{
			Vox_Vol_Hold_Timer++;
			
			return;
		}
		
		if( Vox_TX_Timer < VOX_VOUT_5V_DEBOUNCE )							//转0V 500ms
		{
			COM_CTRL = OFF;

			BST_EN = 0;	
			
			Vox_TX_Timer++;

			Pattern_TX_Over_Flag = 1;
		}
		else
		{
			if( Pattern_TX_Over_Flag )                                 		//转adt模式，用于后续识别耳机出入仓检测
			{
				Pattern_TX_Over_Flag = 0; 
				
				COM_CTRL = ON;
				
				Vox_Vout_Enable = OFF;
				
				VOX_EN_Type(VOX_ADT_Mode);  
			}
			else
			{
				if( !Get_CHIP_STA1_Flag )
				{
					Get_CHIP_STA1_Flag = 1;
					
					CHIP_STA1_BK = CHIP_STA1 & 0xA0;						//获取耳机loadon状态
				}
			}
			
			if( Get_CHIP_STA1_Flag )
			{
				/*耳机出入盒判断*/
				if( CHIP_STA1_BK != (CHIP_STA1 & 0xA0) )					//查询耳机loadon状态，loadon状态改变，则说明有耳机出入盒。
				{
					Earphone_Chg_Flag = 1;	

					Earphone_Chg_LED_On_Timer = 0;
					
					CHIP_STA1_BK = CHIP_STA1 & 0xA0;
				}
				
#if KEY_ENABLE
				/*开盖状态下，长按按键5s，则VOX发送数据：55 AA 02 06 DD BA*/
				if( Key_Press_ll_irq )
				{	
					if( Vox_Output_Debounce < Vox_TX_Pattern_Tim )
					{
						if( (Vox_Output_Debounce % Vox_TX_Interval == 0) )
						{
							Vox_TX_Machine();
						}

						Vox_Output_Debounce++;
					}
					else
					{
						Key_Press_ll_irq = 0;
						
						Vox_Output_Debounce = 0;
					}
				}				
#endif				
			}
		}
	}
	
	if( Cover_Close_Flag )
	{			
		/*跟随充说明：
		  1、关盖后初始化Boost输出5V，IOFF 20mA；
		*/
	#if VOX_FOLLOW_CHG
	
		if( Boost_VoxVout_Follow_Flag )
		{
			if ( CHIP_STA1 & 0x0C )					//是否存在IOFF标志，存在，则Boost上升一个step，否则，Boost下降一个step。
			{
				Boost_Vout_Value += 1;								//Boost 输出上升一个step

				Boost_Up_Flag = 1;
				
				if( Boost_Vout_Value >= BOOST_VOUT_MAX )				//Boost输出达到电压上限值，则结束跟随充。
				{
					Boost_Vout_Value = BOOST_VOUT_MAX;
					
					Boost_VoxVout_Follow_Flag = 0;
					
					SFRADDR = VOX_CON0;									//IOFF选择低电流档2/3/4/5mA
					SFRDATA &= ~0x20;	

					SFRADDR = VOX_CON2;									 
					SFRDATA &= ~0xC0;
					SFRDATA |= 0x40;									//IOFF 3mA				
				}	
				
			}
			else
			{
				if( !Boost_Up_Flag )						//只在初始化找最低轻载电压时执行
				{
					Boost_Vout_Value -= 1;								//Boost 输出下降一个step
					if( Boost_Vout_Value <= 0 )
					{
						Boost_Vout_Value = 0;
					}
				}
			}
			
			SFRADDR = BST_CTL0; 								//Boost 输出
			SFRDATA |= Boost_Vout_Value;

			return;
		}

		
	#endif
	
		if( ( (CHIP_STA1 & 0xAC) == 0xAC ) || F_batlevel_low )					//耳机充满或盒子低电，则关闭Vout输出通路，关闭Boost。
		{			
			if( Vox_Vol_Hold_Timer < VOX_VOUT_5V_LEAST_CNT ) 					//重载转轻载延时5s后关闭Boost输出。
			{
				Vox_Vol_Hold_Timer++;
				
				return;
			}	
		
			BST_EN = 0; 			
					
			VOX_EN_Type(VOX_ADT_Mode);
			
			Vox_Vout_Enable = OFF;
			
			COM_CTRL = OFF;														//关MOS管，节省功耗。
		}
	}	
}

#ifdef VOX_TX

/*
*******************************************************************************
*			 void Vox_TX_Machine(void)
*
* Description : Vor Detect:耳机识别。 (100ms调用周期)
*
* Arguments	 : NONE

* Returns	 : NONE

* Notes		 : NONE
*
*******************************************************************************
*/

void Vox_TX_Machine(void)
{
	uint8_t tx_pData[7] = 0;
	
	tx_pData[0] = 0x55;
	
	tx_pData[1] = 0xAA;
	
	tx_pData[2] = 0x02;	
	
	tx_pData[3] = 0x06;
	
	tx_pData[4] = 0xDD;
	
	tx_pData[5] = 0xBA;
	
	COM_CTRL = OFF;					//VOX切换到通讯TX功能模式（3.3V）。
	
	SFRADDR = P0_PU;
	SFRDATA |= 0x02;

	SFRADDR = MFP_CTL0;
	SFRDATA |= 0x04;				//P01 as UART's TX

	Uart0SendPacket(7, tx_pData);		 //多加一个字节发送，后面要设置TX为GPIO，会导致最后一个字节没来得及发出去。

	SFRADDR = MFP_CTL0;				//Set P01 Pinmux As GPIO Function
	SFRDATA &= ~0x0C;	
	
	SFRADDR = P0_PU;	
	SFRDATA &= ~0x02;	
	
	COM_CTRL = ON;	
}

#endif

#endif

