//------------------------------------------------------------------------------ // // Function: OALTimerUpdateRescheduleTime // // This function is called by kernel to set next reschedule time. // VOID OALTimerUpdateRescheduleTime( DWORD timeMSec ) { UINT32 baseMSec, periodMSec; INT32 delta; // Get current system timer counter baseMSec = CurMSec; // How far we are from next tick delta = (INT32)(g_oalTimerContext.match - OALTimerGetCount()); if( delta < 0 ) { UpdatePeriod(0); goto cleanUp; } // If timer interrupts occurs, or we are within 1 ms of the scheduled // interrupt, just return - timer ISR will take care of it. if ((baseMSec != CurMSec) || (delta < MSEC_TO_TICK(1))) goto cleanUp; // Calculate the distance between the new time and the last timer interrupt periodMSec = timeMSec - OEMGetTickCount(); // Trying to set reschedule time prior or equal to CurMSec - this could // happen if a thread is on its way to sleep while preempted before // getting into the Sleep Queue if ((INT32)periodMSec < 0) { periodMSec = 0; } else if (periodMSec > g_oalTimerContext.maxPeriodMSec) { periodMSec = g_oalTimerContext.maxPeriodMSec; } // Now we find new period, so update timer UpdatePeriod(periodMSec); cleanUp: return; }
//------------------------------------------------------------------------------ // // Function: OALTimerSetCompare // __inline VOID OALTimerSetCompare(UINT32 compare) { OALTimerSetReg(&g_pTimerRegs->TMAR, compare); // We commented out the following line because it causes issues to the overall performance // of the system. As the tick timer is clocked at 32 kHz, the TMAR register takes some // time to update and we loose this time waiting for it. The consequence is that we spend // more than 5% of the time in this loop where the CPU should actually be idle. Not waiting // should not have any consequence as we never actually read its value. // //while ((INREG32(&g_pTimerRegs->TWPS) & GPTIMER_TWPS_TMAR) != 0); // make sure we don't set next timer interrupt to the past // if (compare < OALTimerGetReg(&g_pTimerRegs->TCRR)) UpdatePeriod(1); }
//------------------------------------------------------------------------------ // // Function: OALTimerIntrHandler // // This function implement timer interrupt handler. It is called from common // ARM interrupt handler. // UINT32 OALTimerIntrHandler() { UINT32 count; INT32 period, delta; UINT32 sysIntr = SYSINTR_NOP; // allow bsp to process timer interrupt first sysIntr = OALTickTimerIntr(); if (sysIntr != SYSINTR_NOP) return sysIntr; // Clear interrupt OALTimerSetReg(&g_pTimerRegs->TISR, GPTIMER_TIER_MATCH); // How far from interrupt we are? count = OALTimerGetCount(); delta = count - g_oalTimerContext.match; // If delta is negative, timer fired for some reason // To be safe, reprogram the timer for minimum delta if (delta < 0) { delta = 0; goto cleanUp; } #ifdef OAL_ILTIMING if (g_oalILT.active) { g_oalILT.isrTime1 = delta; } #endif // Find how long period was period = count - g_oalTimerContext.base; g_oalTimerContext.curCounts += period; g_oalTimerContext.base += period; // Calculate actual CurMSec CurMSec = (UINT32) TICK_TO_MSEC(g_oalTimerContext.curCounts); OALLED(LED_IDX_TIMER, CurMSec >> 10); // Reschedule? delta = dwReschedTime - CurMSec; if (delta <= 0) { sysIntr = SYSINTR_RESCHED; delta = g_oalTimerContext.maxPeriodMSec; } cleanUp: // Set new period UpdatePeriod(delta); #ifdef OAL_ILTIMING if (g_oalILT.active) { if (--g_oalILT.counter == 0) { sysIntr = SYSINTR_TIMING; g_oalILT.counter = g_oalILT.counterSet; g_oalILT.isrTime2 = 0; } } #endif return sysIntr; }
//------------------------------------------------------------------------------ // // 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; }
void wxGamePanel::ResetPeriod() { m_period = 0; UpdatePeriod(); }
void wxGamePanel::DecPeriod() { m_period = (--m_period < 0) ? 0 : m_period; UpdatePeriod(); }
void wxGamePanel::IncPeriod() { m_period = (++m_period > 9) ? 9 : m_period; UpdatePeriod(); }