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

Last change on this file since 127 was 99, checked in by nguyenhu, 9 years ago

compilation under linux with 0.2.X framework

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