I2C数据传输的三个主要API

描述

I2C Data Transfer

I2C 数据传输主要有三个 API

int i2c_master_send(const struct i2c_client *client,const char *buf,int count)

client:I2C 设备对应的 i2c_client。
buf:要发送的数据。
count:要发送的数据字节数,要小于 64KB,以为 i2c_msg 的 len 成员变量是一个 u16(无符号 16 位)类型的数据。
返回值:负值,失败,其他非负值,发送的字节数。

int i2c_master_recv(const struct i2c_client *client,char *buf,int count)
client:I2C 设备对应的 i2c_client。
buf:要接收的数据。
count:要接收的数据字节数,要小于 64KB,以为 i2c_msg 的 len 成员变量是一个 u16(无符号 16 位)类型的数据。
返回值:负值,失败,其他非负值,发送的字节数。

int i2c_transfer(struct i2c_adapter *adap,struct i2c_msg *msgs,int num)

adap:所使用的 I2C 适配器,i2c_client 会保存其对应的 i2c_adapter。
msgs:I2C 要发送的一个或多个消息。
num:消息数量,也就是 msgs 的数量。
返回值:负值,失败,其他非负值,发送的 msgs 数量。

i2c_master_send 和 i2c_master_recv 都是对 i2c_transfer 的封装。因此我们重点研究 i2c_transfer。

I2C

其中,adap->algo->master_xfer 由芯片原厂提供。在 MTK 平台,是 mtk_i2c_transfer 函数,不同平台命名不同。

static int mtk_i2c_transfer(struct i2c_adapter *adap,struct i2c_msg msgs[], int num)
{
 int ret;
 int left_num = num;
 struct mtk_i2c *i2c = i2c_get_adapdata(adap);

  //打开时钟
 ret = mtk_i2c_clock_enable(i2c);
 if (ret)
  return ret;

  //初始化硬件
 mtk_i2c_init_hw(i2c);

 i2c- >auto_restart = i2c- >dev_comp- >auto_restart;

 if (i2c- >auto_restart && num == 2) {
  if (!(msgs[0].flags & I2C_M_RD) && (msgs[1].flags & I2C_M_RD) &&
      msgs[0].addr == msgs[1].addr) {
   i2c- >auto_restart = 0;
  }
 }

 if (i2c- >auto_restart && num >= 2 && i2c- >speed_hz > MAX_FS_MODE_SPEED)
  i2c- >ignore_restart_irq = true;
 else
  i2c- >ignore_restart_irq = false;

 while (left_num--) {
  if (!msgs- >buf) {
   dev_dbg(i2c- >dev, "data buffer is NULL.n");
   ret = -EINVAL;
   goto err_exit;
  }

  if (msgs- >flags & I2C_M_RD)
   i2c- >op = I2C_MASTER_RD;
  else
   i2c- >op = I2C_MASTER_WR;

  if (!i2c- >auto_restart) {
   if (num > 1) {
    /* combined two messages into one transaction */
    i2c- >op = I2C_MASTER_WRRD;
    left_num--;
   }
  }

  /* always use DMA mode. */
  ret = mtk_i2c_do_transfer(i2c, msgs, num, left_num);
  if (ret < 0)
   goto err_exit;

  msgs++;
 }
 /* the return value is number of executed messages */
 ret = num;

err_exit:
 mtk_i2c_clock_disable(i2c);
 return ret;
}
打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分