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

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

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 44 by torben, Sun Feb 4 21:22:44 2007 UTC revision 54 by torben, Mon Feb 5 10:10:18 2007 UTC
# Line 1  Line 1 
1  #ifdef _WINDOWS  #ifndef _MSC_VER //linux
2  #include "StdAfx.h"  #include <sys/types.h>
3  #else //linux  #include <sys/stat.h>
4    
5    #include <unistd.h>
6  #include <errno.h>  #include <errno.h>
7    #include <termios.h>
8    #include <fcntl.h>
9  #endif  #endif
10    
11    #include "stdafx.h"
12  #include "Serial.h"  #include "Serial.h"
13    
14  #include <stdexcept>  #include <stdexcept>
15  #include <string>  #include <string>
16  #include <sstream>  #include <sstream>
17    #include <iostream>
18  #include <iomanip>  #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()  std::string writeLastError()
28  {  {
29  #ifdef _WINDOWS  #ifdef _MSC_VER
30          LPVOID lpMsgBuf;          LPVOID lpMsgBuf;
31          FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,          FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER|FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
32                          NULL,                          NULL,
# Line 27  std::string writeLastError() Line 40  std::string writeLastError()
40          out << "Error" << lpMsgBuf;          out << "Error" << lpMsgBuf;
41          return out.str();          return out.str();
42  #else //linux  #else //linux
43          char message[256];          return std::string( strerror(errno) );
         strerror_r(errno, message, 255);  
         return std::string(message);  
44  #endif  #endif
45  }  }
46    
# Line 39  CSerial::CSerial() Line 50  CSerial::CSerial()
50          mIsopen = false;          mIsopen = false;
51  }  }
52    
53  CSerial::CSerial(char* port, int bitrate)  
54    CSerial::CSerial(char* port, Baudrate bitrate)
55  {  {
56          mPortstr = port;          mPortstr = port;
57          mBitrate = bitrate;          mBitrate = bitrate;
58          mIsopen = false;          mIsopen = false;
59    
60  #ifdef _WINDOWS  #ifdef _MSC_VER
61          openWindows();          openWindows();
62  #else  #else
63          openLinux();          openLinux();
# Line 57  CSerial::~CSerial(void) Line 69  CSerial::~CSerial(void)
69          close();          close();
70  }  }
71    
72  void CSerial::open(char* port, int bitrate)  void CSerial::open(char* port, Baudrate bitrate)
73  {  {
74          if (mIsopen)          if (mIsopen)
75                  throw std::runtime_error("Port already opened");                  throw std::runtime_error("Port already opened");
# Line 65  void CSerial::open(char* port, int bitra Line 77  void CSerial::open(char* port, int bitra
77          mPortstr = port;          mPortstr = port;
78          mBitrate = bitrate;          mBitrate = bitrate;
79                    
80  #ifdef _WINDOWS  #ifdef _MSC_VER
81          openWindows();          openWindows();
82  #else  #else
83          openLinux();          openLinux();
84  #endif  #endif
85  }  }
86    
87  #ifdef _WINDOWS  #ifdef _MSC_VER
88  void CSerial::openWindows()  void CSerial::openWindows()
89  {  {
90          mComport = CreateFile( mPortstr, GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);          mComport = CreateFile( mPortstr, GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,0);
# Line 93  void CSerial::openWindows() Line 105  void CSerial::openWindows()
105                  throw std::exception(error.c_str());                  throw std::exception(error.c_str());
106          }          }
107    
108          dcb.BaudRate = mBitrate;          dcb.BaudRate = convertBaudrate(mBitrate);
109          dcb.ByteSize = 8;          dcb.ByteSize = 8;
110          dcb.Parity = NOPARITY;          dcb.Parity = NOPARITY;
111          dcb.StopBits = ONESTOPBIT;          dcb.StopBits = ONESTOPBIT;
# Line 106  void CSerial::openWindows() Line 118  void CSerial::openWindows()
118          {          {
119                  std::string error = writeLastError();                  std::string error = writeLastError();
120                  CloseHandle(mComport);                  CloseHandle(mComport);
121                  throw std::exception(error.c_str());                  throw std::runtime_error( error );
122          }          }
123    
124          mIsopen = true;          mIsopen = true;
# Line 114  void CSerial::openWindows() Line 126  void CSerial::openWindows()
126  #endif  #endif
127    
128    
129  #ifndef _WINDOWS  #ifndef _MSC_VER
130  void CSerial::openLinux()  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 = convertBaudrate(mBitrate) | 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    
154    /*      cfmakeraw(&newtio);
155            cfsetospeed(&newtio, B9600 );
156            cfsetispeed(&newtio, B9600 );
157    */      
158                                            
159            tcflush(mFiledescriptor, TCIFLUSH);
160            tcsetattr(mFiledescriptor, TCSANOW, &newtio);
161            
162            std::cout << "port configured " << std::endl;
163            mIsopen = true;
164  }  }
165  #endif  #endif
166    
# Line 124  void CSerial::close() Line 168  void CSerial::close()
168  {  {
169          if (mIsopen)          if (mIsopen)
170          {          {
171  #ifdef _WINDOWS  #ifdef _MSC_VER
172                  while (getComstat().cbOutQue >0)                  while (getComstat().cbOutQue >0)
173                          Sleep(5);                          Sleep(5);
174                  SetCommState(mComport,&mDcbRestore);                  SetCommState(mComport,&mDcbRestore);
175                  CloseHandle(mComport);                  CloseHandle(mComport);
176  #else // linux close()  #else // linux close()
177                    tcdrain(mFiledescriptor);
178                    tcsetattr(mFiledescriptor, TCSADRAIN, &mOldtio); //restore settings, when all data is written
179                    ::close(mFiledescriptor); //close()== system-call
180  #endif  #endif
181                  mIsopen = false;                  mIsopen = false;
182          }          }
183  }  }
184    
185    
186  unsigned char CSerial::readByte()  int CSerial::readByte()
187  {  {
188          unsigned char out;          unsigned char out;
189          unsigned long size;          unsigned long size;
190    
191          if (!mIsopen)          if (!mIsopen)
192                  throw std::runtime_error("Port not opened");                  throw std::runtime_error("Port not opened");
193  #ifdef _WINDOWS  #ifdef _MSC_VER
194          ReadFile(mComport,&out,1,&size,0);          ReadFile(mComport,&out,1,&size,0);
195          if (size != 1)          if (size != 1)
196          {          {
# Line 152  unsigned char CSerial::readByte() Line 199  unsigned char CSerial::readByte()
199                  throw std::exception(error.c_str());                  throw std::exception(error.c_str());
200          }          }
201  #else //linux readByte()  #else //linux readByte()
202            size = read(mFiledescriptor, &out, 1);
203            if (size != 1)
204            {
205                    //std::cout << writeLastError() << std::endl;
206                    return -1;
207            }
208  #endif  #endif
209    
210          //printByte("Read", out);          printByte("Read", out);
211          return out;          return out;
212  }  }
213    
# Line 163  void CSerial::writeByte(unsigned char ou Line 216  void CSerial::writeByte(unsigned char ou
216  {  {
217          unsigned long size;          unsigned long size;
218    
219          //printByte("Write", out);          printByte("Write", out);
220          if (!mIsopen)          if (!mIsopen)
221                  throw std::runtime_error("Port not opened");                  throw std::runtime_error("Port not opened");
222    
223  #ifdef _WINDOWS  #ifdef _MSC_VER
224          while (getComstat().cbOutQue >0)          while (getComstat().cbOutQue >0)
225                  Sleep(2);                  Sleep(2);
226    
# Line 179  void CSerial::writeByte(unsigned char ou Line 232  void CSerial::writeByte(unsigned char ou
232                  throw std::exception(error.c_str());                  throw std::exception(error.c_str());
233          }          }
234  #else //linux writeByte()  #else //linux writeByte()
235            //tcdrain(mFiledescriptor);
236            size = write(mFiledescriptor,&out,1);
237            Sleep(50);
238            //tcdrain(mFiledescriptor);
239            if (size != 1)
240                    throw std::runtime_error(writeLastError() );
241  #endif  #endif
242  }  }
243  #ifdef _WINDOWS  
244    int CSerial::convertBaudrate(Baudrate rate)
245    {
246            int retval=0;
247            std::cout << "Rate:" << rate << std::endl;
248    #ifdef _MSC_VER
249            switch( rate )
250            {
251                    case Baud300:
252                            retval = 300;
253                            break;
254                    case Baud600:
255                            retval = 600;
256                            break;
257                    case Baud1200:
258                            retval = 1200;
259                            break;
260                    case Baud2400:
261                            retval = 2400;
262                            break;
263                    case Baud4800:
264                            retval = 4800;
265                            break;
266                    case Baud9600:
267                            retval = 9600;
268                            break;
269                    case Baud19200:
270                            retval = 19200;
271                            break;
272                    case Baud38400:
273                            retval = 38400;
274                            break;
275                    case Baud57600:
276                            retval = 57600;
277                            break;
278                    case Baud11520:
279                            retval = 115200;
280                            break;                  
281            }
282    #else
283            switch (rate)
284            {
285                    case Baud300:
286                            retval = B300;
287                            break;
288                    case Baud600:
289                            retval = B600;
290                            break;
291                    case Baud1200:
292                            retval = B1200;
293                            break;
294                    case Baud2400:
295                            retval = B2400;
296                            break;
297                    case Baud4800:
298                            retval = B4800;
299                            break;
300                    case Baud9600:
301                            retval = B9600;
302                            break;
303                    case Baud19200:
304                            retval = B19200;
305                            break;
306                    case Baud38400:
307                            retval = B38400;
308                            break;
309                    case Baud57600:
310                            retval = B57600;
311                            break;
312                    case Baud115200:
313                            retval = B115200;
314                            break;
315            }
316    #endif
317    
318            std::cout << "Rate: " << retval << "/" << B9600 << std::endl;
319            return retval;
320    }
321    
322    #ifdef _MSC_VER
323  COMSTAT CSerial::getComstat() const  COMSTAT CSerial::getComstat() const
324  {  {
325          if (!mIsopen)          if (!mIsopen)
# Line 196  COMSTAT CSerial::getComstat() const Line 334  COMSTAT CSerial::getComstat() const
334    
335  int CSerial::bytesReady() const  int CSerial::bytesReady() const
336  {  {
337  #ifdef _WINDOWS  #ifdef _MSC_VER
338          return getComstat().cbInQue;          return getComstat().cbInQue;
339  #else  #else
340          return 0;          return 0;
# Line 205  int CSerial::bytesReady() const Line 343  int CSerial::bytesReady() const
343    
344  int CSerial::outQueueSize() const  int CSerial::outQueueSize() const
345  {  {
346  #ifdef _WINDOWS  #ifdef _MSC_VER
347          return getComstat().cbOutQue;          return getComstat().cbOutQue;
348  #else  #else
349          return 0;          return 0;
350  #endif  #endif
351  }  }
352    
353  /* Debug function  // Debug function
354    //
355  void CSerial::printByte(char* description, unsigned char byte)  void CSerial::printByte(char* description, unsigned char byte)
356  {  {
357          std::cout << description << " : " <<  (int) byte << "/" << std::setw(2) << std::setfill('0') << std::hex << (int) byte << std::endl;          std::cout << description << " : " <<  (int) byte << "/" << std::setw(2) << std::setfill('0') << std::hex << (int) byte << std::endl;
358          std::cout << std::dec;          std::cout << std::dec;
359  }  }
360  */  
361    
362  /*  /*
363  void CSerial::writeBytes(UCVector out)  void CSerial::writeBytes(UCVector out)

Legend:
Removed from v.44  
changed lines
  Added in v.54

  ViewVC Help
Powered by ViewVC 1.1.20