RS-485

RS-485 mostly used in half duplex operation mode, and uses a differential balanced line over twisted pair. RS-485 drivers need to be put in transmit mode explicitly by asserting a signal to the driver. This allows RS-485 to implement linear topologies using only two wires, and it can span relatively large distances (up to 1,200m @ 100kbit/s).

You can't set the "rs485delaylastchartx" parameter, it's calculated automatically from the baudrate.

Special notes for the APF28/i.MX28 mxs-auart driver:

All delays are in microseconds.

The "rs485delaylastchartx" parameter is not used in DMA mode.

The parameters: "rs485rtsonsend" "rs485rtsaftersend" "rs485rxduringtx" are not used. (Only used by atmel_serial.c and crisv10.c drivers)

If the RS-485 mode is turned on, it will override (turn off) the RTS/CTS hardware flow settings of the UART, whatever is configured.

How to use it from C code

The RS-485 mode can also be turned on with ioctl calls from C code, here is the example:

#include <stdio.h>#include <fcntl.h>#include <linux/ioctl.h>#include <linux/serial.h>#include <asm-generic/ioctls.h> /* TIOCGRS485 + TIOCSRS485 ioctl definitions */intmain(void){structserial_rs485rs485conf;intfd=open("/dev/ttySP0",O_RDWR);if(fd<0){printf("Error: Can't open: /dev/ttySP0\n");}/* Don't forget to read first the current state of the RS-485 options with ioctl. If You don't do this, You will destroy the rs485conf.delay_rts_last_char_tx parameter which is automatically calculated by the driver when You opens the port device. */if(ioctl(fd,TIOCGRS485,&rs485conf)<0){printf("Error: TIOCGRS485 ioctl not supported.\n");}/* Enable RS-485 mode: */rs485conf.flags|=SER_RS485_ENABLED;/* Set rts/txen delay before send, if needed: (in microseconds) */rs485conf.delay_rts_before_send=0;/* Set rts/txen delay after send, if needed: (in microseconds) */rs485conf.delay_rts_after_send=0;if(ioctl(fd,TIOCSRS485,&rs485conf)<0){printf("Error: TIOCSRS485 ioctl not supported.\n");}fcntl(fd,F_SETFL,0);intn=write(fd,"ABC\r\n",5);if(n<0){/* Error handling */}if(close(fd)<0){printf("Error: Can't close: /dev/ttySP0\n");}}

Hardware Notes

The RS-485 Transmit Enable (TXEN) output will be the RTS pin of the UART.

The TXEN/RTS output is _active low_, it must be inverted to use it with the popular RS-485 transceiver ICs. On kernel with device tree, this can be done with rs485-rts-active-high option when declaring UART config.

When U-Boot runs and the board start to boot, the RTS pin works as an input, so please add a pull-up resistor to this pin, before the inverter, to prevent RS-485 bus lockups.

Links

De-asserting RTS fastest as possible is a well known problem on every platforms: