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

📄 power.c

📁 Windows CE 6.0 针对PXA270的开发板的BSP参考代码
💻 C
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// Use of this sample source code is subject to the terms of the Microsoft
// license agreement under which you licensed this sample source code. If
// you did not accept the terms of the license agreement, you are not
// authorized to use this sample source code. For the terms of the license,
// please see the license agreement between you and Microsoft or, if applicable,
// see the LICENSE.RTF on your install media or the root of your tools installation.
// THE SAMPLE SOURCE CODE IS PROVIDED "AS IS", WITH NO WARRANTIES.
//
//------------------------------------------------------------------------------
//
//  File:  power.c
//
//  Power BSP callback functions implementation. 
//
#include <bsp.h>
#include <intr_fpga.h>

//Local functions
//
void BSPSetWakeSrc(PBULVERDE_PWER_REGBITS pPwer, int irq);
BOOL BSPGetWakeSrc(PBULVERDE_PEDR_REGBITS pPedr, UINT32* pSrcIrq);

//Module level vars
//
static volatile UINT32 g_BLRegs_intmskena_savedval = 0;
static volatile UINT32 g_BLRegs_intsetclr_savedval = 0;
static volatile MAINSTONEII_BLR_REGS *g_pBLRegs = NULL;
static volatile BULVERDE_GPIO_REG    *g_pGPIORegs = NULL;

//------------------------------------------------------------------------------
//
// Function:     BSPPowerOffInit
//
// Description:  This function is called during OEMInit to set registers for suspend/resume functionality.
//
VOID BSPPowerOffInit()
{
    PBULVERDE_PWRRST_REG   pPwrRst_reg = (PBULVERDE_PWRRST_REG) OALPAtoUA(BULVERDE_BASE_REG_PA_PWR);
    UINT32 dummyRead;
    UINT32 rtcSysIntr = SYSINTR_RTC_ALARM;

    g_pBLRegs   = (volatile MAINSTONEII_BLR_REGS *) OALPAtoVA(MAINSTONEII_BASE_REG_PA_FPGA, FALSE);
    g_pGPIORegs = (volatile BULVERDE_GPIO_REG*) OALPAtoUA(BULVERDE_BASE_REG_PA_GPIO);

    // set wake up sources keybd control register (PKWR)
    //
    //disable all
    OUTREG32(&pPwrRst_reg->pkwr, 0x0);
    dummyRead = INREG32(&pPwrRst_reg->pkwr);  //read to make sure values are latched

    // enable rising edge and/or falling edge GPIO detects
    // otherwise GPIO edge detects will not resume the device
    // (GPIO1 is tied to SW21 on Mainstone II board. This switch is
    // used as the suspend/resume power button (see pwrbutton driver))
    
    // enable all rising edge detects, disable GPIO1 (pwrbutton) rising edge detect
    OUTREG32(&pPwrRst_reg->prer, (~(PRER_REG_RSVD_BITS) & ~0x00000002));
    dummyRead = INREG32(&pPwrRst_reg->prer);                                        

    // disable all falling edge detects, enable GPIO1 (pwrbutton) falling edge detect
    OUTREG32(&pPwrRst_reg->pfer, (~(PFER_REG_RSVD_BITS) & 0x00000002));
    dummyRead = INREG32(&pPwrRst_reg->pfer);

    // enable wake up from RTC alarm on sleep/suspend
    OALIoCtlHalEnableWake(IOCTL_HAL_ENABLE_WAKE, &rtcSysIntr, sizeof(rtcSysIntr), NULL, 0, NULL);
    
}

//------------------------------------------------------------------------------
//
// Function:     BSPPowerOff
//
// Description:  This function is called as the last function before calling the XLLP layer
// to save the context and put the CPU in low power mode.
//
VOID BSPPowerOff()
{
    UINT32 *pIrqs, i, count, sysIntr;
    UINT32 dummyRead;
    UINT32 pwerVal = 0;
    PBULVERDE_PWER_REGBITS  pwerBits    = (PBULVERDE_PWER_REGBITS) &pwerVal;
    PBULVERDE_PWRRST_REG    pPwrRst_reg = (PBULVERDE_PWRRST_REG) OALPAtoUA(BULVERDE_BASE_REG_PA_PWR);
    

    // In low power mode (sleep/deep-sleep) drive same levels on GPIO outputs as current levels.
    // Note: Need to set everytime as PGSRx registers are set to 0 on each reset.
    //
    pPwrRst_reg->pgsr0  = g_pGPIORegs->GPLR0 & ~PGSR0_REG_RSVD_BITS;
    pPwrRst_reg->pgsr1  = g_pGPIORegs->GPLR1 & ~PGSR1_REG_RSVD_BITS;
    pPwrRst_reg->pgsr2  = g_pGPIORegs->GPLR2 & ~PGSR2_REG_RSVD_BITS;
    pPwrRst_reg->pgsr3  = g_pGPIORegs->GPLR3 & ~PGSR3_REG_RSVD_BITS;

    // Save off FPGA interrupt controller mask and clear it.
    // BSPSetWakeSrc will set it up with wake up source mask.
    //
    g_BLRegs_intmskena_savedval = (INREG32((PULONG)&g_pBLRegs->int_msk_en)) & ~INTMSK_RESERVED_BITS;
    OUTREG32((PULONG)&g_pBLRegs->int_msk_en,  0);

    // Save off pending FPGA interrupts and clear the reg.
    //
    g_BLRegs_intsetclr_savedval = (INREG32((PULONG)&g_pBLRegs->int_set_clr)) & ~INTSETCLR_RESERVED_BITS;
    OUTREG32((PULONG)&g_pBLRegs->int_set_clr,  0);
    
    // Set wake up sources
    //
    for (sysIntr = SYSINTR_DEVICES; sysIntr < SYSINTR_MAXIMUM; sysIntr++) {
        if (!OALPowerWakeSource(sysIntr))
            continue;                                               // Skip if sysIntr isn't allowed as wake source
        if (!OALIntrTranslateSysIntr(sysIntr, &count, &pIrqs))
            continue;                                                // Get IRQs
        for (i = 0; i < count; i++) {                              // Hardware supports only restricted number of sources
            BSPSetWakeSrc(pwerBits, pIrqs[i]);
        }
    }

    // set wake up sources register (PWER)
    OUTREG32(&pPwrRst_reg->pwer, pwerVal);
    dummyRead = INREG32(&pPwrRst_reg->pwer);

}    

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

VOID BSPPowerOn()
{
    UINT32 wakesrc, srcIrq;
    PBULVERDE_PWRRST_REG  pPwrRst_reg = (PBULVERDE_PWRRST_REG) OALPAtoUA(BULVERDE_BASE_REG_PA_PWR);

    // find wake up source
    //
    wakesrc = INREG32(&pPwrRst_reg->pedr);
    wakesrc &= ~PEDR_REG_RSVD_BITS;
    if (BSPGetWakeSrc((PBULVERDE_PEDR_REGBITS)&wakesrc, &srcIrq))
        g_oalWakeSource = OALIntrTranslateIrq(srcIrq);

    // clear wake up source status register (PEDR)
    OUTREG32(&pPwrRst_reg->pedr, wakesrc );

    // Restore the FPGA interrupt controller.
    //

    // 1.  Disable all FPGA interrupts (disable FPGA GPIO0 assertion to Bulverde).
    OUTREG32((PULONG)&g_pBLRegs->int_msk_en,  0);

    // 2.  Clear the Bulverde GPIO0 edge detection.
    OUTREG32((PULONG)&g_pGPIORegs->GEDR0, XLLP_GPIO_BIT_0);

    // 3.  Wait...
    OALStall(1);

    // 4.  Restore FPGA pending interrupts from before device was suspended.
    //     Note: this adds pending interrupts from pre-suspend state to any 
    //     other interrupts that might have been fired during suspend state.
    OUTREG32((PULONG)&g_pBLRegs->int_set_clr,
        ((INREG32((PULONG)&g_pBLRegs->int_set_clr)) & ~INTSETCLR_RESERVED_BITS) | g_BLRegs_intsetclr_savedval);

    // 5.  Restore the FPGA mask (this will cause any pending interrupts to assert
    //     to the Bulverde).
    OUTREG32((PULONG)&g_pBLRegs->int_msk_en,  g_BLRegs_intmskena_savedval);
}       

//------------------------------------------------------------------------------
//
// Function:     BSPSetWakeSrc
//
// Description:  called to set wake-up sources. 
//
void BSPSetWakeSrc(PBULVERDE_PWER_REGBITS pPwer, int irq)
{
    //ignore undefined IRQ
    if (irq == OAL_INTR_IRQ_UNDEFINED)
        return;
    
    switch(irq) {
        case IRQ_RTCALARM:
            pPwer->rtc_alarm = 1;
            break;
        case IRQ_GPIO1:
            pPwer->gpio1 = 1;
            break;
        case IRQ_GPIO0:
            pPwer->gpio0 = 1;
            break;
        default:
            // Handle FPGA interrupts
            //
            if (irq >= IRQ_MAINSTONEII_GPIO0_MIN && irq <= IRQ_MAINSTONEII_GPIO0_MAX)
            {
                // Unmask the corresponding FPGA interrupt bit
                UINT32 TempVal = (INREG32((PULONG)&g_pBLRegs->int_msk_en) & ~INTMSK_RESERVED_BITS);
                OUTREG32((PULONG)&g_pBLRegs->int_msk_en, (TempVal | FPGA_INT_BIT(irq)));

                //Enable GPIO0 interrupt as all FPGA interrupts appear at GPIO0
                pPwer->gpio0 = 1;

                break;
            }
            OALMSG(OAL_WARN, (
                L"BSPSetWakeSrc: IRQ %d not supported as wake up source\r\n", irq
            ));
    }
}


//------------------------------------------------------------------------------
//
// Function:     BSPGetWakeSrc
//
// Description:  called to get the wake-up source.
//
BOOL BSPGetWakeSrc(PBULVERDE_PEDR_REGBITS pPedr, UINT32* pSrcIrq)
{
    if (pPedr->rtc_alarm)
        *pSrcIrq = IRQ_RTCALARM;
    else if (pPedr->gpio1)
        *pSrcIrq = IRQ_GPIO1;
    else if (pPedr->gpio0)
        {
            // Handle FPGA interrupts.
            // Bulverde says GPIO0 caused wake-up. Since all
            // FPGA interrupts are tied to GPIO0 determine
            // which FPGA interrupt caused the wake-up.
            //
            
            UINT8  nInt;
            UINT32 TempVal;

            // Read the pending FPGA interrupts and ignore masked/reserved interrupts.
            TempVal  = INREG32((PULONG)&g_pBLRegs->int_set_clr);
            TempVal &= (INREG32((PULONG)&g_pBLRegs->int_msk_en) & ~INTMSK_RESERVED_BITS);

            // Scan through the pending interrupts and look for a match.
            for (nInt = IRQ_MAINSTONEII_GPIO0_MIN ; nInt <= IRQ_MAINSTONEII_GPIO0_MAX ; nInt++)
            {
                if (TempVal & FPGA_INT_BIT(nInt))
                {
                    *pSrcIrq = nInt;
                    break;
                }
            }
        }
    else
        return 0;           //no match found

    return 1;                // match found
}

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

⌨️ 快捷键说明

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