📄 hartlol.c
字号:
/**********************************************************************
* Copyright (c) 1998 - 2000 by Borst Automation, Fachingen
* All rights reserved
*
* Filename: HartLoL.c
* Project: HART Slave
* Date: Sep-10-99
* Author(s): W. Borst
*
* Revision:
* Date: Name: Version: Description:
* Dec-03-98 W. Borst ----- Initial Draft
* Jan-20-99 W. Borst 1.0 Driver did not return error codes
* Change of NoComErr()
* Changes in BuildDefaultResponse
* Short frame only accepted for
* command 0
* FrameIsForMe()
* Sep-10-99 W. Borst 1.1 Changes for Project be001/99
* Jul-25-00 W. Borst 1.2 Changes for Project li001/00
*
*
* Description: Hart receive and send state machine.
* Receiver based on gap time out.
*
**********************************************************************/
/**********************************************************************
* The Standard Include *
**********************************************************************/
#define __HARTLOL_H__
#include "..\Protocol\HartLoL.h"
/**********************************************************************
* Public data *
**********************************************************************/
T_APP_INTF strHrtAppIf; /* Interface buffer for application */
/**********************************************************************
* Local data *
**********************************************************************/
static m_ucResponse2 = HRT_COLD_START;
/* IO state machine */
static T_COM_SM strHrtComSM =
{ 0,0,0,0,0,0,0,0,0,0,
{0xff,0xff,0xff,0xff,0xff} //Number of preambles
};
static T_APP_INTF astrHrtSrvBuf[2]; /* Buffer to store services */
static BYTE byHrtToState = HRT_TO_STATE_NONE;
/* Time out status */
static BYTE byHrtToCounter = 0;
/* Counter as multiple of
5 ms */
static BYTE byInChar = 0; /* The received character */
static BYTE byInErr = 0; /* The receiver error */
/**********************************************************************
* Public Functions *
**********************************************************************/
/*******/
VOID hrtInit()
/*******/
{
/* IO state machine structure */
strHrtComSM.byState = HRT_IO_IDLE;
/* Application interface buffers */
strHrtAppIf.byStatus = HRT_APP_IDLE;
astrHrtSrvBuf[0].byStatus = HRT_APP_IDLE;
astrHrtSrvBuf[1].byStatus = HRT_APP_IDLE;
M_HRT_INIT_COM;
}
/*###########*/
void hrt5msCycle(void)
/*###########*/
{ /*
* Call the data link layer on time out
*/
if(byHrtToCounter)
{ if (!(--byHrtToCounter))
DataLinkLayerFunction();
}
}
/*##########*/
void hrtGetChar()
/*##########*/
{ StartTimeOut(HRT_TO_GAP,HRT_TO_STATE_GAP);
byInChar = M_HRT_GET_RCV_CHAR;
byInErr = M_HRT_GET_RCV_ERROR;
switch (strHrtComSM.byState)
{ case HRT_IO_IDLE:
strHrtComSM.byCount = 0;
if (byInChar == HRT_PREAMBLE)
strHrtComSM.byState = HRT_WAIT_NEXT_PREAMBLE;
break;
case HRT_WAIT_NEXT_PREAMBLE:
if (byInChar == HRT_PREAMBLE)
strHrtComSM.byState = HRT_RCV_WAIT_DEL;
else
strHrtComSM.byState = HRT_IO_IDLE;
break;
case HRT_RCV_WAIT_DEL:
if (IsValidDel())
{ GetFirstChar();
strHrtComSM.byState = HRT_RCV_READING;
}
else
{ if (byInChar != HRT_PREAMBLE)
strHrtComSM.byState = HRT_IO_IDLE;
}
break;
case HRT_RCV_READING:
if (!(byInErr & 0x20))
GetNextChar();
break;
case HRT_IO_LOCKED:
break;
}
}
/*###############*/
VOID hrtTransmitDone(VOID)
/*###############*/
{
}
/*############*/
static VOID StartTimeOut(BYTE byTimeOutValue,BYTE byTimeOutState)
/*############*/
{ /*
* Set down counter with required timer value
*/
M_HRT_DISABLE_INTERRUPT;
byHrtToCounter = byTimeOutValue;
byHrtToState = byTimeOutState;
M_HRT_ENABLE_INTERRUPT;
}
/*###########*/
static VOID StopTimeOut(VOID)
/*###########*/
{
M_HRT_DISABLE_INTERRUPT;
byHrtToCounter = 0;
byHrtToState = HRT_TO_STATE_NONE;
M_HRT_ENABLE_INTERRUPT;
}
/*############*/
static BOOL FrameIsForMe(VOID)
/*############*/
/*
* The function is evaluating the received frame and is
* trying to find out why not to process the frame as early
* as possible.
* However, if the function is returning 'TRUE' this frame
* has to be worked out by the application.
*/
{ BYTE e;
BOOL bAddrMatch;
BYTE byCheck;
BYTE byLenPos;
BYTE byFrameLen;
if (strHrtComSM.byCount < HRT_MIN_FRAME_ABS)
/* DEL,ADR,CMD,LEN,CHK is minimum */
/* frame too short */
return FALSE; /* NOT ME!!! */
/* set master type */
if (strHrtComSM.byData[HRT_ADDR_POS] & HRT_MASTER_ADDR_BIT)
strHrtComSM.byMasterType = HRT_PRIM_MASTER;
else
strHrtComSM.byMasterType = HRT_SEC_MASTER;
if (strHrtComSM.bAddrErr) /* note: error was evaluated by GetNextChar() */
/* address error */
return FALSE; /* NOT ME!!! */
if ((strHrtComSM.byData[HRT_DELIMITER_POS] & HRT_DELIMITER_TYPE_MASK) != HRT_STX)
/* not a request */
return FALSE; /* NOT ME!!! */
bAddrMatch = FALSE; /* being pessimistic at this point */
if (strHrtComSM.byData[HRT_DELIMITER_POS] & HRT_LONG_ADDR)
{ /*
* long frame
*/
if (strHrtComSM.byCount < HRT_MIN_FRAME_LONG)
/* DEL,UN0,UN1,UN2,UN3,UN4,CMD,LEN,CHK
is minimum */
/* frame too short */
return FALSE; /* NOT ME!!! */
/* test if unique id is correct address */
bAddrMatch = TRUE; /* assume it is me */
/* mask out host address bits */
if ((strHrtComSM.byData[HRT_ADDR_POS] & HRT_MASK_OUT_HI_ADDR_BITS)
!=
(rs_osFbHartUniqueID[0] & HRT_MASK_OUT_HI_ADDR_BITS)
)
bAddrMatch = FALSE; /* not me */
/* Check the remaining part of the unique identifier */
for (e=1;e<5;e++)
{ if (strHrtComSM.byData[(HRT_ADDR_POS)+e] != rs_osFbHartUniqueID[e])
bAddrMatch = FALSE; /* not me */
}
/* set command */
strHrtComSM.byCmd = strHrtComSM.byData[HRT_LONGF_CMD_POS];
if (strHrtComSM.byData[HRT_LONGF_CMD_POS] == HRT_CMD_GET_UNIQUE_ID_BY_TAG)
{ /* addressed by tag name */
if (strHrtComSM.byCount < HRT_MIN_FRAME_BY_TAG)
/* DEL,UN0,UN1,UN2,UN3,UN4,CMD,LEN
TG0,TG1,TG2,TG3,TG4,TG5,CHK
is minimum */
/* frame too short */
return FALSE; /* NOT ME!!! */
if (strHrtComSM.byData[HRT_LONGF_LEN_POS] < HRT_TAG_NAME_SIZE)
/* data length error */
return FALSE; /* NOT ME!!! */
if (bAddrMatch == FALSE)
{ /* device was not addressed by unique id
check for broadcast address */
bAddrMatch = TRUE; /* assume it is me */
/* mask out host address bits */
if ((strHrtComSM.byData[HRT_ADDR_POS] & HRT_MASK_OUT_HI_ADDR_BITS) != 0)
return FALSE; /* NOT ME!!! */
/* Check for the broadcast address */
for (e=HRT_ADDR_POS+1;e<(HRT_LONG_ADDR_SIZE);e++)
{ if (strHrtComSM.byData[e] != HRT_BROADCAST_ADDR)
{ return FALSE; /* NOT ME!!! */
}
}
}
if (bAddrMatch)
{ /* now check for correct tag name */
for (e=0;e<HRT_TAG_NAME_SIZE;e++)
{ if (re_paFbHartTagName[e] != strHrtComSM.byData[HRT_LONGF_REQDATA_POS + e])
return FALSE; /* NOT ME!!! */
}
}
}
else
{ if (bAddrMatch == FALSE)
return FALSE; /* NOT ME!!! */
}
byLenPos = HRT_LONGF_LEN_POS;
bAddrMatch = TRUE; /* **** it is me, but is chk correct ? ****/
}
else
{ /*
* short frame
*/
if (strHrtComSM.byData[HRT_SHORTF_CMD_POS] !=
HRT_CMD_GET_UNIQUE_ID_BY_SHORT
)
return FALSE; /* This is not command 0, 20.1.99 */
if ((strHrtComSM.byData[HRT_ADDR_POS] & HRT_MASK_OUT_HI_ADDR_BITS) != re_ui8FbHartAddress)
return FALSE; /* NOT ME!!! */
byLenPos = HRT_SHORTF_LEN_POS;
/* set command */
strHrtComSM.byCmd = strHrtComSM.byData[HRT_SHORTF_CMD_POS];
bAddrMatch = TRUE; // **** it is me, but is chk correct ? ****
}
/***********************************
* Check if byte count was correct *
***********************************/
if (bAddrMatch)
{ if (strHrtComSM.byCount < (byLenPos + strHrtComSM.byData[byLenPos] + 2))
return FALSE; /* not enough data bytes received */
}
/***********************************/
if (bAddrMatch)
{ /* checksum check done only if no overflow */
if (!(strHrtComSM.byErr & HRT_ERR_BUFFER_OVERFLOW))
{ byCheck = 0;
byFrameLen = (BYTE)(byLenPos + 1 + strHrtComSM.byData[byLenPos]);
//checksum check
for (e=0;e<byFrameLen;e++)
{ byCheck ^= strHrtComSM.byData[e];
}
if (byCheck != strHrtComSM.byData[byFrameLen])
/* flag longitudinal address error */
strHrtComSM.byErr |= HRT_ERR_LONG_PARITY;
}
return TRUE;
}
else
{ return FALSE; /* No address match */
}
}
/*###########*/
static VOID GetNextChar(VOID)
/*###########*/
{ if (strHrtComSM.byCount >= HRT_MAX_IO_BUFFER)
{ byInErr |= HRT_ERR_BUFFER_OVERFLOW;
}
else
{ strHrtComSM.byData[strHrtComSM.byCount++] = byInChar;
}
/*******************
* Check for error *
*******************/
if (byInErr)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -