David Rimer / RadioHead-148
Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RH_NRF905.h Source File

RH_NRF905.h

00001 // RH_NRF905.h
00002 // Author: Mike McCauley (mikem@airspayce.com)
00003 // Copyright (C) 2014 Mike McCauley
00004 // $Id: RH_NRF905.h,v 1.7 2015/03/09 06:04:26 mikem Exp $
00005 //
00006 
00007 #ifndef RH_NRF905_h
00008 #define RH_NRF905_h
00009 
00010 #include <RHGenericSPI.h>
00011 #include <RHNRFSPIDriver.h>
00012 
00013 // This is the maximum (and only) number of bytes that can be carried by the nRF905.
00014 // We use some for headers, leaving fewer for RadioHead messages
00015 #define RH_NRF905_MAX_PAYLOAD_LEN 32
00016 
00017 // The length of the headers we add.
00018 // The headers are inside the nRF905 payload
00019 // As well as the usual TO, FROM, ID, FLAGS, we also need LEN, since
00020 // nRF905 only has fixed width messages.
00021 // REVISIT: could we have put the LEN into the FLAGS field?
00022 #define RH_NRF905_HEADER_LEN 5
00023 
00024 // This is the maximum RadioHead user message length that can be supported by this library. Limited by
00025 // the supported message lengths in the nRF905
00026 #define RH_NRF905_MAX_MESSAGE_LEN (RH_NRF905_MAX_PAYLOAD_LEN-RH_NRF905_HEADER_LEN)
00027 
00028 // Register names
00029 #define RH_NRF905_REG_MASK                   0x0f
00030 #define RH_NRF905_REG_W_CONFIG               0x00
00031 #define RH_NRF905_REG_R_CONFIG               0x10
00032 #define RH_NRF905_REG_W_TX_PAYLOAD           0x20
00033 #define RH_NRF905_REG_R_TX_PAYLOAD           0x21
00034 #define RH_NRF905_REG_W_TX_ADDRESS           0x22
00035 #define RH_NRF905_REG_R_TX_ADDRESS           0x23
00036 #define RH_NRF905_REG_R_RX_PAYLOAD           0x24
00037 #define RH_NRF905_REG_CHANNEL_CONFIG         0x80
00038 
00039 // Configuration register
00040 #define RH_NRF905_CONFIG_0                    0x00
00041 #define RH_NRF905_CONFIG_0_CH_NO              0xff
00042 
00043 #define RH_NRF905_CONFIG_1                    0x01
00044 #define RH_NRF905_CONFIG_1_AUTO_RETRAN        0x20
00045 #define RH_NRF905_CONFIG_1_RX_RED_PWR         0x10
00046 #define RH_NRF905_CONFIG_1_PA_PWR             0x0c
00047 #define RH_NRF905_CONFIG_1_PA_PWR_N10DBM      0x00
00048 #define RH_NRF905_CONFIG_1_PA_PWR_N2DBM       0x04
00049 #define RH_NRF905_CONFIG_1_PA_PWR_6DBM        0x08
00050 #define RH_NRF905_CONFIG_1_PA_PWR_10DBM       0x0c
00051 #define RH_NRF905_CONFIG_1_HFREQ_PLL          0x02
00052 #define RH_NRF905_CONFIG_1_CH_NO              0x01
00053 
00054 #define RH_NRF905_CONFIG_2                    0x02
00055 #define RH_NRF905_CONFIG_2_TX_AFW             0x70
00056 #define RH_NRF905_CONFIG_2_RX_AFW             0x07
00057 
00058 #define RH_NRF905_CONFIG_3                    0x03
00059 #define RH_NRF905_CONFIG_3_RX_PW              0x3f
00060 
00061 #define RH_NRF905_CONFIG_4                    0x04
00062 #define RH_NRF905_CONFIG_4_TX_PW              0x3f
00063 
00064 #define RH_NRF905_CONFIG_5                    0x05
00065 #define RH_NRF905_CONFIG_5_RX_ADDRESS         0xff
00066 
00067 #define RH_NRF905_CONFIG_6                    0x06
00068 #define RH_NRF905_CONFIG_6_RX_ADDRESS         0xff
00069 
00070 #define RH_NRF905_CONFIG_7                    0x07
00071 #define RH_NRF905_CONFIG_7_RX_ADDRESS         0xff
00072 
00073 #define RH_NRF905_CONFIG_8                    0x08
00074 #define RH_NRF905_CONFIG_8_RX_ADDRESS         0xff
00075 
00076 #define RH_NRF905_CONFIG_9                    0x09
00077 #define RH_NRF905_CONFIG_9_CRC_MODE_16BIT     0x80
00078 #define RH_NRF905_CONFIG_9_CRC_EN             0x40
00079 #define RH_NRF905_CONFIG_9_XOF                0x38
00080 #define RH_NRF905_CONFIG_9_XOF_4MHZ           0x00
00081 #define RH_NRF905_CONFIG_9_XOF_8MHZ           0x08
00082 #define RH_NRF905_CONFIG_9_XOF_12MHZ          0x10
00083 #define RH_NRF905_CONFIG_9_XOF_16MHZ          0x18
00084 #define RH_NRF905_CONFIG_9_XOF_20MHZ          0x20
00085 #define RH_NRF905_CONFIG_9_UP_CLK_EN          0x04
00086 #define RH_NRF905_CONFIG_9_UP_CLK_FREQ        0x03
00087 #define RH_NRF905_CONFIG_9_UP_CLK_FREQ_4MHZ   0x00
00088 #define RH_NRF905_CONFIG_9_UP_CLK_FREQ_2MHZ   0x01
00089 #define RH_NRF905_CONFIG_9_UP_CLK_FREQ_1MHZ   0x02
00090 #define RH_NRF905_CONFIG_9_UP_CLK_FREQ_500KHZ 0x03
00091 
00092 // Status register is always read as first byte
00093 #define RH_NRF905_STATUS_AM                   0x80
00094 #define RH_NRF905_STATUS_DR                   0x20
00095 
00096 /////////////////////////////////////////////////////////////////////
00097 /// \class RH_NRF905 RH_NRF905.h <RH_NRF905.h>
00098 /// \brief Send and receive addressed, reliable, acknowledged datagrams by nRF905 and compatible transceivers.
00099 ///
00100 /// This base class provides basic functions for sending and receiving unaddressed, unreliable datagrams
00101 /// of arbitrary length to 28 octets per packet. Use one of the Manager classes to get addressing and 
00102 /// acknowledgement reliability, routing, meshes etc.
00103 ///
00104 /// The nRF905 transceiver is configured to use Enhanced Shockburst with 16 Bit CRC, and 32 octet packets.
00105 ///
00106 /// Naturally, for any 2 radios to communicate that must be configured to use the same frequency
00107 /// and with identical network addresses.
00108 ///
00109 /// The nRF905 from Nordic Semiconductor http://www.nordicsemi.com/eng/Products/Sub-1-GHz-RF/nRF905
00110 /// (http://www.nordicsemi.com/jpn/nordic/content_download/2452/29528/file/Product_Specification_nRF905_v1.5.pdf)
00111 /// is a low-cost 433/868/915 MHz ISM transceiver module. It supports a number of channel frequencies at
00112 /// 100kHz deviation and 50kHz bandwidth with Manchester encoding.
00113 ///
00114 /// We tested with inexpensive nRF905 modules from eBay, similar to:
00115 /// http://www.aliexpress.com/store/product/Free-ship-NRF905-433MHz-Wireless-Transmission-Module-Transceiver-Module-with-Antenna-for-the-433MHz-ISM-band/513046_607163305.html
00116 ///
00117 /// This library provides functions for sending and receiving messages of up to 27 octets on any 
00118 /// frequency supported by the nRF905.
00119 ///
00120 /// Several nRF905 modules can be connected to an Arduino, permitting the construction of translators
00121 /// and frequency changers, etc.
00122 ///
00123 /// Example Arduino programs are included to show the main modes of use.
00124 ///
00125 /// \par Packet Format
00126 ///
00127 /// All messages sent and received by this class conform to this fixed length packet format
00128 ///
00129 /// - 4 octets NETWORK ADDRESS
00130 /// - 32 octets PAYLOAD, consisting of:
00131 ///   - 1 octet TO header
00132 ///   - 1 octet FROM header
00133 ///   - 1 octet ID header
00134 ///   - 1 octet FLAGS header
00135 ///   - 1 octet user message length header
00136 ///   - 0 to 27 octets of user message, trailing octets after the user message length are ignored
00137 /// - 2 octets CRC 
00138 ///
00139 /// All messages sent and received by this driver are 32 octets. The user message length is embedded in the message.
00140 ///
00141 /// \par Connecting nRF905
00142 ///
00143 /// The nRF905 is a 3.3V part is is *NOT* 5V tolerant. So you MUST use a 3.3V CPU such as Teensy, Arduino Due etc
00144 /// or else provide for level shifters between the CPU and the nRF905. Failure to consider this will probbaly
00145 /// break your nRF905.
00146 ///
00147 /// The electrical connection between the nRF905 and the CPU require 3.3V, the 3 x SPI pins (SCK, SDI, SDO), 
00148 /// a Chip Enable pin, a Transmit Enable pin and a Slave Select pin.
00149 ///
00150 /// The examples below assume the commonly found cheap Chinese nRF905 modules. The RH_RF905 driver assumes the 
00151 /// the nRF905 has a 16MHz crystal.
00152 ///
00153 /// Connect the nRF905 to Teensy like this
00154 /// \code
00155 ///                 CPU          nRF905 module
00156 ///                 3V3----------VCC   (3.3V)
00157 ///             pin D8-----------CE    (chip enable in)
00158 ///             pin D9-----------TX_EN (transmit enable in)
00159 ///          SS pin D10----------CSN   (chip select in)
00160 ///         SCK pin D13----------SCK   (SPI clock in)
00161 ///        MOSI pin D11----------MOSI  (SPI Data in)
00162 ///        MISO pin D12----------MISO  (SPI data out)
00163 ///                 GND----------GND   (ground in)
00164 /// \endcode
00165 ///
00166 /// Caution: Arduino Due is a 3.3V part and is not 5V tolerant (so too is the nRF905 module
00167 /// so they can be connected directly together. Unlike other Arduinos the Due has it default SPI 
00168 /// connections on a dedicated 6 pin SPI header in the center of the board, which is 
00169 /// physically compatible with Uno, Leonardo and Mega2560. A little dot marks pin 1 on the header.
00170 /// You must connect to these
00171 /// and *not* to the usual Arduino SPI pins 11, 12 and 13.
00172 /// See http://21stdigitalhome.blogspot.com.au/2013/02/arduino-due-hardware-spi.html
00173 ///
00174 /// Connect the nRF905 to Arduino Due like this
00175 /// \code
00176 ///                      CPU          nRF905 module
00177 ///                      3V3----------VCC   (3.3V)
00178 ///                  pin D8-----------CE    (chip enable in)
00179 ///                  pin D9-----------TX_EN (transmit enable in)
00180 ///               SS pin D10----------CSN   (chip select in)
00181 ///  SCK on SPI header pin 3----------SCK   (SPI clock in)
00182 /// MOSI on SPI header pin 4----------MOSI  (SPI Data in)
00183 /// MISO on SPI header pin 1----------MISO  (SPI data out)
00184 ///                      GND----------GND   (ground in)
00185 /// \endcode
00186 ///
00187 /// and you can then use the default constructor RH_NRF905(). 
00188 /// You can override the default settings for the CE, TX_EN and CSN pins 
00189 /// in the NRF905() constructor if you wish to connect the slave select CSN to other than the normal one for your 
00190 /// CPU.
00191 ///
00192 /// It is possible to have 2 radios conected to one CPU, provided each radio has its own 
00193 /// CSN, TX_EN and CE line (SCK, MOSI and MISO are common to both radios)
00194 ///
00195 /// \par Example programs
00196 ///
00197 /// Several example programs are provided. They work out of the box with Teensy 3.1 and Arduino Due 
00198 /// connected as show above.
00199 ///
00200 /// \par Radio Performance
00201 ///
00202 /// Frequency accuracy may be debatable.
00203 /// 
00204 /// \par Memory
00205 ///
00206 /// Memory usage of this class is minimal. The compiled client and server sketches are about 16000 bytes on Teensy. 
00207 ///
00208 class RH_NRF905 : public RHNRFSPIDriver
00209 {
00210 public:
00211     /// \brief Convenient values for setting transmitter power in setRF()
00212     /// These are designed to agree with the values for PA_PWR
00213     /// To be passed to setRF();
00214     typedef enum
00215     {
00216     TransmitPowerm10dBm = 0,  ///< -10 dBm
00217     TransmitPowerm2dBm,       ///< -2 dBm
00218     TransmitPower6dBm,        ///< 6 dBm
00219     TransmitPower10dBm        ///< 10 dBm
00220     } TransmitPower;
00221 
00222     /// Constructor. You can have multiple instances, but each instance must have its own
00223     /// chip enable and slave select pin. 
00224     /// After constructing, you must call init() to initialise the interface
00225     /// and the radio module
00226     /// \param[in] chipEnablePin the Arduino pin to use to enable the chip for transmit/receive
00227     /// \param[in] txEnablePin the Arduino pin cponnected to the txEn pin on the radio that enable transmit mode
00228     /// \param[in] slaveSelectPin the Arduino pin number of the output to use to select the NRF905 before
00229     /// accessing it. Defaults to the normal SS pin for your Arduino (D10 for Diecimila, Uno etc, D53 for Mega, 
00230     /// D10 for Maple, Teensy)
00231     /// \param[in] spi Pointer to the SPI interface object to use. 
00232     ///                Defaults to the standard Arduino hardware SPI interface
00233     RH_NRF905(PINS chipEnablePin, PINS txEnablePin, PINS slaveSelectPin, RHGenericSPI& spi = hardware_spi);
00234   
00235     /// Initialises this instance and the radio module connected to it.
00236     /// The following steps are taken:g
00237     /// - Set the chip enable and chip select pins to output LOW, HIGH respectively.
00238     /// - Initialise the SPI output pins
00239     /// - Initialise the SPI interface library to 8MHz (Hint, if you want to lower
00240     /// the SPI frequency (perhaps where you have other SPI shields, low voltages etc), 
00241     /// call SPI.setClockDivider() after init()).
00242     /// -Flush the receiver and transmitter buffers
00243     /// - Set the radio to receive with powerUpRx();
00244     /// \return  true if everything was successful
00245     bool        init();
00246 
00247     /// Reads a single register from the NRF905
00248     /// \param[in] reg Register number, one of NR905_REG_*
00249     /// \return The value of the register
00250     uint8_t        spiReadRegister(uint8_t reg);
00251 
00252     /// Writes a single byte to the NRF905, and at the ame time reads the current STATUS register
00253     /// \param[in] reg Register number, one of NRF905_REG_*
00254     /// \param[in] val The value to write
00255     /// \return the current STATUS (read while the command is sent)
00256     uint8_t        spiWriteRegister(uint8_t reg, uint8_t val);
00257 
00258     /// Reads a number of consecutive registers from the NRF905 using burst read mode
00259     /// \param[in] reg Register number of the first register, one of NRF905_REG_*
00260     /// \param[in] dest Array to write the register values to. Must be at least len bytes
00261     /// \param[in] len Number of bytes to read
00262     /// \return the current STATUS (read while the command is sent)
00263     uint8_t           spiBurstReadRegister(uint8_t reg, uint8_t* dest, uint8_t len);
00264 
00265     /// Write a number of consecutive registers using burst write mode
00266     /// \param[in] reg Register number of the first register, one of NRF905_REG_*
00267     /// \param[in] src Array of new register values to write. Must be at least len bytes
00268     /// \param[in] len Number of bytes to write
00269     /// \return the current STATUS (read while the command is sent)
00270     uint8_t        spiBurstWriteRegister(uint8_t reg, uint8_t* src, uint8_t len);
00271 
00272     /// Reads and returns the device status register NRF905_REG_02_DEVICE_STATUS
00273     /// \return The value of the device status register
00274     uint8_t        statusRead();
00275   
00276     /// Sets the transmit and receive channel number.
00277     /// The RF frequency used is (422.4 + channel/10) * (1+hiFrequency) MHz
00278     /// \param[in] channel The channel number. 
00279     /// \param[in] hiFrequency false for low frequency band (422.4MHz and up), true for high frequency band (845MHz and up)
00280     /// \return true on success
00281     bool setChannel(uint16_t channel, bool hiFrequency = false);
00282 
00283     /// Sets the Network address.
00284     /// Only nodes with the same network address can communicate with each other. You 
00285     /// can set different network addresses in different sets of nodes to isolate them from each other.
00286     /// The default network address is 0xE7E7E7E7
00287     /// \param[in] address The new network address. Must match the network address of any receiving node(s).
00288     /// \param[in] len Number of bytes of address to set (1 to 4).
00289     /// \return true on success, false if len is not in the range 1-4 inclusive.
00290     bool setNetworkAddress(uint8_t* address, uint8_t len);
00291 
00292     /// Sets the transmitter power to use
00293     /// \param [in] power Transmitter power. One of NRF905::TransmitPower.
00294     /// \return true on success
00295     bool setRF(TransmitPower power);
00296 
00297     /// Sets the radio in power down mode.
00298     /// Sets chip enable to LOW.
00299     /// \return true on success
00300     void setModeIdle();
00301 
00302     /// Sets the radio in RX mode.
00303     /// Sets chip enable to HIGH to enable the chip in RX mode.
00304     /// \return true on success
00305     void setModeRx();
00306 
00307     /// Sets the radio in TX mode.
00308     /// Pulses the chip enable LOW then HIGH to enable the chip in TX mode.
00309     /// \return true on success
00310     void setModeTx();
00311 
00312     /// Sends data to the address set by setTransmitAddress()
00313     /// Sets the radio to TX mode
00314     /// \param [in] data Data bytes to send.
00315     /// \param [in] len Number of data bytes to set in teh TX buffer. The actual size of the 
00316     /// transmitted data payload is set by setPayloadSize
00317     /// \return true on success (which does not necessarily mean the receiver got the message, only that the message was
00318     /// successfully transmitted).
00319     bool send(const uint8_t* data, uint8_t len);
00320 
00321     /// Blocks until the current message (if any) 
00322     /// has been transmitted
00323     /// \return true on success, false if the chip is not in transmit mode
00324     virtual bool waitPacketSent();
00325 
00326     /// Indicates if the chip is in transmit mode and 
00327     /// there is a packet currently being transmitted
00328     /// \return true if the chip is in transmit mode and there is a transmission in progress
00329     bool isSending();
00330 
00331     /// Prints the value of a single chip register
00332     /// to the Serial device if RH_HAVE_SERIAL is defined for the current platform
00333     /// For debugging purposes only.
00334     /// \return true on success
00335     bool printRegister(uint8_t reg);
00336 
00337     /// Prints the value of all chip registers
00338     /// to the Serial device if RH_HAVE_SERIAL is defined for the current platform
00339     /// For debugging purposes only.
00340     /// \return true on success
00341     bool printRegisters();
00342 
00343     /// Checks whether a received message is available.
00344     /// This can be called multiple times in a timeout loop
00345     /// \return true if a complete, valid message has been received and is able to be retrieved by
00346     /// recv()
00347     bool available();
00348 
00349     /// Turns the receiver on if it not already on.
00350     /// If there is a valid message available, copy it to buf and return true
00351     /// else return false.
00352     /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).
00353     /// You should be sure to call this function frequently enough to not miss any messages
00354     /// It is recommended that you call it in your main loop.
00355     /// \param[in] buf Location to copy the received message
00356     /// \param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied.
00357     /// \return true if a valid message was copied to buf
00358     bool recv(uint8_t* buf, uint8_t* len);
00359 
00360     /// The maximum message length supported by this driver
00361     /// \return The maximum message length supported by this driver
00362     uint8_t maxMessageLength();
00363 
00364 protected:
00365     /// Examine the revceive buffer to determine whether the message is for this node
00366     void validateRxBuf();
00367 
00368     /// Clear our local receive buffer
00369     void clearRxBuf();
00370 
00371 private:
00372     /// This idle mode chip configuration
00373     uint8_t             _configuration;
00374 
00375     /// the number of the chip enable pin
00376     uint8_t             _chipEnablePin;
00377 
00378     /// The number of the transmit enable pin
00379     uint8_t             _txEnablePin;
00380 
00381     /// Number of octets in the buffer
00382     uint8_t             _bufLen;
00383     
00384     /// The receiver/transmitter buffer
00385     uint8_t             _buf[RH_NRF905_MAX_PAYLOAD_LEN];
00386 
00387     /// True when there is a valid message in the buffer
00388     bool                _rxBufValid;
00389 };
00390 
00391 /// @example nrf905_client.pde
00392 /// @example nrf905_server.pde
00393 /// @example nrf905_reliable_datagram_client.pde
00394 /// @example nrf905_reliable_datagram_server.pde
00395 
00396 #endif