19,504
社区成员
发帖
与我相关
我的任务
分享
static DWORD dwPartialCurMSec = 0; // Keep CPU-specific sub-millisecond leftover.
void
OEMIdle( DWORD dwIdleParam )
{
DWORD dwIdleMSec;
DWORD dwPrevMSec = *pCurMSec;
// Use for 64-bit math
ULARGE_INTEGER currIdle = { curridlelow, curridlehigh };
if ((int) (dwIdleMSec = dwReschedTime - dwPrevMSec) <= 0)
{
return; // already time to wakeup
}
// just idle till tick if profiling or running iltiming
if (bProfileTimerRunning || fIntrTime) // fIntrTime : Interrupt Latency timeing.
{
// idle till end of 'tick'
CPUEnterIdle(dwIdleParam);
// Update global idle time and return
currIdle.QuadPart += RESCHED_PERIOD;
curridlelow = currIdle.LowPart;
curridlehigh = currIdle.HighPart;
return;
}
RETAILMSG(1,(TEXT("OEMIdle ->RESCHED_PERIOD=%d \r\n"),RESCHED_PERIOD));
//
// Since OEMIdle( ) is being called in the middle of a normal reschedule
// period, CurMSec, dwPartialCurMSec, and CurTicks need to be updated accordingly.
// Once we reach this point, we must re-program the timer (if we ever did)
// because dwPartialCurMSec will be modified in the next function call.
//
CPUGetSysTimerCountElapsed(RESCHED_PERIOD, pCurMSec, &dwPartialCurMSec, pCurTicks);
if ((int) (dwIdleMSec -= *pCurMSec - dwPrevMSec) > 0)
{
dwPrevMSec = *pCurMSec;
//
// The system timer may not be capable of arbitrary timeouts. Get the
// CPU-specific highest possible timeout available.
//
dwIdleMSec = CPUGetSysTimerCountMax(dwIdleMSec);
//
// Set the timer to wake up much later than usual, if needed.
//
CPUSetSysTimerCount(dwIdleMSec);
CPUClearSysTimerIRQ( );
//
// Enable wakeup on any interrupt, then go to sleep.
//
// DEBUGMSG(1, (TEXT("OEMIDle \r\n")));
CPUEnterIdle(dwIdleParam);
INTERRUPTS_OFF( );
//
// We're awake! The wake-up ISR (or any other ISR) has already run.
//
if (dwPrevMSec != *pCurMSec)
{
//
// We completed the full period we asked to sleep. Update the counters.
//
*pCurMSec += (dwIdleMSec - RESCHED_PERIOD); // Subtract resched period, because ISR also incremented.
CurTicks.QuadPart += (dwIdleMSec - RESCHED_PERIOD) * dwReschedIncrement;
currIdle.QuadPart += dwIdleMSec;
} else {
//
// Some other interrupt woke us up before the full idle period was
// complete. Determine how much time has elapsed.
//
currIdle.QuadPart += CPUGetSysTimerCountElapsed(dwIdleMSec, pCurMSec, &dwPartialCurMSec, pCurTicks);
}
}
// Re-arm counters
CPUSetSysTimerCount(RESCHED_PERIOD);
CPUClearSysTimerIRQ( );
// Update global idle time
curridlelow = currIdle.LowPart;
curridlehigh = currIdle.HighPart;
return;
}
------------------------------------------------------------------------------------------------------
void
InitClock(void)
{
volatile PWMreg *s2440PWM =(PWMreg *)PWM_BASE;
volatile INTreg *s2440INT = (INTreg *)INT_BASE;
DWORD ttmp;
// Timer4 as OS tick and disable it first.
s2440INT->rINTMSK |= BIT_TIMER4; // Mask timer4 interrupt.
s2440INT->rSRCPND = BIT_TIMER4; // Clear pending bit
s2440INT->rINTPND = BIT_TIMER4;
// Operating clock : PCLK=101500000 (101.5 Mhz)
// IMPORTANT : MUST CHECK S2440.H DEFINITIONS !!!!
s2440PWM->rTCFG1 = 0x8080; //;;; SHL
s2440PWM->rTCFG0 &= ~(0xff << 8); /* Prescaler 1's Value */
s2440PWM->rTCFG0 |= (PRESCALER << 8); // prescaler value=15
RETAILMSG(1, (_T("InitClock_PRESCALER=%d\r\n"),PRESCALER));
/* Timer4 Divider field clear */
s2440PWM->rTCFG1 = 0x11111; // ;;; SHL
s2440PWM->rTCFG1 &= ~(0xf << 16);
#if( SYS_TIMER_DIVIDER == D2 )
s2440PWM->rTCFG1 |= (D1_2 << 16); /* 1/2 */
#elif ( SYS_TIMER_DIVIDER == D4 )
s2440PWM->rTCFG1 |= (D1_4 << 16); /* 1/4 */
#elif ( SYS_TIMER_DIVIDER == D8 )
s2440PWM->rTCFG1 |= (D1_8 << 16); /* 1/8 */
#elif ( SYS_TIMER_DIVIDER == D16 )
s2440PWM->rTCFG1 |= (D1_16 << 16); /* 1/16 */
#endif
s2440PWM->rTCNTB4 = RESCHED_INCREMENT; //((RESCHED_PERIOD * OEM_CLOCK_FREQ) / 1000)
ttmp = s2440PWM->rTCON & (~(0xf << 20));
s2440PWM->rTCON = ttmp | (2 << 20); /* update TCVNTB4, stop */
s2440PWM->rTCON = ttmp | (1 << 20); /* one-shot mode, start */
// Number of timer counts for reschedule interval
dwReschedIncrement = RESCHED_INCREMENT;
// Set OEM timer count for 1 ms
OEMCount1ms = OEM_COUNT_1MS;
// Set OEM clock frequency
OEMClockFreq = OEM_CLOCK_FREQ;
s2440INT->rINTMSK &= ~BIT_TIMER4;
return;
}