Point Labs / RadioHeadLite

Dependents:   Threaded_LoRa_Modem

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers RH_RF95.h Source File

RH_RF95.h

00001 // RH_RF95.h
00002 //
00003 // Definitions for HopeRF LoRa radios per:
00004 // http://www.hoperf.com/upload/rf/RFM95_96_97_98W.pdf
00005 // http://www.hoperf.cn/upload/rfchip/RF96_97_98.pdf
00006 //
00007 // Author: Mike McCauley (mikem@airspayce.com)
00008 // Copyright (C) 2014 Mike McCauley
00009 // $Id: RH_RF95.h,v 1.7 2015/05/17 00:11:26 mikem Exp $
00010 //
00011 
00012 #ifndef RH_RF95_h
00013 #define RH_RF95_h
00014 #include "PinNames.h"
00015 #include <RHSPIDriver.h>
00016 
00017 // This is the maximum number of interrupts the driver can support
00018 // Most Arduinos can handle 2, Megas can handle more
00019 #define RH_RF95_NUM_INTERRUPTS 3
00020 
00021 // Max number of octets the LORA Rx/Tx FIFO can hold
00022 #define RH_RF95_FIFO_SIZE 255
00023 
00024 // This is the maximum number of bytes that can be carried by the LORA.
00025 // We use some for headers, keeping fewer for RadioHead messages
00026 #define RH_RF95_MAX_PAYLOAD_LEN RH_RF95_FIFO_SIZE
00027 
00028 // The length of the headers we add.
00029 // The headers are inside the LORA's payload
00030 #define RH_RF95_HEADER_LEN 4
00031 
00032 // This is the maximum message length that can be supported by this driver.
00033 // Can be pre-defined to a smaller size (to save SRAM) prior to including this header
00034 // Here we allow for 1 byte message length, 4 bytes headers, user data and 2 bytes of FCS
00035 #ifndef RH_RF95_MAX_MESSAGE_LEN
00036 #define RH_RF95_MAX_MESSAGE_LEN (RH_RF95_MAX_PAYLOAD_LEN - RH_RF95_HEADER_LEN)
00037 #endif
00038 
00039 // The crystal oscillator frequency of the module
00040 #define RH_RF95_FXOSC 32000000.0
00041 
00042 // The Frequency Synthesizer step = RH_RF95_FXOSC / 2^^19
00043 #define RH_RF95_FSTEP  (RH_RF95_FXOSC / 524288)
00044 
00045 
00046 // Register names (LoRa Mode, from table 85)
00047 #define RH_RF95_REG_00_FIFO                                0x00
00048 #define RH_RF95_REG_01_OP_MODE                             0x01
00049 #define RH_RF95_REG_02_RESERVED                            0x02
00050 #define RH_RF95_REG_03_RESERVED                            0x03
00051 #define RH_RF95_REG_04_RESERVED                            0x04
00052 #define RH_RF95_REG_05_RESERVED                            0x05
00053 #define RH_RF95_REG_06_FRF_MSB                             0x06
00054 #define RH_RF95_REG_07_FRF_MID                             0x07
00055 #define RH_RF95_REG_08_FRF_LSB                             0x08
00056 #define RH_RF95_REG_09_PA_CONFIG                           0x09
00057 #define RH_RF95_REG_0A_PA_RAMP                             0x0a
00058 #define RH_RF95_REG_0B_OCP                                 0x0b
00059 #define RH_RF95_REG_0C_LNA                                 0x0c
00060 #define RH_RF95_REG_0D_FIFO_ADDR_PTR                       0x0d
00061 #define RH_RF95_REG_0E_FIFO_TX_BASE_ADDR                   0x0e
00062 #define RH_RF95_REG_0F_FIFO_RX_BASE_ADDR                   0x0f
00063 #define RH_RF95_REG_10_FIFO_RX_CURRENT_ADDR                0x10
00064 #define RH_RF95_REG_11_IRQ_FLAGS_MASK                      0x11
00065 #define RH_RF95_REG_12_IRQ_FLAGS                           0x12
00066 #define RH_RF95_REG_13_RX_NB_BYTES                         0x13
00067 #define RH_RF95_REG_14_RX_HEADER_CNT_VALUE_MSB             0x14
00068 #define RH_RF95_REG_15_RX_HEADER_CNT_VALUE_LSB             0x15
00069 #define RH_RF95_REG_16_RX_PACKET_CNT_VALUE_MSB             0x16
00070 #define RH_RF95_REG_17_RX_PACKET_CNT_VALUE_LSB             0x17
00071 #define RH_RF95_REG_18_MODEM_STAT                          0x18
00072 #define RH_RF95_REG_19_PKT_SNR_VALUE                       0x19
00073 #define RH_RF95_REG_1A_PKT_RSSI_VALUE                      0x1a
00074 #define RH_RF95_REG_1B_RSSI_VALUE                          0x1b
00075 #define RH_RF95_REG_1C_HOP_CHANNEL                         0x1c
00076 #define RH_RF95_REG_1D_MODEM_CONFIG1                       0x1d
00077 #define RH_RF95_REG_1E_MODEM_CONFIG2                       0x1e
00078 #define RH_RF95_REG_1F_SYMB_TIMEOUT_LSB                    0x1f
00079 #define RH_RF95_REG_20_PREAMBLE_MSB                        0x20
00080 #define RH_RF95_REG_21_PREAMBLE_LSB                        0x21
00081 #define RH_RF95_REG_22_PAYLOAD_LENGTH                      0x22
00082 #define RH_RF95_REG_23_MAX_PAYLOAD_LENGTH                  0x23
00083 #define RH_RF95_REG_24_HOP_PERIOD                          0x24
00084 #define RH_RF95_REG_25_FIFO_RX_BYTE_ADDR                   0x25
00085 #define RH_RF95_REG_26_MODEM_CONFIG3                       0x26
00086 
00087 #define RH_RF95_REG_40_DIO_MAPPING1                        0x40
00088 #define RH_RF95_REG_41_DIO_MAPPING2                        0x41
00089 #define RH_RF95_REG_42_VERSION                             0x42
00090 
00091 #define RH_RF95_REG_4B_TCXO                                0x4b
00092 #define RH_RF95_REG_4D_PA_DAC                              0x4d
00093 #define RH_RF95_REG_5B_FORMER_TEMP                         0x5b
00094 #define RH_RF95_REG_61_AGC_REF                             0x61
00095 #define RH_RF95_REG_62_AGC_THRESH1                         0x62
00096 #define RH_RF95_REG_63_AGC_THRESH2                         0x63
00097 #define RH_RF95_REG_64_AGC_THRESH3                         0x64
00098 
00099 // RH_RF95_REG_01_OP_MODE                             0x01
00100 #define RH_RF95_LONG_RANGE_MODE                       0x80
00101 #define RH_RF95_ACCESS_SHARED_REG                     0x40
00102 #define RH_RF95_MODE                                  0x07
00103 #define RH_RF95_MODE_SLEEP                            0x00
00104 #define RH_RF95_MODE_STDBY                            0x01
00105 #define RH_RF95_MODE_FSTX                             0x02
00106 #define RH_RF95_MODE_TX                               0x03
00107 #define RH_RF95_MODE_FSRX                             0x04
00108 #define RH_RF95_MODE_RXCONTINUOUS                     0x05
00109 #define RH_RF95_MODE_RXSINGLE                         0x06
00110 #define RH_RF95_MODE_CAD                              0x07
00111 
00112 // RH_RF95_REG_09_PA_CONFIG                           0x09
00113 #define RH_RF95_PA_SELECT                             0x80
00114 #define RH_RF95_OUTPUT_POWER                          0x0f
00115 
00116 // RH_RF95_REG_0A_PA_RAMP                             0x0a
00117 #define RH_RF95_LOW_PN_TX_PLL_OFF                     0x10
00118 #define RH_RF95_PA_RAMP                               0x0f
00119 #define RH_RF95_PA_RAMP_3_4MS                         0x00
00120 #define RH_RF95_PA_RAMP_2MS                           0x01
00121 #define RH_RF95_PA_RAMP_1MS                           0x02
00122 #define RH_RF95_PA_RAMP_500US                         0x03
00123 #define RH_RF95_PA_RAMP_250US                         0x0
00124 #define RH_RF95_PA_RAMP_125US                         0x05
00125 #define RH_RF95_PA_RAMP_100US                         0x06
00126 #define RH_RF95_PA_RAMP_62US                          0x07
00127 #define RH_RF95_PA_RAMP_50US                          0x08
00128 #define RH_RF95_PA_RAMP_40US                          0x09
00129 #define RH_RF95_PA_RAMP_31US                          0x0a
00130 #define RH_RF95_PA_RAMP_25US                          0x0b
00131 #define RH_RF95_PA_RAMP_20US                          0x0c
00132 #define RH_RF95_PA_RAMP_15US                          0x0d
00133 #define RH_RF95_PA_RAMP_12US                          0x0e
00134 #define RH_RF95_PA_RAMP_10US                          0x0f
00135 
00136 // RH_RF95_REG_0B_OCP                                 0x0b
00137 #define RH_RF95_OCP_ON                                0x20
00138 #define RH_RF95_OCP_TRIM                              0x1f
00139 
00140 // RH_RF95_REG_0C_LNA                                 0x0c
00141 #define RH_RF95_LNA_GAIN                              0xe0
00142 #define RH_RF95_LNA_BOOST                             0x03
00143 #define RH_RF95_LNA_BOOST_DEFAULT                     0x00
00144 #define RH_RF95_LNA_BOOST_150PC                       0x11
00145 
00146 // RH_RF95_REG_11_IRQ_FLAGS_MASK                      0x11
00147 #define RH_RF95_RX_TIMEOUT_MASK                       0x80
00148 #define RH_RF95_RX_DONE_MASK                          0x40
00149 #define RH_RF95_PAYLOAD_CRC_ERROR_MASK                0x20
00150 #define RH_RF95_VALID_HEADER_MASK                     0x10
00151 #define RH_RF95_TX_DONE_MASK                          0x08
00152 #define RH_RF95_CAD_DONE_MASK                         0x04
00153 #define RH_RF95_FHSS_CHANGE_CHANNEL_MASK              0x02
00154 #define RH_RF95_CAD_DETECTED_MASK                     0x01
00155 
00156 // RH_RF95_REG_12_IRQ_FLAGS                           0x12
00157 #define RH_RF95_RX_TIMEOUT                            0x80
00158 #define RH_RF95_RX_DONE                               0x40
00159 #define RH_RF95_PAYLOAD_CRC_ERROR                     0x20
00160 #define RH_RF95_VALID_HEADER                          0x10
00161 #define RH_RF95_TX_DONE                               0x08
00162 #define RH_RF95_CAD_DONE                              0x04
00163 #define RH_RF95_FHSS_CHANGE_CHANNEL                   0x02
00164 #define RH_RF95_CAD_DETECTED                          0x01
00165 
00166 // RH_RF95_REG_18_MODEM_STAT                          0x18
00167 #define RH_RF95_RX_CODING_RATE                        0xe0
00168 #define RH_RF95_MODEM_STATUS_CLEAR                    0x10
00169 #define RH_RF95_MODEM_STATUS_HEADER_INFO_VALID        0x08
00170 #define RH_RF95_MODEM_STATUS_RX_ONGOING               0x04
00171 #define RH_RF95_MODEM_STATUS_SIGNAL_SYNCHRONIZED      0x02
00172 #define RH_RF95_MODEM_STATUS_SIGNAL_DETECTED          0x01
00173 
00174 // RH_RF95_REG_1C_HOP_CHANNEL                         0x1c
00175 #define RH_RF95_PLL_TIMEOUT                           0x80
00176 #define RH_RF95_RX_PAYLOAD_CRC_IS_ON                  0x40
00177 #define RH_RF95_FHSS_PRESENT_CHANNEL                  0x3f
00178 
00179 // RH_RF95_REG_1D_MODEM_CONFIG1                       0x1d
00180 #define RH_RF95_BW                                    0xc0
00181 #define RH_RF95_BW_125KHZ                             0x00
00182 #define RH_RF95_BW_250KHZ                             0x40
00183 #define RH_RF95_BW_500KHZ                             0x80
00184 #define RH_RF95_BW_RESERVED                           0xc0
00185 #define RH_RF95_CODING_RATE                           0x38
00186 #define RH_RF95_CODING_RATE_4_5                       0x00
00187 #define RH_RF95_CODING_RATE_4_6                       0x08
00188 #define RH_RF95_CODING_RATE_4_7                       0x10
00189 #define RH_RF95_CODING_RATE_4_8                       0x18
00190 #define RH_RF95_IMPLICIT_HEADER_MODE_ON               0x04
00191 #define RH_RF95_RX_PAYLOAD_CRC_ON                     0x02
00192 #define RH_RF95_LOW_DATA_RATE_OPTIMIZE                0x01
00193 
00194 // RH_RF95_REG_1E_MODEM_CONFIG2                       0x1e
00195 #define RH_RF95_SPREADING_FACTOR                      0xf0
00196 #define RH_RF95_SPREADING_FACTOR_64CPS                0x60
00197 #define RH_RF95_SPREADING_FACTOR_128CPS               0x70
00198 #define RH_RF95_SPREADING_FACTOR_256CPS               0x80
00199 #define RH_RF95_SPREADING_FACTOR_512CPS               0x90
00200 #define RH_RF95_SPREADING_FACTOR_1024CPS              0xa0
00201 #define RH_RF95_SPREADING_FACTOR_2048CPS              0xb0
00202 #define RH_RF95_SPREADING_FACTOR_4096CPS              0xc0
00203 #define RH_RF95_TX_CONTINUOUS_MOE                     0x08
00204 #define RH_RF95_AGC_AUTO_ON                           0x04
00205 #define RH_RF95_SYM_TIMEOUT_MSB                       0x03
00206 
00207 //#define RH_RF95_REG_40_DIO_MAPPING1                        0x40
00208 #define RH_RF95_DIOMAPPING1_DIO0MAPPING_00                  0x00
00209 #define RH_RF95_DIOMAPPING1_DIO0MAPPING_01                  0x40
00210 #define RH_RF95_DIOMAPPING1_DIO0MAPPING_10                  0x80
00211 #define RH_RF95_DIOMAPPING1_DIO0MAPPING_11                  0xc0
00212 
00213 // RH_RF95_REG_4D_PA_DAC                              0x4d
00214 #define RH_RF95_PA_DAC_DISABLE                        0x04
00215 #define RH_RF95_PA_DAC_ENABLE                         0x07
00216 
00217 /////////////////////////////////////////////////////////////////////
00218 /// \class RH_RF95 RH_RF95.h <RH_RF95.h>
00219 /// \brief Driver to send and receive unaddressed, unreliable datagrams via a LoRa
00220 /// capable radio transceiver.
00221 ///
00222 /// For Semtech SX1276/77/78 and HopeRF RFM95/96/97/98 and other similar LoRa capable radios.
00223 /// Based on http://www.hoperf.com/upload/rf/RFM95_96_97_98W.pdf
00224 /// and http://www.hoperf.cn/upload/rfchip/RF96_97_98.pdf
00225 /// and http://www.semtech.com/images/datasheet/LoraDesignGuide_STD.pdf
00226 /// and http://www.semtech.com/images/datasheet/sx1276.pdf
00227 /// FSK/GFSK/OOK modes are not (yet) supported.
00228 ///
00229 /// Works with
00230 /// - the excellent MiniWirelessLoRa from Anarduino http://www.anarduino.com/miniwireless
00231 ///
00232 /// \par Overview
00233 ///
00234 /// This class provides basic functions for sending and receiving unaddressed,
00235 /// unreliable datagrams of arbitrary length to 251 octets per packet.
00236 ///
00237 /// Manager classes may use this class to implement reliable, addressed datagrams and streams,
00238 /// mesh routers, repeaters, translators etc.
00239 ///
00240 /// Naturally, for any 2 radios to communicate that must be configured to use the same frequency and
00241 /// modulation scheme.
00242 ///
00243 /// This Driver provides an object-oriented interface for sending and receiving data messages with Hope-RF
00244 /// RFM95/96/97/98(W) and compatible radio modules in LoRa mode.
00245 ///
00246 /// The Hope-RF (http://www.hoperf.com) RFM95/96/97/98(W) is a low-cost ISM transceiver
00247 /// chip. It supports FSK, GFSK, OOK over a wide range of frequencies and
00248 /// programmable data rates, and it also supports the proprietary LoRA (Long Range) mode, which
00249 /// is the only mode supported in this RadioHead driver.
00250 ///
00251 /// This Driver provides functions for sending and receiving messages of up
00252 /// to 251 octets on any frequency supported by the radio, in a range of
00253 /// predefined Bandwidths, Spreading Factors and Coding Rates.  Frequency can be set with
00254 /// 61Hz precision to any frequency from 240.0MHz to 960.0MHz. Caution: most modules only support a more limited
00255 /// range of frequencies due to antenna tuning.
00256 ///
00257 /// Up to 2 RFM95/96/97/98(W) modules can be connected to an Arduino (3 on a Mega),
00258 /// permitting the construction of translators and frequency changers, etc.
00259 ///
00260 /// Support for other features such as transmitter power control etc is
00261 /// also provided.
00262 ///
00263 /// Tested on MinWirelessLoRa with arduino-1.0.5
00264 /// on OpenSuSE 13.1
00265 ///
00266 /// \par Packet Format
00267 ///
00268 /// All messages sent and received by this RH_RF95 Driver conform to this packet format:
00269 ///
00270 /// - LoRa mode:
00271 /// - 8 symbol PREAMBLE
00272 /// - Explicit header with header CRC (handled internally by the radio)
00273 /// - 4 octets HEADER: (TO, FROM, ID, FLAGS)
00274 /// - 0 to 251 octets DATA
00275 /// - CRC (handled internally by the radio)
00276 ///
00277 /// \par Connecting RFM95/96/97/98 to Arduino
00278 ///
00279 /// We tested with Anarduino MiniWirelessLoRA, which is an Arduino Duemilanove compatible with a RFM96W
00280 /// module on-board. Therefore it needs no connections other than the USB
00281 /// programming connection and an antenna to make it work.
00282 ///
00283 /// If you have a bare RFM95/96/97/98  that you want to connect to an Arduino, you
00284 /// might use these connections (untested): CAUTION: you must use a 3.3V type
00285 /// Arduino, otherwise you will also need voltage level shifters between the
00286 /// Arduino and the RFM95.  CAUTION, you must also ensure you connect an
00287 /// antenna.
00288 ///
00289 /// \code
00290 ///                 Arduino      RFM95/96/97/98
00291 ///                 GND----------GND   (ground in)
00292 ///                 3V3----------3.3V  (3.3V in)
00293 /// interrupt 0 pin D2-----------DIO0  (interrupt request out)
00294 ///          SS pin D10----------NSS   (chip select in)
00295 ///         SCK pin D13----------SCK   (SPI clock in)
00296 ///        MOSI pin D11----------MOSI  (SPI Data in)
00297 ///        MISO pin D12----------MISO  (SPI Data out)
00298 /// \endcode
00299 ///
00300 /// With these connections, you can then use the default constructor RH_RF95().
00301 /// You can override the default settings for the SS pin and the interrupt in
00302 /// the RH_RF95 constructor if you wish to connect the slave select SS to other
00303 /// than the normal one for your Arduino (D10 for Diecimila, Uno etc and D53
00304 /// for Mega) or the interrupt request to other than pin D2 (Caution,
00305 /// different processors have different constraints as to the pins available
00306 /// for interrupts).
00307 ///
00308 /// It is possible to have 2 or more radios connected to one Arduino, provided
00309 /// each radio has its own SS and interrupt line (SCK, SDI and SDO are common
00310 /// to all radios)
00311 ///
00312 /// Caution: on some Arduinos such as the Mega 2560, if you set the slave
00313 /// select pin to be other than the usual SS pin (D53 on Mega 2560), you may
00314 /// need to set the usual SS pin to be an output to force the Arduino into SPI
00315 /// master mode.
00316 ///
00317 /// Caution: Power supply requirements of the RFM module may be relevant in some circumstances:
00318 /// RFM95/96/97/98 modules are capable of pulling 120mA+ at full power, where Arduino's 3.3V line can
00319 /// give 50mA. You may need to make provision for alternate power supply for
00320 /// the RFM module, especially if you wish to use full transmit power, and/or you have
00321 /// other shields demanding power. Inadequate power for the RFM is likely to cause symptoms such as:
00322 /// - reset's/bootups terminate with "init failed" messages
00323 /// - random termination of communication after 5-30 packets sent/received
00324 /// - "fake ok" state, where initialization passes fluently, but communication doesn't happen
00325 /// - shields hang Arduino boards, especially during the flashing
00326 ///
00327 /// \par Interrupts
00328 ///
00329 /// The RH_RF95 driver uses interrupts to react to events in the RFM module,
00330 /// such as the reception of a new packet, or the completion of transmission
00331 /// of a packet.  The RH_RF95 driver interrupt service routine reads status from
00332 /// and writes data to the the RFM module via the SPI interface. It is very
00333 /// important therefore, that if you are using the RH_RF95 driver with another
00334 /// SPI based deviced, that you disable interrupts while you transfer data to
00335 /// and from that other device.  Use cli() to disable interrupts and sei() to
00336 /// reenable them.
00337 ///
00338 /// \par Memory
00339 ///
00340 /// The RH_RF95 driver requires non-trivial amounts of memory. The sample
00341 /// programs all compile to about 8kbytes each, which will fit in the
00342 /// flash proram memory of most Arduinos. However, the RAM requirements are
00343 /// more critical. Therefore, you should be vary sparing with RAM use in
00344 /// programs that use the RH_RF95 driver.
00345 ///
00346 /// It is often hard to accurately identify when you are hitting RAM limits on Arduino.
00347 /// The symptoms can include:
00348 /// - Mysterious crashes and restarts
00349 /// - Changes in behaviour when seemingly unrelated changes are made (such as adding print() statements)
00350 /// - Hanging
00351 /// - Output from Serial.print() not appearing
00352 ///
00353 /// \par Range
00354 ///
00355 /// We have made some simple range tests under the following conditions:
00356 /// - rf95_client base station connected to a VHF discone antenna at 8m height above ground
00357 /// - rf95_server mobile connected to 17.3cm 1/4 wavelength antenna at 1m height, no ground plane.
00358 /// - Both configured for 13dBm, 434MHz, Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, CRC on. Slow+long range
00359 /// - Minimum reported RSSI seen for successful comms was about -91
00360 /// - Range over flat ground through heavy trees and vegetation approx 2km.
00361 /// - At 20dBm (100mW) otherwise identical conditions approx 3km.
00362 /// - At 20dBm, along salt water flat sandy beach, 3.2km.
00363 ///
00364 /// It should be noted that at this data rate, a 12 octet message takes 2 seconds to transmit.
00365 ///
00366 /// At 20dBm (100mW) with Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on.
00367 /// (Default medium range) in the conditions described above.
00368 /// - Range over flat ground through heavy trees and vegetation approx 2km.
00369 ///
00370 /// \par Transmitter Power
00371 ///
00372 /// You can control the transmitter power on the RF transceiver
00373 /// with the RH_RF95::setTxPower() function. The argument can be any of
00374 /// +5 to +23
00375 /// The default is 13. Eg:
00376 /// \code
00377 /// driver.setTxPower(10);
00378 /// \endcode
00379 ///
00380 /// We have made some actual power measurements against
00381 /// programmed power for Anarduino MiniWirelessLoRa (which has RFM96W-433Mhz installed)
00382 /// - MiniWirelessLoRa RFM96W-433Mhz, USB power
00383 /// - 30cm RG316 soldered direct to RFM96W module ANT and GND
00384 /// - SMA connector
00385 /// - 12db attenuator
00386 /// - SMA connector
00387 /// - MiniKits AD8307 HF/VHF Power Head (calibrated against Rohde&Schwartz 806.2020 test set)
00388 /// - Tektronix TDS220 scope to measure the Vout from power head
00389 /// \code
00390 /// Program power           Measured Power
00391 ///    dBm                         dBm
00392 ///      5                           5
00393 ///      7                           7
00394 ///      9                           8
00395 ///     11                          11
00396 ///     13                          13
00397 ///     15                          15
00398 ///     17                          16
00399 ///     19                          18
00400 ///     20                          20
00401 ///     21                          21
00402 ///     22                          22
00403 ///     23                          23
00404 /// \endcode
00405 /// (Caution: we dont claim laboratory accuracy for these measurements)
00406 /// You would not expect to get anywhere near these powers to air with a simple 1/4 wavelength wire antenna.
00407 class RH_RF95 : public RHSPIDriver
00408 {
00409 public:
00410     /// \brief Defines register values for a set of modem configuration registers
00411     ///
00412     /// Defines register values for a set of modem configuration registers
00413     /// that can be passed to setModemRegisters() if none of the choices in
00414     /// ModemConfigChoice suit your need setModemRegisters() writes the
00415     /// register values from this structure to the appropriate registers
00416     /// to set the desired spreading factor, coding rate and bandwidth
00417     typedef struct {
00418         uint8_t    reg_1d;   ///< Value for register RH_RF95_REG_1D_MODEM_CONFIG1
00419         uint8_t    reg_1e;   ///< Value for register RH_RF95_REG_1E_MODEM_CONFIG2
00420         uint8_t    reg_26;   ///< Value for register RH_RF95_REG_26_MODEM_CONFIG3
00421     } ModemConfig;
00422 
00423     /// Choices for setModemConfig() for a selected subset of common
00424     /// data rates. If you need another configuration,
00425     /// determine the necessary settings and call setModemRegisters() with your
00426     /// desired settings. It might be helpful to use the LoRa calculator mentioned in
00427     /// http://www.semtech.com/images/datasheet/LoraDesignGuide_STD.pdf
00428     /// These are indexes into MODEM_CONFIG_TABLE. We strongly recommend you use these symbolic
00429     /// definitions and not their integer equivalents: its possible that new values will be
00430     /// introduced in later versions (though we will try to avoid it).
00431     typedef enum {
00432         Bw125Cr45Sf128 = 0,    ///< Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium range
00433         Bw500Cr45Sf128,            ///< Bw = 500 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Fast+short range
00434         Bw31_25Cr48Sf512,      ///< Bw = 31.25 kHz, Cr = 4/8, Sf = 512chips/symbol, CRC on. Slow+long range
00435         Bw125Cr48Sf4096,           ///< Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, CRC on. Slow+long range
00436     } ModemConfigChoice;
00437 
00438     /// Constructor. You can have multiple instances, but each instance must have its own
00439     /// interrupt and slave select pin. After constructing, you must call init() to initialise the interface
00440     /// and the radio module. A maximum of 3 instances can co-exist on one processor, provided there are sufficient
00441     /// distinct interrupt lines, one for each instance.
00442     /// \param[in] slaveSelectPin the Arduino pin number of the output to use to select the RH_RF22 before
00443     /// accessing it. Defaults to the normal SS pin for your Arduino (D10 for Diecimila, Uno etc, D53 for Mega, D10 for Maple)
00444     /// \param[in] interruptPin The interrupt Pin number that is connected to the RFM DIO0 interrupt line.
00445     /// Defaults to pin 2, as required by Anarduino MinWirelessLoRa module.
00446     /// Caution: You must specify an interrupt capable pin.
00447     /// On many Arduino boards, there are limitations as to which pins may be used as interrupts.
00448     /// On Leonardo pins 0, 1, 2 or 3. On Mega2560 pins 2, 3, 18, 19, 20, 21. On Due and Teensy, any digital pin.
00449     /// On other Arduinos pins 2 or 3.
00450     /// See http://arduino.cc/en/Reference/attachInterrupt for more details.
00451     /// On Chipkit Uno32, pins 38, 2, 7, 8, 35.
00452     /// On other boards, any digital pin may be used.
00453     /// \param[in] spi Pointer to the SPI interface object to use.
00454     ///                Defaults to the standard Arduino hardware SPI interface
00455     RH_RF95(PINS slaveSelectPin, PINS interruptPin, RHGenericSPI& spi = hardware_spi);
00456 
00457     /// Initialise the Driver transport hardware and software.
00458     /// Make sure the Driver is properly configured before calling init().
00459     /// \return true if initialisation succeeded.
00460     virtual bool    init();
00461 
00462     /// Prints the value of all chip registers
00463     /// to the Serial device if RH_HAVE_SERIAL is defined for the current platform
00464     /// For debugging purposes only.
00465     /// \return true on success
00466     bool printRegisters();
00467 
00468     /// Sets all the registered required to configure the data modem in the RF95/96/97/98, including the bandwidth,
00469     /// spreading factor etc. You can use this to configure the modem with custom configurations if none of the
00470     /// canned configurations in ModemConfigChoice suit you.
00471     /// \param[in] config A ModemConfig structure containing values for the modem configuration registers.
00472     void           setModemRegisters(const ModemConfig* config);
00473 
00474     /// Select one of the predefined modem configurations. If you need a modem configuration not provided
00475     /// here, use setModemRegisters() with your own ModemConfig.
00476     /// \param[in] index The configuration choice.
00477     /// \return true if index is a valid choice.
00478     bool        setModemConfig(ModemConfigChoice index);
00479 
00480     /// Tests whether a new message is available
00481     /// from the Driver.
00482     /// On most drivers, this will also put the Driver into RHModeRx mode until
00483     /// a message is actually received by the transport, when it wil be returned to RHModeIdle.
00484     /// This can be called multiple times in a timeout loop
00485     /// \return true if a new, complete, error-free uncollected message is available to be retreived by recv()
00486     virtual bool    available();
00487 
00488     /// Turns the receiver on if it not already on.
00489     /// If there is a valid message available, copy it to buf and return true
00490     /// else return false.
00491     /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).
00492     /// You should be sure to call this function frequently enough to not miss any messages
00493     /// It is recommended that you call it in your main loop.
00494     /// \param[in] buf Location to copy the received message
00495     /// \param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied.
00496     /// \return true if a valid message was copied to buf
00497     virtual bool    recv(uint8_t* buf, uint8_t* len);
00498 
00499     /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent().
00500     /// Then loads a message into the transmitter and starts the transmitter. Note that a message length
00501     /// of 0 is permitted.
00502     /// \param[in] data Array of data to be sent
00503     /// \param[in] len Number of bytes of data to send
00504     /// \return true if the message length was valid and it was correctly queued for transmit
00505     virtual bool    send(const uint8_t* data, uint8_t len);
00506 
00507     /// Sets the length of the preamble
00508     /// in bytes.
00509     /// Caution: this should be set to the same
00510     /// value on all nodes in your network. Default is 8.
00511     /// Sets the message preamble length in RH_RF95_REG_??_PREAMBLE_?SB
00512     /// \param[in] bytes Preamble length in bytes.
00513     void           setPreambleLength(uint16_t bytes);
00514 
00515     /// Returns the maximum message length
00516     /// available in this Driver.
00517     /// \return The maximum legal message length
00518     virtual uint8_t maxMessageLength();
00519 
00520     /// Sets the transmitter and receiver
00521     /// centre frequency
00522     /// \param[in] centre Frequency in MHz. 137.0 to 1020.0. Caution: RFM95/96/97/98 comes in several
00523     /// different frequency ranges, and setting a frequency outside that range of your radio will probably not work
00524     /// \return true if the selected frquency centre is within range
00525     bool        setFrequency(float centre);
00526 
00527     /// If current mode is Rx or Tx changes it to Idle. If the transmitter or receiver is running,
00528     /// disables them.
00529     void           setModeIdle();
00530 
00531     /// If current mode is Tx or Idle, changes it to Rx.
00532     /// Starts the receiver in the RF95/96/97/98.
00533     void           setModeRx();
00534 
00535     /// If current mode is Rx or Idle, changes it to Rx. F
00536     /// Starts the transmitter in the RF95/96/97/98.
00537     void           setModeTx();
00538 
00539     /// Sets the transmitter power output level.
00540     /// Be a good neighbour and set the lowest power level you need.
00541     /// Caution: legal power limits may apply in certain countries. At powers above 20dBm, PA_DAC is enabled.
00542     /// After init(), the power will be set to 13dBm.
00543     /// \param[in] power Transmitter power level in dBm. For RFM95/96/97/98 LORA, valid values are from +5 to +23
00544     void           setTxPower(int8_t power);
00545 
00546     /// Sets the radio into low-power sleep mode.
00547     /// If successful, the transport will stay in sleep mode until woken by
00548     /// changing mode it idle, transmit or receive (eg by calling send(), recv(), available() etc)
00549     /// Caution: there is a time penalty as the radio takes a finite time to wake from sleep mode.
00550     /// \return true if sleep mode was successfully entered.
00551     virtual bool    sleep();
00552     
00553     void           handleInterrupt();
00554 
00555 protected:
00556     /// This is a low level function to handle the interrupts for one instance of RH_RF95.
00557     /// Called automatically by isr*()
00558     /// Should not need to be called by user code.
00559 
00560 
00561     /// Examine the revceive buffer to determine whether the message is for this node
00562     void validateRxBuf();
00563 
00564     /// Clear our local receive buffer
00565     void clearRxBuf();
00566 
00567 private:
00568 //  static void startISR();
00569     /// Low level interrupt service routine for device connected to interrupt 0
00570     static void         isr0();
00571 
00572     /// Low level interrupt service routine for device connected to interrupt 1
00573     static void         isr1();
00574 
00575     /// Low level interrupt service routine for device connected to interrupt 1
00576     static void         isr2();
00577 
00578     /// Array of instances connected to interrupts 0 and 1
00579     static RH_RF95*     _deviceForInterrupt[];
00580 
00581     /// Index of next interrupt number to use in _deviceForInterrupt
00582     static uint8_t      _interruptCount;
00583 
00584 #if (RH_PLATFORM == RH_PLATFORM_MBED)
00585     /// The configured interrupt pin connected to this instance
00586     InterruptIn _interruptPin;
00587     Thread _isrThread;
00588     static void manageISR();
00589 //    bool doISR;
00590 #else
00591     /// The configured interrupt pin connected to this instance
00592     uint8_t             _interruptPin;
00593 #endif
00594 
00595     /// The index into _deviceForInterrupt[] for this device (if an interrupt is already allocated)
00596     /// else 0xff
00597     uint8_t             _myInterruptIndex;
00598 
00599     /// Number of octets in the buffer
00600     volatile uint8_t    _bufLen;
00601 
00602     /// The receiver/transmitter buffer
00603     uint8_t             _buf[RH_RF95_MAX_PAYLOAD_LEN];
00604 
00605     /// True when there is a valid message in the buffer
00606     volatile bool       _rxBufValid;
00607 };
00608 
00609 /// @example rf95_client.pde
00610 /// @example rf95_server.pde
00611 /// @example rf95_reliable_datagram_client.pde
00612 /// @example rf95_reliable_datagram_server.pde
00613 
00614 #endif
00615