新闻中心

EEPW首页 > 嵌入式系统 > 设计应用 > I2C总线协议学习笔记

I2C总线协议学习笔记

作者: 时间:2016-12-15 来源:网络 收藏


  1. static int mpc_write(struct mpc_i2c *i2c, int target,

  2. const u8 * data, int length, int restart)

  3. {

  4. int i;

  5. unsigned timeout = i2c->adap.timeout;

  6. u32 flags = restart ? CCR_RSTA : 0;


  7. //以防万一,保证I2C模块使能起来

  8. if (!restart)

  9. writeccr(i2c, CCR_MEN);

  10. //写了I2CCR[CCR_MSTA],触发CPU发起START信号

  11. writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX | flags);

  12. //CPU发送一个字节,slave I2C addr和0 (写操作bit)

  13. writeb((target << 1), i2c->base + MPC_I2C_DR);


  14. if (i2c_wait(i2c, timeout, 1) < 0) //等待slave 发ACK

  15. return -1;


  16. for (i = 0; i < length; i++) {


  17. writeb(data[i], i2c->base + MPC_I2C_DR); //CPU接着发数据,包括reg addr和data


  18. if (i2c_wait(i2c, timeout, 1) < 0) //等待slave 发ACK

  19. return -1;

  20. }


  21. return 0;

  22. }


  1. static int i2c_wait(struct mpc_i2c *i2c, unsigned timeout, int writing)

  2. {

  3. unsigned long orig_jiffies = jiffies;

  4. u32 x;

  5. int result = 0;


  6. if (i2c->irq == 0)

  7. { //循环读I2CSR,直到I2CSR[MIF]置1

  8. while (!(readb(i2c->base + MPC_I2C_SR) & CSR_MIF)) {

  9. schedule();

  10. if (time_after(jiffies, orig_jiffies + timeout)) {

  11. pr_debug("I2C: timeoutn");

  12. writeccr(i2c, 0);

  13. result = -EIO;

  14. break;

  15. }

  16. }

  17. x = readb(i2c->base + MPC_I2C_SR);

  18. writeb(0, i2c->base + MPC_I2C_SR);

  19. } else {


  20. result = wait_event_interruptible_timeout(i2c->queue,

  21. (i2c->interrupt & CSR_MIF), timeout * HZ);


  22. if (unlikely(result < 0)) {

  23. pr_debug("I2C: wait interruptedn");

  24. writeccr(i2c, 0);

  25. } else if (unlikely(!(i2c->interrupt & CSR_MIF))) {

  26. pr_debug("I2C: wait timeoutn");

  27. writeccr(i2c, 0);

  28. result = -ETIMEDOUT;

  29. }


  30. x = i2c->interrupt;

  31. i2c->interrupt = 0;

  32. }


  33. if (result < 0)

  34. return result;


  35. if (!(x & CSR_MCF)) {

  36. pr_debug("I2C: unfinishedn");

  37. return -EIO;

  38. }


  39. if (x & CSR_MAL) { //仲裁失败

  40. pr_debug("I2C: MALn");

  41. return -EIO;

  42. }


  43. if (writing && (x & CSR_RXAK)) {//写后没收到ACK

  44. pr_debug("I2C: No RXAKn");


  45. writeccr(i2c, CCR_MEN);

  46. return -EIO;

  47. }

  48. return 0;

  49. }

  1. static int mpc_read(struct mpc_i2c *i2c, int target,

  2. u8 * data, int length, int restart)

  3. {

  4. unsigned timeout = i2c->adap.timeout;

  5. int i;

  6. u32 flags = restart ? CCR_RSTA : 0;


  7. //以防万一,保证I2C模块使能

  8. if (!restart)

  9. writeccr(i2c, CCR_MEN);

  10. //注意这里,再次把CCR_MSTA置1,再触发 START

  11. writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_MTX | flags);




  12. //CPU发送slave I2C addr和读操作1

  13. writeb((target << 1) | 1, i2c->base + MPC_I2C_DR);

//等待Slave发ACK
  1. if (i2c_wait(i2c, timeout, 1) < 0)

  2. return -1;


  3. if (length) {

  4. if (length == 1)

  5. writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_TXAK);

  6. else //为什么不置 TXAK

  7. writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA);


  8. readb(i2c->base + MPC_I2C_DR);

  9. }


  10. for (i = 0; i < length; i++) {

  11. if (i2c_wait(i2c, timeout, 0) < 0)

  12. return -1;



  13. //注意这里TXAK置1,表示CPU每收到1byte数据后,会发送ACK

  14. if (i == length - 2)

  15. writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_MSTA | CCR_TXAK);



  16. //注意这里CCR_MSTA [1->0] CPU会触发STOP

  17. if (i == length - 1)

  18. writeccr(i2c, CCR_MIEN | CCR_MEN | CCR_TXAK);


  19. data[i] = readb(i2c->base + MPC_I2C_DR);

  20. }


  21. return length;

  22. }

上一页 1 2 下一页

关键词: I2C总线协议学习笔

评论


相关推荐

技术专区

关闭