void FMSTR_AppCmdSetResponseData(FMSTR_ADDR nResultDataAddr, FMSTR_SIZE nResultDataLen)
{
    /* any data supplied by user? */
    if(nResultDataAddr)
    {
        /* response data length is trimmed if response data would not fit into buffer */
        pcm_nAppCmdResultDataLen = (FMSTR_SIZE8) nResultDataLen;
        if(pcm_nAppCmdResultDataLen > (FMSTR_SIZE8) FMSTR_APPCMD_BUFF_SIZE)
        {
            pcm_nAppCmdResultDataLen = (FMSTR_SIZE8) FMSTR_APPCMD_BUFF_SIZE;
        }

        if(pcm_nAppCmdResultDataLen > 0U)
        {
            FMSTR_ADDR appCmdBuffAddr;
            FMSTR_ARR2ADDR(appCmdBuffAddr, pcm_pAppCmdBuff);
            FMSTR_CopyMemory(appCmdBuffAddr, nResultDataAddr, pcm_nAppCmdResultDataLen);
        }
    }
    else
    {
        /* no data being returned at all (same effect as pure FMSTR_AppCmdAck) */
        pcm_nAppCmdResultDataLen = 0U;
    }
}
FMSTR_BPTR FMSTR_StoreAppCmd(FMSTR_BPTR pMessageIO)
{
    FMSTR_BPTR pResponse = pMessageIO;
    FMSTR_U8 nArgsLen;
    FMSTR_U8 nCode;

    /* the previous command not yet processed */
    if(pcm_nAppCmd != FMSTR_APPCMDRESULT_NOCMD)
    {
        return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_SERVBUSY);
    }

    pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 1U);
    pMessageIO = FMSTR_ValueFromBuffer8(&nArgsLen, pMessageIO);
    pMessageIO = FMSTR_ValueFromBuffer8(&nCode, pMessageIO);

    /* args len is datalen minus one */
    nArgsLen--;
        
    /* does the application command fit to buffer ? */
    if (nArgsLen > (FMSTR_SIZE8) FMSTR_APPCMD_BUFF_SIZE)
    {
        return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_INVBUFF);
    }
    
    /* store command data into dedicated buffer */
    pcm_nAppCmd = nCode;
    pcm_nAppCmdLen = nArgsLen;
    
    /* data copy */
    if(nArgsLen)
    {
        FMSTR_ADDR appCmdBuffAddr;
        FMSTR_ARR2ADDR(appCmdBuffAddr, pcm_pAppCmdBuff);
        
        /*lint -e{534} ignoring return value */
        FMSTR_CopyFromBuffer(appCmdBuffAddr, pMessageIO, (FMSTR_SIZE8) nArgsLen);
    }

    /* mark command as "running" (without any response data) */
    pcm_nAppCmdResult = FMSTR_APPCMDRESULT_RUNNING;
    pcm_nAppCmdResultDataLen = 0U;

    return FMSTR_ConstToBuffer8(pResponse, FMSTR_STS_OK);
}
FMSTR_BPTR FMSTR_GetAppCmdRespData(FMSTR_BPTR pMessageIO)
{
    FMSTR_BPTR pResponse = pMessageIO;
    FMSTR_U8 nDataLen;
    FMSTR_U8 nDataOffset;

    /* the previous command not yet processed */
    if(pcm_nAppCmd != FMSTR_APPCMDRESULT_NOCMD)
    {
        return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_SERVBUSY);
    }

    pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 1U);
    pMessageIO = FMSTR_ValueFromBuffer8(&nDataLen, pMessageIO);
    pMessageIO = FMSTR_ValueFromBuffer8(&nDataOffset, pMessageIO);

    /* the response would not fit into comm buffer */
    if(nDataLen > (FMSTR_U16)FMSTR_COMM_BUFFER_SIZE)
    {
        return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_RSPBUFFOVF);
    }
    
    /* the data would be fetched outside the app.cmd response data */
    if((((FMSTR_U16)nDataOffset) + nDataLen) > (FMSTR_SIZE8)pcm_nAppCmdResultDataLen)
    {
        return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_INVSIZE);
    }
    
    pResponse = FMSTR_ConstToBuffer8(pResponse, FMSTR_STS_OK);

    /* copy to buffer */
    {    
        FMSTR_ADDR appCmdBuffAddr;
        FMSTR_ARR2ADDR(appCmdBuffAddr, pcm_pAppCmdBuff);
        pResponse = FMSTR_CopyToBuffer(pResponse, appCmdBuffAddr, (FMSTR_SIZE8)nDataLen);
    }
    
    return pResponse;
}
void FMSTR_InitRec(void)
{   
    /* initialize Recorder flags*/
    pcm_wRecFlags.all = 0U;

    /* setup buffer pointer and size so IsInRecBuffer works even  
       before the recorder is first initialized and used */
    
#if FMSTR_REC_OWNBUFF
    /* user wants to use his own buffer */
    pcm_nRecBuffAddr = 0U;
    pcm_wRecBuffSize = 0U;
#elif FMSTR_USE_FASTREC
    /* Initialize Fast Recorder Buffer  */
    FMSTR_InitFastRec();
#else
    /* size in native sizeof units (=bytes on most platforms) */
    FMSTR_ARR2ADDR(pcm_nRecBuffAddr, pcm_pOwnRecBuffer);
    
    /*lint -esym(528, pcm_pOwnRecBuffer) this symbol is used outside of lint sight */
#endif

}
FMSTR_BPTR FMSTR_SetUpRec(FMSTR_BPTR pMessageIO)
{
    FMSTR_BPTR pResponse = pMessageIO;
    FMSTR_SIZE8 nRecVarsetSize;
    FMSTR_SIZE blen;
    FMSTR_U8 i, sz;
    FMSTR_U8 nResponseCode;
    
    /* de-initialize first   */
    FMSTR_AbortRec();

#if FMSTR_REC_OWNBUFF
    /* user wants to use his own buffer, check if it is valid */
    if(!pcm_nRecBuffAddr || !pcm_wRecBuffSize)
    {
        return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_INVBUFF);
    }
#elif (FMSTR_USE_FASTREC) == 0
    /* size in native sizeof units (=bytes on most platforms) */
    FMSTR_ARR2ADDR(pcm_nRecBuffAddr, pcm_pOwnRecBuffer);
#endif

    /* seek the setup data */
#if (FMSTR_USE_FASTREC) == 0
    pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 2U);
    pMessageIO = FMSTR_ValueFromBuffer8(&pcm_nRecTriggerMode, pMessageIO);
#else /* (FMSTR_USE_FASTREC) == 0 */
    pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 3U);
#endif /* (FMSTR_USE_FASTREC) == 0 */

    pMessageIO = FMSTR_ValueFromBuffer16(&pcm_wRecTotalSmps, pMessageIO);

#if (FMSTR_REC_STATIC_POSTTRIG) == 0
    pMessageIO = FMSTR_ValueFromBuffer16(&pcm_wRecPostTrigger, pMessageIO);
#else /* (FMSTR_REC_STATIC_POSTTRIG) == 0 */
    pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 2U);
#endif /* (FMSTR_REC_STATIC_POSTTRIG) == 0 */

#if (FMSTR_REC_STATIC_DIVISOR) == 0
    pMessageIO = FMSTR_ValueFromBuffer16(&pcm_wRecTimeDiv, pMessageIO);
#else /* (FMSTR_REC_STATIC_DIVISOR) == 0 */
    pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 2U);
#endif /* (FMSTR_REC_STATIC_DIVISOR) == 0 */

#if (FMSTR_USE_FASTREC) == 0
    /* address & size of trigger variable */
    pMessageIO = FMSTR_AddressFromBuffer(&pcm_nTrgVarAddr, pMessageIO);
    pMessageIO = FMSTR_ValueFromBuffer8(&pcm_nTrgVarSize, pMessageIO);

    /* trigger compare mode  */
    pMessageIO = FMSTR_ValueFromBuffer8(&pcm_bTrgVarSigned, pMessageIO);

    /* threshold value  */
    pMessageIO = FMSTR_ValueFromBuffer32(&pcm_uTrgThreshold.u32, pMessageIO);
#else /* (FMSTR_USE_FASTREC) == 0 */
    pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 8U);
#endif /* (FMSTR_USE_FASTREC) == 0 */
    
    /* recorder variable count */
    pMessageIO = FMSTR_ValueFromBuffer8(&pcm_nRecVarCount, pMessageIO);

    /* rec variable information must fit into our buffers */
    if(!pcm_nRecVarCount || pcm_nRecVarCount > (FMSTR_U8)FMSTR_MAX_REC_VARS)
    {
#if FMSTR_REC_COMMON_ERR_CODES
        goto FMSTR_SetUpRec_exit_error;
#else
        nResponseCode = FMSTR_STC_INVBUFF;
        goto FMSTR_SetUpRec_exit;
#endif
    }

    /* calculate sum of sizes of all variables */
    nRecVarsetSize = 0U;

    /* get all addresses and sizes */
    for(i=0U; i<pcm_nRecVarCount; i++)
    {
        /* variable size */
        pMessageIO = FMSTR_ValueFromBuffer8(&sz, pMessageIO);
        
        pcm_pRecVarSize[i] = sz;
        nRecVarsetSize += sz;
        
        /* variable address */
        pMessageIO = FMSTR_AddressFromBuffer(&pcm_pRecVarAddr[i], pMessageIO);

        /* valid numeric variable sizes only */
        if(sz == 0U || sz > 8U)
        {
#if FMSTR_REC_COMMON_ERR_CODES
            goto FMSTR_SetUpRec_exit_error;
#else
            nResponseCode = FMSTR_STC_INVSIZE;
            goto FMSTR_SetUpRec_exit;
#endif
        }

#if FMSTR_CFG_BUS_WIDTH > 1U
        /* even sizes only */
        if(sz & 0x1)
        {
#if FMSTR_REC_COMMON_ERR_CODES
            goto FMSTR_SetUpRec_exit_error;
#else
            nResponseCode = FMSTR_STC_INVSIZE;
            goto FMSTR_SetUpRec_exit;
#endif
        }
#endif /* FMSTR_CFG_BUS_WIDTH > 1U */
        
#if FMSTR_USE_TSA && FMSTR_USE_TSA_SAFETY
        if(!FMSTR_CheckTsaSpace(pcm_pRecVarAddr[i], (FMSTR_SIZE8)sz, 0U))
        {
#if FMSTR_REC_COMMON_ERR_CODES
            goto FMSTR_SetUpRec_exit_error;
#else
            nResponseCode = FMSTR_STC_EACCESS;
            goto FMSTR_SetUpRec_exit;
#endif
        }
#endif /* FMSTR_USE_TSA && FMSTR_USE_TSA_SAFETY */
    }

    /* fast recorder handles trigger by itself */
#if (FMSTR_USE_FASTREC) == 0
    /* any trigger? */
    pcm_pCompareFunc = NULL;
    if(pcm_nRecTriggerMode)
    {
        /* access to trigger variable? */
#if FMSTR_USE_TSA && FMSTR_USE_TSA_SAFETY
        if(!FMSTR_CheckTsaSpace(pcm_nTrgVarAddr, (FMSTR_SIZE8)pcm_nTrgVarSize, 0U))
        {
#if FMSTR_REC_COMMON_ERR_CODES
            goto FMSTR_SetUpRec_exit_error;
#else
            nResponseCode = FMSTR_STC_EACCESS;
            goto FMSTR_SetUpRec_exit;
#endif
        }
#endif /* FMSTR_USE_TSA && FMSTR_USE_TSA_SAFETY */
        /* get compare function */

#if FMSTR_REC_FLOAT_TRIG
                if(pcm_bTrgVarSigned&FMSTR_REC_FLOAT_TRIG_MASK)
                {
                        pcm_pCompareFunc = FMSTR_Comparefloat;
                }
                else
#else
                if(pcm_bTrgVarSigned&FMSTR_REC_FLOAT_TRIG_MASK)
                {
#if FMSTR_REC_COMMON_ERR_CODES
            goto FMSTR_SetUpRec_exit_error;
#else
            nResponseCode = FMSTR_STC_FLOATDISABLED;
            goto FMSTR_SetUpRec_exit;
#endif          	
                }
#endif
                {
        switch(pcm_nTrgVarSize)
        {
#if FMSTR_CFG_BUS_WIDTH == 1U
        case 1: pcm_pCompareFunc = pcm_bTrgVarSigned ? FMSTR_Compare8S : FMSTR_Compare8U; break;
#endif
        case 2: pcm_pCompareFunc = pcm_bTrgVarSigned ? FMSTR_Compare16S : FMSTR_Compare16U; break;
        case 4: pcm_pCompareFunc = pcm_bTrgVarSigned ? FMSTR_Compare32S : FMSTR_Compare32U; break;
        
        /* invalid trigger variable size  */
        default:
#if FMSTR_REC_COMMON_ERR_CODES
            goto FMSTR_SetUpRec_exit_error;
#else
            nResponseCode = FMSTR_STC_INVSIZE;
            goto FMSTR_SetUpRec_exit;
#endif
            }
        }
    }
#endif /* (FMSTR_USE_FASTREC) == 0 */
    
    /* total recorder buffer length in native sizeof units (=bytes on most platforms) */
    blen = (FMSTR_SIZE) (pcm_wRecTotalSmps * nRecVarsetSize / FMSTR_CFG_BUS_WIDTH);

    /* recorder memory available? */
    if(blen > FMSTR_GetRecBuffSize())
    {
#if FMSTR_REC_COMMON_ERR_CODES
        goto FMSTR_SetUpRec_exit_error;
#else
        nResponseCode = FMSTR_STC_INVSIZE;
        goto FMSTR_SetUpRec_exit;
#endif
    }

#if (FMSTR_USE_FASTREC) == 0
    /* remember the effective end of circular buffer */
    pcm_dwRecEndBuffPtr = pcm_nRecBuffAddr + blen;
#endif /* (FMSTR_USE_FASTREC) == 0 */

#if FMSTR_USE_FASTREC
    if(!FMSTR_SetUpFastRec())
    {
#if FMSTR_REC_COMMON_ERR_CODES
        goto FMSTR_SetUpRec_exit_error;
#else /* FMSTR_REC_COMMON_ERR_CODES */
        nResponseCode = FMSTR_STC_FASTRECERR;
        goto FMSTR_SetUpRec_exit;
#endif /* FMSTR_REC_COMMON_ERR_CODES */
    }
#endif /* FMSTR_USE_FASTREC */

    /* everything is okay    */
    pcm_wRecFlags.flg.bIsConfigured = 1U;
    nResponseCode = FMSTR_STS_OK;
#if FMSTR_REC_COMMON_ERR_CODES
    goto FMSTR_SetUpRec_exit;
FMSTR_SetUpRec_exit_error:
    nResponseCode = FMSTR_STC_INVSIZE;
#endif
FMSTR_SetUpRec_exit:
    return FMSTR_ConstToBuffer8(pResponse, nResponseCode);
}