📄 timerbvd1.c
字号:
/* Copyright ?2000-2001 Intel Corp. */
/*++
Module Name: timerxsc1.c
Abstract:
Contains OST and RTC initialization routine and
RTC OEM routines
Notes:
--*/
#include <windows.h>
#include <nkintr.h>
#include "bvd1.h"
#include "bvd1bd.h"
#include "timer.h"
#include "xllp_Pm.h"
#include "pcf.h"
#include "xllp_pwri2c.h"
typedef struct I2C_tag
{
DWORD IBMR;
DWORD rsvd1;
DWORD IDBR;
DWORD rsvd2;
DWORD ICR;
DWORD rsvd3;
DWORD ISR;
DWORD rsvd4;
DWORD ISAR;
}I2C_REG;
volatile BOOL fInterruptFlag;
extern DWORD CurMSec;
/*
* Forward References
*/
void XSC1_GetRealTime(LPSYSTEMTIME lpst);
void XSC1_SetRealTime (LPSYSTEMTIME lpst);
void GetRTCTime (unsigned int *cur_time);
void SetRTCTime (unsigned int cur_time);
void ConvertSystemTime(LPSYSTEMTIME lpst, unsigned int *cur_time);
void FormatSystemTime(unsigned int cur_time, LPSYSTEMTIME lpst);
void InitClock(void);
DWORD dwProfilerIncrement;
//#define ORIGINYEAR 1980
#define ORIGINYEAR 2005
//#define JAN1WEEK 2 /* Tuesday */
#define JAN1WEEK 6 /* Saturday */
static unsigned int monthtable[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static unsigned int monthtable_leap[] = {31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static SYSTEMTIME defst = {ORIGINYEAR,1,JAN1WEEK,1,23,59,00,0};
// Use OS Timer 4 as 100ms Timer
void Set100msTimer()
{
XLLP_OST_T *v_pOSTRegs = (XLLP_OST_T *)OST_BASE_U_VIRTUAL;
XLLP_OST_HANDLE_T XllpOSTHandle;
XllpOSTHandle.pOSTRegs = v_pOSTRegs;
XllpOSTHandle.pINTCRegs = (XLLP_INTC_T *)INTC_BASE_U_VIRTUAL;
v_pOSTRegs->omcr4 = 0x000000CA;
v_pOSTRegs->oscr4 = 0;
XllpOstConfigureTimer (&XllpOSTHandle, MatchReg4, 60);
}
//
// HalTimerInit sets up the OS timer to interrupt via match reg 0 on the IRQ level.
// Interrupts are requested at 1ms intervals.
//
// Interrupts are disabled when this is called.
//
// Called from OEMInit()
//
void HalTimerInit(void)
{
SYSTEMTIME st;
P_XLLP_OST_T const v_pOSTRegs = (XLLP_OST_T *)OST_BASE_U_VIRTUAL;
XLLP_OST_HANDLE_T XllpOSTHandle;
XllpOSTHandle.pOSTRegs = v_pOSTRegs;
XllpOSTHandle.pINTCRegs = (XLLP_INTC_T *)INTC_BASE_U_VIRTUAL;
//
// LLI initializes oier and rtsr to zeroes, so no further
// initialization needs to be done. Match timers and
// alarms are disabled.
//
// Current usage of Match registers:
// M0 - Scheduler
// M1 - Touch Panel
// M2 - Profiler
//
//
// Note: No RTC trim value needs to be set. The value
// loaded into the trim register at hardware-reset results
// in a 1Hz clock, given a perfect crystal.
//
//
// Check real time clock, initialize if necessary
// (used for polling in net routines)
//
XSC1_GetRealTime(&st);
if ((st.wYear < ORIGINYEAR) ||
(st.wMonth < 1) ||
(st.wMonth > 12) ||
(st.wDay < 1) ||
(st.wDay > 31) ||
(st.wHour > 23) ||
(st.wMinute > 59) ||
(st.wSecond > 59) ||
(st.wMilliseconds > 999)) {
XSC1_SetRealTime(&defst);
}
//
// Configure and arm the timer interrupt
//
InitClock();
Set100msTimer();
}
//
// InitClock sets up the OS timer to interrupt via match reg 0 on the IRQ level.
// Interrupts are requested at 1ms intervals.
//
// Interrupts are disabled when this is called.
// This routine is called when resuming from sleep
//
void InitClock(void) {
P_XLLP_OST_T const v_pOSTRegs = (XLLP_OST_T *)OST_BASE_U_VIRTUAL;
XLLP_OST_HANDLE_T XllpOSTHandle;
unsigned long timermatch;
XllpOSTHandle.pOSTRegs = v_pOSTRegs;
XllpOSTHandle.pINTCRegs = (XLLP_INTC_T *)INTC_BASE_U_VIRTUAL;
//
// Configure and arm the timer interrupt
// to interrupt every 1ms
//
timermatch = v_pOSTRegs->oscr0+RESCHED_INCREMENT;
XllpOstConfigureTimer (&XllpOSTHandle, MatchReg0, timermatch);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
OEMProfileTimerDisable(void)
{
volatile XLLP_OST_T *const v_pOSTReg = (XLLP_OST_T *)OST_BASE_U_VIRTUAL;
//
// Disable the profiling interrupts
//
TIMER_M2_INT_DIS(v_pOSTReg->oier);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void OEMProfileTimerEnable(DWORD dwUSec)
{
P_XLLP_OST_T const v_pOSTRegs = (XLLP_OST_T *)OST_BASE_U_VIRTUAL;
XLLP_OST_HANDLE_T XllpOSTHandle;
unsigned long timermatch;
XllpOSTHandle.pOSTRegs = v_pOSTRegs;
XllpOSTHandle.pINTCRegs = (XLLP_INTC_T *)INTC_BASE_U_VIRTUAL;
if (dwUSec) {
//
// Rate specified (may need to be limited)
//
if (dwUSec < 20) {
dwUSec = 20;
}
} else {
//
// Use default rate (100 uS)
//
dwUSec = 100;
}
dwProfilerIncrement = (dwUSec * RESCHED_INCREMENT) / 1000;
timermatch = v_pOSTRegs->oscr0+dwProfilerIncrement;
//
//
// Configure and arm the Match2 register to interrupt
// at the profiler increment
//
XllpOstConfigureTimer (&XllpOSTHandle, MatchReg2, timermatch);
}
DWORD GetTimerPeriod(void) {
return RESCHED_PERIOD;
}
DWORD SC_GetTickCount(void) {
return CurMSec;
}
static int
isleap(int year)
{
int leap;
leap = 0;
if ((year % 4) == 0) {
leap = 1;
if ((year % 100) == 0) {
leap = (year%400) ? 0 : 1;
}
}
return leap;
}
//
//
// Returns the time from the RTC in SYSTEMTIME format.
// Called by kernel in respond to GetSystemTime()
//
//
BOOL
OEMGetRealTime(LPSYSTEMTIME lpst)
{
unsigned int cur_time;
//
// Get the RTC value
//
GetRTCTime (&cur_time);
FormatSystemTime (cur_time, lpst);
/*///--- by-paying , use pcf50606's rtc yet.seems some problem.
GetPCFRTCTime(lpst);
/*///---
#if 0
DEBUGMSG(0,(TEXT("OEMGetRealTime: Year: %u, Month: %u, Day: %u, Hour: %u, Minute: %u, second: %u rcnr=%Xh\n"),
lpst->wYear, lpst->wMonth,lpst->wDay, lpst->wHour, lpst->wMinute,lpst->wSecond, cur_time));
#endif
return TRUE;
}
//
//
// Sets the RTC.
// Called by kernel in response to SetSystemTime()
//
//
BOOL OEMSetRealTime(LPSYSTEMTIME lpst)
{
unsigned int cur_time;
ConvertSystemTime (lpst, &cur_time);
SetRTCTime (cur_time);
#if 0
DEBUGMSG(0,(TEXT("OEMSetRealTime: Year: %u, Month: %u, Day: %u, Hour: %u, Minute: %u, second: %u rcnr=%Xh\n"),
lpst->wYear, lpst->wMonth,lpst->wDay, lpst->wHour, lpst->wMinute, lpst->wSecond, cur_time));
#endif
return TRUE;
}
//
//
// Set the RTC alarm.
// Ensure synchronization to RTC registers.
//
// Default behavior will allow setting an alarm
// (thereby cancelling any pending one)
//
//
BOOL OEMSetAlarmTime(LPSYSTEMTIME lpst)
{
unsigned int min, day, month, year;
unsigned int *mtbl;
unsigned int alarm_time;
XLLP_RTC_HANDLE_T XllpRTCHandle;
XllpRTCHandle.pRTCRegs = (XLLP_RTC_T *)RTC_BASE_U_VIRTUAL;
XllpRTCHandle.pINTCRegs = (XLLP_INTC_T *)INTC_BASE_U_VIRTUAL;
day = 0;
for (year=ORIGINYEAR; year<lpst->wYear; year++) {
day += 365 + isleap(year);
}
mtbl = isleap(year) ? monthtable_leap : monthtable;
for (month=0; month<((unsigned)lpst->wMonth-1); month++) {
day += mtbl[month];
}
day += lpst->wDay - 1;
min = (day * 24 + lpst->wHour) * 60 + lpst->wMinute;
alarm_time = min * 60 + lpst->wSecond;
//
// Configure and arm the alarm
//
XllpRtcConfigureAlarm (&XllpRTCHandle, alarm_time);
return TRUE;
}
//
// FormatSystemTime
//
// Takes the RTC time and formats it into the
// Windows CE SYSTEMTIME format
//
void FormatSystemTime(unsigned int cur_time, LPSYSTEMTIME lpst)
{
unsigned int ms, sec, min, hour, day, month, year, leap;
unsigned int *mtbl;
ms = 0;
sec = cur_time % 60;
min = (cur_time / 60);
hour = min / 60;
day = hour / 24;
lpst->wMilliseconds = ms;
lpst->wSecond = sec;
lpst->wMinute = min % 60;
lpst->wHour = hour % 24;
lpst->wDayOfWeek = (day + JAN1WEEK) % 7;
year = ORIGINYEAR;
while (1) {
leap = isleap(year);
if (day < 365+leap)
break;
day -= 365+leap;
year++;
}
lpst->wYear = year;
mtbl = leap ? monthtable_leap : monthtable;
for (month=0; month<12; month++) {
if (day < mtbl[month])
break;
day -= mtbl[month];
}
lpst->wDay = day+1;
lpst->wMonth = month+1;
return;
}
//
// ConvertSystemTime
//
// Takes the Windows CE SYSTEMTIME and converts it to
// an unsigned integer.
//
void ConvertSystemTime(LPSYSTEMTIME lpst, unsigned int *cur_time)
{
unsigned int min, day, month, year;
unsigned int *mtbl;
day = 0;
for (year=ORIGINYEAR; year<lpst->wYear; year++) {
day += 365 + isleap(year);
}
mtbl = isleap(year) ? monthtable_leap : monthtable;
for (month=0; month<(unsigned int)(lpst->wMonth-1); month++) {
day += mtbl[month];
}
day += lpst->wDay - 1;
min = (day * 24 + lpst->wHour) * 60 + lpst->wMinute;
*cur_time = min * 60 + lpst->wSecond;
return;
}
//
//
// GetRTCTime
//
// Called by HalTimerInit and OEMGetRealTime
//
void GetRTCTime (unsigned int *cur_time)
{
volatile XLLP_RTC_T *v_pRTCReg;
v_pRTCReg = (volatile XLLP_RTC_T *)RTC_BASE_U_VIRTUAL;
*cur_time = v_pRTCReg->rcnr;
return;
}
//
// SetRTCTime
//
// Called by HalTimerInit and OEMSetRealTime
//
void SetRTCTime (unsigned int cur_time)
{
volatile XLLP_RTC_T *v_pRTCReg;
v_pRTCReg = (volatile XLLP_RTC_T *)RTC_BASE_U_VIRTUAL;
// Set the RTC value
v_pRTCReg->rcnr = cur_time;
return;
}
//
// XSC1_GetRealTime
//
// Called by HalTimerInit
//
void XSC1_GetRealTime(LPSYSTEMTIME lpst)
{
unsigned int cur_time;
GetRTCTime (&cur_time);
FormatSystemTime (cur_time, lpst);
return;
}
//
// XSC1_SetRealTime
//
// Called by HalTimerInit
//
void XSC1_SetRealTime (LPSYSTEMTIME lpst)
{
unsigned int cur_time;
ConvertSystemTime (lpst, &cur_time);
SetRTCTime (cur_time);
return;
}
//
//
// Support routine returning tick count since
// last timer firing.
//
//
DWORD
PerfCountSinceTick(void)
{
DWORD dwCount;
DWORD ReschedIncr = RESCHED_INCREMENT;
volatile XLLP_OST_T *const v_pOSTReg = (XLLP_OST_T *)OST_BASE_U_VIRTUAL;
//
// Get ticks until next timer interrupt
//
dwCount= ((DWORD)v_pOSTReg->osmr0 - (DWORD)v_pOSTReg->oscr0);
//
// Calculate elapsed ticks since last firing...
//
// Note: if dwCount is negative, the counter went past the match point. The math
// still works since it accounts for the dwReschedIncr time plus the time past
// the match.
return ReschedIncr - dwCount;
}
//
//
// Support routine returning frequency of the timer
// used by Interrupt Latency Timing.
//
//
DWORD
PerfCountFreq(void)
{
DWORD ReschedIncr = RESCHED_INCREMENT;
return ReschedIncr;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -