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 inputPackets() ;
00204   u32 outputPackets() ;
00205 
00211   SFBHWSerial & getHWSerial() { return hwSerial; }
00212 
00218   bool backgroundProcessingActive() ;
00219 
00224 
00233   bool available() ;
00234 
00245   int read();
00246 
00261   int peek();
00262 
00267 
00286   u8 * readPacket();
00287 
00292 
00293   void setPreferredBaudCode(u8 code, bool renegotiateNow = false) ;
00294 
00295   bool dispatch(DispatchHandler dispatcher = 0, u32 maxPackets = 1) ;
00296 
00297   void suppress(const char type) ;
00298   void allow(const char type) ;
00299 
00300   void reflex(const char type, PacketHandler pfunc) ;
00301 
00302   void otherwise(PacketHandler pfunc) ;
00303 
00308 
00318   void putcInterrupt(u8 byte) ;
00319 
00329   void terpriInterrupt() ;
00330 
00340   void putcBlocking(u8 byte) ;
00341 
00350   void terpriBlocking() ;
00351 
00352   void write(u8 byte) { lowPutc(byte); }
00353   void write(const char * str) { print(str); }
00354   void write(u8 * buf, u32 len) { print(buf,len); }
00355 
00363   void flush() ;
00364 
00365   SFBSerial(int face) ; 
00366 
00367 
00374   static void startup_initialization() ;
00375 
00378   //XXX
00379 private:
00380 
00381   /* Low-level internal routines so BRN routines can talk before BRN is complete.. */
00382   void lowPrint(const char * str) ;
00383   void lowPrintln(const char * str) ;
00384   void lowPutc(const u8 byte) ;
00385   void lowTerpri() ;
00386   void lowPrintOurBRO() ;        /* Print our current baud rate offer */ 
00387 
00388   void maybeBlockForOutput() ;  /* Block until output space available, if we're FLAG_BLOCKING */ 
00389 
00390   static PacketBuffer sharedBuffer;
00391 
00392   SFBHWSerial hwSerial;        /* Platform-specific state and methods */
00393 
00394   u32 baud;
00395   u32 nextTimeout;             /* when we're next to act */ 
00396   SFBAlarmIndexType alarmNumber; /* Our alarm number, if != 0 */ 
00397   const u8 face;                 
00398   u8 flags;
00399   u8 state;                    /* Current state in BRN state machine */ 
00400   u8 preferredCode;            /* Our current preferred baud rate code */ 
00401   u8 selectedCode;             /* negotiated baud rate code */ 
00402   bool selectedOdd;            /* negotiated odd parity (else none) */ 
00403   bool haveBufferedByte;       /* for ::available() */ 
00404   u8 bufferedByte;
00405   enum {
00406     STATE_RESET,                /* 0 Entered to send a reset packet */ 
00407     STATE_INIT,                 /* 1 Initial state */ 
00408     STATE_LISTEN,               /* 2 Sending/waiting for SIM */ 
00409     STATE_OFFER,                /* 3 Sent/waiting for SB */ 
00410     STATE_CONFIRM,              /* 4 Sent/waiting for SS */ 
00411     STATE_WAIT,                 /* 5 Delay after baud changed */ 
00412     STATE_DONE,                 /* 6 BRN finished */ 
00413     STATE_SHOWTIME,             /* 7 Queueing and dispatching packets */ 
00414     STATE_CHECKIN,              /* 8 SRU sent to request SIM */ 
00415     MAX_STATES
00416   };
00417 
00418   enum {
00419     FLAG_RUNNING =   0x01,     /* Port is in use (on our side.  This doesn't imply a live connection.) */
00420     FLAG_ODD_PARITY= 0x02,     /* Port is using odd parity (vs no parity) */
00421     FLAG_CONSCIOUS = 0x04,     /* Port is under conscious control - no BRN or bkgd packets will be sent */
00422     FLAG_BRN_DONE  = 0x08,     /* Baud rate negotiation has succeeded or is under conscious control */
00423     FLAG_BLOCKING_BYTES= 0x10, /* Port is running in byte-by-byte mode, with blocking output */
00424     FLAG_GPIOS     = 0x20,     /* Port pins are in use as non-UART pins, we can't touch them */
00425     FLAG_CONNECTED = 0x40,     /* We have received data lately on this face; there's something out there */
00426     FLAG_RSRVD8    = 0x80      /* Reserved */
00427   };
00428 
00429   void start(u32 baud, u8 startFlags) ;
00430 
00431   void stop() ;
00432 
00433   void setBaudRate(u32 baud, bool isOddParity = false) ;
00434 
00435   void setOddParity(bool isOdd) {
00436     if (isOdd) flags |= FLAG_ODD_PARITY;
00437     else flags &= ~FLAG_ODD_PARITY;
00438   }
00439 
00440   typedef void (*InitHandler)(u8 face);
00441   static const char backgroundProcessorTypes[];
00442   static const PacketHandler backgroundProcessorHandlers[];
00443   static const InitHandler backgroundProcessorInits[];
00444 
00445   void backgroundProcessingInit() ;
00446 
00447   static void stateTimeout(u32 when, void * arg) ;
00448 
00449   void step(u32 when, u8 * spacket) ; /* Step the state machine.  spacket==0 means timeout occurred */
00450 
00451   bool stepInit(u32 when, u8 * spacket) ; /* step in state INIT */
00452   bool stepListen(u32 when, u8 * spacket) ; /* step in state LISTEN */
00453   bool stepOffer(u32 when, u8 * spacket) ; /* step in state OFFER */
00454   bool stepConfirm(u32 when, u8 * spacket) ; /* step in state CONFIRM */
00455   bool stepWait(u32 when, u8 * spacket) ; /* step in state WAIT */
00456   bool stepDone(u32 when, u8 * spacket) ; /* step in state DONE */
00457   bool stepShowtime(u32 when, u8 * spacket) ; /* step in state SHOWTIME */
00458   bool stepCheckin(u32 when, u8 * spacket) ; /* step in state CHECKIN */
00459 
00460   void setState(u8 newState, u32 aboutHowManyMs) ;
00461 
00462   static void ppacketDispatcher(u8 * packet) ;
00463 
00464   static void rpacketDispatcher(u8 * packet) ;
00465 
00466   static void spacketDispatcher(u8 * packet) ;
00467   static void spacketInit(u8 face) ;
00468 
00469 };
00470    
00471 /* The one-time serial startup code */
00472 extern void serial_startup_initialization() ;
00473 
00474 /* Some utility functions for packet handling */
00475 extern bool zPacketPrefix(u8 * p1, const char * to) ;
00476 extern bool packetPrefix(u8 * p1, const u8 * to, const u32 len) ;
00477 
00491 extern SFBSerial Faces[FACE_COUNT]; // Declared here but defined in SFBHWSerial(Board|Host)
00492 #define NorthFace Faces[NORTH]      
00493 #define SouthFace Faces[SOUTH]      
00494 #define EastFace Faces[EAST]        
00495 #define WestFace Faces[WEST]        
00496 
00497 /* Make just plain 'Serial' be the same as 'NorthSerial',
00498  * so that Arduinoish code will have some place to go.
00499  *
00500  * Ditto for 'Serial1', etc, so Arduino Mega examples can fly
00501  */
00502 #define Serial NorthFace        
00503 #define Serial1 SouthFace       
00504 #define Serial2 EastFace        
00505 #define Serial3 WestFace        
00506 
00507 #endif  /* SFBSERIAL_H */
00508 

Generated on Thu Jan 7 03:43:47 2010 for SFB by doxygen 1.5.9