Go to most recent revision | Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
158 | KeyOz | 1 | /******************************************************************************************************** |
2 | * PROGRAM : QSerialPortTerminal |
||
3 | * DATE - TIME : vendredi 03 octobre 2008 - 11h15 |
||
4 | * AUTHOR : VIANNEY-LIAUD Philippe ( philippe.vianney.liaud gmail.com ) |
||
5 | * FILENAME : ManageSerialPort.cpp |
||
6 | * LICENSE : GPL |
||
7 | * COMMENTARY : |
||
8 | ********************************************************************************************************/ |
||
9 | #include <QtDebug> |
||
10 | #include "ManageSerialPort.h" |
||
11 | |||
12 | /******************************************************************************************************** |
||
13 | * Classe ManageSerialPort |
||
14 | *****************************************************************************************************/ |
||
15 | |||
16 | //Constructeur |
||
17 | ManageSerialPort::ManageSerialPort() |
||
18 | { |
||
19 | //Init pointeur a NULL |
||
20 | threadSend = NULL; |
||
21 | threadReceive = NULL; |
||
22 | |||
23 | //Init des bool |
||
24 | sendingEnabled = false; |
||
25 | receivingEnabled = false; |
||
26 | closeCalled = false; |
||
27 | saveStateSendEnabled = false; |
||
28 | saveStateReceivedEnabled = false; |
||
29 | saveStateReceiveData = false; |
||
30 | } |
||
31 | |||
32 | ManageSerialPort::ManageSerialPort(const QString &name, const BaudRateType baudRate, \ |
||
33 | const DataBitsType dataBits, const ParityType parity, \ |
||
34 | const StopBitsType stopBits, const FlowType flowControl, \ |
||
35 | ulong seconds, ulong milliseconds) |
||
36 | { |
||
37 | //Init pointeur a NULL |
||
38 | threadSend = NULL; |
||
39 | threadReceive = NULL; |
||
40 | |||
41 | //Init des bool |
||
42 | sendingEnabled = false; |
||
43 | receivingEnabled = false; |
||
44 | closeCalled = false; |
||
45 | saveStateSendEnabled = false; |
||
46 | saveStateReceivedEnabled = false; |
||
47 | saveStateReceiveData = false; |
||
48 | |||
49 | setPort(name); |
||
50 | setBaudRate(baudRate); |
||
51 | setDataBits(dataBits); |
||
52 | setParity(parity); |
||
53 | setStopBits(stopBits); |
||
54 | setFlowControl(flowControl); |
||
55 | setTimeout(seconds, milliseconds); |
||
56 | } |
||
57 | |||
58 | //Destructeur |
||
59 | ManageSerialPort::~ManageSerialPort() |
||
60 | { |
||
61 | if (threadSend != NULL) |
||
62 | { |
||
63 | delete threadSend; |
||
64 | threadSend = NULL; |
||
65 | } |
||
66 | |||
67 | if (threadReceive != NULL) |
||
68 | { |
||
69 | delete threadReceive; |
||
70 | threadReceive = NULL; |
||
71 | } |
||
72 | |||
73 | if (isOpen()) |
||
74 | extSerialPort.close(); |
||
75 | } |
||
76 | |||
77 | bool ManageSerialPort::open() |
||
78 | { |
||
79 | bool res = extSerialPort.open(QIODevice::ReadWrite); |
||
80 | |||
81 | if (closeCalled) |
||
82 | { |
||
83 | if (saveStateSendEnabled) |
||
84 | enableSending(); |
||
85 | |||
86 | if (saveStateReceivedEnabled) |
||
87 | enableReceiving(); |
||
88 | |||
89 | if (saveStateReceiveData) |
||
90 | receiveData(); |
||
91 | closeCalled = false; |
||
92 | } |
||
93 | |||
94 | return res; |
||
95 | } |
||
96 | |||
97 | bool ManageSerialPort::open(const QString &name, const BaudRateType baudRate, \ |
||
98 | const DataBitsType dataBits,const ParityType parity, \ |
||
99 | const StopBitsType stopBits, const FlowType flowControl, \ |
||
100 | ulong seconds, ulong milliseconds) |
||
101 | { |
||
102 | setPort(name); |
||
103 | setBaudRate(baudRate); |
||
104 | setDataBits(dataBits); |
||
105 | setParity(parity); |
||
106 | setStopBits(stopBits); |
||
107 | setFlowControl(flowControl); |
||
108 | setTimeout(seconds, milliseconds); |
||
109 | |||
110 | bool res = extSerialPort.open(QIODevice::ReadWrite); |
||
111 | |||
112 | |||
113 | return res; |
||
114 | } |
||
115 | |||
116 | bool ManageSerialPort::isOpen() |
||
117 | { |
||
118 | return extSerialPort.isOpen(); |
||
119 | } |
||
120 | |||
121 | void ManageSerialPort::close() |
||
122 | { |
||
123 | closeCalled = true; |
||
124 | saveStateSendEnabled = isSendingEnabled(); |
||
125 | saveStateReceivedEnabled = isReceivingEnabled(); |
||
126 | |||
127 | disableSending(); |
||
128 | disableReceiving(); |
||
129 | |||
130 | extSerialPort.close(); |
||
131 | } |
||
132 | |||
133 | void ManageSerialPort::setPort(const QString &name) |
||
134 | { |
||
135 | extSerialPort.setPortName(name); |
||
136 | } |
||
137 | |||
138 | QString ManageSerialPort::getPort() |
||
139 | { |
||
140 | return extSerialPort.portName(); |
||
141 | } |
||
142 | |||
143 | |||
144 | void ManageSerialPort::setBaudRate(const BaudRateType baudRate) |
||
145 | { |
||
146 | extSerialPort.setBaudRate(baudRate); |
||
147 | } |
||
148 | |||
149 | QString ManageSerialPort::getBaudRate() |
||
150 | { |
||
151 | switch (extSerialPort.baudRate()) |
||
152 | { |
||
153 | case BAUD50: |
||
154 | return QString("50"); |
||
155 | case BAUD75: |
||
156 | return QString("75"); |
||
157 | case BAUD110: |
||
158 | return QString("110"); |
||
159 | case BAUD134: |
||
160 | return QString("134"); |
||
161 | case BAUD150: |
||
162 | return QString("150"); |
||
163 | case BAUD200: |
||
164 | return QString("200"); |
||
165 | case BAUD300: |
||
166 | return QString("300"); |
||
167 | case BAUD600: |
||
168 | return QString("600"); |
||
169 | case BAUD1200: |
||
170 | return QString("1200"); |
||
171 | case BAUD1800: |
||
172 | return QString("1800"); |
||
173 | case BAUD2400: |
||
174 | return QString("2400"); |
||
175 | case BAUD4800: |
||
176 | return QString("4800"); |
||
177 | case BAUD9600: |
||
178 | return QString("9600"); |
||
179 | case BAUD14400: |
||
180 | return QString("14400"); |
||
181 | case BAUD19200: |
||
182 | return QString("19200"); |
||
183 | case BAUD38400: |
||
184 | return QString("38400"); |
||
185 | case BAUD56000: |
||
186 | return QString("56000"); |
||
187 | case BAUD57600: |
||
188 | return QString("57600"); |
||
189 | case BAUD76800: |
||
190 | return QString("76800"); |
||
191 | case BAUD115200: |
||
192 | return QString("115200"); |
||
193 | case BAUD128000: |
||
194 | return QString("128000"); |
||
195 | case BAUD256000: |
||
196 | return QString("256000"); |
||
197 | } |
||
198 | return 0; |
||
199 | } |
||
200 | |||
201 | |||
202 | void ManageSerialPort::setDataBits(const DataBitsType dataBits) |
||
203 | { |
||
204 | extSerialPort.setDataBits(dataBits); |
||
205 | } |
||
206 | |||
207 | QChar ManageSerialPort::getDataBits() |
||
208 | { |
||
209 | switch (extSerialPort.dataBits()) |
||
210 | { |
||
211 | case DATA_5: |
||
212 | return QChar('5'); |
||
213 | case DATA_6: |
||
214 | return QChar('6'); |
||
215 | case DATA_7: |
||
216 | return QChar('7'); |
||
217 | case DATA_8: |
||
218 | return QChar('8'); |
||
219 | } |
||
220 | return 0; |
||
221 | } |
||
222 | |||
223 | |||
224 | void ManageSerialPort::setParity(const ParityType parity) |
||
225 | { |
||
226 | extSerialPort.setParity(parity); |
||
227 | } |
||
228 | |||
229 | QString ManageSerialPort::getParity() |
||
230 | { |
||
231 | switch (extSerialPort.parity()) |
||
232 | { |
||
233 | case PAR_NONE: |
||
234 | return QString(tr("None")); |
||
235 | case PAR_ODD: |
||
236 | return QString(tr("Odd")); |
||
237 | case PAR_EVEN: |
||
238 | return QString(tr("Even")); |
||
239 | case PAR_MARK: |
||
240 | return QString(tr("Mark")); |
||
241 | case PAR_SPACE: |
||
242 | return QString(tr("Space")); |
||
243 | } |
||
244 | return 0; |
||
245 | } |
||
246 | |||
247 | |||
248 | void ManageSerialPort::setStopBits(const StopBitsType stopBits) |
||
249 | { |
||
250 | extSerialPort.setStopBits(stopBits); |
||
251 | } |
||
252 | |||
253 | QString ManageSerialPort::getStopBit() |
||
254 | { |
||
255 | switch (extSerialPort.stopBits()) |
||
256 | { |
||
257 | case STOP_1: |
||
258 | return QString("1"); |
||
259 | case STOP_1_5: |
||
260 | return QString("1.5"); |
||
261 | case STOP_2: |
||
262 | return QString("2"); |
||
263 | } |
||
264 | return 0; |
||
265 | } |
||
266 | |||
267 | |||
268 | void ManageSerialPort::setFlowControl(const FlowType flowControl) |
||
269 | { |
||
270 | extSerialPort.setFlowControl(flowControl); |
||
271 | } |
||
272 | |||
273 | QString ManageSerialPort::getFlowControl() |
||
274 | { |
||
275 | switch (extSerialPort.flowControl()) |
||
276 | { |
||
277 | case FLOW_OFF: |
||
278 | return QString(tr("None")); |
||
279 | case FLOW_HARDWARE : |
||
280 | return QString(tr("Hardware")); |
||
281 | case FLOW_XONXOFF : |
||
282 | return QString(tr("Xon/Xoff")); |
||
283 | } |
||
284 | return 0; |
||
285 | } |
||
286 | |||
287 | |||
288 | void ManageSerialPort::setTimeout(ulong seconds, ulong milliseconds) |
||
289 | { |
||
290 | extSerialPort.setTimeout(seconds,milliseconds); |
||
291 | } |
||
292 | |||
293 | /* |
||
294 | QString ManageSerialPort::getLastErrorToString() |
||
295 | { |
||
296 | ulong res = extSerialPort.lastError(); |
||
297 | switch (res) |
||
298 | { |
||
299 | case E_NO_ERROR: |
||
300 | return QString(tr("No Error has occured")); |
||
301 | case E_INVALID_FD: |
||
302 | return QString(tr("Invalid file descriptor (port was not opened correctly)")); |
||
303 | case E_NO_MEMORY: |
||
304 | return QString(tr("Unable to allocate memory tables (POSIX)")); |
||
305 | case E_CAUGHT_NON_BLOCKED_SIGNAL: |
||
306 | return QString(tr("Caught a non-blocked signal (POSIX)")); |
||
307 | case E_PORT_TIMEOUT: |
||
308 | return QString(tr("Operation timed out (POSIX)")); |
||
309 | case E_INVALID_DEVICE: |
||
310 | return QString(tr("The file opened by the port is not a character device (POSIX)")); |
||
311 | case E_BREAK_CONDITION: |
||
312 | return QString(tr("The port detected a break condition")); |
||
313 | case E_FRAMING_ERROR: |
||
314 | return QString(tr("The port detected a framing error (usually caused by incorrect baud rate settings)")); |
||
315 | case E_IO_ERROR: |
||
316 | return QString(tr("There was an I/O error while communicating with the port")); |
||
317 | case E_BUFFER_OVERRUN: |
||
318 | return QString(tr("Character buffer overrun")); |
||
319 | case E_RECEIVE_OVERFLOW: |
||
320 | return QString(tr("Receive buffer overflow")); |
||
321 | case E_RECEIVE_PARITY_ERROR: |
||
322 | return QString(tr("The port detected a parity error in the received data")); |
||
323 | case E_TRANSMIT_OVERFLOW: |
||
324 | return QString(tr("Transmit buffer overflow")); |
||
325 | case E_READ_FAILED: |
||
326 | return QString(tr("General read operation failure")); |
||
327 | case E_WRITE_FAILED: |
||
328 | return QString(tr("General write operation failure")); |
||
329 | } |
||
330 | return 0; |
||
331 | }*/ |
||
332 | |||
333 | /* |
||
334 | ulong ManageSerialPort::getLastError() |
||
335 | { |
||
336 | return extSerialPort.lastError(); |
||
337 | } |
||
338 | */ |
||
339 | |||
340 | |||
341 | void ManageSerialPort::enableSending() |
||
342 | { |
||
343 | if (!sendingEnabled && threadSend == NULL) //Si l'envoi n'est pas active && si threadSend n'est pas alloue |
||
344 | { |
||
345 | threadSend = new ThreadSend(extSerialPort); |
||
346 | sendingEnabled = true; |
||
347 | } |
||
348 | } |
||
349 | |||
350 | void ManageSerialPort::disableSending() |
||
351 | { |
||
352 | if (sendingEnabled && threadSend != NULL) //Si l'envoi est active && si threadSend est alloue |
||
353 | { |
||
354 | delete (threadSend); |
||
355 | threadSend = NULL; |
||
356 | sendingEnabled = false; |
||
357 | } |
||
358 | } |
||
359 | |||
360 | bool ManageSerialPort::isSendingEnabled() |
||
361 | { |
||
362 | return sendingEnabled; |
||
363 | } |
||
364 | |||
365 | uchar ManageSerialPort::sendData(QByteArray &dataToSend) |
||
366 | { |
||
367 | if (!isOpen()) //Si le port n'est pas ouvert |
||
368 | return 2; |
||
369 | |||
370 | if (!sendingEnabled || threadSend == NULL) //Si l'envoi n'est pas active || si threadSend n'est pas alloue |
||
371 | return 3; |
||
372 | |||
373 | threadSend->addDataToSend(dataToSend); //Ajout des donnees a envoyer |
||
374 | return 1; |
||
375 | } |
||
376 | |||
377 | void ManageSerialPort::stopSending() |
||
378 | { |
||
379 | if (!sendingEnabled || threadSend == NULL) //Si l'envoi n'est pas active || si threadSend n'est pas été alloue |
||
380 | return; |
||
381 | |||
382 | if (threadSend->isRunning()) //si un envoi est en cour |
||
383 | { |
||
384 | threadSend->stopSending(); //on donne l'ordre d'arreter l'envoi |
||
385 | |||
386 | long tmp = ULONG_MAX; |
||
387 | threadSend->wait(tmp); //on attend l'arret |
||
388 | } |
||
389 | } |
||
390 | |||
391 | |||
392 | |||
393 | void ManageSerialPort::enableReceiving() |
||
394 | { |
||
395 | if (!receivingEnabled && threadReceive == NULL) //Si la reception n'est pas active && si threadReceive n'est pas alloue |
||
396 | { |
||
397 | threadReceive = new ThreadReceive(extSerialPort); |
||
398 | connect(threadReceive, SIGNAL(newDataReceived(const QByteArray &)), this, SIGNAL(newDataReceived(const QByteArray &))); |
||
399 | receivingEnabled = true; |
||
400 | } |
||
401 | } |
||
402 | |||
403 | void ManageSerialPort::disableReceiving() |
||
404 | { |
||
405 | if (receivingEnabled && threadReceive != NULL) //Si la reception est pas active && si threadReceive est alloue |
||
406 | { |
||
407 | delete (threadReceive); |
||
408 | threadReceive = NULL; |
||
409 | receivingEnabled = false; |
||
410 | } |
||
411 | } |
||
412 | |||
413 | bool ManageSerialPort::isReceivingEnabled() |
||
414 | { |
||
415 | return receivingEnabled; |
||
416 | } |
||
417 | |||
418 | uchar ManageSerialPort::receiveData() |
||
419 | { |
||
420 | if (!isOpen()) //Si le port n'est pas ouvert |
||
421 | return 2; |
||
422 | if (!receivingEnabled || threadReceive == NULL) //Si la reception n'est pas active || si threadReceive n'est pas été alloue |
||
423 | return 3; |
||
424 | |||
425 | if (!threadReceive->isRunning()) |
||
426 | { |
||
427 | saveStateReceiveData = true; |
||
428 | threadReceive->start(); //Demarrage du thread de reception |
||
429 | } |
||
430 | return 1; |
||
431 | } |
||
432 | |||
433 | void ManageSerialPort::stopReceiving() |
||
434 | { |
||
435 | if (!receivingEnabled || threadReceive == NULL) //Si la reception n'est pas active || si threadReceive n'est pas alloue |
||
436 | return; |
||
437 | |||
438 | if (threadReceive->isRunning()) //Si le thread de reception est en fonctionnement |
||
439 | { |
||
440 | saveStateReceiveData = false; |
||
441 | threadReceive->stopReceiving(); //on donne l'ordre d'arreter la reception |
||
442 | |||
443 | long tmp = ULONG_MAX; |
||
444 | threadReceive->wait(tmp); //on attend l'arret |
||
445 | } |
||
446 | } |
||
447 | |||
448 | |||
449 | |||
450 | |||
451 | |||
452 | |||
453 | |||
454 | |||
455 | |||
456 | |||
457 | |||
458 | /******************************************************************************************************** |
||
459 | * Classe ThreadSend |
||
460 | *****************************************************************************************************/ |
||
461 | |||
462 | ThreadSend::ThreadSend(QextSerialPort &addressSerialPort) : extSerialPort(addressSerialPort) |
||
463 | { |
||
464 | dataToSend.clear(); |
||
465 | stopped=false; |
||
466 | } |
||
467 | |||
468 | ThreadSend::~ThreadSend() |
||
469 | { |
||
470 | if (isRunning()) |
||
471 | { |
||
472 | stopSending(); |
||
473 | wait(); |
||
474 | } |
||
475 | } |
||
476 | |||
477 | |||
478 | void ThreadSend::addDataToSend(QByteArray &dataToAdd) |
||
479 | { |
||
480 | QMutexLocker locker(&mutexSend); |
||
481 | for (int i=0; i<dataToAdd.size(); i++) |
||
482 | dataToSend.enqueue(QByteArray(1,dataToAdd.at(i))); |
||
483 | |||
484 | if (!isRunning()) |
||
485 | start(); |
||
486 | } |
||
487 | |||
488 | void ThreadSend::stopSending() |
||
489 | { |
||
490 | stopped=true; |
||
491 | } |
||
492 | |||
493 | void ThreadSend::run() |
||
494 | { |
||
495 | QByteArray byteArray; |
||
496 | |||
497 | forever |
||
498 | { |
||
499 | if (dataToSend.isEmpty() || stopped) |
||
500 | { |
||
501 | stopped = false; |
||
502 | break; |
||
503 | } |
||
504 | mutexSend.lock(); |
||
505 | byteArray = dataToSend.dequeue(); |
||
506 | mutexSend.unlock(); |
||
507 | |||
508 | extSerialPort.write(byteArray, 1); |
||
509 | } |
||
510 | } |
||
511 | |||
512 | |||
513 | |||
514 | |||
515 | |||
516 | /******************************************************************************************************** |
||
517 | * Classe ThreadReceive - A TERMINER |
||
518 | *****************************************************************************************************/ |
||
519 | |||
520 | ThreadReceive::ThreadReceive(QextSerialPort &addressSerialPort) : extSerialPort(addressSerialPort) |
||
521 | { |
||
522 | stopped=false; |
||
523 | } |
||
524 | |||
525 | ThreadReceive::~ThreadReceive() |
||
526 | { |
||
527 | if (isRunning()) |
||
528 | { |
||
529 | stopReceiving(); |
||
530 | wait(); |
||
531 | } |
||
532 | } |
||
533 | |||
534 | void ThreadReceive::stopReceiving() |
||
535 | { |
||
536 | stopped = true; |
||
537 | } |
||
538 | |||
539 | void ThreadReceive::run() |
||
540 | { |
||
541 | int numBytes=0; |
||
542 | char data[1024]; |
||
543 | QByteArray dataReceived; |
||
544 | |||
545 | forever |
||
546 | { |
||
547 | if (stopped) |
||
548 | { |
||
549 | stopped = false; |
||
550 | break; |
||
551 | } |
||
552 | |||
553 | mutexReceive.lock(); |
||
554 | |||
555 | numBytes = extSerialPort.bytesAvailable(); |
||
556 | if (numBytes > 0) |
||
557 | { |
||
558 | extSerialPort.read(data, numBytes); |
||
559 | |||
560 | for (int xy=1; xy < numBytes; xy++) |
||
561 | { |
||
562 | if (data[xy] == 0) |
||
563 | { |
||
564 | data[xy] = 127; |
||
565 | } |
||
566 | } |
||
567 | |||
568 | data[numBytes]='\0'; |
||
569 | |||
570 | dataReceived = data; |
||
571 | |||
572 | emit newDataReceived(dataReceived); |
||
573 | } |
||
574 | mutexReceive.unlock(); |
||
575 | } |
||
576 | } |
||
577 |