SylixOS iMX6平台I2C总线驱动(3)

程序清单 37 __i2cTryTransfer的具体实现

static INT  __i2cTryTransfer (UINT                uiChannel,                           PLW_I2C_ADAPTER  pI2cAdapter,                           PLW_I2C_MESSAGE  pI2cMsg,                           INT                 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); …… }

__i2cTransferEnable的具体实现

__i2cTransferEnable函数使能I2C,设置时钟频率。

__i2cTransferStart的具体实现

__i2cTransferStart函数设置I2C控制器为主模式(占用总线)。

__i2cTransferMsg的具体实现

i2cTransferMsg函数判断读/写模式,对应不同操作。如程序清单 38所示。

程序清单 38 __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          *  (设置为接收模式)          */         ……         /*          *  若只有一个字节,设置选择不发送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++;         } } …… }

__i2cTransferTxByte的具体实现

如程序清单 39,程序清单 310所示。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/fe08012c725cebb94d15d7ae4ab6785b.html