SFBSerial.h

Go to the documentation of this file.
00001 /*                                       -*- mode:C++; fill-column: 100 -*-
00002   SFBSerial.h - 'Platform-independent' serial port support
00003   Copyright (C) 2008 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 
00029 #ifndef SFBSERIAL_H
00030 #define SFBSERIAL_H
00031 
00032 #include "SFBConstants.h"       /* For FACE_COUNT */
00033 #include "SFBAlarm.h"           /* For SFBAlarmIndexType */ 
00034 #include "SFBReactor.h"         /* For PacketHandler, DispatchHandler, Body */ 
00035 #include "SFBHWSerial.h"        /* For hardware-specific serial support */ 
00036 #include "SFBPrint.h"           /* For facePrint* */ 
00037 
00045 enum StandardBaudRateCodes {
00046   SFBAUD300 = 0,                
00047   SFBAUD1200 = 1,               
00048   SFBAUD9600 = 2,               
00049   SFBAUD57600 = 3,              
00050   SFBAUD115200 = 4,             
00051   SFBAUD230400 = 5,             
00052   SFBAUD500000 = 6,             
00053   SFBAUD1000000 = 7,            
00054   SFBAUD2000000 = 8,            
00055   SFBAUD3000000 = 9,            
00056 
00057   SFBAUD_CODE_COUNT = 10,       
00058 
00059   SFBAUD_RENDEZVOUS = 2         
00060 
00061 
00062 
00063 
00064 
00065 };
00066 
00076 extern int getStandardBaudCode(u32 baudCodeOrRate) ;
00077 
00086 extern u32 getStandardBaudRate(u32 baudCode) ;
00087 
00094 class SFBSerial {
00095 
00096 public:
00097 
00100   void begin() ;
00101 
00102   void begin(u32 baud, bool manual = true) ;
00103 
00104   void reserve() ;            
00105 
00106   void end() ;
00107   /* The endless, hideous print routines.. */
00114   void print(const char * str) {         facePrint(face,str); } 
00115 
00117   void print(const u8 * str, u32 len) {  facePrint(face,str,len); } 
00118 
00120   void print(int decimal) {              facePrint(face,decimal); }
00121 
00123   void print(unsigned int decimal) {     facePrint(face,decimal); }
00124 
00126   void print(long decimal) {             facePrint(face,decimal); }
00127 
00129   void print(unsigned long decimal) {    facePrint(face,decimal); }
00130 
00132   void print(long decimal, int code) {   facePrint(face,decimal,code); }
00133 
00135   void print(double val) {               facePrint(face,val); }
00136 
00138   void println() {                       facePrintln(face); }
00139 
00141   void println(const char * str) {       facePrintln(face,str); }
00142 
00144   void println(const u8 * str, u32 len) {facePrintln(face,str,len); }
00145 
00147   void println(int decimal) {            facePrintln(face,decimal); }
00148 
00150   void println(unsigned int decimal) {   facePrintln(face,decimal); }
00151 
00153   void println(long decimal) {           facePrintln(face,decimal); }
00154 
00156   void println(unsigned long decimal) {  facePrintln(face,decimal); }
00157 
00159   void println(long decimal, int code) { facePrintln(face,decimal,code); }
00160 
00162   void println(double val) {             facePrintln(face,val); }
00163 
00165   void printlnCheckByte() ;
00170   bool isInUse() ;  
00171 
00172   bool isManualMode() ; 
00173 
00174   bool isReflexMode() ; 
00175 
00176   bool isConsciousMode() ; 
00177 
00178   void switchToBlocking() ;
00179   
00180   u32 getBaud() { return baud; } 
00181 
00182   bool getOddParity() { return flags&FLAG_ODD_PARITY; } 
00183 
00184   u32 getFace() { return face; }  
00185 
00201   bool ready() ;
00202 
00203   u32 inputBufferUsed() ;
00204   u32 outputBufferUsed() ;
00205   u32 inputBufferFree() ;
00206   u32 outputBufferFree() ;
00207   u32 brokenPackets() { return brokenPacketCount; }
00208   void incrBrokenPacketCount() { ++brokenPacketCount; }
00209 
00215   SFBHWSerial & getHWSerial() { return hwSerial; }
00216 
00222   bool backgroundProcessingActive() ;
00223 
00228 
00237   bool available() ;
00238 
00249   int read();
00250 
00265   int peek();
00266 
00271 
00290   u8 * readPacket();
00291 
00296 
00297   void setPreferredBaudCode(u8 code, bool renegotiateNow = false) ;
00298 
00299   bool dispatch(DispatchHandler dispatcher = 0, u32 maxPackets = 1) ;
00300 
00301   void suppress(const char type) ;
00302   void allow(const char type) ;
00303 
00304   void reflex(const char type, PacketHandler pfunc) ;
00305 
00306   void otherwise(PacketHandler pfunc) ;
00307 
00312 
00322   void putcInterrupt(u8 byte) ;
00323 
00333   void terpriInterrupt() ;
00334 
00344   void putcBlocking(u8 byte) ;
00345 
00354   void terpriBlocking() ;
00355 
00356   void write(u8 byte) { lowPutc(byte); }
00357   void write(const char * str) { print(str); }
00358   void write(u8 * buf, u32 len) { print(buf,len); }
00359 
00367   void flush() ;
00368 
00369   SFBSerial(int face) ; 
00370 
00371 
00378   static void startup_initialization() ;
00379 
00382   //XXX
00383 private:
00384 
00385   /* Low-level internal routines so BRN routines can talk before BRN is complete.. */
00386   void lowPrint(const char * str) ;
00387   void lowPrintln(const char * str) ;
00388   void lowPutc(const u8 byte) ;
00389   void lowTerpri() ;
00390   void lowPrintOurBRO() ;        /* Print our current baud rate offer */ 
00391 
00392   void maybeBlockForOutput() ;  /* Block until output space available, if we're FLAG_BLOCKING */ 
00393 
00394   static PacketBuffer sharedBuffer;
00395 
00396   SFBHWSerial hwSerial;        /* Platform-specific state and methods */
00397 
00398   u32 baud;
00399   u32 nextTimeout;             /* when we're next to act */ 
00400   u32 brokenPacketCount;       /* how many inbound packets were dead */ 
00401   SFBAlarmIndexType alarmNumber; /* Our alarm number, if != 0 */ 
00402   const u8 face;                 
00403   u8 flags;
00404   u8 state;                    /* Current state in BRN state machine */ 
00405   u8 preferredCode;            /* Our current preferred baud rate code */ 
00406   u8 selectedCode;             /* negotiated baud rate code */ 
00407   bool selectedOdd;            /* negotiated odd parity (else none) */ 
00408   bool haveBufferedByte;       /* for ::available() */ 
00409   u8 bufferedByte;
00410   enum {
00411     STATE_RESET,                /* 0 Entered to send a reset packet */ 
00412     STATE_INIT,                 /* 1 Initial state */ 
00413     STATE_LISTEN,               /* 2 Sending/waiting for SIM */ 
00414     STATE_OFFER,                /* 3 Sent/waiting for SB */ 
00415     STATE_CONFIRM,              /* 4 Sent/waiting for SS */ 
00416     STATE_WAIT,                 /* 5 Delay after baud changed */ 
00417     STATE_DONE,                 /* 6 BRN finished */ 
00418     STATE_SHOWTIME,             /* 7 Queueing and dispatching packets */ 
00419     STATE_CHECKIN,              /* 8 SRU sent to request SIM */ 
00420     MAX_STATES
00421   };
00422 
00423   enum {
00424     FLAG_RUNNING =   0x01,     /* Port is in use (on our side.  This doesn't imply a live connection.) */
00425     FLAG_ODD_PARITY= 0x02,     /* Port is using odd parity (vs no parity) */
00426     FLAG_CONSCIOUS = 0x04,     /* Port is under conscious control - no BRN or bkgd packets will be sent */
00427     FLAG_BRN_DONE  = 0x08,     /* Baud rate negotiation has succeeded or is under conscious control */
00428     FLAG_BLOCKING_BYTES= 0x10, /* Port is running in byte-by-byte mode, with blocking output */
00429     FLAG_GPIOS     = 0x20,     /* Port pins are in use as non-UART pins, we can't touch them */
00430     FLAG_CONNECTED = 0x40,     /* We have received data lately on this face; there's something out there */
00431     FLAG_RSRVD8    = 0x80      /* Reserved */
00432   };
00433 
00434   void start(u32 baud, u8 startFlags) ;
00435 
00436   void stop() ;
00437 
00438   void setBaudRate(u32 baud, bool isOddParity = false) ;
00439 
00440   void setOddParity(bool isOdd) {
00441     if (isOdd) flags |= FLAG_ODD_PARITY;
00442     else flags &= ~FLAG_ODD_PARITY;
00443   }
00444 
00445   typedef void (*InitHandler)(u8 face);
00446   static const char backgroundProcessorTypes[];
00447   static const PacketHandler backgroundProcessorHandlers[];
00448   static const InitHandler backgroundProcessorInits[];
00449 
00450   void backgroundProcessingInit() ;
00451 
00452   static void stateTimeout(u32 when, void * arg) ;
00453 
00454   void step(u32 when, u8 * spacket) ; /* Step the state machine.  spacket==0 means timeout occurred */
00455 
00456   bool stepInit(u32 when, u8 * spacket) ; /* step in state INIT */
00457   bool stepListen(u32 when, u8 * spacket) ; /* step in state LISTEN */
00458   bool stepOffer(u32 when, u8 * spacket) ; /* step in state OFFER */
00459   bool stepConfirm(u32 when, u8 * spacket) ; /* step in state CONFIRM */
00460   bool stepWait(u32 when, u8 * spacket) ; /* step in state WAIT */
00461   bool stepDone(u32 when, u8 * spacket) ; /* step in state DONE */
00462   bool stepShowtime(u32 when, u8 * spacket) ; /* step in state SHOWTIME */
00463   bool stepCheckin(u32 when, u8 * spacket) ; /* step in state CHECKIN */
00464 
00465   void setState(u8 newState, u32 aboutHowManyMs) ;
00466 
00467   static void ppacketDispatcher(u8 * packet) ;
00468 
00469   static void rpacketDispatcher(u8 * packet) ;
00470 
00471   static void spacketDispatcher(u8 * packet) ;
00472   static void spacketInit(u8 face) ;
00473 
00474 };
00475    
00476 /* The one-time serial startup code */
00477 extern void serial_startup_initialization() ;
00478 
00479 /* Some utility functions for packet handling */
00480 extern bool zPacketPrefix(u8 * p1, const char * to) ;
00481 extern bool packetPrefix(u8 * p1, const u8 * to, const u32 len) ;
00482 
00496 extern SFBSerial Faces[FACE_COUNT]; // Declared here but defined in SFBHWSerial(Board|Host)
00497 #define NorthFace Faces[NORTH]      
00498 #define SouthFace Faces[SOUTH]      
00499 #define EastFace Faces[EAST]        
00500 #define WestFace Faces[WEST]        
00501 
00502 /* Make just plain 'Serial' be the same as 'NorthSerial',
00503  * so that Arduinoish code will have some place to go.
00504  *
00505  * Ditto for 'Serial1', etc, so Arduino Mega examples can fly
00506  */
00507 #define Serial NorthFace        
00508 #define Serial1 SouthFace       
00509 #define Serial2 EastFace        
00510 #define Serial3 WestFace        
00511 
00512 #endif  /* SFBSERIAL_H */
00513 

Generated on Fri Apr 22 06:54:12 2011 for SFB by doxygen 1.5.9