RS485 RTS control too slow
Posted: 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:
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?
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);
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?