Serial.C

00001 /*!@file Devices/Serial.C class for interfacing with a serial port */
00002 
00003 // //////////////////////////////////////////////////////////////////// //
00004 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2003   //
00005 // by the University of Southern California (USC) and the iLab at USC.  //
00006 // See http://iLab.usc.edu for information about this project.          //
00007 // //////////////////////////////////////////////////////////////////// //
00008 // Major portions of the iLab Neuromorphic Vision Toolkit are protected //
00009 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency //
00010 // in Visual Environments, and Applications'' by Christof Koch and      //
00011 // Laurent Itti, California Institute of Technology, 2001 (patent       //
00012 // pending; application number 09/912,225 filed July 23, 2001; see      //
00013 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status).     //
00014 // //////////////////////////////////////////////////////////////////// //
00015 // This file is part of the iLab Neuromorphic Vision C++ Toolkit.       //
00016 //                                                                      //
00017 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can   //
00018 // redistribute it and/or modify it under the terms of the GNU General  //
00019 // Public License as published by the Free Software Foundation; either  //
00020 // version 2 of the License, or (at your option) any later version.     //
00021 //                                                                      //
00022 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope  //
00023 // that it will be useful, but WITHOUT ANY WARRANTY; without even the   //
00024 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
00025 // PURPOSE.  See the GNU General Public License for more details.       //
00026 //                                                                      //
00027 // You should have received a copy of the GNU General Public License    //
00028 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write   //
00029 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,   //
00030 // Boston, MA 02111-1307 USA.                                           //
00031 // //////////////////////////////////////////////////////////////////// //
00032 //
00033 // Primary maintainer for this file: Nitin Dhavale <dhavale@usc.edu>
00034 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Devices/Serial.C $
00035 // $Id: Serial.C 12962 2010-03-06 02:13:53Z irock $
00036 //
00037 
00038 #include "Serial.H"
00039 #include <iostream>
00040 #include <sys/types.h>
00041 #include <dirent.h>
00042 #include <unistd.h>
00043 #include <string>
00044 #include <stdio.h>
00045 #include <string.h>
00046 
00047 
00048 //const ModelOptionDef OPT_DevName =
00049 //{ MODOPT_ARG(std::string), "DevName", &MOC_Serial, OPTEXP_CORE,
00050 //    "Device file",
00051 //    "serial-dev", '\0', "", "/dev/ttyUSB0" };
00052 
00053 // ######################################################################
00054 
00055 Serial::Serial() :
00056         itsCmdDevName("/dev/ttyUSB0"),
00057         itsDeviceDescription(""),
00058         itsSearchPrefix("ttyUSB"),
00059         itsBaud(9600),
00060         itsCharBits(8),
00061         itsStopBits(1),
00062         itsUseParity(false),
00063         itsParityOdd(false),
00064         itsFlowHard(false),
00065         itsFlowSoft(false),
00066         itsRdTout(0),
00067         itsBlocking(true),
00068         itsSerialOk(false),
00069         dev(-1),
00070   itsDevName(""),
00071   serialErrno(serialErrSuccess)
00072 {
00073 
00074 }
00075 
00076 // ######################################################################
00077 void Serial::start()
00078 {
00079         //Check to see if we have a hardcoded device name. If so, then let's just
00080         //go ahead and enable that port. If
00081         printf("Looking Device Name [%s]\n",itsDevName.c_str());
00082         if(itsDevName != "")
00083         {
00084                 printf("Opening %s", itsDevName.c_str());
00085                 enablePort(itsDevName);
00086         } else if (itsDevName == "search") {
00087                 printf("Searching for devices\n");
00088                 itsCmdDevName = "";
00089 
00090                 DIR *directory_p;
00091                 struct dirent *entry_p;
00092 
00093                 //Open the device directory to search for devices whose names match the search prefix
00094                 directory_p = ::opendir ("/dev");
00095                 if (directory_p == NULL)
00096                         printf("Could Not Open /dev Directory!\n");
00097 
00098                 //Iterate through the directory entries
00099                 while ((entry_p = ::readdir (directory_p)))
00100                 {
00101                         std::string entryName(entry_p->d_name);
00102                         if(entryName.find(itsSearchPrefix.c_str()) != std::string::npos)
00103                         {//If the directory entry name matches our search prefix, then let's try configuring a serial
00104                          //port on that device, sending it an identity request command (0x00), and comparing the result
00105                          //with our required device description
00106 
00107                                 enablePort("/dev/" + entryName);
00108                                 unsigned char cmd[1] = {0};
00109 
00110         write(cmd,1);
00111                                 std::vector<unsigned char> deviceStringVec = readFrame(cmd[0], 255);
00112 
00113                                 std::string deviceString(deviceStringVec.begin(), deviceStringVec.end());
00114                                 printf("%s : %s", entryName.c_str(), deviceString.c_str());
00115 
00116                                 if(deviceString == itsDeviceDescription)
00117                                 {
00118                                         itsCmdDevName ="/dev/"+entryName;
00119                                         break;
00120                                 }
00121                         }
00122 
00123 
00124                 }
00125                 (void) ::closedir (directory_p);
00126                 if(itsCmdDevName == "")
00127                 {
00128                         printf("Could Not Find Serial Device Matching Descriptor (%s)\n", itsDeviceDescription.c_str());
00129                 }
00130         } else {
00131                 printf("Opening from cmd line %s\n", itsCmdDevName.c_str());
00132                 enablePort(itsCmdDevName);
00133   }
00134 }
00135 
00136 
00137 // ######################################################################
00138 void Serial::enablePort(std::string DeviceName)
00139 {
00140         closePort();
00141         serialErrno = serialErrSuccess;      // clear the error flag
00142 
00143         openPort(DeviceName);                // open the device
00144         perror();
00145 
00146         setSpeed(itsBaud);          // Set the baud rate
00147         perror();
00148 
00149         setFlowControl(itsFlowHard,
00150                         itsFlowSoft);           // Set flow control
00151         perror();
00152 
00153         setCharBits(itsCharBits);   // set no of bits in a char
00154         perror();
00155 
00156         setParity(itsUseParity,
00157                         itsParityOdd);          // Set even or odd parity
00158         perror();
00159 
00160         setBlocking(itsBlocking);   // blocking mode?
00161         perror();
00162 }
00163 
00164 
00165 #include <cstdio>
00166 // ######################################################################
00167 void Serial::stop()
00168 {
00169   closePort();
00170 }
00171 
00172 // ######################################################################
00173 void Serial::closePort()
00174 {
00175         if(dev >= 0) {
00176                 //sendBreak();
00177                 close(dev);
00178                 dev = -1; }
00179 }
00180 
00181 // ######################################################################
00182 void Serial::configureSearch(const std::string DeviceDescription, const int speed, const std::string SearchPrefix, const char *format,
00183                 const bool flowSoft, const bool flowHard,
00184                 const int tout)
00185 {
00186         printf("Search for %s in speed %d\n",DeviceDescription.c_str(),speed);
00187         itsDevName = "search";
00188         itsDeviceDescription = DeviceDescription;
00189         itsSearchPrefix = SearchPrefix;
00190         //enable serch
00191         //configure("search", speed, format, flowSoft, flowHard, tout);
00192         //Bypass search
00193         configure("", speed, format, flowSoft, flowHard, tout);
00194 }
00195 
00196 // ######################################################################
00197 void Serial::configure(const char *dev, const int speed, const char *format,
00198                 const bool flowSoft, const bool flowHard,
00199                 const int tout)
00200 {
00201   itsDevName = dev;
00202 
00203 
00204         itsBaud = speed;
00205         itsFlowSoft = flowSoft;
00206         itsFlowHard = flowHard;
00207         itsRdTout = tout;
00208 
00209         if (strlen(format) != 3) printf("Incorrect format string: %s", format);
00210 
00211         switch(format[0]) {
00212                 case '5': itsCharBits = 5; break;
00213                 case '6': itsCharBits = 6; break;
00214                 case '7': itsCharBits = 7; break;
00215                 case '8': itsCharBits = 8; break;
00216                 default: printf("Invalid charbits: %c (should be 5..8)", format[0]);
00217         }
00218 
00219         switch(format[1]) {
00220                 case 'N': itsUseParity = false; break;
00221                 case 'E': itsUseParity = true; itsParityOdd = false; break;
00222                 case 'O': itsUseParity = true; itsParityOdd = true; break;
00223                 default: printf("Invalid parity: %c (should be N,E,O)", format[1]);
00224         }
00225 
00226         switch(format[2]) {
00227                 case '1': itsStopBits = (1); break;
00228                 case '2': itsStopBits = (2); break;
00229                 default: printf("Invalid stopbits: %c (should be 1..2)", format[2]);
00230         }
00231 }
00232 
00233 // ######################################################################
00234 serialError Serial::setSpeed(const int speed)
00235 {
00236         struct termios options;
00237         unsigned int rate;
00238 
00239         switch(speed)
00240         {
00241                 case 115200:
00242                         rate = B115200;
00243                         break;
00244                 case 57600:
00245                         rate = B57600;
00246                         break;
00247                 case 38400:
00248                         rate = B38400;
00249                         break;
00250                 case 19200:
00251                         rate = B19200;
00252                         break;
00253                 case 9600:
00254                         rate = B9600;
00255                         break;
00256                 case 4800:
00257                         rate = B4800;
00258                         break;
00259                 case 2400:
00260                         rate = B2400;
00261                         break;
00262                 case 1200:
00263                         rate = B1200;
00264                         break;
00265                 case 600:
00266                         rate = B600;
00267                         break;
00268                 case 300:
00269                         rate = B300;
00270                         break;
00271                 case 110:
00272                         rate = B110;
00273                         break;
00274                 case 0:
00275                         rate = B0;
00276                         break;
00277                 default:
00278                         return serialError(serialErrSpeedInvalid);
00279         }
00280 
00281         // get current options
00282         if(tcgetattr(dev, &options)==-1){
00283                 serialErrno = serialErrTcGetAttrFailed;
00284                 return serialErrno;
00285         }
00286 
00287         // set the speed
00288         cfsetispeed(&options, rate);
00289         cfsetospeed(&options, rate);
00290 
00291         // change the terminals parameter instantly
00292         if( tcsetattr(dev, TCSANOW, &options) == -1){
00293                 serialErrno = serialErrTcSetAttrFailed;
00294                 return serialErrno;
00295         }
00296 
00297         if( tcgetattr(dev, &options) == -1) {
00298                 serialErrno = serialErrTcGetAttrFailed;
00299                 return serialErrno;
00300         }
00301 
00302         // update our ModelParam:
00303         itsBaud=speed;
00304 
00305         return serialErrSuccess;
00306 }
00307 
00308 
00309 // ######################################################################
00310 serialError Serial::setFlowControl(const bool useHard, const bool useSoft)
00311 {
00312         termios options;
00313 
00314         if( tcgetattr(dev, &options) == -1){
00315                 serialErrno = serialErrTcGetAttrFailed;
00316                 return serialErrno;
00317         }
00318 
00319         options.c_cflag &= ~CRTSCTS;
00320         options.c_iflag &= ~(IXON | IXANY | IXOFF);
00321 
00322         if (useSoft) options.c_iflag |= (IXON | IXANY | IXOFF);
00323         if (useHard) options.c_cflag |= CRTSCTS;
00324 
00325         if(tcsetattr(dev, TCSANOW, &options) == -1){
00326                 serialErrno = serialErrTcGetAttrFailed;
00327                 return serialErrno;
00328         }
00329 
00330         // update our ModelParams:
00331         itsFlowHard=useHard;
00332         itsFlowSoft=useSoft;
00333 
00334         return serialErrSuccess;
00335 }
00336 
00337 // ######################################################################
00338 serialError Serial::setCharBits(const int bits)
00339 {
00340         termios options;
00341 
00342         if(tcgetattr(dev, &options)==-1){
00343                 serialErrno = serialErrTcGetAttrFailed;
00344                 return serialErrno;
00345         }
00346 
00347         options.c_cflag &= ~CSIZE; // mask off the 'size' bits
00348 
00349         switch(bits)
00350         {
00351                 case 5: options.c_cflag |= CS5; break;
00352                 case 6: options.c_cflag |= CS6; break;
00353                 case 7: options.c_cflag |= CS7; break;
00354                 case 8: options.c_cflag |= CS8; break;
00355                 default: return serialError(serialErrCharsizeInvalid);
00356         }
00357 
00358         if( tcsetattr(dev, TCSANOW, &options) == -1 ){
00359                 serialErrno = serialErrTcSetAttrFailed;
00360                 return serialErrno;
00361         }
00362 
00363         // update our ModelParam:
00364         itsCharBits=bits;
00365 
00366         return serialErrSuccess;
00367 }
00368 
00369 // ######################################################################
00370 serialError Serial::setParity(const bool useParity, const bool oddParity)
00371 {
00372         struct termios options;
00373 
00374         if(tcgetattr(dev, &options)==-1){
00375                 serialErrno = serialErrTcGetAttrFailed;
00376                 return serialErrno;
00377         }
00378 
00379         options.c_cflag &= ~(PARENB | PARODD);
00380         if (useParity)
00381         {
00382                 if (oddParity)
00383                         options.c_cflag |= (PARENB | PARODD);
00384                 else
00385                         options.c_cflag |= PARENB;
00386         }
00387 
00388         if(tcsetattr(dev, TCSANOW, &options) == -1){
00389                 serialErrno = serialErrTcSetAttrFailed;
00390                 return serialErrno;
00391         }
00392 
00393         // update our ModelParams:
00394         itsUseParity=useParity;
00395         itsParityOdd=oddParity;
00396 
00397         return serialErrSuccess;
00398 }
00399 
00400 // ######################################################################
00401 serialError Serial::setStopBits(const int bits)
00402 {
00403         struct termios options;
00404 
00405         if(tcgetattr(dev, &options)==-1){
00406                 serialErrno = serialErrTcGetAttrFailed;
00407                 return serialErrno;
00408         }
00409 
00410         options.c_cflag &= ~CSTOPB;
00411         if (bits == 2) options.c_cflag |= CSTOPB;
00412         else if (bits != 1) return serialError(serialErrStopbitsInvalid);
00413 
00414         if(tcsetattr(dev, TCSANOW, &options) == -1){
00415                 serialErrno = serialErrTcSetAttrFailed;
00416                 return serialErrno;
00417         }
00418 
00419         // update our ModelParam:
00420         itsStopBits=bits;
00421 
00422         return serialErrSuccess;
00423 }
00424 
00425 // ######################################################################
00426 serialError Serial::setBlocking(const bool blocking)
00427 {
00428         int flags = fcntl(dev, F_GETFL, 0);
00429         if (flags == -1) printf("Cannot get flags");
00430         if (blocking) flags &= (~O_NONBLOCK); else flags |= O_NONBLOCK;
00431         if (fcntl(dev, F_SETFL, flags) == -1) printf("Cannot set flags");
00432 
00433         itsBlocking=blocking;
00434 
00435         return serialErrSuccess;
00436 }
00437 
00438 // ######################################################################
00439 void Serial::toggleDTR(const time_t ms)
00440 {
00441         struct termios tty, old;
00442         if(tcgetattr(dev, &tty) == -1 || tcgetattr(dev, &old) == -1){
00443                 serialErrno = serialErrTcGetAttrFailed;
00444         }
00445 
00446         cfsetospeed(&tty, B0);
00447         cfsetispeed(&tty, B0);
00448 
00449         if(tcsetattr(dev, TCSANOW, &tty) == -1){
00450                 serialErrno = serialErrTcSetAttrFailed;
00451         }
00452 
00453         if(ms)
00454                 usleep(ms*1000);
00455 
00456         if(tcsetattr(dev, TCSANOW, &old) == -1){
00457                 serialErrno = serialErrTcSetAttrFailed;
00458         }
00459 }
00460 
00461 // ######################################################################
00462 void Serial::sendBreak(void)
00463 {
00464         // Send a Hangup to the port
00465         tcsendbreak(dev, 0);
00466 }
00467 
00468 // ######################################################################
00469 serialError Serial::error(const serialError serialErrorNum)
00470 {
00471         serialErrno = serialErrorNum;
00472         return serialErrorNum;
00473 }
00474 
00475 // ######################################################################
00476 int Serial::openPort(std::string DeviceName)
00477 {
00478         //const pid_t fuser =
00479         //        rutz::unixcall::get_file_user_pid(DeviceName.c_str());
00480         int fuser = 0;
00481 
00482         if (fuser != 0 && DeviceName.compare("/dev/null") != 0)
00483         {
00484                 printf("serial device %s is already in use by process pid=%d;\n"
00485                                 "\ttry using /dev/null or a different serial device instead",
00486                                 DeviceName.c_str(), int(fuser));
00487         }
00488 
00489         int flags= O_RDWR | O_NOCTTY;
00490         termios options;
00491 
00492         // don't set the flag if we are setting a timeout on
00493         // the descriptor
00494         if (itsRdTout < 0) flags |= O_NDELAY;
00495 
00496         printf("Opening port %s\n", DeviceName.c_str());
00497         dev = ::open(DeviceName.c_str(), flags);
00498         if (dev == -1) { serialErrno = serialErrOpenFailed; return dev; }
00499         printf("Done\n");
00500 
00501         // Save current state
00502         if( tcgetattr(dev, &savedState) == -1 ){
00503                 serialErrno = serialErrTcGetAttrFailed;
00504                 return -1;
00505         }
00506 
00507         // reset all the flags
00508         if( fcntl(dev, F_SETFL, 0) == -1 ){
00509                 serialErrno = serialErrFcntlFailed;
00510                 return -1;
00511         }
00512 
00513         if(tcgetattr(dev, &options) == -1 ){
00514                 serialErrno = serialErrTcGetAttrFailed;
00515                 return -1;
00516         }
00517 
00518         // get raw input from the port
00519         options.c_cflag |= ( CLOCAL     // ignore modem control lines
00520                         | CREAD ); // enable the receiver
00521 
00522         options.c_iflag &= ~(  IGNBRK    // ignore BREAK condition on input
00523                         | BRKINT  // If IGNBRK is not set, generate SIGINT
00524                         // on BREAK condition, else read BREAK as \0
00525                         | PARMRK
00526                         | ISTRIP  // strip off eighth bit
00527                         | INLCR   // donot translate NL to CR on input
00528                         | IGNCR   // ignore CR
00529                         | ICRNL   // translate CR to newline on input
00530                         | IXON    // disable XON/XOFF flow control on output
00531                         );
00532 
00533         // disable implementation-defined output processing
00534         options.c_oflag &= ~OPOST;
00535         options.c_lflag &= ~(ECHO  // dont echo i/p chars
00536                         | ECHONL // do not echo NL under any circumstance
00537                         | ICANON // disable cannonical mode
00538                         | ISIG   // do not signal for INTR, QUIT, SUSP etc
00539                         | IEXTEN // disable platform dependent i/p processing
00540                         );
00541 
00542         // set a timeout on the descriptor
00543         if(itsRdTout > 0) {
00544                 options.c_cc[VMIN] = 0;
00545                 options.c_cc[VTIME] = itsRdTout;
00546         }
00547 
00548         if( tcsetattr(dev, TCSANOW, &options) == -1){
00549                 serialErrno = serialErrTcSetAttrFailed;
00550                 return -1;
00551         }
00552         return dev;
00553 }
00554 
00555 
00556 // ######################################################################
00557 int Serial::read(void* buffer, const int nbytes)
00558 {
00559         int n = ::read(dev, buffer, nbytes);
00560         if(n==-1)
00561                 serialErrno = serialErrReadFailed;
00562 
00563         if(n==0)
00564                 serialErrno = serialErrReadTimedOut;
00565 
00566         return n;
00567 }
00568 
00569 
00570 // ######################################################################
00571 char Serial::read(void)
00572 {
00573         char ch;
00574 
00575         this->read(&ch, 1);
00576 
00577         return ch;
00578 }
00579 
00580 std::vector<unsigned char> Serial::readFrame(const unsigned char frameStart, const unsigned char frameEnd, const int frameLength, const double timeout)
00581 {
00582 
00583         std::vector<unsigned char> data;
00584         unsigned char buffer[1024];
00585 
00586 
00587         //Read data into the data buffer
00588         //printf("Reading buffer...");
00589         int bytesRead = read(buffer, 1024);
00590         //printf("bytesRead[%d]\n",bytesRead);
00591         if(bytesRead > 0)
00592         {
00593         //      printf("buffer0[%d],framestart[%d]",buffer[0],frameStart);
00594                 if(frameStart!=buffer[0])
00595                         return std::vector<unsigned char>();
00596                 int framesize = buffer[1];
00597         //      printf("framesize[%d]\n",framesize);
00598                 for(int i=0;i<framesize;i++)
00599                         data.push_back(buffer[i+2]);
00600                 return data;
00601                 
00602         }
00603         else
00604         { //If the serial read returned 0 bytes, then just wait for a bit before reading again
00605                 usleep(1000);
00606                 printf("Read Fail\n");
00607 
00608                 //If the timer has expired, then let's just return an empty vector
00609                 //if(/*timer.getSecs() > timeout && */timeout > 0)
00610                 return std::vector<unsigned char>();
00611         }
00612 }
00613 
00614 
00615 // ######################################################################
00616 int Serial::write(const void* buffer, const int nbytes)
00617 {
00618         //char c[3] = { 0xff, 0x01, 0xff };
00619         //::write(dev, c, 3);
00620 
00621         int n = ::write(dev, buffer, nbytes);
00622 
00623         /*
00624         //printf("----------------- WRITE --------------------");
00625         for(int i=0; i<n; ++i)
00626         {
00627         fprintf(stderr, "%02X ",
00628         (static_cast<const unsigned char*>(buffer)[i])&0xff);
00629         }
00630         fprintf(stderr,"\n");
00631         //printf("-------------------------------------------");
00632         */
00633 
00634         if(n==-1)
00635                 serialErrno = serialErrWriteFailed;
00636 
00637         return n;
00638 }
00639 
00640 // ######################################################################
00641 int Serial::write(const unsigned char character)
00642 {
00643         return write(&character, 1);
00644 }
00645 
00646 
00647 // ######################################################################
00648 void Serial::flush(void)
00649 {
00650         //Flush the input
00651         int status = tcflush(dev,TCIFLUSH);
00652         if(status != 0)
00653                 printf("BAD SERIAL FLUSH");
00654 
00655 }
00656 
00657 // ######################################################################
00658 void Serial::perror(void)
00659 {
00660         switch(serialErrno)
00661         {
00662                 case serialErrSuccess:
00663                         printf("Serial::OK\n");
00664                         return;
00665                 case serialErrOpenNoTty:
00666                         printf("Serial::Open() No TTY Failed");
00667                         break;
00668                 case serialErrOpenFailed:
00669                         printf("Serial::Open() Failed");
00670                         break;
00671                 case serialErrSpeedInvalid:
00672                         printf("Serial::setSpeed() Invalid Speed Param");
00673                         break;
00674                 case serialErrFlowInvalid:
00675                         printf("Serial::setFlow() Invalid Flow Param");
00676                         break;
00677                 case serialErrParityInvalid:
00678                         printf("Serial::setParity() Invalid parity Param");
00679                         break;
00680                 case serialErrCharsizeInvalid:
00681                         printf("Serial::setCharSize() Invalid Char Size");
00682                         break;
00683                 case serialErrStopbitsInvalid:
00684                         printf("Serial::setStopBits() Invalid Stop Bits");
00685                         break;
00686                 case serialErrOptionInvalid:
00687                         printf("Serial::read() invalid option");
00688                         break;
00689                 case serialErrOutput:
00690                         printf("Serial::read() err output");
00691                         break;
00692                 case serialErrReadFailed:
00693                         printf("Serial::read() Failed");
00694                         break;
00695                 case serialErrReadTimedOut:
00696                         printf("Serial::read() Timed Out");
00697                         break;
00698                 case serialErrWriteFailed:
00699                         printf("Serial::Write() Failed");
00700                         break;
00701                 case serialErrFcntlFailed:
00702                         printf("Serial::Fcntl() Failed");
00703                         break;
00704                 case serialErrTcGetAttrFailed:
00705                         printf("Serial::tcgetattr() Failed");
00706                         break;
00707                 case serialErrTcSetAttrFailed:
00708                         printf("Serial::tcsetattr() Failed");
00709                         break;
00710                 default:
00711                         printf("Unknow error!");
00712         }
00713 }
00714 
00715 
00716 // ######################################################################
00717 Serial::~Serial(void)
00718 {  }
00719 
00720 
00721 
00722 // ######################################################################
00723 /* So things look consistent in everyone's emacs... */
00724 /* Local Variables: */
00725 /* indent-tabs-mode: nil */
00726 /* End: */
Generated on Sun May 8 08:04:45 2011 for iLab Neuromorphic Vision Toolkit by  doxygen 1.6.3