diff options
Diffstat (limited to 'Documentation/serial/serial-rs485.txt')
-rw-r--r-- | Documentation/serial/serial-rs485.txt | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/Documentation/serial/serial-rs485.txt b/Documentation/serial/serial-rs485.txt new file mode 100644 index 000000000000..a3b1af7b6db9 --- /dev/null +++ b/Documentation/serial/serial-rs485.txt | |||
@@ -0,0 +1,119 @@ | |||
1 | RS485 SERIAL COMMUNICATIONS | ||
2 | |||
3 | 1. INTRODUCTION | ||
4 | |||
5 | EIA-485, also known as TIA/EIA-485 or RS-485, is a standard defining the | ||
6 | electrical characteristics of drivers and receivers for use in balanced | ||
7 | digital multipoint systems. | ||
8 | This standard is widely used for communications in industrial automation | ||
9 | because it can be used effectively over long distances and in electrically | ||
10 | noisy environments. | ||
11 | |||
12 | 2. HARDWARE-RELATED CONSIDERATIONS | ||
13 | |||
14 | Some CPUs (e.g., Atmel AT91) contain a built-in half-duplex mode capable of | ||
15 | automatically controlling line direction by toggling RTS. That can used to | ||
16 | control external half-duplex hardware like an RS485 transceiver or any | ||
17 | RS232-connected half-duplex device like some modems. | ||
18 | |||
19 | For these microcontrollers, the Linux driver should be made capable of | ||
20 | working in both modes, and proper ioctls (see later) should be made | ||
21 | available at user-level to allow switching from one mode to the other, and | ||
22 | vice versa. | ||
23 | |||
24 | 3. DATA STRUCTURES ALREADY AVAILABLE IN THE KERNEL | ||
25 | |||
26 | The Linux kernel provides the serial_rs485 structure (see [1]) to handle | ||
27 | RS485 communications. This data structure is used to set and configure RS485 | ||
28 | parameters in the platform data and in ioctls. | ||
29 | |||
30 | Any driver for devices capable of working both as RS232 and RS485 should | ||
31 | provide at least the following ioctls: | ||
32 | |||
33 | - TIOCSRS485 (typically associated with number 0x542F). This ioctl is used | ||
34 | to enable/disable RS485 mode from user-space | ||
35 | |||
36 | - TIOCGRS485 (typically associated with number 0x542E). This ioctl is used | ||
37 | to get RS485 mode from kernel-space (i.e., driver) to user-space. | ||
38 | |||
39 | In other words, the serial driver should contain a code similar to the next | ||
40 | one: | ||
41 | |||
42 | static struct uart_ops atmel_pops = { | ||
43 | /* ... */ | ||
44 | .ioctl = handle_ioctl, | ||
45 | }; | ||
46 | |||
47 | static int handle_ioctl(struct uart_port *port, | ||
48 | unsigned int cmd, | ||
49 | unsigned long arg) | ||
50 | { | ||
51 | struct serial_rs485 rs485conf; | ||
52 | |||
53 | switch (cmd) { | ||
54 | case TIOCSRS485: | ||
55 | if (copy_from_user(&rs485conf, | ||
56 | (struct serial_rs485 *) arg, | ||
57 | sizeof(rs485conf))) | ||
58 | return -EFAULT; | ||
59 | |||
60 | /* ... */ | ||
61 | break; | ||
62 | |||
63 | case TIOCGRS485: | ||
64 | if (copy_to_user((struct serial_rs485 *) arg, | ||
65 | ..., | ||
66 | sizeof(rs485conf))) | ||
67 | return -EFAULT; | ||
68 | /* ... */ | ||
69 | break; | ||
70 | |||
71 | /* ... */ | ||
72 | } | ||
73 | } | ||
74 | |||
75 | |||
76 | 4. USAGE FROM USER-LEVEL | ||
77 | |||
78 | From user-level, RS485 configuration can be get/set using the previous | ||
79 | ioctls. For instance, to set RS485 you can use the following code: | ||
80 | |||
81 | #include <linux/serial.h> | ||
82 | |||
83 | /* Driver-specific ioctls: */ | ||
84 | #define TIOCGRS485 0x542E | ||
85 | #define TIOCSRS485 0x542F | ||
86 | |||
87 | /* Open your specific device (e.g., /dev/mydevice): */ | ||
88 | int fd = open ("/dev/mydevice", O_RDWR); | ||
89 | if (fd < 0) { | ||
90 | /* Error handling. See errno. */ | ||
91 | } | ||
92 | |||
93 | struct serial_rs485 rs485conf; | ||
94 | |||
95 | /* Set RS485 mode: */ | ||
96 | rs485conf.flags |= SER_RS485_ENABLED; | ||
97 | |||
98 | /* Set rts delay before send, if needed: */ | ||
99 | rs485conf.flags |= SER_RS485_RTS_BEFORE_SEND; | ||
100 | rs485conf.delay_rts_before_send = ...; | ||
101 | |||
102 | /* Set rts delay after send, if needed: */ | ||
103 | rs485conf.flags |= SER_RS485_RTS_AFTER_SEND; | ||
104 | rs485conf.delay_rts_after_send = ...; | ||
105 | |||
106 | if (ioctl (fd, TIOCSRS485, &rs485conf) < 0) { | ||
107 | /* Error handling. See errno. */ | ||
108 | } | ||
109 | |||
110 | /* Use read() and write() syscalls here... */ | ||
111 | |||
112 | /* Close the device when finished: */ | ||
113 | if (close (fd) < 0) { | ||
114 | /* Error handling. See errno. */ | ||
115 | } | ||
116 | |||
117 | 5. REFERENCES | ||
118 | |||
119 | [1] include/linux/serial.h | ||