[Resend] Poor documentation of SER_RS485_RTS_ON_SEND and SER_RS485_RTS_AFTER_SEND

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi all,

I have some trouble finding out the meaning of SER_RS485_RTS_ON_SEND and
SER_RS485_RTS_AFTER_SEND. The documentation says:

linux/serial.h
==============
> * * %SER_RS485_RTS_ON_SEND	- Logical level for RTS pin when sending.
> * * %SER_RS485_RTS_AFTER_SEND	- Logical level for RTS pin after sent.

Practically all UART chips have a -RTS, /RTS pin or RTSn pin and no RTS pin.
And what is the meaning of "Logical level" here? Is it the same as Logic Level?

Should I conclude that setting the SER_RS485_RTS_ON_SEND flag should
result in the logic level on the /RTS pin being high (> 0V) during transmission?
And similarly that setting the SER_RS485_RTS_AFTER_SEND flag should
result in the logic level on the /RTS pin being high after transmission?

rs485.yaml
==========
>   rs485-rts-active-high:
>     description: drive RTS high when sending (this is the default).
>     $ref: /schemas/types.yaml#/definitions/flag
> 
>   rs485-rts-active-low:
>     description: drive RTS low when sending (default is high).
>     $ref: /schemas/types.yaml#/definitions/flag

Can I assume that RTS usually means the /RTS pin on the UART chip here.

Looking at the implemented drivers does not make things better.

Some drivers think that when the SER_RS485_RTS_ON_SEND flag is set they
should set the RTS bit in E.g. the MCR register when starting a transmission,
which results in the /RTS pin going low on E.g. a genuine 8250.

8250_port.c
===========
> /**
>  * serial8250_em485_start_tx() - generic ->rs485_start_tx() callback
>  * @up: uart 8250 port
>  *
>  * Generic callback usable by 8250 uart drivers to start rs485 
> transmission.
>  * Assumes that setting the RTS bit in the MCR register means RTS is 
> high.

Wow, that's an odd assumption for a generic 8250/16x50 driver!

>  * (Some chips use inverse semantics.)  [...]
>  */
> void serial8250_em485_start_tx(struct uart_8250_port *up)
> {
> 	unsigned char mcr = serial8250_in_MCR(up);
> 
> 	if (!(up->port.rs485.flags & SER_RS485_RX_DURING_TX))
> 		serial8250_stop_rx(&up->port);
> 
> 	if (up->port.rs485.flags & SER_RS485_RTS_ON_SEND)
> 		mcr |= UART_MCR_RTS;
> 	else
> 		mcr &= ~UART_MCR_RTS;
> 	serial8250_out_MCR(up, mcr);
> }

The next one behaves the same, but makes a different assumption:

8250_omap.c
===========
> static int omap8250_rs485_config(struct uart_port *port,
> 				 struct ktermios *termios,
> 				 struct serial_rs485 *rs485)
> {
> 	[...]
> 	/*
> 	 * Retain same polarity semantics as RS485 software emulation,
> 	 * i.e. SER_RS485_RTS_ON_SEND means driving RTS low on send.

Shouldn't SER_RS485_RTS_ON_SEND mean driving RTS high on send?

> 	 */
> 	if (rs485->flags & SER_RS485_RTS_ON_SEND)
> 		priv->mdr3 &= ~UART_OMAP_MDR3_DIR_POL;
> 	else
> 		priv->mdr3 |= UART_OMAP_MDR3_DIR_POL;
> 
> 	serial_out(up, UART_OMAP_MDR3, priv->mdr3);

Others believe that they should clear the RTS bit in MCR for
SER_RS485_RTS_ON_SEND when starting a transmission, resulting in the
/RTS pin going high.

8250_bcm2835aux.c
=================
> static void bcm2835aux_rs485_start_tx(struct uart_8250_port *up)
> {
> 	[...]
> 	/*
> 	 * On the bcm2835aux, the MCR register contains no other
> 	 * flags besides RTS.  So no need for a read-modify-write.
> 	 */
> 	if (up->port.rs485.flags & SER_RS485_RTS_ON_SEND)
> 		serial8250_out_MCR(up, 0);
> 	else
> 		serial8250_out_MCR(up, UART_MCR_RTS);
> }

Same here:

8250_pci.c
==========
> static int pci_fintek_rs485_config(struct uart_port *port, struct 
> ktermios *termios,
> 			       struct serial_rs485 *rs485)
> {
> 		[...]
> 		if (rs485->flags & SER_RS485_RTS_ON_SEND) {
> 			/* RTS driving high on TX */
> 			setting &= ~FINTEK_RTS_INVERT;
> 		} else {
> 			/* RTS driving low on TX */
> 			setting |= FINTEK_RTS_INVERT;
> 		}

Can the list shed some light on this and reach a consensus here?

Kind Regards,
Maarten





[Index of Archives]     [Kernel Newbies]     [Security]     [Netfilter]     [Bugtraq]     [Linux PPP]     [Linux FS]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Samba]     [Video 4 Linux]     [Linmodem]     [Device Mapper]     [Linux Kernel for ARM]

  Powered by Linux