新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > I2C總線協(xié)議學(xué)習(xí)筆記

I2C總線協(xié)議學(xué)習(xí)筆記

作者: 時(shí)間:2016-12-15 來源:網(wǎng)絡(luò) 收藏


  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],觸發(fā)CPU發(fā)起START信號(hào)

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

  12. //CPU發(fā)送一個(gè)字節(jié),slave I2C addr和0 (寫操作bit)

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


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

  15. return -1;


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


  17. writeb(data[i], i2c->base + MPC_I2C_DR); //CPU接著發(fā)數(shù)據(jù),包括reg addr和data


  18. if (i2c_wait(i2c, timeout, 1) < 0) //等待slave 發(fā)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. { //循環(huán)讀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,再觸發(fā) START

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




  12. //CPU發(fā)送slave I2C addr和讀操作1

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

//等待Slave發(fā)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數(shù)據(jù)后,會(huì)發(fā)送ACK

  14. if (i == length - 2)

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



  16. //注意這里CCR_MSTA [1->0] CPU會(huì)觸發(fā)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 下一頁

關(guān)鍵詞: I2C總線協(xié)議學(xué)習(xí)筆

評(píng)論


相關(guān)推薦

技術(shù)專區(qū)

關(guān)閉