summaryrefslogtreecommitdiff
path: root/tvapi/libtv/tvutils/serial_base.cpp (plain)
blob: 8a5a98b3ffe34e9e27d14c10a61967c2c22d507c
1#include <stdio.h>
2#include <unistd.h>
3#include <stdlib.h>
4#include <sys/types.h>
5#include <sys/stat.h>
6#include <fcntl.h>
7#include <string.h>
8#include <pthread.h>
9#include <termios.h>
10#include <errno.h>
11
12#include <android/log.h>
13#include <cutils/log.h>
14
15#include "serial_base.h"
16
17#define LOG_TAG "serial_base"
18#include "CTvLog.h"
19
20#define CS_SERIAL_A_DEV_PATH "/dev/ttyS0"
21#define CS_SERIAL_B_DEV_PATH "/dev/ttyS1"
22
23static int gSerialAHandle = -1;
24static pthread_mutex_t serial_a_op_mutex = PTHREAD_MUTEX_INITIALIZER;
25static pthread_mutex_t serial_a_r_mutex = PTHREAD_MUTEX_INITIALIZER;
26static pthread_mutex_t serial_a_w_mutex = PTHREAD_MUTEX_INITIALIZER;
27static pthread_mutex_t serial_a_speed_mutex = PTHREAD_MUTEX_INITIALIZER;
28static pthread_mutex_t serial_a_parity_mutex = PTHREAD_MUTEX_INITIALIZER;
29
30static int gSerialBHandle = -1;
31static pthread_mutex_t serial_b_op_mutex = PTHREAD_MUTEX_INITIALIZER;
32static pthread_mutex_t serial_b_r_mutex = PTHREAD_MUTEX_INITIALIZER;
33static pthread_mutex_t serial_b_w_mutex = PTHREAD_MUTEX_INITIALIZER;
34static pthread_mutex_t serial_b_speed_mutex = PTHREAD_MUTEX_INITIALIZER;
35static pthread_mutex_t serial_b_parity_mutex = PTHREAD_MUTEX_INITIALIZER;
36
37static int speed_arr[] = { B115200, B38400, B19200, B9600, B4800, B2400, B1200, B300, B38400, B19200, B9600, B4800, B2400, B1200, B300, };
38static int name_arr[] = { 115200, 38400, 19200, 9600, 4800, 2400, 1200, 300, 38400, 19200, 9600, 4800, 2400, 1200, 300, };
39
40static int open_com_dev(int *dev_handle, char *dev_path)
41{
42 if (*dev_handle < 0) {
43 *dev_handle = open(dev_path, O_RDWR);
44 if (*dev_handle < 0) {
45 LOGE("%s, Can't Open Serial Port %s", "TV", dev_path);
46 }
47 }
48
49 return *dev_handle;
50}
51
52static int close_com_dev(int *dev_handle)
53{
54 if (*dev_handle >= 0) {
55 close(*dev_handle);
56 *dev_handle = -1;
57 }
58
59 return 0;
60}
61
62static __inline__ int cfsetdatabits(struct termios *s, int db)
63{
64 if (db == 5) {
65 s->c_cflag = (s->c_cflag & ~CSIZE) | (CS5 & CSIZE);
66 } else if (db == 6) {
67 s->c_cflag = (s->c_cflag & ~CSIZE) | (CS6 & CSIZE);
68 } else if (db == 7) {
69 s->c_cflag = (s->c_cflag & ~CSIZE) | (CS7 & CSIZE);
70 } else if (db == 8) {
71 s->c_cflag = (s->c_cflag & ~CSIZE) | (CS8 & CSIZE);
72 } else {
73 LOGE("%s, Unsupported data size!\n", "TV");
74 }
75
76 return 0;
77}
78
79static __inline__ int cfsetstopbits(struct termios *s, int sb)
80{
81 if (sb == 1) {
82 s->c_cflag &= ~CSTOPB;
83 } else if (sb == 2) {
84 s->c_cflag |= CSTOPB;
85 } else {
86 LOGE("%s, Unsupported stop bits!\n", "TV");
87 }
88
89 return 0;
90}
91
92static __inline__ int cfsetparity(struct termios *s, int pb)
93{
94 if (pb == 'n' || pb == 'N') {
95 s->c_cflag &= ~PARENB; /* Clear parity enable */
96 s->c_cflag &= ~INPCK; /* Enable parity checking */
97 } else if (pb == 'o' || pb == 'O') {
98 s->c_cflag |= (PARODD | PARENB);
99 s->c_cflag |= INPCK; /* Disable parity checking */
100 } else if (pb == 'e' || pb == 'E') {
101 s->c_cflag |= PARENB; /* Enable parity */
102 s->c_cflag &= ~PARODD;
103 s->c_iflag |= INPCK; /* Disable parity checking */
104 } else if (pb == 's' || pb == 'S') {
105 s->c_cflag &= ~PARENB;
106 s->c_cflag &= ~CSTOPB;
107 s->c_cflag |= INPCK; /* Disable parity checking */
108 } else {
109 LOGE("%s, Unsupported parity!\n", "TV");
110 }
111
112 return 0;
113}
114
115static int gOriAttrGetFlag = 0;
116static struct termios gOriAttrValue;
117static __inline__ int com_get_attr(int fd, struct termios *s)
118{
119 if (gOriAttrGetFlag == 0) {
120 if (tcgetattr(fd, s) != 0) {
121 return -1;
122 }
123
124 gOriAttrGetFlag = 1;
125 gOriAttrValue = *s;
126 }
127
128 *s = gOriAttrValue;
129
130 return 0;
131}
132
133static int com_set_opt(int hComm, int speed, int db, int sb, int pb, int to, int raw_mode)
134{
135 int i = 0;
136 struct termios tmpOpt;
137
138 if (com_get_attr(hComm, &tmpOpt) != 0) {
139 LOGE("%s, get serial attr error(%s)!\n", "TV", strerror(errno));
140 return -1;
141 }
142
143 for (i = 0; i < sizeof(speed_arr) / sizeof(int); i++) {
144 if (speed == name_arr[i]) {
145 cfsetispeed(&tmpOpt, speed_arr[i]);
146 cfsetospeed(&tmpOpt, speed_arr[i]);
147 break;
148 }
149 }
150
151 cfsetdatabits(&tmpOpt, db);
152 cfsetstopbits(&tmpOpt, sb);
153 cfsetparity(&tmpOpt, pb);
154
155 if (to >= 0) {
156 tmpOpt.c_cc[VTIME] = to; /* 设置超时15 seconds*/
157 tmpOpt.c_cc[VMIN] = 0; /* Update the options and do it NOW */
158 }
159
160 if (raw_mode == 1) {
161 cfmakeraw(&tmpOpt);
162 }
163
164 tcflush(hComm, TCIOFLUSH);
165 if (tcsetattr(hComm, TCSANOW, &tmpOpt) < 0) {
166 LOGE("%s, set serial attr error(%s)!\n", "TV", strerror(errno));
167 return -1;
168 }
169 tcflush(hComm, TCIOFLUSH);
170
171 return 0;
172}
173
174static int com_write_data(int hComm, const unsigned char *pData, unsigned int uLen)
175{
176 unsigned int len;
177
178 if (hComm < 0) {
179 return -1;
180 }
181
182 if (pData == NULL) {
183 return -1;
184 }
185
186 LOGD("%s, write %d bytes\n", "TV", uLen);
187
188 len = write(hComm, pData, uLen);
189 if (len == uLen) {
190 LOGD("%s, write data success\n", "TV");
191 return len;
192 } else {
193 tcflush(hComm, TCOFLUSH);
194 LOGE("%s, write data failed and tcflush hComm\n", "TV");
195 return -1;
196 }
197}
198
199static int com_read_data(int hComm, char *pData, unsigned int uLen)
200{
201 char inbuff[uLen];
202 char buff[uLen];
203 char tempbuff[uLen];
204 int i = 0, j = 0;
205
206 memset(inbuff, '\0', uLen);
207 memset(buff, '\0', uLen);
208 memset(tempbuff, '\0', uLen);
209
210 if (hComm < 0) {
211 return -1;
212 }
213
214 char *p = inbuff;
215
216 fd_set readset;
217 struct timeval tv;
218 int MaxFd = 0;
219
220 unsigned int c = 0;
221 int z, k;
222
223 do {
224 FD_ZERO(&readset);
225 FD_SET(hComm, &readset);
226 MaxFd = hComm + 1;
227 tv.tv_sec = 0;
228 tv.tv_usec = 100000;
229 do {
230 z = select(MaxFd, &readset, 0, 0, &tv);
231 } while (z == -1 && errno == EINTR);
232
233 if (z == -1) {
234 hComm = -1;
235 break;
236 }
237
238 if (z == 0) {
239 hComm = -1;
240 break;
241 }
242
243 if (FD_ISSET(hComm, &readset)) {
244 z = read(hComm, buff, uLen - c);
245#if 0
246 for (k = 0; k < z; k++) {
247 LOGD("%s, inbuff[%d]:%02X", "TV", k, buff[k]);
248 }
249#endif
250 c += z;
251
252 if (z > 0) {
253 if (z < (signed int) uLen) {
254 buff[z + 1] = '\0';
255 memcpy(p, buff, z);
256 p += z;
257 } else {
258 memcpy(inbuff, buff, z);
259 }
260
261 memset(buff, '\0', uLen);
262 } else {
263 hComm = -1;
264 }
265
266 if (c >= uLen) {
267 hComm = -1;
268 break;
269 }
270 }
271 } while (hComm >= 0);
272
273 memcpy(pData, inbuff, c);
274 p = NULL;
275 return c;
276}
277
278int com_a_open_dev()
279{
280 int tmp_ret = 0;
281
282 pthread_mutex_lock(&serial_a_op_mutex);
283
284 tmp_ret = open_com_dev(&gSerialAHandle, CS_SERIAL_A_DEV_PATH);
285
286 pthread_mutex_unlock(&serial_a_op_mutex);
287
288 return tmp_ret;
289}
290
291int com_b_open_dev()
292{
293 int tmp_ret = 0;
294
295 pthread_mutex_lock(&serial_b_op_mutex);
296
297 tmp_ret = open_com_dev(&gSerialBHandle, CS_SERIAL_B_DEV_PATH);
298
299 pthread_mutex_unlock(&serial_b_op_mutex);
300
301 return tmp_ret;
302}
303
304int com_a_close_dev()
305{
306 int tmp_ret = 0;
307
308 pthread_mutex_lock(&serial_a_op_mutex);
309
310 tmp_ret = close_com_dev(&gSerialAHandle);
311
312 pthread_mutex_unlock(&serial_a_op_mutex);
313
314 return tmp_ret;
315}
316
317int com_b_close_dev()
318{
319 int tmp_ret = 0;
320
321 pthread_mutex_lock(&serial_b_op_mutex);
322
323 tmp_ret = close_com_dev(&gSerialBHandle);
324
325 pthread_mutex_unlock(&serial_b_op_mutex);
326
327 return tmp_ret;
328}
329
330int com_a_get_dev()
331{
332 int tmp_ret = 0;
333
334 pthread_mutex_lock(&serial_a_op_mutex);
335
336 tmp_ret = gSerialAHandle;
337
338 pthread_mutex_unlock(&serial_a_op_mutex);
339
340 return tmp_ret;
341}
342
343int com_b_get_dev()
344{
345 int tmp_ret = 0;
346
347 pthread_mutex_lock(&serial_b_op_mutex);
348
349 tmp_ret = gSerialBHandle;
350
351 pthread_mutex_unlock(&serial_b_op_mutex);
352
353 return tmp_ret;
354}
355
356int com_a_set_opt(int speed, int db, int sb, int pb, int to, int raw_mode)
357{
358 int tmp_ret = 0;
359
360 pthread_mutex_lock(&serial_a_parity_mutex);
361
362 if (com_a_get_dev() < 0) {
363 pthread_mutex_unlock(&serial_a_parity_mutex);
364 return -1;
365 }
366
367 tmp_ret = com_set_opt(gSerialAHandle, speed, db, sb, pb, to, raw_mode);
368
369 pthread_mutex_unlock(&serial_a_parity_mutex);
370
371 return tmp_ret;
372}
373
374int com_b_set_opt(int speed, int db, int sb, int pb, int to, int raw_mode)
375{
376 int tmp_ret = 0;
377
378 pthread_mutex_lock(&serial_b_parity_mutex);
379
380 if (com_b_get_dev() < 0) {
381 pthread_mutex_unlock(&serial_b_parity_mutex);
382 return -1;
383 }
384
385 tmp_ret = com_set_opt(gSerialBHandle, speed, db, sb, pb, to, raw_mode);
386
387 pthread_mutex_unlock(&serial_b_parity_mutex);
388
389 return tmp_ret;
390}
391
392int com_a_write_data(const unsigned char *pData, unsigned int uLen)
393{
394 int tmp_ret = 0;
395
396 pthread_mutex_lock(&serial_a_w_mutex);
397
398 if (com_a_get_dev() < 0) {
399 pthread_mutex_unlock(&serial_a_w_mutex);
400 return -1;
401 }
402
403 LOGD("%s, write %d bytes\n", "TV", uLen);
404
405 tmp_ret = com_write_data(gSerialAHandle, pData, uLen);
406
407 pthread_mutex_unlock(&serial_a_w_mutex);
408
409 return tmp_ret;
410}
411
412int com_b_write_data(const unsigned char *pData, unsigned int uLen)
413{
414 int tmp_ret = 0;
415
416 pthread_mutex_lock(&serial_b_w_mutex);
417
418 if (com_b_get_dev() < 0) {
419 pthread_mutex_unlock(&serial_b_w_mutex);
420 return -1;
421 }
422
423 LOGD("%s, write %d bytes\n", "TV", uLen);
424
425 tmp_ret = com_write_data(gSerialBHandle, pData, uLen);
426
427 pthread_mutex_unlock(&serial_b_w_mutex);
428
429 return tmp_ret;
430}
431
432int com_a_read_data(char *pData, unsigned int uLen)
433{
434 int tmp_ret = 0;
435
436 pthread_mutex_lock(&serial_a_r_mutex);
437
438 if (com_a_get_dev() < 0) {
439 pthread_mutex_unlock(&serial_a_r_mutex);
440 return -1;
441 }
442
443 tmp_ret = com_read_data(gSerialAHandle, pData, uLen);
444
445 pthread_mutex_unlock(&serial_a_r_mutex);
446
447 return tmp_ret;
448}
449
450int com_b_read_data(char *pData, unsigned int uLen)
451{
452 int tmp_ret = 0;
453
454 pthread_mutex_lock(&serial_b_r_mutex);
455
456 if (com_b_get_dev() < 0) {
457 pthread_mutex_unlock(&serial_b_r_mutex);
458 return -1;
459 }
460
461 tmp_ret = com_read_data(gSerialBHandle, pData, uLen);
462
463 pthread_mutex_unlock(&serial_b_r_mutex);
464
465 return tmp_ret;
466}
467