⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 realtimeclock.c

📁 Ep93XX TionProV2 BSP
💻 C
📖 第 1 页 / 共 2 页
字号:
//**********************************************************************
//                                                                      
// Filename: realtimeclock.c
//                                                                      
// Description: 
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF
// ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
//
// Use of this source code is subject to the terms of the Cirrus 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 
// EULA.RTF on your install media.
//
// Copyright(c) Cirrus Logic Corporation 2005, All Rights Reserved
//                                                                      
//**********************************************************************

#include <windows.h>
#include <nkintr.h>
#include <hwdefs.h>


DWORD dwReschedIncrement;

#ifdef REAL_RTC

extern BOOL InitializeISL1208(LPSYSTEMTIME ptime);
//extern BOOL ISL1208GetRealTime( LPSYSTEMTIME  ptime );
extern BOOL ISL1208SetRealTime(LPSYSTEMTIME ptime);

BOOL g_bRTCWithBattery=TRUE;
BOOL g_bRealRTCInitialized=FALSE;

unsigned __int64 RealTimeBias = 0;  // Number of 100-nanosecond intervals since
                                    // January 1, 1601. 
typedef volatile struct _rtcif_tag 
{
	DWORD	dr;			// data register
	DWORD	mr;			// match register
	union {
		DWORD	stat;		// interrupt status (read only)
		DWORD	eoi;		// interrupt clear (write only)
	};
	DWORD	lr;			// load register
	DWORD	cr;			// control register
} RTCIF, *PRTCIF;


BOOL isleap(int year)
{
    BOOL leap=FALSE;

	if ((year % 4) == 0)
	{
        leap = TRUE;
        if ((year % 100) == 0) {
            leap = (year%400) ? 0 : 1;
        }
    }
    return leap;
}


short DayOfThisMonth( short year, short month )
{
	if(month<=7)
	{
		if( month%2) return 31;
		else if( month !=2) return 30;
		else if( isleap( year ) ) return 29;
		else  return 28;
	}
	else
	{
		if( month%2) return 30;
        else         return 31;
	}
}

DWORD  GetDaysFrom1601( LPSYSTEMTIME pTime )
{
	DWORD year;
	DWORD leapYear=0;
	DWORD day;
	WORD  i;
	UCHAR cMonth=pTime->wMonth-1;

	year= pTime->wYear;
	year-=1601;

	leapYear = year/4;
	leapYear-= year/100;
	leapYear+= year/400;

	day= year*365 + leapYear;

	for( i=1; i< pTime->wMonth; i++ )
	{
		day+=DayOfThisMonth( (short)(pTime->wYear) , (short)i );
	}
	day+=pTime->wDay -1;
	return day;
}


__int64 MySystemTimeToFileTime( LPSYSTEMTIME pTime )
{ 
	DWORD    day;
	DWORD    nsDay= 864000000;// 000; //8640,0000,0000
	__int64 time;

	day=GetDaysFrom1601( pTime);
	day*=1000;
	
	time= (__int64)day * nsDay;
	nsDay= ((  60*pTime->wHour  + pTime->wMinute ) *60 +pTime->wSecond ) ;

	time+= (__int64)nsDay*10000000;

	return time;
}

BOOL OEMGetRealTime(LPSYSTEMTIME lpst)
{
    unsigned __int64 realTime;
    FILETIME ft;
	BOOL bRet;
    //
    // Implement the realtime clock.
    //
    PRTCIF pRTC = (PRTCIF) RTC_BASE;
    DWORD dwRTCDR = pRTC->dr;

	if( g_bRTCWithBattery ){

		if( !g_bRealRTCInitialized ){
		
			SYSTEMTIME time;
			time.wYear=2006;
			time.wMonth=7;
			time.wDay=7; 
			time.wHour=12; 
			time.wMinute=1; 
			time.wSecond=1; 

			time.wDayOfWeek=5; 

			time.wMilliseconds=0;

			if( InitializeISL1208( &time ) )
				g_bRealRTCInitialized=TRUE;
			else
				g_bRTCWithBattery=FALSE;

			*(__int64*)(&ft)= MySystemTimeToFileTime(&time);

			realTime = (unsigned __int64) dwRTCDR;		// data in seconds
			realTime *= 1000;							// convert to ms
			realTime *= 10000;							// convert to 100ns
			
			// get the desired "real" time
			RealTimeBias = (unsigned __int64) ft.dwHighDateTime << 32;
			RealTimeBias += ft.dwLowDateTime;
		
			// compensate for the clock time
			RealTimeBias -= realTime;
		}
	}
    //
    // read the clock registers
    //
    realTime = (unsigned __int64) dwRTCDR;		// data in seconds
    realTime *= 1000;							// convert to ms
    realTime *= 10000;							// convert to 100ns
    realTime += RealTimeBias;					// convert to "real" time

    //
    // load time/data structure
    //
    ft.dwLowDateTime = (DWORD)realTime;
    ft.dwHighDateTime = (DWORD)(realTime >> 32);

	bRet=KFileTimeToSystemTime( &ft, lpst );

	RETAILMSG(0,(TEXT("Time %d/%d/%d  %d:%d:%d --%d(%d)\r\n")
		,lpst->wYear
		,lpst->wMonth
		,lpst->wDay
		,lpst->wHour
		,lpst->wMinute
		,lpst->wSecond
		,lpst->wDayOfWeek
		,bRet
		));

    return bRet;
}

BOOL OEMSetRealTime(LPSYSTEMTIME lpst)
{
    unsigned __int64 realTime;
    FILETIME ft;
    //
    // Impliment battery backed real time clock.
    //
    //
    PRTCIF pRTC = (PRTCIF) RTC_BASE;
    DWORD dwRTCDR = pRTC->dr;

	if( !ISL1208SetRealTime( lpst ) )
		g_bRTCWithBattery=FALSE;
	
	*(__int64*)(&ft)= MySystemTimeToFileTime(lpst);
//    if (bRet = KSystemTimeToFileTime(lpst, &ft))
    {
        // read the clock registers
        realTime = (unsigned __int64) dwRTCDR;		// data in seconds
        realTime *= 1000;							// convert to ms
        realTime *= 10000;							// convert to 100ns
		
        // get the desired "real" time
        RealTimeBias = (unsigned __int64) ft.dwHighDateTime << 32;
        RealTimeBias += ft.dwLowDateTime;
	
		// compensate for the clock time
        RealTimeBias -= realTime;
    }
    return TRUE;
}

BOOL OEMSetAlarmTime(LPSYSTEMTIME lpst)
{
    FILETIME ft;
    BOOL bRet = FALSE;
    ULARGE_INTEGER alarmTime, currentTime, deltaTime;
    PRTCIF pRTC = (PRTCIF) RTC_BASE;
    DWORD dwRTCDR = pRTC->dr;
	
    // get the desired alarm time
    if (bRet = KSystemTimeToFileTime(lpst, &ft)) {
		alarmTime.LowPart = ft.dwLowDateTime;
		alarmTime.HighPart = ft.dwHighDateTime;
		alarmTime.QuadPart -= RealTimeBias;
		
        // get the current time
        currentTime.QuadPart = (unsigned __int64) dwRTCDR;		// data in seconds
        currentTime.QuadPart *= 1000;							// convert to ms
        currentTime.QuadPart *= 10000;						// convert to 100ns
		
        // make sure the alarm occurs in the future
        if(alarmTime.QuadPart < currentTime.QuadPart) {
			DEBUGMSG(FALSE, (_T("OEMSetAlarmTime: alarm 0x%08x:%08x occurs before 0x%08x:%08x\r\n"),
				alarmTime.HighPart, alarmTime.LowPart, currentTime.HighPart, currentTime.LowPart));
        } else {
			// round up to the nearest number of seconds
			deltaTime.QuadPart = alarmTime.QuadPart - currentTime.QuadPart;
			deltaTime.QuadPart += 9999999;					// msecs, usecs, 100ns
			deltaTime.QuadPart /= 10000000;				// convert to seconds
			
			// do we have enough resolution in our timer to handle the request?
			if(deltaTime.HighPart != 0) {
				DEBUGMSG(FALSE, (_T("OEMSetAlarmTime: alarm 0x%08x:%08x delta with 0x%08x:%08x (0x%08x:%08x) is too large\r\n"),
					alarmTime.HighPart, alarmTime.LowPart, currentTime.HighPart, currentTime.LowPart, deltaTime.HighPart, deltaTime.LowPart));
			} else {
				// clear interrupts, write the comparator, and enable interrupts
				pRTC->eoi = 0;			// any value clears pending interrupts
				pRTC->mr = dwRTCDR + deltaTime.LowPart;
				pRTC->cr = 1;			// enable match interrupt
				OEMInterruptEnable(SYSINTR_RTC_ALARM, NULL, 0);
				bRet = TRUE;
        	}
        }
    }

    // return TRUE if alarm set, FALSE otherwise
    return bRet;
}

#else //REAL_RTC


extern volatile LARGE_INTEGER CurTicks;

// The following control the debug output of the alarm & set functions
#define DEBUG_ALARM     0
#define DEBUG_SET       0

static volatile BOOL    gfInitRTC = TRUE;
static FILETIME         gftLastFileTime;
static LARGE_INTEGER    gliLastCurTicks;             // in ms

//
// The following are located in hal\interrupt.c
// They are used to control the alarm setting.
//
extern volatile BOOL           gfRTCAlarm;      // Is the RTC alarm enabled?
extern volatile LARGE_INTEGER  gliRTCAlarmTicks; // Date & time of the alarm.


//
// Multipling by 161111 and then right shifting by 13 is the same as 10000000 / TIMER_508KHZ_FREQ  
//
// This gives you the number of 100 nano second chunks...(nano chunks)
//
//#define TICKS_TO_NANO_CHUNKS( time )  (time) *= 161111; (time) = ((time) >> 13)
//#define TICKS_TO_NANO_CHUNKS( time )  (time)*=10*17/100;

#define TICKS_TO_NANO_CHUNKS( time )  (time)*=1302; (time)=(time)>>7


//#define TICKS_TO_NANO_CHUNKS( time )  (time)*=10*11; (time)=(time)>>6

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -