Subversion Repositories Projects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
674 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] = 'a';
565
                        }
566
            }
567
 
568
                        data[numBytes]='\0';
569
 
570
                        dataReceived = data;
571
 
572
                        emit newDataReceived(dataReceived);
573
                }
574
                        mutexReceive.unlock();
575
        }
576
}
577