コード例 #1
0
ファイル: timer.c プロジェクト: zizilala/projects_etest
//------------------------------------------------------------------------------
//
//  Function:  UpdatePeriod
//
VOID
UpdatePeriod(
    UINT32 periodMSec
    )
{
    UINT32 period, match;
    INT32 delta;
    UINT64 offsetMSec = periodMSec;
    UINT64 tickCount = OALGetTickCount();
    INT nDelay;

    // Calculate count difference
    period = (UINT32)MSEC_TO_TICK(offsetMSec);

    nDelay = min(period, DELTA_TIME);
    // This is compare value
    match = ((UINT32)MSEC_TO_TICK(tickCount)) + nDelay;

    delta = (INT32)(OALTimerGetCount()+ g_oalTimerContext.margin - match);

    // If we are behind, issue interrupt as soon as possible
    if (delta > 0)
    {
        match += MSEC_TO_TICK(1);
    }

    // Save off match value
    g_oalTimerContext.match = match;

    // Set timer match value
    OALTimerSetCompare(match);
}
コード例 #2
0
//------------------------------------------------------------------------------
//
//  Function:  OALTimerReduceSysTick
//
UINT32 OALTimerReduceSysTick(UINT32 count, UINT32 margin)
{
    UINT32 rc, edge, compare;

    edge = OALTimerGetCount();
    compare = OALTimerGetCompare();

    // Update the countdown value
    OALTimerSetCompare(count);

    if (edge > margin) 
    {
        // We are far enough from the interrupt that we should return the
        // number of ticks that would have occurred since the last tick based
        // on the new number of counts per tick. We will avoid the interrupt and
        // just start fresh.
        rc = (compare - edge) / count;
        OALTimerSetCount(count); 
    } 
    else {
        // We are close enough to the next interrupt that we will let the
        // interrupt occur. We will also return the number of counts that would
        // have happened since the last tick based on the new number of counts
        // per tick, but we will subtract one because another is just about to
        // happen.
        rc = (compare / count) - 1;
    }

    return rc;
}
コード例 #3
0
ファイル: cntcmp.c プロジェクト: zizilala/projects_etest
//------------------------------------------------------------------------------
//
//  Function: OALTimerUpdate
//
//  This function is called to change length of actual system timer period.
//  When end of new period is closer to actual time than margin period end
//  is shifted by margin (but next period should fix this shift - this is
//  reason why OALTimerRecharge doesn't read back compare register and it
//  uses saved value instead).
//
UINT32 OALTimerUpdate(UINT32 period, UINT32 margin)
{
    UINT32 edge;

    // New compare value is base plus period
    g_timer.compare = g_timer.base + period;
    // Are we more than margin before new compare?
    edge = OALTimerGetCount() + margin;
    if ((INT32)(g_timer.compare - edge) > 0) {
       // Yes, then use calculated value
       OALTimerSetCompare(g_timer.compare);
    } else {
       // No, shift real compare value
       OALTimerSetCompare(edge);
    }            
    return 0;
}
コード例 #4
0
//------------------------------------------------------------------------------
//
//  Function:  OALTimerExtendSysTick
//
VOID OALTimerExtendSysTick(UINT32 count, UINT32 margin, UINT32 offset)
{
    UINT32 compare, edge;

    edge = OALTimerGetCount();
    compare = OALTimerGetCompare();

    if (edge > ((count - compare) + margin + offset))
    {
        // We are far enough away from the interrupt that we should just
        // increase the time it will take to hit the next interrupt taking into
        // account the offset provided.
        OALTimerSetCount(edge - (count - offset - compare)); 
    }
    OALTimerSetCompare(count);
}
コード例 #5
0
ファイル: cntcmp.c プロジェクト: zizilala/projects_etest
//------------------------------------------------------------------------------
//
//  Function:  OALTimerRecharge
//
//  This function recharge count/compare timer. In case that we are late more
//  than margin value we will use count as new counter base. Under
//  normal conditions previous compare value stored in global variable is used.
//  Using global variable instead reading compare register allows compensate
//  offset when we reduce system tick to value which can cause hazard.
//
VOID OALTimerRecharge(UINT32 period, UINT32 margin)
{
    UINT32 count;

    count = OALTimerGetCount();
    // Check if recharge was called in required margin
    if ((INT32)(count - OALTimerGetCompare() - margin) < 0) {
        // Yes, base new period on previous (no shift)
        g_timer.base = g_timer.compare;
        g_timer.compare += period;
    } else {
        // No, base new period on actual counter value (shift)
        g_timer.base = count;
        g_timer.compare = g_timer.base + period;
    }
    OALTimerSetCompare(g_timer.compare); 
}
コード例 #6
0
ファイル: cntcmp.c プロジェクト: zizilala/projects_etest
//------------------------------------------------------------------------------
//
//  Function:  OALTimerInitCount
//
//  This function initialize count/compare timer.
//
VOID OALTimerInitCount(UINT32 period)
{
    g_timer.base = OALTimerGetCount();
    g_timer.compare = g_timer.base + period;
    OALTimerSetCompare(g_timer.compare); 
}
コード例 #7
0
ファイル: timer.c プロジェクト: zizilala/projects_etest
//------------------------------------------------------------------------------
//
//  Function:     OEMIdle
//
//  This function is called by the kernel when there are no threads ready to
//  run. The CPU should be put into a reduced power mode if possible and halted.
//  It is important to be able to resume execution quickly upon receiving an
//  interrupt.
//
//  Interrupts are disabled when OEMIdle is called and when it returns.
//
//  This implementation doesn't change system tick. It is intend to be used
//  with variable tick implementation. However it should work with fixed
//  variable tick implementation also (with lower efficiency because maximal
//  idle time is 1 ms).
//
//  WARNING: This function is called from deep within the kernel, it cannot make
//  any system calls, use any critical sections, or debug messages.
//
VOID
OEMIdle(
    DWORD idleParam
    )
{
    static UINT _max = 0;
    static UINT _count = 0;

    INT delta;
    UINT tcrrTemp;
    UINT tcrrEnter, tcrrExit;
    UINT idleDelta, newIdleLow;
    INT wakeupDelay;
    INT maxDelay;
    DWORD latencyState;    

    UNREFERENCED_PARAMETER(idleParam);

    PrcmInitializePrevPowerState();

    // How far are we from next timer interrupt
    // If we are really near to timer interrupt do nothing...
    latencyState = OALWakeupLatency_GetCurrentState();
    tcrrEnter = OALTimerGetReg(&g_pTimerRegs->TCRR);
    delta = g_oalTimerContext.match - tcrrEnter;
    if (delta < (INT32)g_oalTimerContext.margin) goto cleanUp;

    // get latency time...
    //
    // check if current latency is greater than current requirements
    maxDelay = min(delta, g_wakeupLatencyConstraintTickCount);
    wakeupDelay = OALWakeupLatency_GetDelayInTicks(latencyState);
    if (maxDelay < wakeupDelay)
    {
        // check if current state meets timing constraint
        latencyState = OALWakeupLatency_FindStateByMaxDelayInTicks(maxDelay);
        wakeupDelay = OALWakeupLatency_GetDelayInTicks(latencyState);
    }

    // check one last time to make sure we aren't going to sleep longer than
    if (maxDelay >= wakeupDelay)
    {
        //  Indicate in idle
        OALLED(LED_IDX_IDLE, 1);
        
        if (OALWakeupLatency_IsChipOff(latencyState))
        {
            if (!OALContextSave())
            {
                // Context Save Failed
                goto cleanUp;
            }
        }
        // account for wakeup latency
        OALWakeupLatency_PushState(latencyState);
        g_oalTimerContext.match -= wakeupDelay;
        OALTimerSetCompare(g_oalTimerContext.match);
    }
    else
    {
        goto cleanUp;
    }

    // Move SoC/CPU to idle mode    
    fnOALCPUIdle(g_pCPUInfo);
    
    // restore latency state
    OALWakeupLatency_PopState();
    
    PrcmCapturePrevPowerState();

    // get current TCRR value: workaround for errata 1.35
    OALTimerGetReg(&g_pTimerRegs->TCRR);
    tcrrExit = OALTimerGetReg(&g_pTimerRegs->TCRR);

    PrcmProcessPostMpuWakeup();

    // ERRATA 1.31 workaround
    do
    {
        tcrrTemp = OALTimerGetReg(&g_pTimerRegs->TCRR);
    }
    while (tcrrTemp == tcrrExit);

    PrcmProfilePrevPowerState(tcrrTemp, wakeupDelay);

    // Update idle counter
    idleDelta = OALTimerGetReg(&g_pTimerRegs->TCRR) - tcrrEnter;
    newIdleLow = curridlelow + idleDelta;
    if (newIdleLow < curridlelow) 
	    curridlehigh++;
    curridlelow = newIdleLow;

cleanUp:
    OALLED(LED_IDX_IDLE, 0);
    return;    
}
コード例 #8
0
//------------------------------------------------------------------------------
//
VOID OALTimerInitCount(UINT32 count)
{
    OALTimerSetCompare(count);
    OALTimerSetCount(count);
}