-
Notifications
You must be signed in to change notification settings - Fork 1
/
serial_conf.c
218 lines (198 loc) · 4.86 KB
/
serial_conf.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
#include <stdbool.h>
#include <string.h>
#include <sys/ioctl.h>
#include <termios.h>
#include "serial_conf.h"
int setPortOptions(int fd, int baudrate, int databits, int parity, int stop,
bool softwareHandshake, bool hardwareHandshake) {
struct termios newtio;
memset(&newtio, 0, sizeof(newtio));
if (tcgetattr(fd, &newtio) != 0) {
return ERR_TC_GET_ATTR;
}
speed_t _baud= -1;
switch (baudrate) {
#ifdef B0
case 0: _baud= B0; break;
#endif
#ifdef B50
case 50: _baud= B50; break;
#endif
#ifdef B75
case 75: _baud= B75; break;
#endif
#ifdef B110
case 110: _baud= B110; break;
#endif
#ifdef B134
case 134: _baud= B134; break;
#endif
#ifdef B150
case 150: _baud= B150; break;
#endif
#ifdef B200
case 200: _baud= B200; break;
#endif
#ifdef B300
case 300: _baud= B300; break;
#endif
#ifdef B600
case 600: _baud= B600; break;
#endif
#ifdef B1200
case 1200: _baud= B1200; break;
#endif
#ifdef B1800
case 1800: _baud= B1800; break;
#endif
#ifdef B2400
case 2400: _baud= B2400; break;
#endif
#ifdef B4800
case 4800: _baud= B4800; break;
#endif
#ifdef B7200
case 7200: _baud= B7200; break;
#endif
#ifdef B9600
case 9600: _baud= B9600; break;
#endif
#ifdef B14400
case 14400: _baud= B14400; break;
#endif
#ifdef B19200
case 19200: _baud= B19200; break;
#endif
#ifdef B28800
case 28800: _baud= B28800; break;
#endif
#ifdef B38400
case 38400: _baud= B38400; break;
#endif
#ifdef B57600
case 57600: _baud= B57600; break;
#endif
#ifdef B76800
case 76800: _baud= B76800; break;
#endif
#ifdef B115200
case 115200: _baud= B115200; break;
#endif
#ifdef B128000
case 128000: _baud= B128000; break;
#endif
#ifdef B230400
case 230400: _baud= B230400; break;
#endif
#ifdef B460800
case 460800: _baud= B460800; break;
#endif
#ifdef B576000
case 576000: _baud= B576000; break;
#endif
#ifdef B921600
case 921600: _baud= B921600; break;
#endif
#ifdef B1000000
case 1000000: _baud= B1000000; break;
#endif
#ifdef B1152000
case 1152000: _baud= B1152000; break;
#endif
#ifdef B1500000
case 1500000: _baud= B1500000; break;
#endif
#ifdef B2000000
case 2000000: _baud= B2000000; break;
#endif
#ifdef B2500000
case 2500000: _baud= B2500000; break;
#endif
#ifdef B3000000
case 3000000: _baud= B3000000; break;
#endif
#ifdef B3500000
case 3500000: _baud= B3500000; break;
#endif
#ifdef B4000000
case 4000000: _baud= B4000000; break;
#endif
default:
return ERR_BAUD;
}
if (_baud != -1) {
cfsetospeed(&newtio, _baud);
cfsetispeed(&newtio, _baud);
}
switch (databits) {
case 5:
newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS5;
break;
case 6:
newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS6;
break;
case 7:
newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS7;
break;
case 8:
newtio.c_cflag = (newtio.c_cflag & ~CSIZE) | CS8;
break;
default:
return ERR_BITS;
}
// ignore modem control lines and enable the receiver
newtio.c_cflag |= CLOCAL | CREAD;
// parity (0 == no parity, 1 == odd, 2 == even)
newtio.c_cflag &= ~(PARENB | PARODD);
if (parity == 2) {
newtio.c_cflag |= PARENB;
} else if (parity == 1) {
newtio.c_cflag |= (PARENB | PARODD);
} else if (parity != 0) {
return ERR_PARITY;
}
// Set 1 stopbit
newtio.c_cflag &= ~CSTOPB;
if (stop == 2) {
newtio.c_cflag |= CSTOPB;
} else if(stop != 1) {
return ERR_STOP_BITS;
}
// Ignore "BREAK" condition on input
newtio.c_iflag= IGNBRK;
// Enable or disabled the software handshake
if (softwareHandshake) {
newtio.c_iflag |= IXON | IXOFF;
} else {
newtio.c_iflag &= ~(IXON | IXOFF | IXANY);
}
// clear out the local and output modes
newtio.c_lflag= 0;
newtio.c_oflag= 0;
// Set timeout to 0
newtio.c_cc[VTIME]= 0;
// 1 char minimum for a non-canonical read
newtio.c_cc[VMIN]= 1;
if (tcsetattr(fd, TCSANOW, &newtio) != 0) {
return ERR_TC_SET_ATTR;
}
int mcs= 0;
ioctl(fd, TIOCMGET, &mcs);
mcs |= TIOCM_RTS;
ioctl(fd, TIOCMSET, &mcs);
if (tcgetattr(fd, &newtio) != 0) {
return ERR_TC_GET_ATTR;
}
#ifdef CRTSCTS
// hardware handshake
if (hardwareHandshake) {
newtio.c_cflag |= CRTSCTS;
} else {
newtio.c_cflag &= ~CRTSCTS;
}
#endif
if (tcsetattr(fd, TCSANOW, &newtio) != 0) {
return ERR_TC_SET_ATTR;
}
return 0;
}