
#include "PowerManagement.h"
#include "CAN_Communication_Matrix.h"
 
uint8_t PowerStatusBackup;
uint8_t NM_RECEIVE;
uint8_t sleepFl1g, sleepFlg;
uint8_t PWRCANResetFlag;
uint8_t SpeedBackup;
uint8_t Speedtime;
uint8_t Powerstatus;
 extern  uint8_t  PositionLightSts_Count;
 extern uint8_t  DriveDoorSts_Count;
extern INT8U HIGH_VOLTAGE;
extern INT8U LOW_VOLTAGE;
extern uint8_t DTC_STATUS[cnDTCslen];
extern uint8_t BlTurnOffDelay ;

INT8U ContrlorResumeofFUEL;
extern INT8U ContrlorResumeofTEMP;
extern INT8U ContrlorResumeofVspeed;
extern INT8U ContrlorResumeofEspeed;
extern uint8_t  ContrlorResumeofGAS1  ;  //气压1

extern uint16_t ESpeedValNUM;         //转速
extern uint16_t VspeedValNUM;         //车速
extern uint16_t ESpeedVal;            //转速
//extern uint16_t VspeedVal;            //车速
extern uint8_t TempSeg;             //水温
//extern uint16_t SOCSeg;              //SOC
uint16_t FuelSeg;             //燃油
uint16_t ADblueSeg;           //天蓝液
uint16_t OilSeg;
uint16_t GAS1_DISPLAY;                //气压1
uint16_t GAS2_DISPLAY;                //气压2
extern uint8_t  S3_ServerEN;          //扩展会话5s定时器使能开关
extern uint8_t  DiagnosticReceived;

_MeterPos				g_voltageMeter;
_MeterPos				g_currentMeter;
_MeterPos				g_EnergyFeedbackMeter;
_MeterPos				g_EnergyConsumMeter;

//extern	uint16_t WaterTempValNUM;     //水温
//extern	uint16_t FuelValNUM;          //燃油
//extern	uint16_t WaterTempVal;        //水温
//extern	uint16_t FuelVal;             //车速

uint8_t  TIME_100MS;                  //置于RTC_ISR 100ms周期
Power_Statuss  g_Power_St;            //当前实际电源状态
uint8_t  Network_Status;  
uint8_t  CanFrameExist;               //置于CAN_ISR中
uint8_t  CounterWarning;              //定时
uint8_t  tDelay1;              //定时
uint8_t  tDelay2;              //定时
uint8_t  tWaitBusSleep;              //定时
uint8_t  CounterCan;                  //定时

uint8_t  CounterWarningFlag;              //定时
uint8_t  CounterCanFlag;                  //定时
uint8_t  CLEAR_ODO_STAR=0;

//uint8_t  CouterLine;
//uint8_t  CouterLineFlag;

uint8_t BCM_Sleep_Flag;

void Power_Management_Init(void)
{
  Power_On_System_Init();
  wdt_reset();
  Power_On_Memory_Init();
  Power_Wake_Up_Init();               //300ms
  PowerStatusBackup = 0xFF;
  Sys_Status_Update_Mode_Set ( SYS_STAT_UPDATE_MODE_WAKEUP );
  g_Power_St=IGN_Default;              //20200301
}
void Power_Management_Service ( void )
{
    uint8_t m_Power_St;
    m_Power_St = 0;

    switch ( g_Power_St )
    {
        case IGN_OFF:     //IGN-ON------->IGN_OFF  KL15--OFF   等待判断           未休眠时
            
            //Data_Tpms_Init ();
            Stepper_Motor_Shutdown();
            //Network_Status  = Network_Active ;
                            
            m_Power_St = IGN_OFF_State_Keep();

            if ( m_Power_St == 0 )      //OFF---->OFF自保持
            {
                g_Power_St = IGN_OFF; 
            }
            else if ( m_Power_St == 1 ) //OFF---->Sleep--->WakeUp
            {
                g_Power_St = IGN_SleepInit;

            }
            else if ( m_Power_St == 2 ) //OFF---->ON
            {
                g_Power_St = IGN_ON;
                if(NVM_RESET_ODO_FLAG==0 ) 
                {
                     if(KeyEnterinStatus==1) 
                    {
                           CLEAR_ODO_STAR=1;
                    }
                }
                Com_TxStart(); 
            }

            break;

        case IGN_SleepInit://睡眠之前初始化
            Power_Sleep_Init();
            MSCAN0_Enter_Low_Power_Mode();
            //if(!LINE_IN_POSITION)
              g_Power_St = IGN_Sleep;
            //break;         //----hyq--20180415

        case IGN_Sleep    ://IGN_OFF------>IGN_Sleep KL15--OFF   满足休眠条件   1.KL15 OOFF  2.总线无报文 3.满足网络管理休面条件
            while ( g_Power_St == IGN_Sleep )
            {
                m_Power_St = Power_Sleep_Loop();

                if ( m_Power_St == 0 )
                {
                    Power_Wake_Up_Init();
                    //	  PWM_INIT();
                    g_Power_St = IGN_OFF;
                }
                else	if ( m_Power_St == 3 )
                {
                    g_Power_St = IGN_WakeUp;
                }
                else  if ( m_Power_St == 5 )
                {
                    g_Power_St = IGN_Sleep;
                }
            }

            break;

        case IGN_WakeUp://IGN_Sleep---->IGN_WakeUp     
            Power_Wake_Up_Init();
            g_Power_St = IGN_ON;
            break;

        case IGN_ON:    //IGN-OFF---->IGN_ON   IGN_Wakeup
            //type_nvm = 0; //////////////////////////////////////////////////////////////
           // TFT_LCD_Clear_Multi_Layer ( 0, YVC_LYR_NUM_CPU-1 ); //////////////////////
            Power_IGN_On_Init();
            INIT_DTC_STATUS_IGN_ON();     //----hyq--20180728 网络管理
            Sys_Status_Update_Mode_Set ( SYS_STAT_UPDATE_MODE_NORMAL );
            g_Power_St = IGN_Stay_ON;
            LINE_OUT_FUEL_CTRL = 1 ;      //----hyq--20190506 燃油传感器给电
            break;

        case IGN_LVP:  //欠压
        case IGN_OVP:
            Power_Protect_Loop();
            g_Power_St = IGN_WakeUp;
            break;

        case IGN_Stay_ON:

            //判断IGN OFF
            if ( SYS_OPR_STAT_IGN_OFF )
                g_Power_St = IGN_OFF;
            else
                g_Power_St = IGN_Stay_ON;

            break;

        case IGN_Default:  //上电默认状态 在这里转出来
            Sys_Status_Update_Service();

            if ( SYS_OPR_STAT_IGN_OFF )
                g_Power_St = IGN_OFF;
            else
                g_Power_St = IGN_ON;

            break;

        default:
            break;
    }
}
/*****************************************************************
** Function name: IGN_OFF_State_Keep()                                             
** Input:-----                                                                                                         
** Output:----                                                        
** Return:----  
**2 有KL15唤醒
**1 满足休眠条件
**0 维持在KL15 OFF                      
** Function Description: 此函数判断电源状态转换使用.有3个出口.0.IGN--OFF;  1:---->IGN_Sleep;  2:IGN_ON;                       
** Version: 1.0                                                   
** Be careful:                                                    
*****************************************************************/
uint8_t StepMoter;
uint8_t IGN_OFF_State_Keep(void)          
{
 //uint8_t i;                           
 if(SYS_OPR_STAT_IGN_ON)	  
 	return 2;   //off下 不满足1  KL15上电唤醒       	
 if(SYS_OPR_STAT_IGN_OFF)          
 	{ 
 	
 	  if(CanFrameExist==1)     //顺序不能动,别问我为什么,试出来的
 	 	{
 			CounterCan=0;	
 			CounterCanFlag=0;	
 		} 
 		  
 		if(TIME_100MS==1)              //100ms定时
 		{			       
   	  if(BCM_Sleep_Flag==1)     //满足网络预休眠条件开始 tDelay1
   	  {
     	  if(tDelay1<200)
     	  tDelay1++;
   	  }
   	  else
   	   tDelay1=0;
   	  
   	  if(Network_Status  == Network_Ready) 
   	  {
   	     if(NWM_BCM_STATUS & CAN_MSG_LOST)      //  tWaitMsgTimeOut
       	  {
           	  if(tDelay2<200)
           	  tDelay2++;
       	   }
   	  }
   	  else
   	     tDelay2=0;
   	  if(Network_Status  == Network_Wait)
   	  {
   	  if(tWaitBusSleep<200)      //进入网络等待休眠
   	  tWaitBusSleep++;
   	  }
   	  else
   	    tWaitBusSleep=0;
   		if(CounterCan<250)
   	    CounterCan++; 
   		TIME_100MS=0;	
 		}
 		//----------------电机
 	  StepMoter=Stepper_Motor_Get_Status();
 		if(StepMoter != STEPPER_MOTOR_STOP)
 		return 0;
 		if(CounterCan>=200) //20秒 fhl20200420无报文20秒自己进入睡眠
 		{
 		 CounterCan=0; 		
 		 CounterCanFlag = 1;
 		} 
 		if(CounterCanFlag == 1)  // 目前满足休眠条件 可以跳转
 		{
 		   return 1;
 		}
 	  switch ( Network_Status )
    {       
        case Network_Active:        if(BCM_Sleep_Indicator==2) //满足网络预休眠条件     C3-1
                                    {
                                     BCM_Sleep_Flag=1;  //开始tDelay1计时
                                    }
                                    else if	(BCM_Sleep_Indicator==1)       //进入或保持网络激活20190809
                                     {
                                       tDelay1=0 ;
                                       tDelay2=0 ;
                                       BCM_Sleep_Flag=0; 
                                       tWaitBusSleep=0;
                                       ICM_Sleep_Indicator=1;   //20190809
                                       Network_Status  = Network_Active ;
                                     }
                                   if(CanFrameExist==1)     //20200305
                               	 	{
                               			CanFrameExist=0;
                               			}
                                 	//	if(tDelay1>150)   //进入网络欲休眠              C3-2   //20200301 ,每100ms+1
                                 		if(tDelay1>=148)   //进入网络欲休眠              C3-2     //20200301根据测试反馈减去 600ms
                                 		{
                                 		  tDelay1=0;
                                 		  BCM_Sleep_Flag=0; 
                                      Network_Status  = Network_Ready ;
                                 		}
             break;
        case Network_Ready:       ICM_Sleep_Indicator=2;   //20190807
                                  if(CanFrameExist==1)     //20200305
                               	 	{
                               			CanFrameExist=0;
                               			}
                                  if(BCM_Sleep_Indicator==2)
                                    tDelay2=0;
                                  else if(BCM_Sleep_Indicator==1)       //进入或保持网络激活20190809
                                   {
                                     tDelay1=0 ;
                                     tDelay2=0 ;
                                     BCM_Sleep_Flag=0; 
                                     tWaitBusSleep=0;
                                     ICM_Sleep_Indicator=1;   //20190809
                                     Network_Status  = Network_Active ;
                                   }
                        	    		if(tDelay2>=29)      //进入网络等待休眠            C5      //20200301 ,每100ms+1
                        	    	//	if(tDelay2>=24)      //进入网络等待休眠            C5      //20200301根据测试反馈减去 200ms
                               		{
                               		  tDelay2=0;
                                    Network_Status  = Network_Wait ;
                               		}	
             break;
        case Network_Wait:      // ICM_Sleep_Indicator=0;   //20200306
                                 Com_TxStop();	//关闭 外发报文
                                 if(CanFrameExist==1)     //20200305
                               	 {
                               			CanFrameExist=0;
                                	}
                                 if	(BCM_Sleep_Indicator==2)       //进入或保持网络激活20190809      C7
                                 {
                                   ICM_Sleep_Indicator=2;   //20190809
                                   tWaitBusSleep=0;
                                   Network_Status  = Network_Ready ;
                                   Com_TxStart();  
                                 }
                                 else if	(BCM_Sleep_Indicator==1)       //进入或保持网络激活20190809
                                 {
                                   tDelay1=0 ;
                                   tDelay2=0 ;
                                   BCM_Sleep_Flag=0; 
                                   tWaitBusSleep=0;
                                   ICM_Sleep_Indicator=2;   //20190809
                                   Network_Status  = Network_Ready ;
                                   Com_TxStart(); 
                                 }
                                 if(tWaitBusSleep>=49)       //总线睡眠延迟时间到，进入网络非激活      C8
                               		{
                                     Network_Status  = Network_Inactive ;
                               		}
             break;
        case Network_Inactive:   tWaitBusSleep=0;
                                 if	(BCM_Sleep_Indicator==1)       //进入或保持网络激活20190809
                                 {
                                   tDelay1=0 ;
                                   tDelay2=0 ;
                                   BCM_Sleep_Flag=0; 
                                   tWaitBusSleep=0;
                                   ICM_Sleep_Indicator=1;   //20190809
                                   Network_Status  = Network_Active ;
                                 }
                                 if(CanFrameExist==1)     //20200305
                               	 	{
                               			CanFrameExist=0;
                               		  Network_Status  = Network_Active ;	       //20200305
                               		  ICM_Sleep_Indicator=1;   //20190809
                               		  Com_TxStart(); 
                               		  return 0;
                               		} 
                                 return 1;
             break;
        default:              Network_Status  = Network_Active ;
                              ICM_Sleep_Indicator=1;   //20190809
                              if(CanFrameExist==1)     //20200305
                              {
                               		CanFrameExist=0;
                              }
            break;        
     }
 		 //----------------------------------------------------------------------------//
 	  return 0;   //目前状态在off里自保持   
 	}     
    return 0;   //目前状态在off里自保持                           
}    
/*****************************************************************
** Function name: Power_Protect_Loop()                                             
** Input:-----                                                                                                         
** Output:----                                                        
** Return:----                        
** Function Description: 系统非常规运行(1、过压、欠压保护 2、系统休眠)时,执行的循环程序
** Version: 1.0                                                   
** Be careful:                                                    
*****************************************************************/ 
void Power_Protect_Loop ( void )
{
  Sys_Status_Update_Mode_Set ( SYS_STAT_UPDATE_MODE_RECOVERY );
  while ( SYS_PWR_STAT_PROTECT )
  {
#if CODEMODE==Normal   
   wdt_reset();
   Enter_Stop_Mode();                 //----hyq--STOP
#endif 
   RTI_Timing_Service();
   Data_IGN_Off_Timing_Service();
   Sys_Status_Update_Service();
  }
}
/*****************************************************************
** Function name: Power_Sleep_Loop()                                             
** Input:-----                                                                                                         
** Output:----                                                        
** Return:----   
** 0 can唤醒 
** 3 KL15唤醒
** 5 保持休眠                  
** Function Description: 此函数主要满足休眠条件后 关闭各个模块功能.初始化时钟.降低整体功耗.进入SleepLoop      100ms由rtc唤醒一次.检测KL15或者can唤醒条件是否满足
** Version: 1.0                                                   
** Be careful:                                                    
*****************************************************************/
uint8_t Power_Sleep_Loop ( void )
{
#if CODEMODE==Normal 
  Enter_Stop_Mode();                  //----hyq--STOP
  wdt_reset();                        //看门狗
#endif
  if (MSCAN0_Get_Wake_Up_Flag())      //如果总线被唤醒
  {
    CAN0RIER_RXFIE = 1;   			//使能CAN接收中断
    CoCAN_Signal_Update_Service();
    if((DriveDoorSts_can==1)||(PsngrDoorSts_can==1)||(PositionLightSts_can==1)||(HazardLightSts==1))    //20200524 fhl
    {
        Clock_Init();
        MSCAN0_Exit_Low_Power_Mode(); 
        tWaitBusSleep=0;
     		Network_Status  = Network_Active ;	       //20200305
        return 0;
    }
    else
   // MSCAN0_Enter_Low_Power_Mode();
      CAN0RIER_RXFIE = 0;   			//使能CAN接收中断
  }
  //----hyq--20180808 硬线唤醒
  //if(LINE_IN_POSITION)
  //{
  //  Clock_Init();
  //  return 0;
  //}
  RTI_Timing_Service();
  Data_IGN_Off_Timing_Service();
  Sys_Status_Update_Service();

	if(!SYS_OPR_STAT_IGN_OFF)
	{
	  MSCAN0_Exit_Low_Power_Mode(); 
    return 3;
   }
  return 5;
}
/******************************************************************************
系统初始化程序
******************************************************************************/

/*****************************************************************
** Function name: Power_On_System_Init()                                             
** Input:-----                                                                                                         
** Output:----                                                        
** Return:----                        
** Function Description: 此函数为模块及底层初始化
** Version: 1.0                                                   
** Be careful:                                                    
*****************************************************************/

//首次上电初始化
void Power_On_System_Init ( void )
{
  DisableInterrupts;
  IVBR = 0xFB;                  // relocate interrupt table to 0xFB00;
#if CODEMODE==Normal  
  WDT_Init();                   //看门狗
#endif  
  Clock_Init();                 
  RTI_Init();                   //时钟
  
  MSCAN0_Init();
  
  GPIO_Init(); 
  DB8379_Init();
                    
  PWM_Init();		                 
  SCI0_UART_Init();
  IIC_Init();
  Analog_Signal_Converter_Init();
  Sys_Status_Init();
  Data_Power_On_Init();
  Drive_Info_Power_On_Init();    //初始化
  Drive_Info_Export_Init();
  //Buzzer_Init();
  //LCD_Seg_Init();                //断码初始化
  sleepFlg = 1;
  CoCAN_Set_Mode ( CoCAN_MODE_NORMAL );
  BL_Init();
  APIBGNMEnable = 1;
  API_Start();
  EnableInterrupts;
  Line_In_Enable ( 1 );     
  Line_In_Status_Reset();
  Sys_Status_Update_Mode_Set ( SYS_STAT_UPDATE_MODE_INIT );
  Sys_Status_Update_Service();
}
/*****************************************************************
** Function name: Power_On_Memory_Init()                                             
** Input:-----                                                                                                         
** Output:----                                                        
** Return:----                        
** Function Description: //首次上电存储器初始化
** Version: 1.0                                                   
** Be careful:                                                    
*****************************************************************/ 
void Power_On_Memory_Init ( void )
{
  uint8_t i;
  NVM_Init();
  //加载故障码
  for ( i = 0; i < 19; i++ )
    DTC_STATUS[i] = NVMDTC.Data[i];   
  Read_27_DATA_FROM_FLASH();
  Read_2E_DATA_FROM_FLASH();
  Read_BACKUP_DATA_FROM_FLASH();
}

/*****************************************************************
** Function name: Power_IGN_On_Init()                                             
** Input:-----                                                                                                         
** Output:----                                                        
** Return:----                        
** Function Description: IGN转换为ON状态时初始化                  
** Version: 1.0                                                   
** Be careful:                                                    
*****************************************************************/ 
void Power_IGN_On_Init ( void )
{
  //CounterWarning=0;  //定时
  CounterCan=0;      //定时
  CounterCanFlag = 0;
  //CouterLine = 0;    //定时
  tDelay1=0;
  tDelay2=0;
  tWaitBusSleep=0;
  BCM_Sleep_Flag=0;
  Network_Status  = Network_Active ;
  Data_IGN_On_Init();
  //Warning_Signal_Init();          //报警状态初始化
  Popup_Scheduler_Init();
  Sound_Scheduler_Init();
  Startup_Animation_Reset();
  //////////////////////////
  //PWM_INIT();
  Clear_TFT();
    BL_Init();  
   BackLight_Plate_Needle_Close();    //表盘背光
  BackLight_TFT_Close();             //屏背光  
  /////////////////////////
  Stepper_Motor_Start_Up();
  LED_OUT_KEY_CTRL=1;
  //Radar_R3_Init();
  //Radar_R3_Receive_Enable(1); 
	
	//SEG_LCD_Init();	                  //--hyq-20180923
  Line_In_Enable ( 1 ); 
}
/*****************************************************************
** Function name: Power_Sleep_Init()                                             
** Input:-----                                                                                                         
** Output:----                                                        
** Return:----                        
** Function Description: 此函数主要满足休眠条件后 关闭各个模块功能.初始化时钟.降低整体功耗.准备进入SleepLoop      
** Version: 1.0                                                   
** Be careful:                                                    
*****************************************************************/
void Power_Sleep_Init ( void )
{
  //wdt_reset();
  Line_In_Enable ( 0 );
  CoCAN_Set_Mode ( CoCAN_MODE_NORMAL );
  Com_TxStop() ;
  ///////////////////////////////////////////////
  //CLEAR_ALLSCR();                    //关LCD
  BackLight_Plate_Needle_Close();    //表盘背光
  BackLight_TFT_Close();             //屏背光
  Clear_TFT(); 
  ///////////////////////////////////////////////
  TFT_LCD_Shutdown();
  Buzzer_Shutdown();                 //蜂鸣器关闭
  Analog_Signal_Converter_Init();
  GPIO_Init(); 
  PWM_Channel_Stop(2);
  PWM_Channel_Stop(5);
//  PWM_Channel_Stop(7);
  TFT_nRST = 0;        
  TFT_MOSI = 0;
  TFT_SCLK = 0;
  TFT_nCS  = 0;
  
  NM_RECEIVE = 0;
  API_Stop();
  
  RTICTL      = 0xDF;         //Real Time = 8M / 800000 = 10HZ  (10MS)
  CRGINT_RTIE = 1;	          //开Real Time 中断
  
  BlTurnOffDelay = 10 ;
  
  Sys_Status_Update_Mode_Set ( SYS_STAT_UPDATE_MODE_WAKEUP );
}
/*****************************************************************
** Function name: Power_Wake_Up_Init()                                             
** Input:-----                                                                                                         
** Output:----                                                        
** Return:----                        
** Function Description: 此函数主要处理电源唤醒之后数据及相关模块的初始化. 进入途径为IGN_Sleep.出口为IGN_ON           
** Version: 1.0                                                   
** Be careful:                                                    
*****************************************************************/
void Power_Wake_Up_Init ( void )
{
  //wdt_reset();
  Clock_Init();                 // 初始化时钟和看门狗
  GPIO_Init();                  // GPIO 初始化 
  DB8379_Init();
  CoCAN_Init();
  Drive_Info_Export_Init();
  Analog_Signal_Converter_Init();
  SCI0_UART_Init();
  
  APIBGNMEnable = 1;
  API_Start();
  IIC_Init();
  ///////////////////////////////////////////////////
  //LCD_Seg_Init();      
  BL_Init();                         //背光
 // if(!LINE_IN_POSITION)
   
   // BackLight_Plate_Needle_Close();    //表盘背光
 // else
 //  BackLight_TFT_Set(60);
    
  //BackLight_TFT_Close();             //屏背光
  //SEG_LCD_Init();                    //----hyq--20180923
  
  Line_In_Enable ( 1 );
  
  //////////////////////////////////////////////////
  Key_Status_Init();                //按键初始化
  Popup_Scheduler_Init();
  IO_Management_Init();             //状态初始化
  Diagnostic_init();
  TFT_LCD_Startup();                //屏初始化
  PWM_INIT();
  Sound_Player_Init();              //声音初始化
  Sound_Scheduler_Init();
  INIT_DTC_STATUS_IGN_ON();
  Sys_Status_Update_Mode_Set ( SYS_STAT_UPDATE_MODE_NORMAL );
  ICM_Sleep_Indicator=1;          //20190807
  CoCAN_Set_Mode ( CoCAN_MODE_NORMAL );
  Com_RxStart();
  Com_TxStart(); 
  PositionLightSts_Count=0;
 DriveDoorSts_Count=0;
}            
void Com_RxStart ( void )
{
  CoCAN_Rx_Enable(CoCAN_ENABLE);
}

void Com_TxStart(void)
{
  CoCAN_Tx_Enable(CoCAN_ENABLE);
}
void Com_TxStop(void)
{
  CoCAN_Tx_Enable(CoCAN_DISABLE);
}
void Com_RxStop(void)
{
  CoCAN_Rx_Enable(COCAN_PSEUDO_DISABLE);
}
void Diagnostic_init(void)
{
  ContrlorResumeofFUEL = 0;
  ContrlorResumeofTEMP = 0;
  ContrlorResumeofVspeed = 0;
  ContrlorResumeofEspeed = 0;
  ContrlorResumeofGAS1  = 0;  //气压1
  ESpeedValNUM = 0;       
  VspeedValNUM = 0;       
  ESpeedVal = 0;          
  VspeedVal = 0;          
  TempSeg = 0;           
  FuelSeg = 0;  
  ADblueSeg = 0;              //天蓝液
  OilSeg = 0;
  GAS1_DISPLAY  = 0;                 //气压1
  GAS2_DISPLAY  = 0;                 //气压2                 
}








