コード例 #1
0
ファイル: idle.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).
//
VOID OEMIdle(DWORD idleParam)
{
    UINT32 baseMSec;
    INT32 usedCounts, idleCounts;
    ULARGE_INTEGER idle;

    // Get current system timer counter
    baseMSec = CurMSec;
    
    // Find how many hi-res ticks was already used
    usedCounts = OALTimerCountsSinceSysTick();

    // We should wait this time
    idleCounts = g_oalTimer.actualCountsPerSysTick;
    
    // Move SoC/CPU to idle mode
    OALCPUIdle();

    // When there wasn't timer interrupt modify idle time
    if (CurMSec == baseMSec) {
        idleCounts = OALTimerCountsSinceSysTick();
    }

    // Get real idle value. If result is negative we didn't idle at all.
    idleCounts -= usedCounts;
    if (idleCounts < 0) idleCounts = 0;

    // Update idle counters
    idle.LowPart = curridlelow;
    idle.HighPart = curridlehigh;
    idle.QuadPart += idleCounts;
    curridlelow  = idle.LowPart;
    curridlehigh = idle.HighPart;
}
コード例 #2
0
//------------------------------------------------------------------------------
//
//  Function: OALTimerUpdate
//
//  This function is called to change length of actual system timer period.
//  If end of actual period is closer than margin period isn't changed (so
//  original period elapse). Function returns time which already expires
//  in new period length units. If 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)
{

#if (BSP_TYPE == BSP_SMDK2443)
	UINT32 tcon, ret;
	
	ret = OALTimerCountsSinceSysTick();

	OUTREG32(&g_pPWMRegs->TCNTB4, period);
    tcon = INREG32(&g_pPWMRegs->TCON) & ~(0x0F << 20);
    OUTREG32(&g_pPWMRegs->TCON, tcon | (0x2 << 20) );
    OUTREG32(&g_pPWMRegs->TCON, tcon | (0x5 << 20) );

	return (ret);

#elif (BSP_TYPE == BSP_SMDK2450)

#if	0	// Fixed Tick do not Update TImer
	UINT32 tcon, ret;
	
	ret = OALTimerCountsSinceSysTick();

	OUTREG32(&g_pPWMRegs->TCNTB4, period);
    tcon = INREG32(&g_pPWMRegs->TCON) & ~(0x0F << 20);
    OUTREG32(&g_pPWMRegs->TCON, tcon | (0x2 << 20) );
    OUTREG32(&g_pPWMRegs->TCON, tcon | (0x5 << 20) );

	return (ret);
#else
	return	0;
#endif

#endif
}
コード例 #3
0
//------------------------------------------------------------------------------
//
//  Function: OALTimerIntrHandler
//
//  This function implement timer interrupt handler. It is called from common
//  ARM interrupt handler.
//
UINT32 OALTimerIntrHandler()
{
    UINT32 sysIntr = SYSINTR_NOP;

    LastTimerMatch = g_XllpOSTHandle.pOSTRegs->osmr0;


#ifdef OAL_ILTIMING
    if (g_oalILT.active) {
        g_oalILT.isrTime1 = OALTimerCountsSinceSysTick();
    }        
#endif

    // g_LastPartialCounts represents fractional milliseconds which will
    // be added to CurMSec once they add up to one MSec.
    g_TotalPartialCounts += g_LastPartialCounts;
    g_LastPartialCounts = 0;

    if ((g_TotalPartialCounts > g_oalTimer.countsPerMSec)) 
    {
        CurMSec++;
        g_TotalPartialCounts -= g_oalTimer.countsPerMSec;
    }
    
    // Update the millisecond and high resolution counters
    CurMSec += g_oalTimer.actualMSecPerSysTick;
    g_oalTimer.curCounts += g_oalTimer.actualCountsPerSysTick;

    //Re-schedule?
    if ((INT32)(CurMSec - dwReschedTime) >= 0)  {
        sysIntr = SYSINTR_RESCHED;

        // Recharge timer with the maximum period possible from now. Kernel will call
        // OALTimerUpdateRescheduleTime to set it to the correct value it wants.
        RechargeTimer(CurMSec + g_oalTimer.maxPeriodMSec);
    }
    else {
        RechargeTimer(dwReschedTime);
    }
    
    // Update LEDs.
    // (Right shift by 10 instead of expensive division by 1000. This will 
    // cause the LEDs to update every 1.024 seconds instead every 1 second,
    // which is okay as this is just a notification and not a measurement of any sort)
    OEMWriteDebugLED(0, CurMSec >> 10);

#ifdef OAL_ILTIMING
    if (g_oalILT.active) {
        g_oalILT.counter--;
        if (g_oalILT.counter == 0) {
            sysIntr = SYSINTR_TIMING;
            g_oalILT.counter = g_oalILT.counterSet;
            g_oalILT.isrTime2 = OALTimerCountsSinceSysTick();
        }
    }
#endif

    return (sysIntr);
}
コード例 #4
0
//------------------------------------------------------------------------------
//
//  Function:  OALTimerUpdateRescheduleTime
//
//  This function is called by kernel to set next reschedule time.
//
VOID OALTimerUpdateRescheduleTime(DWORD time)
{
    UINT32 baseMSec;
    INT32 counts;

    // Get current system timer counter
    baseMSec = CurMSec;

    // Return if we are already setup correctly
    if (time == (baseMSec + g_oalTimer.actualMSecPerSysTick)) goto cleanUp;

    // How far we are from next tick
    counts = g_oalTimer.actualCountsPerSysTick - OALTimerCountsSinceSysTick();

    // If timer interrupts occurs, or we are within 1 ms of the scheduled
    // interrupt, just return - timer ISR will take care of it.
    if (baseMSec != CurMSec || counts < (INT32)g_oalTimer.countsPerMSec) {
        goto cleanUp;
    }        

    //Note: We are going to assume that RechargeTimer will not take more than 1 ms and since we have already
    // checked above that there is at least 1 ms before the next timer interrupt, no timer interrupts
    // can occur during RechargeTimer execution (thus we satisfy the condition imposed by RechargeTimer)
    RechargeTimer(time);

cleanUp:
    return;    
}
コード例 #5
0
//------------------------------------------------------------------------------
//
//  Function: OALTimerIntrHandler
//
//  This function implement timer interrupt handler. It is called from common
//  ARM interrupt handler.
//
UINT32 OALTimerIntrHandler()
{
    UINT32 sysIntr = SYSINTR_NOP;

#if (BSP_TYPE == BSP_SMDK2443)
#if 1// for WFI

        OUTREG32(&g_pIntrRegs->SRCPND, 1 << IRQ_TIMER4);
        OUTREG32(&g_pIntrRegs->INTPND, 1 << IRQ_TIMER4);
#endif	
#elif (BSP_TYPE == BSP_SMDK2450)
    static DWORD HeartBeatCnt, HeartBeatStat;  //LED4 is used for heart beat	
        // Clear the interrupt
        OUTREG32(&g_pIntrRegs->SRCPND1, 1 << IRQFORTIMER);
        OUTREG32(&g_pIntrRegs->INTPND1, 1 << IRQFORTIMER);

#ifndef DVS_EN
 //[david.modify] 2008-09-09 17:30
 // GPF4在4.3INCH项目上用做MENU_KEY
#if 0
		if (++HeartBeatCnt > 100)
		{
			HeartBeatCnt   = 0;
			HeartBeatStat ^= 1;
			g_pPortRegs->GPCCON = (g_pPortRegs->GPCCON & ~(3<<14)) | (1<<14); 
			if (HeartBeatStat) 
			{
				g_pPortRegs->GPCDAT &= ~(1<<7); // LED 4 Off
			}
			else
			{
				g_pPortRegs->GPCDAT |=  (1<<7); // LED 4 On
			}			
		}
#endif

#endif	
#endif	
    // Update high resolution counter
    g_oalTimer.curCounts += g_oalTimer.countsPerSysTick;
                             
    // Update the millisecond counter
    CurMSec += g_oalTimer.msecPerSysTick;


    // Reschedule?
    if ((int)(CurMSec - dwReschedTime) >= 0) sysIntr = SYSINTR_RESCHED;

#ifdef OAL_ILTIMING
    if (g_oalILT.active) {
        if (--g_oalILT.counter == 0) {
            sysIntr = SYSINTR_TIMING;
            g_oalILT.counter = g_oalILT.counterSet;
            g_oalILT.isrTime2 = OALTimerCountsSinceSysTick();
        }
    }
#endif

#ifdef DVS_EN
	ChangeSystemStateDVS();
#endif
    return sysIntr;
}