I’ve done some progresses here.
Controlling the RTS line with ioctl DOES work. The problem was that I was expecting to switch RTS high when setting TIOCM_RTS, and it’s just the opposite. On the other hand, I can manually control RTS using “memwatch”.
memwatch -x -a 0x90011110 -d 0x00
Sets the UART Modem Control Register RTS bit to 0
memwatch -x -a 0x90011110 -d 0x02
Sets the UART Modem Control Register RTS bit to 1
Now I can freely change the RTS line through the serial driver (ns921x-serial.c), from my application.
However, this doesn’t solve the main problem, as RTS needs to be directly controlled by the serial driver (due to the timing issues). Then I realized that the UART Modem Control Register has a bit (bit 5, Automatic Flow Control) used as follows:
0 RTS controlled by bit 1 (RTS)
1 RTS controlled by 4-byte RX FIFO status
This bit is defined in nx921x-serial.c as UART_MCR_AFE but is nowhere managed by the serial driver. Thus, I did a small modification in the ns921x_uart_set_mctrl function:
static void ns921x_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
//u32 mcr = 0;
u32 mcr = UART_MCR_AFE; // <– MODIFIED
/* RTS signal should be controlled as gpio to allow using AFE */
if (mctrl & TIOCM_RTS)
mcr |= UART_MCR_RTS;
if (mctrl & TIOCM_DTR)
mcr |= UART_MCR_DTR;
if (mctrl & TIOCM_LOOP)
mcr |= UART_MCR_LOOP;
uartwrite32(port, mcr, UART_MCR);
}
The result is not good… This disables the serial communications in the same way than setting CRTSCTS from user space…
For most UART applications, RTS is not used under these critical conditions. Nevertheless, RS485 needs RTS to be high only during transmissions. Longer delays always prevent the RS485 slaves from responding as the data liens are not high impedance. Thus, RS485 needs the serial driver to do “Automatic Flow Control” (MCR bit 5 = 1) and “RS485 Transceiver control” (WCR bit 19 = 1).
Thanks for your time,
Daniel.