/*
 * File:   __GP22GAS_IR_APP_C
 * Author:
 *
 * Created on：2016-3-7
 */

#ifdef __cplusplus
extern "C"
{
#endif
	

#include "UWater_ir_app.h"
#include "UWater_frame_app.h"
#include "UWater_timer1uS_driver.h"
#include "UWater_uart_driver.h"
#include "UWater_lcd_app.h"
#include "UWater_key_app.h"
#include "UWater_DebugPrint.h"
	
u8 s_g_ir_control_state = IR_CONTROL_S0;
u8 s_g_ir_state = 0;

/************************************************
Function: void UartIrOpen()
Description: 打开红外
Input:
return: 
Others:
 *************************************************/
void UartIrOpen(void)
{

    IR_38KCarrier_Close();
    
    Gpio_WriteOutputIO(IR_UART_CTL_PORT, IR_UART_CTL_PIN, FALSE);
    UartInit(IR_UART_COM, BAUD2400, DATA_BIT_8, STOPBIT_1, UART_EVEN_PARITY, UART_LPUART_Disable);
}

/************************************************
Function: void UartIrClose()
Description: 关闭红外
Input:
return: 
Others:
 *************************************************/
void UartIrClose(void)
{
//    Sysctrl_SetPeripheralGate(SysctrlPeripheralBaseTim, FALSE); //Base Timer外设时钟关闭
	Bt_M0_Stop(TIM2);
				
	UartPreSleep(IR_UART_COM);
	Gpio_WriteOutputIO(IR_UART_CTL_PORT, IR_UART_CTL_PIN, TRUE);//电源控制脚开漏输出高，红外模块断电	
	
	//配置红外接收RX口为输出，输出低，为了防止红外接收芯片漏电	
	stc_gpio_cfg_t stcGpioCfg;
	DDL_ZERO_STRUCT(stcGpioCfg);	
	stcGpioCfg.enDir = GpioDirOut;    ///< 端口方向配置	
	stcGpioCfg.enDrv = GpioDrvL;      ///< 端口驱动能力配置->低驱动能力	
	stcGpioCfg.enPu = GpioPuDisable;  ///< 端口上下拉配置->无
	stcGpioCfg.enPd = GpioPdDisable;	
	stcGpioCfg.enOD = GpioOdDisable;  ///< 端口开漏输出配置
	stcGpioCfg.enCtrlMode = GpioAHB;  ///< 端口输入/输出值寄存器总线控制模式配置->AHB
	Gpio_Init(LPUART0_RX_PORT, LPUART0_RX_PIN, &stcGpioCfg);
	Gpio_WriteOutputIO(LPUART0_RX_PORT, LPUART0_RX_PIN, FALSE);	
	Gpio_Init(LPUART0_TX_PORT, LPUART0_TX_PIN, &stcGpioCfg);
	Gpio_WriteOutputIO(LPUART0_TX_PORT, LPUART0_TX_PIN, TRUE);	//TX也配置为输出高
    Gpio_Init(IR_38K_PORT, IR_38K_PIN, &stcGpioCfg);
    Gpio_SetAfMode(IR_38K_PORT,IR_38K_PIN,GpioAf0); //普通IO
	Gpio_WriteOutputIO(IR_38K_PORT, IR_38K_PIN, TRUE);//38K引脚输出为高
   
}
	
/************************************************
Function: void IrInitApp()
Description: 初始化
Input:
return: 
Others:
 *************************************************/
void IrInitApp(void)
{	
    IR_Uart_38K_Config();

    //< RX 控制脚初始化
	stc_gpio_cfg_t stcGpioCfg;
	DDL_ZERO_STRUCT(stcGpioCfg);	
	stcGpioCfg.enDir = GpioDirOut;    ///< 端口方向配置	
	stcGpioCfg.enDrv = GpioDrvL;      ///< 端口驱动能力配置->低驱动能力	
	stcGpioCfg.enPu = GpioPuDisable;  ///< 端口上下拉配置->无
	stcGpioCfg.enPd = GpioPdDisable;	
	stcGpioCfg.enOD = GpioOdEnable;  ///< 端口开漏输出配置
	stcGpioCfg.enCtrlMode = GpioAHB;  ///< 端口输入/输出值寄存器总线控制模式配置->AHB	
	Gpio_Init(IR_UART_CTL_PORT, IR_UART_CTL_PIN, &stcGpioCfg);	
	Gpio_WriteOutputIO(IR_UART_CTL_PORT, IR_UART_CTL_PIN, TRUE);	

	UartIrOpen();    
	s_g_ir_control_state = IR_CONTROL_S0;
	FrameSetMsgApp(MsgOpenIr);
}

/************************************************
Function: IrIfSleepApp()
Description: 查询应用层模块是否允许进入休眠
Input:
return: 1 允许休眠    0不允许休眠
Others:
 *************************************************/
u8 IrIfSleepApp(void)
{
	if( IR_CONTROL_S0 == s_g_ir_control_state)
    {
        return TRUE;
    }
    return FALSE;
}
u8 IrIfInS0WakeTime(void)
{
	if(s_g_ir_control_state == IR_CONTROL_S0)
	{
		return TRUE;
	}
	return FALSE;
}
/************************************************
Function: IrMachineApp()
Description: 
Input:
return: 
Others:
 *************************************************/
void IrMachineApp(void)
{
	switch (s_g_ir_control_state)
	{
		case IR_CONTROL_S0:
		{
			if(FrameCheckMsgApp(MsgOpenIr))
			{
				FrameClearMsgApp(MsgOpenIr);
				Set100msTimer(TIMER_100MS_IR_OPEN, 600);//复位之后定时60秒,关闭
				s_g_ir_control_state = IR_CONTROL_S1;
			}
			else if(KeyCheckIrOpenMsg() == TRUE )//检测到按键消息
			{
				KeyClearIrOpenMsg();//清除消息
				Set100msTimer(TIMER_100MS_IR_OPEN, 200);//按键唤醒定时20秒,关闭
				s_g_ir_control_state = IR_CONTROL_S1;
			}
			break;
		}
		case IR_CONTROL_S1:
		{
				if(TASK_IDLE == UartIfIdle(IR_UART_COM))
				{
					UartIrOpen();
					s_g_ir_control_state  = IR_CONTROL_S2;
				}
			
			break;
		}
		case IR_CONTROL_S2:
		{
			//非检定且时间到
			if((0 == Check100msTimer(TIMER_100MS_IR_OPEN)) && 
				(TASK_IDLE == UartIfIdle(IR_UART_COM))&&
				(10 == LcdCheckStateApp())&&
				(FALSE ==GetPrintNbDataSwitch()&&
				(FrameIfSleepApp() == TRUE)))
			{
				UartIrClose();
				KeyClearIrOpenMsg();//清除消息
				s_g_ir_control_state  = IR_DEAL_S0;
			}
			break;
		}
		default:
		{
			s_g_ir_control_state  = IR_DEAL_S0;
			break;
		}
	}
}
/*************************************************
Function: static void IR_Uart_38K_Config(void)
Description: 红外38K 配置PWM相关寄存器
Input:  无
Return: 无
Others: 
*************************************************/
void IR_Uart_38K_Config(void)
{
#if IR_38K_OPEN    
    u16 u16ArrValue;
    u16 u16CntValue;
	u16 u16Period;
    stc_bt_mode0_cfg_t stcBtBaseCfg;
	stc_gpio_cfg_t stcTIM1APort;	  
	
    DDL_ZERO_STRUCT(stcTIM1APort);  
	DDL_ZERO_STRUCT(stcBtBaseCfg);
    //PA03设置为TIM2_CHB
    stcTIM1APort.enDir  = GpioDirOut;
    Gpio_Init(IR_38K_PORT, IR_38K_PIN, &stcTIM1APort);
    Gpio_SetAfMode(IR_38K_PORT,IR_38K_PIN,IR_38K_AF); 	
    Sysctrl_SetPeripheralGate(SysctrlPeripheralBaseTim, TRUE); //Base Timer外设时钟使能
    
    stcBtBaseCfg.enWorkMode = BtWorkMode0;                  //定时器模式
    stcBtBaseCfg.enCT       = BtTimer;                      //定时器功能，计数时钟为内部PCLK
    stcBtBaseCfg.enPRS      = BtPCLKDiv1;                   //PCLK/3
    stcBtBaseCfg.enCntMode  = Bt16bitArrMode;               //自动重载16位计数器/定时器
    stcBtBaseCfg.bEnTog     = TRUE;
    stcBtBaseCfg.bEnGate    = FALSE;
    stcBtBaseCfg.enGateP    = BtGatePositive;
    
    Bt_Mode0_Init(TIM2, &stcBtBaseCfg);                     //TIM2 的模式0功能初始化8 *
    
	u16Period = Sysctrl_GetPClkFreq() /(2 * 38000); 
    u16ArrValue = 0x10000 - u16Period;
    Bt_M0_ARRSet(TIM2, u16ArrValue);                        //设置重载值(ARR = 0x10000 - 周期)    
    u16CntValue = 0x10000 - u16Period;    
    Bt_M0_Cnt16Set(TIM2, u16CntValue);                      //设置计数初值    
    Bt_M0_Enable_Output(TIM2, TRUE);                         //TIM2 端口输出使能
		
#endif	
}
//
void IR_Uart_38K_PreSleep(void)
{
	Sysctrl_SetPeripheralGate(SysctrlPeripheralBaseTim, FALSE); //Base Timer外设时钟关闭
	Bt_M0_Stop(TIM2);			

	Gpio_WriteOutputIO(IR_UART_CTL_PORT, IR_UART_CTL_PIN, TRUE);//电源控制脚开漏输出高，红外模块断电	
	
	//配置红外接收RX口为输出，输出低，为了防止红外接收芯片漏电	
	stc_gpio_cfg_t stcGpioCfg;
	DDL_ZERO_STRUCT(stcGpioCfg);	
	stcGpioCfg.enDir = GpioDirOut;    ///< 端口方向配置	
	stcGpioCfg.enDrv = GpioDrvL;      ///< 端口驱动能力配置->低驱动能力	
	stcGpioCfg.enPu = GpioPuDisable;  ///< 端口上下拉配置->无
	stcGpioCfg.enPd = GpioPdDisable;	
	stcGpioCfg.enOD = GpioOdDisable;  ///< 端口开漏输出配置
	stcGpioCfg.enCtrlMode = GpioAHB;  ///< 端口输入/输出值寄存器总线控制模式配置->AHB
	Gpio_Init(LPUART0_RX_PORT, LPUART0_RX_PIN, &stcGpioCfg);
	Gpio_WriteOutputIO(LPUART0_RX_PORT, LPUART0_RX_PIN, FALSE);	
	Gpio_Init(LPUART0_TX_PORT, LPUART0_TX_PIN, &stcGpioCfg);
	Gpio_WriteOutputIO(LPUART0_TX_PORT, LPUART0_TX_PIN, TRUE);	//TX也配置为输出高
    Gpio_Init(IR_38K_PORT, IR_38K_PIN, &stcGpioCfg);
    Gpio_SetAfMode(IR_38K_PORT,IR_38K_PIN,GpioAf0); //普通IO
	Gpio_WriteOutputIO(IR_38K_PORT, IR_38K_PIN, TRUE);//38K引脚输出为高
}
//
//void IR_Uart_38K_Enable(boolean_t enCmd)
//{
//#if IR_38K_OPEN
//	if(TRUE == enCmd)
//	{ 
//		UartInit(IR_UART_COM,BAUD2400,DATA_BIT_8,STOPBIT_1,UART_EVEN_PARITY,UART_LPUART_Disable);//UART_EVEN_PARITY    UART_NONE_PARITY
//		IR_Uart_38K_Config();
//		Bt_M0_Run(TIM2);        //TIM2 运行
//				
//		Gpio_WriteOutputIO(IR_UART_CTL_PORT, IR_UART_CTL_PIN, FALSE);		
//	}
//	else
//	{		
//		Gpio_WriteOutputIO(IR_38K_PORT,IR_38K_PIN, TRUE);//38K引脚输出为高
//		Gpio_WriteOutputIO(IR_UART_CTL_PORT, IR_UART_CTL_PIN, TRUE);//电源控制脚开漏输出高，红外模块断电			
//		//配置红外接收RX口为输出，输出低，为了防止红外接收芯片漏电	
//		stc_gpio_cfg_t stcGpioCfg;
//		DDL_ZERO_STRUCT(stcGpioCfg);	
//		stcGpioCfg.enDir = GpioDirOut;    ///< 端口方向配置	
//		stcGpioCfg.enDrv = GpioDrvL;      ///< 端口驱动能力配置->低驱动能力	
//		stcGpioCfg.enPu = GpioPuDisable;  ///< 端口上下拉配置->无
//		stcGpioCfg.enPd = GpioPdDisable;	
//		stcGpioCfg.enOD = GpioOdDisable;  ///< 端口开漏输出配置
//		stcGpioCfg.enCtrlMode = GpioAHB;  ///< 端口输入/输出值寄存器总线控制模式配置->AHB
//		Gpio_Init(LPUART0_RX_PORT, LPUART0_RX_PIN, &stcGpioCfg);
//		Gpio_WriteOutputIO(LPUART0_RX_PORT, LPUART0_RX_PIN, FALSE);	
//		Gpio_Init(LPUART0_TX_PORT, LPUART0_TX_PIN, &stcGpioCfg);
//		Gpio_WriteOutputIO(LPUART0_TX_PORT, LPUART0_TX_PIN, TRUE);	//TX也配置为输出高
//		Gpio_WriteOutputIO(IR_38K_PORT, IR_38K_PIN, TRUE);//38K引脚输出为高
//	}
//#endif
//}

/*************************************************
Function: void IR_38K_Open(void)
Description: 红外38K 配置PWM相关寄存器,并开启38K载波
Input:  无
Return: 无
Others: 
*************************************************/
void IR_38KCarrier_Open(void)
{
    IR_Uart_38K_Config();
    Bt_M0_Run(TIM2); 

}

/*************************************************
Function: void IR_38K_Close(void)
Description: 关闭38K载波，把该引脚配置为输出高
Input:  无
Return: 无
Others: 
*************************************************/
void IR_38KCarrier_Close(void)
{
    Bt_M0_Stop(TIM2); 
    stc_gpio_cfg_t stcGpioCfg;
	DDL_ZERO_STRUCT(stcGpioCfg);	
	stcGpioCfg.enDir = GpioDirOut;    ///< 端口方向配置	
	stcGpioCfg.enDrv = GpioDrvL;      ///< 端口驱动能力配置->低驱动能力	
	stcGpioCfg.enPu = GpioPuDisable;  ///< 端口上下拉配置->无
	stcGpioCfg.enPd = GpioPdDisable;	
	stcGpioCfg.enOD = GpioOdDisable;  ///< 端口开漏输出配置
	stcGpioCfg.enCtrlMode = GpioAHB;  ///< 端口输入/输出值寄存器总线控制模式配置->AHB
    Gpio_Init(IR_38K_PORT, IR_38K_PIN, &stcGpioCfg);
    Gpio_SetAfMode(IR_38K_PORT,IR_38K_PIN,GpioAf0); //普通IO
	Gpio_WriteOutputIO(IR_38K_PORT, IR_38K_PIN, TRUE);//38K引脚输出为高

}




#ifdef __cplusplus
}
#endif		//#ifdef __cplusplus

