📄 freemaster_rec.c
字号:
#endif
}
/**************************************************************************//*!
*
* @brief API: Pull the trigger of the recorder
*
* This function starts the post-trigger stop countdown
*
******************************************************************************/
void FMSTR_TriggerRec(void)
{
pcm_wRecFlags.flg.bIsStopping = 1;
pcm_wStoprecCountDown = pcm_wRecPostTrigger;
}
/**************************************************************************//*!
*
* @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 = 0;
// initialize time divisor
pcm_wRecTimeDivCtr = 0;
// initiate virgin cycle
pcm_wRecFlags.flg.bIsStopping = 0; // no trigger active
pcm_wRecFlags.flg.bTrgCrossActive = 0; // waiting for threshold crossing
pcm_wRecFlags.flg.bInvirginCycle = 1; // initial cycle
pcm_wRecFlags.flg.bIsRunning = 1; // 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, 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);
// fill the return info
pMessageIO = FMSTR_ConstToBuffer8(pMessageIO, FMSTR_STS_OK);
pMessageIO = FMSTR_AddressToBuffer(pMessageIO, pcm_nRecBuffAddr);
return FMSTR_ValueToBuffer16(pMessageIO, pcm_wRecBuffStartIx);
}
/**************************************************************************//*!
*
* @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
*
* @note The following inlines might look strange, but those are here to assure correct
* behavior when SDM model is enabled (SDM: address operations in low 16 bits only).
* We need these inlines to access the trigger variable value as its address is kept
* as in UWord32 variable. C language pointers can not be used due to 16bit trimmed
* pointer arithmetic in SDM.
*
******************************************************************************/
#define CMP(v,t) ((v) < (t)) ? 0 : 1;
#if FMSTR_CFG_BUS_WIDTH == 1
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)
*
******************************************************************************/
#if defined(FMSTR_PLATFORM_56F8xxx) || defined(FMSTR_PLATFORM_56F8xx)
#pragma interrupt called
#endif
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
*
******************************************************************************/
#if defined(FMSTR_PLATFORM_56F8xxx) || defined(FMSTR_PLATFORM_56F8xx)
#pragma interrupt called
#endif
static void FMSTR_Recorder2(void)
{
FMSTR_SIZE8 sz;
FMSTR_U8 i;
// skip this call ?
if(pcm_wRecTimeDivCtr)
{
// maybe next time...
pcm_wRecTimeDivCtr--;
return;
}
// re-initialize timer divider
pcm_wRecTimeDivCtr = pcm_wRecTimeDiv;
// take snapshot of variable values
for (i=0; i<pcm_nRecVarCount; i++)
{
sz = pcm_pRecVarSize[i];
FMSTR_CopyMemory(pcm_dwRecWritePtr, pcm_pRecVarAddr[i], sz);
pcm_dwRecWritePtr += sz / FMSTR_CFG_BUS_WIDTH;
}
// 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 = 0;
pcm_wRecBuffStartIx = 0;
}
// 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
i = pcm_pCompareFunc();
// negated logic (falling-edge) ?
if(pcm_nRecTriggerMode == 2)
i = !i;
// above threshold ?
if(i)
{
// 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 = 1;
}
}
// 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 = 0;
return;
}
// perhaps next time
pcm_wStoprecCountDown--;
}
}
#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) { }
#endif /* FMSTR_USE_RECORDER */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -