Esempio n. 1
0
//------------------------------------------------------------------------------
//
//  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 s3c2450 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;
/*#undef	OAL_TIMER
#undef	OAL_FUNC
#define OAL_TIMER	1
#define	OAL_FUNC	1*/
    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;
    curridlelow = 0;

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

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

    // Hardware Setup
#if (BSP_TYPE == BSP_SMDK2443)
    g_pPWMRegs = (S3C2450_PWM_REG*)OALPAtoUA(S3C2450_BASE_REG_PA_PWM);
#elif (BSP_TYPE == BSP_SMDK2450)
    g_pPWMRegs = (volatile S3C2450_PWM_REG*)OALPAtoUA(S3C2450_BASE_REG_PA_PWM);
    g_pClkpwrRegs = (volatile S3C2450_CLKPWR_REG *)OALPAtoUA(S3C2450_BASE_REG_PA_CLOCK_POWER);
    g_pIntrRegs = (volatile S3C2450_INTR_REG *)OALPAtoUA(S3C2450_BASE_REG_PA_INTR);
    g_pPortRegs = (volatile S3C2450_IOPORT_REG *)OALPAtoUA(S3C2450_BASE_REG_PA_IOPORT);
#endif	
    // Set prescaler 1 to 1 
    OUTREG32(&g_pPWMRegs->TCFG0, INREG32(&g_pPWMRegs->TCFG0) & ~0x0000FF00);
	OUTREG32(&g_pPWMRegs->TCFG0, INREG32(&g_pPWMRegs->TCFG0) | (PRESCALER<<8));
    // Select MUX input 1/2
    OUTREG32(&g_pPWMRegs->TCFG1, INREG32(&g_pPWMRegs->TCFG1) & ~(0xF << 16));
#if( SYS_TIMER_DIVIDER == DV2 )
    OUTREG32(&g_pPWMRegs->TCFG1, INREG32(&g_pPWMRegs->TCFG1) | (D1_2 << 16));
#elif ( SYS_TIMER_DIVIDER == DV4 )
    OUTREG32(&g_pPWMRegs->TCFG1, INREG32(&g_pPWMRegs->TCFG1) | (D1_4 << 16));
#elif ( SYS_TIMER_DIVIDER == DV8 )
    OUTREG32(&g_pPWMRegs->TCFG1, INREG32(&g_pPWMRegs->TCFG1) | (D1_8 << 16));
#elif ( SYS_TIMER_DIVIDER == DV16 )
    OUTREG32(&g_pPWMRegs->TCFG1, INREG32(&g_pPWMRegs->TCFG1) | (D1_16 << 16));
#endif
    // 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;
}
Esempio n. 2
0
//------------------------------------------------------------------------------
//
//  Function: OALTimerInit
//
//  General purpose timer 1 is used for system tick. It supports
//  count/compare mode on 32kHz clock
//
BOOL
OALTimerInit(
    UINT32 sysTickMSec,
    UINT32 countsPerMSec,
    UINT32 countsMargin
    )
{
    BOOL rc = FALSE;
    UINT srcClock;
    UINT32 sysIntr;

	UNREFERENCED_PARAMETER(sysTickMSec);
	UNREFERENCED_PARAMETER(countsPerMSec);
	UNREFERENCED_PARAMETER(countsMargin);

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

    //  Initialize timer state information
    g_oalTimerContext.maxPeriodMSec = dwOEMMaxIdlePeriod;   // Maximum period the timer will interrupt on, in mSec
    g_oalTimerContext.margin =        DELTA_TIME;           // Time needed to reprogram the timer interrupt
    g_oalTimerContext.curCounts =     0;
    g_oalTimerContext.base =          0;
    g_oalTimerContext.match =         0xFFFFFFFF;
    g_oalTimerContext.Posted =       0;

    // Set idle conversion constant and counters
    idleconv     = MSEC_TO_TICK(1);
    curridlehigh = 0;
    curridlelow  = 0;

    // Use variable system tick
    pOEMUpdateRescheduleTime = OALTimerUpdateRescheduleTime;

	// Get virtual addresses for hardware
    g_TimerDevice = BSPGetSysTimerDevice(); // OMAP_DEVICE_GPTIMER1
    
    g_pTimerRegs = OALPAtoUA(GetAddressByDevice(g_TimerDevice));
	OALMSG(1 && OAL_FUNC, (L" TimerPA: 0x%x\r\n", GetAddressByDevice(g_TimerDevice)));
	OALMSG(1 && OAL_FUNC, (L" TimerUA: 0x%x\r\n", g_pTimerRegs));
	// Select 32K frequency source clock
    srcClock = BSPGetSysTimer32KClock(); // k32K_FCLK
    
	//PrcmDeviceSetSourceClocks(g_TimerDevice,1,&srcClock);

    // enable gptimer
    EnableDeviceClocks(g_TimerDevice, TRUE);


    // stop timer
    OALTimerSetReg(&g_pTimerRegs->TCLR, 0);

    // Soft reset GPTIMER
    OALTimerSetReg(&g_pTimerRegs->TIOCP, SYSCONFIG_SOFTRESET);

    // While until done
    while ((OALTimerGetReg(&g_pTimerRegs->TISTAT) & GPTIMER_TISTAT_RESETDONE) == 0);

    // Set smart idle
    OALTimerSetReg(
        &g_pTimerRegs->TIOCP,
            SYSCONFIG_SMARTIDLE|SYSCONFIG_ENAWAKEUP|
            SYSCONFIG_AUTOIDLE
        );

    // Enable posted mode
    OALTimerSetReg(&g_pTimerRegs->TSICR, GPTIMER_TSICR_POSTED);
    g_oalTimerContext.Posted =       1;

    // Set match register to avoid unwanted interrupt
    OALTimerSetReg(&g_pTimerRegs->TMAR, 0xFFFFFFFF);

    // Enable match interrupt
    OALTimerSetReg(&g_pTimerRegs->TIER, GPTIMER_TIER_MATCH);

    // Enable match wakeup
    OALTimerSetReg(&g_pTimerRegs->TWER, GPTIMER_TWER_MATCH);

    // Enable timer in auto-reload and compare mode
    OALTimerSetReg(&g_pTimerRegs->TCLR, GPTIMER_TCLR_CE|GPTIMER_TCLR_AR|GPTIMER_TCLR_ST);

    // Wait until write is done
    //while ((INREG32(&g_pTimerRegs->TWPS) & GPTIMER_TWPS_TCLR) != 0);

    // Set global variable to tell interrupt module about timer used
    g_oalTimerIrq = GetIrqByDevice(g_TimerDevice,NULL); // 37

    // Request SYSINTR for timer IRQ, it is done to reserve it...
    sysIntr = OALIntrRequestSysIntr(1, &g_oalTimerIrq, OAL_INTR_FORCE_STATIC); // 17

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

    // Initialize timer to maximum period
    UpdatePeriod(g_oalTimerContext.maxPeriodMSec);

    // Done
    rc = TRUE;

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