rtc.c
来自「Windows CE 6.0 BSP for VOIPAC Board (PXA」· C语言 代码 · 共 264 行
C
264 行
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
// File: rtc.c
//
#include <windows.h>
#include <ceddk.h>
#include <nkintr.h>
#include <oal.h>
#include <vr4131.h>
//------------------------------------------------------------------------------
//
// Type: VR4131_RTC
//
// Structure is used to simplify conversion from hardware to OS time format.
//
#include <packon.h>
typedef union {
struct {
UINT16 l;
UINT16 m;
UINT16 h;
UINT16 x;
};
UINT64 v;
} VR4131_RTC;
#include <packoff.h>
//------------------------------------------------------------------------------
//
// Local: g_rtcBase
//
static UINT64 g_rtcBase = 0;
//------------------------------------------------------------------------------
//
// Function: OALIoCtlHalInitRTC
//
// This function is called by WinCE OS to initialize the time after boot.
// Input buffer contains SYSTEMTIME structure with default time value.
// If hardware has persistent real time clock it will ignore this value
// (or all call).
//
BOOL OALIoCtlHalInitRTC(
UINT32 code, VOID *pInpBuffer, UINT32 inpSize, VOID *pOutBuffer,
UINT32 outSize, UINT32 *pOutSize
) {
BOOL rc = FALSE;
SYSTEMTIME *pTime = (SYSTEMTIME*)pInpBuffer;
OALMSG(OAL_IOCTL&&OAL_FUNC, (L"+OALIoCtlHalInitRTC(...)\r\n"));
// Validate inputs
if (pInpBuffer == NULL || inpSize < sizeof(SYSTEMTIME)) {
OALMSG(OAL_ERROR, (L"ERROR:OALIoCtlHalInitRTC: INVALID PARAMETER\r\n"));
goto cleanUp;
}
// Add static mapping for RTC alarm
OALIntrStaticTranslate(SYSINTR_RTC_ALARM, IRQ_ETIMER);
// And enable it (it will not occur until it is set in OEMSetAlarmTime)
OEMInterruptEnable(SYSINTR_RTC_ALARM, NULL, 0);
rc = OEMSetRealTime(pTime);
cleanUp:
OALMSG(OAL_IOCTL&&OAL_FUNC, (L"-OALIoCtlHalInitRTC(rc = %d)\r\n", rc));
return rc;
}
//------------------------------------------------------------------------------
//
// Function: OEMGetRealTime
//
// This function is called by the kernel to retrieve the time from
// the real-time clock.
//
BOOL OEMGetRealTime(SYSTEMTIME *pTime)
{
BOOL rc = FALSE;
VR4131_RTCU_REGS *pRTCRegs;
VR4131_RTC t;
ULARGE_INTEGER time;
FILETIME fileTime;
OALMSG(OAL_RTC&&OAL_FUNC, (L"+OEMGetRealTime\r\n"));
if(!pTime) goto cleanUp;
// Get virtual address
pRTCRegs = OALPAtoUA(VR4131_REG_PA_RTCU);
t.v = 0;
do {
t.l = INREG16(&pRTCRegs->ETIMEL);
t.m = INREG16(&pRTCRegs->ETIMEM);
t.h = INREG16(&pRTCRegs->ETIMEH);
} while (t.l !=INREG16(&pRTCRegs->ETIMEL));
time.QuadPart = (t.v * 10000000)/32768 + g_rtcBase;
fileTime.dwLowDateTime = time.LowPart;
fileTime.dwHighDateTime = time.HighPart;
if(KFileTimeToSystemTime)
{
if((rc = KFileTimeToSystemTime(&fileTime, pTime)))
{
#if 0
OALLog(
L"OEMGetRealTime: %04x:%04x:%04x base: %08x:%08x time: %08x:%08x\r\n",
t.h, t.m, t.l, (UINT32)(g_rtcBase >> 16), (UINT16)g_rtcBase,
time.HighPart, time.LowPart
);
#endif
OALMSG(OAL_RTC&&OAL_FUNC, (
L"-OEMGetRealTime(rc = %d, %d/%d/%d %d:%d:%d.%03d)\r\n", rc,
pTime->wYear, pTime->wMonth, pTime->wDay, pTime->wHour, pTime->wMinute,
pTime->wSecond, pTime->wMilliseconds
));
}
}
cleanUp:
return rc;
}
//------------------------------------------------------------------------------
//
// Function: OEMSetRealTime
//
// This function is called by the kernel to set the real-time clock.
//
BOOL OEMSetRealTime(SYSTEMTIME *pTime)
{
VR4131_RTCU_REGS *pRTCRegs;
VR4131_RTC t;
ULARGE_INTEGER time;
FILETIME fileTime;
BOOL rc = FALSE;
if(!pTime) goto cleanUp;
OALMSG(OAL_RTC&&OAL_FUNC, (
L"+OEMSetRealTime(%d/%d/%d %d:%d:%d.%03d)\r\n",
pTime->wYear, pTime->wMonth, pTime->wDay, pTime->wHour, pTime->wMinute,
pTime->wSecond, pTime->wMilliseconds
));
if(KSystemTimeToFileTime)
{
if((rc = KSystemTimeToFileTime(pTime, &fileTime)))
{
time.LowPart = fileTime.dwLowDateTime;
time.HighPart = fileTime.dwHighDateTime;
// Get virtual address
pRTCRegs = OALPAtoUA(VR4131_REG_PA_RTCU);
t.v = 0;
do {
t.h = INREG16(&pRTCRegs->ETIMEH);
t.m = INREG16(&pRTCRegs->ETIMEM);
t.l = INREG16(&pRTCRegs->ETIMEL);
} while (
t.m != INREG16(&pRTCRegs->ETIMEM) || t.h != INREG16(&pRTCRegs->ETIMEH)
);
time.QuadPart -= (t.v * 10000000)/32768;
g_rtcBase = time.QuadPart;
#if 0
OALLog(
L"OEMGetRealTime: %04x:%04x:%04x base: %08x:%08x time: %08x:%08x\r\n",
t.h, t.m, t.l, (UINT32)(g_rtcBase >> 16), (UINT16)g_rtcBase,
time.HighPart, time.LowPart
);
#endif
}
}
cleanUp:
OALMSG(OAL_RTC&&OAL_FUNC, (L"-OEMSetRealTime(rc = %d)\r\n", rc));
return rc;
}
//------------------------------------------------------------------------------
//
// Function: OEMSetAlarmTime
//
// This function is called by the kernel to set the real-time clock alarm.
//
BOOL OEMSetAlarmTime(SYSTEMTIME *pTime)
{
BOOL rc = FALSE;
VR4131_RTCU_REGS *pRTCRegs;
VR4131_RTC t;
ULARGE_INTEGER time;
FILETIME fileTime;
if(!pTime) goto cleanUp;
OALMSG(OAL_RTC&&OAL_FUNC, (
L"+OEMSetAlarmTime(%d/%d/%d %d:%d:%d.%03d)\r\n",
pTime->wYear, pTime->wMonth, pTime->wDay, pTime->wHour, pTime->wMinute,
pTime->wSecond, pTime->wMilliseconds
));
if(KSystemTimeToFileTime)
{
if((rc = KSystemTimeToFileTime(pTime, &fileTime)))
{
time.LowPart = fileTime.dwLowDateTime;
time.HighPart = fileTime.dwHighDateTime;
time.QuadPart -= g_rtcBase;
t.v = (time.QuadPart * 32768)/10000000;
// Get virtual address
pRTCRegs = OALPAtoUA(VR4131_REG_PA_RTCU);
OALMSG(FALSE, (
L" %04x:%04x:%04x -- %04x:%04x:%04x\r\n", INREG16(&pRTCRegs->ETIMEH),
INREG16(&pRTCRegs->ETIMEM), INREG16(&pRTCRegs->ETIMEL), t.h, t.m, t.l
));
// Set hardware
OUTREG16(&pRTCRegs->ECMPH, t.h);
OUTREG16(&pRTCRegs->ECMPM, t.m);
OUTREG16(&pRTCRegs->ECMPL, t.l);
// Re-enable interrupt (it is disabled since last alarm occurs)
OEMInterruptDone(SYSINTR_RTC_ALARM);
}
}
cleanUp:
OALMSG(OAL_RTC&&OAL_FUNC, (L"-OEMSetAlarmTime(rc = %d)\r\n", rc));
return rc;
}
//------------------------------------------------------------------------------
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?