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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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    
11 torben 44 #include <stdexcept>
12 torben 38 #include <string>
13     #include <sstream>
14 torben 56
15     #ifdef DEBUG
16 torben 46 #include <iostream>
17 torben 38 #include <iomanip>
18 torben 56 #endif
19 torben 38
20 torben 57 #include "stdafx.h"
21     #include "Serial.h"
22 torben 46
23    
24 torben 38 std::string writeLastError()
25     {
26 torben 49 #ifdef _MSC_VER
27 torben 38 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 torben 57 out << "Error " << lpMsgBuf;
38 torben 38 return out.str();
39 torben 44 #else //linux
40 torben 46 return std::string( strerror(errno) );
41 torben 44 #endif
42 torben 38 }
43    
44    
45     CSerial::CSerial()
46     {
47     mIsopen = false;
48     }
49    
50 torben 54
51     CSerial::CSerial(char* port, Baudrate bitrate)
52 torben 38 {
53     mPortstr = port;
54     mBitrate = bitrate;
55     mIsopen = false;
56    
57 torben 49 #ifdef _MSC_VER
58 torben 44 openWindows();
59     #else
60     openLinux();
61     #endif
62 torben 38 }
63    
64     CSerial::~CSerial(void)
65     {
66     close();
67     }
68    
69 torben 54 void CSerial::open(char* port, Baudrate bitrate)
70 torben 38 {
71     if (mIsopen)
72 torben 44 throw std::runtime_error("Port already opened");
73 torben 38
74     mPortstr = port;
75     mBitrate = bitrate;
76 torben 44
77 torben 49 #ifdef _MSC_VER
78 torben 44 openWindows();
79     #else
80     openLinux();
81     #endif
82 torben 38 }
83    
84 torben 49 #ifdef _MSC_VER
85 torben 44 void CSerial::openWindows()
86 torben 38 {
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 torben 44 throw std::runtime_error(writeLastError().c_str());
92 torben 38 }
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 torben 54 dcb.BaudRate = convertBaudrate(mBitrate);
106 torben 38 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 torben 49 throw std::runtime_error( error );
119 torben 38 }
120    
121     mIsopen = true;
122     }
123 torben 44 #endif
124 torben 38
125 torben 44
126 torben 49 #ifndef _MSC_VER
127 torben 44 void CSerial::openLinux()
128     {
129 torben 46 termios newtio;
130    
131 torben 57 mFiledescriptor = ::open(mPortstr, O_RDWR | O_NOCTTY | O_NONBLOCK);
132 torben 46 if (mFiledescriptor < 0)
133     throw std::runtime_error( writeLastError() );
134    
135     bzero(&newtio, sizeof(newtio) );
136    
137     // use a std. 8N1 config
138 torben 54 newtio.c_cflag = convertBaudrate(mBitrate) | CRTSCTS | CS8 | CLOCAL | CREAD;
139 torben 46 newtio.c_iflag = IGNPAR;
140     newtio.c_oflag = 0;
141    
142 torben 54 // set input mode (non-canonical, no echo,...)
143 torben 46 newtio.c_lflag = 0;
144    
145 torben 54 newtio.c_cc[VTIME] = 0; // inter-character timer unused
146     newtio.c_cc[VMIN] = 0; // blocking read until 1 chars received
147    
148 torben 46
149     tcflush(mFiledescriptor, TCIFLUSH);
150     tcsetattr(mFiledescriptor, TCSANOW, &newtio);
151    
152     mIsopen = true;
153 torben 44 }
154     #endif
155    
156 torben 38 void CSerial::close()
157     {
158     if (mIsopen)
159     {
160 torben 49 #ifdef _MSC_VER
161 torben 38 while (getComstat().cbOutQue >0)
162     Sleep(5);
163     SetCommState(mComport,&mDcbRestore);
164     CloseHandle(mComport);
165 torben 44 #else // linux close()
166 torben 46 tcdrain(mFiledescriptor);
167     tcsetattr(mFiledescriptor, TCSADRAIN, &mOldtio); //restore settings, when all data is written
168     ::close(mFiledescriptor); //close()== system-call
169 torben 44 #endif
170 torben 38 mIsopen = false;
171     }
172     }
173    
174    
175 torben 47 int CSerial::readByte()
176 torben 38 {
177     unsigned char out;
178     unsigned long size;
179    
180     if (!mIsopen)
181 torben 44 throw std::runtime_error("Port not opened");
182 torben 49 #ifdef _MSC_VER
183 torben 38 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 torben 44 #else //linux readByte()
191 torben 46 size = read(mFiledescriptor, &out, 1);
192 torben 47 if (size != 1)
193     {
194     return -1;
195     }
196 torben 44 #endif
197 torben 38
198 torben 46 printByte("Read", out);
199 torben 38 return out;
200     }
201    
202    
203     void CSerial::writeByte(unsigned char out)
204     {
205     unsigned long size;
206    
207 torben 47 printByte("Write", out);
208 torben 38 if (!mIsopen)
209 torben 44 throw std::runtime_error("Port not opened");
210 torben 38
211 torben 49 #ifdef _MSC_VER
212 torben 38 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 torben 44 #else //linux writeByte()
223 torben 47 //tcdrain(mFiledescriptor);
224 torben 46 size = write(mFiledescriptor,&out,1);
225 torben 47 Sleep(50);
226     //tcdrain(mFiledescriptor);
227 torben 46 if (size != 1)
228     throw std::runtime_error(writeLastError() );
229 torben 44 #endif
230 torben 38 }
231 torben 46
232 torben 54 int CSerial::convertBaudrate(Baudrate rate)
233     {
234     int retval=0;
235 torben 49 #ifdef _MSC_VER
236 torben 54 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 torben 55 case Baud115200:
266 torben 54 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 torben 38 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 torben 44 #endif
320 torben 38
321     int CSerial::bytesReady() const
322     {
323 torben 49 #ifdef _MSC_VER
324 torben 38 return getComstat().cbInQue;
325 torben 44 #else
326     return 0;
327     #endif
328 torben 38 }
329    
330     int CSerial::outQueueSize() const
331     {
332 torben 49 #ifdef _MSC_VER
333 torben 38 return getComstat().cbOutQue;
334 torben 44 #else
335     return 0;
336     #endif
337 torben 38 }
338    
339 torben 46 // Debug function
340     //
341 torben 38 void CSerial::printByte(char* description, unsigned char byte)
342     {
343 torben 56 #ifdef DEBUG
344 torben 38 std::cout << description << " : " << (int) byte << "/" << std::setw(2) << std::setfill('0') << std::hex << (int) byte << std::endl;
345     std::cout << std::dec;
346 torben 56 #endif
347 torben 38 }
348    
349 torben 46
350 torben 38 /*
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