⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 freemaster_rec.c

📁 freescale最新的16位单片机
💻 C
📖 第 1 页 / 共 2 页
字号:
/******************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2004-2005 Freescale Semiconductor, Inc.
* (c) Copyright 2001-2004 Motorola, Inc.
* ALL RIGHTS RESERVED.
*
****************************************************************************//*!
*
* @file   freemaster_rec.c
*
* @brief  FreeMaster Recorder implementation
*
* @version 1.0.3.0
* 
* @date Jul-25-2006
* 
*******************************************************************************/

#include "freemaster.h"
#include "freemaster_private.h"
#include "freemaster_protocol.h"

#if FMSTR_USE_RECORDER

/***********************************
*  local variables 
***********************************/

// configuration variables
static FMSTR_U16  pcm_wRecTotalSmps;        ///< number of samples to measure
static FMSTR_U16  pcm_wRecPostTrigger;      ///< number of post-trigger samples to keep
static FMSTR_U8   pcm_nRecTriggerMode;      ///< triger mode (0 = disabled, 1 = _/, 2 = \_)
static FMSTR_U16  pcm_wRecTimeDiv;          ///< divisor of recorder "clock"
static FMSTR_ADDR pcm_nTrgVarAddr;          ///< trigger variable address
static FMSTR_U8   pcm_nTrgVarSize;          ///< trigger variable threshold size
static FMSTR_U8   pcm_bTrgVarSigned;        ///< trigger compare mode (0 = unsigned, 1 = signed)

static union 
{
#if FMSTR_CFG_BUS_WIDTH == 1
    FMSTR_U8  u8; 
    FMSTR_S8  s8;
#endif
    FMSTR_U16 u16;
    FMSTR_S16 s16;
    FMSTR_U32 u32;
    FMSTR_S32 s32;
} pcm_uTrgThreshold;                    ///< trigger threshold level (1,2 or 4 bytes)

static FMSTR_U8    pcm_nRecVarCount;        ///< number of active recorder variables
static FMSTR_ADDR  pcm_pRecVarAddr[FMSTR_MAX_SCOPE_VARS]; ///< addresses of recorded variables
static FMSTR_SIZE8 pcm_pRecVarSize[FMSTR_MAX_SCOPE_VARS]; ///< sizes of recorded variables

static FMSTR_ADDR  pcm_nRecBuffAddr;        ///< recorder buffer address
static FMSTR_SIZE  pcm_wRecBuffSize;        ///< recorder buffer size
static FMSTR_U16   pcm_wRecBuffStartIx;     ///< first sample index

// runtime variables 
static FMSTR_ADDR pcm_dwRecWritePtr;        ///< write pointer in recorder buffer
static FMSTR_ADDR pcm_dwRecEndBuffPtr;      ///< pointer to end of active recorder buffer
static FMSTR_U16  pcm_wRecTimeDivCtr;       ///< recorder "clock" divisor counter
static FMSTR_U16  pcm_wStoprecCountDown;    ///< post-trigger countdown counter

// recorder runtime flags
static volatile union 
{
    FMSTR_FLAGS all;
    
    struct 
    {
        unsigned bIsConfigured : 1;     // recorder is configured
        unsigned bIsRunning : 1;        // recorder is running
        unsigned bIsStopping : 1;       // trigger activated, sample countdown
        unsigned bInvirginCycle : 1;    // virgin cycle of the circular buffer in-progress
        unsigned bTrgCrossActive : 1;   // trigger trheshold was crossed
    } flg;
    
} pcm_wRecFlags;

/// compare functions prototype
typedef FMSTR_BOOL (*FMSTR_PCOMPAREFUNC)(void);

/// pointer to active compare function
static FMSTR_PCOMPAREFUNC pcm_pCompareFunc;

#if !FMSTR_REC_OWNBUFF
// put buffer into far memory ?
#if FMSTR_REC_FARBUFF
#pragma section fardata begin
#endif // FMSTR_REC_FARBUFF
/// statically allocated recorder buffer (FMSTR_REC_OWNBUFF is FALSE)
static FMSTR_U8 pcm_pOwnRecBuffer[FMSTR_REC_BUFF_SIZE];
// end of far memory section
#if FMSTR_REC_FARBUFF
#pragma section fardata end
#endif // FMSTR_REC_FARBUFF
#endif // FMSTR_REC_OWNBUFF

/***********************************
*  local functions
***********************************/

static FMSTR_BOOL FMSTR_Compare8S(void);
static FMSTR_BOOL FMSTR_Compare8U(void);
static FMSTR_BOOL FMSTR_Compare16S(void);
static FMSTR_BOOL FMSTR_Compare16U(void);
static FMSTR_BOOL FMSTR_Compare32S(void);
static FMSTR_BOOL FMSTR_Compare32U(void);
static void FMSTR_Recorder2(void);

/**************************************************************************//*!
*
* @brief    Recorder Initialization
*
******************************************************************************/

void FMSTR_InitRec(void)
{   
    // 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 = 0;
    pcm_wRecBuffSize = 0;
#else
    // size in native sizeof units (=bytes on most platforms)
    pcm_wRecBuffSize = FMSTR_REC_BUFF_SIZE;
    FMSTR_ARR2ADDR(pcm_nRecBuffAddr, pcm_pOwnRecBuffer);
#endif
}

/**************************************************************************//*!
*
* @brief    API: Replacing the recorder buffer with the user's one
*
* @param    pBuffer - user buffer pointer
* @param    wBuffSize - buffer size
*
* @note Use the FMSTR_SetUpBuff32 to pass the forced 32bit address in SDM
*
******************************************************************************/

void FMSTR_SetUpRecBuff(FMSTR_ADDR pBuffer, FMSTR_SIZE nBuffSize)
{    
    pcm_nRecBuffAddr = pBuffer;
    pcm_wRecBuffSize  = nBuffSize;
}

/**************************************************************************//*!
*
* @brief    Handling SETUPREC and SETUPREC_EX commands
*
* @param    pMessageIO - original command (in) and response buffer (out) 
*
* @return   As all command handlers, the return value should be the buffer 
*           pointer where the response output finished (except checksum)
*
******************************************************************************/

FMSTR_BPTR FMSTR_SetUpRec(FMSTR_BPTR pMessageIO)
{
    FMSTR_BPTR pResponse = pMessageIO;
    FMSTR_SIZE8 nRecVarsetSize;
    FMSTR_U8 i, sz;
    FMSTR_SIZE blen;

    // 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);
#else
    // size in native sizeof units (=bytes on most platforms)
    pcm_wRecBuffSize = FMSTR_REC_BUFF_SIZE;
    FMSTR_ARR2ADDR(pcm_nRecBuffAddr, pcm_pOwnRecBuffer);
#endif

    // seek the setup data
    pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 2);
    pMessageIO = FMSTR_ValueFromBuffer8(&pcm_nRecTriggerMode, pMessageIO);
    pMessageIO = FMSTR_ValueFromBuffer16(&pcm_wRecTotalSmps, pMessageIO);
    pMessageIO = FMSTR_ValueFromBuffer16(&pcm_wRecPostTrigger, pMessageIO);
    pMessageIO = FMSTR_ValueFromBuffer16(&pcm_wRecTimeDiv, pMessageIO);

    // 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);

    // recorder variable count
    pMessageIO = FMSTR_ValueFromBuffer8(&pcm_nRecVarCount, pMessageIO);

    // rec variable information must fit into our buffers
    if(!pcm_nRecVarCount || pcm_nRecVarCount > FMSTR_MAX_REC_VARS)
        return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_INVBUFF);

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

    // get all addresses and sizes
    for(i=0; 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 == 0 || sz > 8)
            return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_INVSIZE);

#if FMSTR_CFG_BUS_WIDTH > 1 
        // even sizes only
        if(sz & 1)
            return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_INVSIZE);
#endif
        
#if FMSTR_USE_TSA && FMSTR_USE_TSA_SAFETY
        if(!FMSTR_CheckTsaSpace(pcm_pRecVarAddr[i], sz, 0))
            return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_EACCESS);
#endif
    }

    // 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, pcm_nTrgVarSize, 0))
            return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_EACCESS);
#endif
        // get compare function
        switch(pcm_nTrgVarSize)
        {
#if FMSTR_CFG_BUS_WIDTH == 1
        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:
            return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_INVSIZE);
        }
    }
    
    // total recorder buffer length in native sizeof units (=bytes on most platforms)
    blen = pcm_wRecTotalSmps * nRecVarsetSize / FMSTR_CFG_BUS_WIDTH;

    // recorder memory available?
    if(blen > pcm_wRecBuffSize)
        return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_INVSIZE);

    // remember the effective end of circular buffer
    pcm_dwRecEndBuffPtr = pcm_nRecBuffAddr + blen;

    // everything is okay   
    pcm_wRecFlags.flg.bIsConfigured = 1;

    return FMSTR_ConstToBuffer8(pResponse, FMSTR_STS_OK);
}

/**************************************************************************//*!
*
* @brief    Abort and de-initialize recorder
*
******************************************************************************/

void FMSTR_AbortRec(void)
{
    // clear flags
    pcm_wRecFlags.all = 0;
}

/**************************************************************************//*!
*
* @brief    Check wether given memory region is inside the recorder buffer
*
* @param    dwAddr - address of the memory to be checked
* @param    wSize  - size of the memory to be checked
*
* @return   This function returns non-zero if user space is in recorder buffer
*
* This function is called as a pert of TSA-checking process when the PC host
* is requesting memory contents
*
******************************************************************************/

FMSTR_BOOL FMSTR_IsInRecBuffer(FMSTR_ADDR dwAddr, FMSTR_SIZE8 wSize)
{
    if(dwAddr < pcm_nRecBuffAddr)
        return 0;
    
    return (dwAddr + wSize) <= (pcm_nRecBuffAddr + FMSTR_GetRecBuffSize());
}

/**************************************************************************//*!
*
* @brief    Get recorder memory size 
*
* @return   Recorder memory size in native sizeof units (=bytes on most platforms)
*
******************************************************************************/

FMSTR_SIZE FMSTR_GetRecBuffSize()
{
#if FMSTR_REC_OWNBUFF
    return pcm_wRecBuffSize;
#else
    return FMSTR_REC_BUFF_SIZE;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -