简体   繁体   English

为 max310x SPI-UART 转换器启用 RS485 模式

[英]Enable RS485 mode for max310x SPI-UART converter

In my application I need RS485 interfaces.在我的应用程序中,我需要 RS485 接口。 I am using some UARTs from am3352 but I need few more, so I'm trying to expand using SPI and max3109 chip.我正在使用 am3352 的一些 UART,但我需要更多,所以我正在尝试使用 SPI 和 max3109 芯片进行扩展。

I have successfully added max3109 to my device tree using module max310x - it shows two devices: /dev/ttyMAX0 and /dev/ttyMAX1.我已经使用模块 max310x 成功地将 max3109 添加到我的设备树 - 它显示了两个设备:/dev/ttyMAX0 和 /dev/ttyMAX1。 Here is the device tree fragment:这是设备树片段:

&spi1 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&spi1_pins>;
    num_cs = <1>;
    cs-gpios = <&gpio2 17 0>;
    ti,pindir-d0-out-d1-in;

    max310x_0: max0@0 {
        compatible = "maxim,max3109";
        reg = <0>;
        spi-max-frequency = <24000000>;
        clocks = <&clk1m8>;
        clock-names = "xtal";
        interrupt-parent = <&gpio2>;
        interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
        gpio-controller;
        #gpio-cells = <2>;
        clk1m8: clk1m8 {
            compatible = "fixed-clock";
            #clock-cells = <0>;
            clock-frequency = <1843200>;
        };
    };
};

and the pins:和引脚:

spi1_pins: pinmux_spi1_pins {
    pinctrl-single,pins = <
        0x108 (PIN_INPUT_PULLUP | MUX_MODE2) /* (H16) gmii1_col.spi1_sclk */
        0x10c (PIN_INPUT_PULLUP | MUX_MODE2) /* (H17) gmii1_crs.spi1_d0 */
        0x110 (PIN_INPUT_PULLUP | MUX_MODE2) /* (J15) gmii1_rxer.spi1_d1 */
    >;
};

UARTs from max3109 are connected to rs232/rs485 converter with max3109's RTSn pins conected to both DE and RE pins. max3109 的 UART 连接到 rs232/rs485 转换器,max3109 的 RTSn 引脚连接到 DE 和 RE 引脚。

The problem: UARTS on max3109 seems to work fine - both rs485 are transmitting data, but not reciving.问题:max3109 上的 UARTS 似乎工作正常 - 两个 rs485 都在传输数据,但没有接收。 Problem is that RTS is always at 0V level...问题是 RTS 始终处于 0V 电平...

In UARTs from am3352 I am using in device tree the following property: "linux,rs485-enabled-at-boot-time".在 am3352 的 UART 中,我在设备树中使用以下属性:“linux,rs485-enabled-at-boot-time”。 But adding it to main max310x_0 node is not giving any effect - this node is the expander node (containing 2 UARTs and gpio-controller), not the UART itself.但是将它添加到主要的 max310x_0 节点没有任何效果——这个节点是扩展器节点(包含 2 个 UART 和 gpio 控制器),而不是 UART 本身。

My idea is that I need to add a child-nodes for each UART and in it place the property "linux,rs485-enabled-at-boot-time".我的想法是我需要为每个 UART 添加一个子节点,并在其中放置属性“linux,rs485-enabled-at-boot-time”。 But I don't have a clue how to do it.但我不知道该怎么做。 I tried something like this:我试过这样的事情:

&spi1 {
    status = "okay";
    pinctrl-names = "default";
    pinctrl-0 = <&spi1_pins>;
    num_cs = <1>;
    cs-gpios = <&gpio2 17 0>;
    ti,pindir-d0-out-d1-in;

    max310x_0: max0@0 {
        compatible = "maxim,max3109";
        reg = <0>;
        spi-max-frequency = <24000000>;
        clocks = <&clk1m8>;
        clock-names = "xtal";
        interrupt-parent = <&gpio2>;
        interrupts = <12 IRQ_TYPE_EDGE_FALLING>;
        gpio-controller;
        #gpio-cells = <2>;
        clk1m8: clk1m8 {
            compatible = "fixed-clock";
            #clock-cells = <0>;
            clock-frequency = <1843200>;
        };
        ttyMAX0 {
            linux,rs485-enabled-at-boot-time;
        };
        ttyMAX1 {
            linux,rs485-enabled-at-boot-time;
        };
    };
};

but it didn't worked.但它没有用。

My question: How am I supposed to add those child-nodes (if that's the proper way) and what should I place in them to make RTS work?我的问题:我应该如何添加这些子节点(如果这是正确的方法)以及我应该在它们中放置什么以使 RTS 工作?

EDIT: after sawdust suggestion it seems it's impossible to add rs485 mode in device tree.编辑:在锯末建议之后,似乎不可能在设备树中添加 rs485 模式。 So I tried to add this functionality to device tree and I think I'm starting to understand how things work down in here.所以我尝试将此功能添加到设备树中,我想我开始了解这里的工作原理。 To start with something I'm printing port.flags value to dmesg and it seems my little insertion works (a bit) - it changes the value depending on presence of linux,rs485-enabled-at-boot-time parameter in device tree.首先,我正在将port.flags值打印到dmesg ,看起来我的小插入工作(有点) - 它根据设备树中linux,rs485-enabled-at-boot-time参数的存在来更改值。 Here is the code I have inserted:这是我插入的代码:

    if (of_property_read_bool(dev->of_node, "linux,rs485-enabled-at-boot-time")) 
    s->p[i].port.flags |= SER_RS485_ENABLED; 
    printk("s->p[i].port.flags is: %d\n",s->p[i].port.flags); 

The value of port.flags toggles from 134225920 to 134225921 depending on presence of linux,rs485-enabled-at-boot-time .port.flags切换从134225920134225921取决于存在linux,rs485-enabled-at-boot-time but the RTS pin still have constant 0V on my oscilloscope... I'm trying to figure out if SER_RS485_RTS_ON_SEND and SER_RS485_RTS_AFTER_SEND have something to do with this, but I'm prete sure it's only for reverting RTS signal.但是 RTS 引脚在我的示波器上仍然具有恒定的 0V SER_RS485_RTS_ON_SEND ...我想弄清楚SER_RS485_RTS_ON_SENDSER_RS485_RTS_AFTER_SEND是否与此有关,但我确信它仅用于恢复 RTS 信号。

After few attempts IOCTL was the best and easiest solution.经过几次尝试, IOCTL是最好和最简单的解决方案。 Here is some example code that helped me much.这是一些对我有很大帮助的示例代码。 https://gist.github.com/amarburg/07564916d8d32e20e6ae375c1c83a995 https://gist.github.com/amarburg/07564916d8d32e20e6ae375c1c83a995

It's basic example how to turn RS485 mode on and off using IOCTL and read it's current mode.这是如何使用IOCTL打开和关闭 RS485 模式并读取其当前模式的基本示例。 Works with both CPUs internal UARTS and MAX3109.适用于两个 CPU 内部 UARTS 和 MAX3109。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM