#include "common_include.h"


volatile    uint16_t          NM_BatVolt;
volatile    uint8_t           NM_tVoltageDelay;
volatile    uint8_t           NM_Volt_Abnormal;
volatile    _AppMsgTime       AppMsgTime[3];
volatile    uint8_t           AppMsgSendRequest;


//
void    NM_Time_2ms_Count(void);
void    NM_Send_PDU_Fun(void);         //Send PDU Message Interface Function
void    NM_Send_App_Fun(void);         //Send Application Message Interface Function

void    NM_CheckSleep_Fun(void);
void    NM_CheckBusOff_Fun(void);
void    NM_RemoteWakeup_Fun(void);
void    NM_LocalWakeup_Fun(void);
void    NM_tSleepRequTimeCount_Fun(void);
void    NM_Receive_isr_Fun(uint16_t id,uint8_t *pBuf);
void    NM_TranMsgErrorDetect(void);
void    NM_TranMsgSuccessDetect(void);
void    NM_CheckBatVolt(uint16_t adValue);
void    NM_SetIgnState(uint8_t IgnPosition);

/*-------------------------------------------------------------------------
* Function Name  : NM_Time_2ms_Count
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void NM_Time_2ms_Count(void)
{
    if(NM_BatVolt >= 600)
    {
        if((NM_BatVolt >= VoltUpLimit) || (NM_BatVolt <= VoltDownLimit))
        {
            NM_tVoltageDelay = 100;  //200ms
            NM_Volt_Abnormal = 1;
            return;
        }
        else
        {
            if(NM_tVoltageDelay)
            {
                NM_tVoltageDelay --;
            }
            if((NM_Volt_Abnormal == 1) && (NM_tVoltageDelay == 0))
            {
                NM_Volt_Abnormal = 2;
            }
        }
    }
    
    if(NM_Time.TmaxEnable)
    {
        if(NM_Time.TmaxTime < NM_Time.OverTmaxTime)
        {
            NM_Time.TmaxTime += 2;
        }
    }
    
    if(NM_Time.TtypEnable)
    {
        if(NM_Time.TtypTime < NM_Time.OverTtypTime)
        {
            NM_Time.TtypTime += 2;
        }
    }
    
    if(NM_Time.TwbsEnable)
    {
        if(NM_Time.TwbsTime < NM_Time.OverTwbsTime)
        {
            NM_Time.TwbsTime += 2;
        }
    }
    
    if(NM_Time.SleepEnable)
    {
        if(NM_Time.SleepTime < NM_Time.OverSleepTime)
        {
            NM_Time.SleepTime += 2;
        }
    }

    if(NM_Time.NM_CheckTime < 10)
    {
        NM_Time.NM_CheckTime ++;
    }
    
    /*if (AppMsgTime[MSG_0x1DF].msgEvent) {
        if (((AppMsgTime[MSG_0x1DF].msgEventCnt == 0) && (AppMsgTime[MSG_0x1DF].AppTime < 90)) || ((AppMsgTime[MSG_0x1DF].msgEventCnt) && (AppMsgTime[MSG_0x1DF].AppTime < 10))) {
            AppMsgTime[MSG_0x1DF].msgEvent = 0;
            AppMsgTime[MSG_0x1DF].msgEventCnt = 2;
            AppMsgTime[MSG_0x1DF].AppTime = 0;
        }
    }

    if(AppMsgTime[MSG_0x1DF].AppTime) {
        AppMsgTime[MSG_0x1DF].AppTime--;
    } 
    
    if (AppMsgTime[MSG_0x1D4].msgEvent) {
        if (((AppMsgTime[MSG_0x1D4].msgEventCnt == 0) && (AppMsgTime[MSG_0x1D4].AppTime < 90)) || ((AppMsgTime[MSG_0x1D4].msgEventCnt) && (AppMsgTime[MSG_0x1D4].AppTime < 10))) {
            AppMsgTime[MSG_0x1D4].msgEvent = 0;
            AppMsgTime[MSG_0x1D4].msgEventCnt = 2;
            AppMsgTime[MSG_0x1D4].AppTime = 0;
        }
    }
    
    if(AppMsgTime[MSG_0x1D4].AppTime)
    {
        AppMsgTime[MSG_0x1D4].AppTime--;
    }
    
    if (AppMsgTime[MSG_0x1D5].msgEvent) {
        if (((AppMsgTime[MSG_0x1D5].msgEventCnt == 0) && (AppMsgTime[MSG_0x1D5].AppTime < 90)) || ((AppMsgTime[MSG_0x1D5].msgEventCnt) && (AppMsgTime[MSG_0x1D5].AppTime < 10))) {
            AppMsgTime[MSG_0x1D5].msgEvent = 0;
            AppMsgTime[MSG_0x1D5].msgEventCnt = 2;
            AppMsgTime[MSG_0x1D5].AppTime = 0;
        }
    }
    
    if(AppMsgTime[MSG_0x1D5].AppTime)
    {
        AppMsgTime[MSG_0x1D5].AppTime--;
    }*/
      
    NM_tSleepRequTimeCount_Fun();
}


/*-------------------------------------------------------------------------
* Function Name  : NM_CheckBatVolt
* Description    : 
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void NM_SetIgnState(uint8_t IgnPosition)
{
    NM_IGN_State = IgnPosition;
}

/*-------------------------------------------------------------------------
* Function Name  : NM_CheckBatVolt
* Description    : 
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void NM_CheckBatVolt(uint16_t adValue)
{
    uint32_t temp = 0;
    temp = adValue;
    //temp = temp * 43 * 50 / 4095 + 65;
    temp = temp * 50 * 43 / 4095;
    NM_BatVolt = temp + 65;
}

/*-------------------------------------------------------------------------
* Function Name  : NM_TranMsgSuccessDetect
* Description    : palace in interrupt
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void NM_TranMsgSuccessDetect(void)
{
    if(NM_LAST_ID == NM_CAN_CHL_ID)
    {
        NM_TX_STATE = 1;
        NM_ER_STATE = 0;
        NM_LAST_ID = 0;
        NM_D_Online( );
    }
}

/*-------------------------------------------------------------------------
* Function Name  : NM_TranMsgErrorDetect
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void NM_TranMsgErrorDetect( void )
{
    if(NM_LAST_ID == NM_CAN_CHL_ID)
    {
        NM_LAST_ID = 0;
        NM_D_Online( );
        
        NM_ER_STATE = 1;
        NM_TX_STATE = 0;
    }
}

/*-------------------------------------------------------------------------
* Function Name  : NM_CheckSleep_Fun
* Description    : check self sleep condition
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void NM_CheckSleep_Fun(void)
{
    NM_LocalWakeup_Fun( );
}

/*-------------------------------------------------------------------------
* Function Name  : NM_LocalWakeup_Fun
* Description    : KL15 voltage wakeup event handle
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void NM_LocalWakeup_Fun(void)
{
    if(NM_IGN_State == NM_IGN_ON)
    {
        if(NetWorkStatus.WakeupEvent != NM_LocalWakeup)
        {
            NetWorkStatus.WakeupEvent = NM_LocalWakeup;

            Eic_Disable((stc_eic00_t *) &EIC00, 6);
        }
        
        NM_tSleepRequestMin = 0;
        NM_SPDU.bits.Opcode &= 0xCF;
        NetWorkStatus.bussleep = NM_NO;
    }
    else
    {
        if(NM_Main_Program != NMBusSleep_main)
        {
             NetWorkStatus.WakeupEvent = NM_WaitWakeup;
        }
        
        if(NM_LastSend_PDU_Type == LIMP_HOME_MSG)
        {
            if(NM_LimpHomeTxCnt >= NM_Time_RequestLimpSleepInd)
            {
                NM_LimpHomeTxCnt = 0;
                NetWorkStatus.bussleep = NM_YES;
            }
        }
        else if((NM_LastSend_PDU_Type == ALIVE_MSG) || (NM_LastSend_PDU_Type == RING_MSG))
        {
            if(NM_tSleepRequestMin >= NM_Time_RequestSleepInd)
            {
                NetWorkStatus.bussleep = NM_YES;
            }
        }
    }
}


/*-------------------------------------------------------------------------
* Function Name  : NM_RemoteWakeup_Fun
* Description    : Remote data or PDU Frame wakeup event handle
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void NM_RemoteWakeup_Fun(void)
{
    NetWorkStatus.WakeupEvent = NM_RemoteWakeup;
    NetWorkStatus.bussleep = NM_NO;
    NM_tSleepRequestMin = 0;
}

/*-------------------------------------------------------------------------
* Function Name  : NM_tSleepRequTimeCount_Fun
* Description    : tSleepRequestN / tSleepRequestL count
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void NM_tSleepRequTimeCount_Fun(void)
{ 
    if((NM_SPDU.bits.Opcode & 0x10) == 0)
    {
        if(NM_tSleepRequestMin <= 10000)
        {
            NM_tSleepRequestMin += 2;
        }
    }
}

/*-------------------------------------------------------------------------
* Function Name  : NM_Receive_isr_Fun
* Description    : handle receive PDU;
* Input          :
* Output         : None
* Return         : None
* onther         : propose : in interrupt function
--------------------------------------------------------------------------*/
void NM_Receive_isr_Fun(uint16_t id,uint8_t *pBuf)
{
    if((id >= NM_CAN_ID_BASE) && (id <= NM_CAN_ID_BOTTOM))
    {
        if(NM_PDU_BUF.bits.ProceF == NM_BUF_EMPTY)
        {
            NM_ID_BUF = id - NM_CAN_ID_BASE;
            NM_PDU_BUF.msg[ 0 ] = *(pBuf + 0);
            NM_PDU_BUF.msg[ 1 ] = *(pBuf + 1);
            NM_PDU_BUF.msg[ 2 ] = *(pBuf + 2);
            NM_PDU_BUF.msg[ 3 ] = *(pBuf + 3);
            NM_PDU_BUF.msg[ 4 ] = *(pBuf + 4);
            NM_PDU_BUF.msg[ 5 ] = *(pBuf + 5);
            NM_PDU_BUF.msg[ 6 ] = *(pBuf + 6);
            NM_PDU_BUF.msg[ 7 ] = *(pBuf + 7);
            NM_PDU_BUF.bits.ProceF = NM_BUF_FULL;
        }
    }
}

/*-------------------------------------------------------------------------
* Function Name  : NM_Send_PDU_Fun
* Description    : Send PDU Message interface function
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void NM_Send_PDU_Fun( void )
{
    uint8_t  bufInex = 0; 
      
    NM_SPDU .msg[ 0 ] = NM_Destination;
    
    CanFD_Send_StandMsg(CANFD1_Type,NM_CAN_CHL_ID,bufInex,TX_ISR_EN,(uint8_t *)&NM_SPDU.msg[ 0 ],8);

}

/*-------------------------------------------------------------------------
* Function Name  : NM_Send_App_Fun
* Description    : Send Application Message interface function
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void NM_Send_App_Fun( void )
{
    if(NetWorkStatus.BusOffEvent) //at busoff disable send app msg
    {
        return;
    }

    if(AppMsgSendRequest)
    {
        if (AppMsgTime[MSG_0x1DF].AppTime == 0) {
            if (AppMsgTime[MSG_0x1DF].msgEventCnt) {
                AppMsgTime[MSG_0x1DF].msgEventCnt--;
                AppMsgTime[MSG_0x1DF].AppTime = 20;
            } else {
                AppMsgTime[MSG_0x1DF].AppTime = 100;
            }
            //Send0x1DF();
        }
             
        if (AppMsgTime[MSG_0x1D4].AppTime == 0) {
            if (AppMsgTime[MSG_0x1D4].msgEventCnt) {
                AppMsgTime[MSG_0x1D4].msgEventCnt--;
                AppMsgTime[MSG_0x1D4].AppTime = 20;
            } else {
                AppMsgTime[MSG_0x1D4].AppTime = 100;
            }
            //Send0x1D4();
        }
             
        if (AppMsgTime[MSG_0x1D5].AppTime == 0) {
            if (AppMsgTime[MSG_0x1D5].msgEventCnt) {
                AppMsgTime[MSG_0x1D5].msgEventCnt--;
                AppMsgTime[MSG_0x1D5].AppTime = 20;
            } else {
                AppMsgTime[MSG_0x1D5].AppTime = 100;
            }
            //Send0x1D5();
        }
        
  
    }
}