V148
Fork of RadioHead-148 by
RH_RF69.h@1:b7641da2b203, 2017-10-25 (annotated)
- Committer:
- ilkaykozak
- Date:
- Wed Oct 25 05:14:09 2017 +0000
- Revision:
- 1:b7641da2b203
- Parent:
- 0:ab4e012489ef
V148
Who changed what in which revision?
User | Revision | Line number | New 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 |