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

📄 timer_fixedtick.c

📁 SMDK2416_BSP
💻 C
📖 第 1 页 / 共 2 页
字号:
				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 + -