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

📄 xllp.c

📁 Windows CE 6.0 BSP for VOIP sample phone. Intel PXA270 platform.
💻 C
字号:
//
// 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.
//


/******************************************************************************
**
**  COPYRIGHT (C) 2000, 2001 Intel Corporation.
**
** Portions of the source code contained or described herein and all documents
** related to such source code (Material) are owned by Intel Corporation
** or its suppliers or licensors and is licensed by Microsoft Corporation for distribution.  
** Title to the Material remains with Intel Corporation or its suppliers and licensors. 
** Use of the Materials is subject to the terms of the Microsoft license agreement which accompanied the Materials.  
** No other license under any patent, copyright, trade secret or other intellectual
** property right is granted to or conferred upon you by disclosure or
** delivery of the Materials, either expressly, by implication, inducement,
** estoppel or otherwise 
** Some portion of the Materials may be copyrighted by Microsoft Corporation.
**
**  FILENAME:       xllp_i2c.c
**
**  PURPOSE:        Xllp i2c file
**
**
******************************************************************************/
#include <windows.h>
#include <windev.h>
#include <types.h>
#include <memory.h>
#include <string.h>
#include <ceddk.h>

#include <bulverde_base_regs.h>
#include <plato.h>
#include <xllp_intc.h>
#include <xllp_gpio.h>
#include <xllp_clkmgr.h>
#include <xllp_ost.h>
#include <xllp_i2c.h>
#include "pcf50606.h"
#include "pmdriver.h"

#ifndef SHIP_BUILD
extern DBGPARAM dpCurSettings;
#endif

static XLLP_BOOL_T 
Xllp_I2CWrite(volatile P_XLLP_I2C_T I2C_regs, 
             volatile XLLP_OST_T *pOSTRegs, 
             XLLP_UINT8_T slaveAddr, 
             const XLLP_UINT8_T *bytesBuf, 
             XLLP_UINT32_T bytesCount, 
             XLLP_BOOL_T bSendStop);

static XLLP_BOOL_T 
Xllp_I2CRead(volatile P_XLLP_I2C_T I2C_regs, 
            volatile XLLP_OST_T *pOSTRegs, 
            XLLP_UINT8_T slaveAddr, 
            XLLP_UINT8_T * bytesBuf, 
            XLLP_UINT32_T bytesCount, 
            XLLP_BOOL_T bSendStop);

/* 
 * Initialization to use I2C bus
 *
 * PARAMETERS:
 *          P_XLLP_I2C_T I2C_regs structure for i2c regs
 *           P_XLLP_CLKMGR_T clkaddr - address of clkmanager
 *          XLLP_UINT32_T dev_id - Default slave device id for Bulverde
 *
 * RETURNS: True - failure
 *          false - success         
 */
  /*  Enable I2C Interface Unit - 
   *   
   *      XLLP_ICR_GCD  - Disable General Call (will be master)
   *      XLLP_ICR_UIE    - Enable I2C unit
   *      XLLP_ICR_SCLEA - Enable I2C Clock Generator 
   *      
   */
XLLP_BOOL_T XllpI2CInit(P_XLLP_I2C_T I2C_regs, P_XLLP_GPIO_T gpio, P_XLLP_CLKMGR_T clkMgr, XLLP_UINT32_T dev_id)
{
    I2C_regs->ICR = 0;

    clkMgr->cken |=  XLLP_CLKEN_I2C;

    gpio->GPDR3 |= (XLLP_GPIO_BIT_SCL | XLLP_GPIO_BIT_SDA);

    gpio->GAFR3_U |=  ( XLLP_GPIO_AF_BIT_SCL | XLLP_GPIO_AF_BIT_SDA);

    /* Setup I2C slave address */
    I2C_regs->ISAR =  dev_id;

    I2C_regs->ICR = XLLP_ICR_SCLEA;
    I2C_regs->ICR |= XLLP_ICR_UIE;

    return(XLLP_FALSE);
}

/* 
 * Initialization to use PWRI2C bus
 *
 * PARAMETERS:
 *          P_XLLP_I2C_T I2C_regs structure for i2c regs
 *           P_XLLP_CLKMGR_T clkaddr - address of clkmanager
 *          XLLP_UINT32_T dev_id - Default slave device id for Bulverde
 *
 * RETURNS: True - failure
 *          false - success         
 */
 /*  Enable PWRI2C Interface Unit - 
 *   
 *      
 */

XLLP_BOOL_T XllpPI2CInit(volatile P_XLLP_PI2C_T I2C_regs, 
                         volatile P_XLLP_GPIO_T gpio, 
                         volatile P_XLLP_CLKMGR_T clkMgr, 
                         XLLP_UINT32_T dev_id)
{

    clkMgr->cken |=  XLLP_CLKEN_PWRI2C;

    I2C_regs->PCFR |= 0x40;
    
    I2C_regs->ICR = 0;
    /* Setup I2C slave address */
    I2C_regs->ISAR =  dev_id;

    I2C_regs->ICR = XLLP_ICR_SCLEA;
    I2C_regs->ICR |= XLLP_ICR_UIE;

    return(XLLP_FALSE);
}


/* 
 * Wait for Receive empty status
 *
 * RETURNS: 0 success
 *          1 failure
 */
static XLLP_BOOL_T 
XllpI2CRxFull(volatile P_XLLP_I2C_T I2C_regs, 
              volatile XLLP_OST_T *pOSTRegs, 
              XLLP_INT32_T timeout)
{
    XLLP_UINT32_T temp;

    while (timeout--)
    {
        temp = I2C_regs->ISR;
        if ((temp & XLLP_ISR_IRF) == XLLP_ISR_IRF)
        {
            I2C_regs->ISR = temp | XLLP_ISR_IRF;
            return XLLP_FALSE;
        }
        // delay 1 ms here
        XllpOstDelayMilliSeconds((XLLP_OST_T *)pOSTRegs, 1);
    }

  return XLLP_TRUE;
}

/* Wait for transmit empty status
 *
 * RETURNS: 0 success
 *          1 failure
 */
static XLLP_BOOL_T 
XllpI2CTxEmpty(volatile P_XLLP_I2C_T I2C_regs, 
               volatile XLLP_OST_T *pOSTRegs, 
               XLLP_INT32_T timeout)
{
    XLLP_UINT32_T temp;

    while (timeout--)
    {
        temp = I2C_regs->ISR;
        if((temp & XLLP_ISR_ITE) == XLLP_ISR_ITE)
        {
            I2C_regs->ISR = temp | XLLP_ISR_ITE;
            if ((temp & XLLP_ISR_ALD) == XLLP_ISR_ALD)
            {
                I2C_regs->ISR |= XLLP_ISR_ALD;
            }
            return XLLP_FALSE;
        }
        // delay 1 ms here
        XllpOstDelayMilliSeconds((XLLP_OST_T *)pOSTRegs, 1);
    }
    return XLLP_TRUE;
}


static XLLP_BOOL_T 
Xllp_I2CWrite(volatile P_XLLP_I2C_T I2C_regs, 
             volatile XLLP_OST_T *pOSTRegs, 
             XLLP_UINT8_T slaveAddr, 
             const XLLP_UINT8_T * bytesBuf, 
             XLLP_UINT32_T bytesCount, 
             XLLP_BOOL_T bSendStop)
{
    XLLP_UINT32_T reg;
    int timer = 0;
    
    I2C_regs->IDBR = slaveAddr & ~XLLP_IDBR_MODE;
    reg = I2C_regs->ICR;
    reg |= (XLLP_ICR_START | XLLP_ICR_TB);
    reg &= ~(XLLP_ICR_STOP | XLLP_ICR_ALDIE);
    I2C_regs->ICR = reg;

    if (XllpI2CTxEmpty(I2C_regs, pOSTRegs,20) == XLLP_TRUE)
    {
        return XLLP_TRUE;
    }

    // Send all the bytes
    while (bytesCount--)
    {
        I2C_regs->IDBR = (XLLP_UINT32_T)(*bytesBuf++);
        
        reg = I2C_regs->ICR;
        
        reg &= ~XLLP_ICR_START;
        reg |= (XLLP_ICR_ALDIE | XLLP_ICR_TB);
        
        if ((bytesCount == 0) && bSendStop)
            reg |= XLLP_ICR_STOP;
        else
            reg &= ~XLLP_ICR_STOP;

        I2C_regs->ICR = reg;

        if (XllpI2CTxEmpty(I2C_regs, pOSTRegs, 250) == XLLP_TRUE)
        {
            return XLLP_TRUE;
        }
    }

    // Clear the STOP bit always
    I2C_regs->ICR &= ~XLLP_ICR_STOP;
    return XLLP_FALSE;
}

static XLLP_BOOL_T 
Xllp_I2CRead(volatile P_XLLP_I2C_T I2C_regs, 
            volatile XLLP_OST_T *pOSTRegs, 
            XLLP_UINT8_T slaveAddr, 
            XLLP_UINT8_T * bytesBuf, 
            XLLP_UINT32_T bytesCount, 
            XLLP_BOOL_T bSendStop)
{
    XLLP_UINT32_T reg;

    // Send device address with write bit
    I2C_regs->IDBR = slaveAddr & ~XLLP_IDBR_MODE;

    reg = I2C_regs->ICR;
    reg |= (XLLP_ICR_START | XLLP_ICR_TB);
    reg &= ~(XLLP_ICR_STOP | XLLP_ICR_ALDIE);
    I2C_regs->ICR = reg;

    if (XllpI2CTxEmpty(I2C_regs, pOSTRegs,20) == XLLP_TRUE)
    {
        return XLLP_TRUE;
    }

    // Write register address
    I2C_regs->IDBR = (XLLP_UINT32_T)(*bytesBuf++);

    reg = I2C_regs->ICR;
    reg &= ~(XLLP_ICR_START | XLLP_ICR_STOP);
    reg |= (XLLP_ICR_ALDIE | XLLP_ICR_TB);
    I2C_regs->ICR = reg;

    if (XllpI2CTxEmpty(I2C_regs, pOSTRegs, 250) == XLLP_TRUE)
    {
        return XLLP_TRUE;
    }

    // Switch to read
    I2C_regs->IDBR = slaveAddr | XLLP_IDBR_MODE;

    // Send device address with read bit
    reg = I2C_regs->ICR;
    reg |= (XLLP_ICR_START | XLLP_ICR_TB);
    reg &= ~(XLLP_ICR_STOP | XLLP_ICR_ALDIE);
    I2C_regs->ICR = reg;

    if (XllpI2CTxEmpty(I2C_regs, pOSTRegs,20) == XLLP_TRUE)
    {
        return XLLP_TRUE;
    }

    // Read consecutive device registers
    while (bytesCount--)
    {
        reg = I2C_regs->ICR;
        reg &= ~XLLP_ICR_START;
        reg |= XLLP_ICR_ALDIE | XLLP_ICR_TB;
        if (bytesCount == 0)
        {
            reg |= XLLP_ICR_ACKNACK;
            if (bSendStop)
                reg |= XLLP_ICR_STOP;
            else
                reg &= ~XLLP_ICR_STOP;
        } else
        {
            reg &= ~XLLP_ICR_ACKNACK;
        }
        I2C_regs->ICR = reg;

        if (XllpI2CRxFull(I2C_regs, pOSTRegs, 60) == XLLP_TRUE)
        {   
            return XLLP_TRUE;
        }
        reg = I2C_regs->IDBR & 0xFF;
        *bytesBuf++ = (XLLP_UINT8_T)reg;
    }

    I2C_regs->ICR &= ~(XLLP_ICR_STOP | XLLP_ICR_ACKNACK);

    return XLLP_FALSE;
}



DWORD
PDD_I2CWrite(LPCRITICAL_SECTION lpcsI2CAccess,
    volatile XLLP_I2C_T *v_pI2CRegs,
    volatile XLLP_OST_T *v_pOSTRegs,
    UCHAR cRegisterAddress,
    PUCHAR pBuffer,
    DWORD Count)
{
    UCHAR   cDataBuffer[65];

    // Add register address to top of buffer
    cDataBuffer[0] = cRegisterAddress;
    memcpy (&cDataBuffer[1], pBuffer, Count);
    Count++;

    EnterCriticalSection(lpcsI2CAccess);

    if (Xllp_I2CWrite((XLLP_I2C_T *)v_pI2CRegs, 
                     (XLLP_OST_T *) v_pOSTRegs, 
                     (XLLP_UINT8_T)PCF50606_I2C_ID, 
                     (const XLLP_UINT8_T *)cDataBuffer, 
                     Count, 
                     TRUE))
        Count = 0;

    LeaveCriticalSection(lpcsI2CAccess);

    return Count-1;
}

DWORD
PDD_I2CRead(LPCRITICAL_SECTION lpcsI2CAccess,
    volatile XLLP_I2C_T *v_pI2CRegs,
    volatile XLLP_OST_T *v_pOSTRegs,
    UCHAR cRegisterAddress,
    PUCHAR pBuffer,
    DWORD Count)
{
    UCHAR   cDataBuffer[65];

    // Add register address to top of buffer
    cDataBuffer[0] = cRegisterAddress;

    EnterCriticalSection(lpcsI2CAccess);

    if (Xllp_I2CRead((XLLP_I2C_T *)v_pI2CRegs, 
                    (XLLP_OST_T *)v_pOSTRegs, 
                    (XLLP_UINT8_T)PCF50606_I2C_ID, 
                    cDataBuffer, 
                    Count, 
                    TRUE))
        Count = 0;
    else
        // Put data in register cache
        memcpy (pBuffer, &cDataBuffer[1], Count);

    LeaveCriticalSection(lpcsI2CAccess);

    return Count;
}

⌨️ 快捷键说明

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