/[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 76 by torben, Wed Jun 4 13:06:09 2008 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    #include <unistd.h>
5  #include <errno.h>  #include <errno.h>
6    #include <termios.h>
7    #include <fcntl.h>
8  #endif  #endif
9    
10  #include "Serial.h"  #include "Serial.h"
# Line 9  Line 12 
12  #include <stdexcept>  #include <stdexcept>
13  #include <string>  #include <string>
14  #include <sstream>  #include <sstream>
15    
16    
17    #ifdef DEBUG
18    #include <iostream>
19  #include <iomanip>  #include <iomanip>
20    #endif
21    
22    
23    
24    
25  std::string writeLastError()  std::string writeLastError()
26  {  {
27  #ifdef _WINDOWS  #ifdef _MSC_VER
28          LPVOID lpMsgBuf;          LPVOID lpMsgBuf;
29          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,
30                          NULL,                          NULL,
# Line 24  std::string writeLastError() Line 35  std::string writeLastError()
35                          NULL);                          NULL);
36    
37          std::ostringstream out;          std::ostringstream out;
38          out << "Error" << lpMsgBuf;          out << "Error " << lpMsgBuf;
39          return out.str();          return out.str();
40  #else //linux  #else //linux
41          char message[256];          return std::string( strerror(errno) );
         strerror_r(errno, message, 255);  
         return std::string(message);  
42  #endif  #endif
43  }  }
44    
# Line 39  CSerial::CSerial() Line 48  CSerial::CSerial()
48          mIsopen = false;          mIsopen = false;
49  }  }
50    
51  CSerial::CSerial(char* port, int bitrate)  
52    CSerial::CSerial(char* port, Baudrate bitrate)
53  {  {
54          mPortstr = port;          mPortstr = port;
55          mBitrate = bitrate;          mBitrate = bitrate;
56          mIsopen = false;          mIsopen = false;
57    
58  #ifdef _WINDOWS  #ifdef _MSC_VER
59          openWindows();          openWindows();
60  #else  #else
61          openLinux();          openLinux();
# Line 57  CSerial::~CSerial(void) Line 67  CSerial::~CSerial(void)
67          close();          close();
68  }  }
69    
70  void CSerial::open(char* port, int bitrate)  void CSerial::open(char* port, Baudrate bitrate)
71  {  {
72          if (mIsopen)          if (mIsopen)
73                  throw std::runtime_error("Port already opened");                  throw std::runtime_error("Port already opened");
# Line 65  void CSerial::open(char* port, int bitra Line 75  void CSerial::open(char* port, int bitra
75          mPortstr = port;          mPortstr = port;
76          mBitrate = bitrate;          mBitrate = bitrate;
77                    
78  #ifdef _WINDOWS  #ifdef _MSC_VER
79          openWindows();          openWindows();
80  #else  #else
81          openLinux();          openLinux();
82  #endif  #endif
83  }  }
84    
85  #ifdef _WINDOWS  #ifdef _MSC_VER
86  void CSerial::openWindows()  void CSerial::openWindows()
87  {  {
88          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 103  void CSerial::openWindows()
103                  throw std::exception(error.c_str());                  throw std::exception(error.c_str());
104          }          }
105    
106          dcb.BaudRate = mBitrate;          dcb.BaudRate = convertBaudrate(mBitrate);
107          dcb.ByteSize = 8;          dcb.ByteSize = 8;
108          dcb.Parity = NOPARITY;          dcb.Parity = NOPARITY;
109          dcb.StopBits = ONESTOPBIT;          dcb.StopBits = ONESTOPBIT;
# Line 106  void CSerial::openWindows() Line 116  void CSerial::openWindows()
116          {          {
117                  std::string error = writeLastError();                  std::string error = writeLastError();
118                  CloseHandle(mComport);                  CloseHandle(mComport);
119                  throw std::exception(error.c_str());                  throw std::runtime_error( error );
120          }          }
121    
122          mIsopen = true;          mIsopen = true;
# Line 114  void CSerial::openWindows() Line 124  void CSerial::openWindows()
124  #endif  #endif
125    
126    
127  #ifndef _WINDOWS  #ifndef _MSC_VER
128  void CSerial::openLinux()  void CSerial::openLinux()
129  {  {
130            termios newtio;
131    
132            mFiledescriptor = ::open(mPortstr, O_RDWR | O_NOCTTY | O_NONBLOCK);
133            if (mFiledescriptor < 0)
134                    throw std::runtime_error( writeLastError() );
135    
136            tcgetattr(mFiledescriptor, &mOldtio);
137    
138            bzero(&newtio, sizeof(newtio) );
139    
140            // use a std. 8N1 config
141            newtio.c_cflag = convertBaudrate(mBitrate) | CS8 | CLOCAL | CREAD;
142            newtio.c_iflag = IGNPAR;
143            newtio.c_oflag = 0;
144    
145            // set input mode (non-canonical, no echo,...)
146            newtio.c_lflag = 0;
147                            
148            newtio.c_cc[VTIME]    = 0;   // inter-character timer unused
149            newtio.c_cc[VMIN]     = 0;   // blocking read until 1 chars received
150            
151                                            
152            tcflush(mFiledescriptor, TCIFLUSH);
153            tcsetattr(mFiledescriptor, TCSANOW, &newtio);
154            
155            mIsopen = true;
156  }  }
157  #endif  #endif
158    
# Line 124  void CSerial::close() Line 160  void CSerial::close()
160  {  {
161          if (mIsopen)          if (mIsopen)
162          {          {
163  #ifdef _WINDOWS  #ifdef _MSC_VER
164                  while (getComstat().cbOutQue >0)                  while (getComstat().cbOutQue >0)
165                          Sleep(5);                          Sleep(5);
166                  SetCommState(mComport,&mDcbRestore);                  SetCommState(mComport,&mDcbRestore);
167                  CloseHandle(mComport);                  CloseHandle(mComport);
168  #else // linux close()  #else // linux close()
169                    tcdrain(mFiledescriptor);
170                    tcsetattr(mFiledescriptor, TCSADRAIN, &mOldtio); //restore settings, when all data is written
171                    ::close(mFiledescriptor); //close()== system-call
172  #endif  #endif
173                  mIsopen = false;                  mIsopen = false;
174          }          }
175  }  }
176    
177    
178  unsigned char CSerial::readByte()  int CSerial::readByte()
179  {  {
180          unsigned char out;          unsigned char out;
181          unsigned long size;          int size = readBytes(&out,1);
182    
183          if (!mIsopen)          if (size == 0)
184                  throw std::runtime_error("Port not opened");                  return 256;
 #ifdef _WINDOWS  
         ReadFile(mComport,&out,1,&size,0);  
         if (size != 1)  
         {  
                 std::string error = writeLastError();  
                 CloseHandle(mComport);  
                 throw std::exception(error.c_str());  
         }  
 #else //linux readByte()  
 #endif  
185    
         //printByte("Read", out);  
186          return out;          return out;
187  }  }
188    
189    
190  void CSerial::writeByte(unsigned char out)  void CSerial::writeByte(unsigned char out)
191  {  {
192          unsigned long size;          writeBytes(&out,1);
193    }
         //printByte("Write", out);  
         if (!mIsopen)  
                 throw std::runtime_error("Port not opened");  
   
 #ifdef _WINDOWS  
         while (getComstat().cbOutQue >0)  
                 Sleep(2);  
194    
195          WriteFile(mComport,&out,1,&size, NULL);  int CSerial::convertBaudrate(Baudrate rate)
196          if (size ==0)  {
197            int retval=0;
198    #ifdef _MSC_VER
199            switch( rate )
200          {          {
201                  std::string error = writeLastError();                  case Baud300:
202                  CloseHandle(mComport);                          retval = 300;
203                  throw std::exception(error.c_str());                          break;
204                    case Baud600:
205                            retval = 600;
206                            break;
207                    case Baud1200:
208                            retval = 1200;
209                            break;
210                    case Baud2400:
211                            retval = 2400;
212                            break;
213                    case Baud4800:
214                            retval = 4800;
215                            break;
216                    case Baud9600:
217                            retval = 9600;
218                            break;
219                    case Baud19200:
220                            retval = 19200;
221                            break;
222                    case Baud38400:
223                            retval = 38400;
224                            break;
225                    case Baud57600:
226                            retval = 57600;
227                            break;
228                    case Baud115200:
229                            retval = 115200;
230                            break;                  
231            }
232    #else
233            switch (rate)
234            {
235                    case Baud300:
236                            retval = B300;
237                            break;
238                    case Baud600:
239                            retval = B600;
240                            break;
241                    case Baud1200:
242                            retval = B1200;
243                            break;
244                    case Baud2400:
245                            retval = B2400;
246                            break;
247                    case Baud4800:
248                            retval = B4800;
249                            break;
250                    case Baud9600:
251                            retval = B9600;
252                            break;
253                    case Baud19200:
254                            retval = B19200;
255                            break;
256                    case Baud38400:
257                            retval = B38400;
258                            break;
259                    case Baud57600:
260                            retval = B57600;
261                            break;
262                    case Baud115200:
263                            retval = B115200;
264                            break;
265          }          }
 #else //linux writeByte()  
266  #endif  #endif
267    
268            return retval;
269  }  }
270  #ifdef _WINDOWS  
271    #ifdef _MSC_VER
272  COMSTAT CSerial::getComstat() const  COMSTAT CSerial::getComstat() const
273  {  {
274          if (!mIsopen)          if (!mIsopen)
# Line 196  COMSTAT CSerial::getComstat() const Line 283  COMSTAT CSerial::getComstat() const
283    
284  int CSerial::bytesReady() const  int CSerial::bytesReady() const
285  {  {
286  #ifdef _WINDOWS  #ifdef _MSC_VER
287          return getComstat().cbInQue;          return getComstat().cbInQue;
288  #else  #else
289          return 0;          return 0;
# Line 205  int CSerial::bytesReady() const Line 292  int CSerial::bytesReady() const
292    
293  int CSerial::outQueueSize() const  int CSerial::outQueueSize() const
294  {  {
295  #ifdef _WINDOWS  #ifdef _MSC_VER
296          return getComstat().cbOutQue;          return getComstat().cbOutQue;
297  #else  #else
298          return 0;          return 0;
299  #endif  #endif
300  }  }
301    
302  /* Debug function  // Debug function
303    //
304  void CSerial::printByte(char* description, unsigned char byte)  void CSerial::printByte(char* description, unsigned char byte)
305  {  {
306    #ifdef DEBUG
307          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;
308          std::cout << std::dec;          std::cout << std::dec;
309    #endif
310  }  }
 */  
311    
312  /*  
313  void CSerial::writeBytes(UCVector out)  
314    void CSerial::writeBytes(unsigned char* buf, unsigned int len)
315  {  {
316          unsigned long bytesWritten;          if (!mIsopen)
317          unsigned int size = out.size();                  throw std::runtime_error("Port not opened");
318          unsigned char *buf = new unsigned char[size];  #ifdef _MSC_VER
319            writeBytesWindows(buf,len);
320    #else
321            writeBytesLinux(buf,len);
322    #endif
323    }
324    
         for (int i=0; i<size; i++)  
                 buf[i] = out[i];  
325    
326          WriteFile(mComport,buf,size,&bytesWritten,NULL);  #ifdef _MSC_VER
327          if (bytesWritten != size)  void CSerial::writeBytesWindows(unsigned char* buf, unsigned int len)
328    {
329            unsigned int size;
330            while (getComstat().cbOutQue >0)
331                    Sleep(2);
332    
333            WriteFile(mComport,buf,len,&size, NULL);
334            if (size != len)
335          {          {
336                  std::string error = writeLastError();                  std::string error = writeLastError();
337                  CloseHandle(mComport);                  CloseHandle(mComport);
338                  throw std::exception(error.c_str());                  throw std::exception(error.c_str());
339          }          }
         delete[] buf;  
340  }  }
 */  
341    
342    #else
343    void CSerial::writeBytesLinux(unsigned char* buf, unsigned int len)
344    {
345            int size = write(mFiledescriptor, &buf, len);
346            Sleep(50);
347            //tcdrain(mFiledescriptor);
348            if (size != len)
349                    throw std::runtime_error(writeLastError() );
350    }
351    #endif
352    
353  /*  int CSerial::readBytes(unsigned char *buf, unsigned int maxLen)
 UCVector CSerial::readBytes(int maxcount)  
354  {  {
355          UCVector buf;          if (!mIsopen)
356                    throw std::runtime_error("Port not opened");
357    #ifdef _MSC_VER
358            return readBytesWindows(buf,maxLen);
359    #else
360            return readBytesLinux(buf,maxLen);
361    #endif
362    }
363    
364    
365    #ifdef _MSC_VER
366    int CSerial::readBytesWindows(unsigned char* buf, unsigned int maxLen)
367    {
368            unsigned long size;
369            ReadFile(mComport, buf, maxLen, &size, 0);
370            return size;
371    }
372    
373    #else
374    
375          return buf;  int CSerial::readBytesLinux(unsigned char* buf, unsigned int maxLen)
376    {
377            return read(mFiledescriptor, buf, maxLen);
378  }  }
379  */  
380    #endif

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

  ViewVC Help
Powered by ViewVC 1.1.20