?? oaltimer.c
字號:
// Copyright (c) David Vescovi. All rights reserved.
// Part of Project DrumStix
// Windows Embedded Developers Interest Group (WE-DIG) community project.
// http://www.we-dig.org
// Copyright (c) Microsoft Corporation. All rights reserved.
//------------------------------------------------------------------------------
//
// File: oaltimer.c
//
// Timer initialization code.
//
//------------------------------------------------------------------------------
#include <windows.h>
#include <nkintr.h>
#include <oal.h>
#include <pxa255.h>
//------------------------------------------------------------------------------
// Defines
//------------------------------------------------------------------------------
// External Variables
//------------------------------------------------------------------------------
// Global Variables
static volatile OST_REG_T *g_pOSTRegs = NULL;
static volatile INTC_REG_T *g_pINTCRegs = NULL;
//------------------------------------------------------------------------------
// Local Variables
//------------------------------------------------------------------------------
// Local Functions
BOOL OALTimerInit (UINT32 msecPerSysTick,
UINT32 countsPerMSec,
UINT32 countsMargin)
{
g_pOSTRegs = (volatile OST_REG_T *) OALPAtoVA(PXA255_BASE_REG_PA_OST, FALSE);
g_pINTCRegs = (volatile INTC_REG_T *) OALPAtoVA(PXA255_BASE_REG_PA_INTC, FALSE);
OALMSGS(OAL_KITL&&OAL_TIMER, (
L"+OALTimerInit(%d, %d, %d)\r\n", msecPerSysTick, countsPerMSec,countsMargin
));
// Initialize timer state global variable.
//
g_oalTimer.countsPerMSec = countsPerMSec;
g_oalTimer.msecPerSysTick = msecPerSysTick;
g_oalTimer.actualMSecPerSysTick = msecPerSysTick;
g_oalTimer.countsMargin = countsMargin;
g_oalTimer.countsPerSysTick = (countsPerMSec * msecPerSysTick);
g_oalTimer.actualCountsPerSysTick = (countsPerMSec * msecPerSysTick);
g_oalTimer.curCounts = 0;
g_oalTimer.maxPeriodMSec = (UINT32)0x7FFFFFFF/g_oalTimer.countsPerMSec;
// Initialize kernel-exported values.
//
idleconv = countsPerMSec;
curridlehigh = 0;
curridlehigh = 0;
// Initialize high resolution timer function pointers
pQueryPerformanceFrequency = OALTimerQueryPerformanceFrequency;
pQueryPerformanceCounter = OALTimerQueryPerformanceCounter;
// Configure and arm the timer interrupt to interrupt every specified system tick interval.
//
// Disable interrupts on the specified Match register
g_pOSTRegs->OIER &= ~(OIER_E0 | OIER_RESERVED_BITS);
// Clear any interrupt on the specified Match register
g_pOSTRegs->OSSR = OSSR_M0;
// Set up the match register to expire when the oscr reaches
// the next match interval.
g_pOSTRegs->OSMR0 = g_pOSTRegs->OSCR + g_oalTimer.countsPerSysTick;
// Enable the Match register interrupt on OS timer
g_pOSTRegs->OIER |= OIER_E0;
// Enable the Match interrupt at the interrupt controller
g_pINTCRegs->ICMR |= INTC_OSMR0;
return(TRUE);
}
//------------------------------------------------------------------------------
//
// Function: OALTimerCountsSinceSysTick
//
// This function return count of hi res ticks since system tick.
//
//
INT32 OALTimerCountsSinceSysTick()
{
UINT32 LastTimerMatch;
LastTimerMatch = g_pOSTRegs->OSMR0 - g_oalTimer.countsPerSysTick;
// How many ticks since the last timer interrupt?
return (g_pOSTRegs->OSCR - LastTimerMatch);
}
//------------------------------------------------------------------------------
//
// Function: OALTimerIntrHandler
//
// This function implement timer interrupt handler. It is called from common
// ARM interrupt handler.
//
UINT32 OALTimerIntrHandler()
{
UINT32 sysIntr = SYSINTR_NOP;
// Configure and arm the timer interrupt to interrupt every specified system tick interval.
//
// Disable interrupts on the specified Match register
g_pOSTRegs->OIER &= ~(OIER_E0 | OIER_RESERVED_BITS);
// Clear any interrupt on the specified Match register
g_pOSTRegs->OSSR = OSSR_M0;
if ((INT32)(g_pOSTRegs->OSCR - g_pOSTRegs->OSMR0 - g_oalTimer.countsMargin) < 0)
{
// Set up the match register to expire when the oscr reaches
// the next match interval.
g_pOSTRegs->OSMR0 = g_pOSTRegs->OSMR0 + g_oalTimer.countsPerSysTick;
}
else
{
// slip??
// Set up the match register to expire when the oscr reaches
// the next interval.
g_pOSTRegs->OSMR0 = g_pOSTRegs->OSCR + g_oalTimer.countsPerSysTick;
}
// Enable the Match register interrupt on OS timer
g_pOSTRegs->OIER |= OIER_E0;
// Enable the Match interrupt at the interrupt controller
g_pINTCRegs->ICMR |= INTC_OSMR0;
// 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
return (sysIntr);
}
//------------------------------------------------------------------------------
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -