📄 pcf50606.c
字号:
if(IOCTL_SET_PCF_LED1 == dwCode)
{
PCFSetLEDState(pPCF50606, 1, pIn->OffOnBlink, &OnTime, &OffTime);
}
else
{
PCFSetLEDState(pPCF50606, 2, pIn->OffOnBlink, &OnTime, &OffTime);
}
fRetVal = TRUE;
//Fill in the actual values used
if(pBufOut != NULL && dwLenOut == sizeof(struct NLED_SETTINGS_INFO))
{
pOut->LedNum = pIn->LedNum;
pOut->OffOnBlink = pIn->OffOnBlink;
pOut->TotalCycleTime = OnTime + OffTime; //although TotalCycleTime is not used, nledtest.dll requires it be a returned value
pOut->OnTime = OnTime;
pOut->OffTime = OffTime;
pOut->MetaCycleOn = 0;
pOut->MetaCycleOff = 0;
if(pdwActualOut)
{
*pdwActualOut = sizeof(struct NLED_SETTINGS_INFO);
}
}
else
{
if(pdwActualOut)
{
*pdwActualOut = 0;
}
}
}
__except(EXCEPTION_EXECUTE_HANDLER) {
SetLastError(ERROR_INVALID_PARAMETER);
DEBUGMSG(ZONE_ERROR, (_T("%s: IOCTL_SET_PCF_LEDx: exception accessing IOCTL Parameter.\r\n"), pszFname));
}
}
break;
default:
SetLastError(ERROR_NOT_SUPPORTED);
}
return fRetVal;
}
void PCF50606Initialize(PPCF50606 pPCF50606)
{
DWORD bytesReturned;
PPCFBATTERY pPcfBattery = &pPCF50606->pcfBattery;
DEBUGMSG(ZONE_VERBOSE, (TEXT("++PCF50606Initialize\r\n")));
//
// Read On/Off control status register from PCF50606
// (this will clear the interrupts)
//
bytesReturned = PDD_I2CRead(&pPCF50606->csI2CAccess,
pPCF50606->v_pI2CRegs,
pPCF50606->v_pOstRegs,
OOCS,
pPCF50606->pcfRegisterCache+OOCS,
3);
DEBUGMSG(ZONE_VERBOSE, (TEXT("PCF50606: Read On/Off control status reg = %x\r\n"), pPCF50606->pcfRegisterCache[OOCS]));
//
// Read Interrupt controller status register 1,2,3 from PCF50606
// (this will clear the interrupts)
//
bytesReturned = PDD_I2CRead(&pPCF50606->csI2CAccess,
pPCF50606->v_pI2CRegs,
pPCF50606->v_pOstRegs,
INT1,
pPCF50606->pcfRegisterCache+INT1,
3);
DEBUGMSG(ZONE_VERBOSE, (TEXT("PCF50606: Read interrupt cntrl reg, 1:%x 2:%x 3:%x\r\n"),
pPCF50606->pcfRegisterCache[INT1],
pPCF50606->pcfRegisterCache[INT2],
pPCF50606->pcfRegisterCache[INT3]));
// Has ONKEY been pressed for 1 second
if(pPCF50606->pcfRegisterCache[INT1] & INT1_ONKEY1S)
{
// Reset timeout timer
bytesReturned = PDD_I2CRead(&pPCF50606->csI2CAccess,
pPCF50606->v_pI2CRegs,
pPCF50606->v_pOstRegs,
OOCC1,
pPCF50606->pcfRegisterCache+OOCC1,
1);
pPCF50606->pcfRegisterCache[OOCC1] &= ~OOCC1_TOTRST;
pPCF50606->pcfRegisterCache[OOCC1] |= OOCC1_TOTRST;
bytesReturned = PDD_I2CWrite(&pPCF50606->csI2CAccess,
pPCF50606->v_pI2CRegs,
pPCF50606->v_pOstRegs,
OOCC1,
pPCF50606->pcfRegisterCache+OOCC1,
1);
}
//
// Setup and start ADC
//
// NTCSW bias disabled
pPCF50606->pcfRegisterCache[ADCC1] = ADCC1_NTCSWAOFF;
// ADC Start for BATVOLT, no external sync
pPCF50606->pcfRegisterCache[ADCC2] = ADCC2_ADCSYNC_M(NO_SYNC) |
ADCC2_START;
// Write to PCF50606
bytesReturned = PDD_I2CWrite(&pPCF50606->csI2CAccess,
pPCF50606->v_pI2CRegs,
pPCF50606->v_pOstRegs,
ADCC1,
pPCF50606->pcfRegisterCache+ADCC1,
2);
// Read Battery voltage from PCF50606
bytesReturned = PDD_I2CRead(&pPCF50606->csI2CAccess,
pPCF50606->v_pI2CRegs,
pPCF50606->v_pOstRegs,
ADCS1,
pPCF50606->pcfRegisterCache+ADCS1,
2);
DEBUGMSG(ZONE_VERBOSE, (TEXT("PCF50606: Read Battery Voltage: %x\r\n"),
(pPCF50606->pcfRegisterCache[ADCS1] << 2) | (pPCF50606->pcfRegisterCache[ADCS2] & 0x3)));
//
// Battery voltage monitor (BVM)
//
pPCF50606->pcfRegisterCache[BVMC] = BVMC_THRSHLD_M(VOLTS_3_40);
bytesReturned = PDD_I2CWrite(&pPCF50606->csI2CAccess,
pPCF50606->v_pI2CRegs,
pPCF50606->v_pOstRegs,
INT1M,
pPCF50606->pcfRegisterCache+BVMC,
(DWORD)1);
// Set Battery Voltage Delta Persistance Counter to 0
pPcfBattery->dwBattVoltageDeltaPersist = 0;
//
// Read Main battery charger mode and status from PCF50606
//
bytesReturned = PDD_I2CRead(&pPCF50606->csI2CAccess,
pPCF50606->v_pI2CRegs,
pPCF50606->v_pOstRegs,
MBCC1,
pPCF50606->pcfRegisterCache+MBCC1,
3);
DEBUGMSG(ZONE_VERBOSE, (TEXT("PCF50606: Read Charger mode: %x\r\n"),
pPCF50606->pcfRegisterCache[MBCC1]));
bytesReturned = PDD_I2CRead(&pPCF50606->csI2CAccess,
pPCF50606->v_pI2CRegs,
pPCF50606->v_pOstRegs,
MBCS1,
pPCF50606->pcfRegisterCache+MBCS1,
1);
DEBUGMSG(ZONE_VERBOSE, (TEXT("PCF50606: Read Charger status: %x\r\n"),
pPCF50606->pcfRegisterCache[MBCS1]));
//
// Set the charger control voltage to 4.22V
//
pPCF50606->pcfRegisterCache[MBCC3] = MBCC3_CURRAT_M(CHRG_I_400mA) | MBCC3_VCHGCON_M(CHRG_V_4_22);
bytesReturned = PDD_I2CWrite(&pPCF50606->csI2CAccess,
pPCF50606->v_pI2CRegs,
pPCF50606->v_pOstRegs,
MBCC3,
pPCF50606->pcfRegisterCache+MBCC3,
1);
//
// Start the charger (set AUTOFST, Charge mode = Fast CCCV)
//
if((pPCF50606->pcfRegisterCache[MBCS1] & MBCS1_CHGVIN_STAT_M(WITHIN_LIMITS)))
{
StartCharger(pPCF50606);
}
// Clear all PCF50606 interrupts by reading interrupt status from PCF50606
bytesReturned = PDD_I2CRead(&pPCF50606->csI2CAccess,
pPCF50606->v_pI2CRegs,
pPCF50606->v_pOstRegs,
INT1,
pPCF50606->pcfRegisterCache+INT1,
(DWORD)3);
pPCF50606->pcfRegisterCache[INT1]=0x00;
pPCF50606->pcfRegisterCache[INT2]=0x00;
pPCF50606->pcfRegisterCache[INT3]=0x00;
//
// Set Interrupt mask registers
//
// Input interrupt masks
pPCF50606->pcfRegisterCache[INT1M] = ~INT1MASK_RUN_DEFAULT;
// Charger interrupt masks
pPCF50606->pcfRegisterCache[INT2M] = ~INT2MASK_RUN_DEFAULT;
// Analog interrupt masks
pPCF50606->pcfRegisterCache[INT3M] = ~INT3MASK_RUN_DEFAULT;
// Write to PCF50606
bytesReturned = PDD_I2CWrite(&pPCF50606->csI2CAccess,
pPCF50606->v_pI2CRegs,
pPCF50606->v_pOstRegs,
INT1M,
pPCF50606->pcfRegisterCache+INT1M,
(DWORD)3);
}
// Power state monitor thread
INT WINAPI PwrMonThread(void)
{
HANDLE hNotifications;
MSGQUEUEOPTIONS msgOptions = {0};
// Create a message queue for Power Manager notifications.
msgOptions.dwSize = sizeof(MSGQUEUEOPTIONS);
msgOptions.dwFlags = 0;
msgOptions.dwMaxMessages = QUEUE_ENTRIES;
msgOptions.cbMaxMessage = sizeof(POWER_BROADCAST) + MAX_NAMELEN;
msgOptions.bReadAccess = TRUE;
m_hReadMsgQ = CreateMsgQueue(NULL, &msgOptions);
if ( m_hReadMsgQ == NULL )
{
DEBUGMSG(ZONE_ERROR, (TEXT("PWM: CreateMsgQueue(Read): error %d\r\n"), GetLastError()));
g_FlagExitThrd = TRUE;
}
// Request Power notifications
hNotifications = RequestPowerNotifications(m_hReadMsgQ, POWER_NOTIFY_ALL);
if ( ! hNotifications )
{
DEBUGMSG(ZONE_ERROR, (TEXT("PWM: RequestPowerNotifications: error %d\r\n"), GetLastError()));
g_FlagExitThrd = TRUE;
}
while(!g_FlagExitThrd)
{
int iBytesInQueue = 0;
DWORD dwFlags;
UCHAR buf[QUEUE_SIZE];
PPOWER_BROADCAST pB = (PPOWER_BROADCAST) buf;
memset(buf, 0, QUEUE_SIZE);
DEBUGMSG(ZONE_VERBOSE, (TEXT("PWM: Waiting for PM state transition notification\r\n")));
// Read message from queue.
if ( ! ReadMsgQueue(m_hReadMsgQ, buf, QUEUE_SIZE, &iBytesInQueue, INFINITE, &dwFlags) )
{
if(g_FlagExitThrd)
break;
DEBUGMSG(1, (TEXT("PWM: ReadMsgQueue: ERROR:%d\r\n"), GetLastError()));
}
else if ( iBytesInQueue < sizeof(POWER_BROADCAST) )
{
DEBUGMSG(ZONE_VERBOSE, (TEXT("PWM: Received short message: %d bytes, expected: %d\r\n"),
iBytesInQueue, sizeof(POWER_BROADCAST)));
}
else
{
switch ( pB->Message )
{
case PBT_TRANSITION:
DEBUGMSG(1, (TEXT("PWM: PBT_TRANSITION to system power state [Flags: 0x%x]: '%s'\r\n"),
pB->Flags, pB->SystemPowerState));
switch ( POWER_STATE(pB->Flags) )
{
case POWER_STATE_ON:
DEBUGMSG(1, (TEXT("PWM: POWER_STATE_ON\r\n")));
break;
case POWER_STATE_OFF:
DEBUGMSG(1, (TEXT("PWM: POWER_STATE_OFF\r\n")));
break;
case POWER_STATE_CRITICAL:
DEBUGMSG(1, (TEXT("PWM: POWER_STATE_CRITICAL\r\n")));
break;
case POWER_STATE_BOOT:
DEBUGMSG(1, (TEXT("PWM: POWER_STATE_BOOT\r\n")));
break;
case POWER_STATE_IDLE:
DEBUGMSG(1, (TEXT("PWM: POWER_STATE_IDLE\r\n")));
break;
case POWER_STATE_USERIDLE:
DEBUGMSG(1, (TEXT("PWM: POWER_STATE_USERIDLE\r\n")));
break;
case POWER_STATE_SUSPEND:
DEBUGMSG(1, (TEXT("PWM: POWER_STATE_SUSPEND\r\n")));
break;
case POWER_STATE_RESET:
DEBUGMSG(1, (TEXT("PWM: POWER_STATE_RESET\r\n")));
break;
case POWER_STATE_PASSWORD:
DEBUGMSG(1, (TEXT("PWM: POWER_STATE_PASSWORD\r\n")));
break;
case 0:
DEBUGMSG(1,(TEXT("PWM: Power State Flags:0x%x\r\n"),pB->Flags));
break;
default:
DEBUGMSG(1,(TEXT("PWM: Unknown Power State Flags:0x%x\r\n"),pB->Flags));
break;
}
break;
case PBT_RESUME:
{
DEBUGMSG(1, (TEXT("PWM: PBT_RESUME\r\n")));
// If Keybd or PMIC resumed the system set the system state to ON
{
DWORD wakeSrc = SYSWAKE_UNKNOWN;
DWORD bytesRet= 0;
if (KernelIoControl(IOCTL_HAL_GET_WAKE_SOURCE, NULL, 0, &wakeSrc, sizeof(wakeSrc), &bytesRet) &&
(bytesRet == sizeof(wakeSrc)))
{
if (SYSINTR_KEYPAD == wakeSrc ||
SYSINTR_PCF50606 == wakeSrc)
{
DEBUGMSG(1, (TEXT("PWM: Wake src is %s. Setting POWER_STATE_ON\r\n"), (wakeSrc == SYSINTR_KEYPAD) ? TEXT("SYSINTR_KEYPAD") : TEXT("SYSINTR_PCF50606")));
SetSystemPowerState(NULL, POWER_STATE_ON, POWER_FORCE);
}
}
else
{
NKDbgPrintfW(L"PWM: Error getting wake source\r\n");
}
}
break;
}
case PBT_POWERSTATUSCHANGE:
DEBUGMSG(1, (TEXT("PWM: PBT_POWERSTATUSCHANGE\r\n")));
break;
case PBT_POWERINFOCHANGE:
{
PPOWER_BROADCAST_POWER_INFO ppbpi = (PPOWER_BROADCAST_POWER_INFO) pB->SystemPowerState;
DEBUGMSG(1, (TEXT("PWM: PBT_POWERINFOCHANGE\r\n")));
DEBUGMSG(1, (TEXT("PWM: \tAC line status %u, battery flag %u, backup flag %u, %d levels\r\n"),
ppbpi->bACLineStatus, ppbpi->bBatteryFlag,
ppbpi->bBackupBatteryFlag, ppbpi->dwNumLevels));
break;
}
default:
DEBUGMSG(1, (TEXT("PWM: Unknown Message:%d\r\n"), pB->Message));
break;
}
}
}
if ( hNotifications )
{
StopPowerNotifications(hNotifications);
hNotifications = NULL;
}
if ( m_hReadMsgQ )
{
CloseMsgQueue(m_hReadMsgQ);
m_hReadMsgQ = NULL;
}
DEBUGMSG(1, (TEXT("PWM: PwrMonThread Exiting\r\n")));
return 0;
}
BOOL WINAPI DllMain(HANDLE hinstDLL,
DWORD dwReason,
LPVOID lpvReserved)
{
switch(dwReason)
{
case DLL_PROCESS_ATTACH :
RETAILREGISTERZONES(hinstDLL);
DEBUGMSG(ZONE_VERBOSE, (TEXT("PCF: DllMain(DLL_PROCESS_ATTACH)\r\n")));
// don't need thread attach/detach messages
DisableThreadLibraryCalls (hinstDLL);
break;
default:
break;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -