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

📄 timerbvd1.c

📁 PXA27X_CAYMAN BSP from CAYMAN board
💻 C
字号:
/* Copyright ?2000-2001 Intel Corp.  */
/*++

Module Name:  timerxsc1.c

Abstract:  
 Contains OST and RTC initialization routine and
 RTC OEM routines

Notes: 

--*/

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

#include "bvd1.h"
#include "bvd1bd.h"
#include "timer.h"

#include "xllp_Pm.h"
#include "pcf.h"
#include "xllp_pwri2c.h"
typedef struct I2C_tag
{
	DWORD IBMR; 
	DWORD rsvd1;
	DWORD IDBR; 
	DWORD rsvd2;
	DWORD ICR;
	DWORD rsvd3;
	DWORD ISR;
	DWORD rsvd4;
	DWORD ISAR;
}I2C_REG;
volatile BOOL fInterruptFlag;

extern DWORD CurMSec;

/*
 * Forward References
 */
void XSC1_GetRealTime(LPSYSTEMTIME lpst);
void XSC1_SetRealTime (LPSYSTEMTIME lpst);
void GetRTCTime (unsigned int *cur_time);
void SetRTCTime (unsigned int cur_time);
void ConvertSystemTime(LPSYSTEMTIME lpst, unsigned int *cur_time);
void FormatSystemTime(unsigned int cur_time, LPSYSTEMTIME lpst);
void InitClock(void);

DWORD dwProfilerIncrement;

//#define ORIGINYEAR  1980
#define ORIGINYEAR  2005  
//#define JAN1WEEK    2      /* Tuesday */
#define JAN1WEEK    6      /* Saturday */

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 = {ORIGINYEAR,1,JAN1WEEK,1,23,59,00,0};

// Use OS Timer 4 as 100ms Timer
void Set100msTimer()
{
    XLLP_OST_T  *v_pOSTRegs = (XLLP_OST_T *)OST_BASE_U_VIRTUAL;
    XLLP_OST_HANDLE_T    XllpOSTHandle;

    XllpOSTHandle.pOSTRegs = v_pOSTRegs;
    XllpOSTHandle.pINTCRegs = (XLLP_INTC_T *)INTC_BASE_U_VIRTUAL;

    v_pOSTRegs->omcr4  = 0x000000CA;
    v_pOSTRegs->oscr4  = 0;

    XllpOstConfigureTimer (&XllpOSTHandle, MatchReg4, 60);
}

//
// HalTimerInit sets up the OS timer to interrupt via match reg 0 on the IRQ level.
// Interrupts are requested at 1ms intervals.
//
// Interrupts are disabled when this is called.
//
// Called from OEMInit()
//
void HalTimerInit(void) 
{
    SYSTEMTIME st;

    P_XLLP_OST_T            const v_pOSTRegs = (XLLP_OST_T *)OST_BASE_U_VIRTUAL;
    XLLP_OST_HANDLE_T       XllpOSTHandle;

    XllpOSTHandle.pOSTRegs = v_pOSTRegs;
    XllpOSTHandle.pINTCRegs = (XLLP_INTC_T *)INTC_BASE_U_VIRTUAL;

    //
    // LLI initializes oier and rtsr to zeroes, so no further
    // initialization needs to be done.  Match timers and
    // alarms are disabled.
    //
    // Current usage of Match registers:
    //  M0 - Scheduler
    //  M1 - Touch Panel
    //  M2 - Profiler
    //

    //
    // Note:  No RTC trim value needs to be set.  The value
    // loaded into the trim register at hardware-reset results
    // in a 1Hz clock, given a perfect crystal.
    //

    //
    // Check real time clock, initialize if necessary 
    // (used for polling in net routines)
    //
    XSC1_GetRealTime(&st);

    if ((st.wYear < ORIGINYEAR) ||
        (st.wMonth < 1) ||
        (st.wMonth > 12) ||
        (st.wDay < 1) ||
        (st.wDay > 31) ||
        (st.wHour > 23) ||
        (st.wMinute > 59) ||
        (st.wSecond > 59) ||
        (st.wMilliseconds > 999)) {

        XSC1_SetRealTime(&defst);
    }


	// 
	// Configure and arm the timer interrupt
	//
	InitClock();

    Set100msTimer();
}


//
// InitClock sets up the OS timer to interrupt via match reg 0 on the IRQ level.
// Interrupts are requested at 1ms intervals.
//
// Interrupts are disabled when this is called.
// This routine is called when resuming from sleep
//
void InitClock(void) {

    P_XLLP_OST_T            const v_pOSTRegs = (XLLP_OST_T *)OST_BASE_U_VIRTUAL;
    XLLP_OST_HANDLE_T       XllpOSTHandle;
    unsigned long           timermatch;

    XllpOSTHandle.pOSTRegs = v_pOSTRegs;
    XllpOSTHandle.pINTCRegs = (XLLP_INTC_T *)INTC_BASE_U_VIRTUAL;

	// 
	// Configure and arm the timer interrupt
	// to interrupt every 1ms 
	//
    timermatch = v_pOSTRegs->oscr0+RESCHED_INCREMENT;
    XllpOstConfigureTimer (&XllpOSTHandle, MatchReg0, timermatch);
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void 
OEMProfileTimerDisable(void)
{
    volatile XLLP_OST_T   *const v_pOSTReg = (XLLP_OST_T *)OST_BASE_U_VIRTUAL;
    
    //
    // Disable the profiling interrupts
    //
    TIMER_M2_INT_DIS(v_pOSTReg->oier); 
}



//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void OEMProfileTimerEnable(DWORD dwUSec)
{
    P_XLLP_OST_T            const v_pOSTRegs = (XLLP_OST_T *)OST_BASE_U_VIRTUAL;
    XLLP_OST_HANDLE_T       XllpOSTHandle;
    unsigned long           timermatch;


    XllpOSTHandle.pOSTRegs = v_pOSTRegs;
    XllpOSTHandle.pINTCRegs = (XLLP_INTC_T *)INTC_BASE_U_VIRTUAL;
    
    if (dwUSec) {
        //
        // Rate specified (may need to be limited)
        //
        if (dwUSec < 20) {
            dwUSec = 20;
        }
    } else {
        //
        // Use default rate (100 uS)
        //
        dwUSec = 100;
    }
    
    dwProfilerIncrement = (dwUSec * RESCHED_INCREMENT) / 1000;
	timermatch = v_pOSTRegs->oscr0+dwProfilerIncrement;
    
	// 
	// 
	// Configure and arm the Match2 register to interrupt
	// at the profiler increment
	//
    XllpOstConfigureTimer (&XllpOSTHandle, MatchReg2, timermatch);

}


DWORD GetTimerPeriod(void) {
    return RESCHED_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;
}

//
//
// Returns the time from the RTC in SYSTEMTIME format.
// Called by kernel in respond to GetSystemTime()
//
//
BOOL
OEMGetRealTime(LPSYSTEMTIME lpst)
{
    unsigned int cur_time;

    //
    // Get the RTC value
    //
    GetRTCTime (&cur_time);

    FormatSystemTime (cur_time, lpst);
/*///--- by-paying , use pcf50606's rtc yet.seems some problem.
	GetPCFRTCTime(lpst);
/*///---
#if 0
	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, cur_time));
#endif

    return TRUE;
}

//
//
// Sets the RTC.
// Called by kernel in response to SetSystemTime()
//
//
BOOL OEMSetRealTime(LPSYSTEMTIME lpst)
{
    unsigned int cur_time;

    ConvertSystemTime (lpst, &cur_time);

    SetRTCTime (cur_time);
#if 0
    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, cur_time));
#endif

    return TRUE;
}

//
//
// Set the RTC alarm.
// Ensure synchronization to RTC registers.
//
// Default behavior will allow setting an alarm 
// (thereby cancelling any pending one)
//
//
BOOL OEMSetAlarmTime(LPSYSTEMTIME lpst)
{
    unsigned int    min, day, month, year;
    unsigned int    *mtbl;
    unsigned int    alarm_time;

    XLLP_RTC_HANDLE_T   XllpRTCHandle;

    XllpRTCHandle.pRTCRegs = (XLLP_RTC_T *)RTC_BASE_U_VIRTUAL;
    XllpRTCHandle.pINTCRegs = (XLLP_INTC_T *)INTC_BASE_U_VIRTUAL;

    day = 0;
    for (year=ORIGINYEAR; year<lpst->wYear; year++) {
        day += 365 + isleap(year);
    }

    mtbl = isleap(year) ? monthtable_leap : monthtable;
    for (month=0; month<((unsigned)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;

	// 
	// Configure and arm the alarm 
	//
    XllpRtcConfigureAlarm (&XllpRTCHandle, alarm_time);


    return TRUE;
}

//
// FormatSystemTime
//
// Takes the RTC time and formats it into the
// Windows CE SYSTEMTIME format
//
void FormatSystemTime(unsigned int cur_time, LPSYSTEMTIME lpst)
{
    unsigned int    ms, sec, min, hour, day, month, year, leap;
    unsigned int    *mtbl;

    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;

    return;
}

//
// ConvertSystemTime
//
// Takes the Windows CE SYSTEMTIME and converts it to
// an unsigned integer.
//
void ConvertSystemTime(LPSYSTEMTIME lpst, unsigned int *cur_time)
{
    unsigned int    min, day, month, year;
    unsigned int    *mtbl;

    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;

    return;

}

//
//
// GetRTCTime
//
// Called by HalTimerInit and OEMGetRealTime
//
void GetRTCTime (unsigned int *cur_time)
{
    volatile XLLP_RTC_T *v_pRTCReg;

    v_pRTCReg = (volatile XLLP_RTC_T *)RTC_BASE_U_VIRTUAL;

    *cur_time = v_pRTCReg->rcnr;

    return;
}


//
// SetRTCTime
//
// Called by HalTimerInit and OEMSetRealTime
//
void SetRTCTime (unsigned int cur_time)
{
    volatile XLLP_RTC_T *v_pRTCReg;

    v_pRTCReg = (volatile XLLP_RTC_T *)RTC_BASE_U_VIRTUAL;

    // Set the RTC value
    v_pRTCReg->rcnr = cur_time;

    return;
}

//
// XSC1_GetRealTime
//
// Called by HalTimerInit
//
void XSC1_GetRealTime(LPSYSTEMTIME lpst)
{
    unsigned int cur_time;

    GetRTCTime (&cur_time);
    FormatSystemTime (cur_time, lpst);
    return;
}

//
// XSC1_SetRealTime
//
// Called by HalTimerInit
//
void XSC1_SetRealTime (LPSYSTEMTIME lpst)
{
    unsigned int cur_time;

    ConvertSystemTime (lpst, &cur_time);

    SetRTCTime (cur_time);
    return;
}

//
//
// Support routine returning tick count since
// last timer firing.
//
//
DWORD
PerfCountSinceTick(void)
{
    DWORD dwCount;
    DWORD ReschedIncr = RESCHED_INCREMENT;
    volatile XLLP_OST_T   *const v_pOSTReg = (XLLP_OST_T *)OST_BASE_U_VIRTUAL;
    
    //
    // Get ticks until next timer interrupt
    //
    dwCount= ((DWORD)v_pOSTReg->osmr0 - (DWORD)v_pOSTReg->oscr0);
    
    //
    // Calculate elapsed ticks since last firing...
    //
    // 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 ReschedIncr - dwCount;
}

//
//
// Support routine returning frequency of the timer
// used by Interrupt Latency Timing.
//
//
DWORD
PerfCountFreq(void)
{
    DWORD ReschedIncr = RESCHED_INCREMENT;

	return ReschedIncr;
}

⌨️ 快捷键说明

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