# SFBSerial Class Reference

A serial communications "endpoint", implementing the SFB packet protocol, including baud rate negotiation (BRN). More...

`#include <SFBSerial.h>`

Collaboration diagram for SFBSerial:

[legend]

## Public Member Functions
Initialization and termination
void | begin ()
| Start packet communication, operating under "full reflex control" with interrupt-based I/O.
void | begin (u32 baud, bool manual=true)
| Start packet communication, operating under "conscious" control or in "manual" byte-at-a-time mode.
void | reserve ()
| Reserve the RX and TX pins of this face for general-purpose I/Os, instead of serial communications.
void | end ()
| Do not use the RX and TX pins of this face, either for serial communications or for GPIOs.
Printing
void | print (const char *str)
| Same as facePrint(u8 face, const char * str) given this getFace().
void | print (const u8 *str, u32 len)
| Same as facePrint(u8 face, const u8 * str, u32 len) given this getFace().
void | print (int decimal)
| Same as facePrint(u8 face, int decimal) given this getFace().
void | print (unsigned int decimal)
| Same as facePrint(u8 face, unsigned int decimal) given this getFace().
void | print (long decimal)
| Same as facePrint(u8 face, long decimal) given this getFace().
void | print (unsigned long decimal)
| Same as facePrint(u8 face, unsigned long decimal) given this getFace().
void | print (long decimal, int code)
| Same as facePrint(u8 face, unsigned long decimal, int code) given this getFace().
void | print (double val)
| Same as facePrint(u8 face, double val) given this getFace().
void | println ()
| Same as facePrintln(u8 face) given this getFace().
void | println (const char *str)
| Same as facePrintln(u8 face, const char * str) given this getFace().
void | println (const u8 *str, u32 len)
| Same as facePrintln(u8 face, const u8 * str, u32 len) given this getFace().
void | println (int decimal)
| Same as facePrintln(u8 face, int decimal) given this getFace().
void | println (unsigned int decimal)
| Same as facePrintln(u8 face, unsigned int decimal) given this getFace().
void | println (long decimal)
| Same as facePrintln(u8 face, long decimal) given this getFace().
void | println (unsigned long decimal)
| Same as facePrintln(u8 face, unsigned long decimal) given this getFace().
void | println (long decimal, int code)
| Same as facePrintln(u8 face, long decimal) given this getFace().
void | println (double val)
| Same as facePrintln(u8 face, long val) given this getFace().
void | printlnCheckByte ()
| Same as facePrintlnCheckByte(u8 face) given this getFace().
Accessors
bool | isInUse ()
| Are we in use?
bool | isManualMode ()
| Are we in manual mode?
bool | isReflexMode ()
| Are we in reflex mode?
bool | isConsciousMode ()
| Are we in conscious mode?
void | switchToBlocking ()
u32 | getBaud ()
| What is our baud rate?
bool | getOddParity ()
| Are we running odd parity (vs none)?
u32 | getFace ()
| What is our face number?
bool | ready ()
| Is this SFBSerial currently capable of printing?
u32 | inputBufferUsed ()
u32 | outputBufferUsed ()
u32 | inputBufferFree ()
u32 | outputBufferFree ()
u32 | brokenPackets ()
void | incrBrokenPacketCount ()
SFBHWSerial & | getHWSerial ()
| Access the underlying SFBHWSerial object that actually performs the input and output for this SFBSerial.
bool | backgroundProcessingActive ()
| Is this SFBSerial operating and in full reflex control?
Legacy byte-at-a-time
bool | available ()
| Check if at least one byte of input is available.
int | read ()
| Read the next byte from this serial face, if any are immediately available.
int | peek ()
| Peek at the next byte from this serial face, if any are immediately available, without consuming it.
Conscious packet handling
u8 * | readPacket ()
| Read the next packet from this serial face, if any are immediately available.
Configuration
void | setPreferredBaudCode (u8 code, bool renegotiateNow=false)
bool | dispatch (DispatchHandler dispatcher=0, u32 maxPackets=1)
void | suppress (const char type)
void | allow (const char type)
void | reflex (const char type, PacketHandler pfunc)
void | otherwise (PacketHandler pfunc)
## Low-level and internal use
void | putcInterrupt (u8 byte)
| Low level routine to print a single byte, if possible.
void | terpriInterrupt ()
| Low level routine to terminate a packet, if possible.
void | putcBlocking (u8 byte)
| Low level routine to print a single byte.
void | terpriBlocking ()
| Low level routine to terminate a packet.
void | write (u8 byte)
void | write (const char *str)
void | write (u8 *buf, u32 len)
void | flush ()
| Flushes the face of incoming serial data.
| SFBSerial (int face)
| Construct an SFBSerial with face number face.
static void | startup_initialization ()
| Low level routine to initialize the SFBSerial subsystem.

## Detailed Description

A serial communications "endpoint", implementing the SFB packet protocol, including baud rate negotiation (BRN).

The SFBSerial class delegates to hardware-specific SFBHWSerial objects to perform actual input and output; the class itself is responsible for performing BRN and presenting a generally uniform communications API.

## Constructor & Destructor Documentation

SFBSerial::SFBSerial | ( | int | face | ) |

Construct an SFBSerial with face number face.

Intended for library internal use during system startup only.

## Member Function Documentation

bool SFBSerial::available | ( |  | ) |

Check if at least one byte of input is available.

Only callable after the serial face has been started in 'manual' mode (i.e., via 'begin(BAUD_RATE)' or 'begin(BAUD_RATE,true)').

Returns:
  `true` if and only if a byte can now be read() from this face, `false` otherwise.

Blinks:
  E_API_ILLEGAL_STATE if the face has not been opened (most recently) in 'manual' mode.

bool SFBSerial::backgroundProcessingActive | ( |  | ) |

Is this SFBSerial operating and in full reflex control?

Returns:
  `true` if this SFBSerial was started via a call to SFBSerial::begin() since the most recent call to SFBSerial::begin(u32 baud), SFBSerial::begin(u32 baud, bool manual), or SFBSerial::reserve(), and returns `false` otherwise.

void SFBSerial::begin | ( | u32 | baud,
|  | bool | manual = `true` |
| ) |  |  |

Start packet communication, operating under "conscious" control or in "manual" byte-at-a-time mode.

Conscious control is selected if the manual argument is specified as `false`; manual mode is selected if manual is omitted or specified as `true`.

This method provides access to two of the four ways of using the RX and TX pins on an SFB face; the other two are:

- Packet communication under "full reflex control" with interrupt-based I/O, via begin().

- RX and TX used as GPIO pins rather than a serial port, via reserve().

The differences between "full reflex control" as initiated by begin(), and "conscious control" as can be initiated by this method, are:

- Conscious control selects the baud rate explicitly, and so, unlike full reflex control, baud rate negotiation is not performed, and

- Full reflex control triggers reflex handlers for received packets automatically (during delay() calls, and in between calls to the sketch `loop()` method), but conscious control does not. In conscious control the sketch must deliberately check for and handle available packets (via readPacket and/or dispatch()). If the sketch fails to call either method frequently enough to respond to arrived packets, the face's input buffer will fill and further packets will be discarded until room is available.

Under manual control, normal line-oriented packet processing and dispatching is circumvented, and instead each byte sent or received is treated as a packet with a packetLength() of 1. Outgoing bytes are sent literally with no framing or escaping, and incoming single-byte 'packets' can be accessed by calling read(). Note that all normal SFB packet communication is inherently line-buffered, and such manual control is the only mechanism (provided by the library) when byte-at-a-time round trip communications is required.

Parameters:

  | baud | The baud rate to configure the hardware. The SFB is not limited to "standard baud rates"; on the board itself arbitrary baud rates in the range of perhaps 110 baud to 230,400 baud (or possibly even higher, depending on total interrupt load) can be specified.
  | manual | If `true`, byte-at-a-time I/O is selected; if `false`, normal packet-oriented I/O is selected.

Side Effects:
  The serial communications hardware in the SFBHWSerial supporting this object is configured appropriately, its transmit and receive buffers are SFBFrame::reset(), and the baud rate is set as indicated. The internal state machine for baud rate negotiation is shut down.

Example:

        void setup() {
          EastFace.begin(9600,false);          // Start east face at 9600 baud, conscious control
        }
        void MyDispatcher(u8 * packet, u8 face) {            // A special routine to 'dispatch' east packets
          if (packetLength(packet) > 0 && packet[0] == 'x')  // Check for our Packets Of Interest
            println("Received 'x' packet from east");        // Announce arrival to everybody
        }
        void loop() {
          EastFace.println("status");          // Talk to whatever's out there
          EastFace.dispatch(MyDispatcher, 10); // Call MyDispatcher up to 10 times, if packets are available
          delay(1000);                         // Wait a second
        }

        void setup() {
          SouthFace.begin(300);                // Start South at 300 baud, under byte-at-a-time manual control
        }
        void loop() {
          int ch;
          ch = SouthFace.read();               // See if a byte is available
          if (ch >= 0) {                       // We got something!  Do work on it
            if (ch >= 'A' && ch <= 'A')        // If upper case..
              ch += 'a'-'A';                   // ..convert it to lower case
            SouthFace.print((u8) ch, BYTE);    // and echo it back to them
          }
        }

void SFBSerial::begin | ( |  | ) |

Start packet communication, operating under "full reflex control" with interrupt-based I/O.

This method is one of the four ways of using the RX and TX pins on an SFB face; the other three are:

- Packet communication under "conscious control" with interrupt-based I/O, via begin(u32, bool) with the second argument explicitly set to `false`.

- Byte-by-byte communication under "manual control" with no packet dispatching, via begin(u32,bool) with the second argument omitted or set to `true`;

- RX and TX used as GPIO pins rather than a serial port, via reserve().

"Full reflex control" as initiated by this method is the default mode of operation for the four faces. During initialization, after the sketch `setup()` routine has returned, this method is called automatically on any of the four SFB faces (NorthFace, SouthFace, EastFace, WestFace) that were not initialized in any of the other three ways.

Side Effects:
  The serial communications hardware in the SFBHWSerial supporting this object is configured appropriately, and its transmit and receive buffers are SFBPacketIO::reset(). The internal state machine is initialized, starting the baud rate negotiation protocol, which commences by setting the baud to the SFBAUD_RENDEZVOUS rate, and then (asynchronously, after this method has returned) transmitting "probe packets" and listening for any responses.

Example:

        void setup() {
          NorthFace.begin();                   // Start a face explicitly now

          while (NorthFace.ready() == false)   // Wait until some SFB-aware entity has
            delay(1);                          // successfully negotiated with us

          NorthFace.println("foo");            // Then say something to them
        }

        ...

void SFBSerial::end | ( |  | ) |

Do not use the RX and TX pins of this face, either for serial communications or for GPIOs.

Cancels the effect of a begin() or a reserve() call; after calling this method, isInUse() will return `false`.

Side Effects:
  The serial communications (UART) hardware in the SFBHWSerial supporting this object is disconnected and powered down. In addition, the RX-and-TX-as-GPIOs internal flags are cleared.

Since:
  0.9.11

void SFBSerial::flush | ( |  | ) |

Flushes the face of incoming serial data.

That is, any call to read() or available() will return only data received after all the most recent call to flush(). Note this call is legal whether the serial face was started in 'manual' mode (i.e., via 'begin(BAUD_RATE)' or 'begin(BAUD_RATE,true)'), or 'conscious' mode (via 'begin(BAUD_RATE,false)'), or full packet processing mode (via 'begin()') -- in the latter two cases all pending packets are discarded.

u32 SFBSerial::getBaud | ( |  | ) | `[inline]`

What is our baud rate?

Returns:
  our current baud rate.

u32 SFBSerial::getFace | ( |  | ) | `[inline]`

What is our face number?

Returns:
  our face code.

SFBHWSerial& SFBSerial::getHWSerial | ( |  | ) | `[inline]`

Access the underlying SFBHWSerial object that actually performs the input and output for this SFBSerial.

Returns:
  a reference to the underlying SFBHWSerial.

bool SFBSerial::getOddParity | ( |  | ) | `[inline]`

Are we running odd parity (vs none)?

Returns:
  true if odd parity, false is none.

bool SFBSerial::isConsciousMode | ( |  | ) |

Are we in conscious mode?

Returns:
  true if we're running as a serial port in conscious packet handling mode.

bool SFBSerial::isInUse | ( |  | ) |

Are we in use?

Returns:
  true if in use as either serial port or GPIOs.

bool SFBSerial::isManualMode | ( |  | ) |

Are we in manual mode?

Returns:
  true if we're running as a serial port in byte-at-a-time mode.

bool SFBSerial::isReflexMode | ( |  | ) |

Are we in reflex mode?

Returns:
  true if we're running as a serial port in reflex packet handling mode.

int SFBSerial::peek | ( |  | ) |

Peek at the next byte from this serial face, if any are immediately available, without consuming it.

Only callable after the serial face has been started in 'manual' mode (i.e., via 'begin(BAUD_RATE)' or 'begin(BAUD_RATE,true)'). Any byte returned by this method is not removed from the input stream, and the same byte will be returned on the next call to via read.

Returns:
  the next byte to be read, greater than or equal to 0, or -1 if no byte is immediately available to be read

Blinks:
  E_API_ILLEGAL_STATE if the face has not been opened (most recently) in 'manual' mode.

Since:
  0.9.3

void SFBSerial::print | ( | double | val | ) | `[inline]`

Same as facePrint(u8 face, double val) given this getFace().

void SFBSerial::print | ( | long | decimal,
|  | int | code |
| ) |  |  | `[inline]`

Same as facePrint(u8 face, unsigned long decimal, int code) given this getFace().

void SFBSerial::print | ( | unsigned long | decimal | ) | `[inline]`

Same as facePrint(u8 face, unsigned long decimal) given this getFace().

void SFBSerial::print | ( | long | decimal | ) | `[inline]`

Same as facePrint(u8 face, long decimal) given this getFace().

void SFBSerial::print | ( | unsigned int | decimal | ) | `[inline]`

Same as facePrint(u8 face, unsigned int decimal) given this getFace().

void SFBSerial::print | ( | int | decimal | ) | `[inline]`

Same as facePrint(u8 face, int decimal) given this getFace().

void SFBSerial::print | ( | const u8 * | str,
|  | u32 | len |
| ) |  |  | `[inline]`

Same as facePrint(u8 face, const u8 * str, u32 len) given this getFace().

void SFBSerial::print | ( | const char * | str | ) | `[inline]`

Same as facePrint(u8 face, const char * str) given this getFace().

void SFBSerial::println | ( | double | val | ) | `[inline]`

Same as facePrintln(u8 face, long val) given this getFace().

void SFBSerial::println | ( | long | decimal,
|  | int | code |
| ) |  |  | `[inline]`

Same as facePrintln(u8 face, long decimal) given this getFace().

void SFBSerial::println | ( | unsigned long | decimal | ) | `[inline]`

Same as facePrintln(u8 face, unsigned long decimal) given this getFace().

void SFBSerial::println | ( | long | decimal | ) | `[inline]`

Same as facePrintln(u8 face, long decimal) given this getFace().

void SFBSerial::println | ( | unsigned int | decimal | ) | `[inline]`

Same as facePrintln(u8 face, unsigned int decimal) given this getFace().

void SFBSerial::println | ( | int | decimal | ) | `[inline]`

Same as facePrintln(u8 face, int decimal) given this getFace().

void SFBSerial::println | ( | const u8 * | str,
|  | u32 | len |
| ) |  |  | `[inline]`

Same as facePrintln(u8 face, const u8 * str, u32 len) given this getFace().

void SFBSerial::println | ( | const char * | str | ) | `[inline]`

Same as facePrintln(u8 face, const char * str) given this getFace().

void SFBSerial::println | ( |  | ) | `[inline]`

Same as facePrintln(u8 face) given this getFace().

void SFBSerial::printlnCheckByte | ( |  | ) |

Same as facePrintlnCheckByte(u8 face) given this getFace().

void SFBSerial::putcBlocking | ( | u8 | byte | ) |

Low level routine to print a single byte.

Intended for library internal use only. Designed for use when the underlying SFBHWSerial is being run via blocking calls (in other words, 'manual' mode only).

Parameters:

  | byte | the byte to print

Side Effects:
  A byte is output to the hardware, which may or may not have any externally visible effects, depending on hardware configuration.

void SFBSerial::putcInterrupt | ( | u8 | byte | ) |

Low level routine to print a single byte, if possible.

Intended for library internal use only. Designed for use when the underlying SFBHWSerial is being run via interrupts (in other words, in 'reflex' or 'conscious', but not 'manual' modes).

Parameters:

  | byte | the byte to print

Side Effects:
  If ready() is `true`, a byte is printed to the underlying SFBHWSerial, with whatever side effects that implies.

int SFBSerial::read | ( |  | ) |

Read the next byte from this serial face, if any are immediately available.

Only callable after the serial face has been started in 'manual' mode (i.e., via 'begin(BAUD_RATE)' or 'begin(BAUD_RATE,true)').

Returns:
  the next byte read, greater than or equal to 0, or -1 if no byte can immediately be read

Blinks:
  E_API_ILLEGAL_STATE if the face has not been opened (most recently) in 'manual' mode.

u8 * SFBSerial::readPacket | ( |  | ) |

Read the next packet from this serial face, if any are immediately available.

Only callable after the serial face has been started in 'conscious' mode (i.e., via 'begin(BAUD_RATE,false)'). Returns a null pointer if no complete packet is available. When a non-null pointer is returned, it points to memory owned by the core libraries, not the sketch, and the returned pointer is valid only ubtil the next call to readPacket on the same face (or the next call on begin, reserve, or flush on the face, whichever comes first.)

Returns:
  a pointer to the next packet read, or 0 if no complete packet is currently available.

Blinks:
  E_API_ILLEGAL_STATE if the face has not been opened (most recently) in 'conscious' mode.

Side Effects:
  On a non-null return, the input corresponding to the returned packet has been removed from the serial face input stream.

Since:
  0.9.3

bool SFBSerial::ready | ( |  | ) |

Is this SFBSerial currently capable of printing?

Returns:
  `true` if one of the following is true:

- this SFBSerial was started under conscious control (using SFBSerial::begin(u32 baud)), or

- this SFBSerial was started under manual control (using SFBSerial::begin(u32 baud, bool manual) with `manual` omitted or set to `true`), or

- this SFBSerial was started under reflex control (using SFBSerial::begin()) and a successfully negotiated baud rate is currently in use.

and returns false otherwise.

void SFBSerial::reserve | ( |  | ) |

Reserve the RX and TX pins of this face for general-purpose I/Os, instead of serial communications.

This method is one of the four ways of using the RX and TX pins on an SFB face; the other three are:

- Packet communication under "full reflex control" with interrupt-based I/O, via begin().

- Packet communication under "conscious control" with interrupt-based I/O, via begin(u32,bool) with the second argument explicitly set to `false`.

- Byte-by-byte communication under "manual control" with no packet dispatching, via begin(u32,bool) with the second argument omitted or set to `true`;

Although there is no explicit 'end()' method to bookend a 'begin()', calling `reserve()` has that effect. After calling `reserve()`, the FACE_RX_PIN and FACE_TX_PIN can be configured and used like any other GPIOs.

Side Effects:
  The serial communications (UART) hardware in the SFBHWSerial supporting this object is disconnected and powered down, and internal flags are set to record that the pins are reserved for GPIO usage.

Example:

        void setup() {
          WestFace.reserve();              // Don't do serial on the west face (say we need those pins)
          pinMode(WEST_RX_PIN, OUTPUT);    // Make WEST RX an output (even though it's normally an input)..
          pinMode(WEST_TX_PIN, INPUT);     // ..and vv for WEST TX -- just to show we can.
        }
        void loop() {
          digitalWrite(WEST_RX_PIN, digitalRead(WEST_TX_PIN));  // Do whatever with our digital pins..
          println("Are we there yet?");    // Will go out all faces _except_ WestFace, which
          delay(1000);                     // we reserved in setup()..
        }

void SFBSerial::startup_initialization | ( |  | ) | `[static]`

Low level routine to initialize the SFBSerial subsystem.

Intended for library internal use during system startup only.

Side Effects:
  The SFBSerial subsystem is initialized: Reflexes are installed for several packet types, SFBAlarm's are created to manage timeouts during communications, etc.

void SFBSerial::terpriBlocking | ( |  | ) |

Low level routine to terminate a packet.

Intended for library internal use only. Designed for use when the underlying SFBHWSerial is being run via blocking calls (in other words, 'manual' mode only).

Side Effects:
  A single newline byte (ASCII '
  ', value 10, `0xa`) is output to the hardware, which may or may not have any externally visible effects, depending on hardware configuration.

void SFBSerial::terpriInterrupt | ( |  | ) |

Low level routine to terminate a packet, if possible.

Intended for library internal use only. Designed for use when the underlying SFBHWSerial is being run via interrupts (in other words, in 'reflex' or 'conscious', but not 'manual' modes).

Parameters:

  | byte | the byte to print

Side Effects:
  If ready() is `true`, the current packet in the underlying SFBHWSerial is terminated, with whatever side effects that implies.

The documentation for this class was generated from the following files:

- src/include/SFBSerial.h
- src/components/library/SFBSerial.cpp