This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

AM6548: UART to RS 485 Conversion Issue

Part Number: AM6548
Other Parts Discussed in Thread: SYSCONFIG

Tool/software:

Hi TI,

In our custom hardware we have am6548 beta 2.0 chip and using SDK version 8.2 for Linux.

We are using 2 UART ports as rs485

1. Port 1 -> Main UART 0 , pins AF11 , AE11 and RTS at AD11

2. Port 2 -> Wakeup UART , pins AB5, AB1 and RTS at AC1 

These 2 UARTS are enumerated as ttyS0 and ttyS2 in Linux. 

I am doing echo on 1 port and cat on 2nd port but I dont receive anything on receiver end. Kernel configurations is default.

Questions :

1. Do I need to make any change in serial driver to make it work for 485 mode ? 

2. Can I do echo and cat from commandline with 485. 485 conversion hardware is on our hardware itself.

Here is dts entry for both the UARTS.

 

Let me know if my dts entry is correct .

Let me know driver changes to be done to make the echo and cat working from driver end in 485 mode.

Regards,

Sarfaraz

  • Hi Sarfaraz,

    I reviewed the information you provided, my first question is why you changed the device tree power-domains for main_uart0 from TI_SCI_PD_EXCLUSIVE to TI_SCI_PD_SHARED?

  • Thanks Bin Liu for connecting, this might be done way back from SDK 6 as we were not using the RTU part it was commented. I Will change the same in device tree. Can you tell me the difference between the 2 Macros. 

    Also is other device tree part OK for RS485 ? 

  • Hi Sarfaraz,

    I didn't look into the kernel code to see how these two macros are treated, but I believe they represent the SoC, PD_EXCLUSIVE means this power domain (PD) has only this single module (uart0 in this case), while PD_SHARED means the power domain has multiple modules.

    Other parts of the device tree look good to me.

    If the RS485 still doesn't work after changed to PD_EXCLUSIVE, please provide the output of the following command:

    # dmesg | grep ttyS

  • Hi Bin Liu,

    When the parameter was SHARED then both the COM ports were detected but when I changed it to EXCLUSIVE then that uart is not detected during boot. 

    Is the linux driver capable of auto handling the RTS signals on hardware ? Do we need to make any changes to auto handle this ? 

    Is there any sample user level code which can test 485 over UART driver ? 

    In our case RTS signal is inverted on hardware. 

    Output with SHARED field : 

    [ 0.469484] 42300000.serial: ttyS0 at MMIO 0x42300000 (irq = 15, base_baud = 6000000) is a 8250
    [ 0.470978] 40a00000.serial: ttyS1 at MMIO 0x40a00000 (irq = 17, base_baud = 6000000) is a 8250
    [ 0.472745] 2800000.serial: ttyS2 at MMIO 0x2800000 (irq = 30, base_baud = 3000000) is a 8250
    [ 0.474006] 2810000.serial: ttyS3 at MMIO 0x2810000 (irq = 31, base_baud = 3000000) is a 8250
    [ 1.748185] printk: console [ttyS3] enabled
    [ 1.754138] 2820000.serial: ttyS4 at MMIO 0x2820000 (irq = 32, base_baud = 3000000) is a 8250

    Output with EXCLUSIVE Field :

    [ 0.469484] 42300000.serial: ttyS0 at MMIO 0x42300000 (irq = 15, base_baud = 6000000) is a 8250
    [ 0.470978] 40a00000.serial: ttyS1 at MMIO 0x40a00000 (irq = 17, base_baud = 6000000) is a 8250
    [ 0.474006] 2810000.serial: ttyS3 at MMIO 0x2810000 (irq = 31, base_baud = 3000000) is a 8250
    [ 1.748185] printk: console [ttyS3] enabled
    [ 1.754138] 2820000.serial: ttyS4 at MMIO 0x2820000 (irq = 32, base_baud = 3000000) is a 8250

    Here you can see ttyS2 is missing where as ttyS0 is present in both case. 

    Regards,

    Sarfaraz 

  • Hi Sarfaraz,

    Please ignore my comment about the SHARD/EXCLUSIVE setting. I now see it is set to PD_EXCLUSIVE in k3-am65-main.dtsi, but then changed to PD_SHARD in k3-am654-base-board.dts. I am looking into this to understand the reason. But I think it should be set to PD_SHARD.

    Is the linux driver capable of auto handling the RTS signals on hardware ?

    Yes, the kernel UART driver handles the RTS pin based on transmitting or receiving in RS-485 mode.

    Is there any sample user level code which can test 485 over UART driver ? 

    I tested RS-485 on different Sitara EVMs a few times before, I believe I used linux-serial-test (https://github.com/cbrake/linux-serial-test.git), but I don't think I used echo/cat for RS-485.

    Since echo/cat doesn't set the UART termios, please use stty command to check both UART to ensure they set to the same baud rate.

    When you do echo/cat, have you checked if the UART RXD/TXD/RTS pins toggle as expected?

  • ok when I use SHARED the ttyS2 port is again detected in Linux boot. Do we need to use rts-gpio property in dts to control RTS line ?

  • The kernel uart driver supports both native RTS or gpio-based RTS. So you should be able to use either.

    The early version of the kernel had bugs in gpio-based RTS control, but I believe the issue should be fixed in the SDK8.x kernel.

  • Hi,

    We tried to view the data on scope. Found that the RTS is always stuck in transmit mode due to this we are only able to transmit and not able to receive . When we try to receive using cat command we found that the voltages are getting dragged to 1V where it should be 5 V as expected. This is with the above dts file. Found some differences in data sheet and TRM, in data sheet wakeup UART RTS signal is mentioned as positive and in sysconfig tool it is mentioned as inverted. How to know which one is correct. Even in TRM Wakeup uart is positive signal. 

    Regards,

    Sarfaraz

  • Hi Sarfaraz,

    I am out of office for a week. So I am looping in our UART hardware expert for your current questions. I will follow up on this thread once I am back in office.

  • Hello Sarfaraz,

    We tried to view the data on scope. Found that the RTS is always stuck in transmit mode due to this we are only able to transmit and not able to receive . When we try to receive using cat command we found that the voltages are getting dragged to 1V where it should be 5 V as expected. This is with the above dts file.

    I need more details on the interface used and connections. 5V is suspect is after the level translation from the SOC.

    Found some differences in data sheet and TRM, in data sheet wakeup UART RTS signal is mentioned as positive and in sysconfig tool it is mentioned as inverted. How to know which one is correct. Even in TRM Wakeup uart is positive signal. 

    Please point me to the section you are referring.

    Regards,

    Sreenivasa

  • Hi Sreenivasa,

    Here is the screenshot of our Schematics 485 section.

    Regarding the difference in Data sheet and TRM 

    Datasheet :

    TRM : 

    Here you can see that in 1st Image all signals are RTSn and in TRM it is mentioned some are RTS and some are RTSn.

    When I Probe with Scope I can see the UART is stuck in transmit mode always and not able to receive the data. We are using Wakeup UART and MAIN UART 0 for RS - 485

    regards,

    Sarfaraz 

  • Hello Sarfaraz,

    I suspect you might have to refer the below diagram

    Figure 12-243. RS-485 Mode Interface Signals

    A high places the transceiver in transmit mode.

    the voltages are getting dragged to 1V where it should be 5 V as expected

    This is the isolator output. I suspect the input could be floating (IO not initialized) How about the isolator input?

    i assume this is the output of the SOC. Is there a cap on the IO. Is there a provision to isolate the input to the isolator and test.

    Regards,

    Sreenivasa

  • Hello Sarfaraz,

    Checking if you have you been able to perform some tests?

    Regards,

    Sreenivasa

  • Hi Sreenivasa,

    I verified that the pins are not floating in any case. Also tried to add the pull up just to give a try from device tree in linux but same observation.

    Also 1 observation was that when I transmitted the character string the RTS was high and after the transmission is complete it became low for short duration and again it went high .

  • Hello Sarfaraz,

    Thank you. 

    We tried to view the data on scope. Found that the RTS is always stuck in transmit mode due to this we are only able to transmit and not able to receive . When we try to receive using cat command we found that the voltages are getting dragged to 1V where it should be 5 V as expected. This is with the above dts file. Found some differences in data sheet and TRM, in data sheet wakeup UART RTS signal is mentioned as positive and in sysconfig tool it is mentioned as inverted. How to know which one is correct. Even in TRM Wakeup uart is positive signal. 

    the output of the isolator per your inputs is 1V. I would expect this to be 0 or 5V if the input is 0 or high.

    I am trying to understand if this is a hardware of software issue. Id the hardware is not a concern, i will have to reassign to a software expert.

    Can you confirm the UART connections from the SOC to the digital isolator toggles between 3.3V and 0V.  The RTS from the SOC is expected to be high during transmit and 0 during receive. 

     

    Regards,

    Sreenivasa

  • Hi Sreenivasa,

    We tried to capture the signals before the isolator and same is observation. the RTS line is low for around 7.8ms and again goes high after transmit is complete. 

    Regards,

    Sarfaraz

  • Hello Sarfaraz

    Thank you.

    Based on the comparison of the yellow signals, i assume the amplitude seems to be Ok. Can you please measure the amplitude.

    I suspect there is no hardware issue.

    Are you checking why the RTS goes high after some time?

    Can you confirm status of RTS during the reset when the RS485 is configured.

    Regards,

    Sreenivasa

  • Hi Sreenivasa,

    I could not find anything in driver that make RST high automatically after transmit.

    RTS is made high immediately when 8250 driver is initialized by Linux during boot time.

    linux,rs485-enabled-at-boot-time; this node in device tree enabled 485 on UART at boot time when driver is loaded. 

    Regards,

    Sarfaraz

  • Hello Sarfaraz

    Thank you.

    I could not find anything in driver that make RST high automatically after transmit.

    is the toggle time after transmitting the data consistent.

    I may have to assign to a software expert.

    Could you please measure the RTS amplitude and confirm there is no hardware issue for me to reassign.

    Regards,

    Sreenivasa

  • Hi Sreenivasa ,

    I have verified the voltage levels for RTS without Isolator. it is 3.3 V when high and 0 v when low. but low remains only for 7.8ms and again goes to high by default. 

    Regards,

    Sarfaraz

  • Hello Sarfaraz

    Thank you.

    Let me check internally and assign to a software expert to support.

    Regards,

    Sreenivasa

  • Hello Sarfaraz,

    The subject matter expert is out of office. Please expect a delayed response.

  • Hi Anshu, 

    Any update on the above issue. Can you tell me if RTS line is auto controlled by UART driver in AM6548 or we need to manually control the lines from application ?

  • Hi Sarfaraz,

    I am back in office this week, but have been working on a customer line down issue.

    The RTS line is controlled by the kernel driver in either RS232 or RS485 mode, it is transparent to Linux user space application.

  • Hi Bin Liu,

    As the RTS should be controlled by driver and should be High only when transmit. I can see that RTS is stuck in High in our case I could not see RTS going to low during RX. 

    I dont see that driver is controlling the Line. 

    Regards,

    Sarfaraz

  • Hi Sarfaraz,

    As the RTS should be controlled by driver and should be High only when transmit. I can see that RTS is stuck in High in our case I could not see RTS going to low during RX. 

    Do you observe this RTS pin behavior on both WKUP_UART0 and MAIN_UART0, or only on WKUP_UART0 or MAIN_UART0?

    By default, the SDK Linux configures MAIN_UART0 as the Linux console. Have you changed the Linux console to other UART on your board so that your project can use MAIN_UART0 for the RS485 application?

    I dont see that driver is controlling the Line. 

    It is mainly handled by "set_mctrl" callback in kernel serial framework.

  • I can see the RTS behavior on both the UARTs. We are using Linux UART2 as our console uart and changed the same in all uboot and linux. that works properly. 

  • Hi Bin Liu,

    Can you reproduce this RTS issue on EVM and test if the RTS is high only when transmit and low in default state. 

  • Hi Sarfaraz,

    Yes, it is on my TODO list to check it on the EVM. However, I have 2 issues that I am currently debugging at this moment, both appear to require quite of my bandwidth, so I don't think I will get my hands on this in a few weeks.

    We had quite some customers using RS-485 on multiple of our processors, none of them reported such RTS behavior.

    When you test RS-485 on your board, can you please test with the open source program https://github.com/cbrake/linux-serial-test.git, and use '-q' option to run it in RS-485 mode.

    You might also want to test with the latest Processor SDK for AM65x (SDKv9.1) to see if the issue still exists.

  • Hi Bin Liu,

    I was checking the serial_core.c file and did not find anything related to rs485-rts-active-high looks like this is not being handled in 8250 driver. I found I TI post which has similar issue. 

    https://e2e.ti.com/support/processors-group/processors/f/processors-forum/527378/am335x-gpio-based-rts-for-rs-485

    In my case also when I made RTS as GPIO line and manually set the polarity I was able to send and receive the data but did not work when the driver is handling the RTS line it is stuck in 1 direction only. 

  • Hi Sarfaraz,

    I was checking the serial_core.c file and did not find anything related to rs485-rts-active-high looks like this is not being handled in 8250 driver.

    The RS485 RTS is default high, so "rs485-rts-active-high" doesn't nothing. The serial_core.c does handle "rs485-rts-active-low" though to change the default.

    I found I TI post which has similar issue. 

    This could be a different issue. The old kernel uses serial_omap.c driver, while it is no longer maintained and now 8250_omap.c is used.

    In my case also when I made RTS as GPIO line and manually set the polarity I was able to send and receive the data

    How did you "manually" set the gpio polarity, by defining rts-gpios DT property, or something else? The kernel uart driver supposed to support both gpio-based RTS and native RTS.

  • Hi Bin Liu,

    Yes I defined rts-gpios DT property and made the RTS line as GPIO , driver did not control the lines automatically but I manually controlled it from /sys/class/gpio interface and was able to send and receive the data. Looks like current driver is not able to control the RTS lines.

    Regards,

    Sarfaraz

  • Hi Sarfaraz,

    How did you test RS485 transfer? Did you use the linux-serial-test program I mentioned above?

  • Hi,

    Yes I used the linux serial test program in a loopback mode mentioned on their README, got the below output.

    /tmp # ./linux-serial-test -q -b 9600 -p /dev/ttyS2
    Linux serial test app
    /dev/ttyS2: No data received for 2.0s. No data transmitted for 2.0s.
    /dev/ttyS2: No data received for 3.0s. No data transmitted for 3.0s.
    /dev/ttyS2: No data received for 5.0s. No data transmitted for 5.0s.
    /dev/ttyS2: No data received for 6.7s.
    /dev/ttyS2: No data received for 8.7s. No data transmitted for 3.0s.
    /dev/ttyS2: No data received for 9.7s. No data transmitted for 4.0s.
    /dev/ttyS2: No data received for 10.7s. No data transmitted for 5.0s.
    /dev/ttyS2: No data received for 12.3s.
    /dev/ttyS2: No data received for 14.3s. No data transmitted for 3.0s.
    /dev/ttyS2: No data received for 15.3s. No data transmitted for 4.0s.
    /dev/ttyS2: No data received for 17.0s.
    /dev/ttyS2: No data received for 18.0s.
    /dev/ttyS2: No data received for 19.0s. No data transmitted for 2.0s.
    /dev/ttyS2: No data received for 20.0s. No data transmitted for 3.0s.
    /dev/ttyS2: No data received for 21.0s. No data transmitted for 4.0s.
    /dev/ttyS2: No data received for 22.7s.
    /dev/ttyS2: No data received for 23.7s.

  • Hi Sarfaraz,

    If you run the program as below to just send one char, is the RTS pin level the same before and after sending and toggled during sending the char?

    ./linux-serial-test -q -b 9600 -p /dev/ttyS2 -y 0x55 -r

  • Hi Bin Liu,

    I will try this scenario never tested with only 1 character. 

    I was checking the default dts files for IDK board I could not find any pinmux setting for wkup uart like other UARTs. Is it like fixed configuration and cannot be changed ?

    I can see pinmux for wkup_i2c but does not see anything related to UART.

    Regards,

    Sarfaraz

  • Hi Sarfaraz,

    Yes I thought transmitting just one char makes it easier to check the RTS pin state before, during, and after the transmission on a scope or logical analyzer.

    for IDK board I could not find any pinmux setting for wkup uart like other UARTs.

    The board device tree only enables the peripherals what are used on the board. WKUP_UART is not used in Linux on the EVM.

    Is it like fixed configuration and cannot be changed ?

    The WKUP_UART pinmux is listed in the AM65x device datasheet. I see the pins have multiple modes.

    I can see pinmux for wkup_i2c

    wkup_i2c is used on the board, it has device "pac9554" on the bus.

  • Hi Bin Liu,

    Shashank Kulkarni (FAE) from TI shared a link for similar observation for AM64XX : https://e2e.ti.com/support/processors-group/processors/f/processors-forum/1401085/am6442-rs485-driver-support/5363360#5363360

    After setting the bit from commandline using devmem command, the RTS line was properly controlled from driver and RS485 is working properly now. 

    command : devmem2 0x42300080 w 0x10 ; devmem2 0x02800080 w 0x10

    Are these changes planned to be integrated in Driver in upcoming releases. 

    Regards,

    Sarfaraz

  • Hi Sarfaraz,

    After setting the bit from commandline using devmem command, the RTS line was properly controlled from driver and RS485 is working properly now. 

    command : devmem2 0x42300080 w 0x10 ; devmem2 0x02800080 w 0x10

    This register bit is to enable the hardware RTS control for RS-485. This feature is enabled in SDK8.6, but not in SDK8.2.

    Without enabling this bit, the kernel UART drivers suppose to control the RTS pin based on the TX/RX direction of RS-485. I suspect there is something else which wasn't configured properly.

    Anyway, if setting this register can make RTS pin working correctly on your board, I recommend you move to SDK8.6 kernel to use this hardware RTS control feature.