1 /*
2 * Copyright (c) 2022 Unionman Technology Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include <termios.h>
17 #include <stdio.h>
18 #include <stdlib.h>
19 #include "serial_uart.h"
20
21 // 转换波特率
conver_baudrate(int baudrate)22 speed_t conver_baudrate(int baudrate)
23 {
24 switch (baudrate) {
25 case 9600L:
26 return B9600;
27 case 19200L:
28 return B19200;
29 case 38400L:
30 return B38400;
31 case 115200L:
32 return B115200;
33 case 1152000L:
34 return B1152000;
35 default:
36 return 1152000L;
37 }
38 }
39
set_baud(int fd,int baud)40 void set_baud(int fd, int baud)
41 {
42 int ret = ERR;
43 struct termios opt;
44
45 tcgetattr(fd, &opt); // tcgetattr用来获取终端参数,将从终端获得的信息fd,保存到opt结构体中
46 tcflush(fd, TCIOFLUSH); // 刷清缓冲区
47 cfsetispeed(&opt, baud);
48 cfsetospeed(&opt, baud);
49
50 ret = tcsetattr(fd, TCSANOW, &opt); // 设置终端参数到opt中,使之立即生效
51 if (ret == ERR) {
52 perror("tcsetattr fd");
53 exit(0);
54 }
55
56 tcflush(fd, TCIOFLUSH); // 刷清缓冲区
57 }
58
59 // 设置数据位
setup_data_bits(int setup_databits,struct termios * options_databits)60 int setup_data_bits(int setup_databits, struct termios *options_databits)
61 {
62 if (options_databits == NULL) {
63 perror("setup_data_bits error");
64 return ERR;
65 }
66
67 switch (setup_databits) {
68 case 5L:
69 options_databits->c_cflag |= CS5;
70 break;
71 case 6L:
72 options_databits->c_cflag |= CS6;
73 break;
74 case 7L:
75 options_databits->c_cflag |= CS7;
76 break;
77 case 8L:
78 options_databits->c_cflag |= CS8;
79 break;
80 default:
81 return ERR;
82 }
83 return OK;
84 }
85
86 // 设置校验位
set_params_parity(int setup_parity,struct termios * options_parity)87 int set_params_parity(int setup_parity, struct termios *options_parity)
88 {
89 switch (setup_parity) {
90 case 'n':
91 case 'N': // 无奇偶校验位
92 options_parity->c_cflag &= ~PARENB; // Clear parity enable/
93 options_parity->c_iflag &= ~INPCK; // disable input parity checking/
94 break;
95
96 case 'o':
97 case 'O': // 设置为奇校验
98 options_parity->c_cflag |= (PARODD | PARENB); // odd parity checking
99 options_parity->c_iflag |= INPCK; // enable parity checking
100 break;
101
102 case 'e':
103 case 'E': // 设置为偶校验
104 options_parity->c_cflag |= PARENB; // Enable parity /
105 options_parity->c_cflag &= ~PARODD; // even parity/
106 options_parity->c_iflag |= INPCK; // enable parity checking /
107 break;
108
109 case 'M':
110 case 'm': // 标记奇偶校验
111 options_parity->c_cflag |= PARENB | CMSPAR | PARODD;
112 options_parity->c_iflag |= INPCK; // enable parity checking /
113 break;
114
115 case 'S':
116 case 's': // 设置为空格
117 options_parity->c_cflag |= PARENB | CMSPAR;
118 options_parity->c_cflag &= ~PARODD;
119 options_parity->c_iflag |= INPCK; // enable parity checking /
120 break;
121
122 default:
123 return ERR;
124 }
125 return OK;
126 }
127
128 // 设置校验位
set_params(int fd,int databits,int stopbits,int parity)129 int set_params(int fd, int databits, int stopbits, int parity)
130 {
131 struct termios options;
132 int ret = ERR;
133
134 if (tcgetattr(fd, &options) != 0) {
135 perror("tcgetattr fail\n");
136 return ERR;
137 }
138
139 options.c_iflag = 0;
140 options.c_oflag = 0;
141
142 // setup data bits
143 options.c_cflag &= ~CSIZE;
144 ret = setup_data_bits(databits, &options);
145 if (ret == ERR) {
146 return ERR;
147 }
148
149 // parity
150 ret = set_params_parity(parity, &options);
151 if (ret == ERR) {
152 return ERR;
153 }
154
155 // stop bits/
156 switch (stopbits) {
157 case 1:
158 options.c_cflag &= ~CSTOPB;
159 break;
160 case 2L:
161 options.c_cflag |= CSTOPB;
162 break;
163 default:
164 return ERR;
165 }
166
167 // 请求发送和清除发送
168 options.c_cflag &= ~CRTSCTS;
169 options.c_lflag = 0;
170 options.c_cc[VTIME] = 10L;
171 options.c_cc[VMIN] = 1;
172
173 tcflush(fd, TCIFLUSH);
174 if (tcsetattr(fd, TCSANOW, &options) != 0) {
175 return ERR;
176 }
177
178 return OK;
179 }
180
181 // 设置波特率
uart_init(int fd,int uartBaud)182 int uart_init(int fd, int uartBaud)
183 {
184 set_baud(fd, conver_baudrate(uartBaud));
185 // uart param /
186 if (set_params(fd, 8L, 1, 'n')) {
187 perror("set uart parameters fail\n");
188 return ERR;
189 }
190 return OK;
191 }
192
193 // 传感器数据处理
data_proce(int * recv)194 int data_proce(int *recv)
195 {
196 if (recv == NULL) {
197 perror("receive data error");
198 return ERR;
199 }
200
201 if ((recv[0] == RECV_HEAD) && (recv[3L] == RECV_END) && (recv[1] == (0xff - recv[2L]))) {
202 switch (recv[1]) {
203 case EVT_BACK:
204 printf("get event back\n");
205 break;
206 case EVT_FORWARD:
207 printf("get event forward\n");
208 break;
209 case EVT_RIGHT:
210 printf("get event right\n");
211 break;
212 case EVT_LEFT:
213 printf("get event left\n");
214 break;
215 case EVT_PULLUP:
216 printf("get event pull up\n");
217 break;
218 case EVT_PULLDOWN:
219 printf("get event pull down\n");
220 break;
221 case EVT_PULLREMOVE:
222 printf("get event pull and remove\n");
223 break;
224 case EVT_TOUCH1:
225 printf("get event touch1\n");
226 break;
227 case EVT_TOUCH2:
228 printf("get event touch2\n");
229 break;
230 case EVT_TOUCH3:
231 printf("get event touch3\n");
232 break;
233 case EVT_TOUCH4:
234 printf("get event touch4\n");
235 break;
236 case EVT_TOUCH5:
237 printf("get event touch5\n");
238 break;
239 default:
240 perror("no such event\n");
241 return ERR;
242 }
243 return OK;
244 }
245 return ERR;
246 }