HART1

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;
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值