(设置为接收模式)
*/
……
/*
* 若只有一个字节,设置选择不发送ACK(最后一次传输不发送ACK)
*/
……
/*
* dummy read
* (行假读)
*/
*pucData = readw(REG_I2C_I2DR(uiChannel));
/*
* 开始读...
*/
if (__i2cTransferRxBytes(pI2cMsg->I2CMSG_pucBuffer,
uiChannel,
pI2cMsg->I2CMSG_usLen) != 0) {
return (PX_ERROR);
}
} else { /* 发送操作 */
/*
* Step 2: send slave address + read/write at the LSB
* (发送从机地址+读写LSB 设置为写位)
*/
……
/*
* 将从机地址数据写入寄存器,等待ACK返回
*/
……
/*
* 设定一个长度,循环往寄存器写,等待ACK返回
*/
pucData = pI2cMsg->I2CMSG_pucBuffer;
for (i = 0; i < pI2cMsg->I2CMSG_usLen; i++) {
/*
* send device register value
* (发送寄存器地址 / 信息)
*/
if ((iRet = __i2cTransferTxByte(pucData, uiChannel)) != 0) {
break;
}
pucData++;
}
}
……
}
22.__i2cTransferTxByte的具体实现
static INT __i2cTransferTxByte (UINT8 *pChar, UINT uiChannel)
{
UINT uiValue = 0;
/*
* clear both IAL and IIF bits
* (清除IAL和IIF位)
*/
……
/*
* write to data register
* (向寄存器中写入数据,从机地址 / 发送信息)
* 0x0E << 1 + write + ack
* 0x07 + ack
* 0x0e << 1 + read + ack
* xx + ack
*/
writew((*pChar), (REG_I2C_I2DR(uiChannel)));
/*
* wait for transfer of byte to complete
* (等待传输完成)
*/
return __i2cTransferWaitOpDone(uiChannel, 1);
}
static INT __i2cTransferWaitOpDone (UINT uiChannel, INT iIsTx)
{
……
/*
* Loop until we get an interrupt
* (循环等待,直到我们得到一个中断,若没有产生中断,返回-10)
*/
while (!(readw(REG_I2C_I2SR(uiChannel)) & IIF) && (--i > 0));
if (i <= 0) {
printk("I2C Error: timeout unexpected\n");
return (ERR_NO_IIF);
}
/*
* Clear the interrupts
* (清除中断位)
*/
……
/*
* Check for arbitration lost
* (检查仲裁位,产生1为仲裁丢失,返回-3)
*/
if (readw(REG_I2C_I2SR(uiChannel)) & IAL) {
printk("Error Arbitration lost\n");
return (ERR_IAL_LOST);
}
/*
* Check for ACK received in transmit mode
* (传输模式中检查是否收到ACK)
*/
if (iIsTx) { /* iIsTx参数传入为1 */
if (readw(REG_I2C_I2SR(uiChannel)) & RXAK) {
/*
* 没有收到ACK,清除MSTA位使其停止传输
*/
printk("Error no ack received\n");
__i2cTransferStop(uiChannel); /* 停止 / 将主从模式位设置为0 */
return (ERR_NO_ACK);
}
}
……
}
23.__i2cTransferRxBytes的具体实现
static INT __i2cTransferRxBytes (UINT8 *pChar,
UINT uiChannel,
INT iSize)
{
……
/*
* 等待传输完成
*/
for (i = 0; iSize > 0; iSize--, i++) {
if (__i2cTransferWaitOpDone(uiChannel, 0) != 0) {
return (PX_ERROR);
}
/*
* 接下来的两个if指令设置为下一个读取控制寄存器的值
* 若iSize == 1则此次为最后一次且已完成传输(清除MSTA位)
* 若iSize == 2则下次为最后一次传输,不发送ACK信号(禁止TXAK位)
*/
……
/*
* 真正开始读取数据
*/
pChar[i] = readw(REG_I2C_I2DR(uiChannel));
}
……
}
24.__i2cTransferStop的具体实现
static VOID __i2cTransferStop (UINT uiChannel)
{
……
/*
* MSTA位设置为0,即可停止传输
*/
uiValue = readw(REG_I2C_I2CR(uiChannel));
uiValue &= ~BIT_I2C_I2CR_MSTA_MASK;
uiValue |= BIT_I2C_I2CR_MSTA_0;
writew(uiValue, REG_I2C_I2CR(uiChannel));
}
25.__i2cTransferDisable的具体实现
static VOID __i2cTransferDisable (UINT uiChannel)
{
……
/*
* disable the controller
* (禁能I2C)
*/
uiValue = readw(REG_I2C_I2SR(uiChannel));
uiValue &= ~CLEAR_ALL_MASK;
uiValue |= CLEAR_ALL;
writew(uiValue, REG_I2C_I2SR(uiChannel));
}