/******************************************************************************
 * Include files
 ******************************************************************************/
#include "wdt.h"
#include "UWater_eeprom_driver.h"
#include "UWater_timer1uS_driver.h"
#include "UWater_uart_driver.h"
#include "UWater_rtcc_driver.h"
#include "UWater_adc_driver.h"
#include "UWater_lcd_driver.h"
#include "UWater_key_driver.h"
#include "UWater_lvd_driver.h"
#include "UWater_gpio_driver.h"
#include "UWater_lptimer_driver.h"
#include "UWater_clktrim_driver.h"
#include "UWater_gp22_driver.h"
#include "UWater_valve_driver.h"
#include "UWater_clktrim_driver.h"
//app
#include "sys_config.h"
#include "UWater_sys.h"
#include "UWater_gp22_app.h"
#include "UWater_pt_app.h" 
#include "UWater_lcd_app.h"
#include "UWater_Rtcc_app.h"
#include "UWater_Power_app.h"
#include "UWater_ir_app.h"
#include "UWater_frame_app.h"
#include "UWater_Key_app.h"
#include "UWater_valve_app.h"
#include "UWater_DebugPrint.h"

#include "sys_processor.h"
#include "SOE.h"
#include "eeprom_app.h"
#include "nb_upload_monitor.h"

/**
 ******************************************************************************
 ** \brief  Main function of project
 **
 ** \return uint32_t return value, if needed
 **
 ** This sample
 **
 ******************************************************************************/
M0P_SYSCTRL_TypeDef *sys_clock;
u8 sleep_num = 0;  //休眠管理查询次数
u8 McuIfSleep(void);
u8 togle = TRUE;
u8 low_power_flag = FALSE;//进行低功耗测试标志
u32 low_power_cnt =0;//用于记录低功耗测试响应秒中断时的次数
u8 rtcc_clk_source=0;

#define PRODUCTION    //批量生产程序，关闭stop下DBG，量产打开
//#define LED_DEBUG    //LED闪烁，调试使用
//extern void setuploadflag(void);
int32_t main(void)
{
	//系统初始化
	 //软件看门狗
    #if defined(PRODUCTION)
		Sysctrl_SetPeripheralGate(SysctrlPeripheralWdt,TRUE);///< 开启WDT外设时钟    
		Wdt_Init((en_wdt_func_t)0,(en_wdt_time_t)10);//1.6s，超时时配置成复位，默认DeepSleep下工作
		Wdt_Start();    //需要测试
    #endif
    Clk_Init();
	UnusedGpioInit();
	//模块初始化
    /**driver init*/
    Timer1usInit();
    LcdInit();
    PowerManageInitSys(); //电源管理初始化前必须先初始化ADC和Timer、RTCC   
    rtcc_clk_source = RtccInit(); 
	LPTimer1Init(rtcc_clk_source);
    EepInit();//lv
	#if MODULE_BLE_USED
	UartInit(BLE_UART_COM, BAUD38400, DATA_BIT_8, STOPBIT_1, UART_EVEN_PARITY, UART_LPUART_Disable);//初始化IDLE状态
	#else
	UartInit(NB_UART_COM, BAUD9600, DATA_BIT_8, STOPBIT_1, UART_NONE_PARITY, UART_LPUART_Disable);
    #endif
	LoadEepromImportantData();
	SoeInit();//用到EE参数
    Gp22Init();//用到EE参数
	KeyInit();//用到EE参数
    #if defined(VALVE)
        ValveInit();
    #endif
	#if CARD_USED
		card_init(); 
	#endif
	
	/**app init*/
    IrInitApp();
    KeyInitApp();
    Gp30InitApp(); 
    LcdInitApp();//放在 Gp30InitApp() 之后
    TempInitApp();
	SystemProcessorInit(); 
#if defined(LED_DEBUG)
		u32 LED_tickstart = Timer1usGetTick();
#endif  
    while (1)
    {
		#if defined(PRODUCTION)
			Wdt_Feed();
		#endif
        #if defined(LED_DEBUG)
        u32 LED_tickstart_new = Timer1usGetTick();
        if(LED_tickstart_new - LED_tickstart > 1000000)   //1000ms
        {
            togle = !togle;
            LED_tickstart = LED_tickstart_new;
            Gpio_WriteOutputIO(LED_PORT,LED_PIN,togle);          
        }
		#endif
		//模块处理机
		/**app machine*/
		IrMachineApp();
		KeyMachineApp();
		Gp30MachineApp();
		TempMachineApp();
		FrameMachineApp();   //位于uart状态机前，lcd状态机后
	#if (MODULE_BLE_USED)
	    ClktrimMainMachine();
		BleMainMachine();
	#else
		NbiotMainMachine();
	#endif
		AppLifeTimeCountMachine();
		SoeDealApp(); 
		SystemProcessor();
		LcdMachineApp();
		#if defined(VALVE)
			ValveMachineDriver();
            ValveDealAppMachine();
		#endif
		#if CARD_USED
			CardMachine();
		#endif
		AdcMachineDriver();
		PowerMachineSys();
		EeSysMachine();
		UartMachineDriver();
		KeyMachineDriver();
		LcdMachineDriver();
		Gp22MachineDriver();
		PrintDataMachine();
//休眠处理先往后放
		if(TRUE == McuIfSleep()) //休眠判断
        {
            sleep_num ++;
			if(sleep_num > 1)
            {	
                sleep_num = 0;
				PowerUnSleepClearSumSys();     //长时间不休眠监视清0
         
				 //各个模块休眠前处理												
				KeyPreSleep();
				Timer1usPreSleep();
				EepPreSleep();
				AdcPreSleep();
		 #if (MODULE_BLE_USED)
				BlePreSleep();
		 #else
		 		NbiotPreSleep();
				UartPreSleep(NB_UART_COM);
		 #endif  
				UartPreSleep(IR_UART_COM);	
				IR_Uart_38K_PreSleep();
				TempPreSleep();	
				Gp22PreSleep();		
				RtccPreSleep();
				PowerPreSleepSys();
				LcdPreSleep();
				SysDealAppPreSleep(); 
				#if defined(VALVE)
					ValvePreSleep();	
				#endif
				if(Gp30CheckBootloaderMsgApp()) //有远程升级则复位
				{
					Meter_ResetCountAdd(0x04);
					NVIC_SystemReset();     //reset //重启
				}       
				if(1 == FrameCheckMsgApp(LowPowerMsg))   //PCBA测试，进入低功耗
				{
                    low_power_flag = TRUE;
                    FrameClearMsgApp(LowPowerMsg);
                    stc_gpio_cfg_t stcGpioCfg;
                    DDL_ZERO_STRUCT(stcGpioCfg);
                    stcGpioCfg.enDir = GpioDirIn;
                    stcGpioCfg.enPd = GpioPdEnable;
                    Gpio_Init(GP22_INT_GPIO, GP22_INT_PIN, &stcGpioCfg);                    
                    SCB->SCR |= 0x00000004u;
                    while(low_power_flag)
                    {
                        __asm("WFI");
                        Wdt_Feed();
                        low_power_cnt++;
						if(low_power_cnt > 40) 
						{
							low_power_cnt = 0;
							low_power_flag = FALSE;
                            stc_gpio_cfg_t stcGpioCfg;
                            DDL_ZERO_STRUCT(stcGpioCfg);
                            stcGpioCfg.enDir = GpioDirIn;
                            stcGpioCfg.enPu = GpioPuEnable;
                            Gpio_Init(GP22_INT_GPIO, GP22_INT_PIN, &stcGpioCfg);
							break;
						} 
                    }
				}				
                //深度休眠模式唤醒 执行中断服务程序
                SCB->SCR |= 0x00000004u;
				for(;;)
				{  
					__asm("WFI"); 
				    Wdt_Feed();
					RecordCalculativeIntvalTimeLPTimer();
					if(0x01 == (RtccCheckMsg()&0x01))//秒中断消息继续休眠
					{
						RtccClearMsg(0);
                        if((0x02 == (RtccCheckMsg()&0x02))//RTCC分钟消息
							||(1 == GP22_Check_IntMsg()))//GP30中断消息
						{							
							break;
						}
					}
					else
					{						
						break;
					}					
				}     
                Timer1usWakeSleep();
                AdcWakeSleep();//
                RtccWakeSleep();//
                EepWakeSleep();//
                KeyWakeSleep();//
                LcdWakeSleep();//
			 #if (MODULE_BLE_USED)
				BleWakeSleep();
			 #else
			 	NbiotWakeSleep();//
			 #endif  
                #if defined(VALVE)
                    ValveWakeSleep();//
                #endif
            }
        } 
	}
}
u8 McuIfSleep(void)
{
   if((FALSE == TimerIfSleep()) ||
		(FALSE == AdcIfSleep()) ||
		(FALSE == RtccIfSleep())||
		(FALSE == PowerIfSleepSys())||
		(FALSE == EepIfSleep()) ||
		(TASK_BUSY == UartIfSleep(LPCOM0))||
		(TASK_BUSY == UartIfSleep(LPCOM1))||
		(FALSE == KeyIfSleep()) ||
		(FALSE == LcdIfSleep()) ||
		(TASK_BUSY == Gp22IfSleep())||
		((FALSE == IrIfSleepApp())&&(1 != FrameCheckMsgApp(LowPowerMsg))) ||
		(FALSE == KeyIfSleepApp()) ||
		((FALSE == FrameIfSleepApp())&&(1 != FrameCheckMsgApp(LowPowerMsg))) ||
		(FALSE == LcdIfSleepApp()) ||
		(FALSE == Gp30IfSleepApp()&&(1 != FrameCheckMsgApp(LowPowerMsg)))||
		(FALSE == TempIfSleepApp())||
		(FALSE == SystemProcessorIfSleep()&&(1 != FrameCheckMsgApp(LowPowerMsg)))||
	#if (MODULE_BLE_USED)
		(FALSE == BleIfSleep())||
		(TASK_BUSY == ClkTrimIfIdle())||
   #else
		((FALSE == NbiotIfSleep())&&(1 != FrameCheckMsgApp(LowPowerMsg)))||
   #endif
		((FALSE == AppLifeTimeCountMachineIfIdle())&&(1 != FrameCheckMsgApp(LowPowerMsg)))||
   #if defined(VALVE)
		(FALSE == ValveIfSleep())||
   #endif
		(FALSE == SaveSoeToEEIfIdle()&&(1 != FrameCheckMsgApp(LowPowerMsg)))||
		(FALSE == UartRcvMachineIfIdle(LPCOM0))||
		(FALSE == UartRcvMachineIfIdle(LPCOM1))||
		(FALSE == UartSendMachineIfIdle(LPCOM0))||
		(FALSE == UartSendMachineIfIdle(LPCOM1))||
		(TASK_BUSY == EeReadImportantDataIfIdle())
		)
    {
        return FALSE;
    }
    else
    {
        return TRUE;
    }
}
/******************************************************************************
 * EOF (not truncated)
 ******************************************************************************/
