NT iNum)
{
……
/*
* 设置I2C时钟频率,清状态位,使能I2C
* 并判断总线状态,若IBB位为0 (总线空闲)继续,否则取消本次传输
*/
if (__i2cTransferEnable(uiChannel) != 0) {
return (PX_ERROR);
}
/*
* 设置为主模式+传输模式
* 设置完后IBB位自动置1(总线繁忙),开始传输
*/
if (__i2cTransferStart(uiChannel) != 0) {
return (PX_ERROR);
}
/*
* 完成设备地址发送后,进入收发消息函数
*/
for (i = 0; i < iNum; i++, pI2cMsg++) {
if (__i2cTransferMsg(uiChannel, pI2cMsg, iNum) != ERROR_NONE) {
break;
}
}
/*
* generate STOP by clearing MSTA bit
* (清除MSTA位使其停止传输)
*/
__i2cTransferStop(uiChannel);
/*
* disable the controller
* (禁止I2C控制器)
*/
__i2cTransferDisable(uiChannel);
……
}
19.__i2cTransferEnable的具体实现
static INT __i2cTransferEnable (UINT uiChannel)
{
UINT uiValue = 0;
/*
* If the request has device info attached and it has a non-zero bit rate, then
* change the clock to the specified rate.
* (如果请求的设备为非零波特率,改变为指定时钟频率)
*/
__i2cSetI2cClk(uiChannel, SPECIFIED_RATE);
/*
* clear the status register
* (清空状态寄存器)
*/
uiValue = readw(REG_I2C_I2SR(uiChannel));
uiValue &= ~CLEAR_ALL_MASK;
uiValue |= CLEAR_ALL;
writew(uiValue, REG_I2C_I2SR(uiChannel));
/*
* enable the I2C controller
* (使能I2c控制器)
*/
uiValue = readw(REG_I2C_I2CR(uiChannel));
uiValue &= ~BIT_I2C_I2CR_IEN_MASK;
uiValue |= BIT_I2C_I2CR_IEN;
writew(uiValue, REG_I2C_I2CR(uiChannel));
/*
* Check if bus is free, if not return error
* (检测总线是否空闲,若被占用返回-1)
*/
if (__i2cTransferBusFree(uiChannel) != 0) {
return (PX_ERROR);
}
return (ERROR_NONE);
}
static VOID __i2cSetI2cClk (UINT uiChannel, UINT32 uiBaud)
{
/*
* 获取系统时钟
*/
UINT32 uiSrcClk = ccmMainClkGet(IPG_PER_CLK);
……
/*
* 设置I2C时钟频率
*/
uiValue = readw(REG_I2C_IFDR(uiChannel));
uiValue &= ~BIT_I2C_IFDR_IC_MASK;
uiValue |= i2c_clk_div[ucIndex][1];
writew(uiValue, REG_I2C_IFDR(uiChannel));
}
static INT __i2cTransferBusFree (UINT uiChannel)
{
INT i = WAIT_RXAK_LOOPS;
/*
* 一段时间内循环判断
*/
while ((readw(REG_I2C_I2SR(uiChannel)) & IBB) && (--i > 0));
if (i <= 0) {
printk("Error: I2C Bus not free!\n");
return (ERROR);
}
return (ERROR_NONE);
}
20.__i2cTransferStart的具体实现
static INT __i2cTransferStart (UINT uiChannel)
{
UINT uiValue = 0;
/*
* Select master mode, assert START signal and also indicate TX mode
* (选择主机模式,表明传输模式,开始信号)
*/
uiValue = readw(REG_I2C_I2CR(uiChannel));
uiValue &= ~BIT_I2C_I2CR_MSTA_MTX_MASK;
uiValue |= BIT_I2C_I2CR_MSTA_MTX;
writew(uiValue, REG_I2C_I2CR(uiChannel));
/*
* make sure bus is busy after the START signal
* (确保开始后的总线信号保持繁忙,否则返回-1)
*/
if (__i2cTransferBusBusy(uiChannel) != 0) {
return (PX_ERROR);
}
return (ERROR_NONE);
}
static INT __i2cTransferBusBusy (UINT uiChannel)
{
INT i = WAIT_BUSY_LOOPS;
while (!(readw(REG_I2C_I2SR(uiChannel)) & IBB) && (--i > 0))
if (i <= 0) {
printk("I2C Error: timeout in \n");
return (PX_ERROR);
}
return (ERROR_NONE);
}
21.__i2cTransferMsg的具体实现
static INT __i2cTransferMsg ( UINT uiChannel,
PLW_I2C_MESSAGE pI2cMsg,
INT iNUM)
{
……
if (pI2cMsg->I2CMSG_usFlag & LW_I2C_M_RD) { /* 读取操作 */
/*
* do repeat-start
* (重复启动) (IEN_MSTA_MTX_RSTA)
*/
……
/*
* send slave address again, but indicate read operation
* (发送从机器件地址,表明为读操作)
*/
……
if (__i2cTransferTxByte(pucData, uiChannel) != 0) { /* 发送从机地址,等待返回ACK */
return -1;
}
/*
* change to receive mode
*