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

📄 idle.c

📁 CIRRUS 公司EP93XX系列CPU的WINCE下的BSP
💻 C
📖 第 1 页 / 共 2 页
字号:
    // because dwPartialCurMSec will be modified in the next function call.
    //
    CPUGetSysTimerCountElapsed(RESCHED_PERIOD, pCurMSec, &dwPartialCurMSec, pCurTicks);

    if ((int) (dwIdleMSec -= *pCurMSec - dwPrevMSec) > 0) {

        dwPrevMSec = *pCurMSec;

        //
        // The system timer may not be capable of arbitrary timeouts. Get the
        // CPU-specific highest possible timeout available.
        //
        dwIdleMSec = CPUGetSysTimerCountMax(dwIdleMSec);
    
        //
        // Set the timer to wake up much later than usual, if needed.
        //
        CPUSetSysTimerCount(dwIdleMSec);
        CPUClearSysTimerIRQ( );
        
        //
        // Enable wakeup on any interrupt, then go to sleep.
        //
        CPUEnterIdle(dwIdleParam);
        INTERRUPTS_OFF( );
        
        //
        // We're awake! The wake-up ISR (or any other ISR) has already run.
        //
        if (dwPrevMSec != *pCurMSec) {
            //
            // We completed the full period we asked to sleep.  Update the counters.
            //
            *pCurMSec  += (dwIdleMSec - RESCHED_PERIOD); // Subtract resched period, because ISR also incremented.
            CurTicks.QuadPart += (dwIdleMSec - RESCHED_PERIOD) * dwReschedIncrement;

            currIdle.QuadPart += dwIdleMSec;
        } else {
            //
            // Some other interrupt woke us up before the full idle period was
            // complete.  Determine how much time has elapsed.
            //
            currIdle.QuadPart += CPUGetSysTimerCountElapsed(dwIdleMSec, pCurMSec, &dwPartialCurMSec, pCurTicks);
        }
    }

    // Re-arm counters
    CPUSetSysTimerCount(RESCHED_PERIOD);
    CPUClearSysTimerIRQ( );

    // Update global idle time
    curridlelow = currIdle.LowPart;
    curridlehigh = currIdle.HighPart;

    return;
}
#endif  // CE_MAJOR_VER == 0x0003

//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
//
// SC_GetTickCount must take into account the partials to reflect where we really
// are in time AND IT SHOULD NOT MODIFY ANY OF THE GLOBALS.
//
DWORD SC_GetTickCount(void) 
{
#if (CE_MAJOR_VER == 0x0003)
    return *pCurMSec;
#else
    DWORD dwInc = 0, dwPartial = dwPartialCurMSec, dwPrev = *pCurMSec;
    ULARGE_INTEGER cdummy = {0, 0};
    CPUGetSysTimerCountElapsed(RESCHED_PERIOD, &dwInc, &dwPartial, &cdummy);
    return (dwPrev == *pCurMSec)? dwPrev + dwInc : *pCurMSec;
#endif
}

//****************************************************************************
// OEMPowerOff
//****************************************************************************
// Power management stuff.
// 
//
VOID OEMPowerOff(void)
{
    volatile ULONG      ulTemp;
    ULONG               ulCscPwrCnt, ulCscDevCfg;

    //
    // Print out the current clock rates to the debug port.
    //
    NKDbgPrintfW( L"OEMPowerOff\r\n" );
    
    INTERRUPTS_OFF();

    //
    // Replace the interrupt mask with the wake event interrupt mask.  These
    // will be the only interrupts that can wake us from suspend.
    //
    *VIC1_INTCLEAR  = 0xFFFFFFFF;
    *VIC2_INTCLEAR  = 0xFFFFFFFF;

    *VIC1_INTENABLE = gdwInterruptWakeMask1 | INT1_TIMER1;
    *VIC2_INTENABLE = gdwInterruptWakeMask2;

    //
    // Check to see if there is a kitl connection.  If so then 
    // keep the clocks on.
    //
    if(!gulCS8950KitlUsed)
    {
        //
        // Power down the system clocks here.
        //
        ulCscPwrCnt                     = *CSC_PWRCNT;
        ulCscDevCfg                     = *CSC_DEVCFG;

        //
        // Power down the clocks as much as possible.
        //
        *CSC_SYSLOCK                    = 0xAA;
        *CSC_PWRCNT                     = 0;

        *CSC_SYSLOCK                    = 0xAA;
        *CSC_DEVCFG                     = (ulCscDevCfg & 
                                          ~(DEVCFG_KEYS | DEVCFG_ADCPD | DEVCFG_RAS  |
                                            DEVCFG_TIN  | DEVCFG_U1EN  | DEVCFG_U2EN |
                                            DEVCFG_U3EN)) | DEVCFG_SHENA;

        *CSC_SYSLOCK                    = 0xAA;
        *CSC_CLKSET2                    = CLKSET2_VALUE & ~( CLKSET2_PLL2_EN | CLKSET2_PLL2_NBYP);

        *SDRAM_REFRESH                  = SDRAM_14MHZ_REFRESH_VALUE;


        *CSC_SYSLOCK                    = 0xAA;
        *CSC_CLKSET1                    = CLKSET1_VALUE & ~CLKSET1_PLL1_NBYP;

        //
        // Flush the pipeline.
        //    
        __emit(0xe1a00000);
        __emit(0xe1a00000);
        __emit(0xe1a00000);
        __emit(0xe1a00000);
        __emit(0xe1a00000);
        __emit(0xe1a00000);
    }


    gfResumeFlag = FALSE;

    INTERRUPTS_ON();

	dwTimeValueWhenSuspend=*TIM_DEBUGVALUELOW;

    while(!gfResumeFlag)
    {

        if(gulCS8950KitlUsed)
        {
            CPUEnterIdle(0);
        }
        else
        {
            ulTemp = *CSC_HALT;
        }
    }

    INTERRUPTS_OFF();

    //
    // Check to see if there is a kitl connection.  If so then 
    // keep the clocks on.
    //
    if(!gulCS8950KitlUsed)
    {
        //
        // Power down the system clocks here.
        //
        *CSC_SYSLOCK                    = 0xAA;
        *CSC_CLKSET1                    = CLKSET1_VALUE;

        //
        // Flush the pipeline.
        //    
        __emit(0xe1a00000);
        __emit(0xe1a00000);
        __emit(0xe1a00000);
        __emit(0xe1a00000);
        __emit(0xe1a00000);
        __emit(0xe1a00000);

        *SDRAM_REFRESH                  = SDRAM_REFRESH_VALUE;


        *CSC_SYSLOCK                    = 0xAA;
        *CSC_CLKSET2                    = CLKSET2_VALUE;
                                          
        *CSC_SYSLOCK                    = 0xAA;
        *CSC_DEVCFG                     = ulCscDevCfg;

        *CSC_SYSLOCK                    = 0xAA;
        *CSC_PWRCNT                     = ulCscPwrCnt;
    }

    //
    // Restore the original interupt mask.
    //
    *VIC1_INTCLEAR  = 0xFFFFFFFF;
    *VIC2_INTCLEAR  = 0xFFFFFFFF;
    *VIC1_INTENABLE = gdwInterruptMask1 | INT1_TIMER1;
    *VIC2_INTENABLE = gdwInterruptMask2;

    INTERRUPTS_ON();
}



//****************************************************************************
// OEMPowerManagerInit
//****************************************************************************
// Power Managment Initialization routine.
// 
//
DWORD OEMPowerManagerInit(void)
{
    int ulInt;
    for(ulInt = 0; ulInt < SYSINTR_MAXIMUM ; ulInt++)
    {
        gfSysIntrWakeupMask[ ulInt ]  = 0;
    }

    //
    // Clear the interrupt wake mask
    //
    gdwInterruptWakeMask1   = 0 ; 
    gdwInterruptWakeMask2   = 0 ;

    return 1;
}

//****************************************************************************
// OEMSetWakeupSource
//****************************************************************************
// This sets the source for the wakeup interrupt.
// 
//
DWORD OEMSetWakeupSource( DWORD dwSources)
{
    DWORD   dwIntMask1, dwIntMask2;
  
    NKDbgPrintfW( L"OEMSetWakeupSource dwSource = 0x%x\r\n",dwSources );
    if(dwSources <SYSINTR_MAXIMUM)
    {
        //
        // OEMTranslateSysIntr currently returns the passed value.
        //
        // DWORD dwPhysInt = OEMTranslateSysIntr(dwSources);

        gfSysIntrWakeupMask[dwSources] = 1;

        SysIntrNumToInterruptMask(dwSources, &dwIntMask1, &dwIntMask2);
        gdwInterruptWakeMask1 |= dwIntMask1;
        gdwInterruptWakeMask2 |= dwIntMask2;
        return 1;
    }
    return 0;
}

//****************************************************************************
// OEMResetWakeupSource
//****************************************************************************
// This clears the specified wakeup interrupt.
// 
//
DWORD OEMResetWakeupSource( DWORD dwSources)
{
    DWORD   dwIntMask1, dwIntMask2;

    NKDbgPrintfW( L"OEMResetWakeupSource dwSource = 0x%x\r\n",dwSources );
    if(dwSources < SYSINTR_MAXIMUM)
    {
        //
        // OEMTranslateSysIntr just returns the passed value.
        //
        //DWORD physInt = OEMTranslateSysIntr(dwSources);

        gfSysIntrWakeupMask[dwSources] = 0;

        SysIntrNumToInterruptMask(dwSources, &dwIntMask1, &dwIntMask2);
        gdwInterruptWakeMask1 &= ~dwIntMask1;
        gdwInterruptWakeMask2 &= ~dwIntMask2;
        return 1;
    }
    return 0;
}

//****************************************************************************
// OEMClearIntSources
//****************************************************************************
// I am going to assume there is only one interrupt in the queue
// when the system wakes up from an interrupt.
// 
//
void OEMClearIntSources( )
{
    NKDbgPrintfW( L"OEMClearIntSources.\r\n");
    gfResumeFlag = FALSE;
}

//****************************************************************************
// OEMGetWakeupSource
//****************************************************************************
// Gets the last interrupt that woke up the system.
// 
//
DWORD OEMGetWakeupSource(void)
{
    NKDbgPrintfW( L"OEMGetWakeupSource.\r\n");
    return gdwLastWakeupSource;
}



⌨️ 快捷键说明

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