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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 46 - (hide annotations) (download)
Sun Feb 4 23:11:02 2007 UTC (17 years, 3 months ago) by torben
File size: 6098 byte(s)
First take at making this linux-serial-thingie work...


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     #define BAUDRATE B38400
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 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     newtio.c_cc[VMIN] = 1; /* blocking read until 1 chars received */
152    
153     tcflush(mFiledescriptor, TCIFLUSH);
154     tcsetattr(mFiledescriptor, TCSANOW, &newtio);
155    
156     std::cout << "port configured " << std::endl;
157     mIsopen = true;
158 torben 44 }
159     #endif
160    
161 torben 38 void CSerial::close()
162     {
163     if (mIsopen)
164     {
165 torben 44 #ifdef _WINDOWS
166 torben 38 while (getComstat().cbOutQue >0)
167     Sleep(5);
168     SetCommState(mComport,&mDcbRestore);
169     CloseHandle(mComport);
170 torben 44 #else // linux close()
171 torben 46 tcdrain(mFiledescriptor);
172     tcsetattr(mFiledescriptor, TCSADRAIN, &mOldtio); //restore settings, when all data is written
173     ::close(mFiledescriptor); //close()== system-call
174 torben 44 #endif
175 torben 38 mIsopen = false;
176     }
177     }
178    
179    
180     unsigned char CSerial::readByte()
181     {
182     unsigned char out;
183     unsigned long size;
184    
185     if (!mIsopen)
186 torben 44 throw std::runtime_error("Port not opened");
187     #ifdef _WINDOWS
188 torben 38 ReadFile(mComport,&out,1,&size,0);
189     if (size != 1)
190     {
191     std::string error = writeLastError();
192     CloseHandle(mComport);
193     throw std::exception(error.c_str());
194     }
195 torben 44 #else //linux readByte()
196 torben 46 size = read(mFiledescriptor, &out, 1);
197     if (size != 1)
198     throw std::runtime_error( writeLastError() );
199 torben 44 #endif
200 torben 38
201 torben 46 printByte("Read", out);
202 torben 38 return out;
203     }
204    
205    
206     void CSerial::writeByte(unsigned char out)
207     {
208     unsigned long size;
209    
210 torben 44 //printByte("Write", out);
211 torben 38 if (!mIsopen)
212 torben 44 throw std::runtime_error("Port not opened");
213 torben 38
214 torben 44 #ifdef _WINDOWS
215 torben 38 while (getComstat().cbOutQue >0)
216     Sleep(2);
217    
218     WriteFile(mComport,&out,1,&size, NULL);
219     if (size ==0)
220     {
221     std::string error = writeLastError();
222     CloseHandle(mComport);
223     throw std::exception(error.c_str());
224     }
225 torben 44 #else //linux writeByte()
226 torben 46 size = write(mFiledescriptor,&out,1);
227     if (size != 1)
228     throw std::runtime_error(writeLastError() );
229 torben 44 #endif
230 torben 38 }
231 torben 46
232 torben 44 #ifdef _WINDOWS
233 torben 38 COMSTAT CSerial::getComstat() const
234     {
235     if (!mIsopen)
236     throw std::exception("Port not opened");
237    
238     COMSTAT stat;
239     DWORD x;
240     ClearCommError(mComport,&x,&stat);
241     return stat;
242     }
243 torben 44 #endif
244 torben 38
245     int CSerial::bytesReady() const
246     {
247 torben 44 #ifdef _WINDOWS
248 torben 38 return getComstat().cbInQue;
249 torben 44 #else
250     return 0;
251     #endif
252 torben 38 }
253    
254     int CSerial::outQueueSize() const
255     {
256 torben 44 #ifdef _WINDOWS
257 torben 38 return getComstat().cbOutQue;
258 torben 44 #else
259     return 0;
260     #endif
261 torben 38 }
262    
263 torben 46 // Debug function
264     //
265 torben 38 void CSerial::printByte(char* description, unsigned char byte)
266     {
267     std::cout << description << " : " << (int) byte << "/" << std::setw(2) << std::setfill('0') << std::hex << (int) byte << std::endl;
268     std::cout << std::dec;
269     }
270    
271 torben 46
272 torben 38 /*
273     void CSerial::writeBytes(UCVector out)
274     {
275     unsigned long bytesWritten;
276     unsigned int size = out.size();
277     unsigned char *buf = new unsigned char[size];
278    
279     for (int i=0; i<size; i++)
280     buf[i] = out[i];
281    
282     WriteFile(mComport,buf,size,&bytesWritten,NULL);
283     if (bytesWritten != size)
284     {
285     std::string error = writeLastError();
286     CloseHandle(mComport);
287     throw std::exception(error.c_str());
288     }
289     delete[] buf;
290     }
291     */
292    
293    
294     /*
295     UCVector CSerial::readBytes(int maxcount)
296     {
297     UCVector buf;
298    
299    
300    
301     return buf;
302     }
303     */

  ViewVC Help
Powered by ViewVC 1.1.20