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