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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

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