allwinner 全志RS485调试,GPIO状态与万用表测量不同

全志RS485调试
思路:UART驱动中已经将485流控功能加进去了,所以我们只需要根据硬件原理图配置一下485脚的GPIO就行了。
硬件原理图:
allwinner 全志RS485调试,GPIO状态与万用表测量不同_第1张图片
将UART3 UART4的RTS脚配置为485流控脚就行, RX和TX不需要配置,在pinctrol已经配置好了。
allwinner 全志RS485调试,GPIO状态与万用表测量不同_第2张图片
设备树修改:

        uart3: uart@05000c00 {
            rs485-en = <&pio PD 16 1 1 1 1>;
            status = "okay";
        };
        uart4: uart@05001000 {
            rs485-en = <&pio PD 20 1 1 1 1>;
            status = "okay";
        };

然后通过串口工具测试发现ok。UART3 UART4就这么简单配置好了。然后UART0卡了我很久,我们来看UART的配置:
allwinner 全志RS485调试,GPIO状态与万用表测量不同_第3张图片
UART0的RTS脚为UART1_RTS,找到这个脚在主控中的PGIO号。
allwinner 全志RS485调试,GPIO状态与万用表测量不同_第4张图片
修改设备树:

		uart0: uart@05000000 {
			uart-supply = <&reg_bldo3>;
			rs485-en = <&pio PG 8 1 1 1 1>;
			status = "okay";

		};

然后诡异的事情就发生了,当我配置完这个脚后,485只能发送不能接受,可是UART0和UART3 UART4的配置都差不多为什么会导致这样的情况呢?接下来就是漫长的debug了。。。。
首先我们用测量PG8的引脚发现为低电平,UART3 UART4的引脚为高电平这就奇怪了。我们去驱动加点打印信息看一下。

A133P:/ $
A133P:/ $ dmesg | grep lijie
[    1.082990] 3 lijie debug gpio_direction_output ok!
[    1.083005] uart uart0:  3 lijie debug sw_uport->rs485_gpio = 200 value = 0
[    1.083018] uart uart0:  x lijie debug sw_uport->rs485_gpio = 200 value = 0
[    1.085674] 3 lijie debug gpio_direction_output ok!
[    1.085687] uart uart3:  3 lijie debug sw_uport->rs485_gpio = 112 value = 0
[    1.085700] uart uart3:  x lijie debug sw_uport->rs485_gpio = 112 value = 0
[    1.086661] 3 lijie debug gpio_direction_output ok!
[    1.086674] uart uart4:  3 lijie debug sw_uport->rs485_gpio = 116 value = 0
[    1.086686] uart uart4:  x lijie debug sw_uport->rs485_gpio = 116 value = 0
A133P:/ $

我们发现驱动将485的gpio调为低电平默认接受状态。
allwinner 全志RS485调试,GPIO状态与万用表测量不同_第5张图片
我们使用串口工具,打开UART0并且发送几条数据,再打开驱动调试信息看看

A133P:/ # dmesg | grep lijie
[    1.091874] 3 lijie debug gpio_direction_output ok!
[    1.091889] uart uart0:  3 lijie debug sw_uport->rs485_gpio = 200 value = 0
[    1.091902] uart uart0:  x lijie debug sw_uport->rs485_gpio = 200 value = 0
[    1.094525] 3 lijie debug gpio_direction_output ok!
[    1.094539] uart uart3:  3 lijie debug sw_uport->rs485_gpio = 112 value = 0
[    1.094551] uart uart3:  x lijie debug sw_uport->rs485_gpio = 112 value = 0
[    1.095534] 3 lijie debug gpio_direction_output ok!
[    1.095547] uart uart4:  3 lijie debug sw_uport->rs485_gpio = 116 value = 0
[    1.095559] uart uart4:  x lijie debug sw_uport->rs485_gpio = 116 value = 0
[   59.966164] 5 lijie debug sw_uport->rs485_gpio = 200 value = 1
[   59.970473] 1 lijie debug sw_uport->rs485_gpio = 200 value = 0
[   60.197280] 5 lijie debug sw_uport->rs485_gpio = 200 value = 1
[   60.201566] 1 lijie debug sw_uport->rs485_gpio = 200 value = 0
[   60.438232] 5 lijie debug sw_uport->rs485_gpio = 200 value = 1
[   60.442523] 1 lijie debug sw_uport->rs485_gpio = 200 value = 0
[   60.685118] 5 lijie debug sw_uport->rs485_gpio = 200 value = 1
[   60.689413] 1 lijie debug sw_uport->rs485_gpio = 200 value = 0

可以发现驱动在数据即将要发送的时候会将485的RTS拉高进入发送模式,当数据发送完毕就会拉低进入接收模式,这个逻辑说明驱动是没有问题的,但是我们用万用表测量发现UART0的485脚一直是高电平状态,根本就没有拉低过。
这就很奇怪,我们再看一下gpio的状态:

A133P:/sys/kernel/debug # cat gpio
gpiochip1: GPIOs 0-319, parent: platform/pio, pio:
 gpio-34  (                    |usbhub_rst          ) out hi
 gpio-38  (                    |touch_gpio_reset    ) out hi
 gpio-39  (                    |touch_gpio_irq      ) in  hi
 gpio-40  (                    |?                   ) in  hi
 gpio-106 (                    |cs-gpios            ) out hi
 gpio-112 (                    |RS485-EN            ) out lo
 gpio-116 (                    |RS485-EN            ) out lo
 gpio-118 (                    |?                   ) in  hi
 gpio-166 (                    |cd                  ) in  hi
 gpio-200 (                    |RS485-EN            ) out lo
 gpio-232 (                    |otg_id              ) in  hi
 gpio-235 (                    |?                   ) out hi
 gpio-236 (                    |phy-rst             ) out hi
 gpio-238 (                    |irq_gpio            ) in  hi
 gpio-240 (                    |mobile_pwr          ) out hi
 gpio-242 (                    |mobile_rst          ) out lo
 gpio-243 (                    |SPK                 ) out lo

gpiochip0: GPIOs 352-383, parent: platform/r_pio, r_pio:
 gpio-354 (                    |bt_rst              ) out lo
 gpio-357 (                    |wifi_bt_pwr         ) out hi
 gpio-360 (                    |usb1-vbus           ) out hi

PG8 = gpio 200 上面显示为485脚输出状态低电平,但是用万用表测试发现是高电平。。。。。这个时候就很无语了。。。。。。。
然后我就想手动拉低确定是不是GPIO号的问题:

mount -t debugfs debug /proc/sys/debug
cd /proc/sys/debug/sunxi_pinctrl
echo PH8 > sunxi_pin  
echo PH6 1 > function
echo PH6 0 > data 

这个是全志手动调试GPIO的方法,输入完上面的命令后,PG8应该为低电平,我们用万用表测试确实是低电平这说明GPIO号没有问题。驱动没有问题,GPIO号没有问题,UART0的485设备树没有问题,这就不知道是什么原因了。。。。。。。。。
后面发现,UART0的RTS脚为UART1_RTS,那UART1呢?

allwinner 全志RS485调试,GPIO状态与万用表测量不同_第6张图片
我们发现UART1 UART2就是普通的串口,然后我们去设备树看看这两个串口的配置信息。

 uart1_pins_a: uart1@0 {
        allwinner,pins = "PG6", "PG7", "PG8", "PG9";
        allwinner,pname = "uart1_tx", "uart1_rx",uart1_rts", "uart1_cts";
         allwinner,function = "uart1";
         allwinner,muxsel = <2>;
         allwinner,drive = <1>;
 };
 
 uart1_pins_b: uart1@1 {
        allwinner,pins = "PG6", "PG7", "PG8", "PG9";
        allwinner,function = "io_disabled";
        allwinner,muxsel = <7>;
        allwinner,drive = <1>;
        allwinner,pull = <1>;
};

看到这里就懂了,pinctrl中配置了UART1的rts和cts脚,但是硬件上面是不需要这两个脚的。
所以我们修改设备树

--- a/arch/arm64/boot/dts/sunxi/sun50iw10p1-pinctrl.dtsi
+++ b/arch/arm64/boot/dts/sunxi/sun50iw10p1-pinctrl.dtsi
@@ -133,9 +133,8 @@
                        };
 
                        uart1_pins_a: uart1@0 {
-                               allwinner,pins = "PG6", "PG7", "PG8", "PG9";
-                               allwinner,pname = "uart1_tx", "uart1_rx",
-                                                 "uart1_rts", "uart1_cts";
+                               allwinner,pins = "PG6", "PG7";
+                               allwinner,pname = "uart1_tx", "uart1_rx";
                                allwinner,function = "uart1";
                                allwinner,muxsel = <2>;
                                allwinner,drive = <1>;
@@ -143,7 +142,7 @@
                        };
 
                        uart1_pins_b: uart1@1 {
-                               allwinner,pins = "PG6", "PG7", "PG8", "PG9";
+                               allwinner,pins = "PG6", "PG7";
                                allwinner,function = "io_disabled";
                                allwinner,muxsel = <7>;
                                allwinner,drive = <1>;

然后重新编译。
allwinner 全志RS485调试,GPIO状态与万用表测量不同_第7张图片
最后UART0就可以正常收到数据了。

总结:
虽然这个485调试花了很多时间,但是学会了很多调试技巧。
在全平台手动拉高拉低,物理手动拉低(镊子短接地)
对485了解更加深刻
对硬件原理图更加得心应手得找到想要的信息了

你可能感兴趣的:(LInux嵌入式,android,linux,嵌入式硬件,软件工程,java)