📄 time1100.c
字号:
#include <windows.h>
#include <bldver.h>
#include <nkintr.h>
//#include "sa1100.h"
#include "arm1100.h"
#include "sa11x0.h"
#include "sa11x0bd.h"
#define REG_POSR 0xA902001C
volatile BOOL fInterruptFlag;
extern DWORD CurMSec;
extern DWORD DiffMSec;
//not sure of relationship between this and the stuff in cfwarm
extern unsigned long OEMClockFreq;
//#define OEMClockFreq 3686400 // ticks/s
DWORD dwReschedIncrement;
DWORD OEMCount1ms;
static volatile DWORD dwCurReschedIncr;
#define ORIGINYEAR 1970
#define JAN1WEEK 1 /* Monday */
extern void ROSERTC_GetElapsedTimer(unsigned int *, unsigned int *);
extern void ROSERTC_SetElapsedTimer(unsigned int, unsigned int);
extern void ROSERTC_SetAlarm(unsigned int, unsigned int);
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 = {1998,1,0,1,23,59,50,0};
void HalTimerInit(void) {
return;
}
//++
// When this is called we will set up GPIO<1> to be a falling edge interrupt
// InitClock sets up the OS timer to int via match reg 0 on the IRQ level
// an int is requested in 1ms from now.
//
// Interrupts are disable when this is called.
//--
void InitClock(void) {
SYSTEMTIME st;
struct rtsrBits my_rtc_statreg;
volatile struct ostreg*const v_pOSTReg = (struct ostreg *)OST_BASE_VIRTUAL;
volatile struct icreg *const v_pICReg = (struct icreg *)IC_BASE_VIRTUAL;
volatile struct rtcreg *const v_pRTCReg = (volatile struct rtcreg *)RTC_BASE_VIRTUAL;
volatile LPDWORD posr = (volatile LPDWORD) REG_POSR;
// Number of timer counts for reschedule interval
dwReschedIncrement = RESCHED_INCREMENT;
// Current resched interval
dwCurReschedIncr = dwReschedIncrement;
// Set OEM timer count for 1 ms
OEMCount1ms = OEM_COUNT_1MS;
// Set OEM clock frequency
OEMClockFreq = OEM_CLOCK_FREQ;
v_pOSTReg->osmr[0] = v_pOSTReg->oscr+ dwReschedIncrement;
my_rtc_statreg.al = 1;
my_rtc_statreg.hz = 1;
my_rtc_statreg.ale = 0;
my_rtc_statreg.hze = 0;
v_pRTCReg->rtsr= my_rtc_statreg;
v_pRTCReg->rttr.cdc=32768; // set the trim to set RTC to 1Hz
//v_pOSTReg->ossr = OSSR_M_M0; // clear any current interrupt
TIMER_M0_INT_CLR(1);
//TIMER_M1_INT_CLR(1);
//TIMER_M2_INT_CLR(1);
//TIMER_M3_INT_CLR(1);
// v_pOSTReg->oier = OIER_M_E0; // turn on the interrupt
TIMER_M1_INT_EN(0);
TIMER_M2_INT_EN(0);
TIMER_M3_INT_EN(0);
TIMER_M0_INT_EN(1);
// wait for RTC stablized
while (!(*posr & 1))
;
//v_pICReg->icmr = (1<<26) | (1<<1); // enable ip<26> for ostimer and <1> for dev ints
TIMER_M0_INT_MASK(1);
// Check real time clock, initialize if necessary (used for polling in net routines)
OEMGetRealTime(&st);
if ((st.wYear < 1980) ||
(st.wMonth < 1) ||
(st.wMonth > 12) ||
(st.wDay < 1) ||
(st.wDay > 31) ||
(st.wHour > 23) ||
(st.wMinute > 59) ||
(st.wSecond > 59) ||
(st.wMilliseconds > 999)) {
DEBUGMSG(1,(TEXT("Invalid time returned from OEMGetRealTime: Year: %u, Month: %u, Day: %u, Hour: %u, Minute: %u, second: %u rcnr=%Xh\n"),
st.wYear, st.wMonth,st.wDay, st.wHour, st.wMinute,st.wSecond,v_pRTCReg->rcnr));
DEBUGMSG(1,(TEXT("Resetting real time clock to default date\n")));
OEMSetRealTime(&defst);
}
}
DWORD GetTimerPeriod(void) {
return RESCHED_PERIOD;
// return TIMER_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;
}
BOOL
OEMGetRealTime(LPSYSTEMTIME lpst)
{
unsigned int ms, sec, min, hour, day, month, year, leap;
unsigned int cur_time;
unsigned int *mtbl;
volatile struct rtcreg *v_pRTCReg;
v_pRTCReg = (volatile struct rtcreg *)RTC_BASE_VIRTUAL;
cur_time = v_pRTCReg->rcnr;
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;
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,v_pRTCReg->rcnr));
return TRUE;
}
BOOL OEMSetRealTime(LPSYSTEMTIME lpst)
{
unsigned int min, day, month, year;
unsigned int *mtbl;
unsigned int cur_time;
volatile struct rtcreg *v_pRTCReg;
v_pRTCReg = (volatile struct rtcreg *)RTC_BASE_VIRTUAL;
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,v_pRTCReg->rcnr));
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;
v_pRTCReg->rcnr = cur_time;
return TRUE;
}
BOOL OEMSetAlarmTime(LPSYSTEMTIME lpst)
{
#if 0
unsigned int min, day, month, year;
unsigned int *mtbl;
unsigned int alarm_time;
struct rtsrBits my_rtc_statreg;
volatile struct icreg *v_pICReg;
volatile struct rtcreg *v_pRTCReg;
v_pRTCReg = (volatile struct rtcreg *)RTC_BASE_VIRTUAL;
v_pICReg = (volatile struct icreg *)IC_BASE_VIRTUAL;
day = 0;
for (year=ORIGINYEAR; year<lpst->wYear; year++) {
day += 365 + isleap(year);
}
mtbl = isleap(year) ? monthtable_leap : monthtable;
for (month=0; month<(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;
v_pRTCReg->rtar = alarm_time;
my_rtc_statreg = v_pRTCReg->rtsr;
//clear any current RTC alarm interrupt
my_rtc_statreg.al = 1;
//enable the RTC alarm interrupt
my_rtc_statreg.ale = 1;
v_pRTCReg->rtsr = my_rtc_statreg;
//unmask interrupt
// v_pICReg->icmr |= RTC_ALM;
RT_ALARM_INT_MASK(1);
#endif
return TRUE;
}
DWORD KCP_ScaleDown(DWORD N) {
unsigned __int64 temp;
temp = (N * 1000) / OEMCount1ms;
return (unsigned int)temp;
}
DWORD KCP_GetStartTime() {
return GET_TICK_TIME();
}
DWORD KCP_GetElapsedTime(DWORD start) {
unsigned int stop = GET_TICK_TIME();
if (stop > start)
return stop - start;
else
return stop + (0xFFFFFFFF - start);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
DWORD
PerfCountFreq()
{
return OEMClockFreq;
// return (3686400);
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
DWORD
PerfCountSinceTick()
{
DWORD dwCount;
volatile struct ostreg *const v_pOSTReg = (struct ostreg *)OST_BASE_VIRTUAL;
dwCount= ((DWORD)v_pOSTReg->osmr[0]-(DWORD)v_pOSTReg->oscr);
// 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 dwCurReschedIncr - dwCount;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
CPUSetSysTimerCount(
DWORD dwCountdownMSec
)
{
DWORD dwCount, dwMatch;
volatile struct ostreg *const v_pOSTReg = (struct ostreg *)OST_BASE_VIRTUAL;
dwCurReschedIncr = dwCountdownMSec * OEMCount1ms;
dwCount = v_pOSTReg->oscr;
dwMatch = dwCount + dwCurReschedIncr;
// DEBUGMSG(1, (TEXT("Moving match to 0x%08X, count is 0x%08X (%d ms)\r\n"), dwMatch, dwCount, dwCountdownMSec));
v_pOSTReg->osmr[0] = dwMatch;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
CPUClearSysTimerIRQ(
void
)
{
volatile struct ostreg *const v_pOSTReg = (struct ostreg *)OST_BASE_VIRTUAL;
//v_pOSTReg->ossr = OSSR_M_M0; // clear match 0 status
TIMER_M0_INT_CLR(1);
// Don't indicate that an IRQ was pending -- the math works out automatically
// with the free-running timer + match in CPUGetSysTimerCountElapsed( ) if
// the timer went past the match point.
return FALSE;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#if (CE_MAJOR_VER == 0x0003)
//
// cedar
//
DWORD
CPUGetSysTimerCountElapsed(
DWORD dwTimerCountdownMSec,
volatile DWORD *pCurMSec,
volatile DWORD *pDiffMSec,
DWORD *pPartialCurMSec,
DWORD *pPartialDiffMSec,
volatile ULARGE_INTEGER *pCurTicks
)
{
volatile struct ostreg *const v_pOSTReg = (struct ostreg *)OST_BASE_VIRTUAL;
DWORD dwTick = dwTimerCountdownMSec * OEMCount1ms;
DWORD dwCount = (DWORD)v_pOSTReg->osmr[0] - (DWORD)v_pOSTReg->oscr;
DWORD dwTemp;
// Note: if dwCount is negative, the counter went past the match point. The math
// still works since it accounts for the dwTick time plus the time past the match.
dwCount = dwTick - dwCount;
pCurTicks->QuadPart += dwCount;
dwTemp = dwCount;
dwTemp += *pPartialDiffMSec;
*pPartialDiffMSec = dwTemp % OEMCount1ms;
*pDiffMSec += dwTemp / OEMCount1ms;
dwTemp = dwCount;
dwTemp += *pPartialCurMSec;
*pPartialCurMSec = dwTemp % OEMCount1ms;
dwTemp = dwTemp / OEMCount1ms;
*pCurMSec += dwTemp;
return dwTemp;
}
#else
//
// dougfir or later
//
DWORD
CPUGetSysTimerCountElapsed(
DWORD dwTimerCountdownMSec,
volatile DWORD *pCurMSec,
DWORD *pPartialCurMSec,
volatile ULARGE_INTEGER *pCurTicks
)
{
volatile struct ostreg *const v_pOSTReg = (struct ostreg *)OST_BASE_VIRTUAL;
DWORD dwTick = dwTimerCountdownMSec * OEMCount1ms;
DWORD dwCount = (DWORD)v_pOSTReg->osmr[0] - (DWORD)v_pOSTReg->oscr;
// Note: if dwCount is negative, the counter went past the match point. The math
// still works since it accounts for the dwTick time plus the time past the match.
dwCount = dwTick - dwCount;
pCurTicks->QuadPart += dwCount;
dwCount += *pPartialCurMSec;
*pPartialCurMSec = dwCount % OEMCount1ms;
dwCount /= OEMCount1ms;
*pCurMSec += dwCount;
return dwCount;
}
#endif // CE_MAJOR_VER == 0x0003
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
CPUEnterIdle()
{
fInterruptFlag = FALSE;
INTERRUPTS_ON();
while (!fInterruptFlag) {
// Just sit here. Any interrupt will bump us out.
}
}
#define IDLE_MAX_MS 30000
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
DWORD
CPUGetSysTimerCountMax(
DWORD dwIdleMSecRequested
)
{
if (dwIdleMSecRequested > IDLE_MAX_MS) {
//
// Our timer isn't capable of idling more than IDLE_MAX_MS milliseconds.
// We'll have to break the sleep time into reasonable chunks.
//
return IDLE_MAX_MS;
}
return dwIdleMSecRequested;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -