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

📄 ist.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
📖 第 1 页 / 共 3 页
字号:
//
// 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 OR INDEMNITIES.
//

#include <windows.h>
#include <windev.h>
#include <types.h>
#include <memory.h>
#include <winuserm.h>
#include <string.h>
#include <nkintr.h>
#include <ceddk.h>
#include <pmimpl.h>
#include <pmpolicy.h>
#include <battery.h>

#include <bulverde_base_regs.h>
#include <plato.h>
#include <xllp_gpio.h>
#include <xllp_clkmgr.h>
#include <xllp_ost.h>
#include <xllp_i2c.h>

#include "bsp_cfg.h"
#include "pcf50606.h"
#include "pmdriver.h"
#include "power_i2c.h"

#ifndef SHIP_BUILD
extern DBGPARAM dpCurSettings;
#endif

#define IST_PRIORITY256         100

static SYSTEM_POWER_STATUS_EX2 gPowerStatus;

BOOL gfACOnline = FALSE;
static BOOL gfBatteryCharging = FALSE;
static BOOL gfRTCSyncThreadRunning = FALSE;

static void
SynchronizeRTCTime(PPCF50606 pPCF50606);

DWORD WINAPI 
SynchronizeRTCThread(PPCF50606 pPCF50606);

static void 
RestartCharger(PPCF50606 pPCF50606);

static void 
StopCharger(PPCF50606 pPCF50606);

static void 
RemoveCharger(PPCF50606 pPCF50606);

static void
BatteryFull(PPCF50606 pPCF50606);

static void
BatteryEmpty(PPCF50606 pPCF50606);

static void
SendPowerChangeMessage(HANDLE pMsgQueue);

static DWORD
ComputeVoltageAverage(PPCFBATTERY pPcfBattery);


static void GetBatteryVoltage(PPCF50606 pPCF50606)
{
    // ADC Start for BATVOLT, no external sync
    pPCF50606->pcfRegisterCache[ADCC2] = ADCC2_ADCMUX_M(SEL_BATVOLT_RES) |
                                         ADCC2_ADCSYNC_M(NO_SYNC) |
                                         ADCC2_START;

    PDD_I2CWrite(&pPCF50606->csI2CAccess,
                 pPCF50606->v_pI2CRegs,
                 pPCF50606->v_pOstRegs,
                 ADCC2,
                 pPCF50606->pcfRegisterCache+ADCC2,
                 1);

    // Read Battery voltage from PCF50606
    PDD_I2CRead(&pPCF50606->csI2CAccess,
                 pPCF50606->v_pI2CRegs,
                 pPCF50606->v_pOstRegs,
                 ADCS1,
                 pPCF50606->pcfRegisterCache+ADCS1,
                 2);

    pPCF50606->pcfBattery.dwCurrentBatteryVoltage =
        ((pPCF50606->pcfRegisterCache[ADCS1] << 2) | (pPCF50606->pcfRegisterCache[ADCS2] & 0x3));

    DEBUGMSG(ZONE_VERBOSE,  (TEXT("PCF50606: Raw Battery Voltage: 0x%x\r\n"),
        pPCF50606->pcfBattery.dwCurrentBatteryVoltage));

    pPCF50606->pcfBattery.dwCurrentBatteryVoltage =
        (pPCF50606->pcfBattery.dwCurrentBatteryVoltage * 6000) >> 10;

    DEBUGMSG(ZONE_VERBOSE, (TEXT("PCF50606: Calculated Battery Voltage: %dmV\r\n"),
        pPCF50606->pcfBattery.dwCurrentBatteryVoltage));
}

#ifdef _DEBUG
static void PrintBatteryTemp(PPCF50606 pPCF50606)
{
    DWORD dwPCFBatteryTemp;

    // ADC Start for BATTEMP, no external sync
    pPCF50606->pcfRegisterCache[ADCC1] = ADCC1_TRATSET |
                                         ADCC1_NTCSWAOFF;

    pPCF50606->pcfRegisterCache[ADCC2] = ADCC2_ADCMUX_M(SEL_BATTEMP_RAT) |
                                         ADCC2_ADCSYNC_M(NO_SYNC) |
                                         ADCC2_START;

    PDD_I2CWrite(&pPCF50606->csI2CAccess,
                                 pPCF50606->v_pI2CRegs,
                                 pPCF50606->v_pOstRegs,
                                 ADCC1,
                                 pPCF50606->pcfRegisterCache+ADCC1,
                                 2);

    
    
    //wait for reading to stabilize
    XllpOstDelayMicroSeconds((P_XLLP_OST_T)pPCF50606->v_pOstRegs, 100);

    PDD_I2CRead(&pPCF50606->csI2CAccess,
                                pPCF50606->v_pI2CRegs,
                                pPCF50606->v_pOstRegs,
                                ADCS1,
                                pPCF50606->pcfRegisterCache+ADCS1,
                                2);

    dwPCFBatteryTemp =
        ((pPCF50606->pcfRegisterCache[ADCS1] << 2) | (pPCF50606->pcfRegisterCache[ADCS2] & 0x3));


    DEBUGMSG(ZONE_VERBOSE, (TEXT("PCF50606: Battery Temp Raw: 0x%x\r\n"),
        dwPCFBatteryTemp));

    dwPCFBatteryTemp = (dwPCFBatteryTemp*10000)/(1023-dwPCFBatteryTemp);

    DEBUGMSG(ZONE_VERBOSE, (TEXT("PCF50606: Battery Temp Resistance: %d Ohms\r\n"),
        dwPCFBatteryTemp));

}
static void PrintMBCState(PPCF50606 pPCF50606)
{
    // Read Battery voltage from PCF50606
    PDD_I2CRead(&pPCF50606->csI2CAccess,
                                pPCF50606->v_pI2CRegs,
                                pPCF50606->v_pOstRegs,
                                MBCC1,
                                pPCF50606->pcfRegisterCache+MBCC1,
                                4);
    DEBUGMSG(ZONE_VERBOSE, (TEXT("\nMain Battery Charger (MBC)Regs\r\n")));
    DEBUGMSG(ZONE_VERBOSE, (TEXT("    PCF50606: MBCC1: %x\r\n"),
        pPCF50606->pcfRegisterCache[MBCC1]));
    DEBUGMSG(ZONE_VERBOSE, (TEXT("    PCF50606: MBCC2: %x\r\n"),
        pPCF50606->pcfRegisterCache[MBCC2]));
    DEBUGMSG(ZONE_VERBOSE, (TEXT("    PCF50606: MBCC3: %x\r\n"),
        pPCF50606->pcfRegisterCache[MBCC3]));
    DEBUGMSG(ZONE_VERBOSE, (TEXT("    PCF50606: MBCS1: %x\r\n"),
        pPCF50606->pcfRegisterCache[MBCS1]));
    DEBUGMSG(ZONE_VERBOSE, (TEXT("\r\n")));
}

static void PrintInterruptStatus(PPCF50606 pPCF50606)
{
    //only print the cached values 
    DEBUGMSG(ZONE_VERBOSE, (TEXT("\nPCF Interupts Status Regs\r\n")));
    DEBUGMSG(ZONE_VERBOSE, (TEXT("    PCF50606: INT1: %x\r\n"),
        pPCF50606->pcfRegisterCache[INT1]));
    DEBUGMSG(ZONE_VERBOSE, (TEXT("    PCF50606: INT1M: %x\r\n"),
        pPCF50606->pcfRegisterCache[INT1M]));
    DEBUGMSG(ZONE_VERBOSE, (TEXT("    PCF50606: INT2: %x\r\n"),
        pPCF50606->pcfRegisterCache[INT2]));
    DEBUGMSG(ZONE_VERBOSE, (TEXT("    PCF50606: INT2M: %x\r\n"),
        pPCF50606->pcfRegisterCache[INT2M]));
    DEBUGMSG(ZONE_VERBOSE, (TEXT("    PCF50606: INT3: %x\r\n"),
        pPCF50606->pcfRegisterCache[INT3]));
    DEBUGMSG(ZONE_VERBOSE, (TEXT("    PCF50606: INT3M: %x\r\n"),
        pPCF50606->pcfRegisterCache[INT3M]));
    DEBUGMSG(ZONE_VERBOSE, (TEXT("\r\n")));
}
#endif


INT WINAPI PCF50606IntrThread(PPCF50606 pPCF50606)
{
    DWORD bytesReturned;
    DWORD dwTimeout;
    DWORD dwPCFMessage;
    DWORD dwErr;
    DWORD wakeSrcKeyPad = SYSINTR_KEYPAD;
    SYSTEMTIME sysRTCTime;
    const BYTE *RTCRegs = pPCF50606->pcfRegisterCache+RTCSC;
    PPCFBATTERY pPcfBattery = &pPCF50606->pcfBattery;

    DEBUGMSG(ZONE_VERBOSE, (TEXT("PCF50606IntrThread starting...\r\n")));

    // Set thread's priority
    CeSetThreadPriority(GetCurrentThread(), IST_PRIORITY256);

    // Polling mode with interrupt enabled only for events
    // Let the first run happen soon so that the battery driver gets a voltage reading.
    dwTimeout = 1;

    while(1)
    {
        if(WaitForSingleObject(pPCF50606->hevPCF50606Event, dwTimeout) == WAIT_OBJECT_0)
        {
            // Actually received interrupt, stop polling
            InterruptDone(SYSINTR_PCF50606);
        }
        else
        {
            // Poll every 'x' seconds
            dwTimeout = PCF50606_MAINTENANCE_POLLING_INTERVAL;
        }

        // Read Interrupt controller register 1,2,3 from PCF50606
        bytesReturned = PDD_I2CRead(&pPCF50606->csI2CAccess,
                                    pPCF50606->v_pI2CRegs,
                                    pPCF50606->v_pOstRegs,
                                    INT1,
                                    pPCF50606->pcfRegisterCache+INT1,
                                    3);

        // Reset PCF message
        dwPCFMessage = 0;

#ifdef _DEBUG
        PrintInterruptStatus(pPCF50606);
#endif

        if(pPCF50606->pcfRegisterCache[INT2] & INT2_CHGERR)
        {
            RETAILMSG(ZONE_ERROR, (TEXT("PCF50606: Charger Error\r\n")));

            bytesReturned = PDD_I2CRead(&pPCF50606->csI2CAccess,
                                        pPCF50606->v_pI2CRegs,
                                        pPCF50606->v_pOstRegs,
                                        MBCS1,
                                        pPCF50606->pcfRegisterCache+MBCS1,
                                        1);

            if(MBCS1_TBATSTAT_M(MBCS1_TEMP_OK) != (pPCF50606->pcfRegisterCache[MBCS1] & MBCS1_TBATSTAT_M(MBCS1_TEMP_MASK)))
            {
                // Plato does not have temprature monitoring hardware so this error must be invalid
                RETAILMSG(ZONE_ERROR, (TEXT("PCF50606: Invalid Temprature Error, Restarting Charger\r\n")));
                StartCharger(pPCF50606); 
            }
        }

        // Query INT register #1

        ///////////////////////////////////////////////
        // Has ONKEY been pressed or released (doubles up as the END key)
        ///////////////////////////////////////////////
        if(pPCF50606->pcfRegisterCache[INT1] & INT1_ONKEYF)
        {
            // key released
            keybd_event((BYTE) VK_TEND, 0x46, KEYEVENTF_KEYUP, 0);
        }

        if(pPCF50606->pcfRegisterCache[INT1] & INT1_ONKEYR)
        {
            // key pressed
            keybd_event((BYTE) VK_TEND, 0x46, 0, 0);
        }
        
        ///////////////////////////////////////////////
        // Has ONKEY been pressed for 1 sec
        ///////////////////////////////////////////////
        if(pPCF50606->pcfRegisterCache[INT1] & INT1_ONKEY1S)
        {
            // Power OFF/ON key held down for one second. Initiate clean shutdown.
            //
            
            // First reset the 8 second timer so that system has enough time to 
            // shutdown properly (or recover from an error)
            pPCF50606->pcfRegisterCache[OOCC1] |= OOCC1_TOTRST;
            bytesReturned = PDD_I2CWrite(&pPCF50606->csI2CAccess,
                                 pPCF50606->v_pI2CRegs,
                                 pPCF50606->v_pOstRegs,
                                 OOCC1,

⌨️ 快捷键说明

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