RK3588添加支持RS485收发

news/2024/9/18 9:05:23/文章来源:https://www.cnblogs.com/wmc245376374/p/18376780

RS485是在串口基础上利用电平转换芯片,将TTL电平转换成485的差分信号,电路图如下:

RO: 接收器输出----接RX
RE: 接收器输出使能(低电平-接收使能)
DE: 驱动器输出使能(高电平-发送使能)
DI: 驱动器输入----接TX
在传输数据时候需要将RS485 RE置高,发送使能,接收禁止;发送完数据以后需要将RS485 RE置低,接收使能,发送禁止。

清楚原理,修改驱动:

1.dts添加re使能口:

&uart6 {pinctrl-0 = <&uart6m1_xfer>;status = "okay";rs485-gpios = <&gpio4 RK_PB5 GPIO_ACTIVE_HIGH>;};

2.驱动修改:

 
diff --git a/include/uapi/linux/serial.h b/include/uapi/linux/serial.h
index 93eb3c496ff1..0828068cca44 100644
--- a/include/uapi/linux/serial.h
+++ b/include/uapi/linux/serial.h
@@ -130,6 +130,7 @@ struct serial_rs485 {__u32   delay_rts_after_send;   /* Delay after send (milliseconds) */__u32   padding[5];             /* Memory is cheap, new structsare a royal PITA .. */
+       __u32    rs485_tx_en_gpio;};
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 82a4f6dab59a..f0a3da1b2930 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -26,6 +26,8 @@#include <linux/clk.h>#include <linux/reset.h>#include <linux/pm_runtime.h>
+#include <linux/gpio.h>
+#include <linux/of_gpio.h>#include <asm/byteorder.h>@@ -502,6 +504,7 @@ static int dw8250_probe(struct platform_device *pdev)int irq;int err;u32 val;
+       int ret = 0;if (!regs) {dev_err(dev, "no registers defined\n");
@@ -544,6 +547,24 @@ static int dw8250_probe(struct platform_device *pdev)data->uart_16550_compatible = device_property_read_bool(dev,"snps,uart-16550-compatible");+       //wmc add
+       ret = of_get_named_gpio(p->dev->of_node, "rs485-gpios", 0);//GPIO4_B5
+       uart.port.rs485.rs485_tx_en_gpio = ret;
+       if(141 == uart.port.rs485.rs485_tx_en_gpio)
+       {
+               err = gpio_request(141, "rs485-ctl");
+               if(err<0){
+                       printk("wmc....rs485-ctl...failed..\n");
+                       return err;
+               }
+    
+    
+        gpio_direction_output(uart.port.rs485.rs485_tx_en_gpio, 0);
+        gpio_set_value(uart.port.rs485.rs485_tx_en_gpio, 0); // defalut low-level
+
+    }
+       //end
+err = device_property_read_u32(dev, "reg-shift", &val);

实现逻辑是,发送数据拉高re引脚,发送完数据再置低:

diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index 9e681b375bad..4d4fe01b328d 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -31,6 +31,7 @@#include <linux/uaccess.h>#include <linux/pm_runtime.h>#include <linux/ktime.h>
+#include <linux/of_gpio.h>#include <asm/io.h>#include <asm/irq.h>
@@ -1797,6 +1798,8 @@ void serial8250_tx_chars(struct uart_8250_port *up)struct uart_port *port = &up->port;struct circ_buf *xmit = &port->state->xmit;int count;
+       int lsr; // 用于获取状态
+       int i;   // 用于循环计数if (port->x_char) {uart_xchar_out(port, UART_TX);
@@ -1811,6 +1814,11 @@ void serial8250_tx_chars(struct uart_8250_port *up)return;}+       if(141 == up->port.rs485.rs485_tx_en_gpio)
+       {
+        gpio_set_value(up->port.rs485.rs485_tx_en_gpio, 1);
+       }
+count = up->tx_loadsz;do {serial_out(up, UART_TX, xmit->buf[xmit->tail]);
@@ -1848,7 +1856,25 @@ void serial8250_tx_chars(struct uart_8250_port *up)* the interrupt and RPM in __stop_tx()*/if (uart_circ_empty(xmit) && !(up->capabilities & UART_CAP_RPM))
+       {__stop_tx(up);
+               lsr = serial_in(up, UART_LSR);
+               if(141 == up->port.rs485.rs485_tx_en_gpio)
+               {
+                       for(i = 0; i < 200; i++)
+                       {
+                                       mdelay(3);
+                                       lsr = serial_in(up, UART_LSR);
+                                       if(UART_LSR_TEMT == (lsr & UART_LSR_TEMT))
+                                       {
+                                               // printk("[%d] wait finished: %d, lsr: %d\n", i, (lsr & UART_LSR_TEMT) == UART_LSR_TEMT, lsr);
+                                               break;
+                                       }
+                       }
+                       gpio_set_value(up->port.rs485.rs485_tx_en_gpio, 0);
+               }
+       }
+               }EXPORT_SYMBOL_GPL(serial8250_tx_chars);

 

 

参考:https://blog.csdn.net/weixin_46461874/article/details/132718936

https://blog.csdn.net/guowuoo2008/article/details/131771333

https://blog.csdn.net/bing328924/article/details/134503353

  

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

网站图片显示错误怎么办

打开HTML文件:使用文本编辑器打开包含图片的HTML文件。检查图片路径:寻找<img>标签,检查src属性是否正确指向图片文件。 例如:html<img src="images/example.jpg" alt="Example Image">验证路径:确认路径是否正确,如果是相对路径,确保它…

STL map、set、multi_map、multi_set 基本概念与用法

目录基本概念关联式容器键值对树形结构的关联式容器set描述set的使用map描述map的使用multiset描述multiset简单使用multimap描述底层结构 基本概念 关联式容器在初阶阶段,我们已经接触过STL中的部分容器,比如:vector、list、deque、 forward_list(C++11)等,这些容器统称为…

如何通过PHP脚本重置密码

<?php $servername = "localhost"; $username = "your_username"; $password = "your_password"; $dbname = "your_database";// 创建连接 $conn = new mysqli($servername, $username, $password, $dbname);// 检测连接 if ($con…

请问网站密码错误怎么找回

当遇到网站密码错误的情况时,可以采取以下几种方式来找回密码:使用找回密码功能:大多数网站都会提供“忘记密码”或“找回密码”的功能。 在登录页面下方通常可以看到这样的链接或按钮。通过邮箱找回:点击“忘记密码”后,网站会要求你提供注册时使用的电子邮件地址。 网站…

网站405错误怎么解决

网站出现405 Method Not Allowed错误通常意味着服务器理解了请求头,但拒绝执行请求方法(如GET、POST、PUT、DELETE等)。这种错误通常是因为服务器不允许使用特定的HTTP方法访问某个资源。以下是一些解决405 Method Not Allowed错误的方法:检查请求方法:确认你使用的HTTP请…

Adobe Substance 3D Sampler v4.2.2 下载及安装教程(3D材质管理软件)

前言 Substance 3D Sampler简称“Sa”是一款由Adobe新推出的3D真实材质贴图制作软件。允许用户通过调整和混合现有材料,或通过扫描(单个或多个图像)中提取新材料来创建和迭代材料集合,从而轻松将真实的图片转换为具有真实感的表面或HDR环境,为用户创作出更为丰富的材质贴图…

网站还原错误怎么解决

在安装网站的过程中遇到了“网站还原错误”,那么这个问题可能是指在网站备份恢复时遇到的错误。这种情况通常发生在网站迁移或恢复备份文件时。 下面是一些解决“网站还原错误”的方法:检查备份文件的完整性和正确性:确保备份文件没有损坏或不完整。 使用文件压缩软件(如Wi…

信息学奥赛初赛天天练-73-NOIP2016普及组-基础题4-枚举法、放苹果、统筹方法

NOIP 2016 普及组 基础题4 16 有 7个一模一样的苹果,放到 3个一样的盘子中,一共有( )种放法 A 7 B 8 C 21 D 3^7 17 下图表示一个果园灌溉系统,有 A,B,C,DA,B,C,D 四个阀门,每个阀门可以打开或关上,所有管道粗细相同,以下设置阀门的方法中, 可以让果树浇上水的是…

网站证书错误怎么解决?怎么解决网站证书错误

网站证书错误通常是因为SSL/TLS证书出现问题导致的。这类错误可能会出现在浏览器的地址栏中,提示用户该网站的安全证书存在问题。下面是一些常见的解决方法:确认网站安全:确认该网站是可信的,而不是钓鱼网站。检查系统时间:确认你的计算机系统时间设置正确。 如果时间不正…

网站cms备案号位置怎么更改

要更改网站CMS备案号的位置,通常需要通过编辑模板文件来实现。以下是一般的步骤:登录CMS后台:登录你所使用的CMS(例如织梦CMS、帝国CMS等)的后台管理界面。找到模板管理:在后台管理界面中找到“模板管理”或类似的选项。编辑模板文件:选择需要更改备案号位置的模板文件,…

织梦cms数据库配置文件在哪

织梦CMS的数据库配置文件通常位于 /data/common.inc.php 文件中。在这个文件里,你可以找到与数据库连接相关的配置信息。 具体的配置项包括:$cfg_dbhost:数据库地址,默认为 localhost。 $cfg_dbname:数据库名称。 $cfg_dbuser:数据库用户名。 $cfg_dbpwd:数据库密码。当…

织梦dede:php标签是什么

{dede:php} 标签是织梦CMS (DedeCMS) 中的一个特殊标签,用于在模板文件中嵌入 PHP 代码。这个标签允许开发者在织梦CMS的模板中直接编写 PHP 代码,从而实现更灵活的逻辑处理。 用法概述标签语法:开始标签:{dede:php} 结束标签:{/dede:php}基本用法:在 {dede:php} 和 {/de…