summaryrefslogtreecommitdiff
path: root/tvapi/libtv/tvutils/CSerialPort.cpp (plain)
blob: f634b0403eac7d19da722b1555824685b7758950
1#include "CSerialPort.h"
2#include <pthread.h>
3#include "CTvLog.h"
4#include <stdio.h>
5#include <unistd.h>
6#include <stdlib.h>
7#include <sys/types.h>
8#include <sys/stat.h>
9#include <fcntl.h>
10#include <string.h>
11#include <termios.h>
12#include <errno.h>
13
14#include "../tvconfig/tvconfig.h"
15
16CSerialPort::CSerialPort()
17{
18 mDevId = -1;
19}
20//close it
21CSerialPort::~CSerialPort()
22{
23}
24
25int CSerialPort::OpenDevice(int serial_dev_id)
26{
27 int tmp_ret = 0;
28 const char *dev_file_name = NULL;
29
30 if (getFd() < 0) {
31 if (serial_dev_id == SERIAL_A) {
32 dev_file_name = DEV_PATH_S0;
33 } else if (serial_dev_id == SERIAL_B) {
34 dev_file_name = DEV_PATH_S1;
35 } else if (serial_dev_id == SERIAL_C) {
36 dev_file_name = DEV_PATH_S2;
37 }
38
39 if (dev_file_name != NULL) {
40 mDevId = serial_dev_id;
41 tmp_ret = openFile(dev_file_name);
42 }
43 }
44
45 return tmp_ret;
46}
47
48int CSerialPort::CloseDevice()
49{
50 mDevId = -1;
51 closeFile();
52
53 return 0;
54}
55
56void CSerialPort::set_speed (int fd, int speed)
57{
58 int i;
59 int status;
60 struct termios Opt;
61 tcgetattr (fd, &Opt);
62 for (i = 0; i < sizeof (speed_arr) / sizeof (int); i++) {
63 if (speed == name_arr[i]) {
64 tcflush (fd, TCIOFLUSH);
65 cfsetispeed (&Opt, speed_arr[i]);
66 cfsetospeed (&Opt, speed_arr[i]);
67 status = tcsetattr (fd, TCSANOW, &Opt);
68 if (status != 0) {
69 perror ("tcsetattr fd1");
70 return;
71 }
72 tcflush (fd, TCIOFLUSH);
73 }
74 }
75}
76
77int CSerialPort::set_Parity (int fd, int databits, int stopbits, int parity)
78{
79 struct termios options;
80 if (tcgetattr (fd, &options) != 0) {
81 perror ("SetupSerial 1");
82 return (0);
83 }
84 options.c_cflag &= ~CSIZE;
85 switch (databits) {
86 case 7:
87 options.c_cflag |= CS7;
88 break;
89 case 8:
90 options.c_cflag |= CS8;
91 break;
92 default:
93 fprintf (stderr, "Unsupported data size\n");
94 return (0);
95 }
96 switch (parity) {
97 case 'n':
98 case 'N':
99 options.c_cflag &= ~PARENB; /* Clear parity enable */
100 options.c_iflag &= ~INPCK; /* Enable parity checking */
101 break;
102 case 'o':
103 case 'O':
104 options.c_cflag |= (PARODD | PARENB);
105 options.c_iflag |= INPCK; /* Disnable parity checking */
106 break;
107 case 'e':
108 case 'E':
109 options.c_cflag |= PARENB; /* Enable parity */
110 options.c_cflag &= ~PARODD;
111 options.c_iflag |= INPCK; /* Disnable parity checking */
112 break;
113 case 'S':
114 case 's': /*as no parity */
115 options.c_cflag &= ~PARENB;
116 options.c_cflag &= ~CSTOPB;
117 break;
118 default:
119 fprintf (stderr, "Unsupported parity\n");
120 return (0);
121 }
122
123 switch (stopbits) {
124 case 1:
125 options.c_cflag &= ~CSTOPB;
126 break;
127 case 2:
128 options.c_cflag |= CSTOPB;
129 break;
130 default:
131 fprintf (stderr, "Unsupported stop bits\n");
132 return (0);
133 }
134 /* Set input parity option */
135 if (parity != 'n')
136 options.c_iflag |= INPCK;
137 tcflush (fd, TCIFLUSH);
138 options.c_cc[VTIME] = 150;
139 options.c_cc[VMIN] = 0; /* Update the options and do it NOW */
140 //qd to set raw mode, which is copied from web
141 options.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP
142 | INLCR | IGNCR | ICRNL | IXON);
143 options.c_oflag &= ~OPOST;
144 options.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
145 options.c_cflag &= ~(CSIZE | PARENB);
146 options.c_cflag |= CS8;
147
148 if (tcsetattr (fd, TCSANOW, &options) != 0) {
149 perror ("SetupSerial 3");
150 return (0);
151 }
152 return (1);
153}
154
155int CSerialPort::setup_serial()
156{
157 set_speed(mFd, 115200);
158 set_Parity(mFd, 8, 1, 'N');
159 return 0;
160}
161
162int CSerialPort::set_opt(int speed, int db, int sb, char pb, int overtime, bool raw_mode)
163{
164 int i = 0;
165 struct termios old_cfg, new_cfg;
166 if (mFd <= 0) {
167 LOGE("not open dev, when set opt");
168 return -1;
169 }
170 //first get it
171 if (tcgetattr(mFd, &old_cfg) != 0) {
172 LOGE("get serial attr error mFd = %d(%s)!\n", mFd, strerror(errno));
173 return -1;
174 }
175
176 //set speed
177 for (i = 0; i < sizeof(speed_arr) / sizeof(int); i++) {
178 if (speed == name_arr[i]) {
179 cfsetispeed(&new_cfg, speed_arr[i]);
180 cfsetospeed(&new_cfg, speed_arr[i]);
181 break;
182 }
183 }
184
185 setdatabits(&new_cfg, db);
186 setstopbits(&new_cfg, sb);
187 setparity(&new_cfg, pb);
188
189
190 if (overtime >= 0) {
191 new_cfg.c_cc[VTIME] = overtime / 100; /* 设置超时 seconds*/
192 new_cfg.c_cc[VMIN] = 0; /* Update the options and do it NOW */
193 }
194
195 if (raw_mode) {
196 cfmakeraw(&new_cfg);
197 }
198
199 //clear
200 tcflush(mFd, TCIOFLUSH);
201 if (tcsetattr(mFd, TCSANOW, &new_cfg) < 0) {
202 LOGE("%s, set serial attr error(%s)!\n", "TV", strerror(errno));
203 return -1;
204 }
205 //clear,let be avail
206 tcflush(mFd, TCIOFLUSH);
207
208 return 0;
209}
210
211int CSerialPort::writeFile(const unsigned char *pData, unsigned int uLen)
212{
213 unsigned int len;
214 len = write(mFd, pData, uLen);
215 if (len == uLen) {
216 return len;
217 } else {
218 tcflush(mFd, TCOFLUSH);
219 LOGE("write data failed and tcflush hComm\n");
220 return -1;
221 }
222}
223
224static int com_read_data(int hComm, unsigned char *pData, unsigned int uLen)
225{
226 char inbuff[uLen];
227 char buff[uLen];
228 char tempbuff[uLen];
229 int i = 0, j = 0;
230
231 memset(inbuff, '\0', uLen);
232 memset(buff, '\0', uLen);
233 memset(tempbuff, '\0', uLen);
234
235 if (hComm < 0) {
236 return -1;
237 }
238
239 char *p = inbuff;
240
241 fd_set readset;
242 struct timeval tv;
243 int MaxFd = 0;
244
245 unsigned int c = 0;
246 int z, k;
247
248 do {
249 FD_ZERO(&readset);
250 FD_SET(hComm, &readset);
251 MaxFd = hComm + 1;
252 tv.tv_sec = 0;
253 tv.tv_usec = 100000;
254 do {
255 z = select(MaxFd, &readset, 0, 0, &tv);
256 } while (z == -1 && errno == EINTR);
257
258 if (z == -1) {
259 hComm = -1;
260 break;
261 }
262
263 if (z == 0) {
264 hComm = -1;
265 break;
266 }
267
268 if (FD_ISSET(hComm, &readset)) {
269 z = read(hComm, buff, uLen - c);
270#if 0
271 for (k = 0; k < z; k++) {
272 LOGD("%s, inbuff[%d]:%02X", "TV", k, buff[k]);
273 }
274#endif
275 c += z;
276
277 if (z > 0) {
278 if (z < (signed int) uLen) {
279 buff[z + 1] = '\0';
280 memcpy(p, buff, z);
281 p += z;
282 } else {
283 memcpy(inbuff, buff, z);
284 }
285
286 memset(buff, '\0', uLen);
287 } else {
288 hComm = -1;
289 }
290
291 if (c >= uLen) {
292 hComm = -1;
293 break;
294 }
295 }
296 } while (hComm >= 0);
297
298 memcpy(pData, inbuff, c);
299 p = NULL;
300 return c;
301}
302
303int CSerialPort::readFile(unsigned char *pBuf, unsigned int uLen)
304{
305 //using non-block mode
306 return com_read_data(mFd, pBuf, uLen);
307}
308
309int CSerialPort::setdatabits(struct termios *s, int db)
310{
311 if (db == 5) {
312 s->c_cflag = (s->c_cflag & ~CSIZE) | (CS5 & CSIZE);
313 } else if (db == 6) {
314 s->c_cflag = (s->c_cflag & ~CSIZE) | (CS6 & CSIZE);
315 } else if (db == 7) {
316 s->c_cflag = (s->c_cflag & ~CSIZE) | (CS7 & CSIZE);
317 } else if (db == 8) {
318 s->c_cflag = (s->c_cflag & ~CSIZE) | (CS8 & CSIZE);
319 } else {
320 LOGE("Unsupported data size!\n");
321 }
322 return 0;
323}
324
325int CSerialPort::setstopbits(struct termios *s, int sb)
326{
327 if (sb == 1) {
328 s->c_cflag &= ~CSTOPB;
329 } else if (sb == 2) {
330 s->c_cflag |= CSTOPB;
331 } else {
332 LOGE("Unsupported stop bits!\n");
333 }
334 return 0;
335}
336
337int CSerialPort::setparity(struct termios *s, char pb)
338{
339 if (pb == 'n' || pb == 'N') {
340 s->c_cflag &= ~PARENB; /* Clear parity enable */
341 s->c_cflag &= ~INPCK; /* Enable parity checking */
342 } else if (pb == 'o' || pb == 'O') {
343 s->c_cflag |= (PARODD | PARENB);
344 s->c_cflag |= INPCK; /* Disable parity checking */
345 } else if (pb == 'e' || pb == 'E') {
346 s->c_cflag |= PARENB; /* Enable parity */
347 s->c_cflag &= ~PARODD;
348 s->c_iflag |= INPCK; /* Disable parity checking */
349 } else if (pb == 's' || pb == 'S') {
350 s->c_cflag &= ~PARENB;
351 s->c_cflag &= ~CSTOPB;
352 s->c_cflag |= INPCK; /* Disable parity checking */
353 } else {
354 LOGE("Unsupported parity!\n");
355 }
356 return 0;
357}
358