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

📄 init2c.c

📁 Wince6环境下
💻 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.
//
//
// (C) Copyright 2006 Marvell International Ltd.
// All Rights Reserved
//
/* 
** INTEL CONFIDENTIAL
** Copyright 2000-2006 Intel Corporation All Rights Reserved.
**
** The source code contained or described herein and all documents
** related to the source code (Material) are owned by Intel Corporation
** or its suppliers or licensors.  Title to the Material remains with
** Intel Corporation or its suppliers and licensors. The Material contains
** trade secrets and proprietary and confidential information of Intel
** or its suppliers and licensors. The Material is protected by worldwide
** copyright and trade secret laws and treaty provisions. No part of the
** Material may be used, copied, reproduced, modified, published, uploaded,
** posted, transmitted, distributed, or disclosed in any way without Intel抯
** prior express written permission.
**
** No 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. Any license under such intellectual property rights
** must be express and approved by Intel in writing.
*/
/**
**  FILENAME:       xllp_i2c.c
**
**  PURPOSE:        Xllp i2c file
**
**
******************************************************************************/

#include "xllp_i2c.h"
#include "xllp_mfp_plat.h"

#ifdef XLLP_MFP_SCL_OFFSET
// only valid if pins are assigned to non-Power I2C
static XLLP_UINT32_T xllp_i2c_mfp_list[] ={ 	XLLP_MFP_SCL_OFFSET,
					 	XLLP_MFP_SDA_OFFSET,
					 	XLLP_MFP_PIN_EOLIST_MARKER};
static XLLP_MFP_ALT_FN_T xllp_i2c_af_list[] = { XLLP_MFP_SCL_AF, 
						XLLP_MFP_SDA_AF};


#endif// def XLLP_MFP_SCL_OFFSET
static XLLP_MFP_DRIVE_STRENGTH_T xllp_i2c_ds_list[] ={	XLLP_MFP_DEFAULT_DS,
							XLLP_MFP_DEFAULT_DS};

static XLLP_MFP_LPM_OUTPUT_T xllp_i2c_lpm_output_list[] = {
				XLLP_MFP_SCL_LPM,
				XLLP_MFP_SDA_LPM
				};

#ifdef XLLP_MFP_SCL_OFFSET
// only valid if pins are assigned to non-Power I2C
    
/* 
 * 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 PXA
 *
 * RETURNS: XLLP_STATUS_SUCCESS
 *          XLLP_STATUS_WRONG_PARAMETER
 *          XLLP_STATUS_NO_RESOURCES
 * 
 *  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_STATUS_T XllpI2cInit(P_XLLP_I2C_T I2C_regs,
			      P_XLLP_VUINT32_T pMfpRegBase,
			      P_XLLP_MFP_RM_DB_ID_T pMfpRmDb, 
				XLLP_UINT32_T dev_id) 
{
	XLLP_STATUS_T re;
	
#ifdef XLLP_DEBUG_PARAM_CHECK
	if (NULL == I2C_regs || NULL == pMfpRegBase || NULL == pMfpRmDb)
		return XLLP_STATUS_WRONG_PARAMETER;
	
#endif
	I2C_regs->XLLP_ICR = 0;
	re = XllpMfpResourceManager_List(pMfpRmDb, xllp_i2c_mfp_list,
					XLLP_MFP_RM_ID_XLLP_I2C, XLLP_SET);
	
	//XLLP_STATUS_WRONG_PARAMETER
	//XLLP_STATUS_NO_RESOURCES
	if (XLLP_STATUS_SUCCESS != re) {
		return re;
	}
	//XLLP_STATUS_WRONG_PARAMETER
	re = XllpMfpSetAfDs_List(pMfpRegBase, 
				xllp_i2c_mfp_list,
				xllp_i2c_af_list, 
				xllp_i2c_ds_list);
	if (XLLP_STATUS_SUCCESS != re) {
		XllpMfpResourceManager_List(pMfpRmDb, xllp_i2c_mfp_list,
					     XLLP_MFP_RM_ID_XLLP_I2C, XLLP_CLEAR);
		return re;
	}
	re =  XllpMfpActivatePullUpDown_List(pMfpRegBase, xllp_i2c_mfp_list, XLLP_OFF);

	if (re != XLLP_STATUS_SUCCESS) {
                XllpMfpResourceManager_List(pMfpRmDb, xllp_i2c_mfp_list,
                                             XLLP_MFP_RM_ID_XLLP_I2C, XLLP_CLEAR);
                return re;
        }
	/* Setup I2C slave address */ 
	I2C_regs->XLLP_ISAR = dev_id;
	I2C_regs->XLLP_ICR = XLLP_ICR_SCLEA;
	I2C_regs->XLLP_ICR |= XLLP_ICR_UIE;
	return (XLLP_STATUS_SUCCESS);
}//end XllpI2cInit


#endif// def XLLP_MFP_SCL_OFFSET
    
/* 
 * 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 PXA
 *
 * RETURNS: XLLP_STATUS_WRONG_PARAMETER
 *			XLLP_STATUS_SUCCESS			
 */ 
 XLLP_STATUS_T XllpPI2cInit(P_XLLP_I2C_T I2C_regs, XLLP_UINT32_T dev_id) 
{
	
#ifdef XLLP_DEBUG_PARAM_CHECK
	if (NULL == I2C_regs)
		return XLLP_STATUS_WRONG_PARAMETER;
	
#endif	
	I2C_regs->XLLP_ICR = 0;
	/* Setup I2C slave address */ 
	I2C_regs->XLLP_ISAR = dev_id;
	I2C_regs->XLLP_ICR = XLLP_ICR_SCLEA;
	I2C_regs->XLLP_ICR |= XLLP_ICR_UIE;
	return (XLLP_STATUS_SUCCESS);
}//end XllpPi2cinit


/* 
 * Wait for Receive empty status
 *
 * RETURNS: XLLP_STATUS_SUCCESS success
 *          XLLP_STATUS_TIME_OUT time out
 */ 
    XLLP_STATUS_T XllpI2cRxFull(P_XLLP_I2C_T I2C_regs, XLLP_OST_T * pOSTRegs,
				XLLP_INT32_T timeout) 
{
	XLLP_UINT32_T temp;
    XLLP_UINT32_T    ticks;
    XLLP_UINT32_T microseconds = timeout * 200;
    XLLP_UINT32_T    start_time;
    start_time = pOSTRegs->oscr0;
    ticks = microseconds * XLLP_OST_TICKS_US;  // approx. 3 ticks per microsecond. 

	while (1)
		{
            XLLP_UINT32_T time = pOSTRegs->oscr0 - start_time;
		temp = I2C_regs->XLLP_ISR;
		if ((temp & XLLP_ISR_IRF) == XLLP_ISR_IRF)
			{
			I2C_regs->XLLP_ISR = temp | XLLP_ISR_IRF;
			return XLLP_STATUS_SUCCESS;
			}
		
                if (time > ticks)
                        return XLLP_STATUS_TIME_OUT;
		    // delay 0.2 ms here
		    //XllpOstDelayMicroSeconds(pOSTRegs, 200);
		}
	return XLLP_STATUS_TIME_OUT;
}


/* Wait for transmit empty status
 *
 * RETURNS:
 *	XLLP_STATUS_SUCCESS
 *	XLLP_STATUS_TIME_OUT
 */ 
    XLLP_STATUS_T XllpI2cTxEmpty(P_XLLP_I2C_T I2C_regs, XLLP_OST_T * pOSTRegs,
				 XLLP_INT32_T timeout) 
{
	XLLP_UINT32_T temp;
    XLLP_UINT32_T    ticks;
    XLLP_UINT32_T microseconds = timeout * 200;
    XLLP_UINT32_T    start_time;
    start_time = pOSTRegs->oscr0;
    ticks = microseconds * XLLP_OST_TICKS_US;  // approx. 3 ticks per microsecond. 

	while (1)
		{
                XLLP_UINT32_T time = pOSTRegs->oscr0 - start_time;
		temp = I2C_regs->XLLP_ISR;
		if ((temp & XLLP_ISR_ITE) == XLLP_ISR_ITE)
			{
			I2C_regs->XLLP_ISR = temp | XLLP_ISR_ITE;
			if ((temp & XLLP_ISR_ALD) == XLLP_ISR_ALD)
				{
				I2C_regs->XLLP_ISR |= XLLP_ISR_ALD;
				}
			return XLLP_STATUS_SUCCESS;
			}
		//XllpOstDelayMicroSeconds(pOSTRegs, 200);
                if (time > ticks)
                     return XLLP_STATUS_TIME_OUT;
		}
	return XLLP_STATUS_TIME_OUT;
}//end XllpI2cIxEmpty

XLLP_STATUS_T XllpI2CWrite(P_XLLP_I2C_T I2C_regs, 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;
	
#ifdef XLLP_DEBUG_PARAM_CHECK
	if (NULL == I2C_regs || NULL == pOSTRegs)
		return XLLP_STATUS_WRONG_PARAMETER;
	
#endif
	I2C_regs->XLLP_IDBR = (slaveAddr << 1) & ~XLLP_IDBR_MODE;
	reg = I2C_regs->XLLP_ICR;
	reg |= (XLLP_ICR_START | XLLP_ICR_TB);
	reg &= ~(XLLP_ICR_STOP | XLLP_ICR_ALDIE);
	I2C_regs->XLLP_ICR = reg;
	if (XllpI2cTxEmpty(I2C_regs, pOSTRegs, 20) == XLLP_STATUS_TIME_OUT)
		{
		return XLLP_STATUS_TIME_OUT;
		}
	
	    // Send all the bytes
	    while (bytesCount--)
		{
		I2C_regs->XLLP_IDBR = (XLLP_UINT32_T) (*bytesBuf++);
		reg = I2C_regs->XLLP_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->XLLP_ICR = reg;
		if (XllpI2cTxEmpty(I2C_regs, pOSTRegs, 250) == XLLP_STATUS_TIME_OUT)
			{
			return XLLP_STATUS_TIME_OUT;
			}
		}
	
	    // Clear the STOP bit always
	    I2C_regs->XLLP_ICR &= ~XLLP_ICR_STOP;
	return XLLP_STATUS_SUCCESS;
}//end XllpI2CWrite

XLLP_STATUS_T XllpI2CRead(P_XLLP_I2C_T I2C_regs, XLLP_OST_T * pOSTRegs,
			    XLLP_UINT8_T slaveAddr, XLLP_UINT8_T * bytesBuf,
			    XLLP_UINT32_T bytesCount, XLLP_BOOL_T bSendStop) 
{
	XLLP_UINT32_T reg;
	
#ifdef XLLP_DEBUG_PARAM_CHECK
	    if (NULL == I2C_regs || NULL == pOSTRegs)
		return XLLP_STATUS_WRONG_PARAMETER;
	
#endif
	I2C_regs->XLLP_IDBR = (slaveAddr << 1) | XLLP_IDBR_MODE;
	reg = I2C_regs->XLLP_ICR;
	reg |= (XLLP_ICR_START | XLLP_ICR_TB);
	reg &= ~(XLLP_ICR_STOP | XLLP_ICR_ALDIE);
	I2C_regs->XLLP_ICR = reg;
	if (XllpI2cTxEmpty(I2C_regs, pOSTRegs, 20) == XLLP_STATUS_TIME_OUT)
		{
		return XLLP_STATUS_TIME_OUT;
		}
	while (bytesCount--)
		{
		reg = I2C_regs->XLLP_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->XLLP_ICR = reg;
		if (XllpI2cRxFull(I2C_regs, pOSTRegs, 60) == XLLP_STATUS_TIME_OUT)
			{
			return XLLP_STATUS_TIME_OUT;
			}
		reg = I2C_regs->XLLP_IDBR & 0xFF;
		*bytesBuf++ = (XLLP_UINT8_T) reg;
		}
	I2C_regs->XLLP_ICR &= ~(XLLP_ICR_STOP | XLLP_ICR_ACKNACK);
	return XLLP_STATUS_SUCCESS;
}//end XllpI2CRead

XLLP_I2C_SPEED_T XllpGetSpeed(P_XLLP_I2C_T I2C_regs) 
{
	
#ifdef XLLP_DEBUG_PARAM_CHECK
	if (NULL == I2C_regs)
		return XLLP_STATUS_WRONG_PARAMETER;
	
#endif
	return ((I2C_regs->
		XLLP_ICR & XLLP_ICR_FM) ? XLLP_I2C_FAST_SPEED :
		XLLP_I2C_NORMAL_SPEED);
}//end XllpGetSpeed

XLLP_I2C_SPEED_T XllpSetSpeed(P_XLLP_I2C_T I2C_regs, XLLP_I2C_SPEED_T speed) 
{
	
#ifdef XLLP_DEBUG_PARAM_CHECK
	    if (NULL == I2C_regs)
		return XLLP_STATUS_WRONG_PARAMETER;
	
#endif
	XLLP_UINT32_T tem;
	XLLP_I2C_SPEED_T pre_speed = XllpGetSpeed(I2C_regs);
	switch (speed) {
	case XLLP_I2C_FAST_SPEED:
		I2C_regs->XLLP_ICR |= XLLP_ICR_FM;
	
	//Be sure the configureation takes effect in case of split transaction problem
		tem = I2C_regs->XLLP_ICR;
		return pre_speed;
		break;
	default:
		I2C_regs->XLLP_ICR &= (~XLLP_ICR_FM);
		
	//Be sure the configuration takes effect in case of split transaction problem
		tem = I2C_regs->XLLP_ICR;
		return pre_speed;
	}
}//end XllpSetSpeed

⌨️ 快捷键说明

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