#include "System_Monitor.h"
#include "Components.h"
#include "Application.h"
#include "delay.h"
#include "wdt.h"

#define u16Base_Vol           0u      
#define u16ENTER_LOW_N_RANGE  6500U    
#define u16EXIT_LOW_N_RANGE   7000U    
#define u16ENTER_LOW_Y_RANGE  9000U    
#define u16EXIT_LOW_Y_RANGE   10000U   

#define u16EXIT_HIGH_Y_RANGE  17000U  
#define u16ENTER_HIGH_Y_RANGE 17500U  
#define u16EXIT_HIGH_N_RANGE  17800U 
#define u16ENTER_HIGH_N_RANGE 18000U  
#define u16Top_Vol            0xffffu 


void Delay_ms(uint32_t u32Ms);

// #pragma alignvar(8)
static const monitorlib_uint16_t  SysFun_Range [ 26u ] = {
    u16Base_Vol,

    u16ENTER_LOW_N_RANGE,
    u16EXIT_LOW_N_RANGE,

    u16ENTER_LOW_Y_RANGE,
    u16EXIT_LOW_Y_RANGE,

    u16EXIT_HIGH_Y_RANGE,
    u16ENTER_HIGH_Y_RANGE,

    u16EXIT_HIGH_N_RANGE,
    u16ENTER_HIGH_N_RANGE,

    u16Top_Vol,
    2500,
    50u,
    u16Base_Vol,

    u16ENTER_LOW_N_RANGE,
    u16EXIT_LOW_N_RANGE,

    u16ENTER_LOW_Y_RANGE,
    u16EXIT_LOW_Y_RANGE,

    u16EXIT_HIGH_Y_RANGE,
    u16ENTER_HIGH_Y_RANGE,

    u16EXIT_HIGH_N_RANGE,
    u16ENTER_HIGH_N_RANGE,

    u16Top_Vol,
    2u,
    2u,

    2u,
    0u,
};
monitorlib_uint16_t Sys_Read_KL30_Voltage_F(void)
{
    monitorlib_uint16_t u16Voltage;
    u16Voltage = (monitorlib_uint16_t)ADC_Conv_Single_Channel(ADC_CH_KL30_VOLTAGE);
    return u16Voltage;
}

monitorlib_uint16_t Sys_Read_KL15_Voltage_F(void)
{
    monitorlib_uint16_t u16Voltage;
    u16Voltage = (monitorlib_uint16_t)ADC_Conv_Single_Channel(ADC_CH_KL15_VOLTAGE);
    return u16Voltage;
}

monitorlib_uint16_t Sys_Read_KL30_Voltage(void)
{
    monitorlib_uint16_t u16Voltage;
    u16Voltage = (monitorlib_uint16_t)ADC_Read_Signal(ADC_CH_KL30_VOLTAGE);
    return u16Voltage;
}

monitorlib_uint16_t Sys_Read_KL15_Voltage(void)
{
    monitorlib_uint16_t u16Voltage;
    u16Voltage = (monitorlib_uint16_t)ADC_Read_Signal(ADC_CH_KL15_VOLTAGE);
    return u16Voltage;
}

monitorlib_uint8_t Sys_Read_KL30_Valid(void)
{
    monitorlib_uint8_t u8Valid;
    u8Valid = ADC_Read_Signal_Valid(ADC_CH_KL30_VOLTAGE);
    return u8Valid;
}

monitorlib_uint8_t Sys_Read_KL15_Valid(void)
{
    monitorlib_uint8_t u8Valid;
    u8Valid = ADC_Read_Signal_Valid(ADC_CH_KL15_VOLTAGE);
    return u8Valid;
}

monitorlib_uint8_t System_LINE_KL15(void)
{
    static monitorlib_uint8_t  u8KL15 = 0;

    #if (PART_NUMBER == RMR42E_60)
        if ((Get_CAN_Num_MMCU_PowerMode() != 0x0) || (System_Indicator_CANFlag == 1) )
        {
            u8KL15 = 1u;
        }
        else
        {
            u8KL15 = 0u;
        }
    #else
        if ((Sys_Read_KL15_Voltage() >= 5500u ) && (Sys_Read_KL30_Voltage() >= 5500u))
        {
            if ((CAN_MSG_Status(&CAN_CH0_CanMsgOp, Co_Can_ConvertSubID_CAN_CH0(CAN_CH0_ID_CAN_0x220_Msg)) == CAN_SIG_NORMAL) && (Get_CAN_CH0_ID_220_Sig_VCU_KeySts() == 1U))
            {
                u8KL15 = 1U;
                g_powerState = 2U;
            }
            else
            {
                u8KL15 = 0U;
                g_powerState = 1U;
            }
        }
        else 
        {
            u8KL15 = 0U;
            g_powerState = 0U;
        }

    #endif

    return u8KL15;
}

void Common_BlockDelay(monitorlib_uint32_t u32Ms)
{
    Gen_TimeDelay(u32Ms * 1000u, 50u);
}

void Sys_LogicProcess(void)
{
}

void Sys_KL30_Init(void)
{
    MonitorExt_st m_st;
    m_st.COM_Delay               = Common_BlockDelay;
    m_st.SysGet_KL15Line         = System_LINE_KL15;
    m_st.SysGet_KL15_Valid       = Sys_Read_KL15_Valid;
    m_st.SysGet_KL30_Valid       = Sys_Read_KL30_Valid;
    m_st.SysGet_KL15_value       = Sys_Read_KL15_Voltage;
    m_st.SysGet_KL30_value       = Sys_Read_KL30_Voltage;
    m_st.SysGet_KL15_value_Force = Sys_Read_KL15_Voltage_F;
    m_st.SysGet_KL30_value_Force = Sys_Read_KL30_Voltage_F;
    m_st.SysMonitorLogic         = Sys_LogicProcess;
    Sys_Set_Pata(SysFun_Range, &m_st);
    System_Monitor_KL30Init( );
}

void Sys_WakeUp_Init(void)
{
    MonitorExt_st m_st;
    m_st.COM_Delay               = Common_BlockDelay;
    m_st.SysGet_KL15Line         = System_LINE_KL15;
    m_st.SysGet_KL15_Valid       = Sys_Read_KL15_Valid;
    m_st.SysGet_KL30_Valid       = Sys_Read_KL30_Valid;
    m_st.SysGet_KL15_value       = Sys_Read_KL15_Voltage;
    m_st.SysGet_KL30_value       = Sys_Read_KL30_Voltage;
    m_st.SysGet_KL15_value_Force = Sys_Read_KL15_Voltage_F;
    m_st.SysGet_KL30_value_Force = Sys_Read_KL30_Voltage_F;
    m_st.SysMonitorLogic         = Sys_LogicProcess;
    Sys_Set_Pata(SysFun_Range, &m_st);
    System_Monitor_WakeupInit( );
}

void Delay_ms(uint32_t u32Ms)
{
    uint32_t i = 0;
    uint32_t u32Counter = 0;

    for (u32Counter = 0; u32Counter < u32Ms; u32Counter++)
    {
        for (i = 0; i < 44; i++)
        {
            __NOP();
            __NOP();
            __NOP();
        }
        WDT_Restart();
    }
}
