Library for HopeRF RFM22 / RFM22B transceiver module ported to mbed. Original Software from Mike McCauley (mikem@open.com.au) . See http://www.open.com.au/mikem/arduino/RF22/

Dependents:   RF22_MAX_test_Send Geofence_receiver Geofence_sender Geofence_sender ... more

More Info about RFM22-modules like connecting and a demo-program see RF22-Notebook

Revision:
5:0386600f3408
Parent:
0:79c6d0071c4c
Child:
6:468dc5b3942f
--- a/RF22.h	Sun Feb 19 21:12:10 2012 +0000
+++ b/RF22.h	Sat Mar 02 20:49:07 2013 +0000
@@ -1,15 +1,17 @@
 // RF22.h
 // Author: Mike McCauley (mikem@open.com.au)
 // Copyright (C) 2011 Mike McCauley
-// $Id: RF22.h,v 1.19 2011/10/09 21:22:24 mikem Exp mikem $
+// $Id: RF22.h,v 1.23 2013/02/06 21:33:56 mikem Exp mikem $
+//
 // ported to mbed by Karl Zweimueller
-//
 /// \mainpage RF22 library for Arduino
 ///
 /// This is the Arduino RF22 library.
 /// It provides an object-oriented interface for sending and receiving data messages with Hope-RF
-/// RF22B based radio modules, and compatible chips and modules, including the RFM22B transceiver module such as 
-/// this one: http://www.sparkfun.com/products/10153
+/// RF22B based radio modules, and compatible chips and modules, 
+/// including the RFM22B transceiver module such as 
+/// this bare module: http://www.sparkfun.com/products/10153
+/// and this shield: https://www.sparkfun.com/products/11018
 ///
 /// RF22 also supports some of the features of ZigBee and XBee, 
 /// (such as mesh routing and automatic route discovery), 
@@ -48,9 +50,13 @@
 /// Example Arduino programs are included to show the main modes of use.
 ///
 /// The version of the package that this documentation refers to can be downloaded 
-/// from http://www.open.com.au/mikem/arduino/RF22/RF22-1.10.zip
+/// from http://www.open.com.au/mikem/arduino/RF22/RF22-1.25.zip
 /// You can find the latest version at http://www.open.com.au/mikem/arduino/RF22
 ///
+/// You can also find online help and disussion at http://groups.google.com/group/rf22-arduino
+/// Please use that group for all questions and discussions on this topic. 
+/// Do not contact the author directly, unless it is to discuss commercial licensing.
+///
 /// Tested on Arduino Diecimila and Mega with arduino-0021 
 /// on OpenSuSE 11.1 and avr-libc-1.6.1-1.15,
 /// cross-avr-binutils-2.19-9.1, cross-avr-gcc-4.1.3_20080612-26.5.
@@ -75,6 +81,11 @@
 /// 'Virtual Wire' http://www.open.com.au/mikem/arduino/VirtualWire.pdf also from the same author.
 ///
 /// \par Connecting RFM-22 to Arduino
+///
+/// If you have the Sparkfun RFM22 Shield (https://www.sparkfun.com/products/11018)
+/// the connections described below are done for you on the shield, no changes required, 
+/// just add headers and plug it in to an Arduino (but not and Arduino Mega, see below)
+///
 /// The physical connection between the RF22B and the Arduino require 3.3V, the 3 x SPI pins (SCK, SDI, SDO), 
 /// a Slave Select pin and an interrupt pin.
 /// Note also that on the RFF22B, it is required to control the TX_ANT and X_ANT pins of the RFM22 in order to enable the
@@ -105,7 +116,7 @@
 ///                              SDN-/ (shutdown in)
 ///                 3V3----------VCC   (3.3V in)
 /// interrupt 0 pin D2-----------NIRQ  (interrupt request out)
-///          SS pin D10----------NSEL  (chip select in)
+///          SS pin D53----------NSEL  (chip select in)
 ///         SCK pin D52----------SCK   (SPI clock in)
 ///        MOSI pin D51----------SDI   (SPI Data in)
 ///        MISO pin D50----------SDO   (SPI data out)
@@ -116,27 +127,37 @@
 /// \endcode
 /// and you can then use the default constructor RF22(). 
 /// You can override the default settings for the SS pin and the interrupt 
-/// in the RF22 constructor if you wish to connect the slave select SS to other than pin D10 
+/// in the RF22 constructor if you wish to connect the slave select SS to other than the normal one for your 
+/// Arduino (D10 for Diecimila, Uno etc and D53 for Mega)
 /// or the interrupt request to other than pin D2.
+///
 /// It is possible to have 2 radios conected to one arduino, provided each radio has its own 
 /// SS and interrupt line (SCK, SDI and SDO are common to both radios)
 ///
-/// \par Example programs
+/// Caution: on some Arduinos such as the Mega 2560, if you set the slave select pin to be other than the usual SS 
+/// pin (D53 on  Mega 2560), you may need to set the usual SS pin to be an output to force the Arduino into SPI 
+/// master mode.
 ///
-/// The following example programs are provided:
-/// - rf22_client, rf22_server: Simple client/server pair using RF22 class
-/// - rf22_datagram_client, rf22_datagram_server: Simple client/server pair using RF22Datagram class
-/// - rf22_reliable_datagram_client, rf22_reliable_datagram_server:
-///   Simple client/server pair using RF22ReliableDatagram class
-/// - rf22_router_client, rf22_router_server1, rf22_router_server2, rf22_router_server3: 
-///   Simple RF22Router network. Requires Arduino Mega.
-/// - rf22_mesh_client, rf22_mesh_server1, rf22_mesh_server2, rf22_mesh_server3: 
-///   Simple RF22Mesh network. Requires Arduino Mega.
-/// - rf22_test: Some test code used during development, shows how to call some support functions
-/// - rf22_snoop: Dumps in ASCII the contents of all RF22 messages received
-/// - rf22_specan: Simple spectrum analyser using the RSSI measurements of the RF22
-///   (see <a href="specan1.png">Sample output</a> showing a plot from 395.0MHz to 396.0MHz of a 
-///   signal generator at 395.5MHz amplitude modulated at 100% 1kHz)
+/// Caution: Power supply requirements of the RF22 module may be relevant in some circumstances: 
+/// RF22 modules are capable of pulling 80mA+ at full power, where Arduino's 3.3V line can
+/// give 50mA. You may need to make provision for alternate power supply for
+/// the RF22, especially if you wish to use full transmit power, and/or you have
+/// other shields demanding power. Inadequate power for the RF22 is reported to cause symptoms such as:
+/// - reset's/bootups terminate with "init failed" messages
+///  -random termination of communication after 5-30 packets sent/received
+///  -"fake ok" state, where initialization passes fluently, but communication doesn't happen
+/// -shields hang Arduino boards, especially during the flashing
+///
+///
+/// \par Interrupts
+///
+/// The RF22 library uses interrupts to react to events in the RF22 module, 
+/// such as the reception of a new packet, or the completion of transmission of a packet. 
+/// The RF22 library interrupt service routine reads status from and writes data
+/// to the the RF22 module via the SPI interface. It is very important therefore,
+/// that if you are using the RF22 library with another SPI based deviced, that you
+/// disable interrupts while you transfer data to and from that other device.
+/// Use cli() to disable interrupts and sei() to reenable them.
 ///
 /// \par Memory
 ///
@@ -160,7 +181,35 @@
 /// 
 /// With an Arduino Mega, with 8 kbytes of SRAM, there is much more RAM headroom for 
 /// your own elaborate programs. 
-/// This library is reported not to work with Arduino Pro Mini and Arduino UNO, but these have not been tested here.
+/// This library is reported to work with Arduino Pro Mini, but that has not been tested by me.
+///
+/// The Arduino UNO is now known to work with RF22. 
+///
+/// \par Automatic Frequency Control (AFC)
+///
+/// The RF22M modules use an inexpensive crystal to control the frequency synthesizer, and therfore you can expect 
+/// the transmitter and receiver frequencies to be subject to the usual inaccuracies of such crystals. The RF22
+/// contains an AFC circuit to compensate for differences in transmitter and receiver frequencies. 
+/// It does this by altering the receiver frequency during reception by up to the pull-in frequency range. 
+/// This RF22 library enables the AFC and by default sets the pull-in frequency range to
+/// 0.05MHz, which should be sufficient to handle most situations. However, if you observe unexplained packet losses
+/// or failure to operate correctly all the time it may be because your modules have a wider frequency difference, and
+/// you may need to set the afcPullInRange to a differentvalue, using setFrequency();
+///
+/// \par Performance
+///
+/// Some simple speed performance tests have been conducted.
+/// In general packet transmission rate will be limited by the modulation scheme.
+/// Also, if your code does any slow operations like Serial printing it will also limit performance. 
+/// We disabled any printing in the tests below.
+/// We tested with RF22::GFSK_Rb125Fd125, which is probably the fastest scheme available.
+/// We tested with a 13 octet message length, over a very short distance of 10cm.
+///
+/// Transmission (no reply) tests with modulation RF22::GFSK_Rb125Fd125 and a 
+/// 13 octet message show about 330 messages per second transmitted.
+///
+/// Transmit-and-wait-for-a-reply tests with modulation RF22::GFSK_Rb125Fd125 and a 
+/// 13 octet message (send and receive) show about 160 round trips per second.
 ///
 /// \par Installation
 ///
@@ -213,8 +262,62 @@
 /// \version 1.9 Fixed typos in RF22_REG_21_CLOCk*. Reported by Steffan Woltjer.
 /// \version 1.10 Fixed a problem where a IFFERR during transmission could cause an infinite loop and a hang. 
 ///              Reported by Raymond Gilbert.
+/// \version 1.11 Fixed an innocuous typo in RF22::handleInterrupt. Reported by Zhentao.
 ///
+/// \version 1.12 Improvements to RF22::init from Guy Molinari to improve compatibility with some 
+/// Arduinos. Now reported to be working with official Mega 2560 and Uno.
+/// Updated so compiles on Arduino 1.0.
 ///
+/// \version 1.13 Announce google support group
+///
+/// \version 1.14 Added definitions for bits and masks in RF22_REG_1D_AFC_LOOP_GEARSHIFT_OVERRIDE 
+/// and RF22_REG_1E_AFC_TIMING_CONTROL  
+///
+/// \version 1.15 Small alterations to initialisation code so that SS pin is not set to output: may cause 
+/// interference with other devices connected to the Arduino. Testing with Uno: OK.
+///
+/// \version 1.16 Fixed a problem that prevented building with arduino 0021
+///
+/// \version 1.17 Added optional AFC pull-in frequency range argument to setFrequency(). 
+/// Default AFC pull-in range set to 0.05MHz
+///
+/// \version 1.18 Changed default value for slave slect pin in constructor to be SS, ie the normal one for 
+/// the compiled Arduino (D10 for Diecimila, Uno etc and D53 for Mega). This is because some Arduinos such as Mega 2560
+/// reportedly use the type of the SS pin to determine whether to run in slave or master mode. Therfore it
+/// is preferred that the slave select pin actually be the normal SS pin.
+///
+/// \version 1.19 Added new mode() function.
+///  Fixed a potential race condition in RF22Datagram::recvfrom which might cause corrupt from, to, id or flags
+///  under extreme circumstances. Improvements to interrupt hygeine by adding cli()_/sei() around all 
+///  RF22 register acceses. Found that 0 length transmit packets confuses the RF22, so they are now forbidden.
+///  Added IPGateway example, which routes UDP messages from an internet connection using an 
+///  Ethernet Shield and sends them
+///  to a radio whose ID is based on the UDP port. Replies are sent back to the originating UDP
+///  address and port.
+///
+///  \version 1.20 _mode is now volatile.
+///  RF22::send() now waits until any previous transmission is complete before sending.
+///  RF22::waitPacketSent() now waits for the RF22 to not be in _mode == RF22_MODE_TX
+///  _txPacketSent member is now redundant and removed.
+///  Improvements to interrupt handling and blocking. Now use ATOMIC_BLOCK(ATOMIC_RESTORESTATE)
+///  to prevent reenabling interrupts too soon. Thanks to Roland Mieslinger for this suggestion.
+///  Added some performance measurements to documentation.
+///
+///  \version 1.21 Fixed a case where a receiver buffer overflow could occur. Reported by Joe Tuttle.
+///
+///  \version 1.22 Added documentation after testing with Sparkfun RFM22 Shield DEV-11018.
+///                Fixed incorrect link to register calculator excel file, reported by Joey Morin.
+///
+///  \version 1.23 Added support for alternative SPI interfaces, with default implementation for the standard 
+///                Arduino hardware SPI interface. Contributed by Joanna Rutkowska.
+///
+///  \version 1.24 Fixed a problem that could cause corrupted receive messages if a transmit interrupted
+///                a partial receive (as was common with eg ReliableDatagram with poor reception. 
+///                Also fixed possible receive buffer overrun.
+///  \version 1.25 More rigorous use of const, additional register defines (RF22_CRCHDRS RF22_VARPKLEN)
+///                and two methods (setPreambleLength() 
+///                and setSyncWords())made public. Patch provided by 
+///                Matthijs Kooijman.
 /// \author  Mike McCauley (mikem@open.com.au)
 
 #ifndef RF22_h
@@ -232,12 +335,14 @@
 #define RF22_SPI_WRITE_MASK 0x80
 
 // This is the maximum message length that can be supported by this library. Limited by
-// the message length octet in the header. Yes, 255 is correct even though the FIFO size in the RF22 is only
-// 64 octets. We use interrupts to refil the Tx FIFO during transmission and to empty the
-// Rx FIF during reception
+// the single message length octet in the header. 
+// Yes, 255 is correct even though the FIFO size in the RF22 is only
+// 64 octets. We use interrupts to refill the Tx FIFO during transmission and to empty the
+// Rx FIFO during reception
 // Can be pre-defined to a smaller size (to save SRAM) prior to including this header
 #ifndef RF22_MAX_MESSAGE_LEN
-#define RF22_MAX_MESSAGE_LEN 255
+//#define RF22_MAX_MESSAGE_LEN 255
+#define RF22_MAX_MESSAGE_LEN 50
 #endif
 
 // Max number of octets the RF22 Rx and Tx FIFOs can hold
@@ -495,17 +600,21 @@
 #define RF22_WTD                                0x03
 
 //  RF22_REG_1D_AFC_LOOP_GEARSHIFT_OVERRIDE     0x1d
-#define RF22_AFC_EN                             0x40
+#define RF22_AFBCD                              0x80
+#define RF22_ENAFC                              0x40
+#define RF22_AFCGEARH                           0x38
+#define RF22_AFCGEARL                           0x07
 
-// Reg  RF22_REG_1E_AFC_TIMING_CONTROL          0x1e
-#define RF22_AFC_TC                             0x0a
-
-// Reg RF22_REG_2A_AFC_LIMITER                  0x2a
-#define RF22_AFC_LIMIT                          0x50
+// RF22_REG_1E_AFC_TIMING_CONTROL               0x1e
+#define RF22_SWAIT_TIMER                        0xc0
+#define RF22_SHWAIT                             0x38
+#define RF22_ANWAIT                             0x07
 
 // RF22_REG_30_DATA_ACCESS_CONTROL              0x30
 #define RF22_ENPACRX                            0x80
+#define RF22_MSBFRST                            0x00
 #define RF22_LSBFRST                            0x40
+#define RF22_CRCHDRS                            0x00
 #define RF22_CRCDONLY                           0x20
 #define RF22_ENPACTX                            0x08
 #define RF22_ENCRC                              0x04
@@ -536,6 +645,7 @@
 #define RF22_HDLEN_2                            0x20
 #define RF22_HDLEN_3                            0x30
 #define RF22_HDLEN_4                            0x40
+#define RF22_VARPKLEN                           0x00
 #define RF22_FIXPKLEN                           0x08
 #define RF22_SYNCLEN                            0x06
 #define RF22_SYNCLEN_1                          0x00
@@ -582,6 +692,11 @@
 #define RF22_HBSEL                              0x20
 #define RF22_FB                                 0x1f
 
+// Define this to include Serial printing in diagnostic routines
+//#define RF22_HAVE_SERIAL
+
+//#include <GenericSPI.h>
+//#include <HardwareSPI.h>
 /////////////////////////////////////////////////////////////////////
 /// \class RF22 RF22.h <RF22.h>
 /// \brief Send and receive unaddressed, unreliable datagrams.
@@ -613,7 +728,7 @@
     /// setModemConfig() writes the register values to the appropriate RF22 registers
     /// to set the desired modulation type, data rate and deviation/bandwidth.
     /// Suitable values for these registers can be computed using the register calculator at
-    /// "http://www.hoperf.com/upfile/RF22B 23B 31B 42B 43B Register Settings_RevB1-v5.xls"
+    /// http://www.hoperf.com/upload/rf/RF22B%2023B%2031B%2042B%2043B%20Register%20Settings_RevB1-v5.xls
     typedef struct
     {
     uint8_t    reg_1c;   ///< Value for register RF22_REG_1C_IF_FILTER_BANDWIDTH
@@ -637,8 +752,7 @@
     } ModemConfig;
   
     /// Choices for setModemConfig() for a selected subset of common modulation types,
-    /// and data rates. If you need another configuration, use the register calculator at
-    /// "http://www.hoperf.com/upfile/RF22B 23B 31B 42B 43B Register Settings_RevB1-v5.xls"
+    /// and data rates. If you need another configuration, use the register calculator.
     /// and call setModemRegisters() with your desired settings
     /// These are indexes into _modemConfig
     typedef enum
@@ -677,7 +791,7 @@
     /// interrupt and slave select pin. After constructing, you must call init() to initialise the intnerface
     /// and the radio module
     /// \param[in] slaveSelectPin the Arduino pin number of the output to use to select the RF22 before
-    /// accessing it
+    /// accessing it. Defaults to the normal SS pin for your Arduino (D10 for Diecimila, Uno etc, D53 for Mega)
     /// \param[in] interrupt The interrupt number to use. Default is interrupt 0 (Arduino input pin 2)
     RF22(PinName slaveSelectPin , PinName mosi, PinName miso, PinName sclk, PinName interrupt );
   
@@ -717,7 +831,7 @@
     /// \param[in] reg Register number of the first register, one of RF22_REG_*
     /// \param[in] src Array of new register values to write. Must be at least len bytes
     /// \param[in] len Number of bytes to write
-    void           spiBurstWrite(uint8_t reg, uint8_t* src, uint8_t len);
+    void           spiBurstWrite(uint8_t reg, const uint8_t* src, uint8_t len);
 
     /// Reads and returns the device status register RF22_REG_02_DEVICE_STATUS
     /// \return The value of the device status register
@@ -749,7 +863,7 @@
     uint16_t       wutRead();
 
     /// Sets the wakeup timer period registers RF22_REG_14_WAKEUP_TIMER_PERIOD1,
-    /// RF22_REG_15_WAKEUP_TIMER_PERIOD2 and RF22_REG_16_WAKEUP_TIMER_PERIOD3
+    /// RF22_REG_15_WAKEUP_TIMER_PERIOD2 and RF22_R<EG_16_WAKEUP_TIMER_PERIOD3
     /// \param[in] wtm Wakeup timer mantissa value
     /// \param[in] wtr Wakeup timer exponent R value
     /// \param[in] wtd Wakeup timer exponent D value
@@ -758,8 +872,10 @@
     /// Sets the transmitter and receiver centre frequency
     /// \param[in] centre Frequency in MHz. 240.0 to 960.0. Caution, some versions of RF22 and derivatives 
     /// implemented more restricted frequency ranges.
-    /// \return true if the selected frquency centre + (fhch * fhs) is within range
-    boolean        setFrequency(float centre);
+    /// \param[in] afcPullInRange Sets the AF Pull In Range in MHz. Defaults to 0.05MHz (50kHz). Range is 0.0 to 0.159375
+    /// for frequencies 240.0 to 480MHz, and 0.0 to 0.318750MHz for  frequencies 480.0 to 960MHz, 
+    /// \return true if the selected frquency centre + (fhch * fhs) is within range and the afcPullInRange is within range
+    boolean        setFrequency(float centre, float afcPullInRange = 0.05);
 
     /// Sets the frequency hopping step size.
     /// \param[in] fhs Frequency Hopping step size in 10kHz increments
@@ -771,7 +887,8 @@
     /// \return true if the selected frquency centre + (fhch * fhs) is within range
     boolean        setFHChannel(uint8_t fhch);
 
-    /// Reads and returns the current RSSI value from register RF22_REG_26_RSSI
+    /// Reads and returns the current RSSI value from register RF22_REG_26_RSSI. If you want to find the RSSI
+    /// of the last received message, use lastRssi() instead.
     /// \return The current RSSI value 
     uint8_t        rssiRead();
 
@@ -780,9 +897,9 @@
     uint8_t        ezmacStatusRead();
 
     /// Sets the parameters for the RF22 Idle mode in register RF22_REG_07_OPERATING_MODE. 
-    /// Idle mode is the mode the RF22 wil be in when not transmitting or receiving. The default idle mode 
+    /// Idle mode is the mode the RF22 will be in when not transmitting or receiving. The default idle mode 
     /// is RF22_XTON ie READY mode. 
-    /// \param[in] mode MAsk of mode bits, using RF22_SWRES, RF22_ENLBD, RF22_ENWT, 
+    /// \param[in] mode Mask of mode bits, using RF22_SWRES, RF22_ENLBD, RF22_ENWT, 
     /// RF22_X32KSEL, RF22_PLLON, RF22_XTON.
     void           setMode(uint8_t mode);
 
@@ -798,6 +915,10 @@
     /// Starts the transmitter in the RF22.
     void           setModeTx();
 
+    /// Returns the operating mode of the library.
+    /// \return the current mode, one of RF22_MODE_*
+    uint8_t        mode();
+
     /// Sets the transmitter power output level in register RF22_REG_6D_TX_POWER.
     /// Be a good neighbour and set the lowest power level you need.
     /// After init(), the power wil be set to RF22_TXPOW_8DBM.
@@ -810,7 +931,7 @@
     /// bandwidths etc. You cas use this to configure the modem with custom configuraitons if none of the 
     /// canned configurations in ModemConfigChoice suit you.
     /// \param[in] config A ModemConfig structure containing values for the modem configuration registers.
-    void           setModemRegisters(ModemConfig* config);
+    void           setModemRegisters(const ModemConfig* config);
 
     /// Select one of the predefined modem configurations. If you need a modem configuration not provided 
     /// here, use setModemRegisters() with your own ModemConfig.
@@ -844,15 +965,16 @@
     /// \return true if a valid message was copied to buf
     boolean        recv(uint8_t* buf, uint8_t* len);
 
-    /// Loads a message into the transmitter and starts the transmitter. Note that a message length
-    /// of 0 is permitted, in which case data may be NULL.
+    /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent().
+    /// Then loads a message into the transmitter and starts the transmitter. Note that a message length
+    /// of 0 is NOT permitted. 
     /// \param[in] data Array of data to be sent
-    /// \param[in] len Number of bytes of data to send.
-    /// \return true
-    boolean        send(uint8_t* data, uint8_t len);
+    /// \param[in] len Number of bytes of data to send (> 0)
+    /// \return true if the message length was valid and it was correctly queued for transmit
+    boolean        send(const uint8_t* data, uint8_t len);
 
-    /// Blocks until the current message 
-    /// (if any) has been completely sent
+    /// Blocks until the RF22 is not in mode RF22_MODE_TX (ie until the RF22 is not transmitting).
+    /// This effectively waits until any previous transmit packet is finished being transmitted.
     void           waitPacketSent();
   
     /// Tells the receiver to accept messages with any TO address, not just messages
@@ -866,17 +988,14 @@
 
     /// Returns the FROM header of the last received message
     /// \return The FROM header
-    /// \return
     uint8_t        headerFrom();
 
     /// Returns the ID header of the last received message
     /// \return The ID header
-    /// \return
     uint8_t        headerId();
 
     /// Returns the FLAGS header of the last received message
     /// \return The FLAGS header
-    /// \return
     uint8_t        headerFlags();
 
     /// Returns the RSSI (Receiver Signal Strength Indicator)
@@ -885,17 +1004,30 @@
     /// \return The RSSI
     uint8_t        lastRssi();
 
-protected:
+    /// Prints a data buffer in HEX.
+    /// For diagnostic use
+    /// \param[in] prompt string to preface the print
+    /// \param[in] buf Location of the buffer to print
+    /// \param[in] len Length of the buffer in octets.
+    static void           printBuffer(const char* prompt, const uint8_t* buf, uint8_t len);
+
+    /// Sets the length of the preamble
+    /// in 4-bit nibbles. 
+    /// Caution: this should be set to the same 
+    /// value on all nodes in your network. Default is 8.
     /// Sets the message preamble length in RF22_REG_34_PREAMBLE_LENGTH
     /// \param[in] nibbles Preamble length in nibbles of 4 bits each.  
     void           setPreambleLength(uint8_t nibbles);
 
     /// Sets the sync words for transmit and receive in registers RF22_REG_36_SYNC_WORD3 
     /// to RF22_REG_39_SYNC_WORD0
+    /// Caution: this should be set to the same 
+    /// value on all nodes in your network. Default is { 0x2d, 0xd4 }
     /// \param[in] syncWords Array of sync words
     /// \param[in] len Number of sync words to set
-    void           setSyncWords(uint8_t* syncWords, uint8_t len);
+    void           setSyncWords(const uint8_t* syncWords, uint8_t len);
 
+protected:
     /// This is a low level function to handle the interrupts for one instance of RF22.
     /// Called automatically by isr0() and isr1()
     /// Should not need to be called.
@@ -910,16 +1042,16 @@
     void           clearTxBuf();
 
     /// Fills the transmitter buffer with the data of a mesage to be sent
-    /// \param[in] data Array of data bytes to be sent (0 to 255)
-    /// \param[in] len Number of data bytes in data
-    /// \return true
-    boolean           fillTxBuf(uint8_t* data, uint8_t len);
+    /// \param[in] data Array of data bytes to be sent (1 to 255)
+    /// \param[in] len Number of data bytes in data (> 0)
+    /// \return true if the message length is valid
+    boolean           fillTxBuf(const uint8_t* data, uint8_t len);
 
     /// Appends the transmitter buffer with the data of a mesage to be sent
     /// \param[in] data Array of data bytes to be sent (0 to 255)
     /// \param[in] len Number of data bytes in data
     /// \return false if the resulting message would exceed RF22_MAX_MESSAGE_LEN, else true
-    boolean           appendTxBuf(uint8_t* data, uint8_t len);
+    boolean           appendTxBuf(const uint8_t* data, uint8_t len);
 
     /// Internal function to load the next fragment of 
     /// the current message into the transmitter FIFO
@@ -978,19 +1110,21 @@
     /// of the Tx buffer after a atransmission failure
     void           restartTransmit();
 
-//private:
+protected:
+    //GenericSPIClass*    _spi;
+
     /// Low level interrupt service routine for RF22 connected to interrupt 0
     //static void         isr0();
     void         isr0();
 
     /// Low level interrupt service routine for RF22 connected to interrupt 1
     //static void         isr1();
-private:
+//private:
     /// Array of instances connected to interrupts 0 and 1
     //static RF22*        _RF22ForInterrupt[];
     
    
-    uint8_t             _mode; // One of RF22_MODE_*
+    volatile uint8_t    _mode; // One of RF22_MODE_*
 
     uint8_t             _idleMode;
     DigitalOut          _slaveSelectPin;
@@ -1004,8 +1138,8 @@
     DigitalOut           led4;
 
     // These volatile members may get changed in the interrupt service routine
+    volatile uint8_t    _bufLen;
     uint8_t             _buf[RF22_MAX_MESSAGE_LEN];
-    volatile uint8_t    _bufLen;
 
     volatile boolean    _rxBufValid;
 
@@ -1017,8 +1151,67 @@
     volatile uint16_t   _txGood;
 
     volatile uint8_t    _lastRssi;
-    
 };
 
+/// @example rf22_client.pde
+/// Client side of simple client/server pair using RF22 class
+
+/// @example rf22_server.pde
+/// Server side of simple client/server pair using RF22 class
+
+/// @example rf22_datagram_client.pde
+/// Client side of simple client/server pair using RF22Datagram class
+
+/// @example rf22_datagram_server.pde
+/// Server side of simple client/server pair using RF22Datagram class
+
+/// @example rf22_reliable_datagram_client.pde
+/// Client side of simple client/server pair using RF22ReliableDatagram class
+
+/// @example rf22_reliable_datagram_server.pde
+/// Server side of simple client/server pair using RF22ReliableDatagram class
+
+/// @example rf22_router_client.pde
+/// Client side of RF22Router network chain
+
+/// @example rf22_router_server1.pde
+/// Server node for RF22Router network chain
+
+/// @example rf22_router_server2.pde
+/// Server node for RF22Router network chain
+
+/// @example rf22_router_server3.pde
+/// Server node for RF22Router network chain
+
+/// @example rf22_mesh_client.pde
+/// Client side of RF22Mesh network chain
+
+/// @example rf22_mesh_server1.pde
+/// Server node for RF22Mesh network chain
+
+/// @example rf22_mesh_server2.pde
+/// Server node for RF22Mesh network chain
+
+/// @example rf22_mesh_server3.pde
+/// Server node for RF22Mesh network chain
+
+/// @example rf22_test.pde
+/// Test suite for RF22 library
+
+/// @example rf22_snoop.pde
+/// Capture and print RF22 packet from the air
+
+/// @example rf22_specan.pde
+/// Simple spectrum analyser using the RSSI measurements of the RF22
+///   (see <a href="specan1.png">Sample output</a> showing a plot from 395.0MHz to 396.0MHz of a 
+///   signal generator at 395.5MHz amplitude modulated at 100% 1kHz)
+///
+
+/// @example IPGateway.pde
+/// Sketch to provide an IP gateway for a set of RF22 radios (Datagram, ReliableDatagram, Router or Mesh)
+/// Routes UDP messages from an internet connection using an Ethernet Shield and sends them
+/// to a radio whose ID is based on the UDP port. Replies are sent back to the originating UDP
+/// address and port
+
 
 #endif