为 max310x SPI-UART 转换器启用 RS485 模式
Enable RS485 mode for max310x SPI-UART converter
在我的应用中我需要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 上的 UARTS 似乎工作正常 - 两个 rs485 都在传输数据,但没有接收数据。问题是 RTS 始终处于 0V 电平...
在来自 am3352 的 UART 中,我在设备树中使用以下 属性:"linux,rs485-enabled-at-boot-time"。但是将它添加到主 max310x_0 节点并没有产生任何效果——这个节点是扩展器节点(包含 2 个 UART 和 gpio 控制器),而不是 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
的值根据 linux,rs485-enabled-at-boot-time
的存在从 134225920
切换到 134225921
。
但 RTS 引脚在我的示波器上仍然保持恒定的 0V...
我想弄清楚 SER_RS485_RTS_ON_SEND
和 SER_RS485_RTS_AFTER_SEND
是否与此有关,但我确信它仅用于恢复 RTS 信号。
经过几次尝试,IOCTL 是最好和最简单的解决方案。这是一些对我有很大帮助的示例代码。 https://gist.github.com/amarburg/07564916d8d32e20e6ae375c1c83a995
这是如何使用 IOCTL 打开和关闭 RS485 模式并读取其当前模式的基本示例。适用于 CPU 内部 UARTS 和 MAX3109。
在我的应用中我需要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 上的 UARTS 似乎工作正常 - 两个 rs485 都在传输数据,但没有接收数据。问题是 RTS 始终处于 0V 电平...
在来自 am3352 的 UART 中,我在设备树中使用以下 属性:"linux,rs485-enabled-at-boot-time"。但是将它添加到主 max310x_0 节点并没有产生任何效果——这个节点是扩展器节点(包含 2 个 UART 和 gpio 控制器),而不是 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
的值根据 linux,rs485-enabled-at-boot-time
的存在从 134225920
切换到 134225921
。
但 RTS 引脚在我的示波器上仍然保持恒定的 0V...
我想弄清楚 SER_RS485_RTS_ON_SEND
和 SER_RS485_RTS_AFTER_SEND
是否与此有关,但我确信它仅用于恢复 RTS 信号。
经过几次尝试,IOCTL 是最好和最简单的解决方案。这是一些对我有很大帮助的示例代码。 https://gist.github.com/amarburg/07564916d8d32e20e6ae375c1c83a995
这是如何使用 IOCTL 打开和关闭 RS485 模式并读取其当前模式的基本示例。适用于 CPU 内部 UARTS 和 MAX3109。