Changes between Version 29 and Version 30 of serial


Ignore:
Timestamp:
07/08/2022 11:08:01 PM (21 months ago)
Author:
Tim Harvey
Comment:

add missing venice details; update newport details; refactor examples

Legend:

Unmodified
Added
Removed
Modified
  • serial

    v29 v30  
    115115|| ||
    116116 1. Depends on software configuration
    117  2. CN80XX UART2 and UART3 and be steered via software PINSEL to any of the GPIO signals including the off-board DIO's - contact support@gateworks.com for details
     117 2. UART2/UART3 are configured in early boot firmware via the hwconfig variable (see [wiki:newport/bootloader#serialconfig here). Additionally CN80XX UART2 and UART3 can be steered via software PINSEL via software modification to any of the GPIO signals including the off-board DIO's - contact support@gateworks.com for details
    118118
    119119
     
    235235Some Gateworks boards have RS485 transceivers connected to host CPU UART's. This often is an optional feature that must be loaded at the factory. Please contact support@gateworks.com via email for more information.
    236236
    237 RS485 uses a differential pair and is typically half-duplex such that the TX and RX share a differential pair on a multi-master bus and the TX and an enable that is controlled via one of:
     237RS485 uses a differential pair and is half-duplex such that the TX and RX share a differential pair on a multi-master bus and the TX and an enable that is controlled via one of:
    238238 1. always enabled (only useful if there is only a single transmitter on the bus)
    239239 2. connected to UART RTS line
    240240 3. connected to host CPU GPIO
    241241
     242Note that RS485 is half-duplex and RS422 is full-duplex.
     243
    242244Because of the half-duplex nature, typically custom software needs to be written to:
    243  * control the enabling of the transmit driver (sometimes this is done for you in the driver)
     245 * control the enabling of the transmit driver (on more modern boards and kernels this is done for you by the driver via device-tree and/or the TIOCSRS485 ioctl)
    244246 * receive the data you sent directly after sending (unless the driver does this for you)
    245247 * implement a protocol such that multiple masters know when it is there turn to transmit
     
    252254The following table and sections below provides per-board details of RS485:
    253255||= Family  =||= Board                 =||= TXEN  =||= Transceiver =||= Termination =||= Fail-Safe Bias =||= Notes =||
    254 || Newport   || GW630x / GW640x                 || gpio476  || [https://www.exar.com/ds/sp335e.pdf SP335E] || optional (gpio16) || included || ||
     256|| Venice    || GW720x / GW730x / GW740x    || RTS  || [https://www.exar.com/ds/sp335e.pdf SP335E] || software selectable via 'rs485_term' gpio || included || TIOCSRS485 support ||
     257|| Newport   || GW630x / GW640x                 || RTS  || [https://www.exar.com/ds/sp335e.pdf SP335E] || software selectable via [wiki:newport/bootloader#serialconfig hwconfig] || included || TIOCSRS485 support ||
    255258|| Ventana   || GW52xx '''(optional)''' || gpio193 || [http://dev.gateworks.com/datasheets/MAX14840E-MAX14841E.pdf MAX14840] || optional     || optional || TIOCSRS485 support ||
    256259||           || GW53xx '''(optional)''' || gpio193 || [http://dev.gateworks.com/datasheets/MAX14840E-MAX14841E.pdf MAX14840] || optional     || optional || TIOCSRS485 support ||
    257260||           || GW54xx '''(optional)''' || gpio193 || [http://dev.gateworks.com/datasheets/MAX14840E-MAX14841E.pdf MAX14840] || optional     || optional || TIOCSRS485 support ||
    258261||           || GW551x+GW16111          || gpio19  || [http://dev.gateworks.com/datasheets/MAX14840E-MAX14841E.pdf MAX14840] || optional     || 4.75k pull up/down || see [#ventana-rs485 ventana RS485 below] ||
    259 || Laguna    || GW238x+GW16067          || gpio3   || [http://dev.gateworks.com/datasheets/MAX3483-MAX3491.pdf MAX3485] || optional      || 4.75k pull up/down || use tcdrain() and userspace /sys/class/gpio/gpio3 ||
     262||           || GW5904 / GW5909         || RTS  || [http://dev.gateworks.com/datasheets/MAX14840E-MAX14841E.pdf MAX14840] || software selectable via 'rs485_term' gpio || included || TIOCSRS485 support ||
     263|| Laguna    || GW238x+GW16067          || gpio3   || [http://dev.gateworks.com/datasheets/MAX3483-MAX3491.pdf MAX3485] || optional      || 4.75k pull up/down || use tcdrain() and userspace /sys/class/gpio/gpio3 - see [#rs485-example here] ||
    260264|| ||
    261265
    262 Note that if a driver supports TIOCSRS485 (in other words it handles the assertion/de-assertion of TXEN in the driver) this is preferred over using tcdrain() to determine when the FIFO is empty as tcdrain() can have considerable latency at small transmit sizes.
    263266
    264267References:
     
    272275
    273276Some boards with RS485 capability may have transceivers with specific fail-safe features within the transceiver however optional on-board termination resistors typically exist as well and it is the responsibility of the system designer to determine where termination needs to go and what values should be used. In general, gateworks boards with RS485 transceivers have an optional resistor for termination that can be loaded with a customer specified value. Contact sales@gateworks.com via e-mail for more information.
     277
     278Additionally some boards have software selectable termination via a gpio (see the table above)
    274279
    275280References:
     
    299304[=#venice-rs485]
    300305=== Venice
    301 See #venice below
     306
     307Software must enable RS485 at boot via device-tree or use the TIOCSRS485 ioctl to configure TXEN - see [#TIOCSRS485 below]).
     308
     309See [#venice below]
    302310
    303311[=#newport-rs485]
     
    310318
    311319RS485 modes feature:
    312  * optional half-duplex, multi-drop RS585:
     320 * optional half-duplex, multi-drop RS485:
    313321 * CN80XX UART2 (/dev/ttyAMA2)
    314322 * optional on-board termination (enabled by gpio16)
    315323 * in-chip fail-safe protection to default idle inputs to logic-high (no external bias resistors required)
    316  * TXEN connected to CN80XX gpio12 which it typically Linux gpio476
    317 
    318 The pl011 Linux driver supporting the CN80XX serial ports (SERIAL_AMBA_PL011 drivers/tty/serial/amba-pl011.c) does not look like it supports RS485 directly. While this support could be added to the serial driver in the future you can alternatively manage the TXEN (gpio476) directly in a user application (asserting TXEN prior to calling write() then using tcdrain() to wait for the UART FIFO to be empty before deasserting TXEN). For RS485 half-duplex using (see example below).
     324 * TXEN connected to CN80XX UART2 RTS
     325
     326The pl011 Linux driver supporting the CN80XX serial ports (SERIAL_AMBA_PL011 drivers/tty/serial/amba-pl011.c) supports RS485 via the TIOCSRS485 ioctl as of Linux 5.15 and this support has been backported to the Gateworks 5.10 kernel.
     327
     328Software must enable RS485 at boot via device-tree or use the TIOCSRS485 ioctl to configure TXEN - see [#TIOCSRS485 below]).
    319329
    320330
     
    330340By 'optional' this means the baseboard design supports this, but it is not loaded on standard product therefore would be a Gateworks Special. Contact sales@gateworks.com if interested to see if a configuration already exists.
    331341
    332 Your software must use the TIOCSRS485 ioctl to configure TXEN (see [#rs485-example] example code).
     342Software must enable RS485 at boot via device-tree or use the TIOCSRS485 ioctl to configure TXEN - see [#TIOCSRS485 below]).
    333343
    334344The GW551x + GW16111 breakout module support half-duplex, multi-drop RS485:
     
    360370
    361371
    362 [=#rs485-example]
    363 === Example Application
    364 Here is an example application that uses the TIOCSRS485 ioctl to configure RS485 for drivers that directly control the transmit enable:
     372[=#TIOCSRS485]
     373=== TIOCSRS485 ioctl
     374For UART's that have a built-in half-duplex mode capable of automatically controlling line direction via a transmit enable by toggling the UART's RTS signal the TIOCSRS485 ioctl can be used to configure RS485 TXEN.
     375
     376Some UART drivers such as the IMX SoC's also allow generic GPIO's to be used for this by configuring the UART via the device-tree rts-gpios property.
     377
     378Code Examples:
     379 * ANSI-C:
     380{{{#!c
     381        #include <linux/serial.h>
     382
     383        /* Include definition for RS485 ioctls: TIOCGRS485 and TIOCSRS485 */
     384        #include <sys/ioctl.h>
     385
     386        /* Open your specific device (e.g., /dev/mydevice): */
     387        int fd = open ("/dev/mydevice", O_RDWR);
     388        if (fd < 0) {
     389                /* Error handling. See errno. */
     390        }
     391
     392        struct serial_rs485 rs485conf;
     393
     394        /* Enable RS485 mode: */
     395        rs485conf.flags |= SER_RS485_ENABLED;
     396
     397        /* Set logical level for RTS pin equal to 1 when sending: */
     398        rs485conf.flags |= SER_RS485_RTS_ON_SEND;
     399        /* or, set logical level for RTS pin equal to 0 when sending: */
     400        rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND);
     401
     402        /* Set logical level for RTS pin equal to 1 after sending: */
     403        rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
     404        /* or, set logical level for RTS pin equal to 0 after sending: */
     405        rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);
     406
     407        /* Set rts delay before send, if needed: */
     408        rs485conf.delay_rts_before_send = ...;
     409
     410        /* Set rts delay after send, if needed: */
     411        rs485conf.delay_rts_after_send = ...;
     412
     413        /* Set this flag if you want to receive data even while sending data */
     414        rs485conf.flags |= SER_RS485_RX_DURING_TX;
     415
     416        if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) {
     417                /* Error handling. See errno. */
     418        }
     419
     420        /* Use read() and write() syscalls here... */
     421
     422        /* Close the device when finished: */
     423        if (close (fd) < 0) {
     424                /* Error handling. See errno. */
     425        }
     426}}}
     427
     428Some Linux UART drivers that call the 'uart_get_rs485_mode' function allow you to configure this behavior on boot via device-tree properties that can be added to the UART device-tree node:
     429 - linux,rs485-enabled-at-boot-time - enables the rs485 feature at boot time. It can be disabled later with proper ioctl
     430 - rs485-rts-delay - Delay between RTS signal and beginning of data sent in milliseconds corresponding to the delay before sending data
     431 - rs485-rx-during-tx - enables the receiving of data even while sending data
     432 - rs485-rts-active-low - drive RTS low when sending (default is high)
     433 - rs485-term-gpios - GPIO pin to enable RS485 bus termination (if defined will drive this low when the UART is configured). As there is no API to alter this behavior often its best to leave this up to userspace GPIO control (unless driving low to disable it on boot is what you want)
     434
     435An example of using device-tree to enable RS485 TXEN configuration at boot can be seen [https://elixir.bootlin.com/linux/latest/source/arch/arm64/boot/dts/freescale/imx8mm-venice-gw73xx-0x-rs485.dts#L41 here]
     436
     437See also:
     438 - https://docs.kernel.org/driver-api/serial/serial-rs485.html
     439 - https://www.kernel.org/doc/Documentation/serial/serial-rs485.txt
     440 - https://www.kernel.org/doc/Documentation/devicetree/bindings/serial/rs485.yaml
     441
     442
     443== Code Examples
     444
     445=== General Linux UART use
     446Here is an example application that demonstrates how to configure the UART (including TIOCSRS485 ioctl to for RS485 transmit enable) as well as sending and receiving data:
    365447{{{#!c
    366448#include <ctype.h>
     
    536618}}}
    537619
    538 Ventana boards with on-board RS485 use ARM gpio193 as the TXEN and our Ventana BSP's support the TIOCSRS485 ioctl such that you do not need to manage the transmitter enable other than enable it and set its polarity when you configure the serial port:
    539 {{{#!c
    540 struct serial_rs485 rs485;
    541 
    542 memset(&rs485, 0, sizeof(rs485));
    543 rs485.flags = SER_RS485_ENABLED | SER_RS485_RTS_ON_SEND;
    544 if (ioctl(fd, TIOCSRS485, &rs485))
    545   perror("TIOCSRS485");
    546 }}}
    547 
     620
     621[=#rs485-example]
     622=== RS485 without TIOCSRS485 driver support
    548623If a board connects RTS, DTR, or a gpio to TX-Enable but does not support the TIOCSRS485 you can alter your code to enable/disable the TX-Enable as needed.
    549624
    550 For example the following function:
     625Note that if a driver supports TIOCSRS485 (in other words it handles the assertion/de-assertion of TXEN in the driver) this is preferred over using tcdrain() to determine when the FIFO is empty as tcdrain() can have considerable latency at small transmit sizes.
     626
     627Example:
    551628{{{#!c
    552629/** write_file - write to a file