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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 51 - (show annotations) (download)
Mon Feb 5 07:16:59 2007 UTC (17 years, 3 months ago) by torben
File size: 6238 byte(s)
At last it compiles on both platforms.


1 #ifndef _MSC_VER //linux
2 #include <sys/types.h>
3 #include <sys/stat.h>
4
5 #include <unistd.h>
6 #include <errno.h>
7 #include <termios.h>
8 #include <fcntl.h>
9 #endif
10
11 #include "stdafx.h"
12 #include "Serial.h"
13
14 #include <stdexcept>
15 #include <string>
16 #include <sstream>
17 #include <iostream>
18 #include <iomanip>
19
20 #define _POSIX_SOURCE 1 /* POSIX compliant source */
21 #define BAUDRATE B9600
22
23 #ifndef _MSC_VER // ugly hack, else will gcc not accept this constant in openLinux()
24 const int flags = O_RDWR | O_NOCTTY | O_NONBLOCK;
25 #endif
26
27 std::string writeLastError()
28 {
29 #ifdef _MSC_VER
30 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 #else //linux
43 return std::string( strerror(errno) );
44 #endif
45 }
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 #ifdef _MSC_VER
60 openWindows();
61 #else
62 openLinux();
63 #endif
64 }
65
66 CSerial::~CSerial(void)
67 {
68 close();
69 }
70
71 void CSerial::open(char* port, int bitrate)
72 {
73 if (mIsopen)
74 throw std::runtime_error("Port already opened");
75
76 mPortstr = port;
77 mBitrate = bitrate;
78
79 #ifdef _MSC_VER
80 openWindows();
81 #else
82 openLinux();
83 #endif
84 }
85
86 #ifdef _MSC_VER
87 void CSerial::openWindows()
88 {
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 throw std::runtime_error(writeLastError().c_str());
94 }
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 throw std::runtime_error( error );
121 }
122
123 mIsopen = true;
124 }
125 #endif
126
127
128 #ifndef _MSC_VER
129 void CSerial::openLinux()
130 {
131 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 newtio.c_cc[VMIN] = 0; /* blocking read until 1 chars received */
151
152 cfmakeraw(&newtio);
153 cfsetospeed(&newtio, BAUDRATE);
154
155
156 tcflush(mFiledescriptor, TCIFLUSH);
157 tcsetattr(mFiledescriptor, TCSANOW, &newtio);
158
159 std::cout << "port configured " << std::endl;
160 mIsopen = true;
161 }
162 #endif
163
164 void CSerial::close()
165 {
166 if (mIsopen)
167 {
168 #ifdef _MSC_VER
169 while (getComstat().cbOutQue >0)
170 Sleep(5);
171 SetCommState(mComport,&mDcbRestore);
172 CloseHandle(mComport);
173 #else // linux close()
174 tcdrain(mFiledescriptor);
175 tcsetattr(mFiledescriptor, TCSADRAIN, &mOldtio); //restore settings, when all data is written
176 ::close(mFiledescriptor); //close()== system-call
177 #endif
178 mIsopen = false;
179 }
180 }
181
182
183 int CSerial::readByte()
184 {
185 unsigned char out;
186 unsigned long size;
187
188 if (!mIsopen)
189 throw std::runtime_error("Port not opened");
190 #ifdef _MSC_VER
191 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 #else //linux readByte()
199 size = read(mFiledescriptor, &out, 1);
200 if (size != 1)
201 {
202 std::cout << writeLastError() << std::endl;
203 return -1;
204 }
205 #endif
206
207 printByte("Read", out);
208 return out;
209 }
210
211
212 void CSerial::writeByte(unsigned char out)
213 {
214 unsigned long size;
215
216 printByte("Write", out);
217 if (!mIsopen)
218 throw std::runtime_error("Port not opened");
219
220 #ifdef _MSC_VER
221 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 #else //linux writeByte()
232 //tcdrain(mFiledescriptor);
233 size = write(mFiledescriptor,&out,1);
234 Sleep(50);
235 //tcdrain(mFiledescriptor);
236 if (size != 1)
237 throw std::runtime_error(writeLastError() );
238 #endif
239 }
240
241 #ifdef _MSC_VER
242 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 #endif
253
254 int CSerial::bytesReady() const
255 {
256 #ifdef _MSC_VER
257 return getComstat().cbInQue;
258 #else
259 return 0;
260 #endif
261 }
262
263 int CSerial::outQueueSize() const
264 {
265 #ifdef _MSC_VER
266 return getComstat().cbOutQue;
267 #else
268 return 0;
269 #endif
270 }
271
272 // Debug function
273 //
274 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
281 /*
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