📄 drv_i2c.c
字号:
/******************************************************************************
**
** COPYRIGHT (C) 2000, 2001 Intel Corporation.
**
** This software as well as the software described in it is furnished under
** license and may only be used or copied in accordance with the terms of the
** license. The information in this file is furnished for informational use
** only, is subject to change without notice, and should not be construed as
** a commitment by Intel Corporation. Intel Corporation assumes no
** responsibility or liability for any errors or inaccuracies that may appear
** in this document or any software that may be provided in association with
** this document.
** Except as permitted by such license, no part of this document may be
** reproduced, stored in a retrieval system, or transmitted in any form or by
** any means without the express written consent of Intel Corporation.
**
** FILENAME: xllp_i2c.c
**
** PURPOSE: Xllp i2c file
**
** LAST MODIFIED: $Modtime: 9/17/03 9:57a $
******************************************************************************/
#include "DRV_i2c.h"
#include "xllp_intc.h"
#define DEBUG 1
/*
* Initialization to use I2C bus
*
* PARAMETERS:
* P_POST_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 -
*
* POST_ICR_GCD - Disable General Call (will be master)
* POST_ICR_UIE - Enable I2C unit
* POST_ICR_SCLEA - Enable I2C Clock Generator
*
*/
XLLP_BOOL_T PostI2cInit(P_POST_I2C_T I2C_regs, P_XLLP_GPIO_T gpio, P_XLLP_CLKMGR_T clkMgr, XLLP_UINT32_T dev_id)
{
/* Verify I2C Unit Clock is enabled */
/* TODO: I may want to disable the I2C Clock Unit after I'm done communicating with the device */
if( !((clkMgr->cken) & XLLP_CLKEN_I2C) )
clkMgr->cken |= XLLP_CLKEN_I2C;
if( !((clkMgr->cken) & XLLP_CLKEN_I2C) )
return(XLLP_TRUE);
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;
if(I2C_regs->ISAR != dev_id)
return(XLLP_TRUE);
I2C_regs->ICR = POST_ICR_INIT_VALUE;
if(I2C_regs->ICR != POST_ICR_INIT_VALUE)
return(XLLP_TRUE);
return(XLLP_FALSE);
}
/*
* Wait for Receive empty status
*
* RETURNS: 0 success
* 1 failure
*/
XLLP_BOOL_T PostI2cRxFull(P_POST_I2C_T I2C_regs)
{
XLLP_UINT32_T ret = XLLP_TRUE; /* failure */
if(I2C_regs->ISR & POST_ISR_IRF){
I2C_regs->ISR = (I2C_regs->ISR & POST_ISR_IRF); /* Write back status to clear */
ret = XLLP_FALSE; /* success */
} /* if */
return ret;
}
/* Wait for transmit empty status
*
* RETURNS: 0 success
* 1 failure
*/
XLLP_BOOL_T PostI2cTxEmpty(P_POST_I2C_T I2C_regs)
{
XLLP_INT32_T ret = XLLP_TRUE; /* failure */
if(I2C_regs->ISR & POST_ISR_ITE)
{
I2C_regs->ISR &= POST_ISR_ITE; /* Write back status to clear */
ret = XLLP_FALSE; /* success */
} /* if */
return ret;
}
/*
* Write data to device
*
* PARAMETERS:
* pI2C_TX - transmit sequence
*
* RETURNS: 0 success
* 1 failure
*/
XLLP_BOOL_T PostI2cSetupRead(P_POST_I2C_T i2c_regs, P_XLLP_INTC_T int_regs, pI2C_TX seq)
{
XLLP_UINT32_T reg_value;
i2c_regs->ICR |= POST_ICR_DRFIE;
i2c_regs->IDBR = seq->dev_id | POST_IDBR_MODE; /* Set read/write bit (bit #0) */
reg_value = i2c_regs->IDBR;
if(reg_value != (seq->dev_id | POST_IDBR_MODE))
return(XLLP_TRUE);
i2c_regs->ICR &= (~POST_ICR_STOP); /* Clear STOP bit */
i2c_regs->ICR |= (POST_ICR_START|POST_ICR_TB); /* Set start and tranfer bits. Transfer bit is self clearing */
reg_value = i2c_regs->ICR;
if( ((!(reg_value&POST_ICR_START))&&
(!(reg_value & POST_ICR_TB)))||
(reg_value & POST_ICR_STOP) )
return(XLLP_TRUE);
return(XLLP_FALSE);
}
XLLP_BOOL_T PostI2cRead(P_POST_I2C_T I2C_regs, pI2C_TX seq, XLLP_UINT32_T ByteNum,
P_XLLP_UINT8_T rx_data, XLLP_UINT32_T rx_data_len)
{
XLLP_UINT32_T reg_value;
/* If receiving the last byte, then*/
if ((ByteNum+1)>=rx_data_len)
{
/* Terminate communication with STOP condition */
I2C_regs->ICR |= (POST_ICR_TB|POST_ICR_STOP|POST_ICR_ACKNACK);
}
else
{
/* Read */
I2C_regs->ICR |= (POST_ICR_TB); /* Read */
}
/* Save byte read */
reg_value = I2C_regs->IDBR;
(rx_data)[ByteNum] = (XLLP_UINT8_T)(reg_value & 0xFF);
return(XLLP_FALSE);
}
/*
* Read data from device
*
* PARAMETERS:
* pI2C_TX - Transmit sequence
* char *rx_data - Received data
* unsigned int rx_data_len - Length of expected data to receive
*
* RETURNS: 0 success
* 1 failure
*/
XLLP_BOOL_T PostI2cSetupWrite(P_POST_I2C_T I2C_regs, P_XLLP_INTC_T int_regs, pI2C_TX seq )
{
XLLP_UINT32_T reg_value;
I2C_regs->IDBR = seq->dev_id & (~POST_IDBR_MODE); /* Clear read bit (bit #0) */
reg_value = I2C_regs->IDBR;
// setting i2c controller to trigger an interrupt for transmitting on the bus
I2C_regs->ICR |= POST_ICR_ITEIE;
// masked the interrupt controller register to cause the interrupt to occur.
// int_regs->icmr |= XLLP_INTC_I2C;
// writing register address which to write too
if(reg_value != (seq->dev_id & (~POST_IDBR_MODE)))
{
return(XLLP_TRUE);
}
/* Initiate write */
I2C_regs->ICR &= ~POST_ICR_STOP;
I2C_regs->ICR |= (POST_ICR_START | POST_ICR_TB);
reg_value = I2C_regs->ICR;
if( ((!(reg_value & POST_ICR_START))&&
(!(reg_value & POST_ICR_TB)))||
(reg_value & POST_ICR_STOP) )
{
return(XLLP_TRUE);
}
return(XLLP_FALSE);
}
/*
* Writes data to device
*
* PARAMETERS:
* P_POST_I2C_T I2C_regs
* pI2C_TX - Transmit sequence
* XLLP_UINT32_T stop_bit -
*
* RETURNS: 0 success
* 1 failure
*/
XLLP_BOOL_T PostI2cWrite(P_POST_I2C_T I2C_regs, pI2C_TX seq, XLLP_UINT32_T ByteNum, XLLP_UINT32_T stop_bit)
{
I2C_regs->IDBR = (seq->data)[ByteNum];
/* If sending the last byte, then*/
if (((ByteNum+1)>=seq->data_len) && (stop_bit == POST_I2C_STOP))
{
/* Terminate communication with STOP condition */
I2C_regs->ICR |= POST_ICR_STOP;
I2C_regs->ICR |= POST_ICR_TB; /* write */
}
else
{
I2C_regs->ICR |= POST_ICR_TB; /* write */
}
return(XLLP_FALSE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -