724 lines
21 KiB
C
724 lines
21 KiB
C
|
|
/******************************************************************************
|
|||
|
|
*
|
|||
|
|
* Freescale Semiconductor Inc.
|
|||
|
|
* (c) Copyright 2004-2006 Freescale Semiconductor, Inc.
|
|||
|
|
* (c) Copyright 2001-2004 Motorola, Inc.
|
|||
|
|
* ALL RIGHTS RESERVED.
|
|||
|
|
*
|
|||
|
|
****************************************************************************//*!
|
|||
|
|
*
|
|||
|
|
* @file PE_freemaster_rec.c
|
|||
|
|
*
|
|||
|
|
* @brief FreeMASTER Recorder implementation.
|
|||
|
|
*
|
|||
|
|
* @version 1.0.10.0
|
|||
|
|
*
|
|||
|
|
* @date Oct-22-2007
|
|||
|
|
*
|
|||
|
|
*******************************************************************************/
|
|||
|
|
|
|||
|
|
#include "PE_freemaster.h"
|
|||
|
|
#include "PE_freemaster_private.h"
|
|||
|
|
#include "PE_freemaster_protocol.h"
|
|||
|
|
|
|||
|
|
#if FMSTR_USE_RECORDER
|
|||
|
|
|
|||
|
|
#include "PE_freemaster_rec.h"
|
|||
|
|
|
|||
|
|
#if FMSTR_USE_FASTREC
|
|||
|
|
#include "PE_freemaster_fastrec.h"
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
/********************************************************
|
|||
|
|
* global variables (shared with FastRecorder if used)
|
|||
|
|
********************************************************/
|
|||
|
|
|
|||
|
|
/* configuration variables */
|
|||
|
|
FMSTR_U16 pcm_wRecTotalSmps; /* number of samples to measure */
|
|||
|
|
FMSTR_U16 pcm_wRecPostTrigger; /* number of post-trigger samples to keep */
|
|||
|
|
FMSTR_U8 pcm_nRecTriggerMode; /* triger mode (0 = disabled, 1 = _/, 2 = \_) */
|
|||
|
|
FMSTR_U16 pcm_wRecTimeDiv; /* divisor of recorder "clock" */
|
|||
|
|
|
|||
|
|
FMSTR_U8 pcm_nRecVarCount; /* number of active recorder variables */
|
|||
|
|
FMSTR_ADDR pcm_pRecVarAddr[FMSTR_MAX_SCOPE_VARS]; /* addresses of recorded variables */
|
|||
|
|
FMSTR_SIZE8 pcm_pRecVarSize[FMSTR_MAX_SCOPE_VARS]; /* sizes of recorded variables */
|
|||
|
|
|
|||
|
|
/* runtime variables */
|
|||
|
|
FMSTR_U16 pcm_wRecBuffStartIx; /* first sample index */
|
|||
|
|
|
|||
|
|
FMSTR_ADDR pcm_dwRecWritePtr; /* write pointer in recorder buffer */
|
|||
|
|
FMSTR_ADDR pcm_dwRecEndBuffPtr; /* pointer to end of active recorder buffer */
|
|||
|
|
FMSTR_U16 pcm_wRecTimeDivCtr; /* recorder "clock" divisor counter */
|
|||
|
|
FMSTR_U16 pcm_wStoprecCountDown; /* post-trigger countdown counter */
|
|||
|
|
|
|||
|
|
/* recorder flags */
|
|||
|
|
FMSTR_REC_FLAGS pcm_wRecFlags;
|
|||
|
|
|
|||
|
|
/***********************************
|
|||
|
|
* local variables
|
|||
|
|
***********************************/
|
|||
|
|
|
|||
|
|
/* configuration variables */
|
|||
|
|
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) */
|
|||
|
|
|
|||
|
|
/*lint -e{960} using union */
|
|||
|
|
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_ADDR pcm_nRecBuffAddr; /* recorder buffer address */
|
|||
|
|
static FMSTR_SIZE pcm_wRecBuffSize; /* recorder buffer size */
|
|||
|
|
|
|||
|
|
/* compare functions prototype */
|
|||
|
|
typedef FMSTR_BOOL (*FMSTR_PCOMPAREFUNC)(void);
|
|||
|
|
|
|||
|
|
/*/ pointer to active compare function */
|
|||
|
|
static FMSTR_PCOMPAREFUNC pcm_pCompareFunc;
|
|||
|
|
|
|||
|
|
#if !FMSTR_REC_OWNBUFF && !FMSTR_USE_FASTREC
|
|||
|
|
/* 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 || FMSTR_USE_FASTREC
|
|||
|
|
/* user wants to use his own buffer */
|
|||
|
|
pcm_nRecBuffAddr = 0U;
|
|||
|
|
pcm_wRecBuffSize = 0U;
|
|||
|
|
#else
|
|||
|
|
/* size in native sizeof units (=bytes on most platforms) */
|
|||
|
|
pcm_wRecBuffSize = (FMSTR_SIZE) FMSTR_REC_BUFF_SIZE;
|
|||
|
|
FMSTR_ARR2ADDR(pcm_nRecBuffAddr, pcm_pOwnRecBuffer);
|
|||
|
|
|
|||
|
|
/*lint -esym(528, pcm_pOwnRecBuffer) this symbol is used outside of lint sight */
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
#if FMSTR_USE_FASTREC
|
|||
|
|
FMSTR_InitFastRec();
|
|||
|
|
#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_SIZE blen;
|
|||
|
|
FMSTR_U8 i, sz;
|
|||
|
|
|
|||
|
|
/* de-initialize first */
|
|||
|
|
FMSTR_AbortRec();
|
|||
|
|
|
|||
|
|
#if FMSTR_REC_OWNBUFF || FMSTR_USE_FASTREC
|
|||
|
|
/* 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_SIZE)FMSTR_REC_BUFF_SIZE;
|
|||
|
|
FMSTR_ARR2ADDR(pcm_nRecBuffAddr, pcm_pOwnRecBuffer); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
/* seek the setup data */
|
|||
|
|
pMessageIO = FMSTR_SkipInBuffer(pMessageIO, 2U);
|
|||
|
|
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_U8)FMSTR_MAX_REC_VARS)
|
|||
|
|
{
|
|||
|
|
return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_INVBUFF);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 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)
|
|||
|
|
{
|
|||
|
|
return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_INVSIZE);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#if FMSTR_CFG_BUS_WIDTH > 1U
|
|||
|
|
/* even sizes only */
|
|||
|
|
if(sz & 0x1)
|
|||
|
|
{
|
|||
|
|
return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_INVSIZE);
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
#if FMSTR_USE_TSA && FMSTR_USE_TSA_SAFETY
|
|||
|
|
if(!FMSTR_CheckTsaSpace(pcm_pRecVarAddr[i], (FMSTR_SIZE8)sz, 0U))
|
|||
|
|
{
|
|||
|
|
return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_EACCESS);
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* fast recorder handles trigger by itself */
|
|||
|
|
#if !FMSTR_USE_FASTREC
|
|||
|
|
/* 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))
|
|||
|
|
{
|
|||
|
|
return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_EACCESS);
|
|||
|
|
}
|
|||
|
|
#endif
|
|||
|
|
/* get compare function */
|
|||
|
|
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:
|
|||
|
|
return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_INVSIZE);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
#endif /* !FMSTR_USE_FASTREC */
|
|||
|
|
|
|||
|
|
/* 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 > pcm_wRecBuffSize)
|
|||
|
|
{
|
|||
|
|
return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_INVSIZE);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* remember the effective end of circular buffer */
|
|||
|
|
pcm_dwRecEndBuffPtr = pcm_nRecBuffAddr + blen;
|
|||
|
|
|
|||
|
|
#if FMSTR_USE_FASTREC
|
|||
|
|
if(!FMSTR_SetUpFastRec())
|
|||
|
|
return FMSTR_ConstToBuffer8(pResponse, FMSTR_STC_FASTRECERR);
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
/* everything is okay */
|
|||
|
|
pcm_wRecFlags.flg.bIsConfigured = 1U;
|
|||
|
|
|
|||
|
|
return FMSTR_ConstToBuffer8(pResponse, FMSTR_STS_OK);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**************************************************************************//*!
|
|||
|
|
*
|
|||
|
|
* @brief Abort and de-initialize recorder
|
|||
|
|
*
|
|||
|
|
******************************************************************************/
|
|||
|
|
|
|||
|
|
void FMSTR_AbortRec(void)
|
|||
|
|
{
|
|||
|
|
/* clear flags */
|
|||
|
|
pcm_wRecFlags.all = 0U;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**************************************************************************//*!
|
|||
|
|
*
|
|||
|
|
* @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 nSize)
|
|||
|
|
{
|
|||
|
|
FMSTR_BOOL bRet = 0U;
|
|||
|
|
|
|||
|
|
if(dwAddr >= pcm_nRecBuffAddr)
|
|||
|
|
{
|
|||
|
|
bRet = (FMSTR_BOOL)((dwAddr + nSize) <= (pcm_nRecBuffAddr + FMSTR_GetRecBuffSize()) ? FMSTR_TRUE : FMSTR_FALSE);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return bRet;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**************************************************************************//*!
|
|||
|
|
*
|
|||
|
|
* @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 || FMSTR_USE_FASTREC
|
|||
|
|
return pcm_wRecBuffSize;
|
|||
|
|
#else
|
|||
|
|
return (FMSTR_SIZE) FMSTR_REC_BUFF_SIZE;
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**************************************************************************//*!
|
|||
|
|
*
|
|||
|
|
* @brief API: Pull the trigger of the recorder
|
|||
|
|
*
|
|||
|
|
* This function starts the post-trigger stop countdown
|
|||
|
|
*
|
|||
|
|
******************************************************************************/
|
|||
|
|
|
|||
|
|
void FMSTR_TriggerRec(void)
|
|||
|
|
{
|
|||
|
|
if(!pcm_wRecFlags.flg.bIsStopping)
|
|||
|
|
{
|
|||
|
|
pcm_wRecFlags.flg.bIsStopping = 1U;
|
|||
|
|
pcm_wStoprecCountDown = pcm_wRecPostTrigger;
|
|||
|
|
|
|||
|
|
#if FMSTR_USE_FASTREC
|
|||
|
|
FMSTR_TriggerFastRec();
|
|||
|
|
#endif
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**************************************************************************//*!
|
|||
|
|
*
|
|||
|
|
* @brief Handling STARTREC command
|
|||
|
|
*
|
|||
|
|
* @param pMessageIO - original command (in) and response buffer (out)
|
|||
|
|
*
|
|||
|
|
* @return As all command handlers, the return value should be the length
|
|||
|
|
* of the response filled into the buffer (including status byte)
|
|||
|
|
*
|
|||
|
|
* This function starts recording (initializes internal recording variables
|
|||
|
|
* and flags)
|
|||
|
|
*
|
|||
|
|
******************************************************************************/
|
|||
|
|
|
|||
|
|
FMSTR_BPTR FMSTR_StartRec(FMSTR_BPTR pMessageIO)
|
|||
|
|
{
|
|||
|
|
/* must be configured */
|
|||
|
|
if(!pcm_wRecFlags.flg.bIsConfigured)
|
|||
|
|
{
|
|||
|
|
return FMSTR_ConstToBuffer8(pMessageIO, FMSTR_STC_NOTINIT);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* already running ? */
|
|||
|
|
if(pcm_wRecFlags.flg.bIsRunning)
|
|||
|
|
{
|
|||
|
|
return FMSTR_ConstToBuffer8(pMessageIO, FMSTR_STS_RECRUN);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* initialize write pointer */
|
|||
|
|
pcm_dwRecWritePtr = pcm_nRecBuffAddr;
|
|||
|
|
|
|||
|
|
/* current (first) sample index */
|
|||
|
|
pcm_wRecBuffStartIx = 0U;
|
|||
|
|
|
|||
|
|
/* initialize time divisor */
|
|||
|
|
pcm_wRecTimeDivCtr = 0U;
|
|||
|
|
|
|||
|
|
/* initiate virgin cycle */
|
|||
|
|
pcm_wRecFlags.flg.bIsStopping = 0U; /* no trigger active */
|
|||
|
|
pcm_wRecFlags.flg.bTrgCrossActive = 0U; /* waiting for threshold crossing */
|
|||
|
|
pcm_wRecFlags.flg.bInvirginCycle = 1U; /* initial cycle */
|
|||
|
|
|
|||
|
|
/* start fast recorder */
|
|||
|
|
#if FMSTR_USE_FASTREC
|
|||
|
|
FMSTR_StartFastRec();
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
/* run now */
|
|||
|
|
pcm_wRecFlags.flg.bIsRunning = 1U; /* is running now! */
|
|||
|
|
|
|||
|
|
return FMSTR_ConstToBuffer8(pMessageIO, FMSTR_STS_OK);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**************************************************************************//*!
|
|||
|
|
*
|
|||
|
|
* @brief Handling STOPREC command
|
|||
|
|
*
|
|||
|
|
* @param pMessageIO - original command (in) and response buffer (out)
|
|||
|
|
*
|
|||
|
|
* @return As all command handlers, the return value should be the length
|
|||
|
|
* of the response filled into the buffer (including status byte)
|
|||
|
|
*
|
|||
|
|
* This function stops recording (same as manual trigger)
|
|||
|
|
*
|
|||
|
|
******************************************************************************/
|
|||
|
|
|
|||
|
|
FMSTR_BPTR FMSTR_StopRec(FMSTR_BPTR pMessageIO)
|
|||
|
|
{
|
|||
|
|
/* must be configured */
|
|||
|
|
if(!pcm_wRecFlags.flg.bIsConfigured)
|
|||
|
|
{
|
|||
|
|
return FMSTR_ConstToBuffer8(pMessageIO, FMSTR_STC_NOTINIT);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* already stopped ? */
|
|||
|
|
if(!pcm_wRecFlags.flg.bIsRunning)
|
|||
|
|
{
|
|||
|
|
return FMSTR_ConstToBuffer8(pMessageIO, FMSTR_STS_RECDONE);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* simulate trigger */
|
|||
|
|
FMSTR_TriggerRec();
|
|||
|
|
|
|||
|
|
return FMSTR_ConstToBuffer8(pMessageIO, FMSTR_STS_OK);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**************************************************************************//*!
|
|||
|
|
*
|
|||
|
|
* @brief Handling GETRECSTS command
|
|||
|
|
*
|
|||
|
|
* @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)
|
|||
|
|
*
|
|||
|
|
* This function returns current recorder status
|
|||
|
|
*
|
|||
|
|
******************************************************************************/
|
|||
|
|
|
|||
|
|
FMSTR_BPTR FMSTR_GetRecStatus(FMSTR_BPTR pMessageIO)
|
|||
|
|
{
|
|||
|
|
/* must be configured */
|
|||
|
|
if(!pcm_wRecFlags.flg.bIsConfigured)
|
|||
|
|
{
|
|||
|
|
return FMSTR_ConstToBuffer8(pMessageIO, FMSTR_STC_NOTINIT);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* get run/stop status */
|
|||
|
|
return FMSTR_ConstToBuffer8(pMessageIO, (FMSTR_U8)(pcm_wRecFlags.flg.bIsRunning ?
|
|||
|
|
FMSTR_STS_RECRUN : FMSTR_STS_RECDONE));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**************************************************************************//*!
|
|||
|
|
*
|
|||
|
|
* @brief Handling GETRECBUFF and GETRECBUFF_EX command
|
|||
|
|
*
|
|||
|
|
* @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)
|
|||
|
|
*
|
|||
|
|
* This function returns recorder buffer information
|
|||
|
|
*
|
|||
|
|
******************************************************************************/
|
|||
|
|
|
|||
|
|
FMSTR_BPTR FMSTR_GetRecBuff(FMSTR_BPTR pMessageIO)
|
|||
|
|
{
|
|||
|
|
/* must be configured */
|
|||
|
|
if(!pcm_wRecFlags.flg.bIsConfigured)
|
|||
|
|
{
|
|||
|
|
return FMSTR_ConstToBuffer8(pMessageIO, FMSTR_STC_NOTINIT);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* must be stopped */
|
|||
|
|
if(pcm_wRecFlags.flg.bIsRunning)
|
|||
|
|
{
|
|||
|
|
return FMSTR_ConstToBuffer8(pMessageIO, FMSTR_STC_SERVBUSY);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#if FMSTR_USE_FASTREC
|
|||
|
|
FMSTR_GetFastRecBuff();
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
/* fill the return info */
|
|||
|
|
pMessageIO = FMSTR_ConstToBuffer8(pMessageIO, FMSTR_STS_OK);
|
|||
|
|
pMessageIO = FMSTR_AddressToBuffer(pMessageIO, pcm_nRecBuffAddr);
|
|||
|
|
|
|||
|
|
return FMSTR_ValueToBuffer16(pMessageIO, pcm_wRecBuffStartIx);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* now follows the sampling routines, skip that if FastRecorder is used */
|
|||
|
|
#if !FMSTR_USE_FASTREC
|
|||
|
|
|
|||
|
|
/**************************************************************************//*!
|
|||
|
|
*
|
|||
|
|
* @brief Compare macro used in trigger detection
|
|||
|
|
*
|
|||
|
|
* @param v - original command
|
|||
|
|
* @param t - response buffer
|
|||
|
|
*
|
|||
|
|
* @return zero when value is lower than threshold.
|
|||
|
|
* @return non-zero when value is greater than or equal as treshold
|
|||
|
|
*
|
|||
|
|
******************************************************************************/
|
|||
|
|
|
|||
|
|
#define CMP(v,t) ((FMSTR_BOOL)(((v) < (t)) ? 0 : 1))
|
|||
|
|
|
|||
|
|
#if FMSTR_CFG_BUS_WIDTH == 1U
|
|||
|
|
|
|||
|
|
static FMSTR_BOOL FMSTR_Compare8S()
|
|||
|
|
{
|
|||
|
|
return CMP(FMSTR_GetS8(pcm_nTrgVarAddr), pcm_uTrgThreshold.s8);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static FMSTR_BOOL FMSTR_Compare8U()
|
|||
|
|
{
|
|||
|
|
return CMP(FMSTR_GetU8(pcm_nTrgVarAddr), pcm_uTrgThreshold.u8);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endif
|
|||
|
|
|
|||
|
|
static FMSTR_BOOL FMSTR_Compare16S()
|
|||
|
|
{
|
|||
|
|
return CMP(FMSTR_GetS16(pcm_nTrgVarAddr), pcm_uTrgThreshold.s16);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static FMSTR_BOOL FMSTR_Compare16U()
|
|||
|
|
{
|
|||
|
|
return CMP(FMSTR_GetU16(pcm_nTrgVarAddr), pcm_uTrgThreshold.u16);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static FMSTR_BOOL FMSTR_Compare32S()
|
|||
|
|
{
|
|||
|
|
return CMP(FMSTR_GetS32(pcm_nTrgVarAddr), pcm_uTrgThreshold.s32);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
static FMSTR_BOOL FMSTR_Compare32U()
|
|||
|
|
{
|
|||
|
|
return CMP(FMSTR_GetU32(pcm_nTrgVarAddr), pcm_uTrgThreshold.u32);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**************************************************************************//*!
|
|||
|
|
*
|
|||
|
|
* @brief API: Recorder worker routine - can be called from application's timer ISR
|
|||
|
|
*
|
|||
|
|
*
|
|||
|
|
* This returns quickly if recorder is not running, otherwise it calls quite lengthy
|
|||
|
|
* recorder routine which does all the recorder work (sampling, triggering)
|
|||
|
|
*
|
|||
|
|
******************************************************************************/
|
|||
|
|
|
|||
|
|
void FMSTR_Recorder(void)
|
|||
|
|
{
|
|||
|
|
/* recorder not active */
|
|||
|
|
if(!pcm_wRecFlags.flg.bIsRunning)
|
|||
|
|
{
|
|||
|
|
return ;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* do the hard work */
|
|||
|
|
FMSTR_Recorder2();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/**************************************************************************//*!
|
|||
|
|
*
|
|||
|
|
* @brief Recorder function called when recorder is active
|
|||
|
|
*
|
|||
|
|
******************************************************************************/
|
|||
|
|
|
|||
|
|
static void FMSTR_Recorder2(void)
|
|||
|
|
{
|
|||
|
|
FMSTR_SIZE8 sz;
|
|||
|
|
FMSTR_BOOL cmp;
|
|||
|
|
FMSTR_U8 i;
|
|||
|
|
|
|||
|
|
/* skip this call ? */
|
|||
|
|
if(pcm_wRecTimeDivCtr)
|
|||
|
|
{
|
|||
|
|
/* maybe next time... */
|
|||
|
|
pcm_wRecTimeDivCtr--;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* re-initialize divider */
|
|||
|
|
pcm_wRecTimeDivCtr = pcm_wRecTimeDiv;
|
|||
|
|
|
|||
|
|
/* take snapshot of variable values */
|
|||
|
|
for (i=0U; i<pcm_nRecVarCount; i++)
|
|||
|
|
{
|
|||
|
|
sz = pcm_pRecVarSize[i];
|
|||
|
|
FMSTR_CopyMemory(pcm_dwRecWritePtr, pcm_pRecVarAddr[i], sz); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>
|
|||
|
|
sz /= FMSTR_CFG_BUS_WIDTH;
|
|||
|
|
pcm_dwRecWritePtr += sz;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* another sample taken (startIx "points" after sample just taken) */
|
|||
|
|
/* i.e. it points to the oldest sample */
|
|||
|
|
pcm_wRecBuffStartIx++;
|
|||
|
|
|
|||
|
|
/* wrap around (circular buffer) ? */
|
|||
|
|
if(pcm_dwRecWritePtr >= pcm_dwRecEndBuffPtr)
|
|||
|
|
{
|
|||
|
|
pcm_dwRecWritePtr = pcm_nRecBuffAddr;
|
|||
|
|
pcm_wRecFlags.flg.bInvirginCycle = 0U;
|
|||
|
|
pcm_wRecBuffStartIx = 0U;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* no trigger testing in virgin cycle */
|
|||
|
|
if(pcm_wRecFlags.flg.bInvirginCycle)
|
|||
|
|
{
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* test trigger condition if still running */
|
|||
|
|
if(!pcm_wRecFlags.flg.bIsStopping && pcm_pCompareFunc != NULL)
|
|||
|
|
{
|
|||
|
|
/* compare trigger threshold */
|
|||
|
|
cmp = pcm_pCompareFunc();
|
|||
|
|
|
|||
|
|
/* negated logic (falling-edge) ? */
|
|||
|
|
if(pcm_nRecTriggerMode == 2U)
|
|||
|
|
{
|
|||
|
|
cmp = (FMSTR_BOOL) !cmp;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* above threshold ? */
|
|||
|
|
if(cmp)
|
|||
|
|
{
|
|||
|
|
/* were we at least once below threshold ? */
|
|||
|
|
if(pcm_wRecFlags.flg.bTrgCrossActive)
|
|||
|
|
{
|
|||
|
|
/* EDGE TRIGGER ! */
|
|||
|
|
FMSTR_TriggerRec();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
/* we got bellow threshold, now wait for being above threshold */
|
|||
|
|
pcm_wRecFlags.flg.bTrgCrossActive = 1U;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* in stopping mode ? (note that this bit might have been set just above!) */
|
|||
|
|
if(pcm_wRecFlags.flg.bIsStopping)
|
|||
|
|
{
|
|||
|
|
/* count down post-trigger samples expired ? */
|
|||
|
|
if(!pcm_wStoprecCountDown)
|
|||
|
|
{
|
|||
|
|
/* STOP RECORDER */
|
|||
|
|
pcm_wRecFlags.flg.bIsRunning = 0U;
|
|||
|
|
return;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* perhaps next time */
|
|||
|
|
pcm_wStoprecCountDown--;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#endif /* !FMSTR_USE_FASTREC */
|
|||
|
|
|
|||
|
|
#else /* FMSTR_USE_RECORDER */
|
|||
|
|
|
|||
|
|
/* use void recorder API functions */
|
|||
|
|
void FMSTR_Recorder(void)
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void FMSTR_TriggerRec(void)
|
|||
|
|
{
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
void FMSTR_SetUpRecBuff(FMSTR_ADDR pBuffer, FMSTR_SIZE wBuffSize)
|
|||
|
|
{
|
|||
|
|
FMSTR_UNUSED(pBuffer);
|
|||
|
|
FMSTR_UNUSED(wBuffSize);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/*lint -efile(766, PE_freemaster_protocol.h) include file is not used in this case */
|
|||
|
|
|
|||
|
|
#endif /* FMSTR_USE_RECORDER */
|
|||
|
|
|
|||
|
|
|