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

📄 time1100.c

📁 WinCE 3.0 BSP, 包含Inter SA1110, Intel_815E, Advantech_PCM9574 等
💻 C
字号:
#include <windows.h>
#include <bldver.h>
#include <nkintr.h>

//#include "sa1100.h"
#include "arm1100.h"
#include "sa11x0.h"
#include "sa11x0bd.h"

#define	REG_POSR	0xA902001C

volatile BOOL fInterruptFlag;

extern DWORD CurMSec;
extern DWORD DiffMSec;

//not sure of relationship between this and the stuff in cfwarm
extern unsigned long OEMClockFreq;
//#define OEMClockFreq 3686400       // ticks/s
DWORD dwReschedIncrement;
DWORD OEMCount1ms;
static volatile DWORD dwCurReschedIncr;

#define ORIGINYEAR  1970
#define JAN1WEEK    1   /* Monday */

extern void ROSERTC_GetElapsedTimer(unsigned int *, unsigned int *);
extern void ROSERTC_SetElapsedTimer(unsigned int, unsigned int);
extern void ROSERTC_SetAlarm(unsigned int, unsigned int);

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 = {1998,1,0,1,23,59,50,0};

void HalTimerInit(void) {
    return;
}


//++
// When this is called we will set up GPIO<1> to be a falling edge interrupt  
// InitClock sets up the OS timer to int via match reg 0 on the IRQ level
// an int is requested in 1ms from now.
//
// Interrupts are disable when this is called.
//--
void InitClock(void) {
    SYSTEMTIME st;

    struct rtsrBits my_rtc_statreg;


    volatile struct ostreg*const v_pOSTReg = (struct ostreg *)OST_BASE_VIRTUAL;
    volatile struct icreg *const v_pICReg = (struct icreg *)IC_BASE_VIRTUAL;
    volatile struct rtcreg *const v_pRTCReg = (volatile struct rtcreg *)RTC_BASE_VIRTUAL;

	volatile LPDWORD posr = (volatile LPDWORD) REG_POSR;
    
    // Number of timer counts for reschedule interval
    dwReschedIncrement = RESCHED_INCREMENT;

	// Current resched interval
	dwCurReschedIncr = dwReschedIncrement;
	
	// Set OEM timer count for 1 ms
    OEMCount1ms = OEM_COUNT_1MS;

    // Set OEM clock frequency
    OEMClockFreq = OEM_CLOCK_FREQ;
    
    v_pOSTReg->osmr[0] = v_pOSTReg->oscr+ dwReschedIncrement;
    my_rtc_statreg.al = 1;
    my_rtc_statreg.hz = 1;
    my_rtc_statreg.ale = 0;
    my_rtc_statreg.hze = 0;

	v_pRTCReg->rtsr= my_rtc_statreg;
	v_pRTCReg->rttr.cdc=32768;				// set the trim to set RTC to 1Hz

    //v_pOSTReg->ossr = OSSR_M_M0; // clear any current interrupt
    TIMER_M0_INT_CLR(1); 
    //TIMER_M1_INT_CLR(1); 
    //TIMER_M2_INT_CLR(1); 
    //TIMER_M3_INT_CLR(1); 

    // v_pOSTReg->oier = OIER_M_E0; // turn on the interrupt
    TIMER_M1_INT_EN(0); 
    TIMER_M2_INT_EN(0); 
    TIMER_M3_INT_EN(0); 
    TIMER_M0_INT_EN(1);

	// wait for RTC stablized
	while (!(*posr & 1))
		;
    //v_pICReg->icmr = (1<<26) | (1<<1); // enable ip<26> for ostimer and <1> for dev ints
    TIMER_M0_INT_MASK(1); 

    // Check real time clock, initialize if necessary (used for polling in net routines)
    OEMGetRealTime(&st);
    if ((st.wYear < 1980) ||
        (st.wMonth < 1) ||
        (st.wMonth > 12) ||
        (st.wDay < 1) ||
        (st.wDay > 31) ||
        (st.wHour > 23) ||
        (st.wMinute > 59) ||
        (st.wSecond > 59) ||
        (st.wMilliseconds > 999)) {

        DEBUGMSG(1,(TEXT("Invalid time returned from OEMGetRealTime: Year: %u, Month: %u, Day: %u, Hour: %u, Minute: %u, second: %u rcnr=%Xh\n"),
                           st.wYear, st.wMonth,st.wDay, st.wHour, st.wMinute,st.wSecond,v_pRTCReg->rcnr));
        DEBUGMSG(1,(TEXT("Resetting real time clock to default date\n")));
        OEMSetRealTime(&defst);
    }
}

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

BOOL
OEMGetRealTime(LPSYSTEMTIME lpst)
{
    unsigned int    ms, sec, min, hour, day, month, year, leap;
    unsigned int    cur_time;
    unsigned int    *mtbl;

    volatile struct rtcreg *v_pRTCReg;

    v_pRTCReg = (volatile struct rtcreg *)RTC_BASE_VIRTUAL;

    cur_time = v_pRTCReg->rcnr;

    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;

	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,v_pRTCReg->rcnr));
    return TRUE;
}

BOOL OEMSetRealTime(LPSYSTEMTIME lpst)
{
    unsigned int    min, day, month, year;
    unsigned int    *mtbl;
    unsigned int cur_time;

    volatile struct rtcreg *v_pRTCReg;

    v_pRTCReg = (volatile struct rtcreg *)RTC_BASE_VIRTUAL;
	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,v_pRTCReg->rcnr));

    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;
   v_pRTCReg->rcnr = cur_time;

    return TRUE;
}

BOOL OEMSetAlarmTime(LPSYSTEMTIME lpst)
{
#if 0
    unsigned int    min, day, month, year;
    unsigned int    *mtbl;
    unsigned int   alarm_time;
 
   struct rtsrBits my_rtc_statreg;
    volatile struct icreg *v_pICReg;
    volatile struct rtcreg *v_pRTCReg;

    v_pRTCReg = (volatile struct rtcreg *)RTC_BASE_VIRTUAL;

    v_pICReg = (volatile struct icreg *)IC_BASE_VIRTUAL;


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

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

    v_pRTCReg->rtar = alarm_time;

    my_rtc_statreg = v_pRTCReg->rtsr;

    //clear any current RTC alarm interrupt

    my_rtc_statreg.al = 1;


    //enable the RTC alarm interrupt
    my_rtc_statreg.ale = 1;

    v_pRTCReg->rtsr = my_rtc_statreg;

   //unmask interrupt   
   // v_pICReg->icmr |= RTC_ALM;
   RT_ALARM_INT_MASK(1);

#endif
    return TRUE;
}

DWORD KCP_ScaleDown(DWORD N) {
    unsigned __int64 temp;
    temp = (N * 1000) / OEMCount1ms;
    return (unsigned int)temp;
}

DWORD KCP_GetStartTime() {
    return GET_TICK_TIME();
}

DWORD KCP_GetElapsedTime(DWORD start) {
    unsigned int stop = GET_TICK_TIME();
    if (stop > start)
        return stop - start;
    else
        return stop + (0xFFFFFFFF - start);
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
DWORD
PerfCountFreq()
{
    return OEMClockFreq;
//    return (3686400);
}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
DWORD
PerfCountSinceTick()
{
    DWORD dwCount;
    volatile struct ostreg *const v_pOSTReg = (struct ostreg *)OST_BASE_VIRTUAL;
    
    dwCount= ((DWORD)v_pOSTReg->osmr[0]-(DWORD)v_pOSTReg->oscr);
    
    // 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 dwCurReschedIncr - dwCount;
}




//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
CPUSetSysTimerCount(
    DWORD dwCountdownMSec
    )
{
    DWORD dwCount, dwMatch;
    volatile struct  ostreg *const v_pOSTReg = (struct ostreg *)OST_BASE_VIRTUAL;

    dwCurReschedIncr = dwCountdownMSec * OEMCount1ms;
    dwCount = v_pOSTReg->oscr;
    dwMatch = dwCount + dwCurReschedIncr;
//    DEBUGMSG(1, (TEXT("Moving match to 0x%08X, count is 0x%08X (%d ms)\r\n"), dwMatch, dwCount, dwCountdownMSec));
    v_pOSTReg->osmr[0] = dwMatch;

}


//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
BOOL
CPUClearSysTimerIRQ(
    void
    )
{
    volatile struct  ostreg *const v_pOSTReg = (struct ostreg *)OST_BASE_VIRTUAL;
    
    //v_pOSTReg->ossr = OSSR_M_M0;		// clear match 0 status
    TIMER_M0_INT_CLR(1);

	// Don't indicate that an IRQ was pending -- the math works out automatically
	// with the free-running timer + match in CPUGetSysTimerCountElapsed( ) if
	// the timer went past the match point.
    return FALSE;
}

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
#if (CE_MAJOR_VER == 0x0003)
//
// cedar
//
DWORD
CPUGetSysTimerCountElapsed(
    DWORD dwTimerCountdownMSec,
    volatile DWORD *pCurMSec,
    volatile DWORD *pDiffMSec,
    DWORD *pPartialCurMSec,
    DWORD *pPartialDiffMSec,
    volatile ULARGE_INTEGER *pCurTicks
    )
{
    volatile struct ostreg *const v_pOSTReg = (struct ostreg *)OST_BASE_VIRTUAL;

    DWORD dwTick = dwTimerCountdownMSec * OEMCount1ms;
	DWORD dwCount = (DWORD)v_pOSTReg->osmr[0] - (DWORD)v_pOSTReg->oscr;
	DWORD dwTemp;

    // Note: if dwCount is negative, the counter went past the match point.  The math
	// still works since it accounts for the dwTick time plus the time past the match.
	dwCount = dwTick - dwCount;
	    
	pCurTicks->QuadPart += dwCount;

	dwTemp = dwCount;
	dwTemp += *pPartialDiffMSec;
	*pPartialDiffMSec = dwTemp % OEMCount1ms;
	*pDiffMSec += dwTemp / OEMCount1ms;
	
	dwTemp = dwCount;
	dwTemp += *pPartialCurMSec;
	*pPartialCurMSec = dwTemp % OEMCount1ms;
	dwTemp = dwTemp / OEMCount1ms;
	*pCurMSec += dwTemp;

	return dwTemp;
}

#else
//
// dougfir or later
//
DWORD
CPUGetSysTimerCountElapsed(
    DWORD dwTimerCountdownMSec,
    volatile DWORD *pCurMSec,
    DWORD *pPartialCurMSec,
    volatile ULARGE_INTEGER *pCurTicks
    )
{
    volatile struct ostreg *const v_pOSTReg = (struct ostreg *)OST_BASE_VIRTUAL;

    DWORD dwTick = dwTimerCountdownMSec * OEMCount1ms;
	DWORD dwCount = (DWORD)v_pOSTReg->osmr[0] - (DWORD)v_pOSTReg->oscr;

    // Note: if dwCount is negative, the counter went past the match point.  The math
    // still works since it accounts for the dwTick time plus the time past the match.
    dwCount = dwTick - dwCount;
        
    pCurTicks->QuadPart += dwCount;

    dwCount += *pPartialCurMSec;
    *pPartialCurMSec = dwCount % OEMCount1ms;
    dwCount /= OEMCount1ms;
    *pCurMSec += dwCount;

    return dwCount;
}
#endif // CE_MAJOR_VER == 0x0003

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
CPUEnterIdle()
{
    fInterruptFlag = FALSE;
    INTERRUPTS_ON();
    while (!fInterruptFlag) {
        // Just sit here. Any interrupt will bump us out.
    }
}

#define IDLE_MAX_MS  30000
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
DWORD
CPUGetSysTimerCountMax(
    DWORD dwIdleMSecRequested
    )
{
    if (dwIdleMSecRequested > IDLE_MAX_MS) {
        //
        // Our timer isn't capable of idling more than IDLE_MAX_MS milliseconds. 
        // We'll have to break the sleep time into reasonable chunks.
        //
        return IDLE_MAX_MS;
    }

    return dwIdleMSecRequested;
}


⌨️ 快捷键说明

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