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

📄 pwrbtn2410.c

📁 我自己编译的armv4i wince60模拟器的bps源文件,已经验证可以使用,欢迎下载
💻 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.
//

// 
// This driver uses the SW1 button on EINT0 for suspend/resume.
// SW2 (EINT2) is for reset.
//

#include <windows.h>
#include <types.h>
#include <nkintr.h>
#include <pm.h>
#include <s3c2410x.h>

// Should match type of SetSystemPowerState() in pm.h
typedef DWORD (*PFN_SetSystemPowerState)(LPCWSTR, DWORD, DWORD);

static PFN_SetSystemPowerState pfnSetSystemPowerState;

static HANDLE PwrButtonIntrEvent;
static HANDLE PowerButtonIntrThreadHandle;

static HANDLE ResetButtonIntrEvent;
static HANDLE ResetButtonIntrThreadHandle;

static DWORD PwrButtonIrq     = IRQ_EINT0;	// Determined by SMDK2410 board layout.
static DWORD PwrButtonSysIntr = SYSINTR_UNDEFINED;

static DWORD ResetButtonIrq     = IRQ_EINT2;	// Determined by SMDK2410 board layout.
static DWORD ResetButtonSysIntr = SYSINTR_UNDEFINED;

static volatile S3C2410X_IOPORT_REG *v_pIOPregs;
static volatile S3C2410X_INTR_REG *s2410INT;

static VOID
EnablePowerButtonInterrupt(VOID)
{
    v_pIOPregs->GPFCON  &= ~(0x3 << 0);		// Set EINT0(GPF0) as EINT0
    v_pIOPregs->GPFCON  |=  (0x2 << 0);

    v_pIOPregs->EXTINT0 &= ~(0x7 << 0);		// Configure EINT0 as Falling Edge Mode
    v_pIOPregs->EXTINT0 |=  (0x2 << 0);
}

static VOID
EnableResetButtonInterrupt(VOID)
{
    v_pIOPregs->GPFCON  &= ~(0x3 << 4);		// Set EINT2(GPF2) as EINT2
    v_pIOPregs->GPFCON  |=  (0x2 << 4);

    v_pIOPregs->EXTINT0 &= ~(0x7 << 8);		// Configure EINT2 as Falling Edge Mode
    v_pIOPregs->EXTINT0 |=  (0x2 << 8);
}

static BOOL
PowerButtonIsPushed(VOID)
{
    //
    // Switches are pulled up when open, and driven low when closed.
    // Return true if switch 1 (EINT0) is closed.
    //
    return ((v_pIOPregs->GPFDAT & (1 << 0)) ? FALSE : TRUE);
}

static BOOL
ResetButtonIsPushed(VOID)
{
    //
    // Switches are pulled up when open, and driven low when closed.
    // Return true if switch 1 (EINT2) is closed.
    //
    return ((v_pIOPregs->GPFDAT & (1 << 2)) ? FALSE : TRUE);
}

static BOOL
InitializeAddresses(VOID)
{
    BOOL RetValue = FALSE;

    // IO Register Allocation
    v_pIOPregs = (volatile S3C2410X_IOPORT_REG *)VirtualAlloc(0, sizeof *v_pIOPregs, MEM_RESERVE, PAGE_NOACCESS);
    if (v_pIOPregs == NULL)
    {
        ERRORMSG(1,(TEXT("PBT: VirtualAlloc failed!\r\n")));
    } else {
        if (!VirtualCopy((PVOID)v_pIOPregs, (PVOID)(S3C2410X_BASE_REG_PA_IOPORT >> 8), sizeof *v_pIOPregs, PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))
        {
            ERRORMSG(1,(TEXT("PBT: VirtualCopy failed!\r\n")));
            VirtualFree((PVOID)v_pIOPregs, 0, MEM_RELEASE);
            v_pIOPregs = NULL;
        }
    }

    s2410INT = (volatile S3C2410X_INTR_REG *)VirtualAlloc(0, sizeof *s2410INT, MEM_RESERVE, PAGE_NOACCESS);
    if (s2410INT == NULL)
    {
        ERRORMSG(1,(TEXT("PBT: VirtualAlloc failed!\r\n")));
    } else {
        if (!VirtualCopy((PVOID)s2410INT, (PVOID)(S3C2410X_BASE_REG_PA_INTR >> 8), sizeof *s2410INT, PAGE_PHYSICAL | PAGE_READWRITE | PAGE_NOCACHE))
        {
            ERRORMSG(1,(TEXT("PBT: VirtualCopy failed!\r\n")));
            VirtualFree((PVOID)s2410INT, 0, MEM_RELEASE);
            s2410INT = NULL;
        }
    }

    if(v_pIOPregs && s2410INT)
    {
      RetValue = TRUE;
    }

    return (RetValue);
}

static DWORD
PowerButtonIntrThread(PVOID pArg)
{

    EnablePowerButtonInterrupt();

    PwrButtonIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    //
    // Request a SYSINTR value from the OAL.
    //
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &PwrButtonIrq, sizeof PwrButtonIrq, &PwrButtonSysIntr, sizeof PwrButtonSysIntr, NULL))
    {
        RETAILMSG(1, (TEXT("PBT: Error! Failed to request sysintr value for power button interrupt.\r\n")));
        return(0);
    }

    if (!(InterruptInitialize(PwrButtonSysIntr, PwrButtonIntrEvent, 0, 0)))
    {
        RETAILMSG(1, (TEXT("ERROR: PwrButton: Interrupt initialize failed.\r\n")));
    }

    // Handle power button presses.
    for (;;)
    {
        WaitForSingleObject(PwrButtonIntrEvent, INFINITE);

        if (PowerButtonIsPushed())     // Guard against noise triggering an interrupt.
        {
            Sleep(200);         // Check again in 200 Ms. to fend off a continuous press.
            if (!PowerButtonIsPushed())    // Must be held+released in less than .2 seconds.
            {
                //
                // Soft reset and standard suspend-resume both start with suspend for now.
                // Call whichever shutdown API is available.
                //
                if(pfnSetSystemPowerState != NULL)
                {
                    RETAILMSG(1,(TEXT("PBT: Signalling power manager to suspend...\r\n")));
                    pfnSetSystemPowerState(NULL, POWER_STATE_SUSPEND, POWER_FORCE);
                } else {
                    RETAILMSG(1,(TEXT("PBT: Suspending by calling PowerOffSystem...\r\n")));
                    PowerOffSystem();
                }
                //
                // Acquiesce to other threads since our work is complete as of
                // the call to PowerOffSystem, or the signalling of the power
                // manager.
                //
                Sleep(0);
            }
            else
                RETAILMSG(1,(TEXT("PBT: Button held too long (ignored)\r\n")));
        }
        else
            RETAILMSG(1,(TEXT("PBT: Feeble button press or noise triggered it (ignored)\r\n")));

        InterruptDone(PwrButtonSysIntr);
    }
}

static DWORD
ResetButtonIntrThread(PVOID pArg)
{

    EnableResetButtonInterrupt();

    ResetButtonIntrEvent = CreateEvent(NULL, FALSE, FALSE, NULL);

    //
    // Request a SYSINTR value from the OAL.
    //
    if (!KernelIoControl(IOCTL_HAL_REQUEST_SYSINTR, &ResetButtonIrq, sizeof ResetButtonIrq, &ResetButtonSysIntr, sizeof ResetButtonSysIntr, NULL))
    {
        RETAILMSG(1, (TEXT("PBT: Error! Failed to request sysintr value for reset button interrupt.\r\n")));
        return(0);
    }

    if (!(InterruptInitialize(ResetButtonSysIntr, ResetButtonIntrEvent, 0, 0)))
    {
        RETAILMSG(1, (TEXT("ERROR: ResetButton: Interrupt initialize failed.\r\n")));
    }

    // Handle power button presses.
    for (;;)
    {
        WaitForSingleObject(ResetButtonIntrEvent, INFINITE);

        //Mask the storage device interrupt EINT11 so we don't service it before reboot is finished
        s2410INT->INTMSK = (s2410INT->INTMSK | (0x1 << 0x5));

        if (ResetButtonIsPushed())     // Guard against noise triggering an interrupt.
        {
            //
            // Soft reset and standard suspend-resume both start with suspend for now.
            // Call whichever shutdown API is available.
            //
            if(pfnSetSystemPowerState != NULL)
            {
                RETAILMSG(1,(TEXT("PBT: Signalling power manager to reset...\r\n")));
                pfnSetSystemPowerState(NULL, POWER_STATE_RESET, POWER_FORCE);
            } else {
                RETAILMSG(1,(TEXT("PBT: Resetting by calling KernelIoControl(IOCTL_HAL_REBOOT)...\r\n")));
                KernelIoControl(IOCTL_HAL_REBOOT,NULL,0,NULL,0,NULL);
            }
            //
            // Acquiesce to other threads since our work is complete as of
            // the call to PowerOffSystem, or the signalling of the power
            // manager.
            //
            Sleep(0);
        }
        else
            RETAILMSG(1,(TEXT("PBT: Feeble button press or noise triggered it (ignored)\r\n")));

        InterruptDone(ResetButtonSysIntr);
    }
}

DWORD
PBT_Init(DWORD dwContext)
{
    DWORD   IDPowerButtonThread;
    DWORD   IDResetButtonThread;
    HMODULE hmCore;

    //
    // Obtain a pointer to the power manager function "SetSystemPowerState"
    // from the core library so we can call into it.
    //
    pfnSetSystemPowerState = NULL;

    hmCore = (HMODULE) LoadLibrary(_T("coredll.dll"));

    if(hmCore != NULL)
    {
        pfnSetSystemPowerState = (PFN_SetSystemPowerState) GetProcAddress(hmCore, _T("SetSystemPowerState"));

        if(pfnSetSystemPowerState == NULL)
        {
            FreeLibrary(hmCore);
        }
    }

    // Initialize addresses now as opposed to when interrupts are handled so there are no race conditions
    InitializeAddresses();

    // Create a thread to handle the power button event, and one to handle the reset button event.
    ResetButtonIntrThreadHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) ResetButtonIntrThread, 0, 0, &IDResetButtonThread);
    if (ResetButtonIntrThreadHandle == 0)
    {
        RETAILMSG(1, (TEXT("PBT: CreateThread() Fail\r\n")));
    }
    PowerButtonIntrThreadHandle = CreateThread(0, 0, (LPTHREAD_START_ROUTINE) PowerButtonIntrThread, 0, 0, &IDPowerButtonThread);
    if (PowerButtonIntrThreadHandle == 0)
    {
        RETAILMSG(1, (TEXT("PBT: CreateThread() Fail\r\n")));
    }

    return (dwContext);
}

BOOL WINAPI
DllEntry(HANDLE hInstDll, DWORD dwReason, LPVOID lpvReserved)
{
    switch (dwReason)
    {
    case DLL_PROCESS_ATTACH:
        DisableThreadLibraryCalls((HMODULE) hInstDll);
        break;
    }
    return (TRUE);
}

BOOL
PBT_Close(DWORD Handle)
{
    return (TRUE);
}

//
// Device deinit - devices are expected to close down.
// The device manager does not check the return code.
//
BOOL
PBT_Deinit(DWORD dwContext)
{
    return (TRUE);
}

//
// Returns handle value for the open instance.
//
DWORD
PBT_Open(DWORD dwData, DWORD dwAccess, DWORD dwShareMode)
{
    return 0;
}

//
// I/O Control function - None implemented in this driver.
//
BOOL
PBT_IOControl(
    DWORD Handle,
    DWORD dwIoControlCode,
    PBYTE pInBuf,
    DWORD nInBufSize,
    PBYTE pOutBuf,
    DWORD nOutBufSize,
    PDWORD pBytesReturned
    )
{
    return FALSE;
}

DWORD
PBT_Read(DWORD Handle, LPVOID pBuffer, DWORD dwNumBytes)
{
    return (0);
}

DWORD
PBT_Write(DWORD Handle, LPCVOID pBuffer, DWORD dwNumBytes)
{
    return (0);
}

DWORD
PBT_Seek(DWORD Handle, LONG lDistance, DWORD dwMoveMethod)
{
    return (0);
}

VOID
PBT_PowerUp(VOID)
{
    return;
}

VOID
PBT_PowerDown(VOID)
{
    return;
}

⌨️ 快捷键说明

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