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

📄 timer.c

📁 该2440 BSP是由三星公司提供的wince5.0的BSP移植到到wince6.0下的
💻 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.
//
//------------------------------------------------------------------------------
//
//  Module: timer.c           
//
//  Interface to OAL timer services.
//
#include <windows.h>
#include <nkintr.h>
#include <ceddk.h>
#include <oal.h>
#include <s3c2440a.h>
#include "BSP.h"

//------------------------------------------------------------------------------
// Local Variables 

static S3C2440A_PWM_REG *g_pPWMRegs = NULL;
 
volatile BOOL b_oalInterruptFlag;

#define DVS_EN
#ifdef DVS_EN

//-----------------------------------------
// Variables for DVS
volatile int CurrentState = Active;
volatile int PrevState = Active;
volatile int NextState = 0;

BOOL  bPowerSaving;

extern void DVS_ON(void);
extern void DVS_OFF(void);
extern void ChangeVoltage(int);
extern int GetCurrentVoltage(void);

volatile BOOL IDLEflag = FALSE;
extern BOOL	VSYNCINTR;
extern BOOL	CurrStateIdle;


#endif 


//------------------------------------------------------------------------------
//
//  Static:  g_timer
//
//  This structure contains timer internal variable. The period is value used
//  to timer recharge, margin value define maximal latency for timer recharge
//  without shift, base value is actual period base and compare is actual
//  period end. The period isn't changed by timer reduce/extend function.
//
static struct {
    UINT32 base;
    UINT32 compare;
} g_timer;

//------------------------------------------------------------------------------
//
//  Function:  OALTimerInitCount
//
//  This function initialize count/compare timer.
//
VOID OALTimerInitCount(UINT32 period)
{
    g_timer.base = OALTimerGetCount();
    g_timer.compare = g_timer.base + period;
    OALTimerSetCompare(g_timer.compare); 
}


//------------------------------------------------------------------------------
//
//  Function: OALTimerInit
//
//  This function is typically called from the OEMInit to initialize
//  Windows CE system timer. The tickMSec parameter determine timer
//  period in milliseconds. On most platform timer period will be
//  1 ms, but it can be usefull to use higher value for some
//  specific (low-power) devices.
//
//  Implementation for s3c2440a is using timer 4 as system timer.
//
BOOL OALTimerInit(
    UINT32 msecPerSysTick, UINT32 countsPerMSec, UINT32 countsMargin
) {
    BOOL rc = FALSE;
    UINT32 countsPerSysTick;
    UINT32 sysIntr, irq;
    UINT32 tcon;

    OALMSG(OAL_TIMER&&OAL_FUNC, (
        L"+OALTimerInit( %d, %d, %d )\r\n", 
        msecPerSysTick, countsPerMSec, countsMargin
    ));

    // Validate Input parameters
    countsPerSysTick = countsPerMSec * msecPerSysTick;
    if (
        msecPerSysTick < 1 || msecPerSysTick > 1000 ||
        countsPerSysTick < 1 || countsPerSysTick > 65535
    ) {
        OALMSG(OAL_ERROR, (
            L"ERROR: OALTimerInit: System tick period out of range..."
        ));
        goto cleanUp;
    }

    // Initialize timer state global variable    
    g_oalTimer.msecPerSysTick = msecPerSysTick;
    g_oalTimer.countsPerMSec = countsPerMSec;
    g_oalTimer.countsMargin = countsMargin;
    g_oalTimer.countsPerSysTick = countsPerSysTick;
    g_oalTimer.curCounts = 0;
    g_oalTimer.maxPeriodMSec = 0xFFFF/g_oalTimer.countsPerMSec;

	g_oalTimer.actualMSecPerSysTick = msecPerSysTick;
	g_oalTimer.actualCountsPerSysTick = countsPerSysTick;

    // Set kernel exported globals to initial values
    idleconv = countsPerMSec;
    curridlehigh = 0;
    curridlehigh = 0;

    // Initialize high resolution timer function pointers
    pQueryPerformanceFrequency = OALTimerQueryPerformanceFrequency;
    pQueryPerformanceCounter = OALTimerQueryPerformanceCounter;

    // Create SYSINTR for timer
    irq = IRQ_TIMER4;
    sysIntr = OALIntrRequestSysIntr(1, &irq, OAL_INTR_FORCE_STATIC);

    // Hardware Setup
    g_pPWMRegs = (S3C2440A_PWM_REG*)OALPAtoUA(S3C2440A_BASE_REG_PA_PWM);

    // Set prescaler 1 to 1 
    OUTREG32(&g_pPWMRegs->TCFG0, INREG32(&g_pPWMRegs->TCFG0) & ~0x0000FF00);
    OUTREG32(&g_pPWMRegs->TCFG0, INREG32(&g_pPWMRegs->TCFG0) | (245-1) <<8);		// charlie, Timer4 scale value
    // Select MUX input 1/2
    OUTREG32(&g_pPWMRegs->TCFG1, INREG32(&g_pPWMRegs->TCFG1) & ~(0xF << 16));
    OUTREG32(&g_pPWMRegs->TCFG1, INREG32(&g_pPWMRegs->TCFG1) | (3 << 16));	// charlie, Timer4 Division
    // Set timer register
    OUTREG32(&g_pPWMRegs->TCNTB4, g_oalTimer.countsPerSysTick);

    // Start timer in auto reload mode
    tcon = INREG32(&g_pPWMRegs->TCON) & ~(0x0F << 20);
    OUTREG32(&g_pPWMRegs->TCON, tcon | (0x2 << 20) );
    OUTREG32(&g_pPWMRegs->TCON, tcon | (0x5 << 20) );

    // Enable System Tick interrupt
    if (!OEMInterruptEnable(sysIntr, NULL, 0)) {
        OALMSG(OAL_ERROR, (
            L"ERROR: OALTimerInit: Interrupt enable for system timer failed"
        ));
        goto cleanUp;

    }

//    
// Define ENABLE_WATCH_DOG to enable watchdog timer support.
// NOTE: When watchdog is enabled, the device will reset itself if watchdog timer is not refreshed within ~4.5 second.
//       Therefore it should not be enabled when kernel debugger is connected, as the watchdog timer will not be refreshed.
//
#ifdef ENABLE_WATCH_DOG
    {
        extern void SMDKInitWatchDogTimer (void);
        SMDKInitWatchDogTimer ();
    }
#endif

    // Done        
    rc = TRUE;
    
cleanUp:
    OALMSG(OAL_TIMER && OAL_FUNC, (L"-OALTimerInit(rc = %d)\r\n", rc));
    return rc;
}


//------------------------------------------------------------------------------
//
//  Function: OALTimerIntrHandler
//
//  This function implement timer interrupt handler. It is called from common
//  ARM interrupt handler.
//
UINT32 OALTimerIntrHandler()
{
    UINT32 sysIntr = SYSINTR_NOP;

    // Update high resolution counter
    g_oalTimer.curCounts += g_oalTimer.actualCountsPerSysTick;
                             
    // Update the millisecond counter
    CurMSec += g_oalTimer.actualMSecPerSysTick;

#ifdef DVS_EN
#if ( DVS_METHOD == 2 )
#if ( USESWPWSAVING == 1)
		if ( bPowerSaving == TRUE && CurMSec - dwPrevTotalTick100 >= 100 )
		{
            S3C2440A_IOPORT_REG *g_pPortRegs = (S3C2440A_IOPORT_REG*)OALPAtoVA(S3C2440A_BASE_REG_PA_IOPORT, FALSE );
			bPowerSaving = FALSE;
			if ( GetCurrentVoltage() != V130 )
			{
				int i;
				ChangeVoltage(HIGHVOLTAGE);
				for(i=0;i<VOLTAGEDELAY;i++)
				{
					INREG32(&g_pPortRegs->GPFDAT); // for loop operation, just read.
				}
				DVS_OFF();
			}
		}
#endif //( USESWPWSAVING == 1)
#elif ( DVS_METHOD == 3 )
		if ( CurrentState == LazyActive || CurrentState == SlowActive )
		{
			S3C2440A_LCD_REG *pLCDRegs = (S3C2440A_LCD_REG *)OALPAtoVA( S3C2440A_BASE_REG_PA_LCD, FALSE );
			S3C2440A_INTR_REG *pIntrRegs = (S3C2440A_INTR_REG*)OALPAtoVA( S3C2440A_BASE_REG_PA_INTR, FALSE );
			if ( CurMSec - dwPrevTotalTick100 >= 500 )		// LazyActive -> Active
			{
				bPowerSaving = FALSE;
				NextState = Active;
				if  ( pLCDRegs->LCDSRCPND & 2 ) pLCDRegs->LCDSRCPND = 2;
				if  ( pLCDRegs->LCDINTPND & 2 ) pLCDRegs->LCDINTPND = 2;
				if  ( pIntrRegs->SRCPND & (1 << IRQ_LCD)) pIntrRegs->SRCPND = (1 << IRQ_LCD);
				if  ( pIntrRegs->INTPND & (1 << IRQ_LCD) ) pIntrRegs->INTPND = (1 << IRQ_LCD);
				pIntrRegs->INTMSK &= ~(1 << IRQ_LCD);		// enable LCD interrupt
				IDLEflag = FALSE;
			}
		}
#endif ( DVS_METHOD == 3 )

#endif //DVS_EN

    // Reschedule?
    if ((int)(CurMSec - dwReschedTime) >= 0) sysIntr = SYSINTR_RESCHED;

#ifdef OAL_ILTIMING
    if (g_oalILT.active) {
        if (--g_oalILT.counter == 0) {
            sysIntr = SYSINTR_TIMING;
            g_oalILT.counter = g_oalILT.counterSet;
            g_oalILT.isrTime2 = OALTimerCountsSinceSysTick();
        }
    }        
#endif

    return sysIntr;
}


//------------------------------------------------------------------------------
//

⌨️ 快捷键说明

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