PlatformIO package of the Teensy core framework compatible with GCC 10 & C++20
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

930 行
45KB

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