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

📄 freemaster_rec.c

📁 freescale最新的16位单片机
💻 C
📖 第 1 页 / 共 2 页
字号:
#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 + -