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

📄 power.c

📁 Microsoft WinCE 6.0 BSP FINAL release source code for use with the i.MX27ADS TO2 WCE600_FINAL_MX27_S
💻 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.
//
// NOTE: stubs are being used - this isn't done
//
//------------------------------------------------------------------------------
//
// Copyright (C) 2004-2006, Freescale Semiconductor, Inc. All Rights Reserved.
// THIS SOURCE CODE, AND ITS USE AND DISTRIBUTION, IS SUBJECT TO THE TERMS
// AND CONDITIONS OF THE APPLICABLE LICENSE AGREEMENT
//
//------------------------------------------------------------------------------
//
//  File:  off.c
//
//  This file provides the capabilities to suspend the system and controlling
//  wake sources.
//
//------------------------------------------------------------------------------

#include <windows.h>
#include <ceddk.h>
#include <nkintr.h>
#include <cmnintrin.h>
#include <oal.h>
#include "csp.h"

//------------------------------------------------------------------------------
// External Functions
//------------------------------------------------------------------------------


//------------------------------------------------------------------------------
// External Variables
//------------------------------------------------------------------------------
extern PCSP_AITC_REGS g_pAITC;
extern PCSP_PLLCRC_REGS g_pPLLCRC;
extern PCSP_GPIO_REGS g_pGPIO;
//extern BOOL g_bBSPIrq;

//------------------------------------------------------------------------------
// Defines
//------------------------------------------------------------------------------
VOID OALClockSetGatingMode(DDK_CLOCK_GATE_INDEX index, 
    DDK_CLOCK_GATE_MODE mode);
//------------------------------------------------------------------------------
// Types
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Global Variables
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Local Variables
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
// Local Functions
//------------------------------------------------------------------------------


//-----------------------------------------------------------------------------
//
// Function: OEMPowerOff
//
// Called when the system is to transition to it's lowest power mode.  This
// function stores off some of the important registers (not really needed for
// DSM since registers will not lose state in DSM).
//
// Parameters:
//      None
//
// Returns:
//      None
//
//-----------------------------------------------------------------------------
VOID OEMPowerOff()
{
    UINT32 intEnableH;
    UINT32 intEnableL;
    UINT32 gpioimrstate[GPIO_PORT_MAX];
    UINT32 sysIntr;
    UINT32 irq;
    UINT32 line;
    GPIO_PORT port;
    BOOL PowerState;    

    // Let BSP do board specific stuff
    BSPPowerOff();    

    // Save state of enabled interrupts
    intEnableH = INREG32(&g_pAITC->INTENABLEH);
    intEnableL = INREG32(&g_pAITC->INTENABLEL);
    gpioimrstate[GPIO_PORT_A] = INREG32(&g_pGPIO->PORT[GPIO_PORT_A].IMR);
    gpioimrstate[GPIO_PORT_B] = INREG32(&g_pGPIO->PORT[GPIO_PORT_B].IMR);
    gpioimrstate[GPIO_PORT_C] = INREG32(&g_pGPIO->PORT[GPIO_PORT_C].IMR);
    gpioimrstate[GPIO_PORT_D] = INREG32(&g_pGPIO->PORT[GPIO_PORT_D].IMR);
    gpioimrstate[GPIO_PORT_E] = INREG32(&g_pGPIO->PORT[GPIO_PORT_E].IMR);
    gpioimrstate[GPIO_PORT_F] = INREG32(&g_pGPIO->PORT[GPIO_PORT_F].IMR);    
 
    // Disable all GPIO interrups 
    OUTREG32(&g_pGPIO->PORT[GPIO_PORT_A].IMR,0);
    OUTREG32(&g_pGPIO->PORT[GPIO_PORT_B].IMR,0);
    OUTREG32(&g_pGPIO->PORT[GPIO_PORT_C].IMR,0);
    OUTREG32(&g_pGPIO->PORT[GPIO_PORT_D].IMR,0);
    OUTREG32(&g_pGPIO->PORT[GPIO_PORT_E].IMR,0);	
    OUTREG32(&g_pGPIO->PORT[GPIO_PORT_F].IMR,0);	
	
    // Disable all 
    OUTREG32(&g_pAITC->INTENABLEH, 0);
    OUTREG32(&g_pAITC->INTENABLEL, 0);
  
    // Now enable interrupt if it was enabled as wakeup source    
    for(sysIntr = SYSINTR_DEVICES; 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);
    }
	
    // Switch off power for KITL device
    PowerState = FALSE;
    KITLIoctl(IOCTL_KITL_POWER_CALL, &PowerState, sizeof(PowerState), NULL, 0, NULL);
   
    // Disable MPLL. When the conditions are satisfied, 
    // the MPLL will be turned off, and this action also
    // automatically turns off the SPLL. We don't need
    // to disable clocks to all modules by clearing PCCR0 
    // and PCCR1 in CRM module.     
    g_pPLLCRC->CSCR &= ~(CSP_BITFMASK(PLLCRC_CSCR_MPEN));

    // Finally power off CPU
    OALCPUPowerOff();

    // Find wakeup source
    irq = (UINT32)EXTREG32BF(&g_pAITC->NIVECSR, AITC_NIVECSR_NIVECTOR);
        
    if(irq == IRQ_GPIO)
    {        
        for(port = GPIO_PORT_A; port < GPIO_PORT_MAX; port++)
        {
            // detect GPIO line that is asserting interrupt
            line = _CountLeadingZeros(INREG32(&g_pGPIO->PORT[port].ISR) 
                                  & INREG32(&g_pGPIO->PORT[port].IMR)); 
            // If at least one GPIO interrupt line is asserted   
            if (line < 32)
            {
                line = 31 - line;
                irq = CSP_IRQ_GPIO_MIN + (port * 32 + line);
                break;
            }                          
        }            
        // Invalid GPIO interrupt
      //  if(irq == IRQ_GPIO)
       //     irq = OAL_INTR_IRQ_UNDEFINED;
    }
    
#if 0//#ifdef OAL_BSP_CALLBACKS
    // Give BSP chance to translate IRQ 
    irq = BSPIntrActiveIrq(irq);

    if(g_bBSPIrq) // If porcessed by BSP, We should clear the GPIO IRQ status
    {
         SETREG32(&g_pGPIO->PORT[port].ISR,(1 << line));
    }
#endif

    // When we find wakup source set global variable
    g_oalWakeSource = OALIntrTranslateIrq(irq);

    // Power on CPU
    OALCPUPowerOn();    

    // Switch on power for KITL device
    PowerState = TRUE;
    KITLIoctl (IOCTL_KITL_POWER_CALL, &PowerState, sizeof(PowerState), NULL, 0, NULL);

    // Then let BSP do board specific stuff
    BSPPowerOn();

    // Restore original interrupt masks
    OUTREG32(&g_pGPIO->PORT[GPIO_PORT_A].IMR, gpioimrstate[GPIO_PORT_A]);
    OUTREG32(&g_pGPIO->PORT[GPIO_PORT_B].IMR, gpioimrstate[GPIO_PORT_B]);
    OUTREG32(&g_pGPIO->PORT[GPIO_PORT_C].IMR, gpioimrstate[GPIO_PORT_C]);
    OUTREG32(&g_pGPIO->PORT[GPIO_PORT_D].IMR, gpioimrstate[GPIO_PORT_D]);
    OUTREG32(&g_pGPIO->PORT[GPIO_PORT_E].IMR, gpioimrstate[GPIO_PORT_E]);	
    OUTREG32(&g_pGPIO->PORT[GPIO_PORT_F].IMR, gpioimrstate[GPIO_PORT_F]);
    OUTREG32(&g_pAITC->INTENABLEH, intEnableH);
    OUTREG32(&g_pAITC->INTENABLEL, intEnableL);
}

//-----------------------------------------------------------------------------
//
//  Function: OALClockSetGatingMode
//
//  This function provides the OAL a safe mechanism for setting the clock 
//  gating mode of peripherals.
//
//  Parameters:
//      index
//           [in] Index for referencing the peripheral clock gating control 
//           bits.
//
//      mode
//           [in] Requested clock gating mode for the peripheral.
//
//  Returns:
//      None
//
//-----------------------------------------------------------------------------
VOID OALClockSetGatingMode(DDK_CLOCK_GATE_INDEX index, DDK_CLOCK_GATE_MODE mode)
{
    BOOL fEnable;
    REG32* pPCCR = &g_pPLLCRC->PCCR0;
    
    // CGR is a shared register so we must disable interrupts temporarily for
    // safe access
    if (mode)
    {
		fEnable = INTERRUPTS_ENABLE(FALSE);
	  	SETREG32(&pPCCR[CRM_PCCR_INDEX(index)], CRM_PCCR_VAL(index, 1));
		INTERRUPTS_ENABLE(fEnable);
    }
      else 
    {
		fEnable = INTERRUPTS_ENABLE(FALSE);
	  	CLRREG32(&pPCCR[CRM_PCCR_INDEX(index)], CRM_PCCR_VAL(index, 1));
		INTERRUPTS_ENABLE(fEnable);
    }	    
}



//-----------------------------------------------------------------------------
//
//  Function: OALClockEnableIIM
//
//  This function enables/disables module clocks for the IIM module. 
//
//  Parameters:
//      bClockEnable
//           [in] Set TRUE to enable IIM module clocks.  Set FALSE
//           to disable IIM module clocks.
//
//  Returns:
//      None
//
//-----------------------------------------------------------------------------
VOID OALClockEnableIIM(BOOL bClockEnable)
{
    DDK_CLOCK_GATE_MODE mode = bClockEnable ? DDK_CLOCK_GATE_MODE_ENABLE :
        DDK_CLOCK_GATE_MODE_DISABLE;
    
    OALClockSetGatingMode(DDK_CLOCK_GATE_INDEX_IIM, mode);
}

⌨️ 快捷键说明

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