[资料分享与下载] Freescale P4080 I2C 驱动分析

[复制链接]
1813|19
 楼主| 跟屁虫 发表于 2015-6-18 20:32 | 显示全部楼层 |阅读模式
本帖最后由 跟屁虫 于 2015-6-18 20:39 编辑

转载自井朝天的博客

Freescale P4080是一款8核心网络处理器,功能强大,外设齐全,基于powerpc e500 core。在嵌入式网络应用上被广泛使用。

看一下p4080上是怎么规定这么资源(registers)的地址的




 楼主| 跟屁虫 发表于 2015-6-18 20:33 | 显示全部楼层
  1.     typedef struct fsl_i2c {  
  2.       
  3.         u8 adr;     /* I2C slave address */  
  4.         u8 res0[3];  
  5.     #define I2C_ADR     0xFE  
  6.     #define I2C_ADR_SHIFT   1  
  7.     #define I2C_ADR_RES ~(I2C_ADR)  
  8.       
  9.         u8 fdr;     /* I2C frequency divider register */  
  10.         u8 res1[3];  
  11.     #define IC2_FDR     0x3F  
  12.     #define IC2_FDR_SHIFT   0  
  13.     #define IC2_FDR_RES ~(IC2_FDR)  
  14.       
  15.         u8 cr;      /* I2C control redister */  
  16.         u8 res2[3];  
  17.     #define I2C_CR_MEN  0x80  
  18.     #define I2C_CR_MIEN 0x40  
  19.     #define I2C_CR_MSTA 0x20  
  20.     #define I2C_CR_MTX  0x10  
  21.     #define I2C_CR_TXAK 0x08  
  22.     #define I2C_CR_RSTA 0x04  
  23.     #define I2C_CR_BCST 0x01  
  24.       
  25.         u8 sr;      /* I2C status register */  
  26.         u8 res3[3];  
  27.     #define I2C_SR_MCF  0x80  
  28.     #define I2C_SR_MAAS 0x40  
  29.     #define I2C_SR_MBB  0x20  
  30.     #define I2C_SR_MAL  0x10  
  31.     #define I2C_SR_BCSTM    0x08  
  32.     #define I2C_SR_SRW  0x04  
  33.     #define I2C_SR_MIF  0x02  
  34.     #define I2C_SR_RXAK 0x01  
  35.       
  36.         u8 dr;      /* I2C data register */  
  37.         u8 res4[3];  
  38.     #define I2C_DR      0xFF  
  39.     #define I2C_DR_SHIFT    0  
  40.     #define I2C_DR_RES  ~(I2C_DR)  
  41.       
  42.         u8 dfsrr;   /* I2C digital filter sampling rate register */  
  43.         u8 res5[3];  
  44.     #define I2C_DFSRR   0x3F  
  45.     #define I2C_DFSRR_SHIFT 0  
  46.     #define I2C_DFSRR_RES   ~(I2C_DR)  
  47.       
  48.         /* Fill out the reserved block */  
  49.         u8 res6[0xE8];  
  50.     } fsl_i2c_t;  
 楼主| 跟屁虫 发表于 2015-6-18 20:34 | 显示全部楼层
  1.     #define CONFIG_SYS_I2C_OFFSET       0x118000  
  2.     #define CONFIG_SYS_I2C2_OFFSET      0x118100  
  3.      #if defined CONFIG_SYS_NUM_OF_I2C  
  4.       static unsigned int i2c_bus_speed[CONFIG_SYS_NUM_OF_I2C] = {CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED,CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SPEED };  
  5.       
  6.        const struct fsl_i2c *i2c_dev[CONFIG_SYS_NUM_OF_I2C] = {  
  7.           (struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_I2C_OFFSET),  
  8.           (struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_I2C_OFFSET + 0x100),  
  9.       #if defined(CONFIG_PPC_P4080)                // (dual) i2c module #2  
  10.          (struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_I2C_OFFSET + 0x1000),  
  11.           (struct fsl_i2c *) (CONFIG_SYS_IMMR + CONFIG_SYS_I2C_OFFSET + 0x1000 + 0x100)  
  12.       #endif  
  13.      };  
 楼主| 跟屁虫 发表于 2015-6-18 20:35 | 显示全部楼层
  1. void i2c_soft_reset(const struct fsl_i2c *dev )  
  2. {  
  3.      volatile u8 cTmp;  
  4.    
  5.          debug("\t@%08x:  I2CCSR:%02x I2CCCR:%02x  ", (int) dev, readb(&dev->sr), readb(&dev->cr));  
  6.    
  7.          /* per 11.5.6 of 8548 UM */  
  8.         writeb(0x20, &dev->cr); //这里都是硬件规定,不要问为啥是0x20, 00100000这个值中已经申明了某一位置位  
  9.          udelay(1000);  
  10.          writeb(0xA0, &dev->cr);          /* start condition */  
  11.          udelay(1000);  
  12.    
  13.          cTmp =  readb(&dev->dr);         /* kick off the read 8 data + ack */  
  14.          debug("I2CCDR:%02x %s \n", cTmp, __FUNCTION__);  
  15.    
  16.          writeb(0x0, &dev->cr);             /* disable and leave it alone */  
  17.          udelay(1000);  
  18.    
  19. }  
 楼主| 跟屁虫 发表于 2015-6-18 20:35 | 显示全部楼层
  1. static int  i2c_wait4bus(void)  
  2. {  
  3.      unsigned long long timeval = get_ticks();  
  4.     const unsigned long long timeout = usec2ticks(CONFIG_I2C_MBB_TIMEOUT);  
  5.   
  6.      while (readb(&i2c_dev[i2c_bus_num]->sr) & I2C_SR_MBB) {  
  7.          if ((get_ticks() - timeval) > timeout)  
  8.              return -1;  
  9.      }  
  10.    
  11.      return 0;  
  12. }  
 楼主| 跟屁虫 发表于 2015-6-18 20:37 | 显示全部楼层
  1. static int i2c_write_addr (u8 dev, u8 dir, int rsta)  
  2. {  
  3.      writeb(I2C_CR_MEN | I2C_CR_MSTA | I2C_CR_MTX  
  4.             | (rsta ? I2C_CR_RSTA : 0),  
  5.             &i2c_dev[i2c_bus_num]->cr);  
  6.    
  7.      writeb((dev << 1) | dir, &i2c_dev[i2c_bus_num]->dr);  
  8.    
  9.      if (i2c_wait(I2C_WRITE_BIT) < 0)  
  10.          return 0;  
  11.    
  12.      return 1;  
  13. }  
  14.    
  15. // static __inline__ int  
  16. static int __i2c_write(u8 *data, int length)  
  17. {  
  18.      int i;  
  19.    
  20.      for (i = 0; i < length; i++) {  
  21.          writeb(data[i], &i2c_dev[i2c_bus_num]->dr);  
  22.    
  23.          if (i2c_wait(I2C_WRITE_BIT) < 0)  
  24.             break;  
  25.      }  
  26.    
  27.      return i;  
  28. }  
 楼主| 跟屁虫 发表于 2015-6-18 20:38 | 显示全部楼层
int   i2c_write(u8 dev, uint addr, int alen, u8 *data, int length)  
{  
     int i = -1; /* signal error */  
     u8 *a = (u8*)&addr;  
   
     if (i2c_wait4bus() >= 0  
         && i2c_write_addr(dev, I2C_WRITE_BIT, 0) != 0  
         && __i2c_write(&a[4 - alen], alen) == alen) {  
         i = __i2c_write(data, length);  
     }  
   
     writeb(I2C_CR_MEN, &i2c_dev[i2c_bus_num]->cr);  
     if (i2c_wait4bus()) /* Wait until STOP */  
         debug("i2c_write: wait4bus timed out\n");  
   
    if (i == length)  
        return 0;  
   
     return -1;  
}  
598330983 发表于 2015-6-18 22:07 | 显示全部楼层
IIC ,用的地方很多的,好多外设都是这个接口,很感谢楼主无私奉献。
cowboy2014 发表于 2015-6-19 08:42 | 显示全部楼层
这个代码和分析真是详细,虽然是转载的别人的
 楼主| 跟屁虫 发表于 2015-6-21 21:25 | 显示全部楼层
只要资料对大家有用处我就是很高兴的
侣行天下 发表于 2015-6-21 21:38 | 显示全部楼层
楼主分享的东西讲解的很详细,能够直接拿过来用了
追逐浪花 发表于 2015-6-21 21:40 | 显示全部楼层
楼主分享的代码能够拿来直接用了,非常好
ccw1986 发表于 2015-6-21 21:57 | 显示全部楼层
代码和分析都有,这样的帖子最容易接受
FSL_TICS_ZJJ 发表于 2015-6-23 11:06 | 显示全部楼层
非常感谢你的经验分享!
李香兰 发表于 2015-6-23 13:55 | 显示全部楼层
这个讲的还是比较详细的,代码也有了
cowboy2014 发表于 2015-6-23 20:28 | 显示全部楼层
这个分析和代码还少比较详尽的
734774645 发表于 2015-6-23 21:31 | 显示全部楼层
typedef struct fsl_i2c {  
      
        u8 adr;     /* I2C slave address */  
        u8 res0[3];  
    #define I2C_ADR     0xFE  
    #define I2C_ADR_SHIFT   1  
    #define I2C_ADR_RES ~(I2C_ADR)  
      
        u8 fdr;     /* I2C frequency divider register */  
        u8 res1[3];  
    #define IC2_FDR     0x3F  
    #define IC2_FDR_SHIFT   0  
    #define IC2_FDR_RES ~(IC2_FDR)  
      
        u8 cr;      /* I2C control redister */  
        u8 res2[3];  
    #define I2C_CR_MEN  0x80  
    #define I2C_CR_MIEN 0x40  
    #define I2C_CR_MSTA 0x20  
    #define I2C_CR_MTX  0x10  
    #define I2C_CR_TXAK 0x08  
    #define I2C_CR_RSTA 0x04  
    #define I2C_CR_BCST 0x01  
      
        u8 sr;      /* I2C status register */  
        u8 res3[3];  
    #define I2C_SR_MCF  0x80  
    #define I2C_SR_MAAS 0x40  
    #define I2C_SR_MBB  0x20  
    #define I2C_SR_MAL  0x10  
    #define I2C_SR_BCSTM    0x08  
    #define I2C_SR_SRW  0x04  
    #define I2C_SR_MIF  0x02  
    #define I2C_SR_RXAK 0x01  
      
        u8 dr;      /* I2C data register */  
        u8 res4[3];  
    #define I2C_DR      0xFF  
    #define I2C_DR_SHIFT    0  
    #define I2C_DR_RES  ~(I2C_DR)  
      
        u8 dfsrr;   /* I2C digital filter sampling rate register */  
        u8 res5[3];  
    #define I2C_DFSRR   0x3F  
    #define I2C_DFSRR_SHIFT 0  
    #define I2C_DFSRR_RES   ~(I2C_DR)  
      
        /* Fill out the reserved block */  
        u8 res6[0xE8];  
    } fsl_i2c_t;  
这个东西太长了。
春风的暖暖 发表于 2015-6-24 08:25 | 显示全部楼层
资料虽然是转载的,但是也非常有用,谢谢楼主了
Messi1999 发表于 2015-6-24 08:28 | 显示全部楼层
正在找这样的例子,没想到在这里找到了,谢谢楼主
小猫爱吃鱼 发表于 2015-6-24 08:34 | 显示全部楼层
这些代码紧扣上面的说明,挺有用的
您需要登录后才可以回帖 登录 | 注册

本版积分规则

28

主题

245

帖子

2

粉丝
快速回复 在线客服 返回列表 返回顶部