📄 init2c.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 + -