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

📄 power.c

📁 Windows CE 6.0 BSP for VOIPAC Board (PXA270) Version 2b.
💻 C
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this source code is subject to the terms of the Microsoft end-user
// license agreement (EULA) under which you licensed this SOFTWARE PRODUCT.
// If you did not accept the terms of the EULA, you are not authorized to use
// this source code. For a copy of the EULA, please see the LICENSE.RTF on your
// install media.
//
//------------------------------------------------------------------------------
//
//  File:  power.c
//
#include <windows.h>
#include <nkintr.h>
#include <oal.h>
#include <omap730.h>

//------------------------------------------------------------------------------
//  External functions

BOOL OALIntrIsIrqPending(UINT32 irq);

//------------------------------------------------------------------------------
//
//  Function:  OEMInterruptPending
//
//  This function returns true when given sysIntr interrupt is pending.
//
BOOL OEMInterruptPending(DWORD sysIntr)
{
    BOOL pending = FALSE;
    const UINT32 *pIrqs;
    UINT32 ix, count;

    OALMSG(OAL_INTR&&OAL_VERBOSE, (
        L"+OEMInterruptPending(%d)\r\n", sysIntr
    ));

    if (OALIntrTranslateSysIntr(sysIntr, &count, &pIrqs)) {
        for (ix = 0; ix < count; ix++ && !pending) {
            pending = OALIntrIsIrqPending(pIrqs[ix]);
        }            
    }

    OALMSG(OAL_INTR&&OAL_VERBOSE, (
        L"-OEMInterruptPending(rc = %d)\r\n", pending
    ));
    return pending;
}

//------------------------------------------------------------------------------
//
//  Function:  OEMPowerOff
//
//  Called when the system is to transition to it's lowest power mode (off).
//
void OEMPowerOff(void)
{
    OMAP730_INTC_REGS *pIntcL1Regs = OALPAtoUA(OMAP730_INTC_L1_REGS_PA);
    OMAP730_INTC_REGS *pIntcL2ARegs = OALPAtoUA(OMAP730_INTC_L2A_REGS_PA);
    OMAP730_INTC_REGS *pIntcL2BRegs = OALPAtoUA(OMAP730_INTC_L2B_REGS_PA);
    OMAP730_GPIO_REGS *pGPIO1Regs = OALPAtoUA(OMAP730_GPIO1_REGS_PA);
    OMAP730_GPIO_REGS *pGPIO2Regs = OALPAtoUA(OMAP730_GPIO2_REGS_PA);
    OMAP730_GPIO_REGS *pGPIO3Regs = OALPAtoUA(OMAP730_GPIO3_REGS_PA);
    OMAP730_GPIO_REGS *pGPIO4Regs = OALPAtoUA(OMAP730_GPIO4_REGS_PA);
    OMAP730_GPIO_REGS *pGPIO5Regs = OALPAtoUA(OMAP730_GPIO5_REGS_PA);
    OMAP730_GPIO_REGS *pGPIO6Regs = OALPAtoUA(OMAP730_GPIO6_REGS_PA);
    OMAP730_ULPD_REGS *pULPDRegs = OALPAtoUA(OMAP730_ULPD_REGS_PA);
    OMAP730_ICR_REGS  *pICRRegs = OALPAtoUA(OMAP730_ICR_REGS_PA);
    UINT32 intcL1, intcL2A, intcL2B;
    UINT32 gpio1, gpio2, gpio3, gpio4, gpio5, gpio6;
    UINT32 sysIntr;
    BOOL fullOff = TRUE;
    

    // Make sure that KITL is powered off
    OALKitlPowerOff();

    // Give chance to do board specific stuff
    BSPPowerOff();

    // Save existing interrupt masks
    intcL1 = INREG32(&pIntcL1Regs->MIR);
    intcL2A = INREG32(&pIntcL2ARegs->MIR); 
    intcL2B = INREG32(&pIntcL2BRegs->MIR); 
    gpio1 = INREG32(&pGPIO1Regs->INTMASK);
    gpio2 = INREG32(&pGPIO2Regs->INTMASK);
    gpio3 = INREG32(&pGPIO3Regs->INTMASK);
    gpio4 = INREG32(&pGPIO4Regs->INTMASK);
    gpio5 = INREG32(&pGPIO5Regs->INTMASK);
    gpio6 = INREG32(&pGPIO6Regs->INTMASK);

    // Disable most interrupts (left IRQ_L2FIQ/IRQ_L2IRQ enabled)
    OUTREG32(&pIntcL1Regs->MIR, 0xFFFFFFFC);
    OUTREG32(&pIntcL2ARegs->MIR, 0xFFFFFFFF);
    OUTREG32(&pIntcL2BRegs->MIR, 0xFFFFFFFF);
    OUTREG32(&pGPIO1Regs->INTMASK, 0xFFFFFFFF);
    OUTREG32(&pGPIO2Regs->INTMASK, 0xFFFFFFFF);
    OUTREG32(&pGPIO3Regs->INTMASK, 0xFFFFFFFF);
    OUTREG32(&pGPIO4Regs->INTMASK, 0xFFFFFFFF);
    OUTREG32(&pGPIO5Regs->INTMASK, 0xFFFFFFFF);
    OUTREG32(&pGPIO6Regs->INTMASK, 0xFFFFFFFF);

    // Enable wake sources interrupts
    for (sysIntr = SYSINTR_FIRMWARE; sysIntr < SYSINTR_MAXIMUM; sysIntr++) {
        // Skip if sysIntr isn't allowed as wake source
        if (!OALPowerWakeSource(sysIntr)) continue;
        // Enable it as interrupt
        OEMInterruptEnable(sysIntr, NULL, 0);
        // There is wakeup source, don't do full power off
        fullOff = FALSE;
    }

    // Enable deep sleep
    SETREG16(&pULPDRegs->POWER_CTRL, POWER_CTRL_DEEP_SLEEP_EN);

    // If we should do full off
    if (fullOff) {
        // Disable interrupt from GSM
        CLRREG16(
            &pICRRegs->MCTL, OMAP730_ICR_MCTL_M_INTEN|OMAP730_ICR_MCTL_G_INTEN
        );
        // Let GSM subsystem power off all...
        OUTREG16(&pICRRegs->MFLAGS, 2);
        // We should not be there for long time...
        while (TRUE);
    }        

    // Move SoC/CPU to idle mode, there is no special power-off
    // mode on OMAP730 (but deep sleep is very similar to it)
    OALCPUIdle();

    // Find wakeup source
    for (sysIntr = SYSINTR_FIRMWARE; sysIntr < SYSINTR_MAXIMUM; sysIntr++) {
        // Skip if sysIntr isn't allowed as wake source
        if (!OALPowerWakeSource(sysIntr)) continue;
        // When this sysIntr is pending we find wake source
        if (OEMInterruptPending(sysIntr)) {
            g_oalWakeSource = sysIntr;
            break;
        }
    }

    // Do board specific stuff    
    BSPPowerOn();

    // Reinitialize KITL
    OALKitlPowerOn();

    // Restore interrupt masks
    OUTREG32(&pIntcL1Regs->MIR, intcL1);
    OUTREG32(&pIntcL2ARegs->MIR, intcL2A);
    OUTREG32(&pIntcL2BRegs->MIR, intcL2B);
    OUTREG32(&pGPIO1Regs->INTMASK, gpio1);
    OUTREG32(&pGPIO2Regs->INTMASK, gpio2);
    OUTREG32(&pGPIO3Regs->INTMASK, gpio3);
    OUTREG32(&pGPIO4Regs->INTMASK, gpio4);
    OUTREG32(&pGPIO5Regs->INTMASK, gpio5);
    OUTREG32(&pGPIO6Regs->INTMASK, gpio6);
}

//------------------------------------------------------------------------------

⌨️ 快捷键说明

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