void HARTLayer7CommandInterpreter(void)
{
TUSIGN16 objIdx;
TUSIGN8 idx, direction, element;
TBOOL configChanged;
COM_OBJ_DESCR SLOW *cmdDescr;
const T_BURSTMSG_CONFVALUES *burstMsgConfDataPtr;
T_BURSTMSG_MANAGEVALUES *burstMsgManageDataPtr;
TUSIGN16 cmdNumberIndex = 0;
TUSIGN16 cmdNumber = 0;
TUSIGN8 objectCount = 0;
TBOOL isPrimaryMasterActive;
// reset error code
TUSIGN16 errorCode = OK;
// *** burst time management ***
// if all burst messages with elapsed max update period sent
if (counterBurstMsgToSend == 0)
{
// for all burst messages
for (idx = 0; idx < hartCst.bursttotalNumberOfMsg; idx++)
{
// pointer of burst message specific management objects
burstMsgManageDataPtr = burstMsgManageObjRefTable[idx].burstMsgManageObjPtr;
// pointer of burst message number specific conf data objects
burstMsgConfDataPtr = burstMsgConfObjRefTable[idx].burstMsgConfObjPtr;
// if update period counter of actual burst message != 0
if (burstMsgManageDataPtr->updatePeriodCounter != 0)
{
// decrement counter value
burstMsgManageDataPtr->updatePeriodCounter--;
}
// if maximum update period counter of actual burst message != 0
if (burstMsgManageDataPtr->maximumUpdatePeriodCounter != 0)
{
// decrement counter value
burstMsgManageDataPtr->maximumUpdatePeriodCounter--;
// if max update period elapsed
if(burstMsgManageDataPtr->maximumUpdatePeriodCounter == 0)
{
// actualize counter of burst messages with elapsed max update period
counterBurstMsgToSend++;
}
}
else
{
// if burst mode enabled for current burst message
if(burstMsgConfDataPtr->modeControlCode != 0)
{
// actualize counter of burst messages with elapsed max update period
counterBurstMsgToSend++;
}
}
}
}
//if squawk active
if(squawkCounter != 0)
{
// actualize remaining squawk
squawkCounter--;
//if squawk not active
if(squawkCounter == 0)
{
// switch squawk to "off"
// @@adjust
//application.SquawkMessageOff_SRV();
}
}
// clear all requests
requestsLayer2_LAYER7 = NO_LAYER2_REQ;
// If first layer 2 request then set request flag and copy receive/transmit buffer from layer 2
if (AskIfLayer7requested_LAYER2())
{
// request from first layer2 set as layer2 identifier
requestsLayer2_LAYER7 = FIRST_LAYER2;
// prepare layer 7 receive / transmit buffer
receiveBuffer_LAYER7 = uReceiveBuffer_LAYER2;
transmitBuffer_LAYER7 = uTransmitBuffer_LAYER2;
}
// else if burst enabled AND no burst message generated set as layer2 identifier
else if ( (DetectBurstMode_LAYER2())
&& (uLayer2flags.burstMsgRespBuilt == 0))
{
// re-initialize burstCmdChanged flag
uLayer2flags.burstCmdChanged = 0;
// pseudo burst request signed as received via first layer2
requestsLayer2_LAYER7 = FIRST_LAYER2;
// prepare LAYER7 receive buffer with request data bytes of burst command
PrepareBurstBuf_LAYER7();
//set flag: burst message generated
uLayer2flags.burstMsgReqBuilt = 1;
}
else
{
}
// if layer2 identifier set
if (requestsLayer2_LAYER7 != NO_LAYER2_REQ)
{
// set default number of data bytes = 2 for response bytes
transmitBuffer_LAYER7.numByte = 2;
// get command number
cmdNumber = (TUSIGN16)transmitBuffer_LAYER7.command;
//Put() Last Received Command Number 2011-09-01
(void)HARTPutObjects(HART_IDX, HART_IDX_lastReceiveCommandNumber, (void*)&cmdNumber);
// if command number == command expansion flag
if (cmdNumber == EXTENSION_COMMAND_NUMBER)
{
// if no extended command number in request available
if (receiveBuffer_LAYER7.numByte < 2)
{
// if device works compliant to hart rev 5
if (hartFreqCst.univCmdRev == 5)
{
// set response code "command not implemented" in 1. response byte
transmitBuffer_LAYER7.firstResp = HART_RESP_ERR_CMD_NOT_IMPLEMENTED;
}
else
{
// set response code "too few data" in 1. response byte
transmitBuffer_LAYER7.firstResp = HART_RESP_ERR_TOO_FEW_DATA;
}
// set error flag
cmdNumberIndex = INVALID_CMD_NUMBER_INDEX;
}
else
{
// copy extended command number in transmit buffer
transmitBuffer_LAYER7.aryData[0] = receiveBuffer_LAYER7.aryData[0];
transmitBuffer_LAYER7.aryData[1] = receiveBuffer_LAYER7.aryData[1];
// set default number of data bytes = 4 for response bytes and extended command number
transmitBuffer_LAYER7.numByte = 4;
// get extended command number
cmdNumber = (TUSIGN16)(receiveBuffer_LAYER7.aryData[0] << 8) + (TUSIGN16)receiveBuffer_LAYER7.aryData[1];
// if command number < 256 (see HCF_SPEC-99 Rev. 9.0 page 29 range for expanded cmd number is 256-65535)
if (cmdNumber < 256)
{
// set response code "invalid extended command number"
transmitBuffer_LAYER7.firstResp = HART_RESP_ERR_INVALID_EXT_CMD_NUMBER;
// set error flag
cmdNumberIndex = INVALID_CMD_NUMBER_INDEX;
}
}
}
//else no extended command
else
{
// if device works compliant to hart rev 5
if (hartFreqCst.univCmdRev == 5)
{
// if command number out of universal command area
if (cmdNumber <= 30)
{
// if command number not hart revision 5 universal command
if( ( (cmdNumber > 6)
&& (cmdNumber < 11))
|| (cmdNumber > 19))
{
// set error flag
cmdNumberIndex = INVALID_CMD_NUMBER_INDEX;
// set command not implemented response code in 1. response byte
transmitBuffer_LAYER7.firstResp = HART_RESP_ERR_CMD_NOT_IMPLEMENTED;
}
}
else
{
// if command number not hart revision 5 common practice command
if( (cmdNumber > 70)
&& ( (cmdNumber < 107)
|| (cmdNumber > 111))
&& (cmdNumber < 121))
{
// set error flag
cmdNumberIndex = INVALID_CMD_NUMBER_INDEX;
// set command not implemented response code in 1. response byte
transmitBuffer_LAYER7.firstResp = HART_RESP_ERR_CMD_NOT_IMPLEMENTED;
}
}
}
}
// if (no error from extended command so long), ...
if (cmdNumberIndex != INVALID_CMD_NUMBER_INDEX)
{
// Search for command table index
cmdNumberIndex = HARTFindCmdTableIndex(cmdNumber);
// Command not implemented?
if (cmdNumberIndex == INVALID_CMD_NUMBER_INDEX)
{
// Set command not implemented response code in 1. response byte
transmitBuffer_LAYER7.firstResp = HART_RESP_ERR_CMD_NOT_IMPLEMENTED;
}
// if not enough data received && not hart rev. 5 specific data of cmd 6, 38, 48
else if ((receiveBuffer_LAYER7.numByte < commands[cmdNumberIndex].requestDataLength) &&
(!((cmdNumber == 6) && (receiveBuffer_LAYER7.numByte == 1))) &&
(!((cmdNumber == 38) && (receiveBuffer_LAYER7.numByte == 0))) &&
(!((cmdNumber == 48) && (receiveBuffer_LAYER7.numByte == 0))) &&
(!((cmdNumber == 105) && (receiveBuffer_LAYER7.numByte == 0))) &&
(!((cmdNumber == 107) && (receiveBuffer_LAYER7.numByte > 0))) &&// (receiveBuffer_LAYER7.numByte <= 4)))&&// updated 3/27 2013 just follow the Hart7 spec to support more slots;
(!((cmdNumber == 51) && (receiveBuffer_LAYER7.numByte > 0) && (receiveBuffer_LAYER7.numByte <= 4))) &&
(!((cmdNumber == 108) && (receiveBuffer_LAYER7.numByte == 1))) &&
(!((cmdNumber == 109) && (receiveBuffer_LAYER7.numByte == 1))))
{
transmitBuffer_LAYER7.firstResp = HART_RESP_ERR_TOO_FEW_DATA; // too few data bytes
}
else
{
// Read or Write ?
if ((commands[cmdNumberIndex].fct == HART_READ) || (commands[cmdNumberIndex].fct == HART_SPECIAL_READ))
{
direction = ACCESS_READ;
}
else
{
direction = ACCESS_WRITE;
}
//Check for write protection*/
isPrimaryMasterActive = (TBOOL)((receiveBuffer_LAYER7.aryAdr[0] & LAYER2_PRIMARY_MASTER) != 0x00);
// Set access right response code in 1. response byte
transmitBuffer_LAYER7.firstResp = HARTCanAccess(cmdNumber, direction, isPrimaryMasterActive);
// Proceed with read / write activity if access is permitted
if( transmitBuffer_LAYER7.firstResp == HART_RESP_OK)
{
switch (commands[cmdNumberIndex].fct)
{
case (HART_READ):
// set pointer to command object description
cmdDescr = (COM_OBJ_DESCR SLOW *) commands[cmdNumberIndex].cmdDescr;
// get number of objects
objectCount = commands[cmdNumberIndex].objectCount;
//if device works compliant to hart rev. 5
if (hartFreqCst.univCmdRev == 5)
{
// if cmd 0 to process
if (cmdNumber == 0)
{
// truncate object command processing after 10th object
objectCount = 10;
}
// if cmd 15 to process
if (cmdNumber == 15)
{
// truncate object command processing after 7th object
objectCount = 7;
}
}
// if find device one time
if ( (cmdNumber == 73)
&& (t_unit_mapper.findDeviceSwitch == HART_FIND_DEVICE_ONE_TIME))
{
// disable find device
hartDyn.findDeviceSwitch = HART_FIND_DEVICE_DISABLED;
t_unit_mapper.findDeviceSwitch = HART_FIND_DEVICE_DISABLED;
}
//if cmd 72 (squawk) to process
if(cmdNumber == 72)
{
//if squawk not active
if(squawkCounter == 0)
{
// switch squawk to "on"
// @@adjust
//application.SquawkMessageOn_SRV();
}
//set squawk counter
squawkCounter = (SQUAWK_TIME / HART_LAYER7_CMD_INTERPRETER_CYCL_TIME) + 1;
}
else
{
// read objects
HARTReadObjects(cmdDescr, objectCount);
}
break;
case (HART_WRITE):
// set data length anyway
transmitBuffer_LAYER7.numByte = 2 + commands[cmdNumberIndex].requestDataLength;
// if command 18
if(cmdNumber == 18)
{
//check date value
errorCode = Check_HART_Date ((HART_DATE_VALUE *) &receiveBuffer_LAYER7.aryData[18]);
}
else
{}
if (errorCode == OK)
{
// set pointer to command object description
cmdDescr = (COM_OBJ_DESCR SLOW *) commands[cmdNumberIndex].cmdDescr;
// get number of objects
objectCount = commands[cmdNumberIndex].objectCount;
// get config changed state
configChanged = commands[cmdNumberIndex].configChanged;
// if cmd 6 request contains only polling address
if ((cmdNumber == 6) && (receiveBuffer_LAYER7.numByte == 1))
{
// Set no. of request specific object commands to 1
objectCount= 1;
// write only polling address to its object
(void)HARTWriteObjects(cmdDescr, objectCount, configChanged);
//If device works conform to HART 7
if (hartFreqCst.univCmdRev == 7)
{
//copy loop current mode in response behind polling adrress
transmitBuffer_LAYER7.aryData[1] = hartFreqCst.loopCurrentMode;
// correct response length
transmitBuffer_LAYER7.numByte++;
}
}
else
{
// write objects
(void)HARTWriteObjects(cmdDescr, objectCount, configChanged);
}
}
break;
case (HART_SPECIAL_READ):
case (HART_SPECIAL_WRITE):
switch (cmdNumber)
{
case 9:
case 33:
case 54:
//set error code
errorCode = OK;
for(idx = 0; idx < receiveBuffer_LAYER7.numByte; idx++)
{
// if non valid device variable index
//add,2013-01-25.
//@Ajust:
//ToDo: The hartCst.maxNoOfDevVariables shall be changed according to different number of device variable in different device.
//The value is 3 in current APP. The max sloc number is 249.
if( ( (receiveBuffer_LAYER7.aryData[idx] > hartCst.maxNoOfDevVariables)
&& (receiveBuffer_LAYER7.aryData[idx] < 244))
|| (receiveBuffer_LAYER7.aryData[idx] > 249))
{
// error code invalid burst message
transmitBuffer_LAYER7.firstResp = HART_RESP_ERR_INVALID_SELECTION;
transmitBuffer_LAYER7.numByte = 2;
// set error code
errorCode = RULE_VIOLATION_ERR;
}
// In case device acts as a HART5 slave not supported device variables must reply
// with "invalid selection" to requests
//@@Adjust
else if(hartFreqCst.univCmdRev == 5)
{
/* (void)HARTGetObjects(ELEC_SER_IDX, ELEC_SER_IDX_activatedOptions, &activatedOptions);
// Slot 5,6 and 7 reply with invalid selection if the pressure option is not fitted
if( (!(activatedOptions & ELEC_SER_PRESSURE)) && ((receiveBuffer_LAYER7.aryData[idx] > 4)
&& (receiveBuffer_LAYER7.aryData[idx] < 8)) )
{
// error code invalid burst message
transmitBuffer_LAYER7.firstResp = HART_RESP_ERR_INVALID_SELECTION;
transmitBuffer_LAYER7.numByte = 2;
// set error code
errorCode = RULE_VIOLATION_ERR;
} */
}
else{}
}
// if no error
if(errorCode == OK)
{
// read/write objects of special commands
HARTSpecialReadWriteObjects(cmdNumberIndex);
// Special handling for #9 and #33
// unit code must be set to 250 if device variable is set to NaN
/* if(cmdNumber == 9)
{
// Check for float values that are set to NaN and change the
// according (previous) unit code to 250
for(i=4; i<=60; i+=8)
{
// Get the float to be checked (TUSIGN32 because NaN = 0x7FA00000 ==>swap 0x0000A07F)
testNaN = *(TUSIGN32*)(transmitBuffer_LAYER7.aryData + i);
if( testNaN == 0x0000A07F )
{
// Change unit code to "not used"
transmitBuffer_LAYER7.aryData[i-1] = 250;
}
else{}
}
}
else if(cmdNumber == 33)
{
// Check for float values that are set to NaN and change the
// according (previous) unit code to 250
for(i=2; i<=20; i+=6)
{
// Get the float to be checked (TUSIGN32 because NaN = 0x7FA00000 ==>swap 0x0000A07F)
testNaN = *(TUSIGN32*)(transmitBuffer_LAYER7.aryData + i);
if( testNaN == 0x0000A07F )
{
// Change unit code to "not used"
transmitBuffer_LAYER7.aryData[i-1] = 250;
}
else{}
}
}
else // if (cmdNumber == 54)
{
// truncucate response to be 27byte + 2
transmitBuffer_LAYER7.numByte = 29;
}*/
}
break;
case 38:
// write a value != 0 to perform an action function
element = 0xFF;
// action object resetConfigFlag
objIdx = HART_IDX_resetConfigFlag;
// write as an attribute
(void)HARTPutAttribute(HART_IDX, objIdx, 0, (void*)&element);
break;
case 48:
// write a value != 0 to perform an action function
element = 0xFF;
// action object resetConfigFlag
objIdx = HART_IDX_resetMoreStatusAvailable;
// write as an attribute
(void)HARTPutAttribute(HART_IDX, objIdx, 0, (void*)&element);
break;
case 51:
HARTSpecialReadWriteObjects(cmdNumberIndex);
break;
case 103:
// burst command 103 execution
HARTCommand_103();
break;
case 104:
// burst command 104 execution
HARTCommand_104();
break;
case 105:
// burst command 105 execution
HARTCommand_105();
break;
case 107:
// burst command 103 execution
HARTCommand_107();
break;
case 108:
// burst command 108 execution
HARTCommand_108();
break;
case 109:
// burst command 109 execution
HARTCommand_109();
break;
// @@st HART 7.4 diagnosis enhancements
case 523:
if (receiveBuffer_LAYER7.numByte < 4)
{
// Invalid number of bytes received
transmitBuffer_LAYER7.firstResp = HART_RESP_ERR_TOO_FEW_DATA;
transmitBuffer_LAYER7.numByte = 4;
}
else
{
HARTSpecialReadWriteObjects(cmdNumberIndex);
// Fill transmit buffer with correct response values
// Note: first two bytes will be the ext. cmd. no.
transmitBuffer_LAYER7.aryData[2] = hartDyn.startingIndexCmd523;
transmitBuffer_LAYER7.aryData[3] = hartDyn.noOfEntriesToReadCmd523;
// Fill in the mapping information as selected in #523
for (idx = 0; idx < (TUSIGN8)(hartDyn.noOfEntriesToReadCmd523 / 2); idx++)
{
transmitBuffer_LAYER7.aryData[idx+4] = hartDyn.statusMapArrayCmd523[idx];
}
// The response was build in hart_overload.c
// The slot command will copy startingIndexCmd523, noOfEntriesToReadCmd523
// followed by the complete statusMapArrayCmd523 array into the transmit buffer
// But rather than sending all out the telegram must be truncucated here
// to (noOfEntriesToReadCmd523/2) + 2byte index and no of values + 2byte frist/second response +2 ext. cmd no.
transmitBuffer_LAYER7.numByte = (hartDyn.noOfEntriesToReadCmd523 / 2) + 2 + 2 +2;
}
break;
default:
// read/write objects of special commands
HARTSpecialReadWriteObjects(cmdNumberIndex);
break;
}
break;
default:
break;
}
}
else{}
}
}
// Determine value of second response byte
transmitBuffer_LAYER7.secResp = HARTCheckSecRespByte(requestsLayer2_LAYER7);
// if first layer 2 request done, ...
if (requestsLayer2_LAYER7 == FIRST_LAYER2)
{
// copy layer 7 transmit buffer to layer 2 transmit buffer
uTransmitBuffer_LAYER2 = transmitBuffer_LAYER7;
// clear request flags
ClearLayer7request_LAYER2();
requestsLayer2_LAYER7 = NO_LAYER2_REQ;
// start response
StartResponse_LAYER2();
}
if (uLayer2flags.burstMsgReqBuilt == 1)
{
uLayer2flags.burstMsgRespBuilt = 1;
uLayer2flags.burstMsgReqBuilt = 0;
}
}
}
HART1
最新推荐文章于 2024-11-04 09:53:33 发布