# SFBHWSerialPortable.h

Go to the documentation of this file.

    00001 /*                                              -*- mode:C++; fill-column:100 -*-
    00002   SFBHWSerialPortable.h - Low-level serial support for the (Unix / Posix / *?) host
    00003   Copyright (C) 2009 The Regents of the University of New Mexico.  All rights reserved.
    00004
    00005   This library is free software; you can redistribute it and/or
    00006   modify it under the terms of the GNU Lesser General Public
    00007   License as published by the Free Software Foundation; either
    00008   version 2.1 of the License, or (at your option) any later version.
    00009
    00010   This library is distributed in the hope that it will be useful,
    00011   but WITHOUT ANY WARRANTY; without even the implied warranty of
    00012   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    00013   Lesser General Public License for more details.
    00014
    00015   You should have received a copy of the GNU General Public License
    00016   along with this library; if not, write to the Free Software
    00017   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
    00018   USA
    00019
    00020   $Id$
    00021 */
    00022
    00030 #ifdef SFBHWSERIALBOARD_H
    00031 #error SFBHWSerialBoard.h and SFBHWSerialPortable.h must not be #included together!
    00032 #endif
    00033
    00034 #ifndef SFBHWSERIALPORTABLE_H
    00035 #define SFBHWSERIALPORTABLE_H
    00036
    00037 #include "SFBPacket.h"
    00038 #include "SFBFrame.h"
    00039 #include "SFBByteBuffer.h"
    00040 #include "SFBAssert.h"
    00041
    00042 class SFBSerial; /* FORWARD DECLARATION */
    00043
    00056 class SFBHWSerial {  /* Note we are defining 'SFBHWSerial', not 'SFBHWSerialPortable'! */
    00057
    00058 public:
    00059
    00060   SFBHWSerial(int face) ;
    00061
    00063   // A routine for deliberately injecting line errors on output for testing.  byteErrorOdds of 0
    00064   // means 'no errors', otherwise there is a 1-in-byteErrorOdds chance that a byte will be mangled.
    00065   //
    00066   // In addition, if the immediately previous byte was mangled by an error, and nextErrorOdds is
    00067   // non-zero, then there is also a 1-in-nextErrorOdds that this byte will be mangled.
    00068   //
    00069   // Both odds should be 0 for normal use.  For testing, something like byteErrorOdds==1000,
    00070   // nextErrorOdds=4 is enough to make getting a clean burn a bit of a challenge.
    00071   //
    00072   // Note that a byteErrorOdds of 1 will attempt to mangle every byte.  But since the mangling
    00073   // involves a 50% chance of flipping each bit of the byte, there is a 1-in-256 chance that a
    00074   // 'mangled' byte will in fact be unaltered.
    00075   void setNoiseParameters(u32 byteErrorOdds, u32 nextErrorOdds) {
    00076     this->errorOdds = byteErrorOdds;
    00077     this->nextErrorOdds = nextErrorOdds;
    00078     this->lastByteError = false;
    00079   }
    00080
    00081   SFBFrame & getFrame() { return theFrame; }
    00082
    00083   void putcBlocking(const u8 byte) ;
    00084
    00085   static u32 getFirstFace() { return NORTH; }
    00086   static bool moreFaces(u32 face) { return face <= WEST; }
    00087   static u32 nextFace(u32 face) { return face+1; }
    00088   static char faceCode(u32 face) { return "NSEW"[face]; }
    00089   static SFBSerial & getFace(u32 face) ;
    00090
    00091   bool getPreferOddParity() { return false; } // Odd vs none; it's N unless both say O; we say N so it's N with us
    00092   u8 getPreferredBaudCode() { return pbc; }
    00093   u8 getLowBaudCode() { return lbc; }
    00094   u8 getHighBaudCode() { return hbc; }
    00095
    00096   void setPreferredBaudCode(u8 code) ;
    00097   void setLowBaudCode(u8 code) ;
    00098   void setHighBaudCode(u8 code) ;
    00099
    00100   void predispatch() ;
    00101
    00102   void start(u32 baud, bool oddParity=false) ;
    00103   void stop() ;
    00104   void setBaudRate(u32 baud,bool isOddParity=false) ;
    00105   void checkTx() ;
    00106
    00107   void * getUFD() { return ufd; }
    00108   void setUFD(void * newUFD) ;
    00109
    00110   bool canRead() ;
    00111   int readByte() ;
    00112
    00113   void forceRxSync() ;
    00114
    00115 private:
    00116
    00117   void readInput();
    00118   void writeOutput();
    00119   bool writeByte(u8 byte);
    00120
    00121   PacketBuffer & rxBuf;         /* Inbound packets are dispatched from here */
    00122   SFBRxByteBuffer rxBytes;      /* Interrupt level writes raw inbound UART RX data to here */
    00123   SFBTxByteBuffer txBytes;      /* Interrupt level reads raw outbound UART TX data from here */
    00124   SFBFrame theFrame;            /* Packets are framed and deframed here */
    00125   bool isRunning;
    00126   const u8 face;
    00127   void * ufd;
    00128   u8 pbc, lbc, hbc;
    00129   int readBuf;
    00130   int bufferedChar;
    00131
    00132   u32 errorOdds;
    00133   u32 nextErrorOdds;
    00134   bool lastByteError;
    00135
    00136   enum {
    00137     FLAG_RUNNING = 0x01     /* Port has been start()ed more recently than is was stop()ped */
    00138   };
    00139
    00140 public:
    00141   static void startup_initialization() ;
    00142 };
    00143
    00144 extern bool canReadFromFd(int fd);
    00145 extern int readByteFromFd(int fd);
    00146 #define CAN_WRITE(fd) (REGISTER_OFFSET(fd,UxLSR) & 0x20)
    00147 #define WRITE_BYTE(fd,byte) (REGISTER_OFFSET(fd,UxTHR) = (byte))
    00148 #define CAN_READ(fd) canReadFromFd(fd)
    00149 #define READ_BYTE(fd) readByteFromFd(fd)
    00150
    00151 #endif  /* SFBHWSERIALPORTABLE_H */
    00152