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

📄 pwrbtn_pcf.c

📁 wince底层驱动开发代码 ARM作为一种嵌入式系统处理器
💻 C
📖 第 1 页 / 共 2 页
字号:
//
// 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.
//

/* ++

    PCF50606 Power Supply Controller & Battery Management

    Notes:
    ======
    o) I2c client

-- */

#include <windows.h>
#include <nkintr.h>
#include <windev.h>
#include <winbase.h>

#include "oalintr.h"

#include "pwr.h"

static DWORD PWR_IST(LPVOID Context);

// Make sure the driver builds OK in tinykern configuration
HMODULE g_hMod = NULL;
typedef void (*PFN_GwesPowerOffSystem)(void);
PFN_GwesPowerOffSystem g_pfnGwesPowerOffSystem = NULL;

// 
// Write PCF50606 registers directly from our cache
//
DWORD
HW_WriteRegisters(
    PPWR_CONTEXT pPWR,
    PUCHAR pBuff,   // Optional buffer
    UCHAR StartReg, // start register
    DWORD nRegs     // number of registers
    )
{
    return 1;
}


/* ++

Setup the regulators/converters.
Currenly uses default settings.

TODO: determine if we can lower anything.

-- */
DWORD
HW_InitRegulators(
    PPWR_CONTEXT    pPWR
    )
{
    return 1;
}


#define ENABLE  TRUE
#define DISABLE FALSE

DWORD
HW_InitCharger(
    PPWR_CONTEXT    pPWR,
    UCHAR           ucMode,
    UCHAR           ucFlags,
    BOOL            bEnable
    )
{
    return 1;
}


DWORD
HW_InitRegisters(
    PPWR_CONTEXT pPWR
    )
{
    DWORD retry = 0;

	// EINT0, GPF0 Port Init
	IOPreg * v_pIOPregs;

	v_pIOPregs = (volatile IOPreg *)VirtualAlloc(0, sizeof(IOPreg), MEM_RESERVE, PAGE_NOACCESS);
	VirtualCopy((PVOID)v_pIOPregs, (PVOID)(IOP_BASE), sizeof(IOPreg), PAGE_READWRITE | PAGE_NOCACHE);

	v_pIOPregs->rGPFCON  &= ~(0x3 << 0);		/* Set EINT0(GPF0) as EINT0							*/
	v_pIOPregs->rGPFCON  |=  (0x2 << 0);

    v_pIOPregs->rEXTINT0 &= ~(0x7 << 0);		/* Configure EINT0 as Falling Edge Mode				*/
    v_pIOPregs->rEXTINT0 |=  (0x4 << 0);

	VirtualFree((PVOID) v_pIOPregs, 0, MEM_RELEASE);
	// EINT0, GPF0 Port Init Done


    EnterCriticalSection(&pPWR->RegCS);

    // init DRV_GLOBAL
    pPWR->pDriverGlobals->power.State   = PCF50606_STATE_IDLE;
    pPWR->pDriverGlobals->power.Error   = ERROR_SUCCESS;

    pPWR->pDriverGlobals->power.ACLineStatus = 0;
	pPWR->pDriverGlobals->power.ACLineStatus |= AC_LINE_BACKUP_POWER;
	pPWR->pDriverGlobals->power.ACLineStatus |= AC_LINE_ONLINE;

    pPWR->pDriverGlobals->power.BatteryFlag  = 0;
	pPWR->pDriverGlobals->power.BatteryFlag |=  BATTERY_FLAG_CHARGING;
    
    pPWR->pDriverGlobals->power.bADCC1   = 0;
    pPWR->pDriverGlobals->power.bADCC2   = 0;
    pPWR->pDriverGlobals->power.bADCDAT1 = 0;
    pPWR->pDriverGlobals->power.bADCDAT2 = 0;
    pPWR->pDriverGlobals->power.bADCDAT3 = 0;


    LeaveCriticalSection(&pPWR->RegCS);
        
    return 0;
}


/* ++

    The reset value of the PCF50606 INTxM registers is 0: Interrupt enabled.
    Once we enable the interrupt they start firing unless we mask them _before_
    enabeling the interrupt(s).
    
-- */
DWORD
HW_Init(
    PPWR_CONTEXT pPWR
    )
{
    DWORD dwErr = ERROR_SUCCESS;
    BOOL    Ret;

	pPWR->pDriverGlobals = NULL;

	RETAILMSG(1, (TEXT("HW_Init : GetProcAddress \r\n"), dwErr));
    //  Load GwesPowerOffSystem from coredll
    g_hMod = LoadLibraryEx(L"coredll.dll", NULL, DONT_RESOLVE_DLL_REFERENCES);
    if(g_hMod) {
        g_pfnGwesPowerOffSystem = (PFN_GwesPowerOffSystem) GetProcAddress(g_hMod, L"GwesPowerOffSystem");
        if(!g_pfnGwesPowerOffSystem) {
            FreeLibrary(g_hMod);
            g_hMod = NULL;
        }
    }
    
	RETAILMSG(1, (TEXT("HW_Init : ERROR_INVALID_PARAMETER \r\n")));
    if ( !pPWR )
        return ERROR_INVALID_PARAMETER;
        
	RETAILMSG(1, (TEXT("HW_Init : InitializeCriticalSection \r\n")));
    InitializeCriticalSection(&pPWR->RegCS);

	RETAILMSG(1, (TEXT("HW_Init : VirtualAlloc \r\n")));
    // map in DRV_GLOB
    if ( pPWR->pDriverGlobals == NULL )
    {
        pPWR->pDriverGlobals =
            (PDRIVER_GLOBALS)
                  VirtualAlloc( 0,
                                DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
                                MEM_RESERVE,
                                PAGE_NOACCESS
                              );
        if ( pPWR->pDriverGlobals == NULL )
        {
            RETAILMSG( 1, (TEXT( "pPWR->pDriverGlobals: VirtualAlloc failed!\r\n")) );
	        goto _error_exit;
        }

        Ret = VirtualCopy( (LPVOID)pPWR->pDriverGlobals,
                           (LPVOID)DRIVER_GLOBALS_PHYSICAL_MEMORY_START,
                           DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE,
                           PAGE_READWRITE | PAGE_NOCACHE
                           );

        if ( Ret == FALSE )
        {
            RETAILMSG( 1, (TEXT( "pPWR->pDriverGlobals: VirtualCopy failed!\r\n")) );
	        goto _error_exit;
        }
    }

	RETAILMSG(1, (TEXT("HW_Init : pPWR->State \r\n")));

    // Init H/W
    pPWR->State = INITIALIZE;
    
    RETAILMSG(1, (TEXT("HW_Init : HW_InitRegisters \r\n"), dwErr));
	dwErr = HW_InitRegisters(pPWR);
    if ( dwErr ) {
	    RETAILMSG(1, (TEXT("HW_Init : HW_InitRegisters  Error \r\n"), dwErr));
        goto _error_exit;
    }

    //
    // create PWR_IST
    //
    RETAILMSG(1, (TEXT("HW_Init : CreateEvent \r\n"), dwErr));
    if ( (pPWR->ISTEvent = CreateEvent(NULL, FALSE, FALSE, NULL)) == NULL) {
        dwErr = GetLastError();
        RETAILMSG(1,(TEXT("PCF50606 ERROR: Unable to create IST event: %u \r\n"), dwErr));
        goto _error_exit;
    }

    RETAILMSG(1, (TEXT("HW_Init : InterruptInitialize \r\n"), dwErr));
    if( !InterruptInitialize(SYSINTR_POWER, pPWR->ISTEvent, NULL, 0) ) {
        dwErr = GetLastError();
        RETAILMSG(1,(TEXT("PCF50606 ERROR: Unable to initialize interrupt: %u\r\n"), dwErr));
        goto _error_exit;
    }

    RETAILMSG(1, (TEXT("HW_Init : CreateThread \r\n"), dwErr));
    if ( (pPWR->IST = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) PWR_IST, pPWR, 0, NULL)) == NULL) {
        dwErr = GetLastError();
        RETAILMSG(1,(TEXT("PCF50606 ERROR: Unable to create IST: %u\r\n"), dwErr));
        goto _error_exit;
    }
    
    RETAILMSG(1, (TEXT("HW_Init : CeSetThreadPriority \r\n"), dwErr));
    // TODO: registry override
    if ( !CeSetThreadPriority(pPWR->IST, POWER_THREAD_PRIORITY)) {
        dwErr = GetLastError();
        RETAILMSG(1, (TEXT("PCF50606 ERROR: CeSetThreadPriority ERROR:%d \r\n"), dwErr));
        goto _error_exit;
    }

    pPWR->State = RUN;

    // Finally, after we are initialized dispatch any unmasked interrupts 
    // we may have missed during system start up. We do this because the INTx
    // registers are cleared on read.
    if ( !dwErr ) 
    {
        RETAILMSG(1,(TEXT("HW_Init OOCS: 0x%.2x\r\n"), pPWR->ResetReg[0] ));
        RETAILMSG(1,(TEXT("HW_Init INT1: 0x%.2x\r\n"), pPWR->ResetReg[1]));
        RETAILMSG(1,(TEXT("HW_Init INT2: 0x%.2x\r\n"), pPWR->ResetReg[2]));
        RETAILMSG(1,(TEXT("HW_Init INT3: 0x%.2x\r\n"), pPWR->ResetReg[3]));
//        pPWR->ResetRegReady = TRUE;
//        SetEvent(pPWR->ISTEvent);
    }

    RETAILMSG(1, (TEXT("HW_Init : Donw \r\n"), dwErr));

_error_exit:
    return dwErr;
}


DWORD
HW_Deinit(
    PPWR_CONTEXT pPWR
    )
{
    if ( !pPWR )
        return ERROR_INVALID_PARAMETER;
    
    RETAILMSG(1,(TEXT("+PWR_Deinit \r\n")));

    pPWR->State = UNINITIALIZED;

    if (pPWR->hADC && CloseHandle(pPWR->hADC))
        pPWR->hADC = NULL;

    if (pPWR->hTSCPRES && CloseHandle(pPWR->hTSCPRES))
        pPWR->hTSCPRES = NULL;

    if (pPWR->hI2C && pPWR->hI2C != INVALID_HANDLE_VALUE && CloseHandle(pPWR->hI2C))
        pPWR->hI2C = INVALID_HANDLE_VALUE;
    
    InterruptDisable(SYSINTR_POWER);

    if (pPWR->ISTEvent && CloseHandle(pPWR->ISTEvent))
        pPWR->ISTEvent = NULL;
    
    if (pPWR->IST && CloseHandle(pPWR->IST))
        pPWR->IST = NULL;  

    if (pPWR->pDriverGlobals) {
        VirtualFree( pPWR->pDriverGlobals,
                     DRIVER_GLOBALS_PHYSICAL_MEMORY_SIZE ,
                     MEM_RELEASE
                    );
        pPWR->pDriverGlobals = NULL;
    }        

    //  Free the coredll instance if we have allocated one
    if(g_hMod) {
        FreeLibrary(g_hMod);
        g_hMod = NULL;
    }

    DeleteCriticalSection(&pPWR->RegCS);

⌨️ 快捷键说明

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