背景
参考
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指令,进行愉快的调试了。文章来源:https://www.toymoban.com/news/detail-478043.html
当然也可以在启动设置项,配置本文开头提到的0xa001寄存器地址了。文章来源地址https://www.toymoban.com/news/detail-478043.html
到了这里,关于YT8531 YT8521驱动调试(二)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!