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

时间:2019-12-19 06:08:20

标签: linux uart device-tree rs485

在我的应用程序中,我需要RS485接口。我正在使用am3352的一些UART,但我还需要更多,因此我正尝试使用SPI和max3109芯片进行扩展。

我已经使用模块max310x成功地将max3109添加到我的设备树中-它显示了两个设备:/ dev / ttyMAX0和/ dev / ttyMAX1。这是设备树片段:

&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>;
        };
    };
};

和图钉:

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 */
    >;
};

max3109的UART连接到rs232 / rs485转换器,而max3109的RTSn引脚连接到DE和RE引脚。

问题:max3109上的UART似乎工作正常-rs485都在传输数据,但未接收数据。问题是RTS始终处于0V电平...

在am3352的UART中,我在设备树中使用以下属性:“ Linux,在引导时启用了rs485”。但是将其添加到max310x_0主节点不会产生任何效果-该节点是扩展器节点(包含2个UART和gpio-controller),而不是UART本身。

我的想法是我需要为每个UART添加一个子节点,并在其中放置属性“ linux,rs485-enabled-at-boot-time”。但是我不知道如何去做。我尝试过这样的事情:

&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;
        };
    };
};

但是没有用。

我的问题:我应该如何添加这些子节点(如果那是正确的方法)?我应该在其中放置什么以使RTS正常工作?

编辑: 经过锯末建议后,似乎无法在设备树中添加rs485模式。 因此,我试图将此功能添加到设备树中,我想我开始了解这里的工作原理。首先,我将port.flags的值打印到dmesg上,似乎我的小插入工作了(有点)-它根据设备树中linux,rs485-enabled-at-boot-time参数的存在来更改值。 这是我插入的代码:

    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); 

取决于port.flags的存在,134225920的值从134225921切换到linux,rs485-enabled-at-boot-time。 但是我的示波器上的RTS引脚仍然具有恒定的0V ... 我正在尝试弄清SER_RS485_RTS_ON_SENDSER_RS485_RTS_AFTER_SEND是否与此有关,但是我敢肯定这仅是用于还原RTS信号。

1 个答案:

答案 0 :(得分:1)

经过几次尝试, IOCTL 是最好,最简单的解决方案。这是一些示例代码,对我有很大帮助。 https://gist.github.com/amarburg/07564916d8d32e20e6ae375c1c83a995

这是一个基本示例,说明如何使用 IOCTL 开启和关闭RS485模式并读取其当前模式。可与两个CPU内部的UART和MAX3109一起使用。