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

📄 pcf50606.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
📖 第 1 页 / 共 3 页
字号:
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

BOOL
PCF_Close(
  DWORD hOpenContext )
{
    BOOL fRetVal = FALSE;
    PPCF50606OPEN pContext = NULL;
    PPCF50606OPEN pPcf50606Open = (PPCF50606OPEN)hOpenContext;
    PPCF50606 pPCF50606 = (PPCF50606)pPcf50606Open->pPCF50606Device;

    DEBUGMSG(ZONE_VERBOSE, (TEXT("PCF_Close()\r\n")));

    // Walk the list to find the open context and delete it.
    pContext = (PPCF50606OPEN)pPCF50606->pOpenContextHead;

    // Head cannot be null if we are here
    DEBUGCHK(NULL != pContext);

    if (pContext->next == NULL)
    {
        // This means there is only one open context
        ASSERT(pPcf50606Open->dwIndex = pContext->dwIndex);
        
        // Deleting the only open context
        CloseMsgQueue(pContext->msgQueuePCFRead);
        LocalFree(pContext);  
        pPCF50606->pOpenContextHead = NULL;
        pPCF50606->dwOpenCount = 0;

        return TRUE;
    }

    // Walk the list to find the index we are going to close.
    while (pContext->next != NULL &&
        ((PPCF50606OPEN)(pContext->next))->dwIndex != pPcf50606Open->dwIndex)
    {
        pContext = (PPCF50606OPEN)pContext->next;
    }

    if (pContext->next == NULL)
    {
        // This should not happen. We couldn't find the open index in our list
        DEBUGCHK(0);
        fRetVal = FALSE;
    }
    else
    {
        // Found it! Free up the resources
        pContext->next = ((PPCF50606OPEN)(pContext->next))->next;
        pContext = (PPCF50606OPEN)pContext->next;
        CloseMsgQueue(pContext->msgQueuePCFRead);
        LocalFree(pContext);  
        pContext = NULL;
        fRetVal = TRUE;
    }
    
    return fRetVal;
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

DWORD
PCF_Read(
  DWORD hOpenContext,
  LPVOID pBuffer,
  DWORD Count)
{
    DEBUGMSG(ZONE_VERBOSE, (TEXT("PCF_Read()\r\n")));
    return((DWORD) -1);
}


// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

DWORD
PCF_Write(
  DWORD hOpenContext,
  LPCVOID pBuffer,
  DWORD Count)
{
    DEBUGMSG(ZONE_VERBOSE, (TEXT("PCF_Write()\r\n")));
    return((DWORD) -1);
}



// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

DWORD
PCF_Seek(
  DWORD hOpenContext,
  long Amount,
  WORD Type)
{
    DEBUGMSG(ZONE_VERBOSE, (TEXT("PCF_Seek()\r\n")));
    return((DWORD) -1);
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

void
PCF_PowerUp(DWORD hDeviceContext)
{
    DWORD bytesReturned;
    PPCF50606 pPCF50606 = (PPCF50606)hDeviceContext;

    RETAILMSG(ZONE_VERBOSE, (TEXT("PCF50606: PCF_PowerUp.\r\n")));

    // Initial low level I2C processor registers;
    XllpPI2CInit((P_XLLP_PI2C_T)pPCF50606->v_pPI2CRegs,
                 (P_XLLP_GPIO_T)pPCF50606->v_pGPIORegs,
                 (P_XLLP_CLKMGR_T)pPCF50606->v_pClkRegs,
                 (XLLP_UINT32_T)0);
    
    // 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);

    // Turn on falling edge detection
    pPCF50606->v_pGPIORegs->GFER0 |= XLLP_BIT_0;

    // Clear pending edge interrupt
    pPCF50606->v_pGPIORegs->GEDR0 &= ~(XLLP_BIT_0);
}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

void
PCF_PowerDown(
  DWORD hDeviceContext)
{
    DWORD bytesReturned;
    PPCF50606 pPCF50606 = (PPCF50606)hDeviceContext;
    
    //
    // Set Interrupt mask registers to set which of the pcf50606 interrupts
    // will interrupt and wake up the host from sleep
    //

    // Input interrupt masks
    pPCF50606->pcfRegisterCache[INT1M] = ~INT1MASK_SLEEP_DEFAULT;

    // Charger interrupt masks
    pPCF50606->pcfRegisterCache[INT2M] = ~INT2MASK_SLEEP_DEFAULT;

    // Analog interrupt masks
    pPCF50606->pcfRegisterCache[INT3M] = ~INT3MASK_SLEEP_DEFAULT;

    // Write to PCF50606
    bytesReturned = PDD_I2CWrite(&pPCF50606->csI2CAccess,
                                 pPCF50606->v_pI2CRegs,
                                 pPCF50606->v_pOstRegs,
                                 INT1M,
                                 pPCF50606->pcfRegisterCache+INT1M,
                                 (DWORD)3);   

     
    // turn off the 3.3V_A1 supply rail
    pPCF50606->pcfRegisterCache[D3REGC1] = 0xd8;
    bytesReturned = PDD_I2CWrite(&pPCF50606->csI2CAccess,
                                 pPCF50606->v_pI2CRegs,
                                 pPCF50606->v_pOstRegs,
                                 D3REGC1,
                                 pPCF50606->pcfRegisterCache+D3REGC1,
                                 (DWORD)1);  
    
}

static BOOL PCFSetLEDState(PPCF50606 pPCF50606, UCHAR cLedNum, INT OffOnBlink, LONG *OnTime, LONG *OffTime)
{
    BOOL fRetVal = FALSE;
    UCHAR cGPOCRegisterAddress = 0;
    UCHAR cLEDCRegisterAddress = 0;
    UCHAR cPeriodValue = 0;
    UCHAR cOnTimeValue = 0;
    SETFNAME(_T("PCFSetLEDState"));
    LONG TotalCycleTime = *OnTime + *OffTime;

    //basic parameter checking
    if((0 > OffOnBlink) || (2 < OffOnBlink))
    {
        DEBUGMSG(ZONE_ERROR, 
            (_T("%s: Invalid OffOnBlink state 0x%x\r\n"), pszFname, OffOnBlink));
        SetLastError(ERROR_INVALID_PARAMETER);
    }
    else if((0 >= *OnTime) ||
            (0 >= *OffTime))
    {
        DEBUGMSG(ZONE_ERROR, 
            (_T("%s: Negative or Zero OnTime (%duSec) or OffTime(%duSec) time.\r\n"), pszFname, *OnTime, *OffTime));
        SetLastError(ERROR_INVALID_PARAMETER);
    }
    else
    {
        fRetVal = TRUE;
    }

    if(fRetVal)
    {
        if(1 == cLedNum)
        {
            cGPOCRegisterAddress = GPOC2;
            cLEDCRegisterAddress = LEDC1;
        }
        else
        {
            cGPOCRegisterAddress = GPOC3;
            cLEDCRegisterAddress = LEDC2;
        }

        //OFF
        if(0 == OffOnBlink) 
        {
            //Tristate Output 
            pPCF50606->pcfRegisterCache[cGPOCRegisterAddress] = 0;
            
            PDD_I2CWrite(&pPCF50606->csI2CAccess,
                 pPCF50606->v_pI2CRegs,
                 pPCF50606->v_pOstRegs,
                 cGPOCRegisterAddress,
                 pPCF50606->pcfRegisterCache+cGPOCRegisterAddress,
                 (DWORD)1);
        }
        else if(2 >= OffOnBlink) //ON or Blinking
        {
            //set Output for LED control
            pPCF50606->pcfRegisterCache[cGPOCRegisterAddress] = GPOC2_5_GPOOD_AC_M(GPOC2_5_LED1);

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

            if(1 == OffOnBlink) //ON
            {
                pPCF50606->pcfRegisterCache[cLEDCRegisterAddress] = LEDC_ACTSET | LEDC_PATTERN_M(PATTERN_ON_ALL);

                PDD_I2CWrite(&pPCF50606->csI2CAccess,
                         pPCF50606->v_pI2CRegs,
                         pPCF50606->v_pOstRegs,
                         cLEDCRegisterAddress,
                         pPCF50606->pcfRegisterCache+cLEDCRegisterAddress,
                         (DWORD)1);  
            }
            else
            {
                //match the closest cycle period possible with the period value table
                for(cPeriodValue = 0; cPeriodValue < NUM_PERIOD_OPTIIONS; cPeriodValue++)
                {
                    if(g_PcfLedPeriodOptions[cPeriodValue] > TotalCycleTime)
                    {
                        if(0 == cPeriodValue)
                        {
                            break;
                        }
                        else
                        {
                            DWORD DistanceFromA = TotalCycleTime - g_PcfLedPeriodOptions[cPeriodValue -1];
                            DWORD DistanceFromB = g_PcfLedPeriodOptions[cPeriodValue] - TotalCycleTime;

                            if(DistanceFromA > DistanceFromB)
                            {
                                break;
                            }
                            else
                            {
                                cPeriodValue--;
                                break;
                            }
                        }
                    }
                }
                if(NUM_PERIOD_OPTIIONS == cPeriodValue)
                {
                    cPeriodValue--;
                }


                //match the closest on_time possible with the on_time table
                for(cOnTimeValue = 0; cOnTimeValue < NUM_ON_TIME_OPTIIONS; cOnTimeValue++)
                {
                    if(g_PcfLedOnTimeOptions[cOnTimeValue] > *OnTime)
                    {
                        if(0 == cOnTimeValue)
                        {
                            break;
                        }
                        else
                        {
                            DWORD DistanceFromA = *OnTime - g_PcfLedOnTimeOptions[cOnTimeValue -1];
                            DWORD DistanceFromB = g_PcfLedOnTimeOptions[cOnTimeValue] - *OnTime;

                            if(DistanceFromA > DistanceFromB)
                            {
                                break;
                            }
                            else
                            {
                                cOnTimeValue--;
                                break;
                            }
                        }
                    }
                }
                if(NUM_ON_TIME_OPTIIONS == cOnTimeValue)
                {
                    cOnTimeValue--;
                }

                pPCF50606->pcfRegisterCache[cLEDCRegisterAddress] = LEDC_ACTSET | LEDC_PERIOD_M(cPeriodValue) | LEDC_PATTERN_M(cOnTimeValue);

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

                //fill in OffTime relative to period of cycle
                *OffTime = TotalCycleTime - *OnTime;
            }
        }
    }

    return fRetVal;
}


// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------

BOOL
PCF_IOControl(
  DWORD hOpenContext,
  DWORD dwCode,
  PBYTE pBufIn,
  DWORD dwLenIn,
  PBYTE pBufOut,
  DWORD dwLenOut,
  PDWORD pdwActualOut)
{
    BOOL fRetVal = FALSE;
    PPCF50606OPEN pPcf50606Open = (PPCF50606OPEN)hOpenContext;
    PPCF50606 pPCF50606 = (PPCF50606)pPcf50606Open->pPCF50606Device;
    SETFNAME(_T("PCF_IOControl"));

    // Allow only kernel mode access
    if (GetDirectCallerProcessId() != GetCurrentProcessId()) 
    {
        RETAILMSG(ZONE_ERROR, (TEXT("PCF_IOControl: User mode calls not allowed.\r\n")));
        SetLastError(ERROR_ACCESS_DENIED);
        return FALSE;
    }
    
    switch(dwCode)
    {
        case IOCTL_GET_PCF_MSGQUEUE:
            __try {
                *((PHANDLE) pBufOut) = pPcf50606Open->msgQueuePCFRead;

                if(pdwActualOut)
                {
                    *pdwActualOut = sizeof(HANDLE);
                }
                fRetVal = TRUE;
            } 

            __except(EXCEPTION_EXECUTE_HANDLER) {
                SetLastError(ERROR_INVALID_PARAMETER);
                DEBUGMSG(ZONE_ERROR, (_T("%s: IOCTL_GET_PCF_MSGQUEUE Invalid Parameter pBufOut 0x%08x\r\n"),
                    pszFname, pBufOut));
            }
            break;

        case IOCTL_GET_PCF_BATTERY_VOLTAGE:
            __try {
                *((PDWORD) pBufOut) = pPCF50606->pcfBattery.dwBatteryVolatge;

                if(pdwActualOut)
                {
                    *pdwActualOut = sizeof(DWORD);
                }
                fRetVal = TRUE;
            } 

            __except(EXCEPTION_EXECUTE_HANDLER) {
                SetLastError(ERROR_INVALID_PARAMETER);
                DEBUGMSG(ZONE_ERROR, (_T("%s: IOCTL_GET_PCF_BATTERY_VOLTAGE Invalid Parameter pBufOut 0x%08x\r\n"),
                    pszFname, pBufOut));
            }
            break;

        case IOCTL_SET_PCF_LED1:
        case IOCTL_SET_PCF_LED2:
            // sanity check parameters
            if(pBufIn != NULL && dwLenIn == sizeof(struct NLED_SETTINGS_INFO)) 
            {
                struct NLED_SETTINGS_INFO  *pIn = (struct NLED_SETTINGS_INFO*)pBufIn;
                struct NLED_SETTINGS_INFO  *pOut = (struct NLED_SETTINGS_INFO*)pBufOut;
                __try {
                    LONG OnTime = pIn->OnTime;
                    LONG OffTime = pIn->OffTime;

⌨️ 快捷键说明

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