This driver is a stripped down version of the Radiohead 1.45 driver, and covers fewer radios. Threading and an event queue have been added to make the ISR's more stable across architectures. Specifically The STM32L4 parts

Dependents:   Threaded_LoRa_Modem

Committer:
davidr99
Date:
Thu Oct 15 01:27:00 2015 +0000
Revision:
0:ab4e012489ef
Child:
1:dfeb5e8b199a
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_RF95.h
davidr99 0:ab4e012489ef 2 //
davidr99 0:ab4e012489ef 3 // Definitions for HopeRF LoRa radios per:
davidr99 0:ab4e012489ef 4 // http://www.hoperf.com/upload/rf/RFM95_96_97_98W.pdf
davidr99 0:ab4e012489ef 5 // http://www.hoperf.cn/upload/rfchip/RF96_97_98.pdf
davidr99 0:ab4e012489ef 6 //
davidr99 0:ab4e012489ef 7 // Author: Mike McCauley (mikem@airspayce.com)
davidr99 0:ab4e012489ef 8 // Copyright (C) 2014 Mike McCauley
davidr99 0:ab4e012489ef 9 // $Id: RH_RF95.h,v 1.7 2015/05/17 00:11:26 mikem Exp $
davidr99 0:ab4e012489ef 10 //
davidr99 0:ab4e012489ef 11
davidr99 0:ab4e012489ef 12 #ifndef RH_RF95_h
davidr99 0:ab4e012489ef 13 #define RH_RF95_h
davidr99 0:ab4e012489ef 14
davidr99 0:ab4e012489ef 15 #include <RHSPIDriver.h>
davidr99 0:ab4e012489ef 16
davidr99 0:ab4e012489ef 17 // This is the maximum number of interrupts the driver can support
davidr99 0:ab4e012489ef 18 // Most Arduinos can handle 2, Megas can handle more
davidr99 0:ab4e012489ef 19 #define RH_RF95_NUM_INTERRUPTS 3
davidr99 0:ab4e012489ef 20
davidr99 0:ab4e012489ef 21 // Max number of octets the LORA Rx/Tx FIFO can hold
davidr99 0:ab4e012489ef 22 #define RH_RF95_FIFO_SIZE 255
davidr99 0:ab4e012489ef 23
davidr99 0:ab4e012489ef 24 // This is the maximum number of bytes that can be carried by the LORA.
davidr99 0:ab4e012489ef 25 // We use some for headers, keeping fewer for RadioHead messages
davidr99 0:ab4e012489ef 26 #define RH_RF95_MAX_PAYLOAD_LEN RH_RF95_FIFO_SIZE
davidr99 0:ab4e012489ef 27
davidr99 0:ab4e012489ef 28 // The length of the headers we add.
davidr99 0:ab4e012489ef 29 // The headers are inside the LORA's payload
davidr99 0:ab4e012489ef 30 #define RH_RF95_HEADER_LEN 4
davidr99 0:ab4e012489ef 31
davidr99 0:ab4e012489ef 32 // This is the maximum message length that can be supported by this driver.
davidr99 0:ab4e012489ef 33 // Can be pre-defined to a smaller size (to save SRAM) prior to including this header
davidr99 0:ab4e012489ef 34 // Here we allow for 1 byte message length, 4 bytes headers, user data and 2 bytes of FCS
davidr99 0:ab4e012489ef 35 #ifndef RH_RF95_MAX_MESSAGE_LEN
davidr99 0:ab4e012489ef 36 #define RH_RF95_MAX_MESSAGE_LEN (RH_RF95_MAX_PAYLOAD_LEN - RH_RF95_HEADER_LEN)
davidr99 0:ab4e012489ef 37 #endif
davidr99 0:ab4e012489ef 38
davidr99 0:ab4e012489ef 39 // The crystal oscillator frequency of the module
davidr99 0:ab4e012489ef 40 #define RH_RF95_FXOSC 32000000.0
davidr99 0:ab4e012489ef 41
davidr99 0:ab4e012489ef 42 // The Frequency Synthesizer step = RH_RF95_FXOSC / 2^^19
davidr99 0:ab4e012489ef 43 #define RH_RF95_FSTEP (RH_RF95_FXOSC / 524288)
davidr99 0:ab4e012489ef 44
davidr99 0:ab4e012489ef 45
davidr99 0:ab4e012489ef 46 // Register names (LoRa Mode, from table 85)
davidr99 0:ab4e012489ef 47 #define RH_RF95_REG_00_FIFO 0x00
davidr99 0:ab4e012489ef 48 #define RH_RF95_REG_01_OP_MODE 0x01
davidr99 0:ab4e012489ef 49 #define RH_RF95_REG_02_RESERVED 0x02
davidr99 0:ab4e012489ef 50 #define RH_RF95_REG_03_RESERVED 0x03
davidr99 0:ab4e012489ef 51 #define RH_RF95_REG_04_RESERVED 0x04
davidr99 0:ab4e012489ef 52 #define RH_RF95_REG_05_RESERVED 0x05
davidr99 0:ab4e012489ef 53 #define RH_RF95_REG_06_FRF_MSB 0x06
davidr99 0:ab4e012489ef 54 #define RH_RF95_REG_07_FRF_MID 0x07
davidr99 0:ab4e012489ef 55 #define RH_RF95_REG_08_FRF_LSB 0x08
davidr99 0:ab4e012489ef 56 #define RH_RF95_REG_09_PA_CONFIG 0x09
davidr99 0:ab4e012489ef 57 #define RH_RF95_REG_0A_PA_RAMP 0x0a
davidr99 0:ab4e012489ef 58 #define RH_RF95_REG_0B_OCP 0x0b
davidr99 0:ab4e012489ef 59 #define RH_RF95_REG_0C_LNA 0x0c
davidr99 0:ab4e012489ef 60 #define RH_RF95_REG_0D_FIFO_ADDR_PTR 0x0d
davidr99 0:ab4e012489ef 61 #define RH_RF95_REG_0E_FIFO_TX_BASE_ADDR 0x0e
davidr99 0:ab4e012489ef 62 #define RH_RF95_REG_0F_FIFO_RX_BASE_ADDR 0x0f
davidr99 0:ab4e012489ef 63 #define RH_RF95_REG_10_FIFO_RX_CURRENT_ADDR 0x10
davidr99 0:ab4e012489ef 64 #define RH_RF95_REG_11_IRQ_FLAGS_MASK 0x11
davidr99 0:ab4e012489ef 65 #define RH_RF95_REG_12_IRQ_FLAGS 0x12
davidr99 0:ab4e012489ef 66 #define RH_RF95_REG_13_RX_NB_BYTES 0x13
davidr99 0:ab4e012489ef 67 #define RH_RF95_REG_14_RX_HEADER_CNT_VALUE_MSB 0x14
davidr99 0:ab4e012489ef 68 #define RH_RF95_REG_15_RX_HEADER_CNT_VALUE_LSB 0x15
davidr99 0:ab4e012489ef 69 #define RH_RF95_REG_16_RX_PACKET_CNT_VALUE_MSB 0x16
davidr99 0:ab4e012489ef 70 #define RH_RF95_REG_17_RX_PACKET_CNT_VALUE_LSB 0x17
davidr99 0:ab4e012489ef 71 #define RH_RF95_REG_18_MODEM_STAT 0x18
davidr99 0:ab4e012489ef 72 #define RH_RF95_REG_19_PKT_SNR_VALUE 0x19
davidr99 0:ab4e012489ef 73 #define RH_RF95_REG_1A_PKT_RSSI_VALUE 0x1a
davidr99 0:ab4e012489ef 74 #define RH_RF95_REG_1B_RSSI_VALUE 0x1b
davidr99 0:ab4e012489ef 75 #define RH_RF95_REG_1C_HOP_CHANNEL 0x1c
davidr99 0:ab4e012489ef 76 #define RH_RF95_REG_1D_MODEM_CONFIG1 0x1d
davidr99 0:ab4e012489ef 77 #define RH_RF95_REG_1E_MODEM_CONFIG2 0x1e
davidr99 0:ab4e012489ef 78 #define RH_RF95_REG_1F_SYMB_TIMEOUT_LSB 0x1f
davidr99 0:ab4e012489ef 79 #define RH_RF95_REG_20_PREAMBLE_MSB 0x20
davidr99 0:ab4e012489ef 80 #define RH_RF95_REG_21_PREAMBLE_LSB 0x21
davidr99 0:ab4e012489ef 81 #define RH_RF95_REG_22_PAYLOAD_LENGTH 0x22
davidr99 0:ab4e012489ef 82 #define RH_RF95_REG_23_MAX_PAYLOAD_LENGTH 0x23
davidr99 0:ab4e012489ef 83 #define RH_RF95_REG_24_HOP_PERIOD 0x24
davidr99 0:ab4e012489ef 84 #define RH_RF95_REG_25_FIFO_RX_BYTE_ADDR 0x25
davidr99 0:ab4e012489ef 85 #define RH_RF95_REG_26_MODEM_CONFIG3 0x26
davidr99 0:ab4e012489ef 86
davidr99 0:ab4e012489ef 87 #define RH_RF95_REG_40_DIO_MAPPING1 0x40
davidr99 0:ab4e012489ef 88 #define RH_RF95_REG_41_DIO_MAPPING2 0x41
davidr99 0:ab4e012489ef 89 #define RH_RF95_REG_42_VERSION 0x42
davidr99 0:ab4e012489ef 90
davidr99 0:ab4e012489ef 91 #define RH_RF95_REG_4B_TCXO 0x4b
davidr99 0:ab4e012489ef 92 #define RH_RF95_REG_4D_PA_DAC 0x4d
davidr99 0:ab4e012489ef 93 #define RH_RF95_REG_5B_FORMER_TEMP 0x5b
davidr99 0:ab4e012489ef 94 #define RH_RF95_REG_61_AGC_REF 0x61
davidr99 0:ab4e012489ef 95 #define RH_RF95_REG_62_AGC_THRESH1 0x62
davidr99 0:ab4e012489ef 96 #define RH_RF95_REG_63_AGC_THRESH2 0x63
davidr99 0:ab4e012489ef 97 #define RH_RF95_REG_64_AGC_THRESH3 0x64
davidr99 0:ab4e012489ef 98
davidr99 0:ab4e012489ef 99 // RH_RF95_REG_01_OP_MODE 0x01
davidr99 0:ab4e012489ef 100 #define RH_RF95_LONG_RANGE_MODE 0x80
davidr99 0:ab4e012489ef 101 #define RH_RF95_ACCESS_SHARED_REG 0x40
davidr99 0:ab4e012489ef 102 #define RH_RF95_MODE 0x07
davidr99 0:ab4e012489ef 103 #define RH_RF95_MODE_SLEEP 0x00
davidr99 0:ab4e012489ef 104 #define RH_RF95_MODE_STDBY 0x01
davidr99 0:ab4e012489ef 105 #define RH_RF95_MODE_FSTX 0x02
davidr99 0:ab4e012489ef 106 #define RH_RF95_MODE_TX 0x03
davidr99 0:ab4e012489ef 107 #define RH_RF95_MODE_FSRX 0x04
davidr99 0:ab4e012489ef 108 #define RH_RF95_MODE_RXCONTINUOUS 0x05
davidr99 0:ab4e012489ef 109 #define RH_RF95_MODE_RXSINGLE 0x06
davidr99 0:ab4e012489ef 110 #define RH_RF95_MODE_CAD 0x07
davidr99 0:ab4e012489ef 111
davidr99 0:ab4e012489ef 112 // RH_RF95_REG_09_PA_CONFIG 0x09
davidr99 0:ab4e012489ef 113 #define RH_RF95_PA_SELECT 0x80
davidr99 0:ab4e012489ef 114 #define RH_RF95_OUTPUT_POWER 0x0f
davidr99 0:ab4e012489ef 115
davidr99 0:ab4e012489ef 116 // RH_RF95_REG_0A_PA_RAMP 0x0a
davidr99 0:ab4e012489ef 117 #define RH_RF95_LOW_PN_TX_PLL_OFF 0x10
davidr99 0:ab4e012489ef 118 #define RH_RF95_PA_RAMP 0x0f
davidr99 0:ab4e012489ef 119 #define RH_RF95_PA_RAMP_3_4MS 0x00
davidr99 0:ab4e012489ef 120 #define RH_RF95_PA_RAMP_2MS 0x01
davidr99 0:ab4e012489ef 121 #define RH_RF95_PA_RAMP_1MS 0x02
davidr99 0:ab4e012489ef 122 #define RH_RF95_PA_RAMP_500US 0x03
davidr99 0:ab4e012489ef 123 #define RH_RF95_PA_RAMP_250US 0x0
davidr99 0:ab4e012489ef 124 #define RH_RF95_PA_RAMP_125US 0x05
davidr99 0:ab4e012489ef 125 #define RH_RF95_PA_RAMP_100US 0x06
davidr99 0:ab4e012489ef 126 #define RH_RF95_PA_RAMP_62US 0x07
davidr99 0:ab4e012489ef 127 #define RH_RF95_PA_RAMP_50US 0x08
davidr99 0:ab4e012489ef 128 #define RH_RF95_PA_RAMP_40US 0x09
davidr99 0:ab4e012489ef 129 #define RH_RF95_PA_RAMP_31US 0x0a
davidr99 0:ab4e012489ef 130 #define RH_RF95_PA_RAMP_25US 0x0b
davidr99 0:ab4e012489ef 131 #define RH_RF95_PA_RAMP_20US 0x0c
davidr99 0:ab4e012489ef 132 #define RH_RF95_PA_RAMP_15US 0x0d
davidr99 0:ab4e012489ef 133 #define RH_RF95_PA_RAMP_12US 0x0e
davidr99 0:ab4e012489ef 134 #define RH_RF95_PA_RAMP_10US 0x0f
davidr99 0:ab4e012489ef 135
davidr99 0:ab4e012489ef 136 // RH_RF95_REG_0B_OCP 0x0b
davidr99 0:ab4e012489ef 137 #define RH_RF95_OCP_ON 0x20
davidr99 0:ab4e012489ef 138 #define RH_RF95_OCP_TRIM 0x1f
davidr99 0:ab4e012489ef 139
davidr99 0:ab4e012489ef 140 // RH_RF95_REG_0C_LNA 0x0c
davidr99 0:ab4e012489ef 141 #define RH_RF95_LNA_GAIN 0xe0
davidr99 0:ab4e012489ef 142 #define RH_RF95_LNA_BOOST 0x03
davidr99 0:ab4e012489ef 143 #define RH_RF95_LNA_BOOST_DEFAULT 0x00
davidr99 0:ab4e012489ef 144 #define RH_RF95_LNA_BOOST_150PC 0x11
davidr99 0:ab4e012489ef 145
davidr99 0:ab4e012489ef 146 // RH_RF95_REG_11_IRQ_FLAGS_MASK 0x11
davidr99 0:ab4e012489ef 147 #define RH_RF95_RX_TIMEOUT_MASK 0x80
davidr99 0:ab4e012489ef 148 #define RH_RF95_RX_DONE_MASK 0x40
davidr99 0:ab4e012489ef 149 #define RH_RF95_PAYLOAD_CRC_ERROR_MASK 0x20
davidr99 0:ab4e012489ef 150 #define RH_RF95_VALID_HEADER_MASK 0x10
davidr99 0:ab4e012489ef 151 #define RH_RF95_TX_DONE_MASK 0x08
davidr99 0:ab4e012489ef 152 #define RH_RF95_CAD_DONE_MASK 0x04
davidr99 0:ab4e012489ef 153 #define RH_RF95_FHSS_CHANGE_CHANNEL_MASK 0x02
davidr99 0:ab4e012489ef 154 #define RH_RF95_CAD_DETECTED_MASK 0x01
davidr99 0:ab4e012489ef 155
davidr99 0:ab4e012489ef 156 // RH_RF95_REG_12_IRQ_FLAGS 0x12
davidr99 0:ab4e012489ef 157 #define RH_RF95_RX_TIMEOUT 0x80
davidr99 0:ab4e012489ef 158 #define RH_RF95_RX_DONE 0x40
davidr99 0:ab4e012489ef 159 #define RH_RF95_PAYLOAD_CRC_ERROR 0x20
davidr99 0:ab4e012489ef 160 #define RH_RF95_VALID_HEADER 0x10
davidr99 0:ab4e012489ef 161 #define RH_RF95_TX_DONE 0x08
davidr99 0:ab4e012489ef 162 #define RH_RF95_CAD_DONE 0x04
davidr99 0:ab4e012489ef 163 #define RH_RF95_FHSS_CHANGE_CHANNEL 0x02
davidr99 0:ab4e012489ef 164 #define RH_RF95_CAD_DETECTED 0x01
davidr99 0:ab4e012489ef 165
davidr99 0:ab4e012489ef 166 // RH_RF95_REG_18_MODEM_STAT 0x18
davidr99 0:ab4e012489ef 167 #define RH_RF95_RX_CODING_RATE 0xe0
davidr99 0:ab4e012489ef 168 #define RH_RF95_MODEM_STATUS_CLEAR 0x10
davidr99 0:ab4e012489ef 169 #define RH_RF95_MODEM_STATUS_HEADER_INFO_VALID 0x08
davidr99 0:ab4e012489ef 170 #define RH_RF95_MODEM_STATUS_RX_ONGOING 0x04
davidr99 0:ab4e012489ef 171 #define RH_RF95_MODEM_STATUS_SIGNAL_SYNCHRONIZED 0x02
davidr99 0:ab4e012489ef 172 #define RH_RF95_MODEM_STATUS_SIGNAL_DETECTED 0x01
davidr99 0:ab4e012489ef 173
davidr99 0:ab4e012489ef 174 // RH_RF95_REG_1C_HOP_CHANNEL 0x1c
davidr99 0:ab4e012489ef 175 #define RH_RF95_PLL_TIMEOUT 0x80
davidr99 0:ab4e012489ef 176 #define RH_RF95_RX_PAYLOAD_CRC_IS_ON 0x40
davidr99 0:ab4e012489ef 177 #define RH_RF95_FHSS_PRESENT_CHANNEL 0x3f
davidr99 0:ab4e012489ef 178
davidr99 0:ab4e012489ef 179 // RH_RF95_REG_1D_MODEM_CONFIG1 0x1d
davidr99 0:ab4e012489ef 180 #define RH_RF95_BW 0xc0
davidr99 0:ab4e012489ef 181 #define RH_RF95_BW_125KHZ 0x00
davidr99 0:ab4e012489ef 182 #define RH_RF95_BW_250KHZ 0x40
davidr99 0:ab4e012489ef 183 #define RH_RF95_BW_500KHZ 0x80
davidr99 0:ab4e012489ef 184 #define RH_RF95_BW_RESERVED 0xc0
davidr99 0:ab4e012489ef 185 #define RH_RF95_CODING_RATE 0x38
davidr99 0:ab4e012489ef 186 #define RH_RF95_CODING_RATE_4_5 0x00
davidr99 0:ab4e012489ef 187 #define RH_RF95_CODING_RATE_4_6 0x08
davidr99 0:ab4e012489ef 188 #define RH_RF95_CODING_RATE_4_7 0x10
davidr99 0:ab4e012489ef 189 #define RH_RF95_CODING_RATE_4_8 0x18
davidr99 0:ab4e012489ef 190 #define RH_RF95_IMPLICIT_HEADER_MODE_ON 0x04
davidr99 0:ab4e012489ef 191 #define RH_RF95_RX_PAYLOAD_CRC_ON 0x02
davidr99 0:ab4e012489ef 192 #define RH_RF95_LOW_DATA_RATE_OPTIMIZE 0x01
davidr99 0:ab4e012489ef 193
davidr99 0:ab4e012489ef 194 // RH_RF95_REG_1E_MODEM_CONFIG2 0x1e
davidr99 0:ab4e012489ef 195 #define RH_RF95_SPREADING_FACTOR 0xf0
davidr99 0:ab4e012489ef 196 #define RH_RF95_SPREADING_FACTOR_64CPS 0x60
davidr99 0:ab4e012489ef 197 #define RH_RF95_SPREADING_FACTOR_128CPS 0x70
davidr99 0:ab4e012489ef 198 #define RH_RF95_SPREADING_FACTOR_256CPS 0x80
davidr99 0:ab4e012489ef 199 #define RH_RF95_SPREADING_FACTOR_512CPS 0x90
davidr99 0:ab4e012489ef 200 #define RH_RF95_SPREADING_FACTOR_1024CPS 0xa0
davidr99 0:ab4e012489ef 201 #define RH_RF95_SPREADING_FACTOR_2048CPS 0xb0
davidr99 0:ab4e012489ef 202 #define RH_RF95_SPREADING_FACTOR_4096CPS 0xc0
davidr99 0:ab4e012489ef 203 #define RH_RF95_TX_CONTINUOUS_MOE 0x08
davidr99 0:ab4e012489ef 204 #define RH_RF95_AGC_AUTO_ON 0x04
davidr99 0:ab4e012489ef 205 #define RH_RF95_SYM_TIMEOUT_MSB 0x03
davidr99 0:ab4e012489ef 206
davidr99 0:ab4e012489ef 207 // RH_RF95_REG_4D_PA_DAC 0x4d
davidr99 0:ab4e012489ef 208 #define RH_RF95_PA_DAC_DISABLE 0x04
davidr99 0:ab4e012489ef 209 #define RH_RF95_PA_DAC_ENABLE 0x07
davidr99 0:ab4e012489ef 210
davidr99 0:ab4e012489ef 211 /////////////////////////////////////////////////////////////////////
davidr99 0:ab4e012489ef 212 /// \class RH_RF95 RH_RF95.h <RH_RF95.h>
davidr99 0:ab4e012489ef 213 /// \brief Driver to send and receive unaddressed, unreliable datagrams via a LoRa
davidr99 0:ab4e012489ef 214 /// capable radio transceiver.
davidr99 0:ab4e012489ef 215 ///
davidr99 0:ab4e012489ef 216 /// For Semtech SX1276/77/78 and HopeRF RFM95/96/97/98 and other similar LoRa capable radios.
davidr99 0:ab4e012489ef 217 /// Based on http://www.hoperf.com/upload/rf/RFM95_96_97_98W.pdf
davidr99 0:ab4e012489ef 218 /// and http://www.hoperf.cn/upload/rfchip/RF96_97_98.pdf
davidr99 0:ab4e012489ef 219 /// and http://www.semtech.com/images/datasheet/LoraDesignGuide_STD.pdf
davidr99 0:ab4e012489ef 220 /// and http://www.semtech.com/images/datasheet/sx1276.pdf
davidr99 0:ab4e012489ef 221 /// FSK/GFSK/OOK modes are not (yet) supported.
davidr99 0:ab4e012489ef 222 ///
davidr99 0:ab4e012489ef 223 /// Works with
davidr99 0:ab4e012489ef 224 /// - the excellent MiniWirelessLoRa from Anarduino http://www.anarduino.com/miniwireless
davidr99 0:ab4e012489ef 225 ///
davidr99 0:ab4e012489ef 226 /// \par Overview
davidr99 0:ab4e012489ef 227 ///
davidr99 0:ab4e012489ef 228 /// This class provides basic functions for sending and receiving unaddressed,
davidr99 0:ab4e012489ef 229 /// unreliable datagrams of arbitrary length to 251 octets per packet.
davidr99 0:ab4e012489ef 230 ///
davidr99 0:ab4e012489ef 231 /// Manager classes may use this class to implement reliable, addressed datagrams and streams,
davidr99 0:ab4e012489ef 232 /// mesh routers, repeaters, translators etc.
davidr99 0:ab4e012489ef 233 ///
davidr99 0:ab4e012489ef 234 /// Naturally, for any 2 radios to communicate that must be configured to use the same frequency and
davidr99 0:ab4e012489ef 235 /// modulation scheme.
davidr99 0:ab4e012489ef 236 ///
davidr99 0:ab4e012489ef 237 /// This Driver provides an object-oriented interface for sending and receiving data messages with Hope-RF
davidr99 0:ab4e012489ef 238 /// RFM95/96/97/98(W) and compatible radio modules in LoRa mode.
davidr99 0:ab4e012489ef 239 ///
davidr99 0:ab4e012489ef 240 /// The Hope-RF (http://www.hoperf.com) RFM95/96/97/98(W) is a low-cost ISM transceiver
davidr99 0:ab4e012489ef 241 /// chip. It supports FSK, GFSK, OOK over a wide range of frequencies and
davidr99 0:ab4e012489ef 242 /// programmable data rates, and it also supports the proprietary LoRA (Long Range) mode, which
davidr99 0:ab4e012489ef 243 /// is the only mode supported in this RadioHead driver.
davidr99 0:ab4e012489ef 244 ///
davidr99 0:ab4e012489ef 245 /// This Driver provides functions for sending and receiving messages of up
davidr99 0:ab4e012489ef 246 /// to 251 octets on any frequency supported by the radio, in a range of
davidr99 0:ab4e012489ef 247 /// predefined Bandwidths, Spreading Factors and Coding Rates. Frequency can be set with
davidr99 0:ab4e012489ef 248 /// 61Hz precision to any frequency from 240.0MHz to 960.0MHz. Caution: most modules only support a more limited
davidr99 0:ab4e012489ef 249 /// range of frequencies due to antenna tuning.
davidr99 0:ab4e012489ef 250 ///
davidr99 0:ab4e012489ef 251 /// Up to 2 RFM95/96/97/98(W) modules can be connected to an Arduino (3 on a Mega),
davidr99 0:ab4e012489ef 252 /// permitting the construction of translators and frequency changers, etc.
davidr99 0:ab4e012489ef 253 ///
davidr99 0:ab4e012489ef 254 /// Support for other features such as transmitter power control etc is
davidr99 0:ab4e012489ef 255 /// also provided.
davidr99 0:ab4e012489ef 256 ///
davidr99 0:ab4e012489ef 257 /// Tested on MinWirelessLoRa with arduino-1.0.5
davidr99 0:ab4e012489ef 258 /// on OpenSuSE 13.1
davidr99 0:ab4e012489ef 259 ///
davidr99 0:ab4e012489ef 260 /// \par Packet Format
davidr99 0:ab4e012489ef 261 ///
davidr99 0:ab4e012489ef 262 /// All messages sent and received by this RH_RF95 Driver conform to this packet format:
davidr99 0:ab4e012489ef 263 ///
davidr99 0:ab4e012489ef 264 /// - LoRa mode:
davidr99 0:ab4e012489ef 265 /// - 8 symbol PREAMBLE
davidr99 0:ab4e012489ef 266 /// - Explicit header with header CRC (handled internally by the radio)
davidr99 0:ab4e012489ef 267 /// - 4 octets HEADER: (TO, FROM, ID, FLAGS)
davidr99 0:ab4e012489ef 268 /// - 0 to 251 octets DATA
davidr99 0:ab4e012489ef 269 /// - CRC (handled internally by the radio)
davidr99 0:ab4e012489ef 270 ///
davidr99 0:ab4e012489ef 271 /// \par Connecting RFM95/96/97/98 to Arduino
davidr99 0:ab4e012489ef 272 ///
davidr99 0:ab4e012489ef 273 /// We tested with Anarduino MiniWirelessLoRA, which is an Arduino Duemilanove compatible with a RFM96W
davidr99 0:ab4e012489ef 274 /// module on-board. Therefore it needs no connections other than the USB
davidr99 0:ab4e012489ef 275 /// programming connection and an antenna to make it work.
davidr99 0:ab4e012489ef 276 ///
davidr99 0:ab4e012489ef 277 /// If you have a bare RFM95/96/97/98 that you want to connect to an Arduino, you
davidr99 0:ab4e012489ef 278 /// might use these connections (untested): CAUTION: you must use a 3.3V type
davidr99 0:ab4e012489ef 279 /// Arduino, otherwise you will also need voltage level shifters between the
davidr99 0:ab4e012489ef 280 /// Arduino and the RFM95. CAUTION, you must also ensure you connect an
davidr99 0:ab4e012489ef 281 /// antenna.
davidr99 0:ab4e012489ef 282 ///
davidr99 0:ab4e012489ef 283 /// \code
davidr99 0:ab4e012489ef 284 /// Arduino RFM95/96/97/98
davidr99 0:ab4e012489ef 285 /// GND----------GND (ground in)
davidr99 0:ab4e012489ef 286 /// 3V3----------3.3V (3.3V in)
davidr99 0:ab4e012489ef 287 /// interrupt 0 pin D2-----------DIO0 (interrupt request out)
davidr99 0:ab4e012489ef 288 /// SS pin D10----------NSS (chip select in)
davidr99 0:ab4e012489ef 289 /// SCK pin D13----------SCK (SPI clock in)
davidr99 0:ab4e012489ef 290 /// MOSI pin D11----------MOSI (SPI Data in)
davidr99 0:ab4e012489ef 291 /// MISO pin D12----------MISO (SPI Data out)
davidr99 0:ab4e012489ef 292 /// \endcode
davidr99 0:ab4e012489ef 293 ///
davidr99 0:ab4e012489ef 294 /// With these connections, you can then use the default constructor RH_RF95().
davidr99 0:ab4e012489ef 295 /// You can override the default settings for the SS pin and the interrupt in
davidr99 0:ab4e012489ef 296 /// the RH_RF95 constructor if you wish to connect the slave select SS to other
davidr99 0:ab4e012489ef 297 /// than the normal one for your Arduino (D10 for Diecimila, Uno etc and D53
davidr99 0:ab4e012489ef 298 /// for Mega) or the interrupt request to other than pin D2 (Caution,
davidr99 0:ab4e012489ef 299 /// different processors have different constraints as to the pins available
davidr99 0:ab4e012489ef 300 /// for interrupts).
davidr99 0:ab4e012489ef 301 ///
davidr99 0:ab4e012489ef 302 /// It is possible to have 2 or more radios connected to one Arduino, provided
davidr99 0:ab4e012489ef 303 /// each radio has its own SS and interrupt line (SCK, SDI and SDO are common
davidr99 0:ab4e012489ef 304 /// to all radios)
davidr99 0:ab4e012489ef 305 ///
davidr99 0:ab4e012489ef 306 /// Caution: on some Arduinos such as the Mega 2560, if you set the slave
davidr99 0:ab4e012489ef 307 /// select pin to be other than the usual SS pin (D53 on Mega 2560), you may
davidr99 0:ab4e012489ef 308 /// need to set the usual SS pin to be an output to force the Arduino into SPI
davidr99 0:ab4e012489ef 309 /// master mode.
davidr99 0:ab4e012489ef 310 ///
davidr99 0:ab4e012489ef 311 /// Caution: Power supply requirements of the RFM module may be relevant in some circumstances:
davidr99 0:ab4e012489ef 312 /// RFM95/96/97/98 modules are capable of pulling 120mA+ at full power, where Arduino's 3.3V line can
davidr99 0:ab4e012489ef 313 /// give 50mA. You may need to make provision for alternate power supply for
davidr99 0:ab4e012489ef 314 /// the RFM module, especially if you wish to use full transmit power, and/or you have
davidr99 0:ab4e012489ef 315 /// other shields demanding power. Inadequate power for the RFM is likely to cause symptoms such as:
davidr99 0:ab4e012489ef 316 /// - reset's/bootups terminate with "init failed" messages
davidr99 0:ab4e012489ef 317 /// - random termination of communication after 5-30 packets sent/received
davidr99 0:ab4e012489ef 318 /// - "fake ok" state, where initialization passes fluently, but communication doesn't happen
davidr99 0:ab4e012489ef 319 /// - shields hang Arduino boards, especially during the flashing
davidr99 0:ab4e012489ef 320 ///
davidr99 0:ab4e012489ef 321 /// \par Interrupts
davidr99 0:ab4e012489ef 322 ///
davidr99 0:ab4e012489ef 323 /// The RH_RF95 driver uses interrupts to react to events in the RFM module,
davidr99 0:ab4e012489ef 324 /// such as the reception of a new packet, or the completion of transmission
davidr99 0:ab4e012489ef 325 /// of a packet. The RH_RF95 driver interrupt service routine reads status from
davidr99 0:ab4e012489ef 326 /// and writes data to the the RFM module via the SPI interface. It is very
davidr99 0:ab4e012489ef 327 /// important therefore, that if you are using the RH_RF95 driver with another
davidr99 0:ab4e012489ef 328 /// SPI based deviced, that you disable interrupts while you transfer data to
davidr99 0:ab4e012489ef 329 /// and from that other device. Use cli() to disable interrupts and sei() to
davidr99 0:ab4e012489ef 330 /// reenable them.
davidr99 0:ab4e012489ef 331 ///
davidr99 0:ab4e012489ef 332 /// \par Memory
davidr99 0:ab4e012489ef 333 ///
davidr99 0:ab4e012489ef 334 /// The RH_RF95 driver requires non-trivial amounts of memory. The sample
davidr99 0:ab4e012489ef 335 /// programs all compile to about 8kbytes each, which will fit in the
davidr99 0:ab4e012489ef 336 /// flash proram memory of most Arduinos. However, the RAM requirements are
davidr99 0:ab4e012489ef 337 /// more critical. Therefore, you should be vary sparing with RAM use in
davidr99 0:ab4e012489ef 338 /// programs that use the RH_RF95 driver.
davidr99 0:ab4e012489ef 339 ///
davidr99 0:ab4e012489ef 340 /// It is often hard to accurately identify when you are hitting RAM limits on Arduino.
davidr99 0:ab4e012489ef 341 /// The symptoms can include:
davidr99 0:ab4e012489ef 342 /// - Mysterious crashes and restarts
davidr99 0:ab4e012489ef 343 /// - Changes in behaviour when seemingly unrelated changes are made (such as adding print() statements)
davidr99 0:ab4e012489ef 344 /// - Hanging
davidr99 0:ab4e012489ef 345 /// - Output from Serial.print() not appearing
davidr99 0:ab4e012489ef 346 ///
davidr99 0:ab4e012489ef 347 /// \par Range
davidr99 0:ab4e012489ef 348 ///
davidr99 0:ab4e012489ef 349 /// We have made some simple range tests under the following conditions:
davidr99 0:ab4e012489ef 350 /// - rf95_client base station connected to a VHF discone antenna at 8m height above ground
davidr99 0:ab4e012489ef 351 /// - rf95_server mobile connected to 17.3cm 1/4 wavelength antenna at 1m height, no ground plane.
davidr99 0:ab4e012489ef 352 /// - Both configured for 13dBm, 434MHz, Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, CRC on. Slow+long range
davidr99 0:ab4e012489ef 353 /// - Minimum reported RSSI seen for successful comms was about -91
davidr99 0:ab4e012489ef 354 /// - Range over flat ground through heavy trees and vegetation approx 2km.
davidr99 0:ab4e012489ef 355 /// - At 20dBm (100mW) otherwise identical conditions approx 3km.
davidr99 0:ab4e012489ef 356 /// - At 20dBm, along salt water flat sandy beach, 3.2km.
davidr99 0:ab4e012489ef 357 ///
davidr99 0:ab4e012489ef 358 /// It should be noted that at this data rate, a 12 octet message takes 2 seconds to transmit.
davidr99 0:ab4e012489ef 359 ///
davidr99 0:ab4e012489ef 360 /// At 20dBm (100mW) with Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on.
davidr99 0:ab4e012489ef 361 /// (Default medium range) in the conditions described above.
davidr99 0:ab4e012489ef 362 /// - Range over flat ground through heavy trees and vegetation approx 2km.
davidr99 0:ab4e012489ef 363 ///
davidr99 0:ab4e012489ef 364 /// \par Transmitter Power
davidr99 0:ab4e012489ef 365 ///
davidr99 0:ab4e012489ef 366 /// You can control the transmitter power on the RF transceiver
davidr99 0:ab4e012489ef 367 /// with the RH_RF95::setTxPower() function. The argument can be any of
davidr99 0:ab4e012489ef 368 /// +5 to +23
davidr99 0:ab4e012489ef 369 /// The default is 13. Eg:
davidr99 0:ab4e012489ef 370 /// \code
davidr99 0:ab4e012489ef 371 /// driver.setTxPower(10);
davidr99 0:ab4e012489ef 372 /// \endcode
davidr99 0:ab4e012489ef 373 ///
davidr99 0:ab4e012489ef 374 /// We have made some actual power measurements against
davidr99 0:ab4e012489ef 375 /// programmed power for Anarduino MiniWirelessLoRa (which has RFM96W-433Mhz installed)
davidr99 0:ab4e012489ef 376 /// - MiniWirelessLoRa RFM96W-433Mhz, USB power
davidr99 0:ab4e012489ef 377 /// - 30cm RG316 soldered direct to RFM96W module ANT and GND
davidr99 0:ab4e012489ef 378 /// - SMA connector
davidr99 0:ab4e012489ef 379 /// - 12db attenuator
davidr99 0:ab4e012489ef 380 /// - SMA connector
davidr99 0:ab4e012489ef 381 /// - MiniKits AD8307 HF/VHF Power Head (calibrated against Rohde&Schwartz 806.2020 test set)
davidr99 0:ab4e012489ef 382 /// - Tektronix TDS220 scope to measure the Vout from power head
davidr99 0:ab4e012489ef 383 /// \code
davidr99 0:ab4e012489ef 384 /// Program power Measured Power
davidr99 0:ab4e012489ef 385 /// dBm dBm
davidr99 0:ab4e012489ef 386 /// 5 5
davidr99 0:ab4e012489ef 387 /// 7 7
davidr99 0:ab4e012489ef 388 /// 9 8
davidr99 0:ab4e012489ef 389 /// 11 11
davidr99 0:ab4e012489ef 390 /// 13 13
davidr99 0:ab4e012489ef 391 /// 15 15
davidr99 0:ab4e012489ef 392 /// 17 16
davidr99 0:ab4e012489ef 393 /// 19 18
davidr99 0:ab4e012489ef 394 /// 20 20
davidr99 0:ab4e012489ef 395 /// 21 21
davidr99 0:ab4e012489ef 396 /// 22 22
davidr99 0:ab4e012489ef 397 /// 23 23
davidr99 0:ab4e012489ef 398 /// \endcode
davidr99 0:ab4e012489ef 399 /// (Caution: we dont claim laboratory accuracy for these measurements)
davidr99 0:ab4e012489ef 400 /// You would not expect to get anywhere near these powers to air with a simple 1/4 wavelength wire antenna.
davidr99 0:ab4e012489ef 401 class RH_RF95 : public RHSPIDriver
davidr99 0:ab4e012489ef 402 {
davidr99 0:ab4e012489ef 403 public:
davidr99 0:ab4e012489ef 404 /// \brief Defines register values for a set of modem configuration registers
davidr99 0:ab4e012489ef 405 ///
davidr99 0:ab4e012489ef 406 /// Defines register values for a set of modem configuration registers
davidr99 0:ab4e012489ef 407 /// that can be passed to setModemRegisters() if none of the choices in
davidr99 0:ab4e012489ef 408 /// ModemConfigChoice suit your need setModemRegisters() writes the
davidr99 0:ab4e012489ef 409 /// register values from this structure to the appropriate registers
davidr99 0:ab4e012489ef 410 /// to set the desired spreading factor, coding rate and bandwidth
davidr99 0:ab4e012489ef 411 typedef struct {
davidr99 0:ab4e012489ef 412 uint8_t reg_1d; ///< Value for register RH_RF95_REG_1D_MODEM_CONFIG1
davidr99 0:ab4e012489ef 413 uint8_t reg_1e; ///< Value for register RH_RF95_REG_1E_MODEM_CONFIG2
davidr99 0:ab4e012489ef 414 uint8_t reg_26; ///< Value for register RH_RF95_REG_26_MODEM_CONFIG3
davidr99 0:ab4e012489ef 415 } ModemConfig;
davidr99 0:ab4e012489ef 416
davidr99 0:ab4e012489ef 417 /// Choices for setModemConfig() for a selected subset of common
davidr99 0:ab4e012489ef 418 /// data rates. If you need another configuration,
davidr99 0:ab4e012489ef 419 /// determine the necessary settings and call setModemRegisters() with your
davidr99 0:ab4e012489ef 420 /// desired settings. It might be helpful to use the LoRa calculator mentioned in
davidr99 0:ab4e012489ef 421 /// http://www.semtech.com/images/datasheet/LoraDesignGuide_STD.pdf
davidr99 0:ab4e012489ef 422 /// These are indexes into MODEM_CONFIG_TABLE. We strongly recommend you use these symbolic
davidr99 0:ab4e012489ef 423 /// definitions and not their integer equivalents: its possible that new values will be
davidr99 0:ab4e012489ef 424 /// introduced in later versions (though we will try to avoid it).
davidr99 0:ab4e012489ef 425 typedef enum {
davidr99 0:ab4e012489ef 426 Bw125Cr45Sf128 = 0, ///< Bw = 125 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Default medium range
davidr99 0:ab4e012489ef 427 Bw500Cr45Sf128, ///< Bw = 500 kHz, Cr = 4/5, Sf = 128chips/symbol, CRC on. Fast+short range
davidr99 0:ab4e012489ef 428 Bw31_25Cr48Sf512, ///< Bw = 31.25 kHz, Cr = 4/8, Sf = 512chips/symbol, CRC on. Slow+long range
davidr99 0:ab4e012489ef 429 Bw125Cr48Sf4096, ///< Bw = 125 kHz, Cr = 4/8, Sf = 4096chips/symbol, CRC on. Slow+long range
davidr99 0:ab4e012489ef 430 } ModemConfigChoice;
davidr99 0:ab4e012489ef 431
davidr99 0:ab4e012489ef 432 /// Constructor. You can have multiple instances, but each instance must have its own
davidr99 0:ab4e012489ef 433 /// interrupt and slave select pin. After constructing, you must call init() to initialise the interface
davidr99 0:ab4e012489ef 434 /// and the radio module. A maximum of 3 instances can co-exist on one processor, provided there are sufficient
davidr99 0:ab4e012489ef 435 /// distinct interrupt lines, one for each instance.
davidr99 0:ab4e012489ef 436 /// \param[in] slaveSelectPin the Arduino pin number of the output to use to select the RH_RF22 before
davidr99 0:ab4e012489ef 437 /// 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 438 /// \param[in] interruptPin The interrupt Pin number that is connected to the RFM DIO0 interrupt line.
davidr99 0:ab4e012489ef 439 /// Defaults to pin 2, as required by Anarduino MinWirelessLoRa module.
davidr99 0:ab4e012489ef 440 /// Caution: You must specify an interrupt capable pin.
davidr99 0:ab4e012489ef 441 /// On many Arduino boards, there are limitations as to which pins may be used as interrupts.
davidr99 0:ab4e012489ef 442 /// 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 443 /// On other Arduinos pins 2 or 3.
davidr99 0:ab4e012489ef 444 /// See http://arduino.cc/en/Reference/attachInterrupt for more details.
davidr99 0:ab4e012489ef 445 /// On Chipkit Uno32, pins 38, 2, 7, 8, 35.
davidr99 0:ab4e012489ef 446 /// On other boards, any digital pin may be used.
davidr99 0:ab4e012489ef 447 /// \param[in] spi Pointer to the SPI interface object to use.
davidr99 0:ab4e012489ef 448 /// Defaults to the standard Arduino hardware SPI interface
davidr99 0:ab4e012489ef 449 RH_RF95(PINS slaveSelectPin, PINS interruptPin, RHGenericSPI& spi = hardware_spi);
davidr99 0:ab4e012489ef 450
davidr99 0:ab4e012489ef 451 /// Initialise the Driver transport hardware and software.
davidr99 0:ab4e012489ef 452 /// Make sure the Driver is properly configured before calling init().
davidr99 0:ab4e012489ef 453 /// \return true if initialisation succeeded.
davidr99 0:ab4e012489ef 454 virtual bool init();
davidr99 0:ab4e012489ef 455
davidr99 0:ab4e012489ef 456 /// Prints the value of all chip registers
davidr99 0:ab4e012489ef 457 /// to the Serial device if RH_HAVE_SERIAL is defined for the current platform
davidr99 0:ab4e012489ef 458 /// For debugging purposes only.
davidr99 0:ab4e012489ef 459 /// \return true on success
davidr99 0:ab4e012489ef 460 bool printRegisters();
davidr99 0:ab4e012489ef 461
davidr99 0:ab4e012489ef 462 /// Sets all the registered required to configure the data modem in the RF95/96/97/98, including the bandwidth,
davidr99 0:ab4e012489ef 463 /// spreading factor etc. You can use this to configure the modem with custom configurations if none of the
davidr99 0:ab4e012489ef 464 /// canned configurations in ModemConfigChoice suit you.
davidr99 0:ab4e012489ef 465 /// \param[in] config A ModemConfig structure containing values for the modem configuration registers.
davidr99 0:ab4e012489ef 466 void setModemRegisters(const ModemConfig* config);
davidr99 0:ab4e012489ef 467
davidr99 0:ab4e012489ef 468 /// Select one of the predefined modem configurations. If you need a modem configuration not provided
davidr99 0:ab4e012489ef 469 /// here, use setModemRegisters() with your own ModemConfig.
davidr99 0:ab4e012489ef 470 /// \param[in] index The configuration choice.
davidr99 0:ab4e012489ef 471 /// \return true if index is a valid choice.
davidr99 0:ab4e012489ef 472 bool setModemConfig(ModemConfigChoice index);
davidr99 0:ab4e012489ef 473
davidr99 0:ab4e012489ef 474 /// Tests whether a new message is available
davidr99 0:ab4e012489ef 475 /// from the Driver.
davidr99 0:ab4e012489ef 476 /// On most drivers, this will also put the Driver into RHModeRx mode until
davidr99 0:ab4e012489ef 477 /// a message is actually received by the transport, when it wil be returned to RHModeIdle.
davidr99 0:ab4e012489ef 478 /// This can be called multiple times in a timeout loop
davidr99 0:ab4e012489ef 479 /// \return true if a new, complete, error-free uncollected message is available to be retreived by recv()
davidr99 0:ab4e012489ef 480 virtual bool available();
davidr99 0:ab4e012489ef 481
davidr99 0:ab4e012489ef 482 /// Turns the receiver on if it not already on.
davidr99 0:ab4e012489ef 483 /// If there is a valid message available, copy it to buf and return true
davidr99 0:ab4e012489ef 484 /// else return false.
davidr99 0:ab4e012489ef 485 /// If a message is copied, *len is set to the length (Caution, 0 length messages are permitted).
davidr99 0:ab4e012489ef 486 /// You should be sure to call this function frequently enough to not miss any messages
davidr99 0:ab4e012489ef 487 /// It is recommended that you call it in your main loop.
davidr99 0:ab4e012489ef 488 /// \param[in] buf Location to copy the received message
davidr99 0:ab4e012489ef 489 /// \param[in,out] len Pointer to available space in buf. Set to the actual number of octets copied.
davidr99 0:ab4e012489ef 490 /// \return true if a valid message was copied to buf
davidr99 0:ab4e012489ef 491 virtual bool recv(uint8_t* buf, uint8_t* len);
davidr99 0:ab4e012489ef 492
davidr99 0:ab4e012489ef 493 /// Waits until any previous transmit packet is finished being transmitted with waitPacketSent().
davidr99 0:ab4e012489ef 494 /// Then loads a message into the transmitter and starts the transmitter. Note that a message length
davidr99 0:ab4e012489ef 495 /// of 0 is permitted.
davidr99 0:ab4e012489ef 496 /// \param[in] data Array of data to be sent
davidr99 0:ab4e012489ef 497 /// \param[in] len Number of bytes of data to send
davidr99 0:ab4e012489ef 498 /// \return true if the message length was valid and it was correctly queued for transmit
davidr99 0:ab4e012489ef 499 virtual bool send(const uint8_t* data, uint8_t len);
davidr99 0:ab4e012489ef 500
davidr99 0:ab4e012489ef 501 /// Sets the length of the preamble
davidr99 0:ab4e012489ef 502 /// in bytes.
davidr99 0:ab4e012489ef 503 /// Caution: this should be set to the same
davidr99 0:ab4e012489ef 504 /// value on all nodes in your network. Default is 8.
davidr99 0:ab4e012489ef 505 /// Sets the message preamble length in RH_RF95_REG_??_PREAMBLE_?SB
davidr99 0:ab4e012489ef 506 /// \param[in] bytes Preamble length in bytes.
davidr99 0:ab4e012489ef 507 void setPreambleLength(uint16_t bytes);
davidr99 0:ab4e012489ef 508
davidr99 0:ab4e012489ef 509 /// Returns the maximum message length
davidr99 0:ab4e012489ef 510 /// available in this Driver.
davidr99 0:ab4e012489ef 511 /// \return The maximum legal message length
davidr99 0:ab4e012489ef 512 virtual uint8_t maxMessageLength();
davidr99 0:ab4e012489ef 513
davidr99 0:ab4e012489ef 514 /// Sets the transmitter and receiver
davidr99 0:ab4e012489ef 515 /// centre frequency
davidr99 0:ab4e012489ef 516 /// \param[in] centre Frequency in MHz. 137.0 to 1020.0. Caution: RFM95/96/97/98 comes in several
davidr99 0:ab4e012489ef 517 /// different frequency ranges, and setting a frequency outside that range of your radio will probably not work
davidr99 0:ab4e012489ef 518 /// \return true if the selected frquency centre is within range
davidr99 0:ab4e012489ef 519 bool setFrequency(float centre);
davidr99 0:ab4e012489ef 520
davidr99 0:ab4e012489ef 521 /// If current mode is Rx or Tx changes it to Idle. If the transmitter or receiver is running,
davidr99 0:ab4e012489ef 522 /// disables them.
davidr99 0:ab4e012489ef 523 void setModeIdle();
davidr99 0:ab4e012489ef 524
davidr99 0:ab4e012489ef 525 /// If current mode is Tx or Idle, changes it to Rx.
davidr99 0:ab4e012489ef 526 /// Starts the receiver in the RF95/96/97/98.
davidr99 0:ab4e012489ef 527 void setModeRx();
davidr99 0:ab4e012489ef 528
davidr99 0:ab4e012489ef 529 /// If current mode is Rx or Idle, changes it to Rx. F
davidr99 0:ab4e012489ef 530 /// Starts the transmitter in the RF95/96/97/98.
davidr99 0:ab4e012489ef 531 void setModeTx();
davidr99 0:ab4e012489ef 532
davidr99 0:ab4e012489ef 533 /// Sets the transmitter power output level.
davidr99 0:ab4e012489ef 534 /// Be a good neighbour and set the lowest power level you need.
davidr99 0:ab4e012489ef 535 /// Caution: legal power limits may apply in certain countries. At powers above 20dBm, PA_DAC is enabled.
davidr99 0:ab4e012489ef 536 /// After init(), the power will be set to 13dBm.
davidr99 0:ab4e012489ef 537 /// \param[in] power Transmitter power level in dBm. For RFM95/96/97/98 LORA, valid values are from +5 to +23
davidr99 0:ab4e012489ef 538 void setTxPower(int8_t power);
davidr99 0:ab4e012489ef 539
davidr99 0:ab4e012489ef 540 /// Sets the radio into low-power sleep mode.
davidr99 0:ab4e012489ef 541 /// If successful, the transport will stay in sleep mode until woken by
davidr99 0:ab4e012489ef 542 /// changing mode it idle, transmit or receive (eg by calling send(), recv(), available() etc)
davidr99 0:ab4e012489ef 543 /// Caution: there is a time penalty as the radio takes a finite time to wake from sleep mode.
davidr99 0:ab4e012489ef 544 /// \return true if sleep mode was successfully entered.
davidr99 0:ab4e012489ef 545 virtual bool sleep();
davidr99 0:ab4e012489ef 546
davidr99 0:ab4e012489ef 547 protected:
davidr99 0:ab4e012489ef 548 /// This is a low level function to handle the interrupts for one instance of RH_RF95.
davidr99 0:ab4e012489ef 549 /// Called automatically by isr*()
davidr99 0:ab4e012489ef 550 /// Should not need to be called by user code.
davidr99 0:ab4e012489ef 551 void handleInterrupt();
davidr99 0:ab4e012489ef 552
davidr99 0:ab4e012489ef 553 /// Examine the revceive buffer to determine whether the message is for this node
davidr99 0:ab4e012489ef 554 void validateRxBuf();
davidr99 0:ab4e012489ef 555
davidr99 0:ab4e012489ef 556 /// Clear our local receive buffer
davidr99 0:ab4e012489ef 557 void clearRxBuf();
davidr99 0:ab4e012489ef 558
davidr99 0:ab4e012489ef 559 private:
davidr99 0:ab4e012489ef 560 /// Low level interrupt service routine for device connected to interrupt 0
davidr99 0:ab4e012489ef 561 static void isr0();
davidr99 0:ab4e012489ef 562
davidr99 0:ab4e012489ef 563 /// Low level interrupt service routine for device connected to interrupt 1
davidr99 0:ab4e012489ef 564 static void isr1();
davidr99 0:ab4e012489ef 565
davidr99 0:ab4e012489ef 566 /// Low level interrupt service routine for device connected to interrupt 1
davidr99 0:ab4e012489ef 567 static void isr2();
davidr99 0:ab4e012489ef 568
davidr99 0:ab4e012489ef 569 /// Array of instances connected to interrupts 0 and 1
davidr99 0:ab4e012489ef 570 static RH_RF95* _deviceForInterrupt[];
davidr99 0:ab4e012489ef 571
davidr99 0:ab4e012489ef 572 /// Index of next interrupt number to use in _deviceForInterrupt
davidr99 0:ab4e012489ef 573 static uint8_t _interruptCount;
davidr99 0:ab4e012489ef 574
davidr99 0:ab4e012489ef 575 #if (RH_PLATFORM == RH_PLATFORM_MBED)
davidr99 0:ab4e012489ef 576 /// The configured interrupt pin connected to this instance
davidr99 0:ab4e012489ef 577 InterruptIn _interruptPin;
davidr99 0:ab4e012489ef 578 #else
davidr99 0:ab4e012489ef 579 /// The configured interrupt pin connected to this instance
davidr99 0:ab4e012489ef 580 uint8_t _interruptPin;
davidr99 0:ab4e012489ef 581 #endif
davidr99 0:ab4e012489ef 582
davidr99 0:ab4e012489ef 583 /// The index into _deviceForInterrupt[] for this device (if an interrupt is already allocated)
davidr99 0:ab4e012489ef 584 /// else 0xff
davidr99 0:ab4e012489ef 585 uint8_t _myInterruptIndex;
davidr99 0:ab4e012489ef 586
davidr99 0:ab4e012489ef 587 /// Number of octets in the buffer
davidr99 0:ab4e012489ef 588 volatile uint8_t _bufLen;
davidr99 0:ab4e012489ef 589
davidr99 0:ab4e012489ef 590 /// The receiver/transmitter buffer
davidr99 0:ab4e012489ef 591 uint8_t _buf[RH_RF95_MAX_PAYLOAD_LEN];
davidr99 0:ab4e012489ef 592
davidr99 0:ab4e012489ef 593 /// True when there is a valid message in the buffer
davidr99 0:ab4e012489ef 594 volatile bool _rxBufValid;
davidr99 0:ab4e012489ef 595 };
davidr99 0:ab4e012489ef 596
davidr99 0:ab4e012489ef 597 /// @example rf95_client.pde
davidr99 0:ab4e012489ef 598 /// @example rf95_server.pde
davidr99 0:ab4e012489ef 599 /// @example rf95_reliable_datagram_client.pde
davidr99 0:ab4e012489ef 600 /// @example rf95_reliable_datagram_server.pde
davidr99 0:ab4e012489ef 601
davidr99 0:ab4e012489ef 602 #endif
davidr99 0:ab4e012489ef 603