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

📄 realtimeclock.c

📁 ebd9307开发板wince bsp源码,包括cs8900,lcd,nand,serial,touch,usb,gpio,wd等驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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.
//
/* -*-C-*-
 *
 * $Revision: 1.5 $
 *   $Author: xinxing $
 *     $Date: 2005/04/29 02:45:54 $
 *
 * Copyright (c) 1999 ARM Limited
 * All Rights Reserved
 *
 * timex20t.c - ARMX20T (X = 7, 9, 10) platform timer routines
 */
#include <windows.h>
#include <nkintr.h>
#include <debugtimer.h>

extern BOOL (*KLocalFileTimeToFileTime)(const FILETIME *, LPFILETIME);

#include <hwdefs.h>


DWORD dwReschedIncrement;
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
//
// Multiply by 33 and then right shift by 24 is the same as TIMER_508KHZ_FREQ / 10000000
// This will give us TICKS
//
//#define NANO_CHUNKS_TO_TICKS( time )  (time) = ((time) << 13); (time) = (time) / 161111



#define EE_DELAY_USEC     5
#define EE_READ_TIMEOUT   500
#define WRITE_ADDRESS     0xA2
#define READ_ADDRESS      0xA3
#define YEAR_REGISTER     8
#define MONTH_REGISTER    7
#define DAY_REGISTER      5
#define HOUR_REGISTER     4 
#define MINUTE_REGISTER   3
#define SECOND_REGISTER   2
#define START_YEAR_VALUE  1950
#define YEAR_ADJUST_VALUE 30
#define NUMBER            1
 

UINT BcdToHex(UINT uiData);
UINT HexToBcd(UINT uiData);
static INT WriteI2CReg(UCHAR ucRegAddr, UCHAR *ucRegValue, INT nbytes);
static INT ReadI2CReg(UCHAR ucRegAddr, UCHAR *buffer, INT nbytes);


static void add64_64_64(
    const LPFILETIME lpNum1, 
    const LPFILETIME lpNum2, 
          LPFILETIME lpResult
)
{
    __int64 num1, num2;

    num1  = (((__int64)lpNum1->dwHighDateTime)<<32);
    num1 += (__int64)lpNum1->dwLowDateTime;
    num2  = (((__int64)lpNum2->dwHighDateTime)<<32);
    num2 += (__int64)lpNum2->dwLowDateTime;
    num1 += num2;
    lpResult->dwHighDateTime = (DWORD)(num1 >> 32);
    lpResult->dwLowDateTime  = (DWORD)(num1 & 0xffffffff);
}

// The following function initializes the RT area in an attempt to 
// eliminate the run time dependency of the OS on the CMOS. The X86
// CMOS is very slow and can take up to 1ms to get the full CMOS clock.
// This function get the start time from the CMOS and initializes the
// local variables that the RT functions need.
//
static void initRTC( void )
{
    SYSTEMTIME curSysTime;
    FILETIME   curFTime;
    UCHAR uiTemp;
	UINT i,wC;

    RETAILMSG(FALSE,(TEXT("\r\n\n******Called initRTC\r\n\n")));

    // This is changed here so that we don't try to
    // initialize the RTC at the same time that it
    // is already being done.
    //
    gfInitRTC = FALSE;

    //
    // Provide a default time...
    memset( &curSysTime, 0, sizeof( curSysTime ) );
    
    for(i=0;i<300;i++)
    {
    	    DelayInuSec(10);
    ReadI2CReg(SECOND_REGISTER,&uiTemp,NUMBER);
    uiTemp &= 0x7f;
    curSysTime.wSecond = BcdToHex((UINT)(uiTemp));
    
        DelayInuSec(10);
    ReadI2CReg(MINUTE_REGISTER,&uiTemp,NUMBER);
    uiTemp &= 0x7f;
    curSysTime.wMinute = BcdToHex((UINT)(uiTemp));
   
    
        DelayInuSec(10);
    ReadI2CReg(HOUR_REGISTER,&uiTemp,NUMBER);
    uiTemp &= 0x3f;
    curSysTime.wHour   = BcdToHex((UINT)(uiTemp));
  
    
        DelayInuSec(10);
    ReadI2CReg(DAY_REGISTER,&uiTemp,NUMBER);
    uiTemp &= 0x3f;
    curSysTime.wDay    = BcdToHex((UINT)(uiTemp));
	
    
    DelayInuSec(10);
    ReadI2CReg(MONTH_REGISTER,&uiTemp,NUMBER);
    if(uiTemp & 0x80)
    	wC = 1900;
    else
    	wC = 2000;
    
    uiTemp &= 0x1f;
    curSysTime.wMonth  = BcdToHex((UINT)(uiTemp));
    

    DelayInuSec(10);
    ReadI2CReg(YEAR_REGISTER,&uiTemp,NUMBER);
   
    curSysTime.wYear   = BcdToHex((UINT)(uiTemp)) + wC;
    
    if(curSysTime.wYear > 1900)
    	break;
    }

    // Convert the file time structure
    //
    if( !KSystemTimeToFileTime( &curSysTime, &curFTime ) )
    {
        memset( &curSysTime, 0, sizeof( curSysTime ) );
        memset( &curFTime, 0, sizeof( curFTime ) );
    }

    // Update current versions of the RTC support
    //
    gliLastCurTicks.QuadPart = CurTicks.QuadPart;
    gftLastFileTime.dwLowDateTime  = curFTime.dwLowDateTime;
    gftLastFileTime.dwHighDateTime = curFTime.dwHighDateTime;
}


BOOL OEMGetRealTime(LPSYSTEMTIME lpst)
{
    //
    // NOTE:  this function is assumed to return a LOCAL time rather than a UTC time!
    //
    unsigned __int64 ui64Delta;
    BOOL             bResult = FALSE;
    LARGE_INTEGER    liTimeDelta;
    FILETIME         ftDelta;
    FILETIME         ftCurFTime;
    LARGE_INTEGER    tmpCurTicks;
	//UCHAR uiTemp;

    if (gfInitRTC) 
    {
        // Setup the software RTC...
        // gliLastCurTicks & gftLastFileTime is set in 
        // the following call.

        
        initRTC();
    }

    
    // get a snapshot of the current tick count...
    tmpCurTicks.QuadPart = CurTicks.QuadPart;

    // Calculate the current diference
    //
    if( tmpCurTicks.QuadPart >= gliLastCurTicks.QuadPart )
    {
        liTimeDelta.QuadPart = 
                tmpCurTicks.QuadPart - gliLastCurTicks.QuadPart;
    }
    else
    {
        // The counter wrapped...
        LARGE_INTEGER liMaxLargeInt;
        
        liMaxLargeInt.HighPart = 0xFFFFFFFF;
        liMaxLargeInt.LowPart  = 0xFFFFFFFF;

        liTimeDelta.QuadPart = 
            tmpCurTicks.QuadPart + 
            (liMaxLargeInt.QuadPart - gliLastCurTicks.QuadPart);
    }

    ui64Delta = (unsigned __int64) liTimeDelta.QuadPart;
    TICKS_TO_NANO_CHUNKS( ui64Delta ); // convert to nano chunks

    // setup to add in the nano chunk time difference
    ftDelta.dwLowDateTime  = (DWORD)  ui64Delta;
    ftDelta.dwHighDateTime = (DWORD) (ui64Delta >> 32);

    // Add the delta to the last known time...
    //
    add64_64_64(  &gftLastFileTime , &ftDelta, &ftCurFTime );

    // convert the answer to a system time format
    //
    if(KFileTimeToSystemTime( &ftCurFTime, lpst ) )
    {
        //
        // update the RTC variables...
        //
        gftLastFileTime.dwLowDateTime  = ftCurFTime.dwLowDateTime;
        gftLastFileTime.dwHighDateTime = ftCurFTime.dwHighDateTime;
        gliLastCurTicks.QuadPart = tmpCurTicks.QuadPart;
        bResult = TRUE;
    }
    else
    {
        // Failed, don't change anything!!!!
        //
        bResult = FALSE;
    }
    return( bResult );
}

BOOL OEMSetRealTime(LPSYSTEMTIME lpst)
{
    //
    // NOTE:  this function is passed a LOCAL time rather than a UTC time!
    //
    BOOL        bResult;
    SYSTEMTIME  curTime;
	UCHAR uiTemp;

	static volatile BOOL noHAL_INIT_RTC = TRUE;

	if (noHAL_INIT_RTC)
	{
		noHAL_INIT_RTC = FALSE ;
		return TRUE ;
	}

    if (gfInitRTC) 
    {
        // Setup the software RTC...
        initRTC();
    }

    DelayInuSec(80);
    uiTemp = (UCHAR)HexToBcd((UINT)lpst->wMonth);
    if(lpst->wYear < 2000)
    	uiTemp |= 0x80;
    
    WriteI2CReg(MONTH_REGISTER,&uiTemp,NUMBER);

    DelayInuSec(80);
    uiTemp = (UCHAR)HexToBcd((UINT)lpst->wDay);
    WriteI2CReg(DAY_REGISTER,&uiTemp,NUMBER);
    DelayInuSec(80);
    
    uiTemp = (UCHAR)HexToBcd((UINT)(lpst->wYear%100));
    WriteI2CReg(YEAR_REGISTER,&uiTemp,NUMBER);
    DelayInuSec(80);

    uiTemp = (UCHAR)HexToBcd((UINT)lpst->wHour);
    WriteI2CReg(HOUR_REGISTER,&uiTemp,NUMBER);
    DelayInuSec(80);

    uiTemp = (UCHAR)HexToBcd((UINT)lpst->wMinute);
    WriteI2CReg(MINUTE_REGISTER,&uiTemp,NUMBER);
    DelayInuSec(80);

    uiTemp = (UCHAR)HexToBcd((UINT)lpst->wSecond);
    WriteI2CReg(SECOND_REGISTER,&uiTemp,NUMBER);
    DelayInuSec(80);

    KFileTimeToSystemTime( &gftLastFileTime, &curTime );

    // if the last file time is updated, then update
    // the last current tick value...
    if( KSystemTimeToFileTime( lpst, &gftLastFileTime ) )
    {
        SYSTEMTIME  newTime;

        // remember when we last updated the time...
        gliLastCurTicks.QuadPart = CurTicks.QuadPart;

        KFileTimeToSystemTime( &gftLastFileTime, &newTime );

        DEBUGMSG(DEBUG_SET,  (_T("OEMSetRealTime: gliLastCurTicks: %d\r\n"),
                 gliLastCurTicks.QuadPart ));
        DEBUGMSG(DEBUG_SET,  (_T("OEMSetRealTime: cur: ST(%02d/%02d/%04d  %02d:%02d:%02d)\r\n"),
                 curTime.wMonth, curTime.wDay,    curTime.wYear,
                 curTime.wHour,  curTime.wMinute, curTime.wSecond ));
        DEBUGMSG(DEBUG_SET,  (_T("OEMSetRealTime: In: ST(%02d/%02d/%04d  %02d:%02d:%02d)\r\n"),
                 lpst->wMonth, lpst->wDay,    lpst->wYear,
                 lpst->wHour,  lpst->wMinute, lpst->wSecond ));
        DEBUGMSG(DEBUG_SET,  (_T("OEMSetRealTime: ft: ST(%02d/%02d/%04d  %02d:%02d:%02d)\r\n"),
                 newTime.wMonth, newTime.wDay,    newTime.wYear,
                 newTime.wHour,  newTime.wMinute, newTime.wSecond ));

        bResult = TRUE;
    }
    return( bResult );
}

BOOL OEMSetAlarmTime(LPSYSTEMTIME lpst)
{
    BOOL             bResult = TRUE;
    SYSTEMTIME       stCurTime;
    FILETIME         ftAlarmTime;
    ULARGE_INTEGER   uliCurFTime;
    ULARGE_INTEGER   uliAlarmFTime;

    // The following call will make sure that
    // the RTC is properly initialized...
    // This will return the LOCAL time.
    // A side-effect that is used here is that
    // gftLastFileTime is set to the current time...
    // gliLastCurTicks is also modified...
    OEMGetRealTime( &stCurTime );

⌨️ 快捷键说明

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