www.pudn.com > Battdrvr.rar > battif.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. // // // This module contains a stub implementation of the battery PDD. OEMs // that want to support the battery APIs on their platform can copy this // file to their platform and link it into their own version of the power // manager DLL. // // If the platform-specific power manager provides its own version of these // entry points, this module will not be pulled into the link map from // the pm_battapi library. // /* Copyright © 1999-2002 Intel Corp. */ // Battery Driver implemented for Sandgate. //-------------------------------------------------------------------------------------------------- // Includes //-------------------------------------------------------------------------------------------------- #include#include #include #include #include "xllp_gpio.h" #include "xsbase270_g.h" //------------------------------------------------------------------------------------------------- // Defines //------------------------------------------------------------------------------------------------- //#define AD2 (6 << 2) //#define AD3 (7 << 2) #define MAXIMUM_VOLTAGE 546 #define MAXIMUM_BAT_VOLTAGE 410 #define MINIMUM_VOLTAGE 300 #define PER 10 #define BAT_SDA (1<<31)//gpio95 #define BAT_CLK (1<<2) // #define BAT_CE (1<<3) //gpio99 #define BAT_STATUS (1<<2)//gpio98 #define WAIT (20) //extern void msWait(unsigned msVal); static volatile BULVERDE_GPIO_REG *g_pGPIORegs = NULL; static volatile UINT8 *g_pBATRegs = NULL; static volatile UINT8 *g_pShadowRegs = NULL; __inline void XSBASE270_BAT_CLEARBIT(UINT32 clk) { *g_pShadowRegs &= ~(clk); *g_pBATRegs = *g_pShadowRegs; } __inline void XSBASE270_BAT_SETBIT(UINT32 clk) { *g_pShadowRegs |= (clk); *g_pBATRegs = *g_pShadowRegs; } UINT16 Get_BatteryVol() { UINT16 dat = 0; int i = 0; g_pGPIORegs->GPDR2 |= BAT_SDA; g_pGPIORegs->GPDR3 |= BAT_CE; g_pGPIORegs->GPCR2 = BAT_SDA; //pull down ce and data,enable chip g_pGPIORegs->GPCR3 = BAT_CE; Sleep(WAIT); g_pGPIORegs->GPDR2 &= ~BAT_SDA; for(i = 15; i >= 0; i--) { XSBASE270_BAT_CLEARBIT(BAT_CLK); Sleep(WAIT); dat |= (((g_pGPIORegs->GPLR2 & BAT_SDA) != 0) ? 0x1 << i : 0); XSBASE270_BAT_SETBIT(BAT_CLK); Sleep(WAIT); } Sleep(WAIT * 2); g_pGPIORegs->GPCR2 = BAT_SDA; g_pGPIORegs->GPDR2 |= BAT_SDA; //pull up ce and data, disable chip g_pGPIORegs->GPSR3 = BAT_CE; Sleep(WAIT * 2); DEBUGMSG(1, (TEXT("\r\nvoltage is 0x%x\r\n"), dat)); dat = (dat & 0x1fe0) >> 5; return (dat * 500 / 256); } //------------------------------------------------------------------------------------------------- // Global Variables //-------------------------------------------------------------------------------------------------- //volatile GPIO_REGS *v_pGPIOReg = NULL; static int first_time; static DWORD terminal_voltage; static DWORD lastvoltage[PER]={0}; //-------------------------------------------------------------------------------------------------- // Prototypes //-------------------------------------------------------------------------------------------------- /* short int ReadAC97(BYTE , unsigned short int * , BYTE ); short int WriteAC97(BYTE , unsigned short int, BYTE ); short int InitAcLink(volatile GPIO_REGS *, BYTE ); extern PVOID VirtualAllocCopy(unsigned size,char *str,PVOID pVirtualAddress); */ BOOL WINAPI BatteryDrvrGetStatus( PSYSTEM_POWER_STATUS_EX2 ,PBOOL ); //------------------------------------------------------------------------------------------------------------ // Function: Battery_sampleADC // // Purpose: Given the ADC number this function collects the digital value for the analog signal. // sampling AD3 gives the charge and AD2 gives the temperature. // Returns: an indicator as to whether the data is valid or Invalid. // //------------------------------------------------------------------------------------------------------------- /* BOOL Battery_sampleADC(DWORD *sample,unsigned ad_number) { unsigned int adccr=0; unsigned int adcDataReg; BOOL noError=FALSE; adccr = ad_number | ADC_ENA; if (WriteAC97(UCB_ADC_CR,*(unsigned short *)&adccr, DEV_BATTERY)) { adccr |= ADC_START; if(WriteAC97(UCB_ADC_CR,*(unsigned short *)&adccr, DEV_BATTERY)) { do { // wait for sample completion ReadAC97(UCB_ADC_DATA,(unsigned short *) &adcDataReg,DEV_TOUCH); } while(!TEST(adcDataReg,ADC_DATA_VAL)); *sample=TEST(adcDataReg,ADC_DATA) ; // disable adc CLEAR(adccr,ADC_ENA); WriteAC97(UCB_ADC_CR,*(unsigned short *)&adccr,DEV_BATTERY); noError=TRUE; } } return(noError); } */ //------------------------------------------------------------------------------------------------------------ // Function: InitBatteryDriver // // Purpose: Initialises the AC link used by the battery driver allocates the necessary memory. // Returns: void // //------------------------------------------------------------------------------------------------------------- void InitBatteryDriver() { PHYSICAL_ADDRESS PA; PA.QuadPart = BULVERDE_BASE_REG_PA_GPIO; g_pGPIORegs = (BULVERDE_GPIO_REG *) MmMapIoSpace(PA, sizeof(BULVERDE_GPIO_REG), FALSE); PA.QuadPart = 0x10200000; g_pBATRegs = (UINT8*)MmMapIoSpace(PA, sizeof(UINT8), FALSE); PA.QuadPart = 0xa3ff0000; g_pShadowRegs = (UINT8*)MmMapIoSpace(PA, sizeof(UINT8), FALSE); if(!g_pGPIORegs || !g_pBATRegs || !g_pShadowRegs) return; g_pGPIORegs->GAFR2_U &=~(0xC0000000);//gpio95 g_pGPIORegs->GAFR3_L &=~(0x000000F0);//gpio98,99 } //------------------------------------------------------------------------------------------------------------ // Function: IsACOnline // // Purpose: Simply indicates whether we are running out of AC or out of Battery. // Returns: TRUE indicates we are running out of the AC wall power supply. // FALSE indicates we are running out of Battery. // //------------------------------------------------------------------------------------------------------------- BOOL WINAPI IsACOnline(void) { g_pGPIORegs->GPDR3 &= ~BAT_STATUS; if((g_pGPIORegs->GPLR3 & BAT_STATUS)) { // NKDbgPrintfW(TEXT("AC is ON\r\n")); // RETAILMSG(1,(TEXT("AC is ON\r\n"))); return TRUE; } else { // NKDbgPrintfW(TEXT("Battery is ON\r\n")); // RETAILMSG(1,(TEXT("Battery is ON\r\n"))); return FALSE; } } BOOL WINAPI BatteryPDDInitialize(LPCTSTR pszRegistryContext) { BOOL fOk = TRUE; SETFNAME(_T("BatteryPDDInitialize")); UNREFERENCED_PARAMETER(pszRegistryContext); DEBUGMSG(ZONE_PDD, (_T("%s: returning %d\r\n"), pszFname, fOk)); return fOk; } void WINAPI BatteryPDDDeinitialize(void) { SETFNAME(_T("BatteryPDDDeinitialize")); DEBUGMSG(ZONE_PDD, (_T("%s: invoked\r\n"), pszFname)); } void WINAPI BatteryPDDResume(void) { SETFNAME(_T("BatteryPDDResume")); DEBUGMSG(ZONE_PDD, (_T("%s: invoked\r\n"), pszFname)); } void WINAPI BatteryPDDPowerHandler(BOOL bOff) { SETFNAME(_T("BatteryPDDPowerHandler")); UNREFERENCED_PARAMETER(bOff); DEBUGMSG(ZONE_PDD | ZONE_RESUME, (_T("%s: invoked w/ bOff %d\r\n"), pszFname, bOff)); } // This routine obtains the most current battery/power status available // on the platform. It fills in the structures pointed to by its parameters // and returns TRUE if successful. If there's an error, it returns FALSE. BOOL WINAPI BatteryPDDGetStatus( PSYSTEM_POWER_STATUS_EX2 pstatus, PBOOL pfBatteriesChangedSinceLastCall ) { // this function is used to report the battery status // now, temperature, and terminal voltage // DWORD charger_voltage; DWORD sample; // DWORD temperature = 0; // unsigned ad_number = 5; float voltage_percent = 0; BOOL PowerStatus; int i,sum=0; DEBUGMSG(1, (_T("BatteryPDDGetStatus++\r\n"))); if(first_time==0) { InitBatteryDriver(); PowerStatus = IsACOnline(); if(PowerStatus) terminal_voltage = MAXIMUM_VOLTAGE; // charger is ON, i.e AC ON else terminal_voltage = MINIMUM_VOLTAGE; // Battery is ON, charger OFF first_time=1; for(i=0;i 0;i--) { lastvoltage[i]=lastvoltage[i-1]; } lastvoltage[0]=sample; for(i = 0; i terminal_voltage)) // AC ON, Battery OFF terminal_voltage = sample; if((PowerStatus==FALSE) && (sample <= terminal_voltage)) // AC OFF, Battery ON sample = terminal_voltage; // NKDbgPrintfW(TEXT("%d\r\n"),sample); // Battery_sampleADC(&temperature, AD2); // DEBUGMSG(1, (TEXT("Already sampling the voltage\r\n"))); if(PowerStatus) { pstatus->ACLineStatus =AC_LINE_ONLINE; pstatus->BatteryFlag =BATTERY_FLAG_NO_BATTERY; } pstatus->ACLineStatus = AC_LINE_OFFLINE; //voltage_percent = (float) (sample - MINIMUM_VOLTAGE)/(MAXIMUM_VOLTAGE-MINIMUM_VOLTAGE); voltage_percent = (float) (sample - MINIMUM_VOLTAGE)/(MAXIMUM_BAT_VOLTAGE-MINIMUM_VOLTAGE); // RETAILMSG(1, (TEXT("terminal_voltage is %d, voltage_percent=%d\r\n"), terminal_voltage, voltage_percent*100)); // Level Indicator if(voltage_percent >= 0.65) pstatus->BatteryFlag = BATTERY_FLAG_HIGH; else if (( voltage_percent <0.65) && (voltage_percent >=0.1)) pstatus->BatteryFlag = BATTERY_FLAG_LOW; else if(voltage_percent<=0.1) pstatus->BatteryFlag = BATTERY_FLAG_CRITICAL; pstatus->BatteryLifePercent = (BYTE) (voltage_percent * 100); pstatus->Reserved1 = 0; pstatus->BatteryLifeTime = BATTERY_LIFE_UNKNOWN; pstatus->BatteryFullLifeTime = BATTERY_LIFE_UNKNOWN; pstatus->Reserved2 = 0; pstatus->BackupBatteryFlag = BATTERY_FLAG_UNKNOWN; pstatus->BackupBatteryLifePercent = 0; pstatus->Reserved3 = 0; pstatus->BackupBatteryLifeTime = BATTERY_LIFE_UNKNOWN; pstatus->BackupBatteryFullLifeTime = BATTERY_LIFE_UNKNOWN; pstatus->BatteryChemistry = 0x04; pstatus->BatteryVoltage = (unsigned long) (voltage_percent * 4.1); ; pstatus->BatteryCurrent = 0; pstatus->BatteryAverageCurrent = 0; pstatus->BatteryAverageInterval = 0; pstatus->BatterymAHourConsumed = 0; pstatus->BatteryTemperature = 0; pstatus->BackupBatteryVoltage = 0; *pfBatteriesChangedSinceLastCall = FALSE; DEBUGMSG(1,(_T("BatteryPDDGetStatus--\r\n"))); return (TRUE); } // This routine indicates how many battery levels will be reported // in the BatteryFlag and BackupBatteryFlag fields of the PSYSTEM_POWER_STATUS_EX2 // filed in by BatteryPDDGetStatus(). This number ranges from 0 through 3 -- // see the Platform Builder documentation for details. The main battery // level count is reported in the low word of the return value; the count // for the backup battery is in the high word. LONG BatteryPDDGetLevels( void ) { LONG lLevels = MAKELONG (3 /* main battery levels */, 3 /* backup battery levels */); SETFNAME(_T("BatteryPDDPowerHandler")); DEBUGMSG(ZONE_PDD, (_T("%s: returning %u (%d main levels, %d backup levels)\r\n"), pszFname, LOWORD(lLevels), HIWORD(lLevels))); return lLevels; } // This routine returns TRUE to indicate that the pfBatteriesChangedSinceLastCall // value filled in by BatteryPDDGetStatus() is valid. If there is no way to // tell that the platform's batteries have been changed this routine should // return FALSE. BOOL BatteryPDDSupportsChangeNotification( void ) { BOOL fSupportsChange = FALSE; SETFNAME(_T("BatteryPDDPowerHandler")); DEBUGMSG(ZONE_PDD, (_T("%s: returning %d\r\n"), pszFname, fSupportsChange)); return fSupportsChange; }