source: pacpussensors/trunk/driver/PosixSerialPort.cpp@ 77

Last change on this file since 77 was 59, checked in by DHERBOMEZ Gérald, 10 years ago

Integration of new modules:

  • GPS NMEA0183 decoder
  • Span CPT Decoder

Update of:

File size: 6.0 KB
Line 
1/*********************************************************************
2// created: 2011/05/18
3// filename: PosixSerialPort.cpp
4//
5// author: Gerald Dherbomez
6//
7// version: $Id: $
8//
9// purpose: This class defines a unix (32bits) driver for serial port
10 *********************************************************************/
11
12#include "PosixSerialPort.h"
13
14#include <QDebug>
15
16#include <stdio.h>
17#include <string.h>
18#include <fcntl.h>
19#include <errno.h>
20#include <termios.h>
21#include <unistd.h>
22#include <sys/ioctl.h>
23
24
25PosixSerialPort::~PosixSerialPort() {
26 qDebug() << "The win32 serial port " << componentName << " was destroyed";
27}
28
29PosixSerialPort::PosixSerialPort(QString name) {
30
31}
32
33
34//////////////////////////////////////////////////////////////////////////
35// return the number of frames that have not been yet decoded
36//////////////////////////////////////////////////////////////////////////
37
38int PosixSerialPort::numberOfFrames() {
39 if (dataFrameList.isEmpty())
40 return 0;
41 return dataFrameList.count();
42}
43
44
45
46//////////////////////////////////////////////////////////////////////////
47// return a pointer to the first frame in the list
48//////////////////////////////////////////////////////////////////////////
49
50FRAME * PosixSerialPort::firstFrame() {
51 return dataFrameList.first();
52}
53
54
55
56
57
58//////////////////////////////////////////////////////////////////////////
59// remove the first frame of the list
60// use this function as soon as you copy the frame
61//////////////////////////////////////////////////////////////////////////
62
63int PosixSerialPort::removeFirstFrame() {
64 frameLock_.lock();
65
66 FRAME * tmp = dataFrameList.first();
67 if (tmp == NULL) {
68 qWarning("Not possible to delete the first item of the dataframe list. It is empty.");
69 return 0;
70 }
71 dataFrameList.removeFirst();
72 delete[] tmp->data;
73 delete tmp;
74 tmp = NULL;
75
76 frameLock_.unlock();
77
78 return 1;
79}
80
81/*!< open the port 'name'
82return true if success
83 */
84bool PosixSerialPort::openPort(const char * name) {
85 handlePort = open(name, O_RDWR | O_NOCTTY | O_NDELAY);
86 if (handlePort == -1) {
87 qWarning("openPort : Unable to open serial port %s",name);
88 return false;
89 } else {
90 fcntl(handlePort, F_SETFL, 0);
91 printf("Port %s has been sucessfully opened and % d is the file description\n", name, handlePort);
92 return true;
93 }
94}
95
96
97/*!< close the port
98return true if success
99 */
100int PosixSerialPort::closePort() {
101 close(handlePort);
102}
103
104/*!< configure the port
105return true if success
106 */
107int PosixSerialPort::configurePort(long baudRate, int byteSize, char parity, int stopBits) {
108
109 struct termios port_settings; // structure to store the port settings in
110
111 tcgetattr(handlePort, &port_settings);
112
113 switch (baudRate) {
114 case 4800:
115 cfsetispeed(&port_settings, B4800); // set baud rates
116 cfsetospeed(&port_settings, B4800);
117 break;
118
119 case 9600:
120 cfsetispeed(&port_settings, B9600); // set baud rates
121 cfsetospeed(&port_settings, B9600);
122 break;
123 case 38400:
124 cfsetispeed(&port_settings, B38400); // set baud rates
125 cfsetospeed(&port_settings, B38400);
126 break;
127 case 115200:
128 cfsetispeed(&port_settings, B115200); // set baud rates
129 cfsetospeed(&port_settings, B115200);
130 break;
131 default:
132 break;
133 }
134
135 port_settings.c_cflag &= ~PARENB; // set no parity, stop bits, data bits
136 port_settings.c_cflag &= ~CSTOPB;
137 port_settings.c_cflag &= ~CSIZE;
138 port_settings.c_cflag |= CS8;
139
140 tcsetattr(handlePort, TCSANOW, &port_settings); // apply the settings to the port
141
142}
143
144
145
146//////////////////////////////////////////////////////////////////////////
147// Read 'maxLength' bytes on the port and copy them in buffer
148// return the number of bytes read
149//////////////////////////////////////////////////////////////////////////
150int PosixSerialPort::readBuffer(char *buffer, int maxLength)
151{
152 int countread = read( handlePort,buffer,maxLength);
153 //printf("read %d of %d, data:%s\n", countread, maxLength, buffer);
154 return countread;
155}
156
157
158void PosixSerialPort::run()
159{
160 while (THREAD_ALIVE)
161 {
162 numberBytesToRead = nbBytesToRead();
163 if (numberBytesToRead > 0)
164 {
165 t_ = road_time(); // datation
166 receivedBuffer_ = new char[numberBytesToRead];
167 memset(receivedBuffer_,0,numberBytesToRead);
168 numberBytesRead = readBuffer(receivedBuffer_,numberBytesToRead);
169 processIncomingData();
170 }
171 else
172 {
173 receivedBuffer_ = NULL;
174 // todo : trouver une autre methode plus efficace que le polling et le sleep !
175 usleep(1000);
176 }
177 }
178}
179
180
181int PosixSerialPort::nbBytesToRead()
182{
183 int bytes;
184
185 ioctl(handlePort, FIONREAD, &bytes);
186
187 return bytes;
188}
189
190//////////////////////////////////////////////////////////////////////////
191/// Process the data received by the processIncomingEvent() function
192/// It may be either bytes (data) or a ring indicator signal (PPS for GPS signal)
193void PosixSerialPort::processIncomingData()
194{
195 // data frame
196 if (numberBytesRead > 0) {
197 FRAME * frame = new FRAME;
198 frame->t = t_;
199 frame->tr = 0;
200 frame->length = numberBytesRead;
201 frame->data = new char[frame->length];
202 memcpy(frame->data, receivedBuffer_, frame->length);
203
204 frameLock_.lock();
205 dataFrameList.append( frame );
206 frameLock_.unlock();
207
208 //printf(receivedBuffer_);
209 emit newDataAvailable(1);
210 delete[] receivedBuffer_;
211 receivedBuffer_ = NULL;
212 }
213
214 if (ringIndicatorDetected) {
215 ringIndicatorDetected = false;
216 FRAME * frame = new FRAME;
217 frame->t = t_;
218 frame->tr = 0;
219 frame->length = 3;
220 frame->data = new char[frame->length];
221 memcpy(frame->data, "PPS", frame->length);
222 frameLock_.lock();
223 dataFrameList.append(frame);
224 frameLock_.unlock();
225
226 emit newDataAvailable(1);
227 }
228
229 // re-initialization
230 t_ = 0;
231 numberBytesToRead = 0;
232}
Note: See TracBrowser for help on using the repository browser.