V148

Fork of RadioHead-148 by David Rimer

Committer:
davidr99
Date:
Thu Oct 15 01:27:00 2015 +0000
Revision:
0:ab4e012489ef
Messy start, but a port for RadioHead.; Currently the SPI modulus are the only ones that work.

Who changed what in which revision?

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