# 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   SFBRxByteBuffer & getRx() { return rxBytes; }
    00116   SFBTxByteBuffer & getTx() { return txBytes; }
    00117
    00118 private:
    00119
    00120   void readInput();
    00121   void writeOutput();
    00122   bool writeByte(u8 byte);
    00123
    00124   PacketBuffer & rxBuf;         /* Inbound packets are dispatched from here */
    00125   SFBRxByteBuffer rxBytes;      /* Interrupt level writes raw inbound UART RX data to here */
    00126   SFBTxByteBuffer txBytes;      /* Interrupt level reads raw outbound UART TX data from here */
    00127   SFBFrame theFrame;            /* Packets are framed and deframed here */
    00128   bool isRunning;
    00129   const u8 face;
    00130   void * ufd;
    00131   u8 pbc, lbc, hbc;
    00132   int readBuf;
    00133   int bufferedChar;
    00134
    00135   u32 errorOdds;
    00136   u32 nextErrorOdds;
    00137   bool lastByteError;
    00138
    00139   enum {
    00140     FLAG_RUNNING = 0x01     /* Port has been start()ed more recently than is was stop()ped */
    00141   };
    00142
    00143 public:
    00144   static void startup_initialization() ;
    00145 };
    00146
    00147 extern bool canReadFromFd(int fd);
    00148 extern int readByteFromFd(int fd);
    00149 #define CAN_WRITE(fd) (REGISTER_OFFSET(fd,UxLSR) & 0x20)
    00150 #define WRITE_BYTE(fd,byte) (REGISTER_OFFSET(fd,UxTHR) = (byte))
    00151 #define CAN_READ(fd) canReadFromFd(fd)
    00152 #define READ_BYTE(fd) readByteFromFd(fd)
    00153
    00154 #endif  /* SFBHWSERIALPORTABLE_H */
    00155