RS485 RTS control too slow

ffrige
Posts: 22
Joined: Thu Oct 15, 2020 3:44 am

RS485 RTS control too slow

Postby ffrige » Mon Aug 30, 2021 9:18 am

I am using the UART interface to read the position of an absolute encoder via RS485 half-duplex at 2.5Mbps. I send a request byte to the encoder and receive a few bytes in response. The encoder starts sending the response data about 3us after it receives the request byte. It all technically works, except for the fact that the switching of the RTS pin is much too slow and causes some or all of the response data to be lost.

I started by using the following configuration to let the driver reset the RTS pin automatically after the UART Tx is completed:

Code: Select all

uart_set_mode(uart_num, UART_MODE_RS485_HALF_DUPLEX);
But monitoring with a scope shows that the pin is only reset more than 30us after the last bit is transmitted. By that time most of the response from the encoder has already arrived and is totally lost because the transceiver is still in transmit mode. What causes such a massive delay between TX and RTS??

Then I tried to do manual switching. I call the uart_write_bytes function with zero TX buffer so that it blocks until TX is done, and then I set the GPIO manually. This is faster than the RS485 mode, around 7us, but still too slow to keep up with the encoder and the first response byte is lost. The time delay is not always stable, sometimes I lose more than one byte.

I also tried to call the uart_write_bytes with a non-zero buffer, so that it doesn't block, and then I start a HW timer to wait for a few us before manually resetting the RTS pin in the timer alarm interrupt. This solution is also not stable because the interrupt sometimes triggers too soon, sometimes too late.

I have no other idea at the moment. What is the common way to handle this requirement? Why isn't the internal RS485 driver able to switch the RTS pin right away?

WiFive
Posts: 3529
Joined: Tue Dec 01, 2015 7:35 am

Re: RS485 RTS control too slow

Postby WiFive » Mon Aug 30, 2021 4:19 pm

Unfortunately it is done in software and there is interrupt latency and a complex isr. You could try a custom isr but 3us might be tough.

ffrige
Posts: 22
Joined: Thu Oct 15, 2020 3:44 am

Re: RS485 RTS control too slow

Postby ffrige » Tue Aug 31, 2021 12:39 am

Ok, I see, thank you, I will try that.

In any case this is not an out of the blue requirement. This kind of encoder interface protocol is very standard in the automation industry and there are zillions of servo drives out there reading encoder data without any issue. A dedicated HW solution would be tricky and costly. I am sure there is a way to solve it in SW.

vjacobs
Posts: 10
Joined: Mon May 20, 2019 8:34 am

Re: RS485 RTS control too slow

Postby vjacobs » Tue Aug 31, 2021 8:12 am

Hi @ffrige,

You can achieve better timings when you surpass the esp-idf driver and code up the UART ISR and other logic yourself. It's a bit more work but it surely pays off.
In our project, we are using 2MBps UART on a half-duplex RS485 bus. When the interrupt fires for the TX_DONE interrupt, I directly switch of the RTS line (mind you, pin has inverse logic):

Code: Select all

uart->dev->conf0.sw_rts = 0; // Start transmission
// actual writing of bytes to UART FIFO

// In ISR, when transmission is done ->
uint32_t status = uart->dev->int_st.val
if (status & UART_TX_DONE_INT_ST)
{
    uart->dev->int_clr.tx_done = 1;
    uart->dev->conf0.sw_rts = 1;
}

In my case, the RTS line goes low between 1 and 2us after the last stopbit.

Best

ffrige
Posts: 22
Joined: Thu Oct 15, 2020 3:44 am

Re: RS485 RTS control too slow

Postby ffrige » Tue Aug 31, 2021 10:27 am

Thank you so much, that sounds really wonderful and reassuring!!

Now I need to figure out how to work with custom interrupts and then will post back the results.

ffrige
Posts: 22
Joined: Thu Oct 15, 2020 3:44 am

Re: RS485 RTS control too slow

Postby ffrige » Tue Aug 31, 2021 1:46 pm

Wait! I just found a much easier solution to the problem. I realized that adding the ESP_INTR_FLAG_IRAM flag to the uart_driver_install() function places the interrupt handler in RAM instead of FLASH. Apparently, the default behavior is to store the ISRs in flash, which makes their execution super slow. Adding that flag solves my problem entirely, as the blocking uart_write_bytes() function returns much faster now, and I can reset the RTS pin within 2us from the end of the last TX bit.

cmatkin
Posts: 2
Joined: Tue Jul 27, 2021 11:11 am

Re: RS485 RTS control too slow

Postby cmatkin » Mon Sep 27, 2021 7:05 am

Hi @ffrige,

Would you mind sharing your rs485 code?
We are just about to start a rs485 project and would like a hand on that side.

Kind regards
Craig

Who is online

Users browsing this forum: No registered users and 239 guests