/**********************************************************************************************************
 * Copyright(C) 2017, HeiLongJiang TYW Co.,Ltd.
 *
 * @Filename:       PowerManagement.c
 *
 * @Description:    电源管理服务文件
 *
 * @Functions List:
 *
 *
 * @History:        Version:            V0.0.1
                    Date:               2018-08-23 15:57:00
                    Author:
                    Modification:
 **********************************************************************************************************/

/**********************************************************************************************************
 * Include
 */

#include "PowerManagement.h"
#include "System_Status_Monitor.h"
#include "WDT.h"
#include "BackLight.h"
#include "Common_Interface.h"
#include "Line_In.h"
#include "Telltales_Lib.h"
#include "Telltales_user.h"

/*数据处理部分*/
#include "Services_Interval.h"
#include "Services_ODO.h"
#include "Services_ODO_Internal.h"
#include "Services_TripA.h"
#include "Service_Time.h"
#include "MBD_Model.h"
#include "CAN_APP.h"
#include "Service_OFF_Time.h"
#include "AirBagSelfChecking.h"
/*GUI显示部分*/
#include "Gauge_Display.h"
#include "Seatbelt.h"
#include "Key.h"
#include "RTE_CAN.h"
#include "RTE_PWM_OUT.h"
#include "Sound_Player.h"
#include "Sound_Scheduler.h"
#include "Popup_Scheduler.h"
#include "UDS_Common.h"
#include "Simulated_IIC_2_Master.h"
#include "LED_Driver.h"
#include "Popups.h"
#include "Radar_R3.h"
#include "BU98R10.h"
#include "GenDelay.h"
#include "Simulated_IIC_Master.h"
#include "Non_volatile_Memorys.h"
#include "Popups.h"

/**********************************************************************************************************
 * Constants and defines
 */

/**********************************************************************************************************
 * Local variables
 */
#pragma location = "BACKUP_RAM_CONTENT"
Power_Status_t g_Power_St; /*当前实际电源状态*/

/*__no_init uint32_t TestBackupRam @(0x0e800000UL);  */ /*区分首次上电和唤醒标志*/
/* #pragma location=0x02000000ul */
uint32_t TestBackupRam;

uint16_t CANModeInitFlag = 0U;
extern uint32_t Factory_ClearOdo_Display_Flag;



uint16_t SleepTime_Timing;

void SetCANModeFlag(void)
{
    CANModeInitFlag = 0x5AA5U;
}

void Clear_CANModeFlag(void)
{
    CANModeInitFlag = 0x3AA3U;
}

uint16_t GetCANModeFlag(void)
{
    return CANModeInitFlag;
}

/*任务延时程序*/
static void Delay_Ms(uint16_t t)
{
    uint16_t RocBackup, Counter;
    RocBackup = Sys_Get_ms_Rolling_Counter( );
    do
    {
        WDT_Clear( );
        if ( ! SYS_OPR_STAT_HALT_NM )
        {
            DoCAN_Communication_Service( );
            UDS_Server_Application_Service( );
            UDS_10ms_Service( );
        }
        Counter = Sys_Get_ms_Rolling_Counter( );
        if ( Counter >= RocBackup )
        {
            Counter -= RocBackup;
        }
        else
        {
            Counter = 65535U - RocBackup + Counter + 1U;
        }
    } while ( Counter < t );
} 

/**********************************************************************************************************
 *@Function:        Power_Sleep_100ms_ISR
 *@Description:         休眠模式下100MS计时
 *@Input:       none.
 *@Output:      none.
 *@Calls:       none.
 *@Return:      none.
 *@Note:            休眠循环中实时调用
 **********************************************************************************************************/
void Power_Sleep_100ms_ISR(void)
{

}
/**********************************************************************************************************
 *@Function:        Power_Management_Service
 *@Description:         电源管理服务.
 *@Input:       none.
 *@Output:      none.
 *@Calls:       none.
 *@Return:      none.
 *@Note:        实时调用.
 **********************************************************************************************************/
void Power_Management_Service(void)
{
    switch ( g_Power_St )
    {

        case _IGN_OFF_Init:
            Power_IgnOff_Init( );
            g_Power_St = _IGN_OFF;
        case _IGN_OFF:
            IGN_OFF_State_Keep( );
            if ( SYS_OPR_STAT_HALT )
            {
                g_Power_St = _IGN_LIMIT;
            }
            break;

        case _IGN_Sleep_Init:

            /*关闭电机待添加*/
            /*关闭扬声器待添加*/
            BackLight_Sleep_Init( ); /*关闭背光*/
            ////      MFS_SPI_HT1629G_Clearn_SEG();/*段码屏显示全写0*/
            /*CanNm_NetworkRelease ( NM_REQ_KL15_OFF );*/ /*40202-2*/
            //      LED_InitAll_St(LED_OFF);/*修改所有指示灯状态为关闭状态*/
            //      LED_ProcessAll();/*同步所有状态到每个buffer*/

            g_Power_St = _IGN_Sleep;
            /*break;*/

        case _IGN_Sleep:

            while ( g_Power_St == _IGN_Sleep )
            {
                Power_Sleep_Loop( );
            }
            g_Power_St = _IGN_OFF_Init;
            RTE_PWM_Start( );

            break;

        case _IGN_ON_Init:
            Power_KL15_Init( );

            g_Power_St = _IGN_ON;

        case _IGN_ON:
            /*关机模式*/
            if ( SYS_OPR_STAT_IGN_OFF )
            {
                g_Power_St = _IGN_OFF_Init;
                Service_OFF_Timing_KL15Init( ); /*下电清零*/
            }

            /*停止模式*/
            if ( SYS_OPR_STAT_HALT )
            {
                g_Power_St = _IGN_LIMIT;
            }

            break;
        /*受限停止*/
        case _IGN_LIMIT:

            /*关闭模式，停止所有功能*/
            Sys_Stop_Task( );
            /*电源恢复，进入重新初始化模式*/
            g_Power_St = _IGN_OFF_Init;

            break;

        default:
            g_Power_St = _IGN_OFF_Init;
            break;
    }
}

/**********************************************************************************************************
 *@Function:        Power_Sleep_Init
 *@Description: 系统进入低功耗睡眠前初始化.
 *@Input:       none.
 *@Output:      none.
 *@Calls:       none.
 *@Return:      none.
 *@Note:        进入Sleep状态前初始化.
 **********************************************************************************************************/
static void Power_Sleep_Init(void)
{
    Line_In_Enable(0u);
    /*bsp_CAN_Sleep();*/
    BackLight_Sleep_Init( );
    LED_Driver_Init_Sleep( );
}

uint8_t MSCAN0_Is_Exist_Frame(void)
{
    uint8_t flag = 0U;

    flag = Can_Read_Bus( );
    Can_Set_Bus(0u);
    return flag;
}
/**********************************************************************************************************
 *@Function:        IGN_OFF_State_Keep
 *@Description: IGN_OFF状态管理函数，返回IGN_ON/Sleep_Init.
 *@Input:       none.
 *@Output:      none.
 *@Calls:       none.
 *@Return:      none.
 *@Note:        none.
 **********************************************************************************************************/
static void IGN_OFF_State_Keep(void)
{
    if ( SYS_OPR_STAT_IGN_ON_NM )
    {
        g_Power_St   = _IGN_ON_Init;
    }
    else
    {
        /*电源管理唤醒*/
        if ( (Read_KL30_ConvertFinish( ) == 0u) || (Line_In_SOC_CC == 1u)
             || (Line_In_DoorOpen == 0u) )
        {
           // sleepFlag = 0U;
        }
        /*KL15唤醒*/
        else
        {
            if ( SleepTime_Timing >= 25000u )
            {
                g_Power_St = _IGN_Sleep_Init;
            }
            else
            {
                g_Power_St = _IGN_OFF;
            }
        }
    }
}
/**********************************************************************************************************
 *@Function:        Power_Sleep_Loop
 *@Description:         系统非常规运行(系统休眠)时,执行的循环程序.
 *@Input:       none.
 *@Output:      none.
 *@Calls:       none.
 *@Return:      none.
 *@Note:        none.
 **********************************************************************************************************/
static void Power_Sleep_Loop(void)
{
    //sleepFlag = 1U;
    Can_Abort_All( );
    CANFD_CH0_Bus_Off_Recover( );
    /*休眠下计时初始化*/
    CAN0_STB   = 1U;
    g_Power_St = _IGN_OFF_Init;
    Power_Sleep_Init( );
    Data_Timer_Record_BeforeSleep( );
    Can_SleepController_Fun( );
    Sys_Enter_Sleep_Mode( );
}
/**********************************************************************************************************
 *@Function:          Power_KL30_Init
 *@Description:           KL30初始化 只执行一次
 *@Input:         none.
 *@Output:        none.
 *@Calls:             none.
 *@Return:        none.
 *@Note:              none.
 **********************************************************************************************************/
void Power_KL30_Init(void)
{
    LED_Driver_Par_st_t led_dr;
    Power_5V_EN                               = 1;
    led_dr.pfnLEDDriverShutdownPinSetCallBack = LED_Driver_Shutdown_Pin_Set;
    led_dr.pu8IS31ChipAddress                 = u8IS31ChipAddress;
    led_dr.pu8AW21036ChipAddress              = u8AW21036ChipAddress;
    led_dr.u8LEDDriverChipNum                 = LED_DRIVER_CHIP_NUM;

    g_Power_St = _IGN_OFF_Init;
    memset(( void * )0x02000010, 0u, 16368U);    // 0503
    IIC_Init();
    NVM_Init();
    /*首次上电只能初始化一次系列*/
    Data_Timer_Record_BeforeSleep( );
    Data_Timer_Record_Calc( );
    Service_OFF_Timing_KL30Init( );
    Common_DataInit( );
    Services_ODO_KL30Init( );
    Services_ODO_KL30Init1( ); /*程序内部使用,里程备份增加专用里程,非显示里程*/
    Data_TripA_KL30Init(0u);
    //Data_Interval_KL30_InitShell( );
    //Data_interval_Geely_ReConfig( );
    BackLight_30_Init( );
    /*首次上电需要初始化,非首次也要初始化系列*/
    Line_In_Enable(0u);
    HW_Key_KL30_Wakeup_Init( );
    Telltales_Init( );
    MBD_AvgVSpeed_KL30Init( );
    Sound_Player_Init( );
    Sound_Scheduler_Init( );
    Popup_Scheduler_Init( );
    Simulated_IIC_2_Init( );
    LED_Driver_Init_KL30(u8LEDDriverRamData, &led_dr);
    BU98R10_Init( );
    Gauge_KL30_Init( );
    Temp_Calc_Init();
    Maintenance_Init_Example();
}
/**********************************************************************************************************
 *@Function:          Power_Wakeup_Init
 *@Description:       Wakeup初始化
 *@Input:             none.
 *@Output:            none.
 *@Calls:             none.
 *@Return:            none.
 *@Note:              none.
 **********************************************************************************************************/
void Power_Wakeup_Init(void)
{
    LED_Driver_Par_st_t led_dr;
    g_Power_St                                = _IGN_OFF_Init;
    Power_5V_EN                               = 1;
    led_dr.pfnLEDDriverShutdownPinSetCallBack = LED_Driver_Shutdown_Pin_Set;
    led_dr.pu8IS31ChipAddress                 = u8IS31ChipAddress;
    led_dr.pu8AW21036ChipAddress              = u8AW21036ChipAddress;
    led_dr.u8LEDDriverChipNum                 = LED_DRIVER_CHIP_NUM;
    Data_Timer_Record_Calc( );
    Common_DataInit( );
    SERVICE_Time_WakeUp_Init( );
    Line_In_Enable(0u);
    HW_Key_KL30_Wakeup_Init( );   
    Telltales_Init( );
    BackLight_Wakeup_Init( );
    BU98R10_Init( );
    Sound_Player_Init( );
    Sound_Scheduler_Init( );
    Popup_Scheduler_Init( );
    Simulated_IIC_2_Init( );
    Temp_Calc_Init();
    LED_Driver_Init_Wakeup(u8LEDDriverRamData, &led_dr);
    Maintenance_Init_Example();
}
/**********************************************************************************************************
 *@Function:        Power_Management_Init
 *@Description:         首次上电初始化.
 *@Input:       none.
 *@Output:      none.
 *@Calls:               none.
 *@Return:      none.
 *@Note:        KL30 + Wakeup调用.
 **********************************************************************************************************/
void Power_Management_Init(void)
{
    if ( Clock_Get_Startup_Mode( ) != CLK_STARTUP_PWR_ON )
    {
        TestBackupRam = 1U; /*非首次接入KL30*/
    }
    else
    {
        TestBackupRam = 0U; /*首次接入KL30*/
    }

    if ( TestBackupRam )
    {
        Power_Wakeup_Init( ); /*Wakeup初始化*/
        Sys_KL30_Init( );
    }
    else
    {
        Sys_KL30_Init( );
        Gen_TimeDelay(260000ul,50ul);
        Power_KL30_Init( ); /*KL30初始化*/
    }
}
/**********************************************************************************************************
 *@Function:          Power_IgnOff_Init
 *@Description:           Ignoff初始化
 *@Input:         none.
 *@Output:        none.
 *@Calls:             none.
 *@Return:        none.
 *@Note:              none.
 **********************************************************************************************************/
static void Power_IgnOff_Init(void)
{
    Line_In_Enable(1u);
    BackLight_IG_OFF_Init( );
    Popups_IG_OFF_Init( );
    Factory_ClearOdo_Display_Flag = 0;
}
/**********************************************************************************************************
 *@Function:          Power_KL15_Init
 *@Description:           KL15初始化
 *@Input:         none.
 *@Output:        none.
 *@Calls:             none.
 *@Return:        none.
 *@Note:              none.
 **********************************************************************************************************/
void Power_KL15_Init(void)
{
    Air_Bag_LED_Testing_Init( );
    Line_In_Enable(1u);
    MMIKeyVarInit( );
    Services_ODOSync_KL15Init( );
    SERVICE_Time_KL15_Init( );
    BackLight_IG_ON_Init( );
    Telltales_KL15_Init( );
    Gauge_KL15_Init( );
    Popups_KL15_Init( );
    Radar_R3_Init( );
}

/**********************************************************************************************************
 *@Function:        Sys_Stop_Task
 *@Description:         停止不可运行任务模式
 *@Input:       none.
 *@Output:      none.
 *@Calls:       none.
 *@Return:      none.
 *@Note:        none.
 **********************************************************************************************************/
void Sys_Stop_Task(void)
{
    static uint8_t Delaycnt;
    /*关闭所有外设功能，只保留AD采集，电源状态切换*/
    {
        /*关闭电机待添加*/
        /*关闭扬声器待添加*/
        BackLight_Sleep_Init( ); /*关闭背光*/
    }
    Delaycnt = 0u;
    for ( ;; )
    {
        /*喂狗*/
        WDT_Clear( );

        /*一定周期调用2ms*/
        Delay_Ms(2U);

        Analog_Signal_Conv_Service( );
        Sys_Status_Update_Service( );
        Delaycnt++;
        if ( Delaycnt >= 5u )
        {
            Delaycnt = 0u;
            Can_BusOff_Fun( );
        }

        /*电源模式正常，退出*/
        if ( SYS_OPR_STAT_RUN )
        {
            // StepMotor_Reset(0u);
            // StepMotor_Limit_Init();
            RTE_PWM_Start( );
            return;
        }
    }
}
