RadioHead
RH_LORA.h
1 // RH_LORA.h
2 //
3 // Definitions for HopeRF LoRa radios per:
4 // http://www.hoperf.com/upload/rf/RFM95_96_97_98W.pdf
5 // http://www.hoperf.cn/upload/rfchip/RF96_97_98.pdf
6 //
7 // Author: Mike McCauley (mikem@airspayce.com)
8 // Copyright (C) 2014 Mike McCauley
9 // $Id: RH_LORA.h,v 1.3 2014/06/29 06:32:36 mikem Exp mikem $
10 //
11 
12 #ifndef RH_LORA_h
13 #define RH_LORA_h
14 
15 #include <RHSPIDriver.h>
16 
17 // This is the maximum number of interrupts the driver can support
18 // Most Arduinos can handle 2, Megas can handle more
19 #define RH_LORA_NUM_INTERRUPTS 3
20 
21 // Max number of octets the LORA Rx/Tx FIFO can hold
22 #define RH_LORA_FIFO_SIZE 255
23 
24 // This is the maximum number of bytes that can be carried by the LORA.
25 // We use some for headers, keeping fewer for RadioHead messages
26 #define RH_LORA_MAX_PAYLOAD_LEN RH_LORA_FIFO_SIZE
27 
28 // The length of the headers we add.
29 // The headers are inside the LORA's payload
30 #define RH_LORA_HEADER_LEN 4
31 
32 // This is the maximum message length that can be supported by this driver.
33 // Can be pre-defined to a smaller size (to save SRAM) prior to including this header
34 // Here we allow for 1 byte message length, 4 bytes headers, user data and 2 bytes of FCS
35 #ifndef RH_LORA_MAX_MESSAGE_LEN
36  #define RH_LORA_MAX_MESSAGE_LEN (RH_LORA_MAX_PAYLOAD_LEN - RH_LORA_HEADER_LEN)
37 #endif
38 
39 // The crystal oscillator frequency of the module
40 #define RH_LORA_FXOSC 32000000.0
41 
42 // The Frequency Synthesizer step = RH_LORA_FXOSC / 2^^19
43 #define RH_LORA_FSTEP (RH_LORA_FXOSC / 524288)
44 
45 
46 // Register names (LoRa Mode, from table 85)
47 #define RH_LORA_REG_00_FIFO 0x00
48 #define RH_LORA_REG_01_OP_MODE 0x01
49 #define RH_LORA_REG_02_RESERVED 0x02
50 #define RH_LORA_REG_03_RESERVED 0x03
51 #define RH_LORA_REG_04_RESERVED 0x04
52 #define RH_LORA_REG_05_RESERVED 0x05
53 #define RH_LORA_REG_06_FRF_MSB 0x06
54 #define RH_LORA_REG_07_FRF_MID 0x07
55 #define RH_LORA_REG_08_FRF_LSB 0x08
56 #define RH_LORA_REG_09_PA_CONFIG 0x09
57 #define RH_LORA_REG_0A_PA_RAMP 0x0a
58 #define RH_LORA_REG_0B_OCP 0x0b
59 #define RH_LORA_REG_0C_LNA 0x0c
60 #define RH_LORA_REG_0D_FIFO_ADDR_PTR 0x0d
61 #define RH_LORA_REG_0E_FIFO_TX_BASE_ADDR 0x0e
62 #define RH_LORA_REG_0F_FIFO_RX_BASE_ADDR 0x0f
63 #define RH_LORA_REG_10_FIFO_RX_CURRENT_ADDR 0x10
64 #define RH_LORA_REG_11_IRQ_FLAGS_MASK 0x11
65 #define RH_LORA_REG_12_IRQ_FLAGS 0x12
66 #define RH_LORA_REG_13_RX_NB_BYTES 0x13
67 #define RH_LORA_REG_14_RX_HEADER_CNT_VALUE_MSB 0x14
68 #define RH_LORA_REG_15_RX_HEADER_CNT_VALUE_LSB 0x15
69 #define RH_LORA_REG_16_RX_PACKET_CNT_VALUE_MSB 0x16
70 #define RH_LORA_REG_17_RX_PACKET_CNT_VALUE_LSB 0x17
71 #define RH_LORA_REG_18_MODEM_STAT 0x18
72 #define RH_LORA_REG_19_PKT_SNR_VALUE 0x19
73 #define RH_LORA_REG_1A_PKT_RSSI_VALUE 0x1a
74 #define RH_LORA_REG_1B_RSSI_VALUE 0x1b
75 #define RH_LORA_REG_1C_HOP_CHANNEL 0x1c
76 #define RH_LORA_REG_1D_MODEM_CONFIG1 0x1d
77 #define RH_LORA_REG_1E_MODEM_CONFIG2 0x1e
78 #define RH_LORA_REG_1F_SYMB_TIMEOUT_LSB 0x1f
79 #define RH_LORA_REG_20_PREAMBLE_MSB 0x20
80 #define RH_LORA_REG_21_PREAMBLE_LSB 0x21
81 #define RH_LORA_REG_22_PAYLOAD_LENGTH 0x22
82 #define RH_LORA_REG_23_MAX_PAYLOAD_LENGTH 0x23
83 #define RH_LORA_REG_24_HOP_PERIOD 0x24
84 #define RH_LORA_REG_25_FIFO_RX_BYTE_ADDR 0x25
85 #define RH_LORA_REG_26_MODEM_CONFIG3 0x26
86 
87 #define RH_LORA_REG_40_DIO_MAPPING1 0x40
88 #define RH_LORA_REG_41_DIO_MAPPING2 0x41
89 #define RH_LORA_REG_42_VERSION 0x42
90 
91 // RH_LORA_REG_01_OP_MODE 0x01
92 #define RH_LORA_LONG_RANGE_MODE 0x80
93 #define RH_LORA_ACCESS_SHARED_REG 0x40
94 #define RH_LORA_MODE 0x07
95 #define RH_LORA_MODE_SLEEP 0x00
96 #define RH_LORA_MODE_STDBY 0x01
97 #define RH_LORA_MODE_FSTX 0x02
98 #define RH_LORA_MODE_TX 0x03
99 #define RH_LORA_MODE_FSRX 0x04
100 #define RH_LORA_MODE_RXCONTINUOUS 0x05
101 #define RH_LORA_MODE_RXSINGLE 0x06
102 #define RH_LORA_MODE_CAD 0x07
103 
104 // RH_LORA_REG_09_PA_CONFIG 0x09
105 #define RH_LORA_PA_SELECT 0x80
106 #define RH_LORA_OUTPUT_POWER 0x0f
107 
108 // RH_LORA_REG_0A_PA_RAMP 0x0a
109 #define RH_LORA_LOW_PN_TX_PLL_OFF 0x10
110 #define RH_LORA_PA_RAMP 0x0f
111 #define RH_LORA_PA_RAMP_3_4MS 0x00
112 #define RH_LORA_PA_RAMP_2MS 0x01
113 #define RH_LORA_PA_RAMP_1MS 0x02
114 #define RH_LORA_PA_RAMP_500US 0x03
115 #define RH_LORA_PA_RAMP_250US 0x0
116 #define RH_LORA_PA_RAMP_125US 0x05
117 #define RH_LORA_PA_RAMP_100US 0x06
118 #define RH_LORA_PA_RAMP_62US 0x07
119 #define RH_LORA_PA_RAMP_50US 0x08
120 #define RH_LORA_PA_RAMP_40US 0x09
121 #define RH_LORA_PA_RAMP_31US 0x0a
122 #define RH_LORA_PA_RAMP_25US 0x0b
123 #define RH_LORA_PA_RAMP_20US 0x0c
124 #define RH_LORA_PA_RAMP_15US 0x0d
125 #define RH_LORA_PA_RAMP_12US 0x0e
126 #define RH_LORA_PA_RAMP_10US 0x0f
127 
128 // RH_LORA_REG_0B_OCP 0x0b
129 #define RH_LORA_OCP_ON 0x20
130 #define RH_LORA_OCP_TRIM 0x1f
131 
132 // RH_LORA_REG_0C_LNA 0x0c
133 #define RH_LORA_LNA_GAIN 0xe0
134 #define RH_LORA_LNA_BOOST 0x03
135 #define RH_LORA_LNA_BOOST_DEFAULT 0x00
136 #define RH_LORA_LNA_BOOST_150PC 0x11
137 
138 // RH_LORA_REG_11_IRQ_FLAGS_MASK 0x11
139 #define RH_LORA_RX_TIMEOUT_MASK 0x80
140 #define RH_LORA_RX_DONE_MASK 0x40
141 #define RH_LORA_PAYLOAD_CRC_ERROR_MASK 0x20
142 #define RH_LORA_VALID_HEADER_MASK 0x10
143 #define RH_LORA_TX_DONE_MASK 0x08
144 #define RH_LORA_CAD_DONE_MASK 0x04
145 #define RH_LORA_FHSS_CHANGE_CHANNEL_MASK 0x02
146 #define RH_LORA_CAD_DETECTED_MASK 0x01
147 
148 // RH_LORA_REG_12_IRQ_FLAGS 0x12
149 #define RH_LORA_RX_TIMEOUT 0x80
150 #define RH_LORA_RX_DONE 0x40
151 #define RH_LORA_PAYLOAD_CRC_ERROR 0x20
152 #define RH_LORA_VALID_HEADER 0x10
153 #define RH_LORA_TX_DONE 0x08
154 #define RH_LORA_CAD_DONE 0x04
155 #define RH_LORA_FHSS_CHANGE_CHANNEL 0x02
156 #define RH_LORA_CAD_DETECTED 0x01
157 
158 // RH_LORA_REG_18_MODEM_STAT 0x18
159 #define RH_LORA_RX_CODING_RATE 0xe0
160 #define RH_LORA_MODEM_STATUS_CLEAR 0x10
161 #define RH_LORA_MODEM_STATUS_HEADER_INFO_VALID 0x08
162 #define RH_LORA_MODEM_STATUS_RX_ONGOING 0x04
163 #define RH_LORA_MODEM_STATUS_SIGNAL_SYNCHRONIZED 0x02
164 #define RH_LORA_MODEM_STATUS_SIGNAL_DETECTED 0x01
165 
166 // RH_LORA_REG_1C_HOP_CHANNEL 0x1c
167 #define RH_LORA_PLL_TIMEOUT 0x80
168 #define RH_LORA_RX_PAYLOAD_CRC_ON 0x40
169 #define RH_LORA_FHSS_PRESENT_CHANNEL 0x3f
170 
171 // RH_LORA_REG_1D_MODEM_CONFIG1 0x1d
172 #define RH_LORA_BW 0xc0
173 #define RH_LORA_BW_125KHZ 0x00
174 #define RH_LORA_BW_250KHZ 0x40
175 #define RH_LORA_BW_500KHZ 0x80
176 #define RH_LORA_BW_RESERVED 0xc0
177 #define RH_LORA_CODING_RATE 0x38
178 #define RH_LORA_CODING_RATE_4_5 0x00
179 #define RH_LORA_CODING_RATE_4_6 0x08
180 #define RH_LORA_CODING_RATE_4_7 0x10
181 #define RH_LORA_CODING_RATE_4_8 0x18
182 #define RH_LORA_IMPLICIT_HEADER_MODE_ON 0x04
183 #define RH_LORA_RX_PAYLOAD_CRC_ON 0x02
184 #define RH_LORA_LOW_DATA_RATE_OPTIMIZE 0x01
185 
186 // RH_LORA_REG_1E_MODEM_CONFIG2 0x1e
187 #define RH_LORA_SPREADING_FACTOR 0xf0
188 #define RH_LORA_SPREADING_FACTOR_64CPS 0x60
189 #define RH_LORA_SPREADING_FACTOR_128CPS 0x70
190 #define RH_LORA_SPREADING_FACTOR_256CPS 0x80
191 #define RH_LORA_SPREADING_FACTOR_512CPS 0x90
192 #define RH_LORA_SPREADING_FACTOR_1024CPS 0xa0
193 #define RH_LORA_SPREADING_FACTOR_2048CPS 0xb0
194 #define RH_LORA_SPREADING_FACTOR_4096CPS 0xc0
195 #define RH_LORA_TX_CONTINUOUS_MOE 0x08
196 #define RH_LORA_AGC_AUTO_ON 0x04
197 #define RH_LORA_SYM_TIMEOUT_MSB 0x03
198 
199 /////////////////////////////////////////////////////////////////////
200 /// \class RH_LORA RH_LORA.h <RH_LORA.h>
201 /// \brief Driver to send and receive unaddressed, unreliable datagrams via a LoRa
202 /// capable radio transceiver.
203 ///
204 /// For Semtech SX1272/73, HopeRF RFM95/96/97/98 and other similar LoRa capable radios
205 /// based on http://www.semtech.com/images/datasheet/sx1272.pdf
206 /// and http://www.semtech.com/images/datasheet/LoraDesignGuide_STD.pdf
207 /// and http://www.hoperf.com/upload/rf/RFM95_96_97_98W.pdf
208 /// and http://www.hoperf.cn/upload/rfchip/RF96_97_98.pdf
209 ///
210 /// Works with
211 /// - the excellent MinWirelessLoRa from Anarduino (link TBA)
212 ///
213 /// \par Overview
214 ///
215 /// This class provides basic functions for sending and receiving unaddressed,
216 /// unreliable datagrams of arbitrary length to 251 octets per packet.
217 ///
218 /// Manager classes may use this class to implement reliable, addressed datagrams and streams,
219 /// mesh routers, repeaters, translators etc.
220 ///
221 /// Naturally, for any 2 radios to communicate that must be configured to use the same frequency and
222 /// modulation scheme.
223 ///
224 /// This Driver provides an object-oriented interface for sending and receiving data messages with Hope-RF
225 /// RFM95/96/97/98(W) and compatible radio modules on LoRa mode.
226 ///
227 /// The Hope-RF (http://www.hoperf.com) RFM95/96/97/98(W) is a low-cost ISM transceiver
228 /// chip. It supports FSK, GFSK, OOK over a wide range of frequencies and
229 /// programmable data rates, and it also supports the proprietary LoRA (Long Range) mode, which
230 /// is what we use in this RadioHead driver.
231 ///
232 /// This Driver provides functions for sending and receiving messages of up
233 /// to 251 octets on any frequency supported by the radio, in a range of
234 /// predefined Bandwidths, Spreading Factors and Coding Rates. Frequency can be set with
235 /// 61Hz precision to any frequency from 240.0MHz to 960.0MHz. Caution: most modules only support a more limited
236 /// range of frequencies due to antenna tuning.
237 ///
238 /// Up to 2 RFM95/96/97/98(W) modules can be connected to an Arduino (3 on a Mega),
239 /// permitting the construction of translators and frequency changers, etc.
240 ///
241 /// Support for other RF69 features such as transmitter power control etc is
242 /// also provided.
243 ///
244 /// Tested on MinWirelessLoRa with arduino-1.0.5
245 /// on OpenSuSE 13.1
246 ///
247 /// \par Packet Format
248 ///
249 /// All messages sent and received by this RH_LORA Driver conform to this packet format:
250 ///
251 /// - LoRa mode:
252 /// - 8 symbol PREAMBLE
253 /// - Explicit header with header CRC (handled internally by the radio)
254 /// - 4 octets HEADER: (TO, FROM, ID, FLAGS)
255 /// - 0 to 251 octets DATA
256 /// - CRC (handled internally by the radio)
257 ///
258 /// \par Connecting RFM95/96/97/98 to Arduino
259 ///
260 /// We tested with Anarduino MiniWirelessLoRA, which is an Arduino Duemilanove compatible with a RFM96W
261 /// module on-board. Therefore it needs no connections other than the USB
262 /// programming connection and an antenna to make it work.
263 ///
264 /// If you have a bare RFM95/96/97/98 that you want to connect to an Arduino, you
265 /// might use these connections (untested): CAUTION: you must use a 3.3V type
266 /// Arduino, otherwise you will also need voltage level shifters between the
267 /// Arduino and the RFM69. CAUTION, you must also ensure you connect an
268 /// antenna
269 ///
270 /// \code
271 /// Arduino RFM95/96/97/98
272 /// GND----------GND (ground in)
273 /// 3V3----------3.3V (3.3V in)
274 /// interrupt 0 pin D2-----------DIO0 (interrupt request out)
275 /// SS pin D10----------NSS (chip select in)
276 /// SCK pin D13----------SCK (SPI clock in)
277 /// MOSI pin D11----------MOSI (SPI Data in)
278 /// MISO pin D12----------MISO (SPI Data out)
279 /// \endcode
280 ///
281 /// With these connections, you can then use the default constructor RH_LORA().
282 /// You can override the default settings for the SS pin and the interrupt in
283 /// the RH_LORA constructor if you wish to connect the slave select SS to other
284 /// than the normal one for your Arduino (D10 for Diecimila, Uno etc and D53
285 /// for Mega) or the interrupt request to other than pin D2 (Caution,
286 /// different processors have different constraints as to the pins available
287 /// for interrupts).
288 ///
289 /// It is possible to have 2 or more radios connected to one Arduino, provided
290 /// each radio has its own SS and interrupt line (SCK, SDI and SDO are common
291 /// to all radios)
292 ///
293 /// Caution: on some Arduinos such as the Mega 2560, if you set the slave
294 /// select pin to be other than the usual SS pin (D53 on Mega 2560), you may
295 /// need to set the usual SS pin to be an output to force the Arduino into SPI
296 /// master mode.
297 ///
298 /// Caution: Power supply requirements of the RFM module may be relevant in some circumstances:
299 /// RFM95/96/97/98 modules are capable of pulling 120mA+ at full power, where Arduino's 3.3V line can
300 /// give 50mA. You may need to make provision for alternate power supply for
301 /// the RFM module, especially if you wish to use full transmit power, and/or you have
302 /// other shields demanding power. Inadequate power for the RFM is likely to cause symptoms such as:
303 /// -reset's/bootups terminate with "init failed" messages
304 /// -random termination of communication after 5-30 packets sent/received
305 /// -"fake ok" state, where initialization passes fluently, but communication doesn't happen
306 /// -shields hang Arduino boards, especially during the flashing
307 ///
308 /// \par Interrupts
309 ///
310 /// The RH_LORA driver uses interrupts to react to events in the RFM module,
311 /// such as the reception of a new packet, or the completion of transmission
312 /// of a packet. The RH_LORA driver interrupt service routine reads status from
313 /// and writes data to the the RFM module via the SPI interface. It is very
314 /// important therefore, that if you are using the RH_LORA driver with another
315 /// SPI based deviced, that you disable interrupts while you transfer data to
316 /// and from that other device. Use cli() to disable interrupts and sei() to
317 /// reenable them.
318 ///
319 /// \par Memory
320 ///
321 /// The RH_LORA driver requires non-trivial amounts of memory. The sample
322 /// programs all compile to about 8kbytes each, which will fit in the
323 /// flash proram memory of most Arduinos. However, the RAM requirements are
324 /// more critical. Therefore, you should be vary sparing with RAM use in
325 /// programs that use the RH_LORA driver.
326 ///
327 /// It is often hard to accurately identify when you are hitting RAM limits on Arduino.
328 /// The symptoms can include:
329 /// - Mysterious crashes and restarts
330 /// - Changes in behaviour when seemingly unrelated changes are made (such as adding print() statements)
331 /// - Hanging
332 /// - Output from Serial.print() not appearing
333 ///
334 /// \par Transmitter Power
335 ///
336 /// You can control the transmitter power on the RF transceiver
337 /// with the RH_LORA::setTxPower() function. The argument can be any of
338 /// +5 to +20
339 /// The default is 13. Eg:
340 /// \code
341 /// driver.setTxPower(10);
342 /// \endcode
343 ///
344 /// We have made some actual power measurements against
345 /// programmed power for Anarduino MiniWirelessLoRa (which has RFM96W-433Mhz installed)
346 /// - MiniWirelessLoRa RFM96W-433Mhz, USB power
347 /// - 30cm RG316 soldered direct to RFM96W module ANT and GND
348 /// - SMA connector
349 /// - MiniKits AD8307 HF/VHF Power Head (calibrated against Rohde&Schwartz 806.2020 test set)
350 /// - Tektronix TDS220 scope to measure the Vout from power head
351 /// \code
352 /// Program power Measured Power
353 /// dBm dBm
354 /// 5 6
355 /// 7 9
356 /// 9 12
357 /// 11 14
358 /// 13 16
359 /// 15 16
360 /// 17 17
361 /// 19 19
362 /// 20 19
363 /// \endcode
364 /// (Caution: we dont claim laboratory accuracy for these measurements)
365 /// You would not expect to get anywhere near these powers to air with a simple 1/4 wavelength wire antenna.
366 class RH_LORA : public RHSPIDriver
367 {
368 public:
369  /// \brief Defines register values for a set of modem configuration registers
370  ///
371  /// Defines register values for a set of modem configuration registers
372  /// that can be passed to setModemRegisters() if none of the choices in
373  /// ModemConfigChoice suit your need setModemRegisters() writes the
374  /// register values from this structure to the appropriate registers
375  /// to set the desired spreading factor, coding rate and bandwidth
376  typedef struct
377  {
378  uint8_t reg_1d; ///< Value for register RH_LORA_REG_1D_MODEM_CONFIG1
379  uint8_t reg_1e; ///< Value for register RH_LORA_REG_1E_MODEM_CONFIG2
380  uint8_t reg_26; ///< Value for register RH_LORA_REG_26_MODEM_CONFIG3
381  } ModemConfig;
382 
383  /// Choices for setModemConfig() for a selected subset of common
384  /// data rates. If you need another configuration,
385  /// determine the necessary settings and call setModemRegisters() with your
386  /// desired settings. It might be helpful to use the LoRa calculator mentioned in
387  /// http://www.semtech.com/images/datasheet/LoraDesignGuide_STD.pdf
388  /// These are indexes into MODEM_CONFIG_TABLE. We strongly recommend you use these symbolic
389  /// definitions and not their integer equivalents: its possible that new values will be
390  /// introduced in later versions (though we will try to avoid it).
391  typedef enum
392  {
393  Bw125Cr45Sf128 = 0, ///< Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
394  Bw500Cr45Sf128, ///< Bw = 500 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on
396 
397  /// Constructor. You can have multiple instances, but each instance must have its own
398  /// interrupt and slave select pin. After constructing, you must call init() to initialise the interface
399  /// and the radio module. A maximum of 3 instances can co-exist on one processor, provided there are sufficient
400  /// distinct interrupt lines, one for each instance.
401  /// \param[in] slaveSelectPin the Arduino pin number of the output to use to select the RH_RF22 before
402  /// accessing it. Defaults to the normal SS pin for your Arduino (D10 for Diecimila, Uno etc, D53 for Mega, D10 for Maple)
403  /// \param[in] interruptPin The interrupt Pin number that is connected to the RFM DIO0 interrupt line.
404  /// Defaults to pin 2, as required by Anardion MinWirelessLoRa module.
405  /// Caution: You must specify an interrupt capable pin.
406  /// On many Arduino boards, there are limitations as to which pins may be used as interrupts.
407  /// On Leonardo pins 0, 1, 2 or 3. On Mega2560 pins 2, 3, 18, 19, 20, 21. On Due and Teensy, any digital pin.
408  /// On other Arduinos pins 2 or 3.
409  /// See http://arduino.cc/en/Reference/attachInterrupt for more details.
410  /// On Chipkit Uno32, pins 38, 2, 7, 8, 35.
411  /// On other boards, any digital pin may be used.
412  /// \param[in] spi Pointer to the SPI interface object to use.
413  /// Defaults to the standard Arduino hardware SPI interface
414  RH_LORA(uint8_t slaveSelectPin = SS, uint8_t interruptPin = 2, RHGenericSPI& spi = hardware_spi);
415 
416  /// Initialise the Driver transport hardware and software.
417  /// Make sure the Driver is properly configured before calling init().
418  /// \return true if initialisation succeeded.
419  virtual bool init();
420 
421  /// Prints the value of all chip registers
422  /// for debugging purposes
423  /// \return true on success
424  bool printRegisters();
425 
426  /// Sets all the registered required to configure the data modem in the LORA, including the bandwidth,
427  /// spreading factor etc. You can use this to configure the modem with custom configurations if none of the
428  /// canned configurations in ModemConfigChoice suit you.
429  /// \param[in] config A ModemConfig structure containing values for the modem configuration registers.
430  void setModemRegisters(const ModemConfig* config);
431 
432  /// Select one of the predefined modem configurations. If you need a modem configuration not provided
433  /// here, use setModemRegisters() with your own ModemConfig.
434  /// \param[in] index The configuration choice.
435  /// \return true if index is a valid choice.
436  bool setModemConfig(ModemConfigChoice index);
437 
438  /// Tests whether a new message is available
439  /// from the Driver.
440  /// On most drivers, this will also put the Driver into RHModeRx mode until
441  /// a message is actually received by the transport, when it wil be returned to RHModeIdle.
442  /// This can be called multiple times in a timeout loop
443  /// \return true if a new, complete, error-free uncollected message is available to be retreived by recv()
444  virtual bool available();
445 
446  /// Turns the receiver on if it not already on.
447  /// If there is a valid message available, copy it to buf and return true
448  /// else return false.
449  /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).
450  /// You should be sure to call this function frequently enough to not miss any messages
451  /// It is recommended that you call it in your main loop.
452  /// \param[in] buf Location to copy the received message
453  /// \param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied.
454  /// \return true if a valid message was copied to buf
455  virtual bool recv(uint8_t* buf, uint8_t* len);
456 
457  /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent().
458  /// Then loads a message into the transmitter and starts the transmitter. Note that a message length
459  /// of 0 is permitted.
460  /// \param[in] data Array of data to be sent
461  /// \param[in] len Number of bytes of data to send
462  /// \return true if the message length was valid and it was correctly queued for transmit
463  virtual bool send(const uint8_t* data, uint8_t len);
464 
465  /// Sets the length of the preamble
466  /// in bytes.
467  /// Caution: this should be set to the same
468  /// value on all nodes in your network. Default is 8.
469  /// Sets the message preamble length in RH_LORA_REG_??_PREAMBLE_?SB
470  /// \param[in] bytes Preamble length in bytes.
471  void setPreambleLength(uint16_t bytes);
472 
473  /// Returns the maximum message length
474  /// available in this Driver.
475  /// \return The maximum legal message length
476  virtual uint8_t maxMessageLength();
477 
478  /// Sets the transmitter and receiver
479  /// centre frequency
480  /// \param[in] centre Frequency in MHz. 137.0 to 1020.0. Caution,RFM95/96/97/98 comes in several
481  /// different frequency ranges, and setting a frequency outside that range of your radio will probably not work
482  /// \return true if the selected frquency centre is within range
483  bool setFrequency(float centre);
484 
485  /// If current mode is Rx or Tx changes it to Idle. If the transmitter or receiver is running,
486  /// disables them.
487  void setModeIdle();
488 
489  /// If current mode is Tx or Idle, changes it to Rx.
490  /// Starts the receiver in the LORA.
491  void setModeRx();
492 
493  /// If current mode is Rx or Idle, changes it to Rx. F
494  /// Starts the transmitter in the LORA.
495  void setModeTx();
496 
497  /// Sets the transmitter power output level.
498  /// Be a good neighbour and set the lowest power level you need.
499  /// Caution: legal power limits may apply in certain countries.
500  /// After init(), the power will be set to 13dBm.
501  /// \param[in] power Transmitter power level in dBm. For RFM95/96/97/98 LORA, valid values are from +5 to +20
502  void setTxPower(int8_t power);
503 
504 protected:
505  /// This is a low level function to handle the interrupts for one instance of RF69.
506  /// Called automatically by isr*()
507  /// Should not need to be called by user code.
508  void handleInterrupt();
509 
510  /// Examine the revceive buffer to determine whether the message is for this node
511  void validateRxBuf();
512 
513  /// Clear our local receive buffer
514  void clearRxBuf();
515 
516 private:
517  /// Low level interrupt service routine for device connected to interrupt 0
518  static void isr0();
519 
520  /// Low level interrupt service routine for device connected to interrupt 1
521  static void isr1();
522 
523  /// Low level interrupt service routine for device connected to interrupt 1
524  static void isr2();
525 
526  /// Array of instances connected to interrupts 0 and 1
527  static RH_LORA* _deviceForInterrupt[];
528 
529  /// Index of next interrupt number to use in _deviceForInterrupt
530  static uint8_t _interruptCount;
531 
532  /// The configured interrupt pin connected to this instance
533  uint8_t _interruptPin;
534 
535  /// Number of octets in the buffer
536  volatile uint8_t _bufLen;
537 
538  /// The receiver/transmitter buffer
539  uint8_t _buf[RH_LORA_MAX_PAYLOAD_LEN];
540 
541  /// True when there is a valid message in the buffer
542  volatile bool _rxBufValid;
543 };
544 
545 /// @example lora_client.pde
546 /// @example lora_server.pde
547 /// @example lora_reliable_datagram_client.pde
548 /// @example lora_reliable_datagram_server.pde
549 
550 #endif
551 
Defines register values for a set of modem configuration registers.
Definition: RH_LORA.h:376
virtual uint8_t maxMessageLength()
Definition: RH_LORA.cpp:245
Bw = 500 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on.
Definition: RH_LORA.h:394
Base class for SPI interfaces.
Definition: RHGenericSPI.h:30
virtual bool available()
Definition: RH_LORA.cpp:176
virtual bool send(const uint8_t *data, uint8_t len)
Definition: RH_LORA.cpp:207
void setModeRx()
Definition: RH_LORA.cpp:270
bool printRegisters()
Definition: RH_LORA.cpp:231
void setModemRegisters(const ModemConfig *config)
Definition: RH_LORA.cpp:306
Driver to send and receive unaddressed, unreliable datagrams via a LoRa capable radio transceiver...
Definition: RH_LORA.h:366
void setModeTx()
Definition: RH_LORA.cpp:280
void validateRxBuf()
Examine the revceive buffer to determine whether the message is for this node.
Definition: RH_LORA.cpp:158
RH_LORA(uint8_t slaveSelectPin=SS, uint8_t interruptPin=2, RHGenericSPI &spi=hardware_spi)
Definition: RH_LORA.cpp:23
Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on.
Definition: RH_LORA.h:393
bool setFrequency(float centre)
Definition: RH_LORA.cpp:250
void setModeIdle()
Definition: RH_LORA.cpp:261
bool setModemConfig(ModemConfigChoice index)
Definition: RH_LORA.cpp:315
virtual bool init()
Definition: RH_LORA.cpp:31
virtual bool recv(uint8_t *buf, uint8_t *len)
Definition: RH_LORA.cpp:190
ModemConfigChoice
Definition: RH_LORA.h:391
void setTxPower(int8_t power)
Definition: RH_LORA.cpp:290
uint8_t reg_26
Value for register RH_LORA_REG_26_MODEM_CONFIG3.
Definition: RH_LORA.h:380
uint8_t reg_1d
Value for register RH_LORA_REG_1D_MODEM_CONFIG1.
Definition: RH_LORA.h:378
uint8_t reg_1e
Value for register RH_LORA_REG_1E_MODEM_CONFIG2.
Definition: RH_LORA.h:379
void handleInterrupt()
Definition: RH_LORA.cpp:102
void clearRxBuf()
Clear our local receive buffer.
Definition: RH_LORA.cpp:182
Base class for a RadioHead drivers that use the SPI bus to communicate with its transport hardware...
Definition: RHSPIDriver.h:38
void setPreambleLength(uint16_t bytes)
Definition: RH_LORA.cpp:327