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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 49 - (hide annotations) (download)
Mon Feb 5 07:06:43 2007 UTC (17 years, 4 months ago) by torben
File size: 6242 byte(s)
Test against the correct #define macro (_WINDOWS -> _MSC_VER)
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 49 #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 46 #include <iostream>
18 torben 38 #include <iomanip>
19    
20 torben 46 #define _POSIX_SOURCE 1 /* POSIX compliant source */
21 torben 47 #define BAUDRATE B9600
22 torben 46
23 torben 49 #ifndef _MSC_VER // ugly hack, else will gcc not accept this constant in openLinux()
24 torben 47 const int flags = O_RDWR | O_NOCTTY ; //| O_NONBLOCK;
25 torben 46 #endif
26    
27 torben 38 std::string writeLastError()
28     {
29 torben 49 #ifdef _MSC_VER
30 torben 38 LPVOID lpMsgBuf;
31     FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
32     NULL,
33     GetLastError(),
34     MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
35     (LPSTR) &lpMsgBuf,
36     0,
37     NULL);
38    
39     std::ostringstream out;
40     out << "Error" << lpMsgBuf;
41     return out.str();
42 torben 44 #else //linux
43 torben 46 return std::string( strerror(errno) );
44 torben 44 #endif
45 torben 38 }
46    
47    
48     CSerial::CSerial()
49     {
50     mIsopen = false;
51     }
52    
53     CSerial::CSerial(char* port, int bitrate)
54     {
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     void CSerial::open(char* port, int bitrate)
72     {
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     dcb.BaudRate = 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 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     std::cout << "opening port " << std::endl;
134     mFiledescriptor = ::open(mPortstr, flags);
135     if (mFiledescriptor < 0)
136     throw std::runtime_error( writeLastError() );
137    
138     std::cout << "port opened" << std::endl;
139     bzero(&newtio, sizeof(newtio) );
140    
141     // use a std. 8N1 config
142     newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
143     newtio.c_iflag = IGNPAR;
144     newtio.c_oflag = 0;
145    
146     /* set input mode (non-canonical, no echo,...) */
147     newtio.c_lflag = 0;
148    
149     newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
150 torben 47 newtio.c_cc[VMIN] = 0; /* blocking read until 1 chars received */
151    
152     cfmakeraw(&newtio);
153     cfsetospeed(&newtio, BAUDRATE);
154    
155 torben 46
156     tcflush(mFiledescriptor, TCIFLUSH);
157     tcsetattr(mFiledescriptor, TCSANOW, &newtio);
158    
159     std::cout << "port configured " << std::endl;
160     mIsopen = true;
161 torben 44 }
162     #endif
163    
164 torben 38 void CSerial::close()
165     {
166     if (mIsopen)
167     {
168 torben 49 #ifdef _MSC_VER
169 torben 38 while (getComstat().cbOutQue >0)
170     Sleep(5);
171     SetCommState(mComport,&mDcbRestore);
172     CloseHandle(mComport);
173 torben 44 #else // linux close()
174 torben 46 tcdrain(mFiledescriptor);
175     tcsetattr(mFiledescriptor, TCSADRAIN, &mOldtio); //restore settings, when all data is written
176     ::close(mFiledescriptor); //close()== system-call
177 torben 44 #endif
178 torben 38 mIsopen = false;
179     }
180     }
181    
182    
183 torben 47 int CSerial::readByte()
184 torben 38 {
185     unsigned char out;
186     unsigned long size;
187    
188     if (!mIsopen)
189 torben 44 throw std::runtime_error("Port not opened");
190 torben 49 #ifdef _MSC_VER
191 torben 38 ReadFile(mComport,&out,1,&size,0);
192     if (size != 1)
193     {
194     std::string error = writeLastError();
195     CloseHandle(mComport);
196     throw std::exception(error.c_str());
197     }
198 torben 44 #else //linux readByte()
199 torben 46 size = read(mFiledescriptor, &out, 1);
200 torben 47 if (size != 1)
201     {
202     std::cout << writeLastError() << std::endl;
203     return -1;
204     }
205 torben 44 #endif
206 torben 38
207 torben 46 printByte("Read", out);
208 torben 38 return out;
209     }
210    
211    
212     void CSerial::writeByte(unsigned char out)
213     {
214     unsigned long size;
215    
216 torben 47 printByte("Write", out);
217 torben 38 if (!mIsopen)
218 torben 44 throw std::runtime_error("Port not opened");
219 torben 38
220 torben 49 #ifdef _MSC_VER
221 torben 38 while (getComstat().cbOutQue >0)
222     Sleep(2);
223    
224     WriteFile(mComport,&out,1,&size, NULL);
225     if (size ==0)
226     {
227     std::string error = writeLastError();
228     CloseHandle(mComport);
229     throw std::exception(error.c_str());
230     }
231 torben 44 #else //linux writeByte()
232 torben 47 //tcdrain(mFiledescriptor);
233 torben 46 size = write(mFiledescriptor,&out,1);
234 torben 47 Sleep(50);
235     //tcdrain(mFiledescriptor);
236 torben 46 if (size != 1)
237     throw std::runtime_error(writeLastError() );
238 torben 44 #endif
239 torben 38 }
240 torben 46
241 torben 49 #ifdef _MSC_VER
242 torben 38 COMSTAT CSerial::getComstat() const
243     {
244     if (!mIsopen)
245     throw std::exception("Port not opened");
246    
247     COMSTAT stat;
248     DWORD x;
249     ClearCommError(mComport,&x,&stat);
250     return stat;
251     }
252 torben 44 #endif
253 torben 38
254     int CSerial::bytesReady() const
255     {
256 torben 49 #ifdef _MSC_VER
257 torben 38 return getComstat().cbInQue;
258 torben 44 #else
259     return 0;
260     #endif
261 torben 38 }
262    
263     int CSerial::outQueueSize() const
264     {
265 torben 49 #ifdef _MSC_VER
266 torben 38 return getComstat().cbOutQue;
267 torben 44 #else
268     return 0;
269     #endif
270 torben 38 }
271    
272 torben 46 // Debug function
273     //
274 torben 38 void CSerial::printByte(char* description, unsigned char byte)
275     {
276     std::cout << description << " : " << (int) byte << "/" << std::setw(2) << std::setfill('0') << std::hex << (int) byte << std::endl;
277     std::cout << std::dec;
278     }
279    
280 torben 46
281 torben 38 /*
282     void CSerial::writeBytes(UCVector out)
283     {
284     unsigned long bytesWritten;
285     unsigned int size = out.size();
286     unsigned char *buf = new unsigned char[size];
287    
288     for (int i=0; i<size; i++)
289     buf[i] = out[i];
290    
291     WriteFile(mComport,buf,size,&bytesWritten,NULL);
292     if (bytesWritten != size)
293     {
294     std::string error = writeLastError();
295     CloseHandle(mComport);
296     throw std::exception(error.c_str());
297     }
298     delete[] buf;
299     }
300     */
301    
302    
303     /*
304     UCVector CSerial::readBytes(int maxcount)
305     {
306     UCVector buf;
307    
308    
309    
310     return buf;
311     }
312     */

  ViewVC Help
Powered by ViewVC 1.1.20