FMSTR_BOOL FMSTR_IsInRecBuffer(FMSTR_ADDR dwAddr, FMSTR_SIZE8 nSize)
{
    FMSTR_BOOL bRet = 0U;
    
    if(dwAddr >= pcm_nRecBuffAddr)
    {
        bRet = (FMSTR_BOOL)((dwAddr + nSize) <= (pcm_nRecBuffAddr + FMSTR_GetRecBuffSize()) ? FMSTR_TRUE : FMSTR_FALSE);    
    }
    
    return bRet;
}
FMSTR_BOOL FMSTR_IsInRecBuffer(FMSTR_ADDR dwAddr, FMSTR_SIZE8 nSize)
{
    FMSTR_BOOL bRet = 0U;
    
    /* Convert Word to Byte address */
    FMSTR_ADDR pcm_dwFastRecStartBuffBytePtr = pcm_dwFastRecStartBuffPtr * 2;
    
    if(dwAddr >= pcm_dwFastRecStartBuffBytePtr)
    {
        bRet = (FMSTR_BOOL)((dwAddr + nSize) <= (pcm_dwFastRecStartBuffBytePtr + FMSTR_GetRecBuffSize()) ? FMSTR_TRUE : FMSTR_FALSE);    
    }
    
    return bRet;
}
FMSTR_BPTR FMSTR_GetBoardInfo(FMSTR_BPTR pMessageIO)
{
    FMSTR_BPTR pResponse = pMessageIO;
    FMSTR_U16 wTmp;
    FMSTR_U8 *pStr;

    pResponse = FMSTR_ConstToBuffer8(pResponse, FMSTR_STS_OK);              
    pResponse = FMSTR_ConstToBuffer8(pResponse, (FMSTR_U8)(FMSTR_PROT_VER));            /* protVer */
    pResponse = FMSTR_ConstToBuffer8(pResponse, (FMSTR_U8)(FMSTR_CFG_FLAGS));           /* cfgFlags */
    pResponse = FMSTR_ConstToBuffer8(pResponse, (FMSTR_U8)(FMSTR_CFG_BUS_WIDTH));       /* dataBusWdt */
    pResponse = FMSTR_ConstToBuffer8(pResponse, (FMSTR_U8)(FMSTR_GLOB_VERSION_MAJOR));  /* globVerMajor */
    pResponse = FMSTR_ConstToBuffer8(pResponse, (FMSTR_U8)(FMSTR_GLOB_VERSION_MINOR));  /* globVerMinor */
    pResponse = FMSTR_ConstToBuffer8(pResponse, (FMSTR_U8)(FMSTR_COMM_BUFFER_SIZE));    /* cmdBuffSize  */

    /* that is all for brief info */
#if FMSTR_USE_BRIEFINFO
    FMSTR_UNUSED(pStr);
    FMSTR_UNUSED(wTmp);
    
#else /* FMSTR_USE_BRIEFINFO */

#if FMSTR_USE_RECORDER

    /* recorder buffer size is always mesured in bytes */
    wTmp = FMSTR_GetRecBuffSize();
    wTmp *= FMSTR_CFG_BUS_WIDTH;

    /* send size and timebase    */
    pResponse = FMSTR_ValueToBuffer16(pResponse, wTmp);
    pResponse = FMSTR_ConstToBuffer16(pResponse, (FMSTR_U16) FMSTR_REC_TIMEBASE);
#else /* FMSTR_USE_RECORDER */

    FMSTR_UNUSED(wTmp);

    /* recorder info zeroed */
    pResponse = FMSTR_ConstToBuffer16(pResponse, 0);
    pResponse = FMSTR_ConstToBuffer16(pResponse, 0);
#endif /* FMSTR_USE_RECORDER */

#if FMSTR_LIGHT_VERSION
FMSTR_UNUSED(pStr);
    pResponse = FMSTR_SkipInBuffer(pResponse, (FMSTR_U8)FMSTR_DESCR_SIZE);
#else
    /* description string */
    pStr = (FMSTR_U8*)  FMSTR_IDT_STRING;
    for(wTmp = 0U; wTmp < (FMSTR_U8)(FMSTR_DESCR_SIZE); wTmp++)
    {
        pResponse = FMSTR_ValueToBuffer8(pResponse, *pStr);

        /* terminating zero used to clear the remainder of the buffer */        
        if(*pStr)
        {
            pStr ++;
        }
    }
#endif /* SEND_IDT_STRING */
    
#endif /* FMSTR_USE_BRIEFINFO */

    return pResponse;   
}
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);
}