/[H7]/branches/linux-serial/Serial.cpp
ViewVC logotype

Contents of /branches/linux-serial/Serial.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 57 - (show annotations) (download)
Mon Feb 5 10:38:58 2007 UTC (17 years, 3 months ago) by torben
File size: 7037 byte(s)
More cleanup

1 #ifndef _MSC_VER //linux
2 #include <sys/types.h>
3 #include <sys/stat.h>
4 #include <unistd.h>
5 #include <errno.h>
6 #include <termios.h>
7 #include <fcntl.h>
8 #endif
9
10
11 #include <stdexcept>
12 #include <string>
13 #include <sstream>
14
15 #ifdef DEBUG
16 #include <iostream>
17 #include <iomanip>
18 #endif
19
20 #include "stdafx.h"
21 #include "Serial.h"
22
23
24 std::string writeLastError()
25 {
26 #ifdef _MSC_VER
27 LPVOID lpMsgBuf;
28 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
29 NULL,
30 GetLastError(),
31 MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
32 (LPSTR) &lpMsgBuf,
33 0,
34 NULL);
35
36 std::ostringstream out;
37 out << "Error " << lpMsgBuf;
38 return out.str();
39 #else //linux
40 return std::string( strerror(errno) );
41 #endif
42 }
43
44
45 CSerial::CSerial()
46 {
47 mIsopen = false;
48 }
49
50
51 CSerial::CSerial(char* port, Baudrate bitrate)
52 {
53 mPortstr = port;
54 mBitrate = bitrate;
55 mIsopen = false;
56
57 #ifdef _MSC_VER
58 openWindows();
59 #else
60 openLinux();
61 #endif
62 }
63
64 CSerial::~CSerial(void)
65 {
66 close();
67 }
68
69 void CSerial::open(char* port, Baudrate bitrate)
70 {
71 if (mIsopen)
72 throw std::runtime_error("Port already opened");
73
74 mPortstr = port;
75 mBitrate = bitrate;
76
77 #ifdef _MSC_VER
78 openWindows();
79 #else
80 openLinux();
81 #endif
82 }
83
84 #ifdef _MSC_VER
85 void CSerial::openWindows()
86 {
87 mComport = CreateFile( mPortstr, GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
88
89 if (mComport == INVALID_HANDLE_VALUE)
90 {
91 throw std::runtime_error(writeLastError().c_str());
92 }
93
94 DCB dcb;
95 dcb.DCBlength = sizeof(DCB);
96 mDcbRestore.DCBlength = sizeof(DCB);
97
98 if (!GetCommState(mComport,&dcb) || !GetCommState(mComport,&mDcbRestore))
99 {
100 std::string error = writeLastError();
101 CloseHandle(mComport);
102 throw std::exception(error.c_str());
103 }
104
105 dcb.BaudRate = convertBaudrate(mBitrate);
106 dcb.ByteSize = 8;
107 dcb.Parity = NOPARITY;
108 dcb.StopBits = ONESTOPBIT;
109 dcb.fDtrControl = DTR_CONTROL_DISABLE;
110 dcb.fRtsControl = RTS_CONTROL_DISABLE;
111 dcb.fParity = false;
112 dcb.fDsrSensitivity = false;
113
114 if (!SetCommState(mComport,&dcb))
115 {
116 std::string error = writeLastError();
117 CloseHandle(mComport);
118 throw std::runtime_error( error );
119 }
120
121 mIsopen = true;
122 }
123 #endif
124
125
126 #ifndef _MSC_VER
127 void CSerial::openLinux()
128 {
129 termios newtio;
130
131 mFiledescriptor = ::open(mPortstr, O_RDWR | O_NOCTTY | O_NONBLOCK);
132 if (mFiledescriptor < 0)
133 throw std::runtime_error( writeLastError() );
134
135 bzero(&newtio, sizeof(newtio) );
136
137 // use a std. 8N1 config
138 newtio.c_cflag = convertBaudrate(mBitrate) | CRTSCTS | CS8 | CLOCAL | CREAD;
139 newtio.c_iflag = IGNPAR;
140 newtio.c_oflag = 0;
141
142 // set input mode (non-canonical, no echo,...)
143 newtio.c_lflag = 0;
144
145 newtio.c_cc[VTIME] = 0; // inter-character timer unused
146 newtio.c_cc[VMIN] = 0; // blocking read until 1 chars received
147
148
149 tcflush(mFiledescriptor, TCIFLUSH);
150 tcsetattr(mFiledescriptor, TCSANOW, &newtio);
151
152 mIsopen = true;
153 }
154 #endif
155
156 void CSerial::close()
157 {
158 if (mIsopen)
159 {
160 #ifdef _MSC_VER
161 while (getComstat().cbOutQue >0)
162 Sleep(5);
163 SetCommState(mComport,&mDcbRestore);
164 CloseHandle(mComport);
165 #else // linux close()
166 tcdrain(mFiledescriptor);
167 tcsetattr(mFiledescriptor, TCSADRAIN, &mOldtio); //restore settings, when all data is written
168 ::close(mFiledescriptor); //close()== system-call
169 #endif
170 mIsopen = false;
171 }
172 }
173
174
175 int CSerial::readByte()
176 {
177 unsigned char out;
178 unsigned long size;
179
180 if (!mIsopen)
181 throw std::runtime_error("Port not opened");
182 #ifdef _MSC_VER
183 ReadFile(mComport,&out,1,&size,0);
184 if (size != 1)
185 {
186 std::string error = writeLastError();
187 CloseHandle(mComport);
188 throw std::exception(error.c_str());
189 }
190 #else //linux readByte()
191 size = read(mFiledescriptor, &out, 1);
192 if (size != 1)
193 {
194 return -1;
195 }
196 #endif
197
198 printByte("Read", out);
199 return out;
200 }
201
202
203 void CSerial::writeByte(unsigned char out)
204 {
205 unsigned long size;
206
207 printByte("Write", out);
208 if (!mIsopen)
209 throw std::runtime_error("Port not opened");
210
211 #ifdef _MSC_VER
212 while (getComstat().cbOutQue >0)
213 Sleep(2);
214
215 WriteFile(mComport,&out,1,&size, NULL);
216 if (size ==0)
217 {
218 std::string error = writeLastError();
219 CloseHandle(mComport);
220 throw std::exception(error.c_str());
221 }
222 #else //linux writeByte()
223 //tcdrain(mFiledescriptor);
224 size = write(mFiledescriptor,&out,1);
225 Sleep(50);
226 //tcdrain(mFiledescriptor);
227 if (size != 1)
228 throw std::runtime_error(writeLastError() );
229 #endif
230 }
231
232 int CSerial::convertBaudrate(Baudrate rate)
233 {
234 int retval=0;
235 #ifdef _MSC_VER
236 switch( rate )
237 {
238 case Baud300:
239 retval = 300;
240 break;
241 case Baud600:
242 retval = 600;
243 break;
244 case Baud1200:
245 retval = 1200;
246 break;
247 case Baud2400:
248 retval = 2400;
249 break;
250 case Baud4800:
251 retval = 4800;
252 break;
253 case Baud9600:
254 retval = 9600;
255 break;
256 case Baud19200:
257 retval = 19200;
258 break;
259 case Baud38400:
260 retval = 38400;
261 break;
262 case Baud57600:
263 retval = 57600;
264 break;
265 case Baud115200:
266 retval = 115200;
267 break;
268 }
269 #else
270 switch (rate)
271 {
272 case Baud300:
273 retval = B300;
274 break;
275 case Baud600:
276 retval = B600;
277 break;
278 case Baud1200:
279 retval = B1200;
280 break;
281 case Baud2400:
282 retval = B2400;
283 break;
284 case Baud4800:
285 retval = B4800;
286 break;
287 case Baud9600:
288 retval = B9600;
289 break;
290 case Baud19200:
291 retval = B19200;
292 break;
293 case Baud38400:
294 retval = B38400;
295 break;
296 case Baud57600:
297 retval = B57600;
298 break;
299 case Baud115200:
300 retval = B115200;
301 break;
302 }
303 #endif
304
305 return retval;
306 }
307
308 #ifdef _MSC_VER
309 COMSTAT CSerial::getComstat() const
310 {
311 if (!mIsopen)
312 throw std::exception("Port not opened");
313
314 COMSTAT stat;
315 DWORD x;
316 ClearCommError(mComport,&x,&stat);
317 return stat;
318 }
319 #endif
320
321 int CSerial::bytesReady() const
322 {
323 #ifdef _MSC_VER
324 return getComstat().cbInQue;
325 #else
326 return 0;
327 #endif
328 }
329
330 int CSerial::outQueueSize() const
331 {
332 #ifdef _MSC_VER
333 return getComstat().cbOutQue;
334 #else
335 return 0;
336 #endif
337 }
338
339 // Debug function
340 //
341 void CSerial::printByte(char* description, unsigned char byte)
342 {
343 #ifdef DEBUG
344 std::cout << description << " : " << (int) byte << "/" << std::setw(2) << std::setfill('0') << std::hex << (int) byte << std::endl;
345 std::cout << std::dec;
346 #endif
347 }
348
349
350 /*
351 void CSerial::writeBytes(UCVector out)
352 {
353 unsigned long bytesWritten;
354 unsigned int size = out.size();
355 unsigned char *buf = new unsigned char[size];
356
357 for (int i=0; i<size; i++)
358 buf[i] = out[i];
359
360 WriteFile(mComport,buf,size,&bytesWritten,NULL);
361 if (bytesWritten != size)
362 {
363 std::string error = writeLastError();
364 CloseHandle(mComport);
365 throw std::exception(error.c_str());
366 }
367 delete[] buf;
368 }
369 */
370
371
372 /*
373 UCVector CSerial::readBytes(int maxcount)
374 {
375 UCVector buf;
376
377
378
379 return buf;
380 }
381 */

  ViewVC Help
Powered by ViewVC 1.1.20