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_RENDEZVOUS = 2         
00058 
00059 
00060 
00061 
00062 
00063 };
00064 
00074 extern int getStandardBaudCode(u32 baudCodeOrRate) ;
00075 
00084 extern u32 getStandardBaudRate(u32 baudCode) ;
00085 
00092 class SFBSerial {
00093 
00094 public:
00095 
00098   void begin() ;
00099 
00100   void begin(u32 baud, bool manual = true) ;
00101 
00102   void reserve() ;              /* The endless, hideous print routines.. */
00109   void print(const char * str) {         facePrint(face,str); } 
00110 
00112   void print(const u8 * str, u32 len) {  facePrint(face,str,len); } 
00113 
00115   void print(int decimal) {              facePrint(face,decimal); }
00116 
00118   void print(unsigned int decimal) {     facePrint(face,decimal); }
00119 
00121   void print(long decimal) {             facePrint(face,decimal); }
00122 
00124   void print(unsigned long decimal) {    facePrint(face,decimal); }
00125 
00127   void print(long decimal, int code) {   facePrint(face,decimal,code); }
00128 
00130   void print(double val) {               facePrint(face,val); }
00131 
00133   void println() {                       facePrintln(face); }
00134 
00136   void println(const char * str) {       facePrintln(face,str); }
00137 
00139   void println(const u8 * str, u32 len) {facePrintln(face,str,len); }
00140 
00142   void println(int decimal) {            facePrintln(face,decimal); }
00143 
00145   void println(unsigned int decimal) {   facePrintln(face,decimal); }
00146 
00148   void println(long decimal) {           facePrintln(face,decimal); }
00149 
00151   void println(unsigned long decimal) {  facePrintln(face,decimal); }
00152 
00154   void println(long decimal, int code) { facePrintln(face,decimal,code); }
00155 
00157   void println(double val) {             facePrintln(face,val); }
00158 
00160   void printlnCheckByte() ;
00165   bool isInUse() ;  
00166 
00167   bool isManualMode() ; 
00168 
00169   bool isReflexMode() ; 
00170 
00171   bool isConsciousMode() ; 
00172 
00173   void switchToBlocking() ;
00174   
00175   u32 getBaud() { return baud; } 
00176 
00177   bool getOddParity() { return flags&FLAG_ODD_PARITY; } 
00178 
00179   u32 getFace() { return face; }  
00180 
00196   bool ready() ;
00197 
00198   u32 inputPackets() ;
00199   u32 outputPackets() ;
00200 
00206   SFBHWSerial & getHWSerial() { return hwSerial; }
00207 
00213   bool backgroundProcessingActive() ;
00214 
00219 
00228   bool available() ;
00229 
00240   int read();
00241 
00256   int peek();
00257 
00262 
00281   u8 * readPacket();
00282 
00287 
00288   void setPreferredBaudCode(u8 code, bool renegotiateNow = false) ;
00289 
00290   bool dispatch(DispatchHandler dispatcher = 0, u32 maxPackets = 1) ;
00291 
00292   void suppress(const char type) ;
00293   void allow(const char type) ;
00294 
00295   void reflex(const char type, PacketHandler pfunc) ;
00296 
00297   void otherwise(PacketHandler pfunc) ;
00298 
00303 
00313   void putcInterrupt(u8 byte) ;
00314 
00324   void terpriInterrupt() ;
00325 
00335   void putcBlocking(u8 byte) ;
00336 
00345   void terpriBlocking() ;
00346 
00347   void write(u8 byte) { lowPutc(byte); }
00348   void write(const char * str) { print(str); }
00349   void write(u8 * buf, u32 len) { print(buf,len); }
00350 
00358   void flush() ;
00359 
00360   SFBSerial(int face) ; 
00361 
00362 
00369   static void startup_initialization() ;
00370 
00373   //XXX
00374 private:
00375 
00376   /* Low-level internal routines so BRN routines can talk before BRN is complete.. */
00377   void lowPrint(const char * str) ;
00378   void lowPrintln(const char * str) ;
00379   void lowPutc(const u8 byte) ;
00380   void lowTerpri() ;
00381   void lowPrintOurBRO() ;        /* Print our current baud rate offer */ 
00382 
00383   void maybeBlockForOutput() ;  /* Block until output space available, if we're FLAG_BLOCKING */ 
00384 
00385   static PacketBuffer sharedBuffer;
00386 
00387   SFBHWSerial hwSerial;        /* Platform-specific state and methods */
00388 
00389   u32 baud;
00390   u32 nextTimeout;             /* when we're next to act */ 
00391   SFBAlarmIndexType alarmNumber; /* Our alarm number, if != 0 */ 
00392   const u8 face;                 
00393   u8 flags;
00394   u8 state;                    /* Current state in BRN state machine */ 
00395   u8 preferredCode;            /* Our current preferred baud rate code */ 
00396   u8 selectedCode;             /* negotiated baud rate code */ 
00397   bool selectedOdd;            /* negotiated odd parity (else none) */ 
00398   bool haveBufferedByte;       /* for ::available() */ 
00399   u8 bufferedByte;
00400   enum {
00401     STATE_RESET,                /* 0 Entered to send a reset packet */ 
00402     STATE_INIT,                 /* 1 Initial state */ 
00403     STATE_LISTEN,               /* 2 Sending/waiting for SIM */ 
00404     STATE_OFFER,                /* 3 Sent/waiting for SB */ 
00405     STATE_CONFIRM,              /* 4 Sent/waiting for SS */ 
00406     STATE_WAIT,                 /* 5 Delay after baud changed */ 
00407     STATE_DONE,                 /* 6 BRN finished */ 
00408     STATE_SHOWTIME,             /* 7 Queueing and dispatching packets */ 
00409     STATE_CHECKIN,              /* 8 SRU sent to request SIM */ 
00410     MAX_STATES
00411   };
00412 
00413   enum {
00414     FLAG_RUNNING =   0x01,     /* Port is in use (on our side.  This doesn't imply a live connection.) */
00415     FLAG_ODD_PARITY= 0x02,     /* Port is using odd parity (vs no parity) */
00416     FLAG_CONSCIOUS = 0x04,     /* Port is under conscious control - no BRN or bkgd packets will be sent */
00417     FLAG_BRN_DONE  = 0x08,     /* Baud rate negotiation has succeeded or is under conscious control */
00418     FLAG_BLOCKING_BYTES= 0x10, /* Port is running in byte-by-byte mode, with blocking output */
00419     FLAG_GPIOS     = 0x20,     /* Port pins are in use as non-UART pins, we can't touch them */
00420     FLAG_CONNECTED = 0x40,     /* We have received data lately on this face; there's something out there */
00421     FLAG_RSRVD8    = 0x80      /* Reserved */
00422   };
00423 
00424   void start(u32 baud, u8 startFlags) ;
00425 
00426   void stop() ;
00427 
00428   void setBaudRate(u32 baud, bool isOddParity = false) ;
00429 
00430   void setOddParity(bool isOdd) {
00431     if (isOdd) flags |= FLAG_ODD_PARITY;
00432     else flags &= ~FLAG_ODD_PARITY;
00433   }
00434 
00435   typedef void (*InitHandler)(u8 face);
00436   static const char backgroundProcessorTypes[];
00437   static const PacketHandler backgroundProcessorHandlers[];
00438   static const InitHandler backgroundProcessorInits[];
00439 
00440   void backgroundProcessingInit() ;
00441 
00442   static void stateTimeout(u32 when, void * arg) ;
00443 
00444   void step(u32 when, u8 * spacket) ; /* Step the state machine.  spacket==0 means timeout occurred */
00445 
00446   bool stepInit(u32 when, u8 * spacket) ; /* step in state INIT */
00447   bool stepListen(u32 when, u8 * spacket) ; /* step in state LISTEN */
00448   bool stepOffer(u32 when, u8 * spacket) ; /* step in state OFFER */
00449   bool stepConfirm(u32 when, u8 * spacket) ; /* step in state CONFIRM */
00450   bool stepWait(u32 when, u8 * spacket) ; /* step in state WAIT */
00451   bool stepDone(u32 when, u8 * spacket) ; /* step in state DONE */
00452   bool stepShowtime(u32 when, u8 * spacket) ; /* step in state SHOWTIME */
00453   bool stepCheckin(u32 when, u8 * spacket) ; /* step in state CHECKIN */
00454 
00455   void setState(u8 newState, u32 aboutHowManyMs) ;
00456 
00457   static void ppacketDispatcher(u8 * packet) ;
00458 
00459   static void rpacketDispatcher(u8 * packet) ;
00460 
00461   static void spacketDispatcher(u8 * packet) ;
00462   static void spacketInit(u8 face) ;
00463 
00464 };
00465    
00466 /* The one-time serial startup code */
00467 extern void serial_startup_initialization() ;
00468 
00469 /* Some utility functions for packet handling */
00470 extern bool zPacketPrefix(u8 * p1, const char * to) ;
00471 extern bool packetPrefix(u8 * p1, const u8 * to, const u32 len) ;
00472 
00486 extern SFBSerial Faces[FACE_COUNT]; // Declared here but defined in SFBHWSerial(Board|Host)
00487 #define NorthFace Faces[NORTH]
00488 #define SouthFace Faces[SOUTH]
00489 #define EastFace Faces[EAST]
00490 #define WestFace Faces[WEST]
00491 
00492 /* Make just plain 'Serial' be the same as 'NorthSerial',
00493  * so that Arduinoish code will have some place to go.
00494  *
00495  * Ditto for 'Serial1', etc, so Arduino Mega examples can fly
00496  */
00497 #define Serial NorthFace
00498 #define Serial1 SouthFace
00499 #define Serial2 EastFace
00500 #define Serial3 WestFace
00501 
00502 #endif  /* SFBSERIAL_H */
00503 

Generated on Mon Oct 26 10:44:22 2009 for SFB by doxygen 1.5.9