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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 61 - (hide annotations) (download)
Tue Feb 6 09:09:32 2007 UTC (17 years, 3 months ago) by torben
File size: 7031 byte(s)
Don't use hardware flow control

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     bzero(&newtio, sizeof(newtio) );
138    
139     // use a std. 8N1 config
140 torben 61 newtio.c_cflag = convertBaudrate(mBitrate) | CS8 | CLOCAL | CREAD;
141 torben 46 newtio.c_iflag = IGNPAR;
142     newtio.c_oflag = 0;
143    
144 torben 54 // set input mode (non-canonical, no echo,...)
145 torben 46 newtio.c_lflag = 0;
146    
147 torben 54 newtio.c_cc[VTIME] = 0; // inter-character timer unused
148     newtio.c_cc[VMIN] = 0; // blocking read until 1 chars received
149    
150 torben 46
151     tcflush(mFiledescriptor, TCIFLUSH);
152     tcsetattr(mFiledescriptor, TCSANOW, &newtio);
153    
154     mIsopen = true;
155 torben 44 }
156     #endif
157    
158 torben 38 void CSerial::close()
159     {
160     if (mIsopen)
161     {
162 torben 49 #ifdef _MSC_VER
163 torben 38 while (getComstat().cbOutQue >0)
164     Sleep(5);
165     SetCommState(mComport,&mDcbRestore);
166     CloseHandle(mComport);
167 torben 44 #else // linux close()
168 torben 46 tcdrain(mFiledescriptor);
169     tcsetattr(mFiledescriptor, TCSADRAIN, &mOldtio); //restore settings, when all data is written
170     ::close(mFiledescriptor); //close()== system-call
171 torben 44 #endif
172 torben 38 mIsopen = false;
173     }
174     }
175    
176    
177 torben 47 int CSerial::readByte()
178 torben 38 {
179     unsigned char out;
180     unsigned long size;
181    
182     if (!mIsopen)
183 torben 44 throw std::runtime_error("Port not opened");
184 torben 49 #ifdef _MSC_VER
185 torben 38 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 torben 44 #else //linux readByte()
193 torben 46 size = read(mFiledescriptor, &out, 1);
194 torben 47 if (size != 1)
195     {
196     return -1;
197     }
198 torben 44 #endif
199 torben 38
200 torben 46 printByte("Read", out);
201 torben 38 return out;
202     }
203    
204    
205     void CSerial::writeByte(unsigned char out)
206     {
207     unsigned long size;
208    
209 torben 47 printByte("Write", out);
210 torben 38 if (!mIsopen)
211 torben 44 throw std::runtime_error("Port not opened");
212 torben 38
213 torben 49 #ifdef _MSC_VER
214 torben 38 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 torben 44 #else //linux writeByte()
225 torben 47 //tcdrain(mFiledescriptor);
226 torben 46 size = write(mFiledescriptor,&out,1);
227 torben 47 Sleep(50);
228     //tcdrain(mFiledescriptor);
229 torben 46 if (size != 1)
230     throw std::runtime_error(writeLastError() );
231 torben 44 #endif
232 torben 38 }
233 torben 46
234 torben 54 int CSerial::convertBaudrate(Baudrate rate)
235     {
236     int retval=0;
237 torben 49 #ifdef _MSC_VER
238 torben 54 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 torben 55 case Baud115200:
268 torben 54 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 torben 38 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 torben 44 #endif
322 torben 38
323     int CSerial::bytesReady() const
324     {
325 torben 49 #ifdef _MSC_VER
326 torben 38 return getComstat().cbInQue;
327 torben 44 #else
328     return 0;
329     #endif
330 torben 38 }
331    
332     int CSerial::outQueueSize() const
333     {
334 torben 49 #ifdef _MSC_VER
335 torben 38 return getComstat().cbOutQue;
336 torben 44 #else
337     return 0;
338     #endif
339 torben 38 }
340    
341 torben 46 // Debug function
342     //
343 torben 38 void CSerial::printByte(char* description, unsigned char byte)
344     {
345 torben 56 #ifdef DEBUG
346 torben 38 std::cout << description << " : " << (int) byte << "/" << std::setw(2) << std::setfill('0') << std::hex << (int) byte << std::endl;
347     std::cout << std::dec;
348 torben 56 #endif
349 torben 38 }
350    
351 torben 46
352 torben 38 /*
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