关于Realtek千兆交换芯片的类似I2C总线EEPROM SMI 无**确读写数据问题

[复制链接]
 楼主| gufeng722 发表于 2013-3-7 08:38 | 显示全部楼层 |阅读模式
最近小生用到Realtek的千兆交换芯片8370(不带M),想通过这个芯片的的EEPROM SMI slave 接口去读取其寄存器的值,弄了几天,遇到的问题是往芯片中的某个寄存器写值以后,读出来以后就不对了(譬如往,地址0x0016没写之前读出来的值是0x0001,往地址0x0016写0xAA55后,再读这个寄存器的值,读出来的值确实0x00FF),器件的ACK应答正常!出现这样的问题有可能是三毛原因,烦请各位路过的大侠帮看看。谢谢了!
jlass 发表于 2013-3-7 10:31 | 显示全部楼层
SMI时序不对居多,特别是读写翻转的时候
 楼主| gufeng722 发表于 2013-3-7 13:50 | 显示全部楼层
jlass 发表于 2013-3-7 10:31
SMI时序不对居多,特别是读写翻转的时候

  1. void rtl_smi_delay(unsigned char t)
  2. {
  3.     while(t--)
  4.     {
  5.                 _Nop();
  6.                 _Nop();
  7.                 _Nop();
  8.                 _Nop();
  9.                 _Nop();
  10.                 _Nop();
  11.         }
  12. }

  13. void rtl_smi_start()
  14. {

  15.         SCK=0;
  16.         SDA=1;
  17.         rtl_smi_delay(5);

  18.         /* CLK 1: 0 -> 1, 1 -> 0 */
  19.         SCK=1;
  20.         rtl_smi_delay(5);
  21.         SCK=0;
  22.         rtl_smi_delay(5);

  23.         /* CLK 2: */
  24.         SCK=1;
  25.         rtl_smi_delay(5);
  26.         SDA=0;
  27.         rtl_smi_delay(5);
  28.         SCK=0;
  29.         //rtl_smi_delay(5);
  30.         //SDA=1;
  31. }

  32. void rtl_smi_stop()
  33. {
  34.         rtl_smi_delay(5);
  35.         SDA=0;
  36.         SCK=0;
  37.         rtl_smi_delay(5);
  38.         SCK=1;
  39.         rtl_smi_delay(5);
  40.         SDA=1;
  41.         rtl_smi_delay(5);
  42.         SDA=0;

  43.         /* add a click */
  44.         rtl_smi_delay(5);
  45.         SDA=1;
  46.         SCK=0;
  47.         rtl_smi_delay(5);
  48.         SCK=1;
  49.         rtl_smi_delay(5);
  50.         SCK=0;

  51. }


  52. void rtl_smi_write_bits(unsigned char wtData, unsigned char len)
  53. {

  54.         for (; len > 0; len--) {
  55.                 SCK=0;
  56.                 rtl_smi_delay(3);       
  57.                 /* prepare data */
  58.                 SDA=!!(wtData & ( 1 << (len - 1)));
  59.                 rtl_smi_delay(2);

  60.                 /* clocking */
  61.                 SCK=1;
  62.                 rtl_smi_delay(5);
  63.                 SCK=0;
  64.         }
  65. }

  66. void rtl_smi_read_bits(unsigned char len, unsigned char *rddata)
  67. {

  68.         //gpio_direction_input(sda); SDA pin 设置为输入模式 P3M1=0;
  69.                 P0M1=0x40;//高阻输入模式
  70.                 P0M0=0x80;
  71.                 SDA=1;

  72.         for (*rddata = 0; len > 0; len--) {
  73.                 unsigned char u;
  74.                 SCK=0;
  75.                 rtl_smi_delay(5);
  76.                 /* clocking */
  77.                 SCK=1;
  78.                 rtl_smi_delay(6);
  79.                 u = SDA;
  80.                 SCK=0;

  81.                 *rddata |= (u << (len - 1));
  82.         }

  83.         //gpio_direction_input(sda); SDA pin 设置为输出模式 P3M1=1;用推挽模式
  84.                 P0M1=0x00;//推挽输出模式
  85.                 P0M0=0xC0;
  86. }

  87. unsigned char rtl_smi_wait_for_ack()
  88. {
  89.         unsigned char retry_cnt;

  90.         retry_cnt = 0;
  91.         do {
  92.                 unsigned char ack;

  93.                 rtl_smi_read_bits(1, &ack);
  94.                 if (ack == 0)
  95.                         break;

  96.                 if (++retry_cnt >15)
  97.                         return 1;
  98.         } while (1);

  99.         return 0;
  100. }



  101. unsigned char rtl_smi_write_byte(unsigned char wtdata)
  102. {
  103.         rtl_smi_write_bits(wtdata, 8);
  104.         return rtl_smi_wait_for_ack();
  105. }

  106. unsigned char rtl_smi_write_byte1(unsigned char wtdata)
  107. {
  108.         rtl_smi_write_bits(wtdata, 8);
  109.         return 0;
  110. }

  111. unsigned char rtl_smi_read_byte0(unsigned char *rddata)//读之后应答结束
  112. {
  113.         unsigned char t;

  114.         /* read data */
  115.         rtl_smi_read_bits(8, &t);
  116.         *rddata = (t & 0xff);

  117.         /* send an ACK */
  118.         rtl_smi_write_bits(0x00,1);

  119.         return 0;
  120. }

  121. unsigned char rtl_smi_read_byte1(unsigned char *rddata)//读之后非应答结束
  122. {
  123.         unsigned char t;

  124.         /* read data */
  125.         rtl_smi_read_bits(8, &t);
  126.         *rddata = (t & 0xff);

  127.         /* send an ACK */
  128.         rtl_smi_write_bits(0x01,1);

  129.         return 0;
  130. }

  131. unsigned char rtl_smi_read_reg(unsigned int addr, unsigned int *rddata)
  132. {
  133.         unsigned char lo = 0;
  134.         unsigned char hi = 0;
  135.         unsigned char ret;
  136.         i2dutype retdata,addrdata;
  137.         addrdata.intdata=addr;

  138.         rtl_smi_start();

  139.         /* send READ command */
  140.         ret = rtl_smi_write_byte(0x0B << 4 | 0x04 << 1 | 0x01);
  141.         LED1=0;
  142.         if (ret)
  143.                 goto out;
  144.         LED2=0;
  145.         /* set ADDR[7:0] */
  146.         ret = rtl_smi_write_byte(addrdata.dudata.Ldata);
  147.         if (ret)
  148.                 goto out;

  149.         /* set ADDR[15:8] */
  150.         ret = rtl_smi_write_byte(addrdata.dudata.Hdata);
  151.         if (ret)
  152.                 goto out;
  153.    //rtl_smi_write_bits(0x00,1);
  154.         /* read DATA[7:0] */
  155.         rtl_smi_read_byte0(&lo);
  156.         /* read DATA[15:8] */
  157.         rtl_smi_read_byte1(&hi);
  158.         retdata.dudata.Hdata=hi;
  159.         retdata.dudata.Ldata=lo;
  160.         *rddata=retdata.intdata;
  161.         //*rddata = ((unsigned int ) lo) | (((unsigned int ) hi) << 8);

  162.         ret = 0;

  163. out:
  164.         rtl_smi_stop();

  165.         return ret;
  166. }

  167. unsigned char rtl_smi_write_reg(unsigned int addr, unsigned int wtdata)
  168. {
  169.         int ret;

  170.         rtl_smi_start();

  171.         /* send WRITE command */
  172.         ret = rtl_smi_write_byte(0x0B << 4 | 0x04 << 1 | 0x00);
  173.         if (ret)
  174.                 goto out;
  175.        
  176.         /* set ADDR[7:0] */
  177.         ret = rtl_smi_write_byte(addr & 0xff);
  178.         if (ret)
  179.                 goto out;
  180.        
  181.         /* set ADDR[15:8] */
  182.         ret = rtl_smi_write_byte(addr >> 8);
  183.         if (ret)
  184.                 goto out;
  185.        
  186.         /* write DATA[7:0] */
  187.         ret = rtl_smi_write_byte(wtdata & 0xff);
  188.         if (ret)
  189.                 goto out;
  190.        
  191.         /* write DATA[15:8] */
  192.         ret = rtl_smi_write_byte(wtdata >> 8);
  193.         if (ret)
  194.                 goto out;
  195.         LED5=0;
  196.         ret = 0;

  197. out:
  198.         rtl_smi_stop();

  199.         return ret;
  200. }


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| gufeng722 发表于 2013-3-7 13:52 | 显示全部楼层
jlass 发表于 2013-3-7 10:31
SMI时序不对居多,特别是读写翻转的时候

大侠有时间帮忙看一下吧!谢谢了!
 楼主| gufeng722 发表于 2013-3-7 14:26 | 显示全部楼层
qingx 发表于 2013-3-7 14:12
咋出不来图啊?

一楼图挂了,我在三楼有重新贴了。就是三楼那两张图!希望帮忙看看啊!3KS
jlass 发表于 2013-3-7 17:02 | 显示全部楼层
gufeng722 发表于 2013-3-7 13:52
大侠有时间帮忙看一下吧!谢谢了!

把SDA和SCK的时序图抓出来和理论图对比,看什么代码啊。:)
 楼主| gufeng722 发表于 2013-3-7 18:24 | 显示全部楼层
jlass 发表于 2013-3-7 17:02
把SDA和SCK的时序图抓出来和理论图对比,看什么代码啊。

用示波器抓出来的图是和时序图对的上啊!哎
jlass 发表于 2013-3-8 08:38 | 显示全部楼层
gufeng722 发表于 2013-3-7 18:24
用示波器抓出来的图是和时序图对的上啊!哎

那就郁闷了,你确认一下它的SDA,SCK接口是否兼容IIC等其他协议的,如果可以的话换IIC看看,不行的话好像也没什么办法了。

EEPROM SMI slave 接口
我对这个描述有点奇怪,如果你要去读寄存器的话应该是属于master啊,是否有上拉/下拉电阻选择的。
墨香米 发表于 2016-10-17 10:32 | 显示全部楼层
你好,你是怎么读取寄存器的值的?是通过单片机吗?将单片机的一些接口连到EEPROM SMI接口上的?
shenjunsuzhou 发表于 2018-11-7 17:40 | 显示全部楼层
请教一个问题:通过i2c口读取phy1 的地址是多少?SGCR的地址是0000吗?
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

11

帖子

2

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