📄 timer_fixedtick.c
字号:
DVS_ON();
ChangeVoltage(ARM_INT_VDD, voltage_set);
g_oalIoCtlClockSpeed = S3C2450_HCLK;
CurrentState = SlowActive;
// RETAILMSG(1, (TEXT("-S-")));
}
else if ( CurrentState == SlowActive && ++SlowCount >= 1)
{
HCLK_DOWNTO_PCLK();
g_oalIoCtlClockSpeed = S3C2450_PCLK;
if ( GetCurrentVoltage(ARM_VDD) == 0 ){
RETAILMSG(1,(TEXT("Cannot get current voltage. State Freezing\n")));
return;
}
if ( GetCurrentVoltage(ARM_VDD) == MIDVOLTAGE ){
int voltage_set[2] = LOW_V_SET;
ChangeVoltage(ARM_INT_VDD, voltage_set);
// RETAILMSG(1, (TEXT("L")));
}
CurrentState = LazyActive;
RETAILMSG(0, (TEXT("-L-")));
}
}
}
}
#endif // DVS_EN
//------------------------------------------------------------------------------
//
// Function: OALTimerIntrHandler
//
// This function implement timer interrupt handler. It is called from common
// ARM interrupt handler.
//
UINT32 OALTimerIntrHandler()
{
UINT32 sysIntr = SYSINTR_NOP;
#if (BSP_TYPE == BSP_SMDK2443)
#if 1// for WFI
OUTREG32(&g_pIntrRegs->SRCPND, 1 << IRQ_TIMER4);
OUTREG32(&g_pIntrRegs->INTPND, 1 << IRQ_TIMER4);
#endif
#elif (BSP_TYPE == BSP_SMDK2450)
static DWORD HeartBeatCnt, HeartBeatStat; //LED4 is used for heart beat
// Clear the interrupt
OUTREG32(&g_pIntrRegs->SRCPND1, 1 << IRQFORTIMER);
OUTREG32(&g_pIntrRegs->INTPND1, 1 << IRQFORTIMER);
#ifndef DVS_EN
if (++HeartBeatCnt > 100)
{
HeartBeatCnt = 0;
HeartBeatStat ^= 1;
g_pPortRegs->GPCCON = (g_pPortRegs->GPCCON & ~(3<<14)) | (1<<14);
if (HeartBeatStat)
{
g_pPortRegs->GPCDAT &= ~(1<<7); // LED 4 Off
}
else
{
g_pPortRegs->GPCDAT |= (1<<7); // LED 4 On
}
}
#endif
#endif
// Update high resolution counter
g_oalTimer.curCounts += g_oalTimer.countsPerSysTick;
// Update the millisecond counter
CurMSec += g_oalTimer.msecPerSysTick;
// 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
#ifdef DVS_EN
ChangeSystemStateDVS();
#endif
return sysIntr;
}
//------------------------------------------------------------------------------
//
// Function: OALTimerCountsSinceSysTick
//
// This function return count of hi res ticks since system tick.
//
// Timer 4 counts down, so we should substract actual value from
// system tick period.
//
INT32 OALTimerCountsSinceSysTick()
{
return (g_oalTimer.countsPerSysTick - INREG32(&g_pPWMRegs->TCNTO4));
}
//------------------------------------------------------------------------------
//
// Function: OALTimerUpdate
//
// This function is called to change length of actual system timer period.
// If end of actual period is closer than margin period isn't changed (so
// original period elapse). Function returns time which already expires
// in new period length units. If end of new period is closer to actual time
// than margin period end is shifted by margin (but next period should fix
// this shift - this is reason why OALTimerRecharge doesn't read back
// compare register and it uses saved value instead).
//
UINT32 OALTimerUpdate(UINT32 period, UINT32 margin)
{
#if (BSP_TYPE == BSP_SMDK2443)
UINT32 tcon, ret;
ret = OALTimerCountsSinceSysTick();
OUTREG32(&g_pPWMRegs->TCNTB4, period);
tcon = INREG32(&g_pPWMRegs->TCON) & ~(0x0F << 20);
OUTREG32(&g_pPWMRegs->TCON, tcon | (0x2 << 20) );
OUTREG32(&g_pPWMRegs->TCON, tcon | (0x5 << 20) );
return (ret);
#elif (BSP_TYPE == BSP_SMDK2450)
#if 0 // Fixed Tick do not Update TImer
UINT32 tcon, ret;
ret = OALTimerCountsSinceSysTick();
OUTREG32(&g_pPWMRegs->TCNTB4, period);
tcon = INREG32(&g_pPWMRegs->TCON) & ~(0x0F << 20);
OUTREG32(&g_pPWMRegs->TCON, tcon | (0x2 << 20) );
OUTREG32(&g_pPWMRegs->TCON, tcon | (0x5 << 20) );
return (ret);
#else
return 0;
#endif
#endif
}
//------------------------------------------------------------------------------
//
// Function: OEMIdle
//
// This Idle function implements a busy idle. It is intend to be used only
// in development (when CPU doesn't support idle mode it is better to stub
// OEMIdle function instead use this busy loop). The busy wait is cleared by
// an interrupt from interrupt handler setting the g_oalLastSysIntr.
//
//
void OEMIdle(DWORD idleParam)
{
UINT32 baseMSec;
INT32 usedCounts, idleCounts;
ULARGE_INTEGER idle;
// Get current system timer counter
baseMSec = CurMSec;
// Find how many hi-res ticks was already used
usedCounts = OALTimerCountsSinceSysTick();
if (usedCounts == g_oalTimer.countsPerSysTick)
{
return;
}
// We should wait this time
idleCounts = g_oalTimer.actualCountsPerSysTick;
// Move SoC/CPU to idle mode
OALCPUIdle();
// When there wasn't timer interrupt modify idle time
if (CurMSec == baseMSec) {
idleCounts = OALTimerCountsSinceSysTick();
}
// Get real idle value. If result is negative we didn't idle at all.
idleCounts -= usedCounts;
if (idleCounts < 0) idleCounts = 0;
// Update idle counters
idle.LowPart = curridlelow;
idle.HighPart = curridlehigh;
idle.QuadPart += idleCounts;
curridlelow = idle.LowPart;
curridlehigh = idle.HighPart;
#ifdef DVS_EN
dwCurrentidle = (DWORD)(idle.QuadPart/idleconv);
#endif
}
//------------------------------------------------------------------------------
//
// Function: OALCPUIdle
//
// This Idle function implements a busy idle. It is intend to be used only
// in development (when CPU doesn't support idle mode it is better to stub
// OEMIdle function instead use this busy loop). The busy wait is cleared by
// an interrupt from interrupt handler setting the g_oalLastSysIntr.
//
//
VOID OALCPUIdle()
{
#if (BSP_TYPE == BSP_SMDK2443)
volatile S3C2450_CLKPWR_REG *s2450CLKPWR = (S3C2450_CLKPWR_REG *)OALPAtoVA(S3C2450_BASE_REG_PA_CLOCK_POWER, FALSE);
volatile S3C2450_INTR_REG *s2450INTR = (S3C2450_INTR_REG *)OALPAtoVA(S3C2450_BASE_REG_PA_INTR, FALSE);
volatile S3C2450_IOPORT_REG *s2450IOPORT = (S3C2450_IOPORT_REG *)OALPAtoVA(S3C2450_BASE_REG_PA_IOPORT, FALSE);
UINT32 sysIntr;
s2450IOPORT->GPFDAT |= ( 1<< 5); // GPF5 output data, turn LED on
s2450CLKPWR->PWRMODE |= (1 << 17);
MMU_WaitForInterrupt();
s2450CLKPWR->PWRMODE &= ~(1 << 17);
s2450IOPORT->GPFDAT &= ~(1 << 5); // GPF5 output data, turn LED off
if(g_pIntrRegs->SRCPND & (1<< IRQ_TIMER4))
sysIntr = OALTimerIntrHandler();
#elif (BSP_TYPE == BSP_SMDK2450)
#ifndef DVS_EN
g_pPortRegs->GPCCON &= ~(3<< 0);
g_pPortRegs->GPCCON |= ( 1<< 0);
g_pPortRegs->GPCDAT |= ( 1<< 0);
#endif
// g_pClkpwrRegs->PWRCFG = g_pClkpwrRegs->PWRCFG&~(0x3<<0)|(0x1<<0);
// g_pClkpwrRegs->PWRCFG |= (1<<17);
// g_pClkpwrRegs->PWRCFG &=~(0x3<<5);
g_pClkpwrRegs->PWRMODE |= (1 << 17);
MMU_WaitForInterrupt();
g_pClkpwrRegs->PWRMODE &= ~(1 << 17);
if((g_pIntrRegs->SRCPND1 & (1<<IRQFORTIMER)) != 0)
{
OALTimerIntrHandler();
}
#ifndef DVS_EN
g_pPortRegs->GPCDAT &= ~(1 << 0);
#endif
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -