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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.20