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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 56 - (hide annotations) (download)
Mon Feb 5 10:24:24 2007 UTC (17 years, 3 months ago) by torben
File size: 7236 byte(s)
Cleanup ....


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

  ViewVC Help
Powered by ViewVC 1.1.20