phy控制器驱动【cpu无mdio控制器】

当CPU没有内置MDIO控制器时,可以通过GPIO模拟MDIO总线与PHY设备进行通信。下面是如何实现PHY控制器驱动的步骤:

1. 设计GPIO MDIO时序

首先,必须了解MDIO协议的基本时序要求:

  • MDC(管理时钟):用于时钟信号。
  • MDIO(管理数据):用于数据传输。

在没有MDIO控制器的情况下,使用两个GPIO引脚分别模拟MDC和MDIO。可以通过GPIO设置高低电平来实现MDIO的时序。

2. GPIO引脚初始化

初始化用于MDIO和MDC的GPIO引脚,并设置为输出或输入模式。

#include <linux/gpio.h>
#include <linux/delay.h>

#define MDIO_PIN  17  // MDIO GPIO引脚
#define MDC_PIN   18  // MDC GPIO引脚

void init_gpio(void) {
    gpio_request(MDIO_PIN, "MDIO");
    gpio_request(MDC_PIN, "MDC");
    gpio_direction_output(MDIO_PIN, 1);  // 默认高电平
    gpio_direction_output(MDC_PIN, 1);   // 默认高电平
}

3. 定义时钟脉冲函数

生成MDC脉冲信号,通常为高低电平切换的延迟,以便满足MDIO时序要求。

void mdc_pulse(void) {
    gpio_set_value(MDC_PIN, 1); // 设置MDC为高
    udelay(1);                   // 延时
    gpio_set_value(MDC_PIN, 0); // 设置MDC为低
    udelay(1);                   // 延时
}

4. 实现MDIO写操作

实现对PHY寄存器的写操作,包括发送预同步、地址和数据。

void mdio_write(int phy_addr, int reg_addr, uint16_t data) {
    // 1. 发送32位1作为预同步
    for (int i = 0; i < 32; i++) {
        gpio_set_value(MDIO_PIN, 1);
        mdc_pulse();
    }

    // 2. 发送启动码(01)和写操作码(01)
    gpio_set_value(MDIO_PIN, 0); // 0
    mdc_pulse();
    gpio_set_value(MDIO_PIN, 1); // 1
    mdc_pulse();
    gpio_set_value(MDIO_PIN, 0); // 写操作
    mdc_pulse();
    gpio_set_value(MDIO_PIN, 1); // 写操作
    mdc_pulse();

    // 3. 发送PHY地址
    for (int i = 4; i >= 0; i--) {
        gpio_set_value(MDIO_PIN, (phy_addr >> i) & 1);
        mdc_pulse();
    }

    // 4. 发送寄存器地址
    for (int i = 4; i >= 0; i--) {
        gpio_set_value(MDIO_PIN, (reg_addr >> i) & 1);
        mdc_pulse();
    }

    // 5. 发送数据
    for (int i = 15; i >= 0; i--) {
        gpio_set_value(MDIO_PIN, (data >> i) & 1);
        mdc_pulse();
    }

    // 6. 设置MDIO为高以结束写操作
    gpio_set_value(MDIO_PIN, 1);
}

5. 实现MDIO读操作

实现对PHY寄存器的读操作,需要将MDIO引脚设置为输入以接收数据。

uint16_t mdio_read(int phy_addr, int reg_addr) {
    uint16_t data = 0;

    // 1. 发送32位1作为预同步
    for (int i = 0; i < 32; i++) {
        gpio_set_value(MDIO_PIN, 1);
        mdc_pulse();
    }

    // 2. 发送启动码和读操作码(10)
    gpio_set_value(MDIO_PIN, 0); // 0
    mdc_pulse();
    gpio_set_value(MDIO_PIN, 1); // 1
    mdc_pulse();
    gpio_set_value(MDIO_PIN, 1); // 读操作
    mdc_pulse();
    gpio_set_value(MDIO_PIN, 0); // 读操作
    mdc_pulse();

    // 3. 发送PHY地址
    for (int i = 4; i >= 0; i--) {
        gpio_set_value(MDIO_PIN, (phy_addr >> i) & 1);
        mdc_pulse();
    }

    // 4. 发送寄存器地址
    for (int i = 4; i >= 0; i--) {
        gpio_set_value(MDIO_PIN, (reg_addr >> i) & 1);
        mdc_pulse();
    }

    // 5. 转移周期
    gpio_direction_input(MDIO_PIN);
    mdc_pulse(); // 第一个时钟周期
    mdc_pulse(); // 第二个时钟周期

    // 6. 读取数据
    for (int i = 15; i >= 0; i--) {
        mdc_pulse();
        data |= gpio_get_value(MDIO_PIN) << i;
    }

    // 7. 恢复MDIO为输出
    gpio_direction_output(MDIO_PIN, 1);
    return data;
}

6. 驱动的注册与初始化

在驱动的init函数中,初始化GPIO和注册MDIO总线。确保在模块退出时清理资源。

static int __init my_driver_init(void) {
    init_gpio(); // 初始化GPIO
    // 注册MDIO总线和PHY设备(省略具体实现)
    return 0;
}

static void __exit my_driver_exit(void) {
    // 清理代码(省略具体实现)
    gpio_free(MDIO_PIN);
    gpio_free(MDC_PIN);
}

7. 注意事项

  • 延迟:确保在设置MDC和MDIO引脚时使用适当的延迟,以遵循MDIO协议的时序。
  • GPIO配置:确保正确配置GPIO引脚的输入输出模式。
  • 中断管理:如果有需要,考虑在读写操作中添加中断处理,以提高效率。

8. 总结

通过GPIO模拟MDIO总线,可以在没有MDIO控制器的CPU上实现PHY设备的读写。尽管这种方法在时序上可能不如硬件MDIO稳定,但在一些特定的应用中仍然具有重要意义。这种方法可以通过简单的GPIO操作实现与PHY设备的有效通信。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/901732.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python 自动化运维:Python基础知识

Python 自动化运维&#xff1a;Python基础知识 目录 &#x1f4ca; Python 基础复习 数据类型、控制结构与常用函数面向对象编程&#xff08;OOP&#xff09;与类的使用函数式编程概念与 lambda 表达式异常处理与日志记录的基本实践 1. &#x1f4ca; Python 基础复习 数据…

【论文阅读】Tabbed Out: Subverting the Android Custom Tab Security Model

论文链接&#xff1a;Tabbed Out: Subverting the Android Custom Tab Security Model | IEEE Conference Publication | IEEE Xplore 总览 “Tabbed Out: Subverting the Android Custom Tab Security Model” 由 Philipp Beer 等人撰写&#xff0c;发表于 2024 年 IEEE Symp…

word技巧:如何禁止复制word文件内容?

在文档管理与协作的复杂环境中&#xff0c;确保文档内容的完整性和安全性至关重要。Microsoft Word作为一款广泛使用的文字处理软件&#xff0c;提供了强大的限制编辑功能&#xff0c;允许用户控制对文档内容的修改权限&#xff0c;有效防止未经授权的更改。本文将深入解析Word…

LabVIEW如何学习数据结构和算法

作为LabVIEW程序员&#xff0c;在学习数据结构和算法时&#xff0c;由于LabVIEW以图形编程为主&#xff0c;与传统编程语言的学习方式有些不同。因此&#xff0c;理解算法思想并将其在LabVIEW中实现是关键。 ​ 1. 夯实编程基础概念 LabVIEW与文本编程语言在实现逻辑上的方式…

Maven项目报错:invalid LOC header (bad signature)

文章目录 Maven项目报错&#xff1a;invalid LOC header (bad signature)1. Maven项目加载或Pom.Xml刷新后仍出现如下错误2. 解决方法 Maven项目报错&#xff1a;invalid LOC header (bad signature) 1. Maven项目加载或Pom.Xml刷新后仍出现如下错误 错误提示&#xff1a; in…

方形件排样优化与订单组批问题探析

方形件排样优化与订单组批问题是计算复杂度很高的组合优化问题&#xff0c;在工业工程中有很广泛的应用背景。为实现个性化定制生产模式&#xff0c;企业会选择订单组批的方式&#xff0c;继而通过排样优化实现批量切割&#xff0c;加工完成后再按照不同客户需求进行分拣&#…

高质量短视频素材平台推荐

在当今短视频内容日益增长的时代&#xff0c;拥有高质量的素材显得尤为重要。以下是一些值得关注的短视频素材平台&#xff0c;它们各具特色&#xff0c;适合不同需求的创作者。 蛙学网 蛙学网专注于提供高质量的短视频素材&#xff0c;适合各种创作需求。虽然该平台需要订阅&a…

DerpNStink: 1渗透测试

靶机&#xff1a;DerpNStink: 1 <https://www.vulnhub.com/entry/derpnstink-1,221/> 攻击机&#xff1a;kail linux 2024 目标&#xff1a;获得4个flag 1,将两台虚拟机网络连接都改为NAT模式&#xff0c;并查看靶机的MAC地址 2&#xff0c;攻击机上做主机扫描发现靶机 靶…

#HarmonyOS:页面和自定义组件生命周期

页面生命周期 即被Entry装饰的组件生命周期 onPageShow&#xff1a;页面每次显示时触发一次&#xff0c;包括路由过程、应用进入前台等场景。onPageHide: 页面每次隐藏时触发一次&#xff0c;包括路由过程、应用进入后台等场景。onBackPress: 当用户点击返回按钮是触发 组件…

自定义类型:联合和枚举【上】

自定义类型&#xff1a;数组&#xff0c;结构体&#xff0c;联合体&#xff0c;枚举。前面一些我们已经讲过了&#xff0c;接下来我们讲联合体和枚举。 一.联合体 1.联合体类型的声明 像结构体一样&#xff0c;联合体也是由一个或者多个成员构成&#xff0c;这些成员可以不同…

网络搜索引擎Shodan(2)

声明&#xff1a;学习视频来自b站up主 泷羽sec&#xff0c;如涉及侵权马上删除文章 声明&#xff1a;本文主要用作技术分享&#xff0c;所有内容仅供参考。任何使用或依赖于本文信息所造成的法律后果均与本人无关。请读者自行判断风险&#xff0c;并遵循相关法律法规。 感谢泷…

(南京观海微电子)——GH7006-01_HKC_B3-PV043WVQ-N80_MIPI_LVDS_RGB原理及代码介绍

1. 原理 2. 代码 /**************************************************/ // Model - GV050WVQ-N82 // IC - GH7006 // Width - 800 // Height - 480 // REV: - V01 // DATA - 20240621 // INTERFACE- LV…

4.1.2 网页设计技术

文章目录 1. 万维网&#xff08;WWW&#xff09;的诞生2. 移动互联网的崛起3. 网页三剑客&#xff1a;HTML、CSS和JavaScriptHTML&#xff1a;网页的骨架CSS&#xff1a;网页的外衣JavaScript&#xff1a;网页的活力 4. 前端框架的演变基于CSS的框架基于JavaScript的框架基于MV…

质量漫谈一

我知道很多同学看到这类问题&#xff0c;第一反应想要去寻找的就是作为测试角色&#xff0c;应该要如何如何去做&#xff1f;但是今天这里作为质量第一篇&#xff0c;不打算按照这样单角度去写&#xff0c;这类同学可以就此打住&#xff0c;如果在意的话&#xff0c;可关注后续…

excel斜线表头

检验数据验证对象 鼠标放在检验数据 验证对象中间&#xff0c;altenter 之后空格 选中格子&#xff0c;右键单元格格式&#xff0c; 完成 如果是需要多分割&#xff0c;操作一样&#xff0c;在画斜线的时候会有区别&#xff0c;在插入里面用直线画斜线即可 在表格插入的时…

采用Excel作为可视化设计器的开源规则引擎 NopRule

决策树和决策矩阵是业务人员可以直观理解的复杂IF-ELSE逻辑表达形式&#xff0c;也是规则引擎中最常用、最有用的部分。常见的规则引擎如Drools虽然提供了更加丰富的功能特性集&#xff0c; 特别是所谓的RETE算法可以用于高效复用多次重复出现的表达式片段&#xff0c;但在实际…

xxl-job java.sql.SQLException: interrupt问题排查

近期生产环境固定凌晨报错&#xff0c;提示 ConnectionManager [Thread-23069] getWriteConnection db:***,pattern: error, jdbcUrl: jdbc:mysql://***:3306/***?connectTimeout3000&socketTimeout180000&autoReconnecttrue&zeroDateTimeBehaviorCONVERT_TO_NUL…

Windows自带录屏好用吗?四大录屏工具轻松实现高效录屏!

Windows系统自带的录屏工具其实就是Xbox Game Bar。今天&#xff0c;除了这个工具&#xff0c;我还会为大家推荐几款实用录屏工具&#xff0c;让大家轻松实现高效录屏&#xff01; 福昕录屏软件 直达链接&#xff1a;www.foxitsoftware.cn/REC/ 操作教程&#xff1a;立即获取…

本地缓存库分析(一):golang-lru

文章目录 本地缓存概览golang-lru标准lrulru的操作PutGet 2q&#xff1a;冷热分离lruPutGet expirable_lru&#xff1a;支持过期时间的lruPutGet过期 总结 本地缓存概览 在业务中&#xff0c;一般会将极高频访问的数据缓存到本地。以减少网络IO的开销&#xff0c;下游服务的压…

css 切角实现(全)

效果 样式代码 <template><div class"container"><div class"clip-all-angle"> 4个角全部剪切 </div><div class"clip-two-angle"> 切底部两个角 </div><div class"clip-two-top-angle"> …