/[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 55 by torben, Mon Feb 5 10:11:47 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    #ifdef _MSC_VER
248            switch( rate )
249            {
250                    case Baud300:
251                            retval = 300;
252                            break;
253                    case Baud600:
254                            retval = 600;
255                            break;
256                    case Baud1200:
257                            retval = 1200;
258                            break;
259                    case Baud2400:
260                            retval = 2400;
261                            break;
262                    case Baud4800:
263                            retval = 4800;
264                            break;
265                    case Baud9600:
266                            retval = 9600;
267                            break;
268                    case Baud19200:
269                            retval = 19200;
270                            break;
271                    case Baud38400:
272                            retval = 38400;
273                            break;
274                    case Baud57600:
275                            retval = 57600;
276                            break;
277                    case Baud115200:
278                            retval = 115200;
279                            break;                  
280            }
281    #else
282            switch (rate)
283            {
284                    case Baud300:
285                            retval = B300;
286                            break;
287                    case Baud600:
288                            retval = B600;
289                            break;
290                    case Baud1200:
291                            retval = B1200;
292                            break;
293                    case Baud2400:
294                            retval = B2400;
295                            break;
296                    case Baud4800:
297                            retval = B4800;
298                            break;
299                    case Baud9600:
300                            retval = B9600;
301                            break;
302                    case Baud19200:
303                            retval = B19200;
304                            break;
305                    case Baud38400:
306                            retval = B38400;
307                            break;
308                    case Baud57600:
309                            retval = B57600;
310                            break;
311                    case Baud115200:
312                            retval = B115200;
313                            break;
314            }
315    #endif
316    
317            return retval;
318    }
319    
320    #ifdef _MSC_VER
321  COMSTAT CSerial::getComstat() const  COMSTAT CSerial::getComstat() const
322  {  {
323          if (!mIsopen)          if (!mIsopen)
# Line 196  COMSTAT CSerial::getComstat() const Line 332  COMSTAT CSerial::getComstat() const
332    
333  int CSerial::bytesReady() const  int CSerial::bytesReady() const
334  {  {
335  #ifdef _WINDOWS  #ifdef _MSC_VER
336          return getComstat().cbInQue;          return getComstat().cbInQue;
337  #else  #else
338          return 0;          return 0;
# Line 205  int CSerial::bytesReady() const Line 341  int CSerial::bytesReady() const
341    
342  int CSerial::outQueueSize() const  int CSerial::outQueueSize() const
343  {  {
344  #ifdef _WINDOWS  #ifdef _MSC_VER
345          return getComstat().cbOutQue;          return getComstat().cbOutQue;
346  #else  #else
347          return 0;          return 0;
348  #endif  #endif
349  }  }
350    
351  /* Debug function  // Debug function
352    //
353  void CSerial::printByte(char* description, unsigned char byte)  void CSerial::printByte(char* description, unsigned char byte)
354  {  {
355          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;
356          std::cout << std::dec;          std::cout << std::dec;
357  }  }
358  */  
359    
360  /*  /*
361  void CSerial::writeBytes(UCVector out)  void CSerial::writeBytes(UCVector out)

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

  ViewVC Help
Powered by ViewVC 1.1.20