RadioHead
RH_RF69.h
1 // RH_RF69.h
2 // Author: Mike McCauley (mikem@airspayce.com)
3 // Copyright (C) 2014 Mike McCauley
4 // $Id: RH_RF69.h,v 1.37 2019/07/14 00:18:48 mikem Exp $
5 //
6 ///
7 
8 
9 #ifndef RH_RF69_h
10 #define RH_RF69_h
11 
12 #include <RHGenericSPI.h>
13 #include <RHSPIDriver.h>
14 
15 // The crystal oscillator frequency of the RF69 module
16 #define RH_RF69_FXOSC 32000000.0
17 
18 // The Frequency Synthesizer step = RH_RF69_FXOSC / 2^^19
19 #define RH_RF69_FSTEP (RH_RF69_FXOSC / 524288)
20 
21 // This is the maximum number of interrupts the driver can support
22 // Most Arduinos can handle 2, Megas can handle more
23 #define RH_RF69_NUM_INTERRUPTS 3
24 
25 // This is the bit in the SPI address that marks it as a write
26 #define RH_RF69_SPI_WRITE_MASK 0x80
27 
28 // Max number of octets the RH_RF69 Rx and Tx FIFOs can hold
29 #define RH_RF69_FIFO_SIZE 66
30 
31 // Maximum encryptable payload length the RF69 can support
32 #define RH_RF69_MAX_ENCRYPTABLE_PAYLOAD_LEN 64
33 
34 // The length of the headers we add.
35 // The headers are inside the RF69's payload and are therefore encrypted if encryption is enabled
36 #define RH_RF69_HEADER_LEN 4
37 
38 // This is the maximum message length that can be supported by this driver. Limited by
39 // the size of the FIFO, since we are unable to support on-the-fly filling and emptying
40 // of the FIFO.
41 // Can be pre-defined to a smaller size (to save SRAM) prior to including this header
42 // Here we allow for 4 bytes of address and header and payload to be included in the 64 byte encryption limit.
43 // the one byte payload length is not encrpyted
44 #ifndef RH_RF69_MAX_MESSAGE_LEN
45 #define RH_RF69_MAX_MESSAGE_LEN (RH_RF69_MAX_ENCRYPTABLE_PAYLOAD_LEN - RH_RF69_HEADER_LEN)
46 #endif
47 
48 // Keep track of the mode the RF69 is in
49 #define RH_RF69_MODE_IDLE 0
50 #define RH_RF69_MODE_RX 1
51 #define RH_RF69_MODE_TX 2
52 
53 // This is the default node address,
54 #define RH_RF69_DEFAULT_NODE_ADDRESS 0
55 
56 // You can define the following macro (either by editing here or by passing it as a compiler definition
57 // to change the default value of the ishighpowermodule argument to setTxPower to true
58 //
59 // #define RFM69_HW
60 #ifdef RFM69_HW
61 #define RH_RF69_DEFAULT_HIGHPOWER true
62 #else
63 #define RH_RF69_DEFAULT_HIGHPOWER false
64 #endif
65 
66 // Register names
67 #define RH_RF69_REG_00_FIFO 0x00
68 #define RH_RF69_REG_01_OPMODE 0x01
69 #define RH_RF69_REG_02_DATAMODUL 0x02
70 #define RH_RF69_REG_03_BITRATEMSB 0x03
71 #define RH_RF69_REG_04_BITRATELSB 0x04
72 #define RH_RF69_REG_05_FDEVMSB 0x05
73 #define RH_RF69_REG_06_FDEVLSB 0x06
74 #define RH_RF69_REG_07_FRFMSB 0x07
75 #define RH_RF69_REG_08_FRFMID 0x08
76 #define RH_RF69_REG_09_FRFLSB 0x09
77 #define RH_RF69_REG_0A_OSC1 0x0a
78 #define RH_RF69_REG_0B_AFCCTRL 0x0b
79 #define RH_RF69_REG_0C_RESERVED 0x0c
80 #define RH_RF69_REG_0D_LISTEN1 0x0d
81 #define RH_RF69_REG_0E_LISTEN2 0x0e
82 #define RH_RF69_REG_0F_LISTEN3 0x0f
83 #define RH_RF69_REG_10_VERSION 0x10
84 #define RH_RF69_REG_11_PALEVEL 0x11
85 #define RH_RF69_REG_12_PARAMP 0x12
86 #define RH_RF69_REG_13_OCP 0x13
87 #define RH_RF69_REG_14_RESERVED 0x14
88 #define RH_RF69_REG_15_RESERVED 0x15
89 #define RH_RF69_REG_16_RESERVED 0x16
90 #define RH_RF69_REG_17_RESERVED 0x17
91 #define RH_RF69_REG_18_LNA 0x18
92 #define RH_RF69_REG_19_RXBW 0x19
93 #define RH_RF69_REG_1A_AFCBW 0x1a
94 #define RH_RF69_REG_1B_OOKPEAK 0x1b
95 #define RH_RF69_REG_1C_OOKAVG 0x1c
96 #define RH_RF69_REG_1D_OOKFIX 0x1d
97 #define RH_RF69_REG_1E_AFCFEI 0x1e
98 #define RH_RF69_REG_1F_AFCMSB 0x1f
99 #define RH_RF69_REG_20_AFCLSB 0x20
100 #define RH_RF69_REG_21_FEIMSB 0x21
101 #define RH_RF69_REG_22_FEILSB 0x22
102 #define RH_RF69_REG_23_RSSICONFIG 0x23
103 #define RH_RF69_REG_24_RSSIVALUE 0x24
104 #define RH_RF69_REG_25_DIOMAPPING1 0x25
105 #define RH_RF69_REG_26_DIOMAPPING2 0x26
106 #define RH_RF69_REG_27_IRQFLAGS1 0x27
107 #define RH_RF69_REG_28_IRQFLAGS2 0x28
108 #define RH_RF69_REG_29_RSSITHRESH 0x29
109 #define RH_RF69_REG_2A_RXTIMEOUT1 0x2a
110 #define RH_RF69_REG_2B_RXTIMEOUT2 0x2b
111 #define RH_RF69_REG_2C_PREAMBLEMSB 0x2c
112 #define RH_RF69_REG_2D_PREAMBLELSB 0x2d
113 #define RH_RF69_REG_2E_SYNCCONFIG 0x2e
114 #define RH_RF69_REG_2F_SYNCVALUE1 0x2f
115 // another 7 sync word bytes follow, 30 through 36 inclusive
116 #define RH_RF69_REG_37_PACKETCONFIG1 0x37
117 #define RH_RF69_REG_38_PAYLOADLENGTH 0x38
118 #define RH_RF69_REG_39_NODEADRS 0x39
119 #define RH_RF69_REG_3A_BROADCASTADRS 0x3a
120 #define RH_RF69_REG_3B_AUTOMODES 0x3b
121 #define RH_RF69_REG_3C_FIFOTHRESH 0x3c
122 #define RH_RF69_REG_3D_PACKETCONFIG2 0x3d
123 #define RH_RF69_REG_3E_AESKEY1 0x3e
124 // Another 15 AES key bytes follow
125 #define RH_RF69_REG_4E_TEMP1 0x4e
126 #define RH_RF69_REG_4F_TEMP2 0x4f
127 #define RH_RF69_REG_58_TESTLNA 0x58
128 #define RH_RF69_REG_5A_TESTPA1 0x5a
129 #define RH_RF69_REG_5C_TESTPA2 0x5c
130 #define RH_RF69_REG_6F_TESTDAGC 0x6f
131 #define RH_RF69_REG_71_TESTAFC 0x71
132 
133 // These register masks etc are named wherever possible
134 // corresponding to the bit and field names in the RFM69 Manual
135 
136 // RH_RF69_REG_01_OPMODE
137 #define RH_RF69_OPMODE_SEQUENCEROFF 0x80
138 #define RH_RF69_OPMODE_LISTENON 0x40
139 #define RH_RF69_OPMODE_LISTENABORT 0x20
140 #define RH_RF69_OPMODE_MODE 0x1c
141 #define RH_RF69_OPMODE_MODE_SLEEP 0x00
142 #define RH_RF69_OPMODE_MODE_STDBY 0x04
143 #define RH_RF69_OPMODE_MODE_FS 0x08
144 #define RH_RF69_OPMODE_MODE_TX 0x0c
145 #define RH_RF69_OPMODE_MODE_RX 0x10
146 
147 // RH_RF69_REG_02_DATAMODUL
148 #define RH_RF69_DATAMODUL_DATAMODE 0x60
149 #define RH_RF69_DATAMODUL_DATAMODE_PACKET 0x00
150 #define RH_RF69_DATAMODUL_DATAMODE_CONT_WITH_SYNC 0x40
151 #define RH_RF69_DATAMODUL_DATAMODE_CONT_WITHOUT_SYNC 0x60
152 #define RH_RF69_DATAMODUL_MODULATIONTYPE 0x18
153 #define RH_RF69_DATAMODUL_MODULATIONTYPE_FSK 0x00
154 #define RH_RF69_DATAMODUL_MODULATIONTYPE_OOK 0x08
155 #define RH_RF69_DATAMODUL_MODULATIONSHAPING 0x03
156 #define RH_RF69_DATAMODUL_MODULATIONSHAPING_FSK_NONE 0x00
157 #define RH_RF69_DATAMODUL_MODULATIONSHAPING_FSK_BT1_0 0x01
158 #define RH_RF69_DATAMODUL_MODULATIONSHAPING_FSK_BT0_5 0x02
159 #define RH_RF69_DATAMODUL_MODULATIONSHAPING_FSK_BT0_3 0x03
160 #define RH_RF69_DATAMODUL_MODULATIONSHAPING_OOK_NONE 0x00
161 #define RH_RF69_DATAMODUL_MODULATIONSHAPING_OOK_BR 0x01
162 #define RH_RF69_DATAMODUL_MODULATIONSHAPING_OOK_2BR 0x02
163 
164 // RH_RF69_REG_11_PALEVEL
165 #define RH_RF69_PALEVEL_PA0ON 0x80
166 #define RH_RF69_PALEVEL_PA1ON 0x40
167 #define RH_RF69_PALEVEL_PA2ON 0x20
168 #define RH_RF69_PALEVEL_OUTPUTPOWER 0x1f
169 
170 // RH_RF69_REG_23_RSSICONFIG
171 #define RH_RF69_RSSICONFIG_RSSIDONE 0x02
172 #define RH_RF69_RSSICONFIG_RSSISTART 0x01
173 
174 // RH_RF69_REG_25_DIOMAPPING1
175 #define RH_RF69_DIOMAPPING1_DIO0MAPPING 0xc0
176 #define RH_RF69_DIOMAPPING1_DIO0MAPPING_00 0x00
177 #define RH_RF69_DIOMAPPING1_DIO0MAPPING_01 0x40
178 #define RH_RF69_DIOMAPPING1_DIO0MAPPING_10 0x80
179 #define RH_RF69_DIOMAPPING1_DIO0MAPPING_11 0xc0
180 
181 #define RH_RF69_DIOMAPPING1_DIO1MAPPING 0x30
182 #define RH_RF69_DIOMAPPING1_DIO1MAPPING_00 0x00
183 #define RH_RF69_DIOMAPPING1_DIO1MAPPING_01 0x10
184 #define RH_RF69_DIOMAPPING1_DIO1MAPPING_10 0x20
185 #define RH_RF69_DIOMAPPING1_DIO1MAPPING_11 0x30
186 
187 #define RH_RF69_DIOMAPPING1_DIO2MAPPING 0x0c
188 #define RH_RF69_DIOMAPPING1_DIO2MAPPING_00 0x00
189 #define RH_RF69_DIOMAPPING1_DIO2MAPPING_01 0x04
190 #define RH_RF69_DIOMAPPING1_DIO2MAPPING_10 0x08
191 #define RH_RF69_DIOMAPPING1_DIO2MAPPING_11 0x0c
192 
193 #define RH_RF69_DIOMAPPING1_DIO3MAPPING 0x03
194 #define RH_RF69_DIOMAPPING1_DIO3MAPPING_00 0x00
195 #define RH_RF69_DIOMAPPING1_DIO3MAPPING_01 0x01
196 #define RH_RF69_DIOMAPPING1_DIO3MAPPING_10 0x02
197 #define RH_RF69_DIOMAPPING1_DIO3MAPPING_11 0x03
198 
199 // RH_RF69_REG_26_DIOMAPPING2
200 #define RH_RF69_DIOMAPPING2_DIO4MAPPING 0xc0
201 #define RH_RF69_DIOMAPPING2_DIO4MAPPING_00 0x00
202 #define RH_RF69_DIOMAPPING2_DIO4MAPPING_01 0x40
203 #define RH_RF69_DIOMAPPING2_DIO4MAPPING_10 0x80
204 #define RH_RF69_DIOMAPPING2_DIO4MAPPING_11 0xc0
205 
206 #define RH_RF69_DIOMAPPING2_DIO5MAPPING 0x30
207 #define RH_RF69_DIOMAPPING2_DIO5MAPPING_00 0x00
208 #define RH_RF69_DIOMAPPING2_DIO5MAPPING_01 0x10
209 #define RH_RF69_DIOMAPPING2_DIO5MAPPING_10 0x20
210 #define RH_RF69_DIOMAPPING2_DIO5MAPPING_11 0x30
211 
212 #define RH_RF69_DIOMAPPING2_CLKOUT 0x07
213 #define RH_RF69_DIOMAPPING2_CLKOUT_FXOSC_ 0x00
214 #define RH_RF69_DIOMAPPING2_CLKOUT_FXOSC_2 0x01
215 #define RH_RF69_DIOMAPPING2_CLKOUT_FXOSC_4 0x02
216 #define RH_RF69_DIOMAPPING2_CLKOUT_FXOSC_8 0x03
217 #define RH_RF69_DIOMAPPING2_CLKOUT_FXOSC_16 0x04
218 #define RH_RF69_DIOMAPPING2_CLKOUT_FXOSC_32 0x05
219 #define RH_RF69_DIOMAPPING2_CLKOUT_FXOSC_RC 0x06
220 #define RH_RF69_DIOMAPPING2_CLKOUT_FXOSC_OFF 0x07
221 
222 // RH_RF69_REG_27_IRQFLAGS1
223 #define RH_RF69_IRQFLAGS1_MODEREADY 0x80
224 #define RH_RF69_IRQFLAGS1_RXREADY 0x40
225 #define RH_RF69_IRQFLAGS1_TXREADY 0x20
226 #define RH_RF69_IRQFLAGS1_PLLLOCK 0x10
227 #define RH_RF69_IRQFLAGS1_RSSI 0x08
228 #define RH_RF69_IRQFLAGS1_TIMEOUT 0x04
229 #define RH_RF69_IRQFLAGS1_AUTOMODE 0x02
230 #define RH_RF69_IRQFLAGS1_SYNADDRESSMATCH 0x01
231 
232 // RH_RF69_REG_28_IRQFLAGS2
233 #define RH_RF69_IRQFLAGS2_FIFOFULL 0x80
234 #define RH_RF69_IRQFLAGS2_FIFONOTEMPTY 0x40
235 #define RH_RF69_IRQFLAGS2_FIFOLEVEL 0x20
236 #define RH_RF69_IRQFLAGS2_FIFOOVERRUN 0x10
237 #define RH_RF69_IRQFLAGS2_PACKETSENT 0x08
238 #define RH_RF69_IRQFLAGS2_PAYLOADREADY 0x04
239 #define RH_RF69_IRQFLAGS2_CRCOK 0x02
240 
241 // RH_RF69_REG_2E_SYNCCONFIG
242 #define RH_RF69_SYNCCONFIG_SYNCON 0x80
243 #define RH_RF69_SYNCCONFIG_FIFOFILLCONDITION_MANUAL 0x40
244 #define RH_RF69_SYNCCONFIG_SYNCSIZE 0x38
245 #define RH_RF69_SYNCCONFIG_SYNCSIZE_1 0x00
246 #define RH_RF69_SYNCCONFIG_SYNCSIZE_2 0x08
247 #define RH_RF69_SYNCCONFIG_SYNCSIZE_3 0x10
248 #define RH_RF69_SYNCCONFIG_SYNCSIZE_4 0x18
249 #define RH_RF69_SYNCCONFIG_SYNCSIZE_5 0x20
250 #define RH_RF69_SYNCCONFIG_SYNCSIZE_6 0x28
251 #define RH_RF69_SYNCCONFIG_SYNCSIZE_7 0x30
252 #define RH_RF69_SYNCCONFIG_SYNCSIZE_8 0x38
253 #define RH_RF69_SYNCCONFIG_SYNCSIZE_SYNCTOL 0x07
254 
255 // RH_RF69_REG_37_PACKETCONFIG1
256 #define RH_RF69_PACKETCONFIG1_PACKETFORMAT_VARIABLE 0x80
257 #define RH_RF69_PACKETCONFIG1_DCFREE 0x60
258 #define RH_RF69_PACKETCONFIG1_DCFREE_NONE 0x00
259 #define RH_RF69_PACKETCONFIG1_DCFREE_MANCHESTER 0x20
260 #define RH_RF69_PACKETCONFIG1_DCFREE_WHITENING 0x40
261 #define RH_RF69_PACKETCONFIG1_DCFREE_RESERVED 0x60
262 #define RH_RF69_PACKETCONFIG1_CRC_ON 0x10
263 #define RH_RF69_PACKETCONFIG1_CRCAUTOCLEAROFF 0x08
264 #define RH_RF69_PACKETCONFIG1_ADDRESSFILTERING 0x06
265 #define RH_RF69_PACKETCONFIG1_ADDRESSFILTERING_NONE 0x00
266 #define RH_RF69_PACKETCONFIG1_ADDRESSFILTERING_NODE 0x02
267 #define RH_RF69_PACKETCONFIG1_ADDRESSFILTERING_NODE_BC 0x04
268 #define RH_RF69_PACKETCONFIG1_ADDRESSFILTERING_RESERVED 0x06
269 
270 // RH_RF69_REG_3B_AUTOMODES
271 #define RH_RF69_AUTOMODE_ENTER_COND_NONE 0x00
272 #define RH_RF69_AUTOMODE_ENTER_COND_FIFO_NOT_EMPTY 0x20
273 #define RH_RF69_AUTOMODE_ENTER_COND_FIFO_LEVEL 0x40
274 #define RH_RF69_AUTOMODE_ENTER_COND_CRC_OK 0x60
275 #define RH_RF69_AUTOMODE_ENTER_COND_PAYLOAD_READY 0x80
276 #define RH_RF69_AUTOMODE_ENTER_COND_SYNC_ADDRESS 0xa0
277 #define RH_RF69_AUTOMODE_ENTER_COND_PACKET_SENT 0xc0
278 #define RH_RF69_AUTOMODE_ENTER_COND_FIFO_EMPTY 0xe0
279 
280 #define RH_RF69_AUTOMODE_EXIT_COND_NONE 0x00
281 #define RH_RF69_AUTOMODE_EXIT_COND_FIFO_EMPTY 0x04
282 #define RH_RF69_AUTOMODE_EXIT_COND_FIFO_LEVEL 0x08
283 #define RH_RF69_AUTOMODE_EXIT_COND_CRC_OK 0x0c
284 #define RH_RF69_AUTOMODE_EXIT_COND_PAYLOAD_READY 0x10
285 #define RH_RF69_AUTOMODE_EXIT_COND_SYNC_ADDRESS 0x14
286 #define RH_RF69_AUTOMODE_EXIT_COND_PACKET_SENT 0x18
287 #define RH_RF69_AUTOMODE_EXIT_COND_TIMEOUT 0x1c
288 
289 #define RH_RF69_AUTOMODE_INTERMEDIATE_MODE_SLEEP 0x00
290 #define RH_RF69_AUTOMODE_INTERMEDIATE_MODE_STDBY 0x01
291 #define RH_RF69_AUTOMODE_INTERMEDIATE_MODE_RX 0x02
292 #define RH_RF69_AUTOMODE_INTERMEDIATE_MODE_TX 0x03
293 
294 // RH_RF69_REG_3C_FIFOTHRESH
295 #define RH_RF69_FIFOTHRESH_TXSTARTCONDITION_NOTEMPTY 0x80
296 #define RH_RF69_FIFOTHRESH_FIFOTHRESHOLD 0x7f
297 
298 // RH_RF69_REG_3D_PACKETCONFIG2
299 #define RH_RF69_PACKETCONFIG2_INTERPACKETRXDELAY 0xf0
300 #define RH_RF69_PACKETCONFIG2_RESTARTRX 0x04
301 #define RH_RF69_PACKETCONFIG2_AUTORXRESTARTON 0x02
302 #define RH_RF69_PACKETCONFIG2_AESON 0x01
303 
304 // RH_RF69_REG_4E_TEMP1
305 #define RH_RF69_TEMP1_TEMPMEASSTART 0x08
306 #define RH_RF69_TEMP1_TEMPMEASRUNNING 0x04
307 
308 // RH_RF69_REG_5A_TESTPA1
309 #define RH_RF69_TESTPA1_NORMAL 0x55
310 #define RH_RF69_TESTPA1_BOOST 0x5d
311 
312 // RH_RF69_REG_5C_TESTPA2
313 #define RH_RF69_TESTPA2_NORMAL 0x70
314 #define RH_RF69_TESTPA2_BOOST 0x7c
315 
316 // RH_RF69_REG_6F_TESTDAGC
317 #define RH_RF69_TESTDAGC_CONTINUOUSDAGC_NORMAL 0x00
318 #define RH_RF69_TESTDAGC_CONTINUOUSDAGC_IMPROVED_LOWBETAON 0x20
319 #define RH_RF69_TESTDAGC_CONTINUOUSDAGC_IMPROVED_LOWBETAOFF 0x30
320 
321 // Define this to include Serial printing in diagnostic routines
322 #define RH_RF69_HAVE_SERIAL
323 
324 
325 /////////////////////////////////////////////////////////////////////
326 /// \class RH_RF69 RH_RF69.h <RH_RF69.h>
327 /// \brief Driver to send and receive unaddressed, unreliable datagrams via an RF69 and compatible radio transceiver.
328 ///
329 /// Works with
330 /// - the excellent Moteino and Moteino-USB
331 /// boards from LowPowerLab http://lowpowerlab.com/moteino/
332 /// - compatible chips and modules such as RFM69W, RFM69HW, RFM69CW, RFM69HCW (Semtech SX1231, SX1231H),
333 /// - RFM69 modules from http://www.hoperfusa.com such as http://www.hoperfusa.com/details.jsp?pid=145
334 /// - Anarduino MiniWireless -CW and -HW boards http://www.anarduino.com/miniwireless/ including
335 /// the marvellous high powered MinWireless-HW (with 20dBm output for excellent range)
336 /// - the excellent Rocket Scream Mini Ultra Pro with the RFM69HCW
337 /// http://www.rocketscream.com/blog/product/mini-ultra-pro-with-radio/
338 /// - The excellent Talk2 Whisper Node boards
339 /// (https://talk2.wisen.com.au/ and https://bitbucket.org/talk2/whisper-node-avr),
340 /// an Arduino compatible board, which include an on-board RF69 radio, external antenna,
341 /// run on 2xAAA batteries and support low power operations. RF69 examples work without modification.
342 /// Use Arduino Board Manager to install the Talk2 code support as described in
343 /// https://bitbucket.org/talk2/whisper-node-avr. Upeload the code with an FTDI adapter set to 3.3V.
344 /// - The excellent Adafruit Feather. These are excellent boards that are available with a variety of radios.
345 /// We tested with the
346 /// Feather 32u4 with RFM69HCW radio, with Arduino IDE 1.6.8 and the Adafruit AVR Boards board manager version 1.6.10.
347 /// https://www.adafruit.com/products/3076
348 ///
349 /// \par Overview
350 ///
351 /// This class provides basic functions for sending and receiving unaddressed,
352 /// unreliable datagrams of arbitrary length to 64 octets per packet.
353 ///
354 /// Manager classes may use this class to implement reliable, addressed datagrams and streams,
355 /// mesh routers, repeaters, translators etc.
356 ///
357 /// Naturally, for any 2 radios to communicate that must be configured to use the same frequency and
358 /// modulation scheme.
359 ///
360 /// This Driver provides an object-oriented interface for sending and receiving data messages with Hope-RF
361 /// RF69B and compatible radio modules, such as the RFM69 module.
362 ///
363 /// The Hope-RF (http://www.hoperf.com) RF69 is a low-cost ISM transceiver
364 /// chip. It supports FSK, GFSK, OOK over a wide range of frequencies and
365 /// programmable data rates. It also suports AES encryption of up to 64 octets
366 /// of payload It is available prepackaged on modules such as the RFM69W. And
367 /// such modules can be prepacked on processor boards such as the Moteino from
368 /// LowPowerLabs (which is what we used to develop the RH_RF69 driver)
369 ///
370 /// This Driver provides functions for sending and receiving messages of up
371 /// to 60 octets on any frequency supported by the RF69, in a range of
372 /// predefined data rates and frequency deviations. Frequency can be set with
373 /// 61Hz precision to any frequency from 240.0MHz to 960.0MHz. Caution: most modules only support a more limited
374 /// range of frequencies due to antenna tuning.
375 ///
376 /// Up to 2 RF69B modules can be connected to an Arduino (3 on a Mega),
377 /// permitting the construction of translators and frequency changers, etc.
378 ///
379 /// The following modulation types are suppported with a range of modem configurations for
380 /// common data rates and frequency deviations:
381 /// - GFSK Gaussian Frequency Shift Keying
382 /// - FSK Frequency Shift Keying
383 ///
384 /// Support for other RF69 features such as on-chip temperature measurement,
385 /// transmitter power control etc is also provided.
386 ///
387 /// Tested on USB-Moteino with arduino-1.0.5
388 /// on OpenSuSE 13.1
389 ///
390 /// \par Packet Format
391 ///
392 /// All messages sent and received by this RH_RF69 Driver conform to this packet format:
393 ///
394 /// - 4 octets PREAMBLE
395 /// - 2 octets SYNC 0x2d, 0xd4 (configurable, so you can use this as a network filter)
396 /// - 1 octet RH_RF69 payload length
397 /// - 4 octets HEADER: (TO, FROM, ID, FLAGS)
398 /// - 0 to 60 octets DATA
399 /// - 2 octets CRC computed with CRC16(IBM), computed on HEADER and DATA
400 ///
401 /// For technical reasons, the message format is not protocol compatible with the
402 /// 'HopeRF Radio Transceiver Message Library for Arduino'
403 /// http://www.airspayce.com/mikem/arduino/HopeRF from the same author. Nor is
404 /// it compatible with messages sent by 'Virtual Wire'
405 /// http://www.airspayce.com/mikem/arduino/VirtualWire.pdf also from the same
406 /// author. Nor is it compatible with messages sent by 'RF22'
407 /// http://www.airspayce.com/mikem/arduino/RF22 also from the same author.
408 ///
409 /// \par Connecting RFM-69 to Arduino
410 ///
411 /// We tested with Moteino, which is an Arduino Uno compatible with the RFM69W
412 /// module on-board. Therefore it needs no connections other than the USB
413 /// programming connection and an antenna to make it work.
414 ///
415 /// If you have a bare RFM69W that you want to connect to an Arduino, you
416 /// might use these connections: CAUTION: you must use a 3.3V type
417 /// Arduino, otherwise you will also need voltage level shifters between the
418 /// Arduino and the RFM69. CAUTION, you must also ensure you connect an
419 /// antenna
420 ///
421 /// \code
422 /// Arduino RFM69W
423 /// GND----------GND (ground in)
424 /// 3V3----------3.3V (3.3V in)
425 /// interrupt 0 pin D2-----------DIO0 (interrupt request out)
426 /// SS pin D10----------NSS (chip select in)
427 /// SCK pin D13----------SCK (SPI clock in)
428 /// MOSI pin D11----------MOSI (SPI Data in)
429 /// MISO pin D12----------MISO (SPI Data out)
430 /// \endcode
431 ///
432 /// For Arduino Due, use these connections:
433 /// \code
434 /// Arduino RFM69W
435 /// GND----------GND (ground in)
436 /// 3V3----------3.3V (3.3V in)
437 /// interrupt 0 pin D2-----------DIO0 (interrupt request out)
438 /// SS pin D10----------NSS (chip select in)
439 /// SCK SPI pin 3----------SCK (SPI clock in)
440 /// MOSI SPI pin 4----------MOSI (SPI Data in)
441 /// MISO SPI pin 1----------MISO (SPI Data out)
442 /// \endcode
443 ///
444 /// With these connections, you can then use the default constructor RH_RF69().
445 /// You can override the default settings for the SS pin and the interrupt in
446 /// the RH_RF69 constructor if you wish to connect the slave select SS to other
447 /// than the normal one for your Arduino (D10 for Diecimila, Uno etc and D53
448 /// for Mega) or the interrupt request to other than pin D2 (Caution,
449 /// different processors have different constraints as to the pins available
450 /// for interrupts).
451 ///
452 /// If you have a Teensy 3.1 and a compatible RFM69 breakout board, you will need to
453 /// construct the RH_RF69 instance like this:
454 /// \code
455 /// RH_RF69 driver(15, 16);
456 /// \endcode
457 ///
458 /// If you have a MoteinoMEGA https://lowpowerlab.com/shop/moteinomega
459 /// with RFM69 on board, you dont need to make any wiring connections
460 /// (the RFM69 module is soldered onto the MotienoMEGA), but you must initialise the RH_RF69
461 /// constructor like this:
462 /// \code
463 /// RH_RF69 driver(4, 2);
464 /// \endcode
465 /// Make sure you have the MoteinoMEGA core installed in your Arduino hardware folder as described in the
466 /// documentation for the MoteinoMEGA.
467 ///
468 /// If you have an Arduino M0 Pro from arduino.org,
469 /// you should note that you cannot use Pin 2 for the interrupt line
470 /// (Pin 2 is for the NMI only). The same comments apply to Pin 4 on Arduino Zero from arduino.cc.
471 /// Instead you can use any other pin (we use Pin 3) and initialise RH_RF69 like this:
472 /// \code
473 /// // Slave Select is pin 10, interrupt is Pin 3
474 /// RH_RF69 driver(10, 3);
475 /// \endcode
476 ///
477 /// If you have a Rocket Scream Mini Ultra Pro with the RFM69HCW
478 /// - Ensure you have Arduino SAMD board support 1.6.5 or later in Arduino IDE 1.6.8 or later.
479 /// - The radio SS is hardwired to pin D5 and the DIO0 interrupt to pin D2,
480 /// so you need to initialise the radio like this:
481 /// \code
482 /// RH_RF69 driver(5, 2);
483 /// \endcode
484 /// - The name of the serial port on that board is 'SerialUSB', not 'Serial', so this may be helpful at the top of our
485 /// sample sketches:
486 /// \code
487 /// #define Serial SerialUSB
488 /// \endcode
489 /// - You also need this in setup before radio initialisation
490 /// \code
491 /// // Ensure serial flash is not interfering with radio communication on SPI bus
492 /// pinMode(4, OUTPUT);
493 /// digitalWrite(4, HIGH);
494 /// \endcode
495 /// - and if you have a 915MHz part, you need this after driver/manager intitalisation:
496 /// \code
497 /// rf69.setFrequency(915.0);
498 /// rf69.setTxPower(20);
499 /// \endcode
500 /// which adds up to modifying sample sketches something like:
501 /// \code
502 /// #include <SPI.h>
503 /// #include <RH_RF69.h>
504 /// RH_RF69 rf69(5, 2); // Rocket Scream Mini Ultra Pro with the RFM69HCW
505 /// #define Serial SerialUSB
506 ///
507 /// void setup()
508 /// {
509 /// // Ensure serial flash is not interfering with radio communication on SPI bus
510 /// pinMode(4, OUTPUT);
511 /// digitalWrite(4, HIGH);
512 ///
513 /// Serial.begin(9600);
514 /// while (!Serial) ; // Wait for serial port to be available
515 /// if (!rf69.init())
516 /// Serial.println("init failed");
517 /// rf69.setFrequency(915.0);
518 /// rf69.setTxPower(20);
519 /// }
520 /// ...
521 /// \endcode
522 ///
523 /// If you have a talk2 Whisper Node board with on-board RF69 radio,
524 /// the example rf69_* sketches work without modifications. Initialise the radio like
525 /// with the default constructor:
526 /// \code
527 /// RH_RF69 driver;
528 /// \endcode
529 ///
530 /// If you have a Feather 32u4 with RFM69HCW you need to initialise the driver like:
531 /// \code
532 /// RH_RF69 driver(8, 7);
533 /// \endcode
534 /// and since the radio is the high power HCW model, you must set the Tx power in the
535 /// range 14 to 20 like this:
536 /// \code
537 /// driver.setTxPower(14);
538 /// \endcode
539 ///
540 /// If you are connecting an RF69 to a ESP8266 board breakout board that exposes pins
541 /// 12, 13, 14, 15 (ie NOT an ESP-01) you can connect like this:
542 /// \code
543 /// ESP8266 RFM69W
544 /// GND-----------GND (ground in)
545 /// VIN-----------3.3V (3.3V in)
546 /// interrupt D0 pin GPIO0-----------DIO0 (interrupt request out)
547 /// SS pin GPIO15----------NSS (chip select in)
548 /// SCK SPI pin GPIO14----------SCK (SPI clock in)
549 /// MOSI SPI pin GPIO13----------MOSI (SPI Data in)
550 /// MISO SPI pin GPIO12----------MISO (SPI Data out)
551 /// \endcode
552 /// and initialise with
553 /// \code
554 /// RH_RF69 driver(15, 0);
555 /// \endcode
556 ///
557 /// It is possible to have 2 or more radios connected to one Arduino, provided
558 /// each radio has its own SS and interrupt line (SCK, SDI and SDO are common
559 /// to all radios)
560 ///
561 /// Caution: on some Arduinos such as the Mega 2560, if you set the slave
562 /// select pin to be other than the usual SS pin (D53 on Mega 2560), you may
563 /// need to set the usual SS pin to be an output to force the Arduino into SPI
564 /// master mode.
565 ///
566 /// Caution: Power supply requirements of the RF69 module may be relevant in some circumstances:
567 /// RF69 modules are capable of pulling 45mA+ at full power, where Arduino's 3.3V line can
568 /// give 50mA. You may need to make provision for alternate power supply for
569 /// the RF69, especially if you wish to use full transmit power, and/or you have
570 /// other shields demanding power. Inadequate power for the RF69 is likely to cause symptoms such as:
571 /// -reset's/bootups terminate with "init failed" messages
572 /// -random termination of communication after 5-30 packets sent/received
573 /// -"fake ok" state, where initialization passes fluently, but communication doesn't happen
574 /// -shields hang Arduino boards, especially during the flashing
575 ///
576 /// \par Encryption
577 ///
578 /// This driver support the on-chip AES encryption provided by the RF69.
579 /// You can enable encryption by calling setEncryptionKey() after init() has been called.
580 /// If both transmitter and receiver have been configured with the same AES key,
581 /// then the receiver will recover the unencrypted message sent by the receiver.
582 /// However, you should note that there is no way for RF69 nor for the RadioHead
583 /// drivers to know whether the AES
584 /// key for a message is 'correct' or not. This is because the RF69 CRC covers the
585 /// _encrypted_ payload not the plaintext.
586 ///
587 /// In RadioHead managers that support addressing,
588 /// the RF69 AES encryption includes the RadioHead payload and the TO and FROM addresses, so
589 /// occasionally (average one in 256 messages), a message encrypted with the
590 /// 'wrong' key will have the 'correct' destination address, and will therefore be
591 /// accepted by RadioHead as a 'random' message content from a 'random' sender.
592 /// Its up to your code to figure out whether the message makes sense or not.
593 ///
594 /// \par Interrupts
595 ///
596 /// The RH_RF69 driver uses interrupts to react to events in the RF69 module,
597 /// such as the reception of a new packet, or the completion of transmission
598 /// of a packet. The RH_RF69 driver interrupt service routine reads status from
599 /// and writes data to the the RF69 module via the SPI interface. It is very
600 /// important therefore, that if you are using the RH_RF69 driver with another
601 /// SPI based deviced, that you disable interrupts while you transfer data to
602 /// and from that other device. Use cli() to disable interrupts and sei() to
603 /// reenable them.
604 ///
605 /// \par Memory
606 ///
607 /// The RH_RF69 driver requires non-trivial amounts of memory. The sample
608 /// programs above all compile to about 8kbytes each, which will fit in the
609 /// flash proram memory of most Arduinos. However, the RAM requirements are
610 /// more critical. Therefore, you should be vary sparing with RAM use in
611 /// programs that use the RH_RF69 driver.
612 ///
613 /// It is often hard to accurately identify when you are hitting RAM limits on Arduino.
614 /// The symptoms can include:
615 /// - Mysterious crashes and restarts
616 /// - Changes in behaviour when seemingly unrelated changes are made (such as adding print() statements)
617 /// - Hanging
618 /// - Output from Serial.print() not appearing
619 ///
620 /// \par Automatic Frequency Control (AFC)
621 ///
622 /// The RF69 module is configured by the RH_RF69 driver to always use AFC.
623 ///
624 /// \par Transmitter Power
625 ///
626 /// You can control the transmitter power on the RF69 transceiver
627 /// with the RH_RF69::setTxPower() function. The argument can be any of
628 /// -18 to +13 (for RF69W) or -14 to 20 (for RF69HW)
629 /// The default is 13. Eg:
630 /// \code
631 /// driver.setTxPower(-5);
632 /// \endcode
633 ///
634 /// We have made some actual power measurements against
635 /// programmed power for Moteino (with RF69W)
636 /// - Moteino (with RF69W), USB power
637 /// - 10cm RG58C/U soldered direct to RFM69 module ANT and GND
638 /// - bnc connecteor
639 /// - 12dB attenuator
640 /// - BNC-SMA adapter
641 /// - MiniKits AD8307 HF/VHF Power Head (calibrated against Rohde&Schwartz 806.2020 test set)
642 /// - Tektronix TDS220 scope to measure the Vout from power head
643 /// \code
644 /// Program power Measured Power
645 /// dBm dBm
646 /// -18 -17
647 /// -16 -16
648 /// -14 -14
649 /// -12 -12
650 /// -10 -9
651 /// -8 -7
652 /// -6 -4
653 /// -4 -3
654 /// -2 -2
655 /// 0 0.2
656 /// 2 3
657 /// 4 5
658 /// 6 7
659 /// 8 10
660 /// 10 13
661 /// 12 14
662 /// 13 15
663 /// 14 -51
664 /// 20 -51
665 /// \endcode
666 /// We have also made some actual power measurements against
667 /// programmed power for Anarduino MiniWireless with RFM69-HW
668 /// Anarduino MiniWireless (with RFM69-HW), USB power
669 /// - 10cm RG58C/U soldered direct to RFM69 module ANT and GND
670 /// - bnc connecteor
671 /// - 2x12dB attenuators
672 /// - BNC-SMA adapter
673 /// - MiniKits AD8307 HF/VHF Power Head (calibrated against Rohde&Schwartz 806.2020 test set)
674 /// - Tektronix TDS220 scope to measure the Vout from power head
675 /// \code
676 /// Program power Measured Power
677 /// dBm dBm
678 /// -18 no measurable output
679 /// 0 no measurable output
680 /// 13 no measurable output
681 /// 14 11
682 /// 15 12
683 /// 16 12.4
684 /// 17 14
685 /// 18 15
686 /// 19 15.8
687 /// 20 17
688 /// \endcode
689 /// (Caution: we dont claim laboratory accuracy for these measurements)
690 /// You would not expect to get anywhere near these powers to air with a simple 1/4 wavelength wire antenna.
691 /// Caution: although the RFM69 appears to have a PC antenna on board, you will get much better power and range even
692 /// with just a 1/4 wave wire antenna.
693 ///
694 /// \par Performance
695 ///
696 /// Some simple speed performance tests have been conducted.
697 /// In general packet transmission rate will be limited by the modulation scheme.
698 /// Also, if your code does any slow operations like Serial printing it will also limit performance.
699 /// We disabled any printing in the tests below.
700 /// We tested with RH_RF69::GFSK_Rb250Fd250, which is probably the fastest scheme available.
701 /// We tested with a 13 octet message length, over a very short distance of 10cm.
702 ///
703 /// Transmission (no reply) tests with modulation RH_RF69::GFSK_Rb250Fd250 and a
704 /// 13 octet message show about 152 messages per second transmitted and received.
705 ///
706 /// Transmit-and-wait-for-a-reply tests with modulation RH_RF69::GFSK_Rb250Fd250 and a
707 /// 13 octet message (send and receive) show about 68 round trips per second.
708 ///
709 class RH_RF69 : public RHSPIDriver
710 {
711 public:
712 
713  /// \brief Defines register values for a set of modem configuration registers
714  ///
715  /// Defines register values for a set of modem configuration registers
716  /// that can be passed to setModemRegisters() if none of the choices in
717  /// ModemConfigChoice suit your need setModemRegisters() writes the
718  /// register values from this structure to the appropriate RF69 registers
719  /// to set the desired modulation type, data rate and deviation/bandwidth.
720  typedef struct
721  {
722  uint8_t reg_02; ///< Value for register RH_RF69_REG_02_DATAMODUL
723  uint8_t reg_03; ///< Value for register RH_RF69_REG_03_BITRATEMSB
724  uint8_t reg_04; ///< Value for register RH_RF69_REG_04_BITRATELSB
725  uint8_t reg_05; ///< Value for register RH_RF69_REG_05_FDEVMSB
726  uint8_t reg_06; ///< Value for register RH_RF69_REG_06_FDEVLSB
727  uint8_t reg_19; ///< Value for register RH_RF69_REG_19_RXBW
728  uint8_t reg_1a; ///< Value for register RH_RF69_REG_1A_AFCBW
729  uint8_t reg_37; ///< Value for register RH_RF69_REG_37_PACKETCONFIG1
730  } ModemConfig;
731 
732  /// Choices for setModemConfig() for a selected subset of common
733  /// modulation types, and data rates. If you need another configuration,
734  /// use the register calculator. and call setModemRegisters() with your
735  /// desired settings.
736  /// These are indexes into MODEM_CONFIG_TABLE. We strongly recommend you use these symbolic
737  /// definitions and not their integer equivalents: its possible that new values will be
738  /// introduced in later versions (though we will try to avoid it).
739  /// CAUTION: some of these configurations do not work corectly and are marked as such.
740  typedef enum
741  {
742  FSK_Rb2Fd5 = 0, ///< FSK, Whitening, Rb = 2kbs, Fd = 5kHz
743  FSK_Rb2_4Fd4_8, ///< FSK, Whitening, Rb = 2.4kbs, Fd = 4.8kHz
744  FSK_Rb4_8Fd9_6, ///< FSK, Whitening, Rb = 4.8kbs, Fd = 9.6kHz
745  FSK_Rb9_6Fd19_2, ///< FSK, Whitening, Rb = 9.6kbs, Fd = 19.2kHz
746  FSK_Rb19_2Fd38_4, ///< FSK, Whitening, Rb = 19.2kbs, Fd = 38.4kHz
747  FSK_Rb38_4Fd76_8, ///< FSK, Whitening, Rb = 38.4kbs, Fd = 76.8kHz
748  FSK_Rb57_6Fd120, ///< FSK, Whitening, Rb = 57.6kbs, Fd = 120kHz
749  FSK_Rb125Fd125, ///< FSK, Whitening, Rb = 125kbs, Fd = 125kHz
750  FSK_Rb250Fd250, ///< FSK, Whitening, Rb = 250kbs, Fd = 250kHz
751  FSK_Rb55555Fd50, ///< FSK, Whitening, Rb = 55555kbs,Fd = 50kHz for RFM69 lib compatibility
752 
753  GFSK_Rb2Fd5, ///< GFSK, Whitening, Rb = 2kbs, Fd = 5kHz
754  GFSK_Rb2_4Fd4_8, ///< GFSK, Whitening, Rb = 2.4kbs, Fd = 4.8kHz
755  GFSK_Rb4_8Fd9_6, ///< GFSK, Whitening, Rb = 4.8kbs, Fd = 9.6kHz
756  GFSK_Rb9_6Fd19_2, ///< GFSK, Whitening, Rb = 9.6kbs, Fd = 19.2kHz
757  GFSK_Rb19_2Fd38_4, ///< GFSK, Whitening, Rb = 19.2kbs, Fd = 38.4kHz
758  GFSK_Rb38_4Fd76_8, ///< GFSK, Whitening, Rb = 38.4kbs, Fd = 76.8kHz
759  GFSK_Rb57_6Fd120, ///< GFSK, Whitening, Rb = 57.6kbs, Fd = 120kHz
760  GFSK_Rb125Fd125, ///< GFSK, Whitening, Rb = 125kbs, Fd = 125kHz
761  GFSK_Rb250Fd250, ///< GFSK, Whitening, Rb = 250kbs, Fd = 250kHz
762  GFSK_Rb55555Fd50, ///< GFSK, Whitening, Rb = 55555kbs,Fd = 50kHz
763 
764  OOK_Rb1Bw1, ///< OOK, Whitening, Rb = 1kbs, Rx Bandwidth = 1kHz.
765  OOK_Rb1_2Bw75, ///< OOK, Whitening, Rb = 1.2kbs, Rx Bandwidth = 75kHz.
766  OOK_Rb2_4Bw4_8, ///< OOK, Whitening, Rb = 2.4kbs, Rx Bandwidth = 4.8kHz.
767  OOK_Rb4_8Bw9_6, ///< OOK, Whitening, Rb = 4.8kbs, Rx Bandwidth = 9.6kHz.
768  OOK_Rb9_6Bw19_2, ///< OOK, Whitening, Rb = 9.6kbs, Rx Bandwidth = 19.2kHz.
769  OOK_Rb19_2Bw38_4, ///< OOK, Whitening, Rb = 19.2kbs, Rx Bandwidth = 38.4kHz.
770  OOK_Rb32Bw64, ///< OOK, Whitening, Rb = 32kbs, Rx Bandwidth = 64kHz.
771 
772 // Test,
774 
775  /// Constructor. You can have multiple instances, but each instance must have its own
776  /// interrupt and slave select pin. After constructing, you must call init() to initialise the interface
777  /// and the radio module. A maximum of 3 instances can co-exist on one processor, provided there are sufficient
778  /// distinct interrupt lines, one for each instance.
779  /// \param[in] slaveSelectPin the Arduino pin number of the output to use to select the RF69 before
780  /// accessing it. Defaults to the normal SS pin for your Arduino (D10 for Diecimila, Uno etc, D53 for Mega, D10 for Maple)
781  /// \param[in] interruptPin The interrupt Pin number that is connected to the RF69 DIO0 interrupt line.
782  /// Defaults to pin 2.
783  /// Caution: You must specify an interrupt capable pin.
784  /// On many Arduino boards, there are limitations as to which pins may be used as interrupts.
785  /// On Leonardo pins 0, 1, 2 or 3. On Mega2560 pins 2, 3, 18, 19, 20, 21. On Due and Teensy, any digital pin.
786  /// On Arduino Zero from arduino.cc, any digital pin other than 4.
787  /// On Arduino M0 Pro from arduino.org, any digital pin other than 2.
788  /// On other Arduinos pins 2 or 3.
789  /// See http://arduino.cc/en/Reference/attachInterrupt for more details.
790  /// On Chipkit Uno32, pins 38, 2, 7, 8, 35.
791  /// On other boards, any digital pin may be used.
792  /// \param[in] spi Pointer to the SPI interface object to use.
793  /// Defaults to the standard Arduino hardware SPI interface
794  RH_RF69(uint8_t slaveSelectPin = SS, uint8_t interruptPin = 2, RHGenericSPI& spi = hardware_spi);
795 
796  /// Initialises this instance and the radio module connected to it.
797  /// The following steps are taken:
798  /// - Initialise the slave select pin and the SPI interface library
799  /// - Checks the connected RF69 module can be communicated
800  /// - Attaches an interrupt handler
801  /// - Configures the RF69 module
802  /// - Sets the frequency to 434.0 MHz
803  /// - Sets the modem data rate to FSK_Rb2Fd5
804  /// \return true if everything was successful
805  bool init();
806 
807  /// Reads the on-chip temperature sensor.
808  /// The RF69 must be in Idle mode (= RF69 Standby) to measure temperature.
809  /// The measurement is uncalibrated and without calibration, you can expect it to be far from
810  /// correct.
811  /// \return The measured temperature, in degrees C from -40 to 85 (uncalibrated)
812  int8_t temperatureRead();
813 
814  /// Sets the transmitter and receiver
815  /// centre frequency
816  /// \param[in] centre Frequency in MHz. 240.0 to 960.0. Caution, RF69 comes in several
817  /// different frequency ranges, and setting a frequency outside that range of your radio will probably not work
818  /// \param[in] afcPullInRange Not used
819  /// \return true if the selected frquency centre is within range
820  bool setFrequency(float centre, float afcPullInRange = 0.05);
821 
822  /// Reads and returns the current RSSI value.
823  /// Causes the current signal strength to be measured and returned
824  /// If you want to find the RSSI
825  /// of the last received message, use lastRssi() instead.
826  /// \return The current RSSI value on units of 0.5dB.
827  int8_t rssiRead();
828 
829  /// Sets the parameters for the RF69 OPMODE.
830  /// This is a low level device access function, and should not normally ned to be used by user code.
831  /// Instead can use stModeRx(), setModeTx(), setModeIdle()
832  /// \param[in] mode RF69 OPMODE to set, one of RH_RF69_OPMODE_MODE_*.
833  void setOpMode(uint8_t mode);
834 
835  /// If current mode is Rx or Tx changes it to Idle. If the transmitter or receiver is running,
836  /// disables them.
837  void setModeIdle();
838 
839  /// If current mode is Tx or Idle, changes it to Rx.
840  /// Starts the receiver in the RF69.
841  void setModeRx();
842 
843  /// If current mode is Rx or Idle, changes it to Rx. F
844  /// Starts the transmitter in the RF69.
845  void setModeTx();
846 
847  /// Sets the transmitter power output level.
848  /// Be a good neighbour and set the lowest power level you need.
849  /// Caution: legal power limits may apply in certain countries.
850  /// After init(), the power will be set to 13dBm for a low power module.
851  /// If you are using a high p[ower modfule such as an RFM69HW, you MUST set the power level
852  /// with the ishighpowermodule flag set to true. Else you wil get no measurable power output.
853  /// Simlarly if you are not using a high power module, you must NOT set the ishighpowermodule
854  /// (which is the default)
855  /// \param[in] power Transmitter power level in dBm. For RF69W (ishighpowermodule = false),
856  /// valid values are from -18 to +13.; Values outside this range are trimmed.
857  /// For RF69HW (ishighpowermodule = true), valid values are from -2 to +20.
858  /// Caution: at +20dBm, duty cycle is limited to 1% and a
859  /// maximum VSWR of 3:1 at the antenna port.
860  /// \param ishighpowermodule Set to true if the connected module is a high power module RFM69HW
861  void setTxPower(int8_t power, bool ishighpowermodule = RH_RF69_DEFAULT_HIGHPOWER);
862 
863  /// Sets all the registers required to configure the data modem in the RF69, including the data rate,
864  /// bandwidths etc. You can use this to configure the modem with custom configurations if none of the
865  /// canned configurations in ModemConfigChoice suit you.
866  /// \param[in] config A ModemConfig structure containing values for the modem configuration registers.
867  void setModemRegisters(const ModemConfig* config);
868 
869  /// Select one of the predefined modem configurations. If you need a modem configuration not provided
870  /// here, use setModemRegisters() with your own ModemConfig. The default after init() is RH_RF69::GFSK_Rb250Fd250.
871  /// \param[in] index The configuration choice.
872  /// \return true if index is a valid choice.
873  bool setModemConfig(ModemConfigChoice index);
874 
875  /// Starts the receiver and checks whether a received message is available.
876  /// This can be called multiple times in a timeout loop
877  /// \return true if a complete, valid message has been received and is able to be retrieved by
878  /// recv()
879  bool available();
880 
881  /// Turns the receiver on if it not already on.
882  /// If there is a valid message available, copy it to buf and return true
883  /// else return false.
884  /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).
885  /// You should be sure to call this function frequently enough to not miss any messages
886  /// It is recommended that you call it in your main loop.
887  /// \param[in] buf Location to copy the received message
888  /// \param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied.
889  /// \return true if a valid message was copied to buf
890  bool recv(uint8_t* buf, uint8_t* len);
891 
892  /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent().
893  /// Then loads a message into the transmitter and starts the transmitter. Note that a message length
894  /// of 0 is NOT permitted.
895  /// \param[in] data Array of data to be sent
896  /// \param[in] len Number of bytes of data to send (> 0)
897  /// \return true if the message length was valid and it was correctly queued for transmit
898  bool send(const uint8_t* data, uint8_t len);
899 
900  /// Sets the length of the preamble
901  /// in bytes.
902  /// Caution: this should be set to the same
903  /// value on all nodes in your network. Default is 4.
904  /// Sets the message preamble length in REG_0?_PREAMBLE?SB
905  /// \param[in] bytes Preamble length in bytes.
906  void setPreambleLength(uint16_t bytes);
907 
908  /// Sets the sync words for transmit and receive
909  /// Caution: SyncWords should be set to the same
910  /// value on all nodes in your network. Nodes with different SyncWords set will never receive
911  /// each others messages, so different SyncWords can be used to isolate different
912  /// networks from each other. Default is { 0x2d, 0xd4 }.
913  /// Caution: tests here show that with a single sync word (ie where len == 1),
914  /// RFM69 reception can be unreliable.
915  /// To disable sync word generation and detection, call with the defaults: setSyncWords();
916  /// \param[in] syncWords Array of sync words, 1 to 4 octets long. NULL if no sync words to be used.
917  /// \param[in] len Number of sync words to set, 1 to 4. 0 if no sync words to be used.
918  void setSyncWords(const uint8_t* syncWords = NULL, uint8_t len = 0);
919 
920  /// Enables AES encryption and sets the AES encryption key, used
921  /// to encrypt and decrypt all messages. The default is disabled.
922  /// \param[in] key The key to use. Must be 16 bytes long. The same key must be installed
923  /// in other instances of RF69, otherwise communications will not work correctly. If key is NULL,
924  /// encryption is disabled, which is the default.
925  void setEncryptionKey(uint8_t* key = NULL);
926 
927  /// Returns the time in millis since the most recent preamble was received, and when the most recent
928  /// RSSI measurement was made.
929  uint32_t getLastPreambleTime();
930 
931  /// The maximum message length supported by this driver
932  /// \return The maximum message length supported by this driver
933  uint8_t maxMessageLength();
934 
935  /// Prints the value of a single register
936  /// to the Serial device if RH_HAVE_SERIAL is defined for the current platform
937  /// For debugging/testing only
938  /// \return true if successful
939  bool printRegister(uint8_t reg);
940 
941  /// Prints the value of all the RF69 registers
942  /// to the Serial device if RH_HAVE_SERIAL is defined for the current platform
943  /// For debugging/testing only
944  /// \return true if successful
945  bool printRegisters();
946 
947  /// Sets the radio operating mode for the case when the driver is idle (ie not
948  /// transmitting or receiving), allowing you to control the idle mode power requirements
949  /// at the expense of slower transitions to transmit and receive modes.
950  /// By default, the idle mode is RH_RF69_OPMODE_MODE_STDBY,
951  /// but eg setIdleMode(RH_RF69_OPMODE_MODE_SLEEP) will provide a much lower
952  /// idle current but slower transitions. Call this function after init().
953  /// \param[in] idleMode The chip operating mode to use when the driver is idle. One of RH_RF69_OPMODE_*
954  void setIdleMode(uint8_t idleMode);
955 
956  /// Sets the radio into low-power sleep mode.
957  /// If successful, the transport will stay in sleep mode until woken by
958  /// changing mode it idle, transmit or receive (eg by calling send(), recv(), available() etc)
959  /// Caution: there is a time penalty as the radio takes a finite time to wake from sleep mode.
960  /// \return true if sleep mode was successfully entered.
961  virtual bool sleep();
962 
963  /// Return the integer value of the device type
964  /// as read from the device in from RH_RF69_REG_10_VERSION.
965  /// Expect 0x24, depending on the type of device actually
966  /// connected.
967  /// \return The integer device type
968  uint16_t deviceType() {return _deviceType;};
969 
970 protected:
971  /// This is a low level function to handle the interrupts for one instance of RF69.
972  /// Called automatically by isr*()
973  /// Should not need to be called by user code.
974  void handleInterrupt();
975 
976  /// Low level function to read the FIFO and put the received data into the receive buffer
977  /// Should not need to be called by user code.
978  void readFifo();
979 
980 protected:
981  /// Low level interrupt service routine for RF69 connected to interrupt 0
982  static void isr0();
983 
984  /// Low level interrupt service routine for RF69 connected to interrupt 1
985  static void isr1();
986 
987  /// Low level interrupt service routine for RF69 connected to interrupt 1
988  static void isr2();
989 
990  /// Array of instances connected to interrupts 0 and 1
992 
993  /// Index of next interrupt number to use in _deviceForInterrupt
994  static uint8_t _interruptCount;
995 
996  /// The configured interrupt pin connected to this instance
997  uint8_t _interruptPin;
998 
999  /// The index into _deviceForInterrupt[] for this device (if an interrupt is already allocated)
1000  /// else 0xff
1002 
1003  /// The radio OP mode to use when mode is RHModeIdle
1004  uint8_t _idleMode;
1005 
1006  /// The reported device type
1007  uint8_t _deviceType;
1008 
1009  /// The selected output power in dBm
1010  int8_t _power;
1011 
1012  /// The message length in _buf
1013  volatile uint8_t _bufLen;
1014 
1015  /// Array of octets of teh last received message or the next to transmit message
1016  uint8_t _buf[RH_RF69_MAX_MESSAGE_LEN];
1017 
1018  /// True when there is a valid message in the Rx buffer
1019  volatile bool _rxBufValid;
1020 
1021  /// Time in millis since the last preamble was received (and the last time the RSSI was measured)
1023 };
1024 
1025 /// @example rf69_client.pde
1026 /// @example rf69_server.pde
1027 /// @example rf69_reliable_datagram_client.pde
1028 /// @example rf69_reliable_datagram_server.pde
1029 
1030 
1031 #endif
RHGenericDriver::_rxGood
volatile uint16_t _rxGood
Count of the number of successfully transmitted messaged.
Definition: RHGenericDriver.h:292
RH_RF69::ModemConfig::reg_02
uint8_t reg_02
Value for register RH_RF69_REG_02_DATAMODUL.
Definition: RH_RF69.h:722
RH_RF69::handleInterrupt
void handleInterrupt()
Definition: RH_RF69.cpp:200
RH_RF69::printRegisters
bool printRegisters()
Definition: RH_RF69.cpp:558
RH_RF69::OOK_Rb32Bw64
@ OOK_Rb32Bw64
OOK, Whitening, Rb = 32kbs, Rx Bandwidth = 64kHz.
Definition: RH_RF69.h:770
RH_RF69::setOpMode
void setOpMode(uint8_t mode)
Definition: RH_RF69.cpp:317
RH_RF69::setModeTx
void setModeTx()
Definition: RH_RF69.cpp:370
RH_RF69::FSK_Rb57_6Fd120
@ FSK_Rb57_6Fd120
FSK, Whitening, Rb = 57.6kbs, Fd = 120kHz.
Definition: RH_RF69.h:748
RH_RF69::RH_RF69
RH_RF69(uint8_t slaveSelectPin=SS, uint8_t interruptPin=2, RHGenericSPI &spi=hardware_spi)
Definition: RH_RF69.cpp:86
RHGenericSPI
Base class for SPI interfaces.
Definition: RHGenericSPI.h:30
RH_RF69::OOK_Rb9_6Bw19_2
@ OOK_Rb9_6Bw19_2
OOK, Whitening, Rb = 9.6kbs, Rx Bandwidth = 19.2kHz.
Definition: RH_RF69.h:768
RH_RF69::setFrequency
bool setFrequency(float centre, float afcPullInRange=0.05)
Definition: RH_RF69.cpp:292
RHGenericSPI::beginTransaction
virtual void beginTransaction()
Definition: RHGenericSPI.h:155
RH_RF69::GFSK_Rb9_6Fd19_2
@ GFSK_Rb9_6Fd19_2
GFSK, Whitening, Rb = 9.6kbs, Fd = 19.2kHz.
Definition: RH_RF69.h:756
RH_RF69::ModemConfig::reg_03
uint8_t reg_03
Value for register RH_RF69_REG_03_BITRATEMSB.
Definition: RH_RF69.h:723
RH_RF69::setModeIdle
void setModeIdle()
Definition: RH_RF69.cpp:329
RH_RF69::ModemConfig::reg_37
uint8_t reg_37
Value for register RH_RF69_REG_37_PACKETCONFIG1.
Definition: RH_RF69.h:729
RH_RF69::_bufLen
volatile uint8_t _bufLen
The message length in _buf.
Definition: RH_RF69.h:1013
RH_RF69::isr2
static void isr2()
Low level interrupt service routine for RF69 connected to interrupt 1.
Definition: RH_RF69.cpp:276
RHGenericDriver::_rxHeaderFrom
volatile uint8_t _rxHeaderFrom
FROM header in the last received mesasge.
Definition: RHGenericDriver.h:265
RH_RF69::_deviceType
uint8_t _deviceType
The reported device type.
Definition: RH_RF69.h:1007
RH_RF69::GFSK_Rb125Fd125
@ GFSK_Rb125Fd125
GFSK, Whitening, Rb = 125kbs, Fd = 125kHz.
Definition: RH_RF69.h:760
RHSPIDriver::spiWrite
uint8_t spiWrite(uint8_t reg, uint8_t val)
Definition: RHSPIDriver.cpp:42
RHSPIDriver
Base class for RadioHead drivers that use the SPI bus to communicate with its transport hardware.
Definition: RHSPIDriver.h:38
RH_RF69::ModemConfig::reg_19
uint8_t reg_19
Value for register RH_RF69_REG_19_RXBW.
Definition: RH_RF69.h:727
RH_RF69::FSK_Rb2_4Fd4_8
@ FSK_Rb2_4Fd4_8
FSK, Whitening, Rb = 2.4kbs, Fd = 4.8kHz.
Definition: RH_RF69.h:743
RH_RF69::ModemConfig::reg_05
uint8_t reg_05
Value for register RH_RF69_REG_05_FDEVMSB.
Definition: RH_RF69.h:725
RHGenericDriver::_lastRssi
volatile int16_t _lastRssi
The value of the last received RSSI value, in some transport specific units.
Definition: RHGenericDriver.h:286
RH_RF69::_buf
uint8_t _buf[RH_RF69_MAX_MESSAGE_LEN]
Array of octets of teh last received message or the next to transmit message.
Definition: RH_RF69.h:1016
RH_RF69::ModemConfig::reg_04
uint8_t reg_04
Value for register RH_RF69_REG_04_BITRATELSB.
Definition: RH_RF69.h:724
RH_RF69::setModemConfig
bool setModemConfig(ModemConfigChoice index)
Definition: RH_RF69.cpp:441
RHGenericDriver::_rxHeaderTo
volatile uint8_t _rxHeaderTo
TO header in the last received mesasge.
Definition: RHGenericDriver.h:262
RH_RF69::FSK_Rb38_4Fd76_8
@ FSK_Rb38_4Fd76_8
FSK, Whitening, Rb = 38.4kbs, Fd = 76.8kHz.
Definition: RH_RF69.h:747
RHGenericDriver::_txHeaderFrom
uint8_t _txHeaderFrom
FROM header to send in all messages.
Definition: RHGenericDriver.h:277
RH_RF69::setEncryptionKey
void setEncryptionKey(uint8_t *key=NULL)
Definition: RH_RF69.cpp:474
RH_RF69::getLastPreambleTime
uint32_t getLastPreambleTime()
RH_RF69::_interruptPin
uint8_t _interruptPin
The configured interrupt pin connected to this instance.
Definition: RH_RF69.h:997
RH_RF69::FSK_Rb19_2Fd38_4
@ FSK_Rb19_2Fd38_4
FSK, Whitening, Rb = 19.2kbs, Fd = 38.4kHz.
Definition: RH_RF69.h:746
RH_RF69::_lastPreambleTime
uint32_t _lastPreambleTime
Time in millis since the last preamble was received (and the last time the RSSI was measured)
Definition: RH_RF69.h:1022
RHSPIDriver::spiUsingInterrupt
void spiUsingInterrupt(uint8_t interruptNumber)
Definition: RHSPIDriver.cpp:91
RH_RF69::readFifo
void readFifo()
Definition: RH_RF69.cpp:230
RHGenericDriver::_thisAddress
uint8_t _thisAddress
This node id.
Definition: RHGenericDriver.h:256
RH_RF69::FSK_Rb125Fd125
@ FSK_Rb125Fd125
FSK, Whitening, Rb = 125kbs, Fd = 125kHz.
Definition: RH_RF69.h:749
RH_RF69::isr1
static void isr1()
Low level interrupt service routine for RF69 connected to interrupt 1.
Definition: RH_RF69.cpp:271
RHGenericDriver::_txGood
volatile uint16_t _txGood
Count of the number of bad messages (correct checksum etc) received.
Definition: RHGenericDriver.h:295
RH_RF69::GFSK_Rb250Fd250
@ GFSK_Rb250Fd250
GFSK, Whitening, Rb = 250kbs, Fd = 250kHz.
Definition: RH_RF69.h:761
RH_RF69::FSK_Rb9_6Fd19_2
@ FSK_Rb9_6Fd19_2
FSK, Whitening, Rb = 9.6kbs, Fd = 19.2kHz.
Definition: RH_RF69.h:745
RH_RF69
Driver to send and receive unaddressed, unreliable datagrams via an RF69 and compatible radio transce...
Definition: RH_RF69.h:709
RH_RF69::setTxPower
void setTxPower(int8_t power, bool ishighpowermodule=RH_RF69_DEFAULT_HIGHPOWER)
Definition: RH_RF69.cpp:387
RH_RF69::GFSK_Rb2Fd5
@ GFSK_Rb2Fd5
GFSK, Whitening, Rb = 2kbs, Fd = 5kHz.
Definition: RH_RF69.h:753
RHGenericDriver::_promiscuous
bool _promiscuous
Whether the transport is in promiscuous mode.
Definition: RHGenericDriver.h:259
RH_RF69::setModeRx
void setModeRx()
Definition: RH_RF69.cpp:354
RHGenericDriver::_rxHeaderFlags
volatile uint8_t _rxHeaderFlags
FLAGS header in the last received mesasge.
Definition: RHGenericDriver.h:271
RH_RF69::deviceType
uint16_t deviceType()
Definition: RH_RF69.h:968
RH_RF69::GFSK_Rb4_8Fd9_6
@ GFSK_Rb4_8Fd9_6
GFSK, Whitening, Rb = 4.8kbs, Fd = 9.6kHz.
Definition: RH_RF69.h:755
RH_RF69::GFSK_Rb38_4Fd76_8
@ GFSK_Rb38_4Fd76_8
GFSK, Whitening, Rb = 38.4kbs, Fd = 76.8kHz.
Definition: RH_RF69.h:758
RH_RF69::rssiRead
int8_t rssiRead()
Definition: RH_RF69.cpp:305
RH_RF69::setModemRegisters
void setModemRegisters(const ModemConfig *config)
Definition: RH_RF69.cpp:432
RH_RF69::OOK_Rb19_2Bw38_4
@ OOK_Rb19_2Bw38_4
OOK, Whitening, Rb = 19.2kbs, Rx Bandwidth = 38.4kHz.
Definition: RH_RF69.h:769
RH_RF69::recv
bool recv(uint8_t *buf, uint8_t *len)
Definition: RH_RF69.cpp:495
RH_RF69::OOK_Rb4_8Bw9_6
@ OOK_Rb4_8Bw9_6
OOK, Whitening, Rb = 4.8kbs, Rx Bandwidth = 9.6kHz.
Definition: RH_RF69.h:767
RH_RF69::ModemConfig::reg_1a
uint8_t reg_1a
Value for register RH_RF69_REG_1A_AFCBW.
Definition: RH_RF69.h:728
RHGenericDriver::RHModeSleep
@ RHModeSleep
Transport hardware is in low power sleep mode (if supported)
Definition: RHGenericDriver.h:51
RHSPIDriver::spiBurstWrite
uint8_t spiBurstWrite(uint8_t reg, const uint8_t *src, uint8_t len)
Definition: RHSPIDriver.cpp:71
RH_RF69::_myInterruptIndex
uint8_t _myInterruptIndex
Definition: RH_RF69.h:1001
RH_RF69::_idleMode
uint8_t _idleMode
The radio OP mode to use when mode is RHModeIdle.
Definition: RH_RF69.h:1004
RHSPIDriver::init
bool init()
Definition: RHSPIDriver.cpp:15
RHSPIDriver::_slaveSelectPin
uint8_t _slaveSelectPin
The pin number of the Slave Select pin that is used to select the desired device.
Definition: RHSPIDriver.h:97
RH_RF69::GFSK_Rb19_2Fd38_4
@ GFSK_Rb19_2Fd38_4
GFSK, Whitening, Rb = 19.2kbs, Fd = 38.4kHz.
Definition: RH_RF69.h:757
RH_RF69::maxMessageLength
uint8_t maxMessageLength()
Definition: RH_RF69.cpp:543
RH_RF69::OOK_Rb1_2Bw75
@ OOK_Rb1_2Bw75
OOK, Whitening, Rb = 1.2kbs, Rx Bandwidth = 75kHz.
Definition: RH_RF69.h:765
RH_RF69::setSyncWords
void setSyncWords(const uint8_t *syncWords=NULL, uint8_t len=0)
Definition: RH_RF69.cpp:459
RH_RF69::temperatureRead
int8_t temperatureRead()
Definition: RH_RF69.cpp:282
RHGenericDriver::_txHeaderId
uint8_t _txHeaderId
ID header to send in all messages.
Definition: RHGenericDriver.h:280
RH_RF69::init
bool init()
Definition: RH_RF69.cpp:100
RH_RF69::send
bool send(const uint8_t *data, uint8_t len)
Definition: RH_RF69.cpp:513
RH_RF69::available
bool available()
Definition: RH_RF69.cpp:487
RHGenericDriver::_txHeaderTo
uint8_t _txHeaderTo
TO header to send in all messages.
Definition: RHGenericDriver.h:274
RH_RF69::printRegister
bool printRegister(uint8_t reg)
Definition: RH_RF69.cpp:548
RH_RF69::ModemConfigChoice
ModemConfigChoice
Definition: RH_RF69.h:740
RH_RF69::setIdleMode
void setIdleMode(uint8_t idleMode)
Definition: RH_RF69.cpp:95
RHGenericDriver::_txHeaderFlags
uint8_t _txHeaderFlags
FLAGS header to send in all messages.
Definition: RHGenericDriver.h:283
RH_RF69::GFSK_Rb55555Fd50
@ GFSK_Rb55555Fd50
GFSK, Whitening, Rb = 55555kbs,Fd = 50kHz.
Definition: RH_RF69.h:762
RH_RF69::sleep
virtual bool sleep()
Definition: RH_RF69.cpp:344
RH_RF69::OOK_Rb1Bw1
@ OOK_Rb1Bw1
OOK, Whitening, Rb = 1kbs, Rx Bandwidth = 1kHz.
Definition: RH_RF69.h:764
RH_RF69::ModemConfig::reg_06
uint8_t reg_06
Value for register RH_RF69_REG_06_FDEVLSB.
Definition: RH_RF69.h:726
RHGenericDriver::_rxHeaderId
volatile uint8_t _rxHeaderId
ID header in the last received mesasge.
Definition: RHGenericDriver.h:268
RH_RF69::GFSK_Rb2_4Fd4_8
@ GFSK_Rb2_4Fd4_8
GFSK, Whitening, Rb = 2.4kbs, Fd = 4.8kHz.
Definition: RH_RF69.h:754
RH_RF69::OOK_Rb2_4Bw4_8
@ OOK_Rb2_4Bw4_8
OOK, Whitening, Rb = 2.4kbs, Rx Bandwidth = 4.8kHz.
Definition: RH_RF69.h:766
RHGenericDriver::RHModeIdle
@ RHModeIdle
Transport is idle.
Definition: RHGenericDriver.h:52
RHSPIDriver::spiRead
uint8_t spiRead(uint8_t reg)
Definition: RHSPIDriver.cpp:30
RH_RF69::GFSK_Rb57_6Fd120
@ GFSK_Rb57_6Fd120
GFSK, Whitening, Rb = 57.6kbs, Fd = 120kHz.
Definition: RH_RF69.h:759
RHGenericDriver::waitPacketSent
virtual bool waitPacketSent()
Definition: RHGenericDriver.cpp:52
RHGenericDriver::_mode
volatile RHMode _mode
The current transport operating mode.
Definition: RHGenericDriver.h:253
RH_RF69::FSK_Rb4_8Fd9_6
@ FSK_Rb4_8Fd9_6
FSK, Whitening, Rb = 4.8kbs, Fd = 9.6kHz.
Definition: RH_RF69.h:744
RH_RF69::FSK_Rb250Fd250
@ FSK_Rb250Fd250
FSK, Whitening, Rb = 250kbs, Fd = 250kHz.
Definition: RH_RF69.h:750
RHSPIDriver::_spi
RHGenericSPI & _spi
Reference to the RHGenericSPI instance to use to transfer data with the SPI device.
Definition: RHSPIDriver.h:94
RH_RF69::FSK_Rb2Fd5
@ FSK_Rb2Fd5
FSK, Whitening, Rb = 2kbs, Fd = 5kHz.
Definition: RH_RF69.h:742
RHGenericDriver::RHModeTx
@ RHModeTx
Transport is in the process of transmitting a message.
Definition: RHGenericDriver.h:53
RHGenericSPI::endTransaction
virtual void endTransaction()
Definition: RHGenericSPI.h:160
RH_RF69::_rxBufValid
volatile bool _rxBufValid
True when there is a valid message in the Rx buffer.
Definition: RH_RF69.h:1019
RH_RF69::_power
int8_t _power
The selected output power in dBm.
Definition: RH_RF69.h:1010
RH_RF69::setPreambleLength
void setPreambleLength(uint16_t bytes)
Definition: RH_RF69.cpp:453
RH_RF69::ModemConfig
Defines register values for a set of modem configuration registers.
Definition: RH_RF69.h:720
RH_RF69::FSK_Rb55555Fd50
@ FSK_Rb55555Fd50
FSK, Whitening, Rb = 55555kbs,Fd = 50kHz for RFM69 lib compatibility.
Definition: RH_RF69.h:751
RHGenericDriver::mode
virtual RHMode mode()
Definition: RHGenericDriver.cpp:159
RHGenericDriver::RHModeRx
@ RHModeRx
Transport is in the process of receiving a message.
Definition: RHGenericDriver.h:54
RHGenericSPI::transfer
virtual uint8_t transfer(uint8_t data)=0
RH_RF69::_interruptCount
static uint8_t _interruptCount
Index of next interrupt number to use in _deviceForInterrupt.
Definition: RH_RF69.h:994
RH_RF69::_deviceForInterrupt
static RH_RF69 * _deviceForInterrupt[]
Array of instances connected to interrupts 0 and 1.
Definition: RH_RF69.h:991
RHGenericDriver::waitCAD
virtual bool waitCAD()
Definition: RHGenericDriver.cpp:72
RH_RF69::isr0
static void isr0()
Low level interrupt service routine for RF69 connected to interrupt 0.
Definition: RH_RF69.cpp:266