0


YT8531 YT8521驱动调试(二)

背景

参考

YT8531 YT8521驱动调试(一)_大牛攻城狮的博客-CSDN博客

原理图

也参考上述提到博客

不同点

接一,针对 YT8521

其实两个phy的外围接口电路涉及基本上移植,不通的就是phy地址的设计

但是YT8521实际使用过程中,需要配置两个寄存器

如下所示

mdio eth0 0x1e 0xa001
mdio eth0 0x1f 0x8160

翻了一下手册,这个寄存器地址是

调试的问题最终还是发现原理图的设计有问题,只是通过上述MDIO指令可以规避

一个是mode_sel的选择是否正确

一个是cfg_ldo电压选择是否正确

这上述配置,在原理图设计的时候都可以通过IO,YT8521的管脚进行选择

例如如下设计

这里还设计一个问题就是在系统中使用mdio指令

mdio指令一般在uboot中使用的多,如下使用方法

mdio - MDIO utility commands

Usage:
mdio list                       - List MDIO buses
mdio read <phydev> [<devad>.]<reg> - read PHY's register at <devad>.<reg>
mdio write <phydev> [<devad>.]<reg> <data> - write PHY's register at <devad>.<reg>
mdio rx <phydev> [<devad>.]<reg> - read PHY's extended register at <devad>.<reg>
mdio wx <phydev> [<devad>.]<reg> <data> - write PHY's extended register at <devad>.<reg>
<phydev> may be:
    <busname>  <addr>
    <addr>
    <eth name>
<addr> <devad>, and <reg> may be ranges, e.g. 1-5.4-0x1f.

=>

=> mdio list

这里提供一种linux系统mdio的配置方法

使用下面代码描述了在用户层访问smi/mdio总线, 读写phy芯片寄存器的通用代码。Linux内核2.6以上通用。需要根据自己的交叉编译环境,进行交叉编译,进行搭建交叉编译环境

如下所示,提供一个可以使用makefile的编写,需要替换自己的交叉编译环境

arm_cross_gcc = /home/gcc-linaro-7.3.1-2018.05-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-gcc

objects = mdio.o
mdio: $(objects)
    $(arm_cross_gcc) -o mdio $(objects)

%.o : %.c
    $(arm_cross_gcc) -c $<

.PHONY:clean
clean:
    rm mdio $(objects)
    @echo clean finish

将下面代码编译后,将可执行文件mdio

如下图所示

使用方法举例:

mdio eth0 1 读取phy寄存器1的数值

mdio eth0 0 0x1120 将0x1120写入 phy寄存器1

eth0 为mac层控制器的名称, 一般为eth0 或mgmt0

mdio.c代码如下,看起来还是比较容易理解的,主要是使用linux系统mii IO_CTL

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <linux/mii.h>

#include <sys/types.h>

#include <sys/socket.h>

#include <sys/ioctl.h>

#include <net/if.h>

#include <linux/sockios.h>

#include <linux/types.h>

#include <netinet/in.h>

#define reteck(ret) \

if(ret < 0){ \

printf("%m! \"%s\" : line: %d\n", __func__, __LINE__); \

goto lab; \

}

#define help() \

printf("mdio:\n"); \

printf("read operation: mdio reg_addr\n"); \

printf("write operation: mdio reg_addr value\n"); \

printf("For example:\n"); \

printf("mdio eth0 1\n"); \

printf("mdio eth0 0 0x12\n\n"); \

exit(0);

int sockfd;

int main(int argc, char *argv[])

{

if(argc == 1 || !strcmp(argv[1], "-h")){

help();

}

struct mii_ioctl_data *mii = NULL;

struct ifreq ifr;

int ret;

memset(&ifr, 0, sizeof(ifr));

strncpy(ifr.ifr_name, argv[1], IFNAMSIZ - 1);

sockfd = socket(PF_LOCAL, SOCK_DGRAM, 0);

reteck(sockfd);

//get phy address in smi bus

ret = ioctl(sockfd, SIOCGMIIPHY, &ifr);

reteck(ret);

mii = (struct mii_ioctl_data*)&ifr.ifr_data;

if(argc == 3){

mii->reg_num = (uint16_t)strtoul(argv[2], NULL, 0);

ret = ioctl(sockfd, SIOCGMIIREG, &ifr);

reteck(ret);

printf("read phy addr: 0x%x reg: 0x%x value : 0x%x\n\n", mii->phy_id, mii->reg_num, mii->val_out);

}else if(argc == 4){

mii->reg_num = (uint16_t)strtoul(argv[2], NULL, 0);

mii->val_in = (uint16_t)strtoul(argv[3], NULL, 0);

ret = ioctl(sockfd, SIOCSMIIREG, &ifr);

reteck(ret);

printf("write phy addr: 0x%x reg: 0x%x value : 0x%x\n\n", mii->phy_id, mii->reg_num, mii->val_in);

}

lab:

close(sockfd);

return 0;

}

这样处理后,将mdio放到开发板文件系统的/sbin或者/bin下就可以使用mdio指令,进行愉快的调试了。

当然也可以在启动设置项,配置本文开头提到的0xa001寄存器地址了。


本文转载自: https://blog.csdn.net/li171049/article/details/130345053
版权归原作者 大牛攻城狮 所有, 如有侵权,请联系我们删除。

“YT8531 YT8521驱动调试(二)”的评论:

还没有评论