打印

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

[复制链接]
4547|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
最近小生用到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时序不对居多,特别是读写翻转的时候


void rtl_smi_delay(unsigned char t)
{
    while(t--)
    {
                _Nop();
                _Nop();
                _Nop();
                _Nop();
                _Nop();
                _Nop();
        }
}

void rtl_smi_start()
{

        SCK=0;
        SDA=1;
        rtl_smi_delay(5);

        /* CLK 1: 0 -> 1, 1 -> 0 */
        SCK=1;
        rtl_smi_delay(5);
        SCK=0;
        rtl_smi_delay(5);

        /* CLK 2: */
        SCK=1;
        rtl_smi_delay(5);
        SDA=0;
        rtl_smi_delay(5);
        SCK=0;
        //rtl_smi_delay(5);
        //SDA=1;
}

void rtl_smi_stop()
{
        rtl_smi_delay(5);
        SDA=0;
        SCK=0;
        rtl_smi_delay(5);
        SCK=1;
        rtl_smi_delay(5);
        SDA=1;
        rtl_smi_delay(5);
        SDA=0;

        /* add a click */
        rtl_smi_delay(5);
        SDA=1;
        SCK=0;
        rtl_smi_delay(5);
        SCK=1;
        rtl_smi_delay(5);
        SCK=0;

}


void rtl_smi_write_bits(unsigned char wtData, unsigned char len)
{

        for (; len > 0; len--) {
                SCK=0;
                rtl_smi_delay(3);       
                /* prepare data */
                SDA=!!(wtData & ( 1 << (len - 1)));
                rtl_smi_delay(2);

                /* clocking */
                SCK=1;
                rtl_smi_delay(5);
                SCK=0;
        }
}

void rtl_smi_read_bits(unsigned char len, unsigned char *rddata)
{

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

        for (*rddata = 0; len > 0; len--) {
                unsigned char u;
                SCK=0;
                rtl_smi_delay(5);
                /* clocking */
                SCK=1;
                rtl_smi_delay(6);
                u = SDA;
                SCK=0;

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

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

unsigned char rtl_smi_wait_for_ack()
{
        unsigned char retry_cnt;

        retry_cnt = 0;
        do {
                unsigned char ack;

                rtl_smi_read_bits(1, &ack);
                if (ack == 0)
                        break;

                if (++retry_cnt >15)
                        return 1;
        } while (1);

        return 0;
}



unsigned char rtl_smi_write_byte(unsigned char wtdata)
{
        rtl_smi_write_bits(wtdata, 8);
        return rtl_smi_wait_for_ack();
}

unsigned char rtl_smi_write_byte1(unsigned char wtdata)
{
        rtl_smi_write_bits(wtdata, 8);
        return 0;
}

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

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

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

        return 0;
}

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

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

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

        return 0;
}

unsigned char rtl_smi_read_reg(unsigned int addr, unsigned int *rddata)
{
        unsigned char lo = 0;
        unsigned char hi = 0;
        unsigned char ret;
        i2dutype retdata,addrdata;
        addrdata.intdata=addr;

        rtl_smi_start();

        /* send READ command */
        ret = rtl_smi_write_byte(0x0B << 4 | 0x04 << 1 | 0x01);
        LED1=0;
        if (ret)
                goto out;
        LED2=0;
        /* set ADDR[7:0] */
        ret = rtl_smi_write_byte(addrdata.dudata.Ldata);
        if (ret)
                goto out;

        /* set ADDR[15:8] */
        ret = rtl_smi_write_byte(addrdata.dudata.Hdata);
        if (ret)
                goto out;
   //rtl_smi_write_bits(0x00,1);
        /* read DATA[7:0] */
        rtl_smi_read_byte0(&lo);
        /* read DATA[15:8] */
        rtl_smi_read_byte1(&hi);
        retdata.dudata.Hdata=hi;
        retdata.dudata.Ldata=lo;
        *rddata=retdata.intdata;
        //*rddata = ((unsigned int ) lo) | (((unsigned int ) hi) << 8);

        ret = 0;

out:
        rtl_smi_stop();

        return ret;
}

unsigned char rtl_smi_write_reg(unsigned int addr, unsigned int wtdata)
{
        int ret;

        rtl_smi_start();

        /* send WRITE command */
        ret = rtl_smi_write_byte(0x0B << 4 | 0x04 << 1 | 0x00);
        if (ret)
                goto out;
       
        /* set ADDR[7:0] */
        ret = rtl_smi_write_byte(addr & 0xff);
        if (ret)
                goto out;
       
        /* set ADDR[15:8] */
        ret = rtl_smi_write_byte(addr >> 8);
        if (ret)
                goto out;
       
        /* write DATA[7:0] */
        ret = rtl_smi_write_byte(wtdata & 0xff);
        if (ret)
                goto out;
       
        /* write DATA[15:8] */
        ret = rtl_smi_write_byte(wtdata >> 8);
        if (ret)
                goto out;
        LED5=0;
        ret = 0;

out:
        rtl_smi_stop();

        return ret;
}


使用特权

评论回复
地板
gufeng722|  楼主 | 2013-3-7 13:52 | 只看该作者
jlass 发表于 2013-3-7 10:31
SMI时序不对居多,特别是读写翻转的时候

大侠有时间帮忙看一下吧!谢谢了!

使用特权

评论回复
5
gufeng722|  楼主 | 2013-3-7 14:26 | 只看该作者
qingx 发表于 2013-3-7 14:12
咋出不来图啊?

一楼图挂了,我在三楼有重新贴了。就是三楼那两张图!希望帮忙看看啊!3KS

使用特权

评论回复
6
jlass| | 2013-3-7 17:02 | 只看该作者
gufeng722 发表于 2013-3-7 13:52
大侠有时间帮忙看一下吧!谢谢了!

把SDA和SCK的时序图抓出来和理论图对比,看什么代码啊。:)

使用特权

评论回复
7
gufeng722|  楼主 | 2013-3-7 18:24 | 只看该作者
jlass 发表于 2013-3-7 17:02
把SDA和SCK的时序图抓出来和理论图对比,看什么代码啊。

用示波器抓出来的图是和时序图对的上啊!哎

使用特权

评论回复
8
jlass| | 2013-3-8 08:38 | 只看该作者
gufeng722 发表于 2013-3-7 18:24
用示波器抓出来的图是和时序图对的上啊!哎

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

EEPROM SMI slave 接口
我对这个描述有点奇怪,如果你要去读寄存器的话应该是属于master啊,是否有上拉/下拉电阻选择的。

使用特权

评论回复
9
墨香米| | 2016-10-17 10:32 | 只看该作者
你好,你是怎么读取寄存器的值的?是通过单片机吗?将单片机的一些接口连到EEPROM SMI接口上的?

使用特权

评论回复
10
shenjunsuzhou| | 2018-11-7 17:40 | 只看该作者
请教一个问题:通过i2c口读取phy1 的地址是多少?SGCR的地址是0000吗?

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

3

主题

11

帖子

2

粉丝