首页 > 其他分享 >RK3588添加支持RS485收发

RK3588添加支持RS485收发

时间:2024-08-23 18:04:13浏览次数:13  
标签:rs485 8250 tx RK3588 RS485 收发 serial include port

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 structs
                                           are 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

  

标签:rs485,8250,tx,RK3588,RS485,收发,serial,include,port
From: https://www.cnblogs.com/wmc245376374/p/18376780

相关文章

  • RK3588开发笔记-pdm接口ES7201音频采集调试记录
    目录​​​​​​​前言一、ES7201技术规格二、PDM接口说明RK3588的PDM接口特性三、原理图连接四、内核配置五、音频调试总结前言        在RK3588开发过程中,音频采集是一个常见的需求,而PDM(PulseDensityModulation)接口因其简单性和低成本广泛应用......
  • 【WCH蓝牙系列芯片】-基于CH582开发板—蓝牙从机HAL_SLEEP模式,串口唤醒收发数据
    -------------------------------------------------------------------------------------------------------------------------------------在之前的博客文档中介绍过CH582作为蓝牙主机,开启睡眠后,通过串口唤醒,并接收串口数据。这里再讲解一下使用CH582芯片作为蓝牙从机,开......
  • 【漫谈C语言和嵌入式004】深入理解RS232、RS422和RS485:嵌入式系统中的串行通信协议
            在嵌入式系统设计中,串行通信协议是设备间数据传输的重要方式。其中,RS232、RS422和RS485是三种常用的标准。这些协议不仅在工业控制、仪器仪表、网络通信等领域得到广泛应用,也在许多嵌入式系统项目中扮演着重要角色。在本文中,我们将深入探讨这三种串行通信标准......
  • 详解Xilinx FPGA高速串行收发器GTX/GTP(9)--TX/RX通道
    目录1、TX端的剩余模块1.1、TXPIPEControl1.2、TXGearbox1.3、PCIEBeacon1.4、SATAOOB1.5、PhaseAdjustFIFO1.6、Polarity1.7、PISO1.8、TXPre/PostEmp和10、TXDriver1.9、TXOOBandPCIE1.10、TXDriver1.11、TXPhaseInterpolatorController(包括12......
  • 经销商文件收发系统:简化流程,释放数据价值!
    经销商文件收发是指在商业运作中,经销商与制造商、供应商、客户、合作伙伴、物流公司等不同角色之间进行文件、资料、产品信息等的传递和交换的过程。这一过程对于确保经销商能够获取最新的产品信息、销售策略、市场活动资料等至关重要,同时也涉及到订单处理、库存管理、财务结算等......
  • CAN收发器断电后重新上电,导致CAN发送异常的问题
    项目背景基于安路FPGA设计的多路CAN控制器转发板,一路主CAN控制器,N路分CAN控制器;项目框图CAN控制器实现框图CAN收发异常的问题CAN复现问题的过程如下:主CAN收发器设备,FPGA-CAN转发板设备,分CAN收发器设备,三者同时上电时,CAN收发通讯正常;当其中的分CAN收发器设备断电后,主CAN......
  • 电压电流高速采集RS485数字信号输出方案
    宽电压供电DC9-30V/0.1A支持USBType-C接口供电和通讯交流款支持三路交流400v,电流互感器,支持波形,半波全波等分析功能。其余可定制功能(±100V,±10V,4-20mA,75mV分流器,K热偶,PT100等)可提供一路5V供电输出给传感器(默认不带,可供电或报警输出)支持离线数据采集,T......
  • 信号处理卡 数据收发卡设计方案:428-基于XC7Z100+ADRV9009的双收双发无线电射频板卡 5G
    数据收发卡设计方案:428-基于XC7Z100+ADRV9009的双收双发无线电射频板卡5G小基站无线图传基于XC7Z100+ADRV9009的双收双发无线电射频板卡一、板卡概述        基于XC7Z100+ADRV9009的双收双发无线电射频板卡是基于Xilinx ZYNQ FPGA和ADI的无线收发芯片ADRV90......
  • 探索巅峰性能 | 迅为RK3588开发板深度剖析
    探索巅峰性能|迅为RK3588开发板深度剖析 迅为RK3588作为瑞芯微公司旗下一款高端处理器的杰出代表,凭借卓越的性能与多样化的外设接口成为了众多开发和爱好者的首选。随着RK3588在市场上的广泛应用,大家不禁要提出疑问:RK3588究竟强在何处?在2022年,北京迅为电子推出了基于RK3588......
  • 高速收发器(四)
    通过前面的学习,我们对GTX的内部结构和工作原理已经有了一定的了解,但是通过文字的描述我们只能掌握一些基础知识,想要真正熟悉GTX还要通过具体的使用。对于GTX的使用,第一步就是打开IPcatalog然后搜索GT,找到下面的7SeriesFPGAsTranscelversWizard之后双击打开,进入配置界面。......