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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 47 - (show annotations) (download)
Mon Feb 5 00:48:02 2007 UTC (17 years, 3 months ago) by torben
File size: 6244 byte(s)
A little more test-code - but still far from functional

1 #ifdef _WINDOWS
2 #include "StdAfx.h"
3 #else //linux
4 #include <sys/types.h>
5 #include <sys/stat.h>
6
7 #include <unistd.h>
8 #include <errno.h>
9 #include <termios.h>
10 #include <fcntl.h>
11 #endif
12
13 #include "Serial.h"
14
15 #include <stdexcept>
16 #include <string>
17 #include <sstream>
18 #include <iostream>
19 #include <iomanip>
20
21 #define _POSIX_SOURCE 1 /* POSIX compliant source */
22 #define BAUDRATE B9600
23
24 #ifndef _WINDOWS // ugly hack, else will gcc not accept this constant in openLinux()
25 const int flags = O_RDWR | O_NOCTTY ; //| O_NONBLOCK;
26 #endif
27
28 std::string writeLastError()
29 {
30 #ifdef _WINDOWS
31 LPVOID lpMsgBuf;
32 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
33 NULL,
34 GetLastError(),
35 MAKELANGID(LANG_NEUTRAL,SUBLANG_DEFAULT),
36 (LPSTR) &lpMsgBuf,
37 0,
38 NULL);
39
40 std::ostringstream out;
41 out << "Error" << lpMsgBuf;
42 return out.str();
43 #else //linux
44 return std::string( strerror(errno) );
45 #endif
46 }
47
48
49 CSerial::CSerial()
50 {
51 mIsopen = false;
52 }
53
54 CSerial::CSerial(char* port, int bitrate)
55 {
56 mPortstr = port;
57 mBitrate = bitrate;
58 mIsopen = false;
59
60 #ifdef _WINDOWS
61 openWindows();
62 #else
63 openLinux();
64 #endif
65 }
66
67 CSerial::~CSerial(void)
68 {
69 close();
70 }
71
72 void CSerial::open(char* port, int bitrate)
73 {
74 if (mIsopen)
75 throw std::runtime_error("Port already opened");
76
77 mPortstr = port;
78 mBitrate = bitrate;
79
80 #ifdef _WINDOWS
81 openWindows();
82 #else
83 openLinux();
84 #endif
85 }
86
87 #ifdef _WINDOWS
88 void CSerial::openWindows()
89 {
90 mComport = CreateFile( mPortstr, GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
91
92 if (mComport == INVALID_HANDLE_VALUE)
93 {
94 throw std::runtime_error(writeLastError().c_str());
95 }
96
97 DCB dcb;
98 dcb.DCBlength = sizeof(DCB);
99 mDcbRestore.DCBlength = sizeof(DCB);
100
101 if (!GetCommState(mComport,&dcb) || !GetCommState(mComport,&mDcbRestore))
102 {
103 std::string error = writeLastError();
104 CloseHandle(mComport);
105 throw std::exception(error.c_str());
106 }
107
108 dcb.BaudRate = mBitrate;
109 dcb.ByteSize = 8;
110 dcb.Parity = NOPARITY;
111 dcb.StopBits = ONESTOPBIT;
112 dcb.fDtrControl = DTR_CONTROL_DISABLE;
113 dcb.fRtsControl = RTS_CONTROL_DISABLE;
114 dcb.fParity = false;
115 dcb.fDsrSensitivity = false;
116
117 if (!SetCommState(mComport,&dcb))
118 {
119 std::string error = writeLastError();
120 CloseHandle(mComport);
121 throw std::exception( error );
122 }
123
124 mIsopen = true;
125 }
126 #endif
127
128
129 #ifndef _WINDOWS
130 void CSerial::openLinux()
131 {
132 termios newtio;
133
134 std::cout << "opening port " << std::endl;
135 mFiledescriptor = ::open(mPortstr, flags);
136 if (mFiledescriptor < 0)
137 throw std::runtime_error( writeLastError() );
138
139 std::cout << "port opened" << std::endl;
140 bzero(&newtio, sizeof(newtio) );
141
142 // use a std. 8N1 config
143 newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
144 newtio.c_iflag = IGNPAR;
145 newtio.c_oflag = 0;
146
147 /* set input mode (non-canonical, no echo,...) */
148 newtio.c_lflag = 0;
149
150 newtio.c_cc[VTIME] = 0; /* inter-character timer unused */
151 newtio.c_cc[VMIN] = 0; /* blocking read until 1 chars received */
152
153 cfmakeraw(&newtio);
154 cfsetospeed(&newtio, BAUDRATE);
155
156
157 tcflush(mFiledescriptor, TCIFLUSH);
158 tcsetattr(mFiledescriptor, TCSANOW, &newtio);
159
160 std::cout << "port configured " << std::endl;
161 mIsopen = true;
162 }
163 #endif
164
165 void CSerial::close()
166 {
167 if (mIsopen)
168 {
169 #ifdef _WINDOWS
170 while (getComstat().cbOutQue >0)
171 Sleep(5);
172 SetCommState(mComport,&mDcbRestore);
173 CloseHandle(mComport);
174 #else // linux close()
175 tcdrain(mFiledescriptor);
176 tcsetattr(mFiledescriptor, TCSADRAIN, &mOldtio); //restore settings, when all data is written
177 ::close(mFiledescriptor); //close()== system-call
178 #endif
179 mIsopen = false;
180 }
181 }
182
183
184 int CSerial::readByte()
185 {
186 unsigned char out;
187 unsigned long size;
188
189 if (!mIsopen)
190 throw std::runtime_error("Port not opened");
191 #ifdef _WINDOWS
192 ReadFile(mComport,&out,1,&size,0);
193 if (size != 1)
194 {
195 std::string error = writeLastError();
196 CloseHandle(mComport);
197 throw std::exception(error.c_str());
198 }
199 #else //linux readByte()
200 size = read(mFiledescriptor, &out, 1);
201 if (size != 1)
202 {
203 std::cout << writeLastError() << std::endl;
204 return -1;
205 }
206 #endif
207
208 printByte("Read", out);
209 return out;
210 }
211
212
213 void CSerial::writeByte(unsigned char out)
214 {
215 unsigned long size;
216
217 printByte("Write", out);
218 if (!mIsopen)
219 throw std::runtime_error("Port not opened");
220
221 #ifdef _WINDOWS
222 while (getComstat().cbOutQue >0)
223 Sleep(2);
224
225 WriteFile(mComport,&out,1,&size, NULL);
226 if (size ==0)
227 {
228 std::string error = writeLastError();
229 CloseHandle(mComport);
230 throw std::exception(error.c_str());
231 }
232 #else //linux writeByte()
233 //tcdrain(mFiledescriptor);
234 size = write(mFiledescriptor,&out,1);
235 Sleep(50);
236 //tcdrain(mFiledescriptor);
237 if (size != 1)
238 throw std::runtime_error(writeLastError() );
239 #endif
240 }
241
242 #ifdef _WINDOWS
243 COMSTAT CSerial::getComstat() const
244 {
245 if (!mIsopen)
246 throw std::exception("Port not opened");
247
248 COMSTAT stat;
249 DWORD x;
250 ClearCommError(mComport,&x,&stat);
251 return stat;
252 }
253 #endif
254
255 int CSerial::bytesReady() const
256 {
257 #ifdef _WINDOWS
258 return getComstat().cbInQue;
259 #else
260 return 0;
261 #endif
262 }
263
264 int CSerial::outQueueSize() const
265 {
266 #ifdef _WINDOWS
267 return getComstat().cbOutQue;
268 #else
269 return 0;
270 #endif
271 }
272
273 // Debug function
274 //
275 void CSerial::printByte(char* description, unsigned char byte)
276 {
277 std::cout << description << " : " << (int) byte << "/" << std::setw(2) << std::setfill('0') << std::hex << (int) byte << std::endl;
278 std::cout << std::dec;
279 }
280
281
282 /*
283 void CSerial::writeBytes(UCVector out)
284 {
285 unsigned long bytesWritten;
286 unsigned int size = out.size();
287 unsigned char *buf = new unsigned char[size];
288
289 for (int i=0; i<size; i++)
290 buf[i] = out[i];
291
292 WriteFile(mComport,buf,size,&bytesWritten,NULL);
293 if (bytesWritten != size)
294 {
295 std::string error = writeLastError();
296 CloseHandle(mComport);
297 throw std::exception(error.c_str());
298 }
299 delete[] buf;
300 }
301 */
302
303
304 /*
305 UCVector CSerial::readBytes(int maxcount)
306 {
307 UCVector buf;
308
309
310
311 return buf;
312 }
313 */

  ViewVC Help
Powered by ViewVC 1.1.20