#include "NM_includes.h" OSEK_NM_PARA NmPara; /*------------------------------------------------------------------------- * Function Name : NM_Do_Nothing * Description : * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void NM_Do_Nothing(void) { ; } /*------------------------------------------------------------------------- * Function Name : NM_Do_Nothing * Description : * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void NM_State_Transformation(void (*pProgram)(void)) { NmPara.NmTxState = 0; NmPara.NmRxState = 0; NmPara.NmErrState = 0; NmPara.NM_Main_Program = pProgram; } /*------------------------------------------------------------------------- * Function Name : NM_ReceiveMsg_handle * Description : handle receive PDU; * Input : * Output : None * Return : None * onther : propose : in interrupt function --------------------------------------------------------------------------*/ void NM_ReceiveMsg_handle(void) { if(NmPara.NmPduBuf.bits.ProceF == BUF_FULL) { NmPara.NmRecvPdu.msg[0] = NmPara.NmPduBuf.msg[0]; NmPara.NmRecvPdu.msg[1] = NmPara.NmPduBuf.msg[1]; NmPara.NmRecvPdu.msg[2] = NmPara.NmPduBuf.msg[2]; NmPara.NmRecvPdu.msg[3] = NmPara.NmPduBuf.msg[3]; NmPara.NmRecvPdu.msg[4] = NmPara.NmPduBuf.msg[4]; NmPara.NmRecvPdu.msg[5] = NmPara.NmPduBuf.msg[5]; NmPara.NmRecvPdu.msg[6] = NmPara.NmPduBuf.msg[6]; NmPara.NmRecvPdu.msg[7] = NmPara.NmPduBuf.msg[7]; NmPara.NmRecvPdu.bits.SourceID = NmPara.NmIdBuf; NmPara.NmRxState = 1; NmPara.NmPduBuf.bits.ProceF = BUF_EMPTY; } } /*------------------------------------------------------------------------- * Function Name : OsekNM_Manage_Main * Description : OSEK Main function * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void OsekNM_Manage_Main(void) { if (NmPara.NmTaskLock == NM_LOCK) { return; } NM_Time_2ms_Count(); if (NmPara.NM_Main_Program == NMLimpHome_main) { NmPara.NmState = NM_STATE_LIMPHOME_MAIN; } else if (NmPara.NM_Main_Program == NMNormal_main) { NmPara.NmState = NM_STATE_NORMAL_MAIN; } else if (NmPara.NM_Main_Program == NMTwbsNormal_main) { NmPara.NmState = NM_STATE_TWBSNORMAL_MAIN; } else if (NmPara.NM_Main_Program == NMNormalPrepSleep_main) { NmPara.NmState = NM_STATE_NORMALPREPSLEEP_MAIN; } else if (NmPara.NM_Main_Program == NMBusSleep_main) { NmPara.NmState = NM_STATE_BUSSLEEP_MAIN; } else if (NmPara.NM_Main_Program == NMLimpHomePrepSleep_main) { NmPara.NmState = NM_STATE_LIMPHOMEPREPSLEEP_MAIN; } else if (NmPara.NM_Main_Program == NMTwbsLimpHome_main) { NmPara.NmState = NM_STATE_TWBSLIMPHOME_MAIN; } else if (NmPara.NM_Main_Program == NMReset_main) { NmPara.NmState = NM_STATE_RESET_MAIN; } else if (NmPara.NM_Main_Program == NM_Do_Nothing) { NmPara.NmState = NM_STATE_DO_NOTHING; } NM_CheckBusOff_Fun(); NM_ReceiveMsg_handle(); NM_CheckSleep_Fun(); if (NmPara.NmIGNState == NM_IGN_ON) { if(NmPara.NmNetWorkStatus.bussleep == NM_NO) { if(NmPara.NM_Main_Program != NMBusSleep_main) { GotoMode(NMAwake); } } } if (NmPara.NM_Main_Program == 0) { NmPara.NM_Main_Program = NMReset_main; } NM_CheckBusOff_Fun(); if (NmPara.NmNetWorkStatus.NMactive == NM_Active) { (*NmPara.NM_Main_Program)(); } if (NmPara.NmNetWorkStatus.APPactive == NM_Active) { NM_Send_App_Fun(); } } /*------------------------------------------------------------------------- * Function Name : NMInitReset * Description : * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void NMInitReset(void) { NmPara.NmRxErrCount = 0; NmPara.NmTxErrCount = 0; NM_D_Online(); } /*------------------------------------------------------------------------- * Function Name : NMReset * Description : * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void NMReset(void) { NmPara.NmDestination = NmPara.NmIdOwn; NmPara.NmRxErrCount++; NmPara.NmRecvPdu.bits.Opcode = 0; NmPara.NmTxState = 0; NmPara.NmRxState = 0; NmPara.NmErrState = 0; NmPara.NmSleepRequestMin = 0; NmPara.NmLimpHomeTxCnt = 0; NmPara.NmNetWorkStatus.bussleep = NM_NO; Transmit_NMPDU(ALIVE_MSG); } /*------------------------------------------------------------------------- * Function Name : NMReset_main * Description : * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void NMReset_main(void) { if (NmPara.NMInitReset_Program == NMInitReset) { (*NmPara.NMInitReset_Program)(); NmPara.NMInitReset_Program = NM_Do_Nothing; } if (NmPara.NMReset_Program == NMReset) { (*NmPara.NMReset_Program)(); NmPara.NMReset_Program = NM_Do_Nothing; } if ((NmPara.NmErrState + NmPara.NmTxState) == 0) { if (NmPara.NmResetContinueCallCnt < 10) { NmPara.NmResetContinueCallCnt++; } else { NmPara.NmResetContinueCallCnt = 0; NmPara.NmErrState = 1; } } if (NmPara.NmErrState) { NMReset_error(); return; } if (NmPara.NmTxState) { NMReset_tx(); } } void NMReset_error(void) { NmPara.NmTxErrCount++; if ((NmPara.NmTxErrCount > NmPara.NmTxLimit) || (NmPara.NmRxErrCount > NmPara.NmRxLimit)) { NM_SetTSendTimer(NmPara.NmTimeError, (_NM_TimeInfo *)&NmPara.NmTime); NmPara.NmMarker.limphome = NM_NO; NM_State_Transformation(NMLimpHome_main); } else { NM_SetTSendTimer(NmPara.NmTimeType, (_NM_TimeInfo *)&NmPara.NmTime); NM_State_Transformation(NMNormal_main); } } void NMReset_tx(void) { if ((NmPara.NmTxErrCount <= NmPara.NmTxLimit) && (NmPara.NmRxErrCount <= NmPara.NmRxLimit)) { NM_SetTSendTimer(NmPara.NmTimeType, (_NM_TimeInfo*)&NmPara.NmTime); NM_State_Transformation(NMNormal_main); } else { NM_SetTSendTimer(NmPara.NmTimeError, (_NM_TimeInfo*)&NmPara.NmTime); NmPara.NmMarker.limphome = NM_NO; NM_State_Transformation(NMLimpHome_main); } } void NMReset_rx(void) { unsigned char OpCode = 0; unsigned char Source = 0; NmPara.NmRxState = 0; NmPara.NmRxErrCount = 0; if (NmPara.NmLastSendPDUType == ALIVE_MSG) { Source = NmPara.NmRecvPdu.bits.SourceID; OpCode = NmPara.NmRecvPdu.msg[ 1 ]; if (OpCode & 0x03) { NM_ConfigLogicalFun(Source); } } } /*------------------------------------------------------------------------- * Function Name : StartNM * Description : * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void StartNM(void) { NmPara.NmMarker.stable = NM_Unstabitily; NmPara.NmSleep.ind = NM_NO; NmPara.NmSleep.ack = NM_NO; NM_D_Init(BusInit); NmPara.NmTaskLock = NM_UNLOCK; TalkNM(); TalkAPP(); NMInitReset(); NMReset(); NmPara.NM_Main_Program = NMReset_main; NmPara.NMInitReset_Program = NM_Do_Nothing; NmPara.NMReset_Program = NM_Do_Nothing; NmPara.NmNetWorkStatus.BusOffEvent = DISABLE; NmPara.NmNetWorkStatus.WakeupEvent = NM_WaitWakeup; NmPara.NmSleepRequestMin = 0; } /*------------------------------------------------------------------------- * Function Name : InitNM * Description : * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void InitNM(OSEK_NM_INIT *NmInit) { NmPara.NmIdBase=0X500; //2018-04-10 //default:0x400 NmPara.NmIdBottom=0X5FF; //default:0x4ff NmPara.NmIdOwn=0X03;// //default:0x4; NmPara.NmRxLimit=4; //default:0x4 NmPara.NmTxLimit=8; //default:0x8 NmPara.NmTimeType=100;//100; //default:100,unit:ms NmPara.NmTimeMax=260;//260; //default:260,unit:ms NmPara.NmTimeError=1000;//1000; //default:1000,unit:ms NmPara.NmTimeWaitBusSleep=1500; //default:1500,unit:ms NmPara.NmTimeRequestSleepInd=5000; //default:5000,unit:ms NmPara.NmTimeRequestLimpSleepInd=4; //default:4 if ((NmInit->NmIdBase) && (NmInit->NmIdBottom) && (NmInit->NmIdBase != NmInit->NmIdBottom)) { NmPara.NmIdBase = NmInit->NmIdBase; NmPara.NmIdBottom = NmInit->NmIdBottom; } if ((NmInit->NmIdBase + NmInit->NmIdOwn) < NmInit->NmIdBottom) { NmPara.NmIdOwn = NmInit->NmIdOwn; } if (NmPara.NmRxLimit) { NmPara.NmRxLimit = NmInit->NmRxLimit; } if (NmPara.NmTxLimit) { NmPara.NmTxLimit = NmInit->NmTxLimit; } if (NmPara.NmTimeType) { NmPara.NmTimeType = NmInit->NmTimeType; } if (NmPara.NmTimeMax) { NmPara.NmTimeMax = NmInit->NmTimeMax; } if (NmPara.NmTimeError) { NmPara.NmTimeError = NmInit->NmTimeError; } if (NmPara.NmTimeWaitBusSleep) { NmPara.NmTimeWaitBusSleep = NmInit->NmTimeWaitBusSleep; } if (NmPara.NmTimeRequestSleepInd) { NmPara.NmTimeRequestSleepInd = NmInit->NmTimeRequestSleepInd; } if (NmPara.NmTimeRequestLimpSleepInd) { NmPara.NmTimeRequestLimpSleepInd = NmInit->NmTimeRequestLimpSleepInd; } StartNM(); } /*------------------------------------------------------------------------- * Function Name : SetTxState * Description : * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void SetTxState(unsigned char n) { NmPara.NmTxState = n; } /*------------------------------------------------------------------------- * Function Name : SetRxState * Description : * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void SetRxState(unsigned char n) { NmPara.NmRxState = n; } /*------------------------------------------------------------------------- * Function Name : SetErrState * Description : * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void SetErrState(unsigned char n) { NmPara.NmErrState = n; } /*------------------------------------------------------------------------- * Function Name : NMNormal_main * Description : * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void NMNormal_main(void) { if (NmPara.NmErrState) { NMNormal_error(); return; } else if (NmPara.NmTxState) { NMNormal_tx(); if (NmPara.NM_Main_Program == NMNormalPrepSleep_main) { return; } } if (NmPara.NmRxState) { NMNormal_rx(); if (NmPara.NM_Main_Program == NMTwbsNormal_main) { return; } } if (NM_TSendTimerOver((_NM_TimeInfo*)&NmPara.NmTime)) { if (NmPara.NmNetWorkStatus.NMactive == NM_Active) { NM_SetTmaxTimer(NmPara.NmTimeMax, (_NM_TimeInfo *)&NmPara.NmTime); Transmit_NMPDU(RING_MSG); } } if (NM_TmaxTimerOver((_NM_TimeInfo*)&NmPara.NmTime)) { NMReset(); NmPara.NM_Main_Program = NMReset_main; } } void NMNormal_rx (void) { unsigned char OpCode = 0; unsigned char Source = 0; unsigned char Destination = 0; unsigned char Own_Node_Staute = 0; unsigned char OwnID = 0; NmPara.NmRxState = 0; NmPara.NmRxErrCount = 0; Source = NmPara.NmRecvPdu.bits.SourceID; Destination = NmPara.NmRecvPdu.bits.DestID; OpCode = NmPara.NmRecvPdu.msg[1]; if (OpCode & 0x03) { NM_ConfigLogicalFun(Source); } if (OpCode & 0x10) { NmPara.NmSleep.ind = NM_YES; } else { NmPara.NmSleep.ind = NM_NO; } if (OpCode & 0x02) {//RING CancelAlarm(NmPara.NmTimeType); CancelAlarm(NmPara.NmTimeMax); if(OpCode & 0x20) {//NmSleep_ACK=1 if(NmPara.NmNetWorkStatus.bussleep) { NM_SetTwbsTimer(NmPara.NmTimeWaitBusSleep, (_NM_TimeInfo *)&NmPara.NmTime); NM_State_Transformation(NMTwbsNormal_main); return; } } OwnID = NmPara.NmIdOwn; if((Destination == OwnID) || (Source == Destination)) { NM_SetTSendTimer(NmPara.NmTimeType,(_NM_TimeInfo *)&NmPara.NmTime); } else { NM_SetTmaxTimer(NmPara.NmTimeMax,(_NM_TimeInfo *)&NmPara.NmTime); Own_Node_Staute = NM_CheckSkip(Source,Destination,OwnID); if (Own_Node_Staute == NM_NODE_SKIP) { NmPara.NmDestination = OwnID; Transmit_NMPDU(ALIVE_MSG); } } } else if(OpCode & 0x01) { NmPara.NmMarker.stable = NM_Unstabitily; } } void NMNormal_tx(void) { NmPara.NmTxState = 0; NmPara.NmTxErrCount = 0; if ((NmPara.NmSleep.ind) && (NmPara.NmNetWorkStatus.bussleep) && (NmPara.NmLastSendPDUType == RING_MSG)) { NM_SetTmaxTimer(NmPara.NmTimeMax, (_NM_TimeInfo *)&NmPara.NmTime); CancelAlarm(NmPara.NmTimeType); NmPara.NmSleep.ack = NM_YES; NM_State_Transformation(NMNormalPrepSleep_main); AbortAllCanTx(); } } void NMNormal_error(void) { NmPara.NmErrState = 0; NmPara.NmTxErrCount++; if (NmPara.NmTxErrCount > NmPara.NmTxLimit) { NM_SetTSendTimer(NmPara.NmTimeError, (_NM_TimeInfo*)&NmPara.NmTime); NmPara.NmMarker.limphome = NM_NO; NM_State_Transformation(NMLimpHome_main); } } /*------------------------------------------------------------------------- * Function Name : NMNormalPrepSleep_main * Description : * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void NMNormalPrepSleep_main(void) { if (NmPara.NmErrState) { NMNormalPrep_error(); return; } else if (NmPara.NmTxState) { NMNormalPrep_tx(); return; } if (NmPara.NmRxState) { NMNormalPrep_rx(); if ((NmPara.NM_Main_Program == NMTwbsNormal_main) || (NmPara.NM_Main_Program == NMNormal_main)) { return; } } if (NM_TmaxTimerOver((_NM_TimeInfo*)&NmPara.NmTime)) { CancelAlarm(NmPara.NmTimeError); CancelAlarm(NmPara.NmTimeType); NmPara.NmMarker.limphome = NM_NO; NMReset(); NmPara.NM_Main_Program = NMReset_main; return; } if (NM_TSendTimerOver((_NM_TimeInfo*)&NmPara.NmTime)) { if(NmPara.NmNetWorkStatus.NMactive == NM_Active) { Transmit_NMPDU(RING_MSG); } } } void NMNormalPrep_rx(void) { unsigned char OpCode = 0; unsigned char Source = 0; unsigned char Destination = 0; unsigned char Own_Node_Staute = 0; unsigned char OwnID = 0; NmPara.NmRxState = 0; NmPara.NmRxErrCount = 0; Source = NmPara.NmRecvPdu.bits.SourceID; Destination = NmPara.NmRecvPdu.bits.DestID; OpCode = NmPara.NmRecvPdu.msg[ 1 ]; if (OpCode & 0x03) { NM_ConfigLogicalFun(Source); } if (OpCode & 0x10) { NmPara.NmSleep.ind = NM_YES; } else { NmPara.NmSleep.ind = NM_NO; } OwnID = NmPara.NmIdOwn; if (NmPara.NmSleep.ind == NM_NO) { CancelAlarm(NmPara.NmTimeMax); CancelAlarm(NmPara.NmTimeType); if ((Destination == OwnID) || (Source == Destination)) { NM_SetTSendTimer(NmPara.NmTimeType, (_NM_TimeInfo *)&NmPara.NmTime); } else { NM_SetTmaxTimer(NmPara.NmTimeMax, (_NM_TimeInfo *)&NmPara.NmTime); Own_Node_Staute = NM_CheckSkip(Source, Destination, OwnID); if (Own_Node_Staute == NM_NODE_SKIP) { NmPara.NmDestination = OwnID; Transmit_NMPDU(ALIVE_MSG); } } NmPara.NM_Main_Program = NMNormal_main; } else { if (OpCode & 0x02) {//RING if ((OpCode & 0x20) == 0x20) {//NmSleep_ACK=1 CancelAlarm(NmPara.NmTimeType); CancelAlarm(NmPara.NmTimeMax); NM_SetTwbsTimer(NmPara.NmTimeWaitBusSleep, (_NM_TimeInfo *)&NmPara.NmTime); NM_State_Transformation(NMTwbsNormal_main); return; } CancelAlarm(NmPara.NmTimeType); CancelAlarm(NmPara.NmTimeMax); if ((Destination == OwnID) || (Source == Destination)) { NM_SetTSendTimer(NmPara.NmTimeType, (_NM_TimeInfo *)&NmPara.NmTime); } else { NM_SetTmaxTimer(NmPara.NmTimeMax,(_NM_TimeInfo *)&NmPara.NmTime); Own_Node_Staute = NM_CheckSkip(Source, Destination, OwnID); if (Own_Node_Staute == NM_NODE_SKIP) { NmPara.NmDestination = OwnID; Transmit_NMPDU(ALIVE_MSG); } } } else if (OpCode & 0x01) { NmPara.NmMarker.stable = NM_Unstabitily; } } } void NMNormalPrep_tx(void) { NmPara.NmTxState = 0; if (NmPara.NmLastSendPDUType == RING_MSG) { NM_SetTwbsTimer(NmPara.NmTimeWaitBusSleep, (_NM_TimeInfo *)&NmPara.NmTime); NM_State_Transformation(NMTwbsNormal_main); } } void NMNormalPrep_error(void) { NmPara.NmErrState = 0; if (NmPara.NmLastSendPDUType == RING_MSG) { NM_SetTwbsTimer(NmPara.NmTimeWaitBusSleep, (_NM_TimeInfo *)&NmPara.NmTime); NM_State_Transformation(NMTwbsNormal_main); } } /*------------------------------------------------------------------------- * Function Name : NMTwbsNormal_main * Description : * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void NMTwbsNormal_main(void) { NM_D_Offline(); if (NmPara.NmRxState) { NMTwbsNormal_rx(); if(NmPara.NM_Main_Program == NMReset_main) { return; } } if (NM_TwbsTimerOver((_NM_TimeInfo*)&NmPara.NmTime)) { NM_State_Transformation(NMBusSleep_main); } } void NMTwbsNormal_rx(void) { NmPara.NmRxState = 0; NM_SetTmaxTimer(NmPara.NmTimeMax, (_NM_TimeInfo*)&NmPara.NmTime); NmPara.NmSleep.ind = NmPara.NmRecvPdu.msg[1] & 0x30; if (NmPara.NmSleep.ind == 0) { NMInitReset(); NMReset(); NmPara.NM_Main_Program = NMReset_main; } } /*------------------------------------------------------------------------- * Function Name : NMLimpHome_main * Description : * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void NMLimpHome_main(void) { if (NmPara.NmTxState) { NMLimpHome_tx(); return; } if (NmPara.NmErrState) { NMLimpHome_error(); return; } if (NmPara.NmRxState) { NMLimpHome_rx(); if((NmPara.NM_Main_Program == NMReset_main) || (NmPara.NM_Main_Program == NMTwbsLimpHome_main)) { return; } } if (NM_TSendTimerOver((_NM_TimeInfo*)&NmPara.NmTime)) { if (NmPara.NmNetWorkStatus.bussleep) { NM_SetTmaxTimer(NmPara.NmTimeMax, (_NM_TimeInfo *)&NmPara.NmTime); NmPara.NmTxState = 0; NmPara.NmRxState = 0; NmPara.NmErrState = 0; NmPara.NmDestination = NmPara.NmIdOwn; Transmit_NMPDU(LIMP_HOME_MSG); if (NmPara.NmSleep.ind) { NM_State_Transformation(NMLimpHomePrepSleep_main); } } else { NM_SetTSendTimer(NmPara.NmTimeError, (_NM_TimeInfo*)&NmPara.NmTime); Transmit_NMPDU(LIMP_HOME_MSG); } } } void NMLimpHome_rx(void) { unsigned char OpCode = 0; NmPara.NmRxState = 0; OpCode = NmPara.NmRecvPdu.msg[ 1 ]; if (OpCode & 0x20) { NmPara.NmSleep.ack = 1; } else { NmPara.NmSleep.ack = 0; } if (OpCode & 0x10) { NmPara.NmSleep.ind = NM_YES; } else { NmPara.NmSleep.ind = NM_NO; } if (NmPara.NmNetWorkStatus.NMactive == NM_Active) { if (NmPara.NmMarker.limphome == NM_YES) { if (NmPara.NmNetWorkStatus.bussleep) { if (NmPara.NmSleep.ack) { NM_SetTwbsTimer(NmPara.NmTimeWaitBusSleep, (_NM_TimeInfo*)&NmPara.NmTime); NM_State_Transformation(NMTwbsLimpHome_main); } else { CancelAlarm(NmPara.NmTimeError); NmPara.NmMarker.limphome = NM_NO; NMInitReset(); NMReset(); NmPara.NM_Main_Program = NMReset_main; } } else {//if(NmNetWorkStatus.bussleep == NM_NO) //5 CancelAlarm(NmPara.NmTimeError); NmPara.NmMarker.limphome = NM_NO; NMInitReset(); NMReset(); NmPara.NM_Main_Program = NMReset_main; } } else { if (NmPara.NmSleep.ack) { NM_SetTwbsTimer(NmPara.NmTimeWaitBusSleep, (_NM_TimeInfo*)&NmPara.NmTime); NM_State_Transformation(NMTwbsLimpHome_main); } else {//5 CancelAlarm(NmPara.NmTimeError); NmPara.NmMarker.limphome = NM_NO; NMInitReset(); NMReset(); NmPara.NM_Main_Program = NMReset_main; } } } } void NMLimpHome_tx(void) { NmPara.NmTxState = 0; if (NmPara.NmLastSendPDUType == LIMP_HOME_MSG) { NmPara.NmMarker.limphome = NM_YES; NM_SetTSendTimer(NmPara.NmTimeError, (_NM_TimeInfo*)&NmPara.NmTime); } } void NMLimpHome_error(void) { NmPara.NmErrState = 0; if(NmPara.NmLastSendPDUType == LIMP_HOME_MSG) { if(!NmPara.NmTime.TtypEnable) { NM_SetTSendTimer(NmPara.NmTimeError, (_NM_TimeInfo*)&NmPara.NmTime); } } } /*------------------------------------------------------------------------- * Function Name : NMLimpHomePrepSleep_main * Description : * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void NMLimpHomePrepSleep_main(void) { if (NmPara.NmRxState) { NMLimpHomePrepSleep_rx(); if ((NmPara.NM_Main_Program == NMLimpHome_main) || (NmPara.NM_Main_Program == NMTwbsLimpHome_main)) { return; } } if (NM_TmaxTimerOver((_NM_TimeInfo*)&NmPara.NmTime)) {//P39 NM_D_Offline(); NM_SetTwbsTimer(NmPara.NmTimeWaitBusSleep, (_NM_TimeInfo*)&NmPara.NmTime); NM_State_Transformation(NMTwbsLimpHome_main); } } void NMLimpHomePrepSleep_rx(void) { unsigned char OpCode = 0; NmPara.NmRxState = 0; OpCode = NmPara.NmRecvPdu.msg[1]; if (OpCode & 0x20) {//P39 NM_SetTwbsTimer(NmPara.NmTimeWaitBusSleep, (_NM_TimeInfo*)&NmPara.NmTime); NM_State_Transformation(NMTwbsLimpHome_main); } else if (OpCode & 0x10) { ; } else { NM_SetTSendTimer(NmPara.NmTimeError, (_NM_TimeInfo*)&NmPara.NmTime); NM_State_Transformation(NMLimpHome_main); } } /*------------------------------------------------------------------------- * Function Name : NMTwbsLimpHome_main * Description : * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void NMTwbsLimpHome_main(void) { NM_D_Offline(); if (NmPara.NmRxState) { NMTwbsLimpHome_rx(); if (NmPara.NM_Main_Program == NMLimpHome_main) { return; } } if (NM_TwbsTimerOver((_NM_TimeInfo*)&NmPara.NmTime)) { NM_State_Transformation(NMBusSleep_main); } } void NMTwbsLimpHome_rx(void) { unsigned char OpCode = 0; NmPara.NmRxState = 0; OpCode = NmPara.NmRecvPdu.msg[1]; if ((OpCode & 0x30) == 0) { NM_SetTSendTimer(NmPara.NmTimeError,(_NM_TimeInfo*)&NmPara.NmTime); NM_State_Transformation(NMLimpHome_main); } } /*------------------------------------------------------------------------- * Function Name : NMBusSleep_main * Description : * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void NMBusSleep_main(void) { NM_D_Offline(); NmPara.NmRxErrCount = 0; NmPara.NmTxErrCount = 0; if (NmPara.NmNetWorkStatus.WakeupEvent == NM_LocalWakeup) { NmPara.NmNetWorkStatus.WakeupEvent = NM_WaitWakeup; GotoMode(NMAwake); } else if (NmPara.NmNetWorkStatus.WakeupEvent == NM_RemoteWakeup) { NmPara.NmNetWorkStatus.WakeupEvent = NM_WaitWakeup; GotoMode(NMAwake); } else { GotoMode(NMBusSleep); } } /*------------------------------------------------------------------------- * Function Name : NM_CheckSkip * Description : * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ unsigned char NM_CheckSkip(unsigned char Source, unsigned char Destination, unsigned char Own_Node) { unsigned char S = 0; unsigned char R = 0; unsigned char D = 0; unsigned char skip; S = Source; R = Own_Node; D = Destination; skip = 0; if (D < R) { if (S < D) { ; } else { if (S < R) { skip = NM_NODE_SKIP; } } } else { if (S < D) { if (S < R) { skip = NM_NODE_SKIP; } } else { skip = NM_NODE_SKIP; } } return skip; } /*------------------------------------------------------------------------- * Function Name : NM_ConfigLogicalFun * Description : determine logical successor * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void NM_ConfigLogicalFun(unsigned char SourceID) { unsigned char S = 0; unsigned char R = 0; unsigned char L = 0; S = SourceID; R = NmPara.NmIdOwn; L = NmPara.NmDestination; if (L == R) { L = S; } else { if (L < R) { if (S < L) { L = S; } else { if (S < R) { } else { L = S; } } } else { if (S < L) { if (S < R) { } else { L = S; } } } } NmPara.NmDestination = L; } /*------------------------------------------------------------------------- * Function Name : GotoMode * Description : * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void GotoMode(unsigned char Mode) { switch (Mode) { case NMBusSleep: NmPara.NmTxState = 0; NmPara.NmRxState = 0; NmPara.NmErrState = 0; NM_D_Init(BusSleep); SilentNM(); break; case NMAwake: if ((NmPara.NM_Main_Program == NMNormal_main) || (NmPara.NM_Main_Program == NMLimpHome_main)) { break; } if (NmPara.NM_Main_Program == NMTwbsNormal_main) { CancelAlarm(NmPara.NmTimeWaitBusSleep); NMInitReset(); NM_State_Transformation(NMReset_main); NmPara.NmDestination = NmPara.NmIdOwn; NmPara.NmRxErrCount++; Transmit_NMPDU(ALIVE_MSG); break; } if (NmPara.NM_Main_Program == NMLimpHomePrepSleep_main) { NmPara.NmMarker.limphome = NM_NO; NM_State_Transformation(NMLimpHome_main); NM_D_Online(); Transmit_NMPDU(LIMP_HOME_MSG); NM_SetTSendTimer(NmPara.NmTimeError,(_NM_TimeInfo*)&NmPara.NmTime); break; } if (NmPara.NM_Main_Program == NMTwbsLimpHome_main) { CancelAlarm(NmPara.NmTimeWaitBusSleep); NmPara.NmMarker.limphome = NM_NO; NM_State_Transformation(NMLimpHome_main); NM_D_Online( ); Transmit_NMPDU(LIMP_HOME_MSG); NM_SetTSendTimer(NmPara.NmTimeError, (_NM_TimeInfo*)&NmPara.NmTime); break; } if (NmPara.NM_Main_Program == NMBusSleep_main) { NM_D_Init(BusInit); //initialize hardware by D_Init(...;BusInit)//NMInit NmPara.NmMarker.limphome = NM_NO;//NMInit NMInitReset(); NmPara.NmDestination = NmPara.NmIdOwn; //P26 reset the system specific default configuration NmPara.NmRxErrCount++; //P25 NM_State_Transformation(NMReset_main); NmPara.NmSendPdu.bits.Opcode &= 0xCF; Transmit_NMPDU(ALIVE_MSG); break; } break; default: NM_State_Transformation(NM_Do_Nothing); } } /*------------------------------------------------------------------------- * Function Name : Transmit_NMPDU * Description : PDU Message handle * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void Transmit_NMPDU(unsigned char PDU_Type) { NmPara.NmLastSendPDUType = PDU_Type; NmPara.NmSleep.ind = NmPara.NmNetWorkStatus.bussleep; switch (PDU_Type) { case ALIVE_MSG: NmPara.NmSendPdu.bits.Opcode = 0x01; NmPara.NmSleep.ack = 0; NmPara.NmMarker.stable = NM_Unstabitily; break; case RING_MSG: NmPara.NmSendPdu.bits.Opcode = 0x02; NmPara.NmMarker.stable = NM_Stabilize; break; case LIMP_HOME_MSG: NmPara.NmSendPdu.bits.Opcode = 0x04; NmPara.NmSleep.ack = 0; NmPara.NmMarker.stable = NM_Unstabitily; break; default: ; } if ((NmPara.NmSendPdu.bits.Opcode & 0x04) == 0x04) { if (NmPara.NmLimpHomeTxCnt < 255) { NmPara.NmLimpHomeTxCnt ++; } } else { NmPara.NmLimpHomeTxCnt = 0; } if (NmPara.NmSleep.ind == NM_YES) { NmPara.NmSendPdu.bits.Opcode |= 0x10; } else { NmPara.NmSendPdu.bits.Opcode &= 0xCF; } if (NmPara.NmSleep.ind == NM_NO) { NmPara.NmSleep.ack = 0; } if (NmPara.NM_Main_Program != NMNormalPrepSleep_main) { NmPara.NmSleep.ack = NM_NO; } if (NmPara.NmSleep.ack) { NmPara.NmSendPdu.bits.Opcode |= 0x20; } else { NmPara.NmSendPdu.bits.Opcode &= 0xDF; } NmPara.NmSendPdu.bits.NM_Data0 = 0x00; NmPara.NmSendPdu.bits.NM_Data1 = 0x00; NmPara.NmSendPdu.bits.NM_Data2 = 0x00; NmPara.NmSendPdu.bits.NM_Data3 = 0x00; NmPara.NmSendPdu.bits.Reserved0 = 0x00; NmPara.NmSendPdu.bits.Reserved1 = 0x00; NmPara.NmErrState = 0; NmPara.NmTxState = 0; NM_Send_PDU_Fun(); } /*------------------------------------------------------------------------- * Function Name : CancelAlarm * Description : Cansel Ttyp /Tmax /Terror count * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void CancelAlarm(unsigned int timetype) { if (timetype == NmPara.NmTimeError) { NmPara.NmTime.TtypEnable = 0; NmPara.NmTime.TtypTime = 0; } else if (timetype == NmPara.NmTimeType) { NmPara.NmTime.TtypEnable = 0; NmPara.NmTime.TtypTime = 0; } else if (timetype == NmPara.NmTimeMax) { NmPara.NmTime.TmaxEnable = 0; NmPara.NmTime.TmaxTime = 0; } else if (timetype == NmPara.NmTimeWaitBusSleep) { NmPara.NmTime.SleepEnable = 0; } } /*------------------------------------------------------------------------- * Function Name : NM_SetTmaxTimer * Description : set Tmax count start * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void NM_SetTmaxTimer(unsigned int Second, _NM_TimeInfo *T) { T->TtypEnable = 0; T->TtypTime = 0; T->TmaxEnable = 1; T->OverTmaxTime = Second; T->TmaxTime = 0; } /*------------------------------------------------------------------------- * Function Name : NM_TmaxTimerOver * Description : check Tmax out * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ unsigned char NM_TmaxTimerOver(_NM_TimeInfo *T) { if ((T->TmaxTime >= T->OverTmaxTime) && (T->TmaxEnable)) { T->TmaxEnable = 0; T->TmaxTime = 0; return 1; } else { return 0; } } /*------------------------------------------------------------------------- * Function Name : NM_SetTSendTimer * Description : set Ttyp or Terror count * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void NM_SetTSendTimer(unsigned int Second, _NM_TimeInfo *T) { T->TmaxEnable = 0; T->TmaxTime = 0; T->TtypEnable = 1; T->OverTtypTime = Second; T->TtypTime = 0; } /*------------------------------------------------------------------------- * Function Name : NM_TSendTimerOver * Description : Ttyp or Terror out * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ unsigned char NM_TSendTimerOver(_NM_TimeInfo *T) { if ((T->TtypTime >= T->OverTtypTime) && (T->TtypEnable)) { T->TtypEnable = 0; T->TtypTime = 0; return 1; } else { return 0; } } /*------------------------------------------------------------------------- * Function Name : NM_SetTwbsTimer * Description : set Twbs count * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void NM_SetTwbsTimer(unsigned int Second, _NM_TimeInfo *T) { T->TwbsEnable = 1; T->OverTwbsTime = Second; T->TwbsTime = 0; } /*------------------------------------------------------------------------- * Function Name : NM_TwbsTimerOver * Description : check Twbs out * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ unsigned char NM_TwbsTimerOver(_NM_TimeInfo *T) { if ((T->TwbsTime >= T->OverTwbsTime) && (T->TwbsEnable)) { T->TwbsEnable = 0; return 1; } else { return 0; } } /*------------------------------------------------------------------------- * Function Name : NM_SetSleepTimer * Description : set sleep wait timer * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ void NM_SetSleepTimer(unsigned int Second, _NM_TimeInfo *T) { T->SleepEnable = 1; T->OverSleepTime = Second; T->SleepTime = 0; } /*------------------------------------------------------------------------- * Function Name : NmSleepTimerOver * Description : * Input : * Output : None * Return : None * onther : --------------------------------------------------------------------------*/ unsigned char NmSleepTimerOver(_NM_TimeInfo *T) { if((T->SleepTime >= T->OverSleepTime) && (T->SleepEnable)) { T->SleepEnable = 0; T->SleepTime = 0; return 1; } else { return 0; } }