How to setup and use RS-485 interfaces on SP7021 BPi-F2P board of Banana Pi

The goal of the document is to illustrate how to setup and use RS-485 interfaces of BPi-F2P board of Banana Pi. BPi-F2P board of Banana Pi is based on Sunplus SP7021 SoC and is designed for industrial control. Refer to picture below, SP7021 is covered under black heat-sink.

BPi-F2P board has two channels of RS-485 interfaces which are connected to a WJ2EDGR-5.08-5P connector (the green rectangle 5-pin connector).

1. Schematics

Refer to schematic of RS-485 of BPi-F2P board below, signal SOC-UART-RX-1 is connected to GPIO_P1_2 (G_MX[10]) of SP7021. Signal SOC-UART-TX-1 is connected to GPIO_P1_3 (G_MX[11]) of SP7021. Signal SOC-485-D/R-1 is connected to GPIO_P0_7 (G_MX[7]) of SP7021. Signal SOC-UART-RX-2 is connected to GPIO_P5_0 (G_MX[40]) of SP7021. Signal SOC-UART-TX-2 is connected to GPIO_P5_1 (G_MX[41]) of SP7021. Signal SOC-485-D/R-2 is connected to GPIO_P0_6 (G_MX[6]) of SP7021. U20 and U21 are dual-channel digital isolator from Novosense Microelectronics. One channel for input and the other for output. They are added for electric isolation between internal digital circuits and output drivers. U19 and U22 are half-duplex RS-485 transceiver from Texas Instruments. It converts 0V/5V-level signals to RS-485 differential signals (A/B). RS-485 differential signals (A/B) are then connected to a WJ2EDGR-5.08-5P connector. U16 and U18 are photo-coupler from Toshiba. Each offers an isolated channel. They are added for isolating SOC-485-D/R-1 and SOC-485-D/R-2 signals, respectively. U17 is an isolated DC-DC converter from MORNSUN Guangzhou Science & Technology. It is used to supply +5V power (VDD5V-ISO) of output drivers.

2. Modify device-tree source

From schematics, we list connections of all RS-485 signals in the following table:

Channel #

Signals of RS-485

Mux-Pins of SP7021

Channel #

Signals of RS-485

Mux-Pins of SP7021

1

SOC-UART-TX-1

11 (GPIO_P1_3/G_MX[11])

SOC-UART-RX-1

10 (GPIO_P1_2/G_MX[10])

SOC-485-D/R-1

7 (GPIO_P0_7/G_MX[7])

2

SOC-UART-TX-2

41 (GPIO_P5_1/G_MX[41])

SOC-UART-RX-2

40 (GPIO_P5_0/G_MX[40])

SOC-485-D/R-2

6 (GPIO_P0_6/G_MX[6])

Modify device-tree node uart1 and uart2 in device-tree source file linux/kernel/arch/arm/boot/dts/sp7021-bpi-f2p.dts to setup channel 1 and 2 of UART for RS-485 interfaces 1 and 2, respectively, as shown below:

&uart1 { pinctrl-names = "default"; pinctrl-0 = <&pins_uart1>; linux,rs485-enabled-at-boot-time; rs485-rts-delay = <0 0>; rts-gpios = <&pctl 7 GPIO_ACTIVE_LOW>; status = "okay"; }; &uart2 { pinctrl-names = "default"; pinctrl-0 = <&pins_uart2>; linux,rs485-enabled-at-boot-time; rs485-rts-delay = <0 0>; rts-gpios = <&pctl 6 GPIO_ACTIVE_LOW>; status = "okay"; };

Note that uart1 and uart2 are labels to node serial@9c000980 and serial@9c000800, respectively.

When property linux,rs485-enabled-at-boot-time is defined in UART node, RTS signal is used to control direction of transferring of RS-485. Property rs485-rts-delay defines delay ‘before sending data’ and delay ‘after sending data’. The first figure is for delay 'before sending data’. The second figure is for delay 'after sending data’. The unit is millisecond. If property rs485-rts-delay is not present, both delay time are 0. Property rs485-rts-active-low inverts polarity of RTS signal. When it is defined, RTS signal is low-active. For example,

&uart1 { : rs485-rts-active-low; : }

BPI-F2P board uses GPIO (non pin-mux pins) to control direction of transferring of RS-485. It can not use RTS signal. Extra property rts-gpios is defined here to control direction of transferring of RS-485 using a GPIO. The control timing is the same as RTS signal (also controlled by delays set by rs485-rts-delay).

Modify dts node pinmux_uart1-pins and pinmux_uart2-pins to setup pins for channel 1 and 2 of UART, respectively, as shown below:

pins_uart1: pinmux_uart1-pins { sunplus,pins = < SPPCTL_IOPAD(11, SPPCTL_PCTL_G_PMUX, MUXF_UA2_TX, 0) SPPCTL_IOPAD(10, SPPCTL_PCTL_G_PMUX, MUXF_UA2_RX, 0) SPPCTL_IOPAD(7, SPPCTL_PCTL_G_GPIO, 0, SPPCTL_PCTL_L_OUT) >; }; pins_uart2: pinmux_uart2-pins { sunplus,pins = < SPPCTL_IOPAD(41, SPPCTL_PCTL_G_PMUX, MUXF_UA2_TX, 0) SPPCTL_IOPAD(40, SPPCTL_PCTL_G_PMUX, MUXF_UA2_RX, 0) SPPCTL_IOPAD(6, SPPCTL_PCTL_G_GPIO, 0, SPPCTL_PCTL_L_OUT) >; };

If you use RTS signal to control direction of transferring of RS-485, you need also define RTS pins. For example,

GPIO_P4_6 (G_MX[38]) of SP7021 is used to control direction of transferring.

Please note that to comply with Linux rules, after version 5.10.59, 4 property-names of pin node of SP7021 are changed as shown in table below:

5.4.35

5.10.59

5.4.35

5.10.59

sppctl,function

function

sppctl,groups

groups

sppctl,pins

sunplus,pins

sppctl,zero_func

sunplus,zerofunc

3. Enable Linux UART drivers

By default, UART module is enabled. Refer to screenshot of “Linux kernel Configuration Menu”:

“Sunplus UART serial port support” is enabled.

4. Build Linux image

Go to top folder. Run make config to select to build image for “BPi-F2P Board”. After make config completes, run make all to build Linux image.

5. Boot Linux

Boot Linux with the built image.

6. Serial port setup, write and read

Use stty command to setup serial port. For example,

It sets channel 1 of serial port (UART) to 115,200 Baud (bps), 8-bit data, 2-bit stop-bit, no parity.

Use echo command to transmit a character string to serial port. For example,

Character ‘A', CR and LF will be transmitted. ASCII code of character 'A’ is 0x41. ASCII code of CR is 0x0D. ASCII code of LF is 0x0A. Refer to snapshot of oscilloscope which was captured when the command is run:

where C1 (yellow) is signal SOC-UART-TX-1, C2 (red) is signal SOC-485-D/R-1, C3 (blue) is signal RS485-A-1, and C4 (green) is signal RS485-B-1. Z1, Z2, Z3 and Z4 are zoom-in of C1, C2, C3 and C4, respectively.

Note that less significant bit (LSB) is sent first.

You can use command-line option -n to suppress CR and LF.

Character ‘A', ‘B' and 'C’ will be transmitted. There is no CR and LF. Refer to snapshot of oscilloscope which was captured when the command is run:

where C1 (yellow) is signal SOC-UART-TX-1, C2 (red) is signal SOC-485-D/R-1, C3 (blue) is signal RS485-A-1, and C4 (green) is signal RS485-B-1. Z1, Z2, Z3 and Z4 are zoom-in of C1, C2, C3 and C4, respectively.

ASCII code 0x41, 0x42 and 0x43 are transmitted successively. LSB is sent first.

Use cat command to receive characters from serial port. For example,

A character string ‘HELLO!’ is received. It is sent by (another BPi-F2P board):

Refer to snapshot of oscilloscope which was captured when the command is run:

where C1 (yellow) is signal RS485-A-1, C2 (red) is signal RS485-B-1, C3 (blue) is signal SOC-UART-RX-1, and C4 (green) is signal SOC-485-D/R-1. Z1, Z2, Z3 and Z4 are zoom-in of C1, C2, C3 and C4, respectively.

ASCII code 0x48, 0x45, 0x4C, 0x4C, 0x4F, 0x21, 0x0D and 0x0A are received successively.

Refer to snapshot of oscilloscope which was captured while 'A', CR and LF are received:

where C1 (yellow) is signal RS485-A-1, C2 (red) is signal RS485-B-1, C3 (blue) is signal SOC-UART-RX-1, and C4 (green) is signal SOC-485-D/R-1. Z1, Z2, Z3 and Z4 are zoom-in of C1, C2, C3 and C4, respectively.

ASCII code 0x41, 0x0D and 0x0A are received successively.