OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 12103|回复: 9

gpio模拟以太网SMI接口,读寄存器失败

[复制链接]

63

主题

305

帖子

1

精华

高级会员

Rank: 4

积分
853
金钱
853
注册时间
2012-8-3
在线时间
79 小时
发表于 2017-10-26 15:56:54 | 显示全部楼层 |阅读模式
1金钱
因为F407不支持op code的设置,所以采用gpio模拟smi接口操作,但是读出来的数据有问题,全是0xffff,找不出问题,是delay_us(1)延时太长吗?

[mw_shl_code=c,true]//IO方向
#define MDIO_IN()  {GPIOA->MODER&=~(3<<(2*2));GPIOA->MODER|=0<<2*2;}        //PA2
#define MDIO_OUT() {GPIOA->MODER&=~(3<<(2*2));GPIOA->MODER|=1<<2*2;} //PA2

#define MDIO    PAout(2) //SCL
#define MDC     PCout(1) //SDA         
#define READ_MDIO  PCin(1) //SDA       

void SMI_Init(void)
{
        //配置PA2 PC1为推完输出,GPIO模拟SMI
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
        GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;        //推完输出
        GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP ;//GPIO_PuPd_UP GPIO_PuPd_NOPULL
        GPIO_Init(GPIOA, &GPIO_InitStructure);//PA2 MDIO
   
        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;//GPIO_PuPd_UP GPIO_PuPd_NOPULL
        GPIO_Init(GPIOC, &GPIO_InitStructure);//PC1 MDC ,不需要上拉
    MDIO = 1;
    MDC = 0;
}

u8 SMI_Read_One_Byte(void)
{
    u8 i, receive=0;
//    MDIO_IN();
    for(i = 0; i < 8; i++)
    {
                receive<<=1;
        MDC=0;//拉低时钟
                delay_us(1);
                MDC=1;  //上升沿传输数据
                delay_us(1);
                if(READ_MDIO) receive|= 0x01; //上升沿,高电平期间读数据
                MDC=0;//时钟恢复低电平
    }
    return receive;
}

u8 SMI_Read_2Bit(void)
{
    u8 i, receive=0;
//    MDIO_IN();
    for(i = 0; i < 2; i++)
    {
        receive<<=1;
        MDC=0;//拉低时钟
                delay_us(1);
                MDC=1;  //上升沿传输数据
                delay_us(1);
        if(READ_MDIO) receive|= 0x01; //上升沿,高电平期间读数据
        MDC=0;//恢复低电平
    }
    return receive;
}

void SMI_Write_One_Byte(u8 data)
{
    u8 i;
//    MDIO_OUT();
    for(i = 0; i < 8; i++)
    {
        MDC=0;
        MDIO=(data&0x80)>>7;//准备数据
        delay_us(1);
        MDC=1;  //上升沿传输数据
        delay_us(1); //保持一段时间
        MDC = 0;//恢复低电平
        data<<=1;
    }
}

void SMI_Write_2Bit(u8 data)
{
    u8 i;
    MDIO_OUT();
    for(i = 0; i < 2; i++)
    {
        MDC=0;
        MDIO=(data&0x2)>>1;
        delay_us(1);
        MDC=1;      //上升沿传输数据
        delay_us(1); //保持一段时间
        MDC = 0;//恢复低电平
        data<<=1;
    }
}

#define START_OF_FRAME_2bit 0x01
#define READ_OP_CODE_2bit 0x2
#define WRITE_OP_CODE_2bit 0x1
#define SMI_OP_CODE_2bit 0x00
#define SMI_TA 0x02
void SMI_Write_Frame(u16 PHYAddress, u16 PHYReg, u16 PHYValue)
{
    u8 addr;
   
    addr = (PHYAddress & 0x7) <<5 | (PHYReg & 0x1F);

    MDIO_OUT();  
    ////32 bit Preamble
    SMI_Write_One_Byte(0xFF);
    SMI_Write_One_Byte(0xFF);
    SMI_Write_One_Byte(0xFF);
    SMI_Write_One_Byte(0xFF);
    SMI_Write_One_Byte(0xFF);
    SMI_Write_One_Byte(0xFF);
    SMI_Write_One_Byte(0xFF);
    SMI_Write_One_Byte(0xFF);

    SMI_Write_2Bit(START_OF_FRAME_2bit);
    SMI_Write_2Bit(WRITE_OP_CODE_2bit);
    SMI_Write_2Bit(0x00);       //dir: 0x0 is write
    SMI_Write_One_Byte(addr);
    SMI_Write_2Bit(SMI_TA);
    SMI_Write_One_Byte(0xFF);
    SMI_Write_One_Byte(PHYValue);
    MDIO_IN();//恢复输入高阻态
}

u16 SMI_Read_Reg(u16 PHYAddress, u16 PHYReg)
{
    u8 addr;
    u16 data;
   
    addr = (PHYAddress & 0x7)<<5 | (PHYReg & 0x1F);
   
    ////32 bit Preamble
    MDIO_OUT();
    SMI_Write_One_Byte(0xFF);
    SMI_Write_One_Byte(0xFF);
    SMI_Write_One_Byte(0xFF);
    SMI_Write_One_Byte(0xFF);

    SMI_Write_2Bit(START_OF_FRAME_2bit);
    SMI_Write_2Bit(READ_OP_CODE_2bit);
    SMI_Write_2Bit(0x0);       //PHYAD[4:3] decide dir: 0x2/0x3 is write
    SMI_Write_One_Byte(addr);
   
    MDIO_IN();
    data = SMI_Read_2Bit();//SMI_TA should be Z0
    data = SMI_Read_One_Byte();
    data = data << 8;
    data = data | SMI_Read_One_Byte();
    return data;
}

u8 KSZ8863_Get_Reg_Value(u8 port, u8 reg_num)
{
        u16 reg;
//        reg = ETH_ReadPHYRegister(port, reg_num); //从port1的1号寄存器中读取网络速度和双工模式
       
        reg = SMI_Read_Reg(port, reg_num);
       
        printf("port %d, reg 0x%x = 0x%x \r\n", port, reg_num, reg);
        return reg;
}

void KSZ8863_Print_Reg_Value(void)
{
        u8 i, port;
        for(port = 1; port < 4; port++){
                for(i = 0; i < 6; i++){
                        KSZ8863_Get_Reg_Value(port, i);
                        delay_ms(100);
                }
        }
}
[/mw_shl_code]

最佳答案

查看完整内容[请看2#楼]

解决了,READ_MDIO 读引脚定义错了,应该定义为PA2: #define READ_MDIO PAin(2) //SDA 可以读全局寄存器了
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

63

主题

305

帖子

1

精华

高级会员

Rank: 4

积分
853
金钱
853
注册时间
2012-8-3
在线时间
79 小时
 楼主| 发表于 2017-10-26 15:56:55 | 显示全部楼层
解决了,READ_MDIO  读引脚定义错了,应该定义为PA2:
#define READ_MDIO  PAin(2) //SDA
可以读全局寄存器了
回复

使用道具 举报

558

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
164897
金钱
164897
注册时间
2010-12-1
在线时间
2100 小时
发表于 2017-10-27 01:03:12 | 显示全部楼层
帮顶
回复

使用道具 举报

63

主题

305

帖子

1

精华

高级会员

Rank: 4

积分
853
金钱
853
注册时间
2012-8-3
在线时间
79 小时
 楼主| 发表于 2017-10-27 10:02:41 | 显示全部楼层
谢谢原子哥,网友博客的分析文章 http://blog.csdn.net/jasonchen_gbd/article/details/51628992
中提到“当PHY向MDIO写数据时,PHY要先发出一个MDC的上升沿,然后等待0-300ns” , 这句话意思是,mac读数据时,mdc时钟是由phy提供的???是这样子么?
回复

使用道具 举报

8

主题

1034

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
3668
金钱
3668
注册时间
2011-5-23
在线时间
2004 小时
发表于 2017-10-27 19:02:23 | 显示全部楼层
本帖最后由 aozima 于 2017-10-27 19:05 编辑

op code 不是只有读和写? 407不支持?

STM32连接KSZ8863有挺多人用的啊,没听说过还要自己模拟MDIO
RT-Thread RTOS 音频,WIFI,蓝牙
回复

使用道具 举报

2

主题

32

帖子

0

精华

高级会员

Rank: 4

积分
868
金钱
868
注册时间
2018-2-9
在线时间
75 小时
发表于 2018-3-9 15:17:53 | 显示全部楼层
楼主方便联系吗?我ID就是QQ
回复

使用道具 举报

5

主题

36

帖子

0

精华

初级会员

Rank: 2

积分
114
金钱
114
注册时间
2017-10-31
在线时间
23 小时
发表于 2018-5-8 22:48:28 | 显示全部楼层
aozima 发表于 2017-10-27 19:02
op code 不是只有读和写? 407不支持?

STM32连接KSZ8863有挺多人用的啊,没听说过还要自己模拟MDIO

我在这个贴看到你的,LZ估计联系不上啦,看到你登录时间最近
回复

使用道具 举报

2

主题

472

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
5696
金钱
5696
注册时间
2018-6-27
在线时间
500 小时
发表于 2019-8-19 08:37:16 | 显示全部楼层
学习学习,学习学习,
回复

使用道具 举报

4

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
85
金钱
85
注册时间
2021-8-2
在线时间
11 小时
发表于 2021-8-4 17:05:42 | 显示全部楼层
楼主,可以分享下源码不,新手学习一下 liu_zx1213@163.com
回复

使用道具 举报

33

主题

218

帖子

0

精华

高级会员

Rank: 4

积分
565
金钱
565
注册时间
2015-1-12
在线时间
75 小时
发表于 2021-12-10 14:16:26 | 显示全部楼层
SMT32介绍的SMI时序图中是下降沿锁定数据,你的读写时序是怎么回事呢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-5-29 07:17

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表