timex20t.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 215 行

C
215
字号
/* -*-C-*-
 *
 * $Revision: 1.2 $
 *   $Author: kwelton $
 *     $Date: 2000/08/08 21:45:52 $
 *
 * 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 "win_plat.h"
#include "timer.h"

extern DWORD CurMSec;
extern DWORD DiffMSec;
DWORD dwReschedIncrement;
extern DWORD HAL_mSecsLeft(void);

unsigned __int64 RealTimeBias = 0;  // Number of 100-nanosecond intervals since
                                    // January 1, 1601. 
DWORD AlarmTime = 0;    // Alarm Off at startup

volatile BOOL fInterruptFlag;

void HalTimerInit(void)
{
    return;
}

DWORD GetTimerPeriod(void)
{
    return RESCHED_PERIOD;
}

//
//  DWORD GetTickCount(VOID)    Return count of time since boot in milliseconds
//
DWORD SC_GetTickCount(void)
{

    return CurMSec;
}

BOOL OEMGetRealTime(LPSYSTEMTIME lpst)
{
    unsigned __int64 realTime;
    FILETIME ft;

    realTime = RealTimeBias + ((unsigned __int64)CurMSec*10000);
    ft.dwLowDateTime = (DWORD)realTime;
    ft.dwHighDateTime = (DWORD)(realTime >> 32);

    return KFileTimeToSystemTime( &ft, lpst );
}

BOOL OEMSetRealTime(LPSYSTEMTIME lpst)
{
    FILETIME ft;
    BOOL bRet;

    if (bRet = KSystemTimeToFileTime(lpst, &ft))
    {
        RealTimeBias = ((__int64)ft.dwHighDateTime<<32 | ft.dwLowDateTime) -
                       ((unsigned __int64)CurMSec*10000);
    }

    return bRet;
}

BOOL OEMSetAlarmTime(LPSYSTEMTIME lpst)
{
    FILETIME ft;
    BOOL bRet;
    unsigned __int64 Time64;

    if (bRet = KSystemTimeToFileTime(lpst, &ft))
    {
        Time64 =
            (((unsigned __int64)ft.dwHighDateTime<<32 | ft.dwLowDateTime) -
             RealTimeBias) / (unsigned __int64)(10000);

        if ((Time64 >> 32) != 0)
        {
            //
            // The alarm time is too big to check using CurMSec.  Return false.
            //
            bRet = FALSE;
        }
        else
            AlarmTime = (DWORD)Time64;
    }
    return bRet;
}

//
// Returns the current time in the time structure by reading the CurMSec
// and TVR values until a read is considered contiguous (CurMSec doesn't
// wrap while the TVR is read).
//
KCPTime_t KCP_GetCurrentTime()
{
    KCPTime_t time;
    volatile DWORD *PtrCurMSec = &CurMSec;
    DWORD dwBaseMs, ticks;

    // Read CurMSec and TVR atomically
    do
    {
        dwBaseMs = *PtrCurMSec;
        ticks = HAL_mSecsLeft() ;
    } while( dwBaseMs != *PtrCurMSec );

    // Fill in the time structure
    time.field.ms  = (dwBaseMs / TIMER_PERIOD) & MS_FIELD_MAX;
    time.field.tvr = ticks & TVR_FIELD_MAX;

    return time;
}

//
//  Takes in the number of TVR ticks and returns the number of microseconds
//  passed.
//
DWORD KCP_ScaleDown(DWORD N)
{
    DWORD temp;

    temp = N;
    temp /= OEMClockFreq;

    return (unsigned int)temp;
}

//
//  Gets the start time and returns the time structure as an unsigned int.
//
DWORD KCP_GetStartTime()
{
    return KCP_GetCurrentTime().u;
}

//
//  Reads the elapsed time as a time structure and calculates the elapsed
//  ticks by doing some math on both this and the start time structure.
//
DWORD KCP_GetElapsedTime(DWORD t0)
{
    KCPTime_t stop = KCP_GetCurrentTime();      // Get stop time structure
    KCPTime_t start;                            // Start time structure
    unsigned __int64 msTicks;                   // Number of ticks from ms
    unsigned __int64 tvrTicks;                  // Number of TVR ticks

    start.u = t0;                               // Convert input into time structure

    // Count the number of ms elapsed.
    if (stop.field.ms >= start.field.ms)        // Check for wrap and account for it
        msTicks = stop.field.ms - start.field.ms;
    else
        msTicks = (stop.field.ms + (MS_FIELD_MAX - start.field.ms)) &
            MS_FIELD_MAX;

    // Convert ms to ticks
    msTicks = (msTicks * TIMER_PERIOD) * mSEC_1 * TICKS_PER_uSEC ;

    // Count the number of TVR ticks elapsed.
    //
    // Check for wrap and account for it
    if (start.field.tvr > stop.field.tvr)
        tvrTicks = start.field.tvr - stop.field.tvr;
    else
        tvrTicks = (start.field.tvr + (TVR_FIELD_MAX - stop.field.tvr)) &
            TVR_FIELD_MAX;

    return (DWORD)(msTicks + tvrTicks);
}

DWORD PerfCountFreq()
{
    return(OEMClockFreq);
}

DWORD PerfCountSinceTick()
{
#ifdef NotYet

NEEDS TO BE CHANGED !!!!!!!
    DWORD dwTIR = *((volatile DWORD *)ARM720_TIR);
    DWORD dwCount = *((volatile DWORD *)ARM720_TVR);

    if (dwCount > dwReschedIncrement)
    {
        // This is an error case. Recover gracefully.
        DEBUGMSG(1, (L"PerfCountSinceTick(): Correcting periodic timer "
                     L"read error\r\n"));
        
        return dwReschedIncrement;
    }

    // Note : this is a countdown timer, not count up.
    if(dwTIR & ARM720_TIR_SET)
        return dwReschedIncrement + (dwReschedIncrement - dwCount);
    else
        return dwReschedIncrement - dwCount;
#else /* NotYet */
    ERRORMSG(1, (TEXT("Unsupported call to PerfCountSinceTick()\r\n")));
    return(0);
#endif /* NotYet */
}

/* EOF timex20t.c */

⌨️ 快捷键说明

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