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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 73 - (hide annotations) (download)
Fri Jul 6 11:31:48 2007 UTC (16 years, 11 months ago) by torben
File size: 7073 byte(s)
Make sure the old port settings is saven in linuxOpen()


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

  ViewVC Help
Powered by ViewVC 1.1.20